@csszyx/unplugin 0.8.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -7
- package/dist/css-mangler.cjs +4 -4
- package/dist/css-mangler.mjs +4 -4
- package/dist/index.cjs +23 -1
- package/dist/index.d.cts +100 -5
- package/dist/index.d.mts +99 -3
- package/dist/index.mjs +7 -1
- package/dist/next-prebuild.cjs +148 -0
- package/dist/next-prebuild.d.cts +66 -0
- package/dist/next-prebuild.d.mts +66 -0
- package/dist/next-prebuild.mjs +131 -0
- package/dist/next-turbo-loader.cjs +210 -0
- package/dist/next-turbo-loader.d.cts +68 -0
- package/dist/next-turbo-loader.d.mts +66 -0
- package/dist/next-turbo-loader.mjs +190 -0
- package/dist/next-watcher.cjs +237 -0
- package/dist/next-watcher.d.cts +106 -0
- package/dist/next-watcher.d.mts +106 -0
- package/dist/next-watcher.mjs +219 -0
- package/dist/shared/unplugin.8er8o6rn.mjs +276 -0
- package/dist/shared/unplugin.B_U4rZvG.cjs +281 -0
- package/dist/shared/unplugin.BbtspS8t.mjs +3271 -0
- package/dist/shared/unplugin.BceVw1eW.mjs +184 -0
- package/dist/shared/unplugin.BtQzlC2C.mjs +567 -0
- package/dist/shared/unplugin.CFp386gH.cjs +3321 -0
- package/dist/shared/unplugin.CPEWNSA0.d.cts +77 -0
- package/dist/shared/unplugin.CPEWNSA0.d.mts +77 -0
- package/dist/shared/unplugin.CScQRdTp.d.cts +15 -0
- package/dist/shared/unplugin.CScQRdTp.d.mts +15 -0
- package/dist/shared/unplugin.CdZxp0x-.d.mts +16 -0
- package/dist/shared/unplugin.DLrBgECN.d.cts +282 -0
- package/dist/shared/unplugin.DLrBgECN.d.mts +282 -0
- package/dist/shared/unplugin.DUxdYaSG.cjs +205 -0
- package/dist/shared/unplugin.s62yJbu1.cjs +591 -0
- package/dist/shared/unplugin.xeED_qwh.d.cts +16 -0
- package/dist/vite.cjs +7 -1
- package/dist/vite.d.cts +2 -1
- package/dist/vite.d.mts +2 -1
- package/dist/vite.mjs +7 -1
- package/dist/webpack.cjs +7 -1
- package/dist/webpack.d.cts +2 -1
- package/dist/webpack.d.mts +2 -1
- package/dist/webpack.mjs +7 -1
- package/package.json +41 -8
- package/dist/shared/unplugin.BNsv2szs.cjs +0 -1753
- package/dist/shared/unplugin.DCv0RtVZ.mjs +0 -1722
- package/dist/shared/unplugin.DUbr5w-N.d.cts +0 -49
- package/dist/shared/unplugin.DUbr5w-N.d.mts +0 -49
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { r as runNextWatcherCycle } from './shared/unplugin.BtQzlC2C.mjs';
|
|
3
|
+
import 'node:fs';
|
|
4
|
+
import 'node:crypto';
|
|
5
|
+
import 'node:os';
|
|
6
|
+
import 'proper-lockfile';
|
|
7
|
+
|
|
8
|
+
class NextWatcherLoop {
|
|
9
|
+
context;
|
|
10
|
+
cycleOptions;
|
|
11
|
+
debounceMs;
|
|
12
|
+
runCycle;
|
|
13
|
+
setTimeoutFn;
|
|
14
|
+
clearTimeoutFn;
|
|
15
|
+
onError;
|
|
16
|
+
timer;
|
|
17
|
+
disposed = false;
|
|
18
|
+
pendingReasons = /* @__PURE__ */ new Set();
|
|
19
|
+
lastResult;
|
|
20
|
+
lastError;
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param options
|
|
24
|
+
*/
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.context = options.context;
|
|
27
|
+
this.cycleOptions = options.cycleOptions ?? {};
|
|
28
|
+
this.debounceMs = options.debounceMs ?? 50;
|
|
29
|
+
this.runCycle = options.runCycle ?? runNextWatcherCycle;
|
|
30
|
+
this.setTimeoutFn = options.setTimeout ?? setTimeout;
|
|
31
|
+
this.clearTimeoutFn = options.clearTimeout ?? clearTimeout;
|
|
32
|
+
this.onError = options.onError;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
get pending() {
|
|
38
|
+
return this.timer !== void 0;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
get reasons() {
|
|
44
|
+
return [...this.pendingReasons];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @param reason
|
|
49
|
+
*/
|
|
50
|
+
notify(reason = "change") {
|
|
51
|
+
if (this.disposed) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.pendingReasons.add(reason);
|
|
55
|
+
if (this.timer !== void 0) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.timer = this.setTimeoutFn(() => {
|
|
59
|
+
try {
|
|
60
|
+
this.runPendingCycle();
|
|
61
|
+
} catch (error) {
|
|
62
|
+
this.lastError = error;
|
|
63
|
+
this.onError?.(error);
|
|
64
|
+
}
|
|
65
|
+
}, this.debounceMs);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
*
|
|
69
|
+
*/
|
|
70
|
+
flush() {
|
|
71
|
+
if (this.disposed || this.timer === void 0) {
|
|
72
|
+
return void 0;
|
|
73
|
+
}
|
|
74
|
+
return this.runPendingCycle();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
*/
|
|
79
|
+
dispose() {
|
|
80
|
+
if (this.timer !== void 0) {
|
|
81
|
+
this.clearTimeoutFn(this.timer);
|
|
82
|
+
}
|
|
83
|
+
this.timer = void 0;
|
|
84
|
+
this.pendingReasons.clear();
|
|
85
|
+
this.disposed = true;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
*
|
|
89
|
+
*/
|
|
90
|
+
runPendingCycle() {
|
|
91
|
+
const timer = this.timer;
|
|
92
|
+
if (timer !== void 0) {
|
|
93
|
+
this.clearTimeoutFn(timer);
|
|
94
|
+
}
|
|
95
|
+
this.timer = void 0;
|
|
96
|
+
const reasons = [...this.pendingReasons];
|
|
97
|
+
this.pendingReasons.clear();
|
|
98
|
+
const result = this.runCycle(this.context, this.cycleOptions, reasons);
|
|
99
|
+
this.lastResult = result;
|
|
100
|
+
this.lastError = void 0;
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function isNextSafelistShardPath(shardsDir, filePath) {
|
|
106
|
+
if (!path.isAbsolute(filePath)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
const relative = path.relative(path.resolve(shardsDir), path.resolve(filePath));
|
|
110
|
+
return relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative) && !relative.includes(path.sep) && !relative.startsWith(".") && relative.endsWith(".json");
|
|
111
|
+
}
|
|
112
|
+
function isNextAppSourcePath(root, filePath) {
|
|
113
|
+
if (!path.isAbsolute(filePath)) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const relative = path.relative(path.resolve(root), path.resolve(filePath));
|
|
117
|
+
return relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
|
|
118
|
+
}
|
|
119
|
+
class NextSafelistWatcher {
|
|
120
|
+
root;
|
|
121
|
+
shardsDir;
|
|
122
|
+
loop;
|
|
123
|
+
started = false;
|
|
124
|
+
closed = false;
|
|
125
|
+
/**
|
|
126
|
+
*
|
|
127
|
+
* @param options
|
|
128
|
+
*/
|
|
129
|
+
constructor(options) {
|
|
130
|
+
this.root = path.resolve(options.context.root);
|
|
131
|
+
this.shardsDir = path.resolve(options.context.safelist.shardsDir);
|
|
132
|
+
this.loop = new NextWatcherLoop(options);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
*
|
|
136
|
+
*/
|
|
137
|
+
get pending() {
|
|
138
|
+
return this.loop.pending;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
*
|
|
142
|
+
*/
|
|
143
|
+
get lastResult() {
|
|
144
|
+
return this.loop.lastResult;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
*
|
|
148
|
+
*/
|
|
149
|
+
get lastError() {
|
|
150
|
+
return this.loop.lastError;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Materialize existing shards before accepting live filesystem events.
|
|
154
|
+
*/
|
|
155
|
+
start() {
|
|
156
|
+
if (this.closed) {
|
|
157
|
+
throw new Error("[csszyx] Cannot start a closed Next safelist watcher.");
|
|
158
|
+
}
|
|
159
|
+
if (this.started && this.loop.lastResult) {
|
|
160
|
+
return this.loop.lastResult;
|
|
161
|
+
}
|
|
162
|
+
this.started = true;
|
|
163
|
+
this.loop.notify("initial");
|
|
164
|
+
const result = this.loop.flush();
|
|
165
|
+
if (!result) {
|
|
166
|
+
throw new Error("[csszyx] Next safelist watcher failed to run its initial cycle.");
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Queue a materialization cycle for one relevant shard filesystem event.
|
|
172
|
+
*
|
|
173
|
+
* @param event Normalized add/change/unlink event.
|
|
174
|
+
* @param filePath Absolute event path.
|
|
175
|
+
* @returns Whether the event was accepted.
|
|
176
|
+
*/
|
|
177
|
+
notify(event, filePath) {
|
|
178
|
+
if (this.closed || !this.started || !isNextSafelistShardPath(this.shardsDir, filePath)) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
this.loop.notify(`shard:${event}`);
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Queue tombstone cleanup after a source file is removed.
|
|
186
|
+
*
|
|
187
|
+
* @param filePath Absolute deleted source path.
|
|
188
|
+
* @returns Whether the event was accepted.
|
|
189
|
+
*/
|
|
190
|
+
notifySourceRemoval(filePath) {
|
|
191
|
+
if (this.closed || !this.started || !isNextAppSourcePath(this.root, filePath)) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
this.loop.notify("source:unlink");
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Flush any pending event batch immediately.
|
|
199
|
+
*/
|
|
200
|
+
flush() {
|
|
201
|
+
return this.loop.flush();
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Flush pending work before permanently closing the controller.
|
|
205
|
+
*/
|
|
206
|
+
close() {
|
|
207
|
+
if (this.closed) {
|
|
208
|
+
return void 0;
|
|
209
|
+
}
|
|
210
|
+
this.closed = true;
|
|
211
|
+
try {
|
|
212
|
+
return this.loop.flush();
|
|
213
|
+
} finally {
|
|
214
|
+
this.loop.dispose();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export { NextSafelistWatcher, isNextAppSourcePath, isNextSafelistShardPath };
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { ensureRustTransformAvailable, transformSourceCode, transformRust, transformOxc, transform } from '@csszyx/compiler';
|
|
3
|
+
import { c as createTransformCacheKey, a as readTransformCache, w as writeTransformCache } from './unplugin.BceVw1eW.mjs';
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
5
|
+
|
|
6
|
+
function readPackageVersion(relativePackageJson, fromUrl) {
|
|
7
|
+
try {
|
|
8
|
+
const packageJson = JSON.parse(
|
|
9
|
+
readFileSync(new URL(relativePackageJson, fromUrl), "utf8")
|
|
10
|
+
);
|
|
11
|
+
return typeof packageJson.version === "string" ? packageJson.version : "0.0.0";
|
|
12
|
+
} catch {
|
|
13
|
+
return "0.0.0";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function transformNextSource(input) {
|
|
18
|
+
const filename = normalizeSourceFilename(input.filename);
|
|
19
|
+
const producer = input.parserMode;
|
|
20
|
+
const cacheInput = createNextSourceTransformCacheInput(input, filename, producer);
|
|
21
|
+
if (input.parserMode === "rust") {
|
|
22
|
+
ensureRustTransformAvailable();
|
|
23
|
+
}
|
|
24
|
+
const cacheKey = input.cacheRoot ? createTransformCacheKey(cacheInput) : null;
|
|
25
|
+
if (input.cacheRoot && cacheKey) {
|
|
26
|
+
const cached = readTransformCache(input.cacheRoot, cacheInput, cacheKey);
|
|
27
|
+
if (cached) {
|
|
28
|
+
return { result: cached, cacheStatus: "hit", producer };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const result = runNextSourceTransform(input, filename);
|
|
32
|
+
assertNoUnsafePassThrough(input.source, result.result, filename);
|
|
33
|
+
if (input.cacheRoot && cacheKey && result.producer === producer) {
|
|
34
|
+
writeTransformCache(input.cacheRoot, cacheInput, result.result, cacheKey);
|
|
35
|
+
return { ...result, cacheStatus: "write" };
|
|
36
|
+
}
|
|
37
|
+
return { ...result, cacheStatus: input.cacheRoot ? "miss" : "disabled" };
|
|
38
|
+
}
|
|
39
|
+
function assertNoUnsafePassThrough(source, result, filename) {
|
|
40
|
+
if (!hasSzSyntax(source)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!result.transformed && result.code === source) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`[csszyx] Next source transform failed closed for ${filename}: source still contains csszyx sz syntax.`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function hasSzSyntax(source) {
|
|
50
|
+
const cleaned = stripJsCommentsAndStrings(source);
|
|
51
|
+
return /\bsz\s*=/.test(cleaned) || /\bsz\s*:\s*[{"']/.test(cleaned);
|
|
52
|
+
}
|
|
53
|
+
function stripJsCommentsAndStrings(source) {
|
|
54
|
+
let out = "";
|
|
55
|
+
let index = 0;
|
|
56
|
+
const length = source.length;
|
|
57
|
+
while (index < length) {
|
|
58
|
+
const char = source[index];
|
|
59
|
+
const peek = index + 1 < length ? source[index + 1] : "";
|
|
60
|
+
if (char === "/" && peek === "/") {
|
|
61
|
+
index += 2;
|
|
62
|
+
while (index < length && source[index] !== "\n") {
|
|
63
|
+
index++;
|
|
64
|
+
}
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (char === "/" && peek === "*") {
|
|
68
|
+
index += 2;
|
|
69
|
+
while (index + 1 < length && !(source[index] === "*" && source[index + 1] === "/")) {
|
|
70
|
+
index++;
|
|
71
|
+
}
|
|
72
|
+
index = Math.min(length, index + 2);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (char === "/" && isRegexLiteralStart(out)) {
|
|
76
|
+
index++;
|
|
77
|
+
let inCharClass = false;
|
|
78
|
+
while (index < length) {
|
|
79
|
+
const current = source[index];
|
|
80
|
+
if (current === "\\" && index + 1 < length) {
|
|
81
|
+
index += 2;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (current === "[") {
|
|
85
|
+
inCharClass = true;
|
|
86
|
+
index++;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (current === "]") {
|
|
90
|
+
inCharClass = false;
|
|
91
|
+
index++;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (current === "/" && !inCharClass) {
|
|
95
|
+
index++;
|
|
96
|
+
while (/[a-z]/i.test(source[index] ?? "")) {
|
|
97
|
+
index++;
|
|
98
|
+
}
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
index++;
|
|
102
|
+
}
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
106
|
+
const quote = char;
|
|
107
|
+
index++;
|
|
108
|
+
while (index < length && source[index] !== quote) {
|
|
109
|
+
if (source[index] === "\\" && index + 1 < length) {
|
|
110
|
+
index += 2;
|
|
111
|
+
} else {
|
|
112
|
+
index++;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
index++;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
out += char;
|
|
119
|
+
index++;
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
function isRegexLiteralStart(emitted) {
|
|
124
|
+
const trimmed = emitted.trimEnd();
|
|
125
|
+
const previous = trimmed.length > 0 ? trimmed.charAt(trimmed.length - 1) : void 0;
|
|
126
|
+
return previous === void 0 || /[({[=:;,!&|?+\-*%^~<>]/.test(previous);
|
|
127
|
+
}
|
|
128
|
+
function runNextSourceTransform(input, filename) {
|
|
129
|
+
const compilerOptions = input.compilerOptions;
|
|
130
|
+
if (input.parserMode === "babel") {
|
|
131
|
+
return {
|
|
132
|
+
result: transformSourceCode(input.source, filename, compilerOptions),
|
|
133
|
+
producer: "babel"
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (input.parserMode === "rust") {
|
|
137
|
+
return {
|
|
138
|
+
result: transformRust(input.source, filename, compilerOptions),
|
|
139
|
+
producer: "rust"
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
return {
|
|
144
|
+
result: transformOxc(input.source, filename, compilerOptions),
|
|
145
|
+
producer: "oxc"
|
|
146
|
+
};
|
|
147
|
+
} catch (error) {
|
|
148
|
+
if (input.allowBabelFallback === false) {
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
const result = transformSourceCode(input.source, filename, compilerOptions);
|
|
152
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
153
|
+
result.diagnostics.push(
|
|
154
|
+
`[csszyx] oxc parser fell back to Babel for ${filename}: ${reason}`
|
|
155
|
+
);
|
|
156
|
+
return { result, producer: "babel-fallback" };
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function createNextSourceTransformCacheInput(input, filename, producer) {
|
|
160
|
+
return {
|
|
161
|
+
pluginVersion: input.pluginVersion,
|
|
162
|
+
compilerVersion: input.compilerVersion,
|
|
163
|
+
parserMode: input.parserMode,
|
|
164
|
+
producer,
|
|
165
|
+
astBudget: input.astBudget ?? input.compilerOptions?.astBudget,
|
|
166
|
+
mangleVars: input.compilerOptions?.mangleVars,
|
|
167
|
+
mangleVarHoistMaxDepth: input.compilerOptions?.mangleVarHoistMaxDepth,
|
|
168
|
+
globalVarAliases: normalizeGlobalVarAliasesForCache(
|
|
169
|
+
input.compilerOptions?.globalVarAliases
|
|
170
|
+
),
|
|
171
|
+
filename,
|
|
172
|
+
source: input.source
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function normalizeSourceFilename(filename) {
|
|
176
|
+
return filename.replace(/\\/g, "/");
|
|
177
|
+
}
|
|
178
|
+
function normalizeGlobalVarAliasesForCache(aliases) {
|
|
179
|
+
if (!aliases) {
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
const entries = aliases instanceof Map ? aliases.entries() : Array.isArray(aliases) ? aliases : Object.entries(aliases);
|
|
183
|
+
const normalized = /* @__PURE__ */ new Map();
|
|
184
|
+
for (const [original, alias] of entries) {
|
|
185
|
+
if (original.startsWith("--") && alias.startsWith("--")) {
|
|
186
|
+
normalized.set(original, alias);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return [...normalized].sort(([left], [right]) => left.localeCompare(right));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function collectNextTransformMetadata(result, source, sourcePath) {
|
|
193
|
+
const classes = new Set(result.classes);
|
|
194
|
+
collectRuntimeStaticClasses(result, classes);
|
|
195
|
+
return {
|
|
196
|
+
sourcePath,
|
|
197
|
+
sourceHash: createHash("sha256").update(source).digest("hex"),
|
|
198
|
+
classes: [...classes].sort(),
|
|
199
|
+
rawClassNames: [...result.rawClassNames].sort(),
|
|
200
|
+
recoveryTokenCount: result.recoveryTokens.size,
|
|
201
|
+
cssVariableCount: result.cssVariableMap.size
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function createNextSafelistShardFromMetadata(metadata, cacheKey) {
|
|
205
|
+
return {
|
|
206
|
+
cacheKey,
|
|
207
|
+
sourcePath: metadata.sourcePath,
|
|
208
|
+
sourceHash: metadata.sourceHash,
|
|
209
|
+
classes: metadata.classes
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function collectRuntimeStaticClasses(result, discoveredClasses) {
|
|
213
|
+
if (!result.usesRuntime) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const szCallRe = /_sz\(\s*\{/g;
|
|
217
|
+
for (const szMatch of result.code.matchAll(szCallRe)) {
|
|
218
|
+
let depth = 1;
|
|
219
|
+
let index = (szMatch.index ?? 0) + szMatch[0].length;
|
|
220
|
+
while (index < result.code.length && depth > 0) {
|
|
221
|
+
if (result.code[index] === "{") {
|
|
222
|
+
depth++;
|
|
223
|
+
} else if (result.code[index] === "}") {
|
|
224
|
+
depth--;
|
|
225
|
+
}
|
|
226
|
+
index++;
|
|
227
|
+
}
|
|
228
|
+
const objectSource = result.code.slice((szMatch.index ?? 0) + szMatch[0].length, index - 1);
|
|
229
|
+
collectRuntimeStringClasses(objectSource, discoveredClasses);
|
|
230
|
+
collectRuntimeNumberClasses(objectSource, discoveredClasses);
|
|
231
|
+
collectRuntimeBooleanClasses(objectSource, discoveredClasses);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function collectRuntimeStringClasses(objectSource, discoveredClasses) {
|
|
235
|
+
const stringKeyValue = /(\w+)\s*:\s*(?:"([^"]*)"|'([^']*)')/g;
|
|
236
|
+
for (const match of objectSource.matchAll(stringKeyValue)) {
|
|
237
|
+
try {
|
|
238
|
+
collectTransformClasses(
|
|
239
|
+
transform({ [match[1]]: match[2] ?? match[3] }),
|
|
240
|
+
discoveredClasses
|
|
241
|
+
);
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function collectRuntimeNumberClasses(objectSource, discoveredClasses) {
|
|
247
|
+
const numberKeyValue = /(\w+)\s*:\s*(-?\d+(?:\.\d+)?)\s*(?=[,}\n])/g;
|
|
248
|
+
for (const match of objectSource.matchAll(numberKeyValue)) {
|
|
249
|
+
try {
|
|
250
|
+
collectTransformClasses(
|
|
251
|
+
transform({ [match[1]]: Number.parseFloat(match[2]) }),
|
|
252
|
+
discoveredClasses
|
|
253
|
+
);
|
|
254
|
+
} catch {
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function collectRuntimeBooleanClasses(objectSource, discoveredClasses) {
|
|
259
|
+
const booleanKeyValue = /(\w+)\s*:\s*(true|false)\s*(?=[,}\n])/g;
|
|
260
|
+
for (const match of objectSource.matchAll(booleanKeyValue)) {
|
|
261
|
+
try {
|
|
262
|
+
collectTransformClasses(
|
|
263
|
+
transform({ [match[1]]: match[2] === "true" }),
|
|
264
|
+
discoveredClasses
|
|
265
|
+
);
|
|
266
|
+
} catch {
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function collectTransformClasses(result, discoveredClasses) {
|
|
271
|
+
for (const className of result.className.split(/\s+/).filter(Boolean)) {
|
|
272
|
+
discoveredClasses.add(className);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export { createNextSafelistShardFromMetadata as a, collectNextTransformMetadata as c, readPackageVersion as r, transformNextSource as t };
|