@csszyx/unplugin 0.6.2 → 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-JGJOUK2R.js → chunk-GXGGTRUA.js} +351 -33
- package/dist/index.cjs +357 -31
- package/dist/index.d.cts +96 -1
- package/dist/index.d.ts +96 -1
- package/dist/index.js +17 -1
- package/dist/vite.cjs +341 -31
- package/dist/vite.js +1 -1
- package/dist/webpack.cjs +341 -31
- package/dist/webpack.js +1 -1
- package/package.json +6 -6
|
@@ -2,6 +2,303 @@ import {
|
|
|
2
2
|
mangleCSSSync
|
|
3
3
|
} from "./chunk-4M7CPGP7.js";
|
|
4
4
|
|
|
5
|
+
// src/rsc-boundary.ts
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
import * as path from "path";
|
|
8
|
+
var SERVER_DIRECTIVE_RE = /^['"]use server['"];?$/;
|
|
9
|
+
var CLIENT_DIRECTIVE_RE = /^['"]use client['"];?$/;
|
|
10
|
+
var RUNTIME_MODULES = /* @__PURE__ */ new Set([
|
|
11
|
+
"@csszyx/runtime",
|
|
12
|
+
"@csszyx/runtime/lite",
|
|
13
|
+
"csszyx",
|
|
14
|
+
"csszyx/lite"
|
|
15
|
+
]);
|
|
16
|
+
var FORBIDDEN_SYMBOLS = /* @__PURE__ */ new Set([
|
|
17
|
+
"_sz",
|
|
18
|
+
"_sz2",
|
|
19
|
+
"_sz3",
|
|
20
|
+
"_szIf",
|
|
21
|
+
"_szMerge",
|
|
22
|
+
"_szSwitch",
|
|
23
|
+
"__csszyx_runtime__"
|
|
24
|
+
]);
|
|
25
|
+
function hasUseServerDirective(code) {
|
|
26
|
+
for (const statement of readDirectivePrologue(code)) {
|
|
27
|
+
if (SERVER_DIRECTIVE_RE.test(statement)) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
if (CLIENT_DIRECTIVE_RE.test(statement)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
function hasUseClientDirective(code) {
|
|
37
|
+
for (const statement of readDirectivePrologue(code)) {
|
|
38
|
+
if (CLIENT_DIRECTIVE_RE.test(statement)) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (SERVER_DIRECTIVE_RE.test(statement)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
function isRSCServerModule(code, id) {
|
|
48
|
+
if (hasUseServerDirective(code)) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
if (hasUseClientDirective(code)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return isNextAppRouterEntry(id);
|
|
55
|
+
}
|
|
56
|
+
function findRSCBoundaryViolation(code, id) {
|
|
57
|
+
if (!isRSCServerModule(code, id)) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
for (const imported of findRuntimeImports(code)) {
|
|
61
|
+
for (const symbol of imported.symbols) {
|
|
62
|
+
if (FORBIDDEN_SYMBOLS.has(symbol)) {
|
|
63
|
+
return {
|
|
64
|
+
symbol,
|
|
65
|
+
path: id,
|
|
66
|
+
importChain: [id, imported.source]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
function createRSCModuleRecord(code, id) {
|
|
74
|
+
const normalized = normalizeModuleId(id);
|
|
75
|
+
return {
|
|
76
|
+
id: normalized,
|
|
77
|
+
isServer: isRSCServerModule(code, normalized),
|
|
78
|
+
isClient: hasUseClientDirective(code),
|
|
79
|
+
imports: findLocalImportSources(code).map((source) => resolveLocalModule(normalized, source)).filter((resolved) => resolved !== null),
|
|
80
|
+
runtimeImports: findRuntimeImports(code).filter((imported) => imported.symbols.some((symbol) => FORBIDDEN_SYMBOLS.has(symbol)))
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function findRSCGraphViolation(records) {
|
|
84
|
+
for (const root of records.values()) {
|
|
85
|
+
if (!root.isServer) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const violation = walkRSCGraph(root, records, [root.id], /* @__PURE__ */ new Set([root.id]));
|
|
89
|
+
if (violation) {
|
|
90
|
+
return {
|
|
91
|
+
symbol: violation.symbol,
|
|
92
|
+
path: root.id,
|
|
93
|
+
importChain: violation.importChain
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
function assertNoRSCGraphViolation(records) {
|
|
100
|
+
const violation = findRSCGraphViolation(records);
|
|
101
|
+
if (!violation) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
throw new Error(formatRSCViolation(violation));
|
|
105
|
+
}
|
|
106
|
+
function isNextAppRouterEntry(id) {
|
|
107
|
+
const clean = id.split("?")[0]?.replace(/\\/g, "/") ?? id;
|
|
108
|
+
return /(^|\/)app\/.*\/?(?:page|layout|template|loading|error|not-found|global-error|default|route)\.[cm]?[tj]sx?$/.test(clean);
|
|
109
|
+
}
|
|
110
|
+
function assertNoRSCBoundaryViolation(code, id) {
|
|
111
|
+
const violation = findRSCBoundaryViolation(code, id);
|
|
112
|
+
if (!violation) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
throw new Error(formatRSCViolation(violation));
|
|
116
|
+
}
|
|
117
|
+
function formatRSCViolation(violation) {
|
|
118
|
+
return `csszyxRSCViolation: ${violation.symbol} imported in Server Component ${violation.path}
|
|
119
|
+
Import chain: ${violation.importChain.join(" -> ")}`;
|
|
120
|
+
}
|
|
121
|
+
function walkRSCGraph(current, records, chain, seen) {
|
|
122
|
+
if (current.isClient) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
const runtime = current.runtimeImports[0];
|
|
126
|
+
const symbol = runtime?.symbols.find((s) => FORBIDDEN_SYMBOLS.has(s));
|
|
127
|
+
if (runtime && symbol) {
|
|
128
|
+
return {
|
|
129
|
+
symbol,
|
|
130
|
+
path: chain[0] ?? current.id,
|
|
131
|
+
importChain: [...chain, runtime.source]
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
for (const importedId of current.imports) {
|
|
135
|
+
if (seen.has(importedId)) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const next = records.get(importedId);
|
|
139
|
+
if (!next) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
seen.add(importedId);
|
|
143
|
+
const violation = walkRSCGraph(next, records, [...chain, importedId], seen);
|
|
144
|
+
if (violation) {
|
|
145
|
+
return violation;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
function readDirectivePrologue(code) {
|
|
151
|
+
const out = [];
|
|
152
|
+
let i = code.charCodeAt(0) === 65279 ? 1 : 0;
|
|
153
|
+
while (i < code.length) {
|
|
154
|
+
i = skipWhitespaceAndComments(code, i);
|
|
155
|
+
const quote = code[i];
|
|
156
|
+
if (quote !== '"' && quote !== "'") {
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
let j = i + 1;
|
|
160
|
+
let escaped = false;
|
|
161
|
+
while (j < code.length) {
|
|
162
|
+
const ch = code[j];
|
|
163
|
+
if (escaped) {
|
|
164
|
+
escaped = false;
|
|
165
|
+
} else if (ch === "\\") {
|
|
166
|
+
escaped = true;
|
|
167
|
+
} else if (ch === quote) {
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
j++;
|
|
171
|
+
}
|
|
172
|
+
if (j >= code.length) {
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
let end = j + 1;
|
|
176
|
+
while (end < code.length && /[ \t\r\n]/.test(code[end])) {
|
|
177
|
+
end++;
|
|
178
|
+
}
|
|
179
|
+
if (code[end] === ";") {
|
|
180
|
+
end++;
|
|
181
|
+
}
|
|
182
|
+
out.push(code.slice(i, end).trim());
|
|
183
|
+
i = end;
|
|
184
|
+
}
|
|
185
|
+
return out;
|
|
186
|
+
}
|
|
187
|
+
function skipWhitespaceAndComments(code, start) {
|
|
188
|
+
let i = start;
|
|
189
|
+
while (i < code.length) {
|
|
190
|
+
while (i < code.length && /\s/.test(code[i])) {
|
|
191
|
+
i++;
|
|
192
|
+
}
|
|
193
|
+
if (code.startsWith("//", i)) {
|
|
194
|
+
const next = code.indexOf("\n", i + 2);
|
|
195
|
+
i = next === -1 ? code.length : next + 1;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (code.startsWith("/*", i)) {
|
|
199
|
+
const next = code.indexOf("*/", i + 2);
|
|
200
|
+
i = next === -1 ? code.length : next + 2;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
return i;
|
|
206
|
+
}
|
|
207
|
+
function findRuntimeImports(code) {
|
|
208
|
+
const imports = [];
|
|
209
|
+
const staticImportRe = /import\s+(?!type\b)([\s\S]*?)\s+from\s+['"]([^'"]+)['"]/g;
|
|
210
|
+
const sideEffectImportRe = /import\s+['"]([^'"]+)['"]/g;
|
|
211
|
+
const dynamicImportRe = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
212
|
+
let match;
|
|
213
|
+
while ((match = staticImportRe.exec(code)) !== null) {
|
|
214
|
+
const clause = match[1];
|
|
215
|
+
const source = match[2];
|
|
216
|
+
if (!RUNTIME_MODULES.has(source)) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
imports.push({ source, symbols: readImportedSymbols(clause) });
|
|
220
|
+
}
|
|
221
|
+
while ((match = sideEffectImportRe.exec(code)) !== null) {
|
|
222
|
+
const source = match[1];
|
|
223
|
+
if (RUNTIME_MODULES.has(source)) {
|
|
224
|
+
imports.push({ source, symbols: [] });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
while ((match = dynamicImportRe.exec(code)) !== null) {
|
|
228
|
+
const source = match[1];
|
|
229
|
+
if (RUNTIME_MODULES.has(source)) {
|
|
230
|
+
imports.push({ source, symbols: Array.from(FORBIDDEN_SYMBOLS) });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return imports;
|
|
234
|
+
}
|
|
235
|
+
function findLocalImportSources(code) {
|
|
236
|
+
const out = [];
|
|
237
|
+
const staticImportRe = /import\s+(?!type\b)(?:[\s\S]*?\s+from\s+)?['"]([^'"]+)['"]/g;
|
|
238
|
+
const exportFromRe = /export\s+(?!type\b)(?:[\s\S]*?)\s+from\s+['"]([^'"]+)['"]/g;
|
|
239
|
+
const dynamicImportRe = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
240
|
+
let match;
|
|
241
|
+
for (const re of [staticImportRe, exportFromRe, dynamicImportRe]) {
|
|
242
|
+
while ((match = re.exec(code)) !== null) {
|
|
243
|
+
const source = match[1];
|
|
244
|
+
if (source.startsWith(".") || source.startsWith("/")) {
|
|
245
|
+
out.push(source);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return out;
|
|
250
|
+
}
|
|
251
|
+
function normalizeModuleId(id) {
|
|
252
|
+
const clean = id.split("?")[0] ?? id;
|
|
253
|
+
try {
|
|
254
|
+
return fs.realpathSync.native(clean).replace(/\\/g, "/");
|
|
255
|
+
} catch {
|
|
256
|
+
return path.resolve(clean).replace(/\\/g, "/");
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function resolveLocalModule(importer, source) {
|
|
260
|
+
const base = source.startsWith("/") ? source : path.resolve(path.dirname(importer), source);
|
|
261
|
+
const candidates = [
|
|
262
|
+
base,
|
|
263
|
+
`${base}.tsx`,
|
|
264
|
+
`${base}.ts`,
|
|
265
|
+
`${base}.jsx`,
|
|
266
|
+
`${base}.js`,
|
|
267
|
+
`${base}.mjs`,
|
|
268
|
+
`${base}.cjs`,
|
|
269
|
+
path.join(base, "index.tsx"),
|
|
270
|
+
path.join(base, "index.ts"),
|
|
271
|
+
path.join(base, "index.jsx"),
|
|
272
|
+
path.join(base, "index.js")
|
|
273
|
+
];
|
|
274
|
+
for (const candidate of candidates) {
|
|
275
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
|
|
276
|
+
return normalizeModuleId(candidate);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
function readImportedSymbols(clause) {
|
|
282
|
+
const symbols = [];
|
|
283
|
+
const named = clause.match(/\{([\s\S]*?)\}/);
|
|
284
|
+
if (named) {
|
|
285
|
+
for (const part of named[1].split(",")) {
|
|
286
|
+
const trimmed = part.trim();
|
|
287
|
+
if (!trimmed || trimmed.startsWith("type ")) {
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const sourceName = trimmed.replace(/^type\s+/, "").split(/\s+as\s+/)[0]?.trim();
|
|
291
|
+
if (sourceName) {
|
|
292
|
+
symbols.push(sourceName);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (/\*\s+as\s+\w+/.test(clause)) {
|
|
297
|
+
symbols.push(...FORBIDDEN_SYMBOLS);
|
|
298
|
+
}
|
|
299
|
+
return symbols;
|
|
300
|
+
}
|
|
301
|
+
|
|
5
302
|
// src/theme-scanner.ts
|
|
6
303
|
var EMPTY_THEME = { colors: [], spacings: [], fonts: [], radii: [], shadows: [] };
|
|
7
304
|
function stripLayerWrappers(css) {
|
|
@@ -145,8 +442,8 @@ function hasTokens(theme) {
|
|
|
145
442
|
}
|
|
146
443
|
|
|
147
444
|
// src/unplugin.ts
|
|
148
|
-
import * as
|
|
149
|
-
import * as
|
|
445
|
+
import * as fs2 from "fs";
|
|
446
|
+
import * as path2 from "path";
|
|
150
447
|
import { transform, transformSourceCode } from "@csszyx/compiler";
|
|
151
448
|
import { compute_mangle_checksum, encode } from "@csszyx/core";
|
|
152
449
|
import { preprocess as sveltePreprocess } from "@csszyx/svelte-adapter";
|
|
@@ -214,7 +511,7 @@ function injectHydrationData(html, mangleMap, checksum, options = {}) {
|
|
|
214
511
|
function transformIndexHtml(html, mangleMap, checksum, options = {}) {
|
|
215
512
|
return injectHydrationData(html, mangleMap, checksum, options);
|
|
216
513
|
}
|
|
217
|
-
function buildRecoveryManifest(tokens, options
|
|
514
|
+
function buildRecoveryManifest(tokens, options) {
|
|
218
515
|
const stripped = options.production === true;
|
|
219
516
|
const strippedDevOnlyPaths = [];
|
|
220
517
|
const sorted = {};
|
|
@@ -235,7 +532,7 @@ function buildRecoveryManifest(tokens, options = {}) {
|
|
|
235
532
|
const checksum = fullChecksum.substring(0, 16);
|
|
236
533
|
const buildId = `${Date.now().toString(36)}-${fullChecksum.substring(0, 6)}`;
|
|
237
534
|
return {
|
|
238
|
-
manifest: { buildId, checksum, tokens: sorted },
|
|
535
|
+
manifest: { buildId, checksum, mangleChecksum: options.mangleChecksum, tokens: sorted },
|
|
239
536
|
strippedDevOnlyPaths
|
|
240
537
|
};
|
|
241
538
|
}
|
|
@@ -257,7 +554,7 @@ function injectRecoveryManifest(html, manifest) {
|
|
|
257
554
|
|
|
258
555
|
// src/theme-type-writer.ts
|
|
259
556
|
import { mkdirSync, writeFileSync } from "fs";
|
|
260
|
-
import { dirname } from "path";
|
|
557
|
+
import { dirname as dirname2 } from "path";
|
|
261
558
|
function generateThemeDts(opts) {
|
|
262
559
|
const { theme, sourceFiles } = opts;
|
|
263
560
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -300,7 +597,7 @@ function generateThemeDts(opts) {
|
|
|
300
597
|
}
|
|
301
598
|
function writeThemeDts(opts) {
|
|
302
599
|
const content = generateThemeDts(opts);
|
|
303
|
-
mkdirSync(
|
|
600
|
+
mkdirSync(dirname2(opts.outputPath), { recursive: true });
|
|
304
601
|
writeFileSync(opts.outputPath, content, "utf-8");
|
|
305
602
|
}
|
|
306
603
|
|
|
@@ -364,8 +661,8 @@ function runThemeScan(rootDir, scanCss) {
|
|
|
364
661
|
const patterns = Array.isArray(scanCss) ? scanCss : [scanCss];
|
|
365
662
|
const sourceFiles = [];
|
|
366
663
|
for (const pattern of patterns) {
|
|
367
|
-
const resolved =
|
|
368
|
-
if (
|
|
664
|
+
const resolved = path2.isAbsolute(pattern) ? pattern : path2.join(rootDir, pattern);
|
|
665
|
+
if (fs2.existsSync(resolved)) {
|
|
369
666
|
sourceFiles.push(resolved);
|
|
370
667
|
}
|
|
371
668
|
}
|
|
@@ -374,20 +671,20 @@ function runThemeScan(rootDir, scanCss) {
|
|
|
374
671
|
}
|
|
375
672
|
const themes = sourceFiles.map((f) => {
|
|
376
673
|
try {
|
|
377
|
-
return parseThemeBlocks(
|
|
674
|
+
return parseThemeBlocks(fs2.readFileSync(f, "utf-8"));
|
|
378
675
|
} catch {
|
|
379
676
|
return null;
|
|
380
677
|
}
|
|
381
678
|
}).filter((t) => t !== null);
|
|
382
679
|
const merged = mergeThemes(themes);
|
|
383
|
-
const outputPath =
|
|
680
|
+
const outputPath = path2.join(rootDir, ".csszyx", "theme.d.ts");
|
|
384
681
|
writeThemeDts({ outputPath, theme: merged, sourceFiles });
|
|
385
682
|
if (!_hasWarnedTsConfig) {
|
|
386
683
|
_hasWarnedTsConfig = true;
|
|
387
684
|
try {
|
|
388
685
|
const checkFile = (cfgPath) => {
|
|
389
|
-
if (
|
|
390
|
-
const content =
|
|
686
|
+
if (fs2.existsSync(cfgPath)) {
|
|
687
|
+
const content = fs2.readFileSync(cfgPath, "utf-8");
|
|
391
688
|
if (!content.includes(".csszyx")) {
|
|
392
689
|
console.warn(`
|
|
393
690
|
\x1B[33m\u26A0\uFE0F CSSzyx: Theme Auto-Scan enabled, but TypeScript isn't configured. Run "npx @csszyx/cli init" to fix.\x1B[0m
|
|
@@ -397,8 +694,8 @@ function runThemeScan(rootDir, scanCss) {
|
|
|
397
694
|
}
|
|
398
695
|
return false;
|
|
399
696
|
};
|
|
400
|
-
if (!checkFile(
|
|
401
|
-
checkFile(
|
|
697
|
+
if (!checkFile(path2.join(rootDir, "tsconfig.json"))) {
|
|
698
|
+
checkFile(path2.join(rootDir, "tsconfig.app.json"));
|
|
402
699
|
}
|
|
403
700
|
} catch {
|
|
404
701
|
}
|
|
@@ -585,7 +882,8 @@ function createCsszyxPlugins(options = {}) {
|
|
|
585
882
|
checksum: "",
|
|
586
883
|
finalized: false,
|
|
587
884
|
rootDir: process.cwd(),
|
|
588
|
-
recoveryTokens: /* @__PURE__ */ new Map()
|
|
885
|
+
recoveryTokens: /* @__PURE__ */ new Map(),
|
|
886
|
+
rscModules: /* @__PURE__ */ new Map()
|
|
589
887
|
};
|
|
590
888
|
const SAFELIST_FILENAME = "csszyx-classes.html";
|
|
591
889
|
const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".tsx", ".jsx", ".ts", ".js"]);
|
|
@@ -594,16 +892,16 @@ function createCsszyxPlugins(options = {}) {
|
|
|
594
892
|
if (classes.size === 0) {
|
|
595
893
|
return;
|
|
596
894
|
}
|
|
597
|
-
const safelistPath =
|
|
895
|
+
const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME);
|
|
598
896
|
const classList = Array.from(classes).join(" ");
|
|
599
897
|
const content = `<!-- Auto-generated by csszyx \u2014 DO NOT EDIT -->
|
|
600
898
|
<!-- Tailwind CSS scans this file for class name detection -->
|
|
601
899
|
<div class="${classList}"><div class="${classList}">x</div><div class="${classList}">x</div></div>
|
|
602
900
|
`;
|
|
603
901
|
try {
|
|
604
|
-
const existing =
|
|
902
|
+
const existing = fs2.existsSync(safelistPath) ? fs2.readFileSync(safelistPath, "utf-8") : "";
|
|
605
903
|
if (existing !== content) {
|
|
606
|
-
|
|
904
|
+
fs2.writeFileSync(safelistPath, content);
|
|
607
905
|
}
|
|
608
906
|
} catch {
|
|
609
907
|
}
|
|
@@ -614,19 +912,19 @@ function createCsszyxPlugins(options = {}) {
|
|
|
614
912
|
function scanDir(dir) {
|
|
615
913
|
let entries;
|
|
616
914
|
try {
|
|
617
|
-
entries =
|
|
915
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
618
916
|
} catch {
|
|
619
917
|
return;
|
|
620
918
|
}
|
|
621
919
|
for (const entry of entries) {
|
|
622
920
|
if (entry.isDirectory()) {
|
|
623
921
|
if (!IGNORE_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
|
|
624
|
-
scanDir(
|
|
922
|
+
scanDir(path2.join(dir, entry.name));
|
|
625
923
|
}
|
|
626
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
627
|
-
const filePath =
|
|
924
|
+
} else if (SOURCE_EXTENSIONS.has(path2.extname(entry.name))) {
|
|
925
|
+
const filePath = path2.join(dir, entry.name);
|
|
628
926
|
try {
|
|
629
|
-
const content =
|
|
927
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
630
928
|
if (!content.includes("sz=") && !content.includes("sz:")) {
|
|
631
929
|
continue;
|
|
632
930
|
}
|
|
@@ -818,14 +1116,17 @@ function createCsszyxPlugins(options = {}) {
|
|
|
818
1116
|
* @returns transformed code with source map, or null if no changes were made
|
|
819
1117
|
*/
|
|
820
1118
|
transform(code, id) {
|
|
1119
|
+
if (/\.[tj]sx?(\?.*)?$/.test(id)) {
|
|
1120
|
+
assertNoRSCBoundaryViolation(code, id);
|
|
1121
|
+
}
|
|
821
1122
|
if (/\.css(\?.*)?$/.test(id)) {
|
|
822
1123
|
const hasTailwindImport = code.includes('@import "tailwindcss') || code.includes("@import 'tailwindcss");
|
|
823
1124
|
if (hasTailwindImport && state.classes.size > 0) {
|
|
824
1125
|
const candidates = Array.from(state.classes).filter((c) => c.length >= 2 && /^[a-z]/.test(c)).join(" ");
|
|
825
1126
|
if (candidates) {
|
|
826
|
-
const safelistPath =
|
|
827
|
-
const cssDir =
|
|
828
|
-
let relPath =
|
|
1127
|
+
const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME).replace(/\\/g, "/");
|
|
1128
|
+
const cssDir = path2.dirname(id).replace(/\\/g, "/");
|
|
1129
|
+
let relPath = path2.posix.relative(cssDir, safelistPath);
|
|
829
1130
|
if (!relPath.startsWith(".")) {
|
|
830
1131
|
relPath = "./" + relPath;
|
|
831
1132
|
}
|
|
@@ -929,6 +1230,11 @@ ${sourceDirective}`
|
|
|
929
1230
|
transformed = true;
|
|
930
1231
|
}
|
|
931
1232
|
}
|
|
1233
|
+
if (/\.[tj]sx?(\?.*)?$/.test(id)) {
|
|
1234
|
+
assertNoRSCBoundaryViolation(transformedCode, id);
|
|
1235
|
+
const record = createRSCModuleRecord(transformedCode, id);
|
|
1236
|
+
state.rscModules.set(record.id, record);
|
|
1237
|
+
}
|
|
932
1238
|
if (transformed || transformedCode.includes("class=") || transformedCode.includes("className=")) {
|
|
933
1239
|
if (szClasses !== void 0) {
|
|
934
1240
|
for (const cls of szClasses) {
|
|
@@ -944,6 +1250,7 @@ ${sourceDirective}`
|
|
|
944
1250
|
/** Finalizes the mangle map after all source modules have been processed. */
|
|
945
1251
|
buildEnd() {
|
|
946
1252
|
finalizeMangleMap();
|
|
1253
|
+
assertNoRSCGraphViolation(state.rscModules);
|
|
947
1254
|
if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
|
|
948
1255
|
globalThis.__csszyx_ssr_mangle_map = state.mangleMap;
|
|
949
1256
|
}
|
|
@@ -966,8 +1273,8 @@ ${sourceDirective}`
|
|
|
966
1273
|
compiler.hooks.thisCompilation.tap("csszyx:theme-deps", (compilation) => {
|
|
967
1274
|
const root = compiler.context || process.cwd();
|
|
968
1275
|
for (const pattern of patterns) {
|
|
969
|
-
const resolved =
|
|
970
|
-
if (
|
|
1276
|
+
const resolved = path2.isAbsolute(pattern) ? pattern : path2.join(root, pattern);
|
|
1277
|
+
if (fs2.existsSync(resolved)) {
|
|
971
1278
|
compilation.fileDependencies.add(resolved);
|
|
972
1279
|
}
|
|
973
1280
|
}
|
|
@@ -997,14 +1304,14 @@ ${sourceDirective}`
|
|
|
997
1304
|
const patterns = Array.isArray(scanCss) ? scanCss : [scanCss];
|
|
998
1305
|
const root = ctx.server.config.root || process.cwd();
|
|
999
1306
|
const isWatched = patterns.some((p) => {
|
|
1000
|
-
const resolved =
|
|
1307
|
+
const resolved = path2.isAbsolute(p) ? p : path2.join(root, p);
|
|
1001
1308
|
return ctx.file === resolved;
|
|
1002
1309
|
});
|
|
1003
1310
|
if (isWatched) {
|
|
1004
1311
|
runThemeScan(root, scanCss);
|
|
1005
1312
|
}
|
|
1006
1313
|
}
|
|
1007
|
-
if (!SOURCE_EXTENSIONS.has(
|
|
1314
|
+
if (!SOURCE_EXTENSIONS.has(path2.extname(ctx.file))) {
|
|
1008
1315
|
return;
|
|
1009
1316
|
}
|
|
1010
1317
|
if (ctx.file.includes("node_modules")) {
|
|
@@ -1012,7 +1319,7 @@ ${sourceDirective}`
|
|
|
1012
1319
|
}
|
|
1013
1320
|
let fileContent, result;
|
|
1014
1321
|
try {
|
|
1015
|
-
fileContent =
|
|
1322
|
+
fileContent = fs2.readFileSync(ctx.file, "utf-8");
|
|
1016
1323
|
} catch {
|
|
1017
1324
|
return;
|
|
1018
1325
|
}
|
|
@@ -1036,7 +1343,7 @@ ${sourceDirective}`
|
|
|
1036
1343
|
}
|
|
1037
1344
|
if (state.classes.size > sizeBefore) {
|
|
1038
1345
|
writeSafelistFile(state.classes);
|
|
1039
|
-
const safelistPath =
|
|
1346
|
+
const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME);
|
|
1040
1347
|
ctx.server.watcher.emit("change", safelistPath);
|
|
1041
1348
|
}
|
|
1042
1349
|
},
|
|
@@ -1058,7 +1365,10 @@ ${sourceDirective}`
|
|
|
1058
1365
|
const isProduction = process.env.NODE_ENV === "production";
|
|
1059
1366
|
const { manifest, strippedDevOnlyPaths } = buildRecoveryManifest(
|
|
1060
1367
|
state.recoveryTokens,
|
|
1061
|
-
{
|
|
1368
|
+
{
|
|
1369
|
+
production: isProduction,
|
|
1370
|
+
mangleChecksum: state.checksum
|
|
1371
|
+
}
|
|
1062
1372
|
);
|
|
1063
1373
|
if (strippedDevOnlyPaths.length > 0) {
|
|
1064
1374
|
console.warn(
|
|
@@ -1272,6 +1582,14 @@ var esbuildPlugin = (options = {}) => {
|
|
|
1272
1582
|
};
|
|
1273
1583
|
|
|
1274
1584
|
export {
|
|
1585
|
+
hasUseServerDirective,
|
|
1586
|
+
hasUseClientDirective,
|
|
1587
|
+
isRSCServerModule,
|
|
1588
|
+
findRSCBoundaryViolation,
|
|
1589
|
+
createRSCModuleRecord,
|
|
1590
|
+
findRSCGraphViolation,
|
|
1591
|
+
assertNoRSCGraphViolation,
|
|
1592
|
+
assertNoRSCBoundaryViolation,
|
|
1275
1593
|
parseThemeBlocks,
|
|
1276
1594
|
mergeThemes,
|
|
1277
1595
|
hasTokens,
|