@csszyx/unplugin 0.6.0 → 0.7.0
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/dist/{chunk-HOQTC45W.js → chunk-GXGGTRUA.js} +356 -37
- package/dist/index.cjs +362 -35
- package/dist/index.d.cts +96 -1
- package/dist/index.d.ts +96 -1
- package/dist/index.js +17 -1
- package/dist/vite.cjs +346 -35
- package/dist/vite.js +1 -1
- package/dist/webpack.cjs +346 -35
- package/dist/webpack.js +1 -1
- package/package.json +6 -6
package/dist/vite.cjs
CHANGED
|
@@ -35,8 +35,8 @@ __export(vite_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(vite_exports);
|
|
36
36
|
|
|
37
37
|
// src/unplugin.ts
|
|
38
|
-
var
|
|
39
|
-
var
|
|
38
|
+
var fs2 = __toESM(require("fs"), 1);
|
|
39
|
+
var path2 = __toESM(require("path"), 1);
|
|
40
40
|
var import_compiler = require("@csszyx/compiler");
|
|
41
41
|
var import_core = require("@csszyx/core");
|
|
42
42
|
var import_svelte_adapter = require("@csszyx/svelte-adapter");
|
|
@@ -200,7 +200,7 @@ function injectHydrationData(html, mangleMap, checksum, options = {}) {
|
|
|
200
200
|
function transformIndexHtml(html, mangleMap, checksum, options = {}) {
|
|
201
201
|
return injectHydrationData(html, mangleMap, checksum, options);
|
|
202
202
|
}
|
|
203
|
-
function buildRecoveryManifest(tokens, options
|
|
203
|
+
function buildRecoveryManifest(tokens, options) {
|
|
204
204
|
const stripped = options.production === true;
|
|
205
205
|
const strippedDevOnlyPaths = [];
|
|
206
206
|
const sorted = {};
|
|
@@ -214,14 +214,14 @@ function buildRecoveryManifest(tokens, options = {}) {
|
|
|
214
214
|
strippedDevOnlyPaths.push(data.path);
|
|
215
215
|
continue;
|
|
216
216
|
}
|
|
217
|
-
sorted[key] = data;
|
|
217
|
+
sorted[key] = stripped ? { mode: data.mode, component: data.component, path: "" } : data;
|
|
218
218
|
}
|
|
219
219
|
const serialised = JSON.stringify(sorted);
|
|
220
220
|
const fullChecksum = (0, import_node_crypto.createHash)("sha256").update(serialised).digest("hex");
|
|
221
221
|
const checksum = fullChecksum.substring(0, 16);
|
|
222
222
|
const buildId = `${Date.now().toString(36)}-${fullChecksum.substring(0, 6)}`;
|
|
223
223
|
return {
|
|
224
|
-
manifest: { buildId, checksum, tokens: sorted },
|
|
224
|
+
manifest: { buildId, checksum, mangleChecksum: options.mangleChecksum, tokens: sorted },
|
|
225
225
|
strippedDevOnlyPaths
|
|
226
226
|
};
|
|
227
227
|
}
|
|
@@ -241,6 +241,303 @@ function injectRecoveryManifest(html, manifest) {
|
|
|
241
241
|
return html + scriptTag;
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
+
// src/rsc-boundary.ts
|
|
245
|
+
var fs = __toESM(require("fs"), 1);
|
|
246
|
+
var path = __toESM(require("path"), 1);
|
|
247
|
+
var SERVER_DIRECTIVE_RE = /^['"]use server['"];?$/;
|
|
248
|
+
var CLIENT_DIRECTIVE_RE = /^['"]use client['"];?$/;
|
|
249
|
+
var RUNTIME_MODULES = /* @__PURE__ */ new Set([
|
|
250
|
+
"@csszyx/runtime",
|
|
251
|
+
"@csszyx/runtime/lite",
|
|
252
|
+
"csszyx",
|
|
253
|
+
"csszyx/lite"
|
|
254
|
+
]);
|
|
255
|
+
var FORBIDDEN_SYMBOLS = /* @__PURE__ */ new Set([
|
|
256
|
+
"_sz",
|
|
257
|
+
"_sz2",
|
|
258
|
+
"_sz3",
|
|
259
|
+
"_szIf",
|
|
260
|
+
"_szMerge",
|
|
261
|
+
"_szSwitch",
|
|
262
|
+
"__csszyx_runtime__"
|
|
263
|
+
]);
|
|
264
|
+
function hasUseServerDirective(code) {
|
|
265
|
+
for (const statement of readDirectivePrologue(code)) {
|
|
266
|
+
if (SERVER_DIRECTIVE_RE.test(statement)) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
if (CLIENT_DIRECTIVE_RE.test(statement)) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
function hasUseClientDirective(code) {
|
|
276
|
+
for (const statement of readDirectivePrologue(code)) {
|
|
277
|
+
if (CLIENT_DIRECTIVE_RE.test(statement)) {
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
if (SERVER_DIRECTIVE_RE.test(statement)) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
function isRSCServerModule(code, id) {
|
|
287
|
+
if (hasUseServerDirective(code)) {
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
if (hasUseClientDirective(code)) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
return isNextAppRouterEntry(id);
|
|
294
|
+
}
|
|
295
|
+
function findRSCBoundaryViolation(code, id) {
|
|
296
|
+
if (!isRSCServerModule(code, id)) {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
for (const imported of findRuntimeImports(code)) {
|
|
300
|
+
for (const symbol of imported.symbols) {
|
|
301
|
+
if (FORBIDDEN_SYMBOLS.has(symbol)) {
|
|
302
|
+
return {
|
|
303
|
+
symbol,
|
|
304
|
+
path: id,
|
|
305
|
+
importChain: [id, imported.source]
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
function createRSCModuleRecord(code, id) {
|
|
313
|
+
const normalized = normalizeModuleId(id);
|
|
314
|
+
return {
|
|
315
|
+
id: normalized,
|
|
316
|
+
isServer: isRSCServerModule(code, normalized),
|
|
317
|
+
isClient: hasUseClientDirective(code),
|
|
318
|
+
imports: findLocalImportSources(code).map((source) => resolveLocalModule(normalized, source)).filter((resolved) => resolved !== null),
|
|
319
|
+
runtimeImports: findRuntimeImports(code).filter((imported) => imported.symbols.some((symbol) => FORBIDDEN_SYMBOLS.has(symbol)))
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function findRSCGraphViolation(records) {
|
|
323
|
+
for (const root of records.values()) {
|
|
324
|
+
if (!root.isServer) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
const violation = walkRSCGraph(root, records, [root.id], /* @__PURE__ */ new Set([root.id]));
|
|
328
|
+
if (violation) {
|
|
329
|
+
return {
|
|
330
|
+
symbol: violation.symbol,
|
|
331
|
+
path: root.id,
|
|
332
|
+
importChain: violation.importChain
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
function assertNoRSCGraphViolation(records) {
|
|
339
|
+
const violation = findRSCGraphViolation(records);
|
|
340
|
+
if (!violation) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
throw new Error(formatRSCViolation(violation));
|
|
344
|
+
}
|
|
345
|
+
function isNextAppRouterEntry(id) {
|
|
346
|
+
const clean = id.split("?")[0]?.replace(/\\/g, "/") ?? id;
|
|
347
|
+
return /(^|\/)app\/.*\/?(?:page|layout|template|loading|error|not-found|global-error|default|route)\.[cm]?[tj]sx?$/.test(clean);
|
|
348
|
+
}
|
|
349
|
+
function assertNoRSCBoundaryViolation(code, id) {
|
|
350
|
+
const violation = findRSCBoundaryViolation(code, id);
|
|
351
|
+
if (!violation) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
throw new Error(formatRSCViolation(violation));
|
|
355
|
+
}
|
|
356
|
+
function formatRSCViolation(violation) {
|
|
357
|
+
return `csszyxRSCViolation: ${violation.symbol} imported in Server Component ${violation.path}
|
|
358
|
+
Import chain: ${violation.importChain.join(" -> ")}`;
|
|
359
|
+
}
|
|
360
|
+
function walkRSCGraph(current, records, chain, seen) {
|
|
361
|
+
if (current.isClient) {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
const runtime = current.runtimeImports[0];
|
|
365
|
+
const symbol = runtime?.symbols.find((s) => FORBIDDEN_SYMBOLS.has(s));
|
|
366
|
+
if (runtime && symbol) {
|
|
367
|
+
return {
|
|
368
|
+
symbol,
|
|
369
|
+
path: chain[0] ?? current.id,
|
|
370
|
+
importChain: [...chain, runtime.source]
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
for (const importedId of current.imports) {
|
|
374
|
+
if (seen.has(importedId)) {
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
const next = records.get(importedId);
|
|
378
|
+
if (!next) {
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
seen.add(importedId);
|
|
382
|
+
const violation = walkRSCGraph(next, records, [...chain, importedId], seen);
|
|
383
|
+
if (violation) {
|
|
384
|
+
return violation;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
function readDirectivePrologue(code) {
|
|
390
|
+
const out = [];
|
|
391
|
+
let i = code.charCodeAt(0) === 65279 ? 1 : 0;
|
|
392
|
+
while (i < code.length) {
|
|
393
|
+
i = skipWhitespaceAndComments(code, i);
|
|
394
|
+
const quote = code[i];
|
|
395
|
+
if (quote !== '"' && quote !== "'") {
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
let j = i + 1;
|
|
399
|
+
let escaped = false;
|
|
400
|
+
while (j < code.length) {
|
|
401
|
+
const ch = code[j];
|
|
402
|
+
if (escaped) {
|
|
403
|
+
escaped = false;
|
|
404
|
+
} else if (ch === "\\") {
|
|
405
|
+
escaped = true;
|
|
406
|
+
} else if (ch === quote) {
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
j++;
|
|
410
|
+
}
|
|
411
|
+
if (j >= code.length) {
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
let end = j + 1;
|
|
415
|
+
while (end < code.length && /[ \t\r\n]/.test(code[end])) {
|
|
416
|
+
end++;
|
|
417
|
+
}
|
|
418
|
+
if (code[end] === ";") {
|
|
419
|
+
end++;
|
|
420
|
+
}
|
|
421
|
+
out.push(code.slice(i, end).trim());
|
|
422
|
+
i = end;
|
|
423
|
+
}
|
|
424
|
+
return out;
|
|
425
|
+
}
|
|
426
|
+
function skipWhitespaceAndComments(code, start) {
|
|
427
|
+
let i = start;
|
|
428
|
+
while (i < code.length) {
|
|
429
|
+
while (i < code.length && /\s/.test(code[i])) {
|
|
430
|
+
i++;
|
|
431
|
+
}
|
|
432
|
+
if (code.startsWith("//", i)) {
|
|
433
|
+
const next = code.indexOf("\n", i + 2);
|
|
434
|
+
i = next === -1 ? code.length : next + 1;
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
if (code.startsWith("/*", i)) {
|
|
438
|
+
const next = code.indexOf("*/", i + 2);
|
|
439
|
+
i = next === -1 ? code.length : next + 2;
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
return i;
|
|
445
|
+
}
|
|
446
|
+
function findRuntimeImports(code) {
|
|
447
|
+
const imports = [];
|
|
448
|
+
const staticImportRe = /import\s+(?!type\b)([\s\S]*?)\s+from\s+['"]([^'"]+)['"]/g;
|
|
449
|
+
const sideEffectImportRe = /import\s+['"]([^'"]+)['"]/g;
|
|
450
|
+
const dynamicImportRe = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
451
|
+
let match;
|
|
452
|
+
while ((match = staticImportRe.exec(code)) !== null) {
|
|
453
|
+
const clause = match[1];
|
|
454
|
+
const source = match[2];
|
|
455
|
+
if (!RUNTIME_MODULES.has(source)) {
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
imports.push({ source, symbols: readImportedSymbols(clause) });
|
|
459
|
+
}
|
|
460
|
+
while ((match = sideEffectImportRe.exec(code)) !== null) {
|
|
461
|
+
const source = match[1];
|
|
462
|
+
if (RUNTIME_MODULES.has(source)) {
|
|
463
|
+
imports.push({ source, symbols: [] });
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
while ((match = dynamicImportRe.exec(code)) !== null) {
|
|
467
|
+
const source = match[1];
|
|
468
|
+
if (RUNTIME_MODULES.has(source)) {
|
|
469
|
+
imports.push({ source, symbols: Array.from(FORBIDDEN_SYMBOLS) });
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
return imports;
|
|
473
|
+
}
|
|
474
|
+
function findLocalImportSources(code) {
|
|
475
|
+
const out = [];
|
|
476
|
+
const staticImportRe = /import\s+(?!type\b)(?:[\s\S]*?\s+from\s+)?['"]([^'"]+)['"]/g;
|
|
477
|
+
const exportFromRe = /export\s+(?!type\b)(?:[\s\S]*?)\s+from\s+['"]([^'"]+)['"]/g;
|
|
478
|
+
const dynamicImportRe = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
479
|
+
let match;
|
|
480
|
+
for (const re of [staticImportRe, exportFromRe, dynamicImportRe]) {
|
|
481
|
+
while ((match = re.exec(code)) !== null) {
|
|
482
|
+
const source = match[1];
|
|
483
|
+
if (source.startsWith(".") || source.startsWith("/")) {
|
|
484
|
+
out.push(source);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return out;
|
|
489
|
+
}
|
|
490
|
+
function normalizeModuleId(id) {
|
|
491
|
+
const clean = id.split("?")[0] ?? id;
|
|
492
|
+
try {
|
|
493
|
+
return fs.realpathSync.native(clean).replace(/\\/g, "/");
|
|
494
|
+
} catch {
|
|
495
|
+
return path.resolve(clean).replace(/\\/g, "/");
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
function resolveLocalModule(importer, source) {
|
|
499
|
+
const base = source.startsWith("/") ? source : path.resolve(path.dirname(importer), source);
|
|
500
|
+
const candidates = [
|
|
501
|
+
base,
|
|
502
|
+
`${base}.tsx`,
|
|
503
|
+
`${base}.ts`,
|
|
504
|
+
`${base}.jsx`,
|
|
505
|
+
`${base}.js`,
|
|
506
|
+
`${base}.mjs`,
|
|
507
|
+
`${base}.cjs`,
|
|
508
|
+
path.join(base, "index.tsx"),
|
|
509
|
+
path.join(base, "index.ts"),
|
|
510
|
+
path.join(base, "index.jsx"),
|
|
511
|
+
path.join(base, "index.js")
|
|
512
|
+
];
|
|
513
|
+
for (const candidate of candidates) {
|
|
514
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
|
|
515
|
+
return normalizeModuleId(candidate);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
function readImportedSymbols(clause) {
|
|
521
|
+
const symbols = [];
|
|
522
|
+
const named = clause.match(/\{([\s\S]*?)\}/);
|
|
523
|
+
if (named) {
|
|
524
|
+
for (const part of named[1].split(",")) {
|
|
525
|
+
const trimmed = part.trim();
|
|
526
|
+
if (!trimmed || trimmed.startsWith("type ")) {
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
const sourceName = trimmed.replace(/^type\s+/, "").split(/\s+as\s+/)[0]?.trim();
|
|
530
|
+
if (sourceName) {
|
|
531
|
+
symbols.push(sourceName);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
if (/\*\s+as\s+\w+/.test(clause)) {
|
|
536
|
+
symbols.push(...FORBIDDEN_SYMBOLS);
|
|
537
|
+
}
|
|
538
|
+
return symbols;
|
|
539
|
+
}
|
|
540
|
+
|
|
244
541
|
// src/theme-scanner.ts
|
|
245
542
|
var EMPTY_THEME = { colors: [], spacings: [], fonts: [], radii: [], shadows: [] };
|
|
246
543
|
function stripLayerWrappers(css) {
|
|
@@ -489,8 +786,8 @@ function runThemeScan(rootDir, scanCss) {
|
|
|
489
786
|
const patterns = Array.isArray(scanCss) ? scanCss : [scanCss];
|
|
490
787
|
const sourceFiles = [];
|
|
491
788
|
for (const pattern of patterns) {
|
|
492
|
-
const resolved =
|
|
493
|
-
if (
|
|
789
|
+
const resolved = path2.isAbsolute(pattern) ? pattern : path2.join(rootDir, pattern);
|
|
790
|
+
if (fs2.existsSync(resolved)) {
|
|
494
791
|
sourceFiles.push(resolved);
|
|
495
792
|
}
|
|
496
793
|
}
|
|
@@ -499,20 +796,20 @@ function runThemeScan(rootDir, scanCss) {
|
|
|
499
796
|
}
|
|
500
797
|
const themes = sourceFiles.map((f) => {
|
|
501
798
|
try {
|
|
502
|
-
return parseThemeBlocks(
|
|
799
|
+
return parseThemeBlocks(fs2.readFileSync(f, "utf-8"));
|
|
503
800
|
} catch {
|
|
504
801
|
return null;
|
|
505
802
|
}
|
|
506
803
|
}).filter((t) => t !== null);
|
|
507
804
|
const merged = mergeThemes(themes);
|
|
508
|
-
const outputPath =
|
|
805
|
+
const outputPath = path2.join(rootDir, ".csszyx", "theme.d.ts");
|
|
509
806
|
writeThemeDts({ outputPath, theme: merged, sourceFiles });
|
|
510
807
|
if (!_hasWarnedTsConfig) {
|
|
511
808
|
_hasWarnedTsConfig = true;
|
|
512
809
|
try {
|
|
513
810
|
const checkFile = (cfgPath) => {
|
|
514
|
-
if (
|
|
515
|
-
const content =
|
|
811
|
+
if (fs2.existsSync(cfgPath)) {
|
|
812
|
+
const content = fs2.readFileSync(cfgPath, "utf-8");
|
|
516
813
|
if (!content.includes(".csszyx")) {
|
|
517
814
|
console.warn(`
|
|
518
815
|
\x1B[33m\u26A0\uFE0F CSSzyx: Theme Auto-Scan enabled, but TypeScript isn't configured. Run "npx @csszyx/cli init" to fix.\x1B[0m
|
|
@@ -522,8 +819,8 @@ function runThemeScan(rootDir, scanCss) {
|
|
|
522
819
|
}
|
|
523
820
|
return false;
|
|
524
821
|
};
|
|
525
|
-
if (!checkFile(
|
|
526
|
-
checkFile(
|
|
822
|
+
if (!checkFile(path2.join(rootDir, "tsconfig.json"))) {
|
|
823
|
+
checkFile(path2.join(rootDir, "tsconfig.app.json"));
|
|
527
824
|
}
|
|
528
825
|
} catch {
|
|
529
826
|
}
|
|
@@ -703,13 +1000,15 @@ function mangleCodeClassesSync(code, mangleMap) {
|
|
|
703
1000
|
}
|
|
704
1001
|
function createCsszyxPlugins(options = {}) {
|
|
705
1002
|
const manglingEnabled = options.production?.mangle !== false;
|
|
1003
|
+
const astBudgetOverride = options.build?.astBudgetLimit;
|
|
706
1004
|
const state = {
|
|
707
1005
|
classes: /* @__PURE__ */ new Set(),
|
|
708
1006
|
mangleMap: {},
|
|
709
1007
|
checksum: "",
|
|
710
1008
|
finalized: false,
|
|
711
1009
|
rootDir: process.cwd(),
|
|
712
|
-
recoveryTokens: /* @__PURE__ */ new Map()
|
|
1010
|
+
recoveryTokens: /* @__PURE__ */ new Map(),
|
|
1011
|
+
rscModules: /* @__PURE__ */ new Map()
|
|
713
1012
|
};
|
|
714
1013
|
const SAFELIST_FILENAME = "csszyx-classes.html";
|
|
715
1014
|
const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".tsx", ".jsx", ".ts", ".js"]);
|
|
@@ -718,16 +1017,16 @@ function createCsszyxPlugins(options = {}) {
|
|
|
718
1017
|
if (classes.size === 0) {
|
|
719
1018
|
return;
|
|
720
1019
|
}
|
|
721
|
-
const safelistPath =
|
|
1020
|
+
const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME);
|
|
722
1021
|
const classList = Array.from(classes).join(" ");
|
|
723
1022
|
const content = `<!-- Auto-generated by csszyx \u2014 DO NOT EDIT -->
|
|
724
1023
|
<!-- Tailwind CSS scans this file for class name detection -->
|
|
725
1024
|
<div class="${classList}"><div class="${classList}">x</div><div class="${classList}">x</div></div>
|
|
726
1025
|
`;
|
|
727
1026
|
try {
|
|
728
|
-
const existing =
|
|
1027
|
+
const existing = fs2.existsSync(safelistPath) ? fs2.readFileSync(safelistPath, "utf-8") : "";
|
|
729
1028
|
if (existing !== content) {
|
|
730
|
-
|
|
1029
|
+
fs2.writeFileSync(safelistPath, content);
|
|
731
1030
|
}
|
|
732
1031
|
} catch {
|
|
733
1032
|
}
|
|
@@ -738,23 +1037,23 @@ function createCsszyxPlugins(options = {}) {
|
|
|
738
1037
|
function scanDir(dir) {
|
|
739
1038
|
let entries;
|
|
740
1039
|
try {
|
|
741
|
-
entries =
|
|
1040
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
742
1041
|
} catch {
|
|
743
1042
|
return;
|
|
744
1043
|
}
|
|
745
1044
|
for (const entry of entries) {
|
|
746
1045
|
if (entry.isDirectory()) {
|
|
747
1046
|
if (!IGNORE_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
|
|
748
|
-
scanDir(
|
|
1047
|
+
scanDir(path2.join(dir, entry.name));
|
|
749
1048
|
}
|
|
750
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
751
|
-
const filePath =
|
|
1049
|
+
} else if (SOURCE_EXTENSIONS.has(path2.extname(entry.name))) {
|
|
1050
|
+
const filePath = path2.join(dir, entry.name);
|
|
752
1051
|
try {
|
|
753
|
-
const content =
|
|
1052
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
754
1053
|
if (!content.includes("sz=") && !content.includes("sz:")) {
|
|
755
1054
|
continue;
|
|
756
1055
|
}
|
|
757
|
-
const result = (0, import_compiler.transformSourceCode)(content, filePath);
|
|
1056
|
+
const result = (0, import_compiler.transformSourceCode)(content, filePath, { astBudget: astBudgetOverride });
|
|
758
1057
|
if (!result.transformed) {
|
|
759
1058
|
continue;
|
|
760
1059
|
}
|
|
@@ -942,14 +1241,17 @@ function createCsszyxPlugins(options = {}) {
|
|
|
942
1241
|
* @returns transformed code with source map, or null if no changes were made
|
|
943
1242
|
*/
|
|
944
1243
|
transform(code, id) {
|
|
1244
|
+
if (/\.[tj]sx?(\?.*)?$/.test(id)) {
|
|
1245
|
+
assertNoRSCBoundaryViolation(code, id);
|
|
1246
|
+
}
|
|
945
1247
|
if (/\.css(\?.*)?$/.test(id)) {
|
|
946
1248
|
const hasTailwindImport = code.includes('@import "tailwindcss') || code.includes("@import 'tailwindcss");
|
|
947
1249
|
if (hasTailwindImport && state.classes.size > 0) {
|
|
948
1250
|
const candidates = Array.from(state.classes).filter((c) => c.length >= 2 && /^[a-z]/.test(c)).join(" ");
|
|
949
1251
|
if (candidates) {
|
|
950
|
-
const safelistPath =
|
|
951
|
-
const cssDir =
|
|
952
|
-
let relPath =
|
|
1252
|
+
const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME).replace(/\\/g, "/");
|
|
1253
|
+
const cssDir = path2.dirname(id).replace(/\\/g, "/");
|
|
1254
|
+
let relPath = path2.posix.relative(cssDir, safelistPath);
|
|
953
1255
|
if (!relPath.startsWith(".")) {
|
|
954
1256
|
relPath = "./" + relPath;
|
|
955
1257
|
}
|
|
@@ -988,7 +1290,7 @@ ${sourceDirective}`
|
|
|
988
1290
|
transformed = true;
|
|
989
1291
|
}
|
|
990
1292
|
} else {
|
|
991
|
-
const result = (0, import_compiler.transformSourceCode)(code, id);
|
|
1293
|
+
const result = (0, import_compiler.transformSourceCode)(code, id, { astBudget: astBudgetOverride });
|
|
992
1294
|
transformedCode = result.code;
|
|
993
1295
|
usesRuntime = result.usesRuntime;
|
|
994
1296
|
usesMerge = result.usesMerge;
|
|
@@ -1053,6 +1355,11 @@ ${sourceDirective}`
|
|
|
1053
1355
|
transformed = true;
|
|
1054
1356
|
}
|
|
1055
1357
|
}
|
|
1358
|
+
if (/\.[tj]sx?(\?.*)?$/.test(id)) {
|
|
1359
|
+
assertNoRSCBoundaryViolation(transformedCode, id);
|
|
1360
|
+
const record = createRSCModuleRecord(transformedCode, id);
|
|
1361
|
+
state.rscModules.set(record.id, record);
|
|
1362
|
+
}
|
|
1056
1363
|
if (transformed || transformedCode.includes("class=") || transformedCode.includes("className=")) {
|
|
1057
1364
|
if (szClasses !== void 0) {
|
|
1058
1365
|
for (const cls of szClasses) {
|
|
@@ -1068,6 +1375,7 @@ ${sourceDirective}`
|
|
|
1068
1375
|
/** Finalizes the mangle map after all source modules have been processed. */
|
|
1069
1376
|
buildEnd() {
|
|
1070
1377
|
finalizeMangleMap();
|
|
1378
|
+
assertNoRSCGraphViolation(state.rscModules);
|
|
1071
1379
|
if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
|
|
1072
1380
|
globalThis.__csszyx_ssr_mangle_map = state.mangleMap;
|
|
1073
1381
|
}
|
|
@@ -1090,8 +1398,8 @@ ${sourceDirective}`
|
|
|
1090
1398
|
compiler.hooks.thisCompilation.tap("csszyx:theme-deps", (compilation) => {
|
|
1091
1399
|
const root = compiler.context || process.cwd();
|
|
1092
1400
|
for (const pattern of patterns) {
|
|
1093
|
-
const resolved =
|
|
1094
|
-
if (
|
|
1401
|
+
const resolved = path2.isAbsolute(pattern) ? pattern : path2.join(root, pattern);
|
|
1402
|
+
if (fs2.existsSync(resolved)) {
|
|
1095
1403
|
compilation.fileDependencies.add(resolved);
|
|
1096
1404
|
}
|
|
1097
1405
|
}
|
|
@@ -1121,14 +1429,14 @@ ${sourceDirective}`
|
|
|
1121
1429
|
const patterns = Array.isArray(scanCss) ? scanCss : [scanCss];
|
|
1122
1430
|
const root = ctx.server.config.root || process.cwd();
|
|
1123
1431
|
const isWatched = patterns.some((p) => {
|
|
1124
|
-
const resolved =
|
|
1432
|
+
const resolved = path2.isAbsolute(p) ? p : path2.join(root, p);
|
|
1125
1433
|
return ctx.file === resolved;
|
|
1126
1434
|
});
|
|
1127
1435
|
if (isWatched) {
|
|
1128
1436
|
runThemeScan(root, scanCss);
|
|
1129
1437
|
}
|
|
1130
1438
|
}
|
|
1131
|
-
if (!SOURCE_EXTENSIONS.has(
|
|
1439
|
+
if (!SOURCE_EXTENSIONS.has(path2.extname(ctx.file))) {
|
|
1132
1440
|
return;
|
|
1133
1441
|
}
|
|
1134
1442
|
if (ctx.file.includes("node_modules")) {
|
|
@@ -1136,7 +1444,7 @@ ${sourceDirective}`
|
|
|
1136
1444
|
}
|
|
1137
1445
|
let fileContent, result;
|
|
1138
1446
|
try {
|
|
1139
|
-
fileContent =
|
|
1447
|
+
fileContent = fs2.readFileSync(ctx.file, "utf-8");
|
|
1140
1448
|
} catch {
|
|
1141
1449
|
return;
|
|
1142
1450
|
}
|
|
@@ -1144,7 +1452,7 @@ ${sourceDirective}`
|
|
|
1144
1452
|
return;
|
|
1145
1453
|
}
|
|
1146
1454
|
try {
|
|
1147
|
-
result = (0, import_compiler.transformSourceCode)(fileContent, ctx.file);
|
|
1455
|
+
result = (0, import_compiler.transformSourceCode)(fileContent, ctx.file, { astBudget: astBudgetOverride });
|
|
1148
1456
|
} catch {
|
|
1149
1457
|
return;
|
|
1150
1458
|
}
|
|
@@ -1160,7 +1468,7 @@ ${sourceDirective}`
|
|
|
1160
1468
|
}
|
|
1161
1469
|
if (state.classes.size > sizeBefore) {
|
|
1162
1470
|
writeSafelistFile(state.classes);
|
|
1163
|
-
const safelistPath =
|
|
1471
|
+
const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME);
|
|
1164
1472
|
ctx.server.watcher.emit("change", safelistPath);
|
|
1165
1473
|
}
|
|
1166
1474
|
},
|
|
@@ -1182,7 +1490,10 @@ ${sourceDirective}`
|
|
|
1182
1490
|
const isProduction = process.env.NODE_ENV === "production";
|
|
1183
1491
|
const { manifest, strippedDevOnlyPaths } = buildRecoveryManifest(
|
|
1184
1492
|
state.recoveryTokens,
|
|
1185
|
-
{
|
|
1493
|
+
{
|
|
1494
|
+
production: isProduction,
|
|
1495
|
+
mangleChecksum: state.checksum
|
|
1496
|
+
}
|
|
1186
1497
|
);
|
|
1187
1498
|
if (strippedDevOnlyPaths.length > 0) {
|
|
1188
1499
|
console.warn(
|