@csszyx/unplugin 0.11.6 → 0.11.8
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 +6 -1
- package/dist/css-mangler.cjs +44 -41
- package/dist/css-mangler.mjs +44 -41
- package/dist/index.cjs +5 -4
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +4 -4
- package/dist/next-config.cjs +1 -1
- package/dist/next-config.mjs +1 -1
- package/dist/next-prebuild.cjs +5 -5
- package/dist/next-prebuild.mjs +5 -5
- package/dist/next-turbo-loader.cjs +13 -12
- package/dist/next-turbo-loader.mjs +13 -12
- package/dist/next-watcher.cjs +2 -2
- package/dist/next-watcher.mjs +2 -2
- package/dist/shared/{unplugin.BFN_Ueyx.cjs → unplugin.C9dMG7ye.cjs} +7 -5
- package/dist/shared/{unplugin.PhOFTQpB.d.cts → unplugin.CNwV3RrQ.d.cts} +18 -5
- package/dist/shared/{unplugin.PhOFTQpB.d.mts → unplugin.CNwV3RrQ.d.mts} +18 -5
- package/dist/shared/unplugin.CcA7jP1r.cjs +48 -0
- package/dist/shared/{unplugin.ByzV6iZE.mjs → unplugin.D-K57LNR.mjs} +13 -7
- package/dist/shared/{unplugin.D0N9bprz.cjs → unplugin.DVCQC5wq.cjs} +12 -5
- package/dist/shared/{unplugin.CBKZoxQ1.cjs → unplugin.DdtOZANG.cjs} +51 -50
- package/dist/shared/{unplugin.ChwZMl_w.mjs → unplugin.Dg1tGPSd.mjs} +8 -6
- package/dist/shared/{unplugin.Rov-j_Wm.cjs → unplugin.DmuOKVS4.cjs} +21 -0
- package/dist/shared/{unplugin.CP2cz9bA.cjs → unplugin.DtPQz8Kg.cjs} +1291 -938
- package/dist/shared/{unplugin.BS60onPk.mjs → unplugin.DtYxS8M8.mjs} +1290 -938
- package/dist/shared/{unplugin.B3cvNxnk.mjs → unplugin.Rl8sIkHi.mjs} +51 -50
- package/dist/shared/unplugin.TtmP77BS.mjs +40 -0
- package/dist/shared/unplugin.nnsa7OVW.mjs +49 -0
- package/dist/vite.cjs +4 -4
- package/dist/vite.d.cts +2 -25
- package/dist/vite.d.mts +1 -25
- package/dist/vite.mjs +4 -8
- package/dist/webpack.cjs +4 -4
- package/dist/webpack.d.cts +2 -5
- package/dist/webpack.d.mts +1 -5
- package/dist/webpack.mjs +4 -8
- package/package.json +7 -7
- package/dist/shared/unplugin.B1mblcm-.mjs +0 -9
- package/dist/shared/unplugin.B3RHYokB.mjs +0 -29
- package/dist/shared/unplugin.BCwRIUs_.cjs +0 -12
|
@@ -14,9 +14,9 @@ const types = require('@csszyx/types');
|
|
|
14
14
|
const vueAdapter = require('@csszyx/vue-adapter');
|
|
15
15
|
const unplugin$1 = require('unplugin');
|
|
16
16
|
const cssMangler = require('../css-mangler.cjs');
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
17
|
+
const runtimeImportScan = require('./unplugin.DmuOKVS4.cjs');
|
|
18
|
+
const transformCache = require('./unplugin.DVCQC5wq.cjs');
|
|
19
|
+
const htmlEscape = require('./unplugin.CcA7jP1r.cjs');
|
|
20
20
|
const postcss = require('postcss');
|
|
21
21
|
const valueParser = require('postcss-value-parser');
|
|
22
22
|
|
|
@@ -116,7 +116,8 @@ function buildScopeId(node) {
|
|
|
116
116
|
}
|
|
117
117
|
current = current.parent;
|
|
118
118
|
}
|
|
119
|
-
|
|
119
|
+
parts.reverse();
|
|
120
|
+
return parts.join(" > ") || DEFAULT_SCOPE_ID;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
const VAR_REFERENCE_RE = /var\(\s*(--[\w-]+)/g;
|
|
@@ -389,7 +390,7 @@ function rewriteGlobalVarValue(value, aliases) {
|
|
|
389
390
|
return;
|
|
390
391
|
}
|
|
391
392
|
const firstArgument = node.nodes.find((child) => child.type !== "space");
|
|
392
|
-
if (
|
|
393
|
+
if (firstArgument?.type !== "word") {
|
|
393
394
|
return;
|
|
394
395
|
}
|
|
395
396
|
const alias = aliases.get(firstArgument.value);
|
|
@@ -539,8 +540,8 @@ function createRSCModuleRecord(code, id) {
|
|
|
539
540
|
}
|
|
540
541
|
function deleteRSCModuleRecord(records, id) {
|
|
541
542
|
const normalized = normalizeModuleId(id);
|
|
542
|
-
const clean = id.split("?")[0]
|
|
543
|
-
const resolved = path__namespace.resolve(clean)
|
|
543
|
+
const clean = transformCache.normalizePathSeparators(id.split("?")[0] ?? id);
|
|
544
|
+
const resolved = transformCache.normalizePathSeparators(path__namespace.resolve(clean));
|
|
544
545
|
pruneRSCModulePathCaches(/* @__PURE__ */ new Set([normalized, resolved, clean]));
|
|
545
546
|
let deleted = records.delete(normalized);
|
|
546
547
|
if (resolved !== normalized) {
|
|
@@ -586,7 +587,7 @@ const APP_ROUTER_ENTRIES = /* @__PURE__ */ new Set([
|
|
|
586
587
|
"route"
|
|
587
588
|
]);
|
|
588
589
|
function isNextAppRouterEntry(id) {
|
|
589
|
-
const clean = id.split("?")[0]
|
|
590
|
+
const clean = transformCache.normalizePathSeparators(id.split("?")[0] ?? id);
|
|
590
591
|
if (!clean.includes("/app/") && !clean.startsWith("app/")) return false;
|
|
591
592
|
const basename = clean.split("/").pop() ?? "";
|
|
592
593
|
const dotIdx = basename.indexOf(".");
|
|
@@ -635,38 +636,41 @@ function walkRSCGraph(current, records, chain, seen) {
|
|
|
635
636
|
}
|
|
636
637
|
return null;
|
|
637
638
|
}
|
|
639
|
+
function findDirectiveQuoteEnd(code, start, quote) {
|
|
640
|
+
let escaped = false;
|
|
641
|
+
for (let index = start + 1; index < code.length; index++) {
|
|
642
|
+
const char = code[index];
|
|
643
|
+
if (escaped) {
|
|
644
|
+
escaped = false;
|
|
645
|
+
} else if (char === "\\") {
|
|
646
|
+
escaped = true;
|
|
647
|
+
} else if (char === quote) {
|
|
648
|
+
return index;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return -1;
|
|
652
|
+
}
|
|
653
|
+
function findDirectiveStatementEnd(code, start) {
|
|
654
|
+
let end = start;
|
|
655
|
+
while (end < code.length && /[ \t\r\n]/.test(code[end])) {
|
|
656
|
+
end++;
|
|
657
|
+
}
|
|
658
|
+
return code[end] === ";" ? end + 1 : end;
|
|
659
|
+
}
|
|
638
660
|
function readDirectivePrologue(code) {
|
|
639
661
|
const out = [];
|
|
640
|
-
let i = code
|
|
662
|
+
let i = readCodePoint(code, 0) === 65279 ? 1 : 0;
|
|
641
663
|
while (i < code.length) {
|
|
642
664
|
i = skipWhitespaceAndComments(code, i);
|
|
643
665
|
const quote = code[i];
|
|
644
666
|
if (quote !== '"' && quote !== "'") {
|
|
645
667
|
break;
|
|
646
668
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
while (j < code.length) {
|
|
650
|
-
const ch = code[j];
|
|
651
|
-
if (escaped) {
|
|
652
|
-
escaped = false;
|
|
653
|
-
} else if (ch === "\\") {
|
|
654
|
-
escaped = true;
|
|
655
|
-
} else if (ch === quote) {
|
|
656
|
-
break;
|
|
657
|
-
}
|
|
658
|
-
j++;
|
|
659
|
-
}
|
|
660
|
-
if (j >= code.length) {
|
|
669
|
+
const quoteEnd = findDirectiveQuoteEnd(code, i, quote);
|
|
670
|
+
if (quoteEnd === -1) {
|
|
661
671
|
break;
|
|
662
672
|
}
|
|
663
|
-
|
|
664
|
-
while (end < code.length && /[ \t\r\n]/.test(code[end])) {
|
|
665
|
-
end++;
|
|
666
|
-
}
|
|
667
|
-
if (code[end] === ";") {
|
|
668
|
-
end++;
|
|
669
|
-
}
|
|
673
|
+
const end = findDirectiveStatementEnd(code, quoteEnd + 1);
|
|
670
674
|
out.push(code.slice(i, end).trim());
|
|
671
675
|
i = end;
|
|
672
676
|
}
|
|
@@ -722,55 +726,50 @@ function findStaticImports(code) {
|
|
|
722
726
|
let cursor = 0;
|
|
723
727
|
while (cursor < code.length) {
|
|
724
728
|
const importStart = code.indexOf("import", cursor);
|
|
725
|
-
if (importStart === -1)
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
if (importStart > 0 && isIdentifierPart(code.charCodeAt(importStart - 1)) || isIdentifierPart(code.charCodeAt(cursor))) {
|
|
730
|
-
continue;
|
|
731
|
-
}
|
|
732
|
-
let position = skipAsciiWhitespace(code, cursor);
|
|
733
|
-
const opener = code.charAt(position);
|
|
734
|
-
if (opener === "(") {
|
|
735
|
-
continue;
|
|
736
|
-
}
|
|
737
|
-
if (opener === '"' || opener === "'") {
|
|
738
|
-
const literal2 = readQuotedString(code, position);
|
|
739
|
-
if (literal2) {
|
|
740
|
-
imports.push({ clause: null, source: literal2.value });
|
|
741
|
-
cursor = literal2.end;
|
|
742
|
-
}
|
|
743
|
-
continue;
|
|
744
|
-
}
|
|
745
|
-
const clauseStart = position;
|
|
746
|
-
let fromStart = -1;
|
|
747
|
-
while (position < code.length) {
|
|
748
|
-
if (code.startsWith("from", position) && (position === clauseStart || !isIdentifierPart(code.charCodeAt(position - 1))) && !isIdentifierPart(code.charCodeAt(position + 4))) {
|
|
749
|
-
fromStart = position;
|
|
750
|
-
break;
|
|
751
|
-
}
|
|
752
|
-
if (code.charAt(position) === ";") {
|
|
753
|
-
break;
|
|
754
|
-
}
|
|
755
|
-
position += 1;
|
|
756
|
-
}
|
|
757
|
-
if (fromStart === -1) {
|
|
758
|
-
continue;
|
|
759
|
-
}
|
|
760
|
-
const clause = code.slice(clauseStart, fromStart).trim();
|
|
761
|
-
if (splitAsciiWhitespace(clause)[0] === "type") {
|
|
762
|
-
cursor = fromStart + 4;
|
|
763
|
-
continue;
|
|
764
|
-
}
|
|
765
|
-
position = skipAsciiWhitespace(code, fromStart + 4);
|
|
766
|
-
const literal = readQuotedString(code, position);
|
|
767
|
-
if (literal) {
|
|
768
|
-
imports.push({ clause, source: literal.value });
|
|
769
|
-
cursor = literal.end;
|
|
770
|
-
}
|
|
729
|
+
if (importStart === -1) break;
|
|
730
|
+
const result = scanStaticImport(code, importStart);
|
|
731
|
+
cursor = result.nextCursor;
|
|
732
|
+
if (result.value) imports.push(result.value);
|
|
771
733
|
}
|
|
772
734
|
return imports;
|
|
773
735
|
}
|
|
736
|
+
function scanStaticImport(code, importStart) {
|
|
737
|
+
const afterKeyword = importStart + 6;
|
|
738
|
+
if (importStart > 0 && isIdentifierPart(readCodePoint(code, importStart - 1)) || isIdentifierPart(readCodePoint(code, afterKeyword))) {
|
|
739
|
+
return { nextCursor: afterKeyword };
|
|
740
|
+
}
|
|
741
|
+
const clauseStart = skipAsciiWhitespace(code, afterKeyword);
|
|
742
|
+
const opener = code.charAt(clauseStart);
|
|
743
|
+
if (opener === "(") return { nextCursor: afterKeyword };
|
|
744
|
+
if (opener === '"' || opener === "'") {
|
|
745
|
+
return scanSideEffectImport(code, clauseStart, afterKeyword);
|
|
746
|
+
}
|
|
747
|
+
return scanImportClause(code, clauseStart, afterKeyword);
|
|
748
|
+
}
|
|
749
|
+
function scanSideEffectImport(code, literalStart, fallbackCursor) {
|
|
750
|
+
const literal = readQuotedString(code, literalStart);
|
|
751
|
+
return literal ? { nextCursor: literal.end, value: { clause: null, source: literal.value } } : { nextCursor: fallbackCursor };
|
|
752
|
+
}
|
|
753
|
+
function scanImportClause(code, clauseStart, fallbackCursor) {
|
|
754
|
+
const fromStart = findImportFromKeyword(code, clauseStart);
|
|
755
|
+
if (fromStart === -1) return { nextCursor: fallbackCursor };
|
|
756
|
+
const clause = code.slice(clauseStart, fromStart).trim();
|
|
757
|
+
if (splitAsciiWhitespace(clause)[0] === "type") {
|
|
758
|
+
return { nextCursor: fromStart + 4 };
|
|
759
|
+
}
|
|
760
|
+
const literalStart = skipAsciiWhitespace(code, fromStart + 4);
|
|
761
|
+
const literal = readQuotedString(code, literalStart);
|
|
762
|
+
return literal ? { nextCursor: literal.end, value: { clause, source: literal.value } } : { nextCursor: fallbackCursor };
|
|
763
|
+
}
|
|
764
|
+
function findImportFromKeyword(code, clauseStart) {
|
|
765
|
+
for (let position = clauseStart; position < code.length; position += 1) {
|
|
766
|
+
if (code.charAt(position) === ";") return -1;
|
|
767
|
+
if (code.startsWith("from", position) && (position === clauseStart || !isIdentifierPart(readCodePoint(code, position - 1))) && !isIdentifierPart(readCodePoint(code, position + 4))) {
|
|
768
|
+
return position;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
return -1;
|
|
772
|
+
}
|
|
774
773
|
function readQuotedString(code, start) {
|
|
775
774
|
const quote = code.charAt(start);
|
|
776
775
|
if (quote !== '"' && quote !== "'") {
|
|
@@ -798,7 +797,7 @@ function readQuotedString(code, start) {
|
|
|
798
797
|
function skipAsciiWhitespace(code, start) {
|
|
799
798
|
let index = start;
|
|
800
799
|
while (index < code.length) {
|
|
801
|
-
const charCode = code
|
|
800
|
+
const charCode = readCodePoint(code, index);
|
|
802
801
|
if (charCode !== 9 && charCode !== 10 && charCode !== 13 && charCode !== 32) {
|
|
803
802
|
break;
|
|
804
803
|
}
|
|
@@ -943,9 +942,9 @@ function normalizeModuleId(id) {
|
|
|
943
942
|
}
|
|
944
943
|
let normalized;
|
|
945
944
|
try {
|
|
946
|
-
normalized = fs__namespace.realpathSync.native(clean)
|
|
945
|
+
normalized = transformCache.normalizePathSeparators(fs__namespace.realpathSync.native(clean));
|
|
947
946
|
} catch {
|
|
948
|
-
normalized = path__namespace.resolve(clean)
|
|
947
|
+
normalized = transformCache.normalizePathSeparators(path__namespace.resolve(clean));
|
|
949
948
|
}
|
|
950
949
|
normalizedModuleIdCache.set(clean, normalized);
|
|
951
950
|
return normalized;
|
|
@@ -991,7 +990,7 @@ function resolveLocalModule(importer, source) {
|
|
|
991
990
|
}
|
|
992
991
|
function pruneRSCModulePathCaches(moduleIds) {
|
|
993
992
|
for (const [key, value] of normalizedModuleIdCache) {
|
|
994
|
-
const normalizedKey =
|
|
993
|
+
const normalizedKey = transformCache.normalizePathSeparators(key);
|
|
995
994
|
if (moduleIds.has(value) || moduleIds.has(normalizedKey)) {
|
|
996
995
|
normalizedModuleIdCache.delete(key);
|
|
997
996
|
}
|
|
@@ -1002,43 +1001,44 @@ function pruneRSCModulePathCaches(moduleIds) {
|
|
|
1002
1001
|
}
|
|
1003
1002
|
}
|
|
1004
1003
|
}
|
|
1005
|
-
function
|
|
1006
|
-
const symbols = [];
|
|
1004
|
+
function readNamedImportedSymbols(clause) {
|
|
1007
1005
|
const openBrace = clause.indexOf("{");
|
|
1008
1006
|
const closeBrace = openBrace === -1 ? -1 : clause.indexOf("}", openBrace);
|
|
1009
|
-
if (openBrace
|
|
1010
|
-
|
|
1011
|
-
for (const part of namedPart.split(",")) {
|
|
1012
|
-
const trimmed = part.trim();
|
|
1013
|
-
if (!trimmed || trimmed.startsWith("type ")) {
|
|
1014
|
-
continue;
|
|
1015
|
-
}
|
|
1016
|
-
const sourceName = trimmed.replace(/^type[ \t]+/, "").split(/(?<![ \t])[ \t]+as[ \t]+/)[0]?.trim();
|
|
1017
|
-
if (sourceName) {
|
|
1018
|
-
symbols.push(sourceName);
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
const namespaceParts = splitAsciiWhitespace(clause);
|
|
1023
|
-
if (namespaceParts.length >= 3 && namespaceParts[0] === "*" && namespaceParts[1] === "as" && isIdentifier(namespaceParts[2] ?? "")) {
|
|
1024
|
-
symbols.push(...FORBIDDEN_SYMBOLS);
|
|
1007
|
+
if (openBrace === -1 || closeBrace === -1) {
|
|
1008
|
+
return [];
|
|
1025
1009
|
}
|
|
1010
|
+
return clause.slice(openBrace + 1, closeBrace).split(",").map((part) => part.trim()).filter((part) => part !== "" && !part.startsWith("type ")).map(
|
|
1011
|
+
(part) => part.replace(/^type[ \t]+/, "").split(/(?<![ \t])[ \t]+as[ \t]+/)[0]?.trim()
|
|
1012
|
+
).filter((symbol) => Boolean(symbol));
|
|
1013
|
+
}
|
|
1014
|
+
function readForbiddenDefaultSymbol(clause) {
|
|
1026
1015
|
const braceStart = clause.indexOf("{");
|
|
1027
1016
|
const braceEnd = clause.indexOf("}", braceStart);
|
|
1028
1017
|
const stripped = braceStart !== -1 && braceEnd !== -1 ? clause.slice(0, braceStart) + clause.slice(braceEnd + 1) : clause;
|
|
1029
|
-
const
|
|
1030
|
-
|
|
1031
|
-
|
|
1018
|
+
const candidate = stripped.trimStart().split(",", 1)[0]?.trim() ?? "";
|
|
1019
|
+
return isIdentifier(candidate) && FORBIDDEN_SYMBOLS.has(candidate) ? candidate : null;
|
|
1020
|
+
}
|
|
1021
|
+
function hasNamespaceImport(clause) {
|
|
1022
|
+
const parts = splitAsciiWhitespace(clause);
|
|
1023
|
+
return parts.length >= 3 && parts[0] === "*" && parts[1] === "as" && isIdentifier(parts[2] ?? "");
|
|
1024
|
+
}
|
|
1025
|
+
function readImportedSymbols(clause) {
|
|
1026
|
+
const symbols = readNamedImportedSymbols(clause);
|
|
1027
|
+
if (hasNamespaceImport(clause)) {
|
|
1028
|
+
symbols.push(...FORBIDDEN_SYMBOLS);
|
|
1029
|
+
}
|
|
1030
|
+
const defaultSymbol = readForbiddenDefaultSymbol(clause);
|
|
1031
|
+
if (defaultSymbol) {
|
|
1032
1032
|
symbols.push(defaultSymbol);
|
|
1033
1033
|
}
|
|
1034
1034
|
return symbols;
|
|
1035
1035
|
}
|
|
1036
1036
|
function isIdentifier(value) {
|
|
1037
|
-
if (value.length === 0 || !isIdentifierStart(value
|
|
1037
|
+
if (value.length === 0 || !isIdentifierStart(readCodePoint(value, 0))) {
|
|
1038
1038
|
return false;
|
|
1039
1039
|
}
|
|
1040
1040
|
for (let index = 1; index < value.length; index += 1) {
|
|
1041
|
-
const code = value
|
|
1041
|
+
const code = readCodePoint(value, index);
|
|
1042
1042
|
if (!isIdentifierStart(code) && (code < 48 || code > 57)) {
|
|
1043
1043
|
return false;
|
|
1044
1044
|
}
|
|
@@ -1048,11 +1048,14 @@ function isIdentifier(value) {
|
|
|
1048
1048
|
function isIdentifierStart(code) {
|
|
1049
1049
|
return code === 36 || code === 95 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
|
|
1050
1050
|
}
|
|
1051
|
+
function readCodePoint(value, index) {
|
|
1052
|
+
return value.codePointAt(index) ?? -1;
|
|
1053
|
+
}
|
|
1051
1054
|
function splitAsciiWhitespace(value) {
|
|
1052
1055
|
const parts = [];
|
|
1053
1056
|
let start = -1;
|
|
1054
1057
|
for (let index = 0; index <= value.length; index += 1) {
|
|
1055
|
-
const code = index < value.length ? value
|
|
1058
|
+
const code = index < value.length ? readCodePoint(value, index) : 32;
|
|
1056
1059
|
const whitespace = code === 9 || code === 10 || code === 13 || code === 32;
|
|
1057
1060
|
if (whitespace) {
|
|
1058
1061
|
if (start !== -1) {
|
|
@@ -1075,13 +1078,7 @@ function stripCommentsForImportScan(code) {
|
|
|
1075
1078
|
const next = code[i + 1];
|
|
1076
1079
|
if (quote) {
|
|
1077
1080
|
out += ch;
|
|
1078
|
-
|
|
1079
|
-
escaped = false;
|
|
1080
|
-
} else if (ch === "\\") {
|
|
1081
|
-
escaped = true;
|
|
1082
|
-
} else if (ch === quote) {
|
|
1083
|
-
quote = null;
|
|
1084
|
-
}
|
|
1081
|
+
({ quote, escaped } = advanceQuotedImportScan(ch, quote, escaped));
|
|
1085
1082
|
i++;
|
|
1086
1083
|
continue;
|
|
1087
1084
|
}
|
|
@@ -1092,28 +1089,15 @@ function stripCommentsForImportScan(code) {
|
|
|
1092
1089
|
continue;
|
|
1093
1090
|
}
|
|
1094
1091
|
if (ch === "/" && next === "/") {
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
out += " ";
|
|
1099
|
-
i++;
|
|
1100
|
-
}
|
|
1092
|
+
const masked = maskLineComment(code, i);
|
|
1093
|
+
out += masked.value;
|
|
1094
|
+
i = masked.end;
|
|
1101
1095
|
continue;
|
|
1102
1096
|
}
|
|
1103
1097
|
if (ch === "/" && next === "*") {
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
const blockCh = code[i];
|
|
1108
|
-
const blockNext = code[i + 1];
|
|
1109
|
-
if (blockCh === "*" && blockNext === "/") {
|
|
1110
|
-
out += " ";
|
|
1111
|
-
i += 2;
|
|
1112
|
-
break;
|
|
1113
|
-
}
|
|
1114
|
-
out += blockCh === "\n" ? "\n" : " ";
|
|
1115
|
-
i++;
|
|
1116
|
-
}
|
|
1098
|
+
const masked = maskBlockComment(code, i);
|
|
1099
|
+
out += masked.value;
|
|
1100
|
+
i = masked.end;
|
|
1117
1101
|
continue;
|
|
1118
1102
|
}
|
|
1119
1103
|
out += ch;
|
|
@@ -1121,6 +1105,31 @@ function stripCommentsForImportScan(code) {
|
|
|
1121
1105
|
}
|
|
1122
1106
|
return out;
|
|
1123
1107
|
}
|
|
1108
|
+
function advanceQuotedImportScan(character, quote, escaped) {
|
|
1109
|
+
if (escaped) return { quote, escaped: false };
|
|
1110
|
+
if (character === "\\") return { quote, escaped: true };
|
|
1111
|
+
return { quote: character === quote ? null : quote, escaped: false };
|
|
1112
|
+
}
|
|
1113
|
+
function maskLineComment(code, start) {
|
|
1114
|
+
const newline = code.indexOf("\n", start + 2);
|
|
1115
|
+
const end = newline === -1 ? code.length : newline;
|
|
1116
|
+
return { end, value: " ".repeat(end - start) };
|
|
1117
|
+
}
|
|
1118
|
+
function maskBlockComment(code, start) {
|
|
1119
|
+
let end = start + 2;
|
|
1120
|
+
while (end < code.length) {
|
|
1121
|
+
if (code.charAt(end) === "*" && code.charAt(end + 1) === "/") {
|
|
1122
|
+
end += 2;
|
|
1123
|
+
break;
|
|
1124
|
+
}
|
|
1125
|
+
end += 1;
|
|
1126
|
+
}
|
|
1127
|
+
let value = "";
|
|
1128
|
+
for (let index = start; index < end; index += 1) {
|
|
1129
|
+
value += code.charAt(index) === "\n" ? "\n" : " ";
|
|
1130
|
+
}
|
|
1131
|
+
return { end, value };
|
|
1132
|
+
}
|
|
1124
1133
|
|
|
1125
1134
|
const EMPTY_THEME = {
|
|
1126
1135
|
colors: [],
|
|
@@ -1132,6 +1141,20 @@ const EMPTY_THEME = {
|
|
|
1132
1141
|
shadows: [],
|
|
1133
1142
|
breakpoints: []
|
|
1134
1143
|
};
|
|
1144
|
+
function findMatchingBrace(source, openBrace) {
|
|
1145
|
+
let depth = 0;
|
|
1146
|
+
for (let index = openBrace; index < source.length; index++) {
|
|
1147
|
+
if (source[index] === "{") {
|
|
1148
|
+
depth++;
|
|
1149
|
+
} else if (source[index] === "}") {
|
|
1150
|
+
depth--;
|
|
1151
|
+
if (depth === 0) {
|
|
1152
|
+
return index;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
return -1;
|
|
1157
|
+
}
|
|
1135
1158
|
function stripLayerWrappers(css) {
|
|
1136
1159
|
let result = "";
|
|
1137
1160
|
let i = 0;
|
|
@@ -1147,26 +1170,13 @@ function stripLayerWrappers(css) {
|
|
|
1147
1170
|
result += css.slice(layerIdx);
|
|
1148
1171
|
break;
|
|
1149
1172
|
}
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
while (j < css.length) {
|
|
1153
|
-
if (css[j] === "{") {
|
|
1154
|
-
depth++;
|
|
1155
|
-
}
|
|
1156
|
-
if (css[j] === "}") {
|
|
1157
|
-
depth--;
|
|
1158
|
-
if (depth === 0) {
|
|
1159
|
-
result += css.slice(openBrace + 1, j);
|
|
1160
|
-
i = j + 1;
|
|
1161
|
-
break;
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
j++;
|
|
1165
|
-
}
|
|
1166
|
-
if (depth !== 0) {
|
|
1173
|
+
const closeBrace = findMatchingBrace(css, openBrace);
|
|
1174
|
+
if (closeBrace === -1) {
|
|
1167
1175
|
result += css.slice(openBrace);
|
|
1168
1176
|
break;
|
|
1169
1177
|
}
|
|
1178
|
+
result += css.slice(openBrace + 1, closeBrace);
|
|
1179
|
+
i = closeBrace + 1;
|
|
1170
1180
|
}
|
|
1171
1181
|
return result;
|
|
1172
1182
|
}
|
|
@@ -1175,20 +1185,9 @@ function extractThemeBlocks(css) {
|
|
|
1175
1185
|
const themeStart = /@theme\s+(?:inline\s+)?\{|@theme\{/g;
|
|
1176
1186
|
for (const match of css.matchAll(themeStart)) {
|
|
1177
1187
|
const openPos = css.indexOf("{", match.index);
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
if (css[j] === "{") {
|
|
1182
|
-
depth++;
|
|
1183
|
-
}
|
|
1184
|
-
if (css[j] === "}") {
|
|
1185
|
-
depth--;
|
|
1186
|
-
if (depth === 0) {
|
|
1187
|
-
blocks.push(css.slice(openPos + 1, j));
|
|
1188
|
-
break;
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
j++;
|
|
1188
|
+
const closePos = findMatchingBrace(css, openPos);
|
|
1189
|
+
if (closePos !== -1) {
|
|
1190
|
+
blocks.push(css.slice(openPos + 1, closePos));
|
|
1192
1191
|
}
|
|
1193
1192
|
}
|
|
1194
1193
|
return blocks;
|
|
@@ -1287,6 +1286,29 @@ function mergeThemes(themes) {
|
|
|
1287
1286
|
function hasTokens(theme) {
|
|
1288
1287
|
return Object.values(theme).some((arr) => arr.length > 0);
|
|
1289
1288
|
}
|
|
1289
|
+
function readCustomPropertyName(block, dashes) {
|
|
1290
|
+
let end = dashes + 2;
|
|
1291
|
+
if (end >= block.length || !/[a-z]/.test(block[end])) {
|
|
1292
|
+
return null;
|
|
1293
|
+
}
|
|
1294
|
+
end++;
|
|
1295
|
+
while (end < block.length && /[a-z0-9-]/.test(block[end])) {
|
|
1296
|
+
end++;
|
|
1297
|
+
}
|
|
1298
|
+
return { name: block.slice(dashes + 2, end), end };
|
|
1299
|
+
}
|
|
1300
|
+
function findCustomPropertyDeclarationEnd(block, nameEnd) {
|
|
1301
|
+
let cursor = nameEnd;
|
|
1302
|
+
while (cursor < block.length && /\s/.test(block[cursor])) {
|
|
1303
|
+
cursor++;
|
|
1304
|
+
}
|
|
1305
|
+
if (block[cursor] === ":") {
|
|
1306
|
+
const valueStart = cursor + 1;
|
|
1307
|
+
const semicolon = block.indexOf(";", valueStart);
|
|
1308
|
+
return semicolon > valueStart ? semicolon + 1 : -1;
|
|
1309
|
+
}
|
|
1310
|
+
return block[nameEnd] === ";" ? nameEnd + 1 : -1;
|
|
1311
|
+
}
|
|
1290
1312
|
function scanCustomPropertyNames(block) {
|
|
1291
1313
|
const names = [];
|
|
1292
1314
|
let i = 0;
|
|
@@ -1295,48 +1317,392 @@ function scanCustomPropertyNames(block) {
|
|
|
1295
1317
|
if (dashes === -1) {
|
|
1296
1318
|
break;
|
|
1297
1319
|
}
|
|
1298
|
-
|
|
1299
|
-
if (
|
|
1320
|
+
const property = readCustomPropertyName(block, dashes);
|
|
1321
|
+
if (!property) {
|
|
1300
1322
|
i = dashes + 1;
|
|
1301
1323
|
continue;
|
|
1302
1324
|
}
|
|
1303
|
-
end
|
|
1304
|
-
|
|
1305
|
-
|
|
1325
|
+
const matchEnd = findCustomPropertyDeclarationEnd(block, property.end);
|
|
1326
|
+
if (matchEnd === -1) {
|
|
1327
|
+
i = dashes + 1;
|
|
1328
|
+
continue;
|
|
1329
|
+
}
|
|
1330
|
+
names.push(property.name);
|
|
1331
|
+
i = matchEnd;
|
|
1332
|
+
}
|
|
1333
|
+
return names;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
const REGEX_PREFIXES = new Set("([{:,;=!?&|+-*%^~<>/");
|
|
1337
|
+
const REGEX_PREFIX_KEYWORDS = /* @__PURE__ */ new Set([
|
|
1338
|
+
"await",
|
|
1339
|
+
"case",
|
|
1340
|
+
"delete",
|
|
1341
|
+
"do",
|
|
1342
|
+
"else",
|
|
1343
|
+
"in",
|
|
1344
|
+
"instanceof",
|
|
1345
|
+
"of",
|
|
1346
|
+
"return",
|
|
1347
|
+
"throw",
|
|
1348
|
+
"typeof",
|
|
1349
|
+
"void",
|
|
1350
|
+
"yield"
|
|
1351
|
+
]);
|
|
1352
|
+
const SIMPLE_ESCAPES = {
|
|
1353
|
+
b: "\b",
|
|
1354
|
+
f: "\f",
|
|
1355
|
+
n: "\n",
|
|
1356
|
+
r: "\r",
|
|
1357
|
+
t: " ",
|
|
1358
|
+
v: "\v",
|
|
1359
|
+
"0": "\0"
|
|
1360
|
+
};
|
|
1361
|
+
function isFixedHex(value, width) {
|
|
1362
|
+
if (value.length !== width) return false;
|
|
1363
|
+
for (const character of value) {
|
|
1364
|
+
if (!"0123456789abcdefABCDEF".includes(character)) return false;
|
|
1365
|
+
}
|
|
1366
|
+
return true;
|
|
1367
|
+
}
|
|
1368
|
+
function decodeEscape(value, cursor) {
|
|
1369
|
+
const escaped = value[cursor];
|
|
1370
|
+
if (SIMPLE_ESCAPES[escaped] !== void 0) {
|
|
1371
|
+
return { value: SIMPLE_ESCAPES[escaped], cursor };
|
|
1372
|
+
}
|
|
1373
|
+
if (escaped === "\r" && value[cursor + 1] === "\n") {
|
|
1374
|
+
return { value: "", cursor: cursor + 1 };
|
|
1375
|
+
}
|
|
1376
|
+
if (escaped === "u" && value[cursor + 1] === "{") {
|
|
1377
|
+
const close = value.indexOf("}", cursor + 2);
|
|
1378
|
+
const hex2 = close === -1 ? "" : value.slice(cursor + 2, close);
|
|
1379
|
+
const codePoint = hex2 && /^[\dA-F]+$/i.test(hex2) ? Number.parseInt(hex2, 16) : -1;
|
|
1380
|
+
if (codePoint >= 0 && codePoint <= 1114111) {
|
|
1381
|
+
return { value: String.fromCodePoint(codePoint), cursor: close };
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
let width = 0;
|
|
1385
|
+
if (escaped === "x") width = 2;
|
|
1386
|
+
else if (escaped === "u") width = 4;
|
|
1387
|
+
const hex = value.slice(cursor + 1, cursor + width + 1);
|
|
1388
|
+
if (width > 0 && isFixedHex(hex, width)) {
|
|
1389
|
+
return {
|
|
1390
|
+
value: String.fromCodePoint(Number.parseInt(hex, 16)),
|
|
1391
|
+
cursor: cursor + width
|
|
1392
|
+
};
|
|
1393
|
+
}
|
|
1394
|
+
const decoded = escaped === "\n" || escaped === "\r" ? "" : escaped;
|
|
1395
|
+
return { value: decoded, cursor };
|
|
1396
|
+
}
|
|
1397
|
+
function decodeJavaScriptString(value) {
|
|
1398
|
+
let output = "";
|
|
1399
|
+
let cursor = 0;
|
|
1400
|
+
while (cursor < value.length) {
|
|
1401
|
+
if (value[cursor] !== "\\" || cursor + 1 >= value.length) {
|
|
1402
|
+
output += value[cursor++];
|
|
1403
|
+
continue;
|
|
1404
|
+
}
|
|
1405
|
+
const decoded = decodeEscape(value, cursor + 1);
|
|
1406
|
+
output += decoded.value;
|
|
1407
|
+
cursor = decoded.cursor + 1;
|
|
1408
|
+
}
|
|
1409
|
+
return output;
|
|
1410
|
+
}
|
|
1411
|
+
function decodeAttributeWhitespace(value) {
|
|
1412
|
+
return value.replace(
|
|
1413
|
+
/&#(?:(\d+)|x([\da-f]+));|&(?:Tab|NewLine);/gi,
|
|
1414
|
+
(entity, decimal, hexadecimal) => {
|
|
1415
|
+
if (!decimal && !hexadecimal) return " ";
|
|
1416
|
+
const codePoint = Number.parseInt(decimal ?? hexadecimal ?? "", decimal ? 10 : 16);
|
|
1417
|
+
return [9, 10, 12, 13, 32].includes(codePoint) ? " " : entity;
|
|
1418
|
+
}
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
function collectClassTokens(target, value) {
|
|
1422
|
+
for (const className of value.split(/\s+/)) {
|
|
1423
|
+
if (className) target.add(className);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
function quotedEnd(source, start, quote) {
|
|
1427
|
+
let cursor = start + 1;
|
|
1428
|
+
while (cursor < source.length) {
|
|
1429
|
+
if (source[cursor] === "\\") cursor += 2;
|
|
1430
|
+
else if (source[cursor++] === quote) break;
|
|
1431
|
+
}
|
|
1432
|
+
return cursor;
|
|
1433
|
+
}
|
|
1434
|
+
function commentEnd(source, start) {
|
|
1435
|
+
if (source[start + 1] === "/") {
|
|
1436
|
+
const end2 = source.indexOf("\n", start + 2);
|
|
1437
|
+
return end2 === -1 ? source.length : end2 + 1;
|
|
1438
|
+
}
|
|
1439
|
+
const end = source.indexOf("*/", start + 2);
|
|
1440
|
+
return end === -1 ? source.length : end + 2;
|
|
1441
|
+
}
|
|
1442
|
+
function isRegexStart(source, start) {
|
|
1443
|
+
let cursor = start - 1;
|
|
1444
|
+
while (cursor >= 0 && /\s/.test(source[cursor])) cursor--;
|
|
1445
|
+
if (source[cursor] === "<" && /[A-Z]/i.test(source[start + 1] ?? "")) return false;
|
|
1446
|
+
if (cursor < 0 || REGEX_PREFIXES.has(source[cursor])) return true;
|
|
1447
|
+
if (!/[\w$]/.test(source[cursor])) return false;
|
|
1448
|
+
const end = cursor + 1;
|
|
1449
|
+
while (cursor >= 0 && /[\w$]/.test(source[cursor])) cursor--;
|
|
1450
|
+
return REGEX_PREFIX_KEYWORDS.has(source.slice(cursor + 1, end));
|
|
1451
|
+
}
|
|
1452
|
+
function regexEnd(source, start) {
|
|
1453
|
+
let cursor = start + 1;
|
|
1454
|
+
let inCharacterClass = false;
|
|
1455
|
+
while (cursor < source.length) {
|
|
1456
|
+
const character = source[cursor];
|
|
1457
|
+
if (character === "\\") cursor += 2;
|
|
1458
|
+
else if (character === "[") {
|
|
1459
|
+
inCharacterClass = true;
|
|
1460
|
+
cursor++;
|
|
1461
|
+
} else if (character === "]") {
|
|
1462
|
+
inCharacterClass = false;
|
|
1463
|
+
cursor++;
|
|
1464
|
+
} else if (character === "/" && !inCharacterClass) {
|
|
1465
|
+
cursor++;
|
|
1466
|
+
while (/[A-Z]/i.test(source[cursor] ?? "")) cursor++;
|
|
1467
|
+
break;
|
|
1468
|
+
} else cursor++;
|
|
1469
|
+
}
|
|
1470
|
+
return cursor;
|
|
1471
|
+
}
|
|
1472
|
+
function templateEnd(source, start) {
|
|
1473
|
+
let cursor = start + 1;
|
|
1474
|
+
while (cursor < source.length) {
|
|
1475
|
+
if (source[cursor] === "\\") cursor += 2;
|
|
1476
|
+
else if (source[cursor] === "`") return cursor + 1;
|
|
1477
|
+
else if (source[cursor] === "$" && source[cursor + 1] === "{") {
|
|
1478
|
+
cursor = findBalancedCodeEnd(source, cursor + 2);
|
|
1479
|
+
} else cursor++;
|
|
1480
|
+
}
|
|
1481
|
+
return source.length;
|
|
1482
|
+
}
|
|
1483
|
+
function lexicalRegionEnd(source, start) {
|
|
1484
|
+
const character = source[start];
|
|
1485
|
+
if (character === '"' || character === "'") return quotedEnd(source, start, character);
|
|
1486
|
+
if (character === "`") return templateEnd(source, start);
|
|
1487
|
+
if (character === "/" && (source[start + 1] === "/" || source[start + 1] === "*")) {
|
|
1488
|
+
return commentEnd(source, start);
|
|
1489
|
+
}
|
|
1490
|
+
if (character === "/" && isRegexStart(source, start)) return regexEnd(source, start);
|
|
1491
|
+
return start;
|
|
1492
|
+
}
|
|
1493
|
+
function findBalancedCodeEnd(source, bodyStart) {
|
|
1494
|
+
let depth = 1;
|
|
1495
|
+
let cursor = bodyStart;
|
|
1496
|
+
while (cursor < source.length) {
|
|
1497
|
+
const regionEnd = lexicalRegionEnd(source, cursor);
|
|
1498
|
+
if (regionEnd !== cursor) {
|
|
1499
|
+
cursor = regionEnd;
|
|
1500
|
+
continue;
|
|
1501
|
+
}
|
|
1502
|
+
if (source[cursor] === "{") depth++;
|
|
1503
|
+
else if (source[cursor] === "}" && --depth === 0) return cursor;
|
|
1504
|
+
cursor++;
|
|
1505
|
+
}
|
|
1506
|
+
return source.length;
|
|
1507
|
+
}
|
|
1508
|
+
function collectTemplateTokens(target, source, start) {
|
|
1509
|
+
let cursor = start + 1;
|
|
1510
|
+
let quasiStart = cursor;
|
|
1511
|
+
while (cursor < source.length) {
|
|
1512
|
+
if (source[cursor] === "\\") {
|
|
1513
|
+
cursor += 2;
|
|
1514
|
+
continue;
|
|
1515
|
+
}
|
|
1516
|
+
if (source[cursor] === "`") {
|
|
1517
|
+
collectClassTokens(target, decodeJavaScriptString(source.slice(quasiStart, cursor)));
|
|
1518
|
+
return cursor + 1;
|
|
1519
|
+
}
|
|
1520
|
+
if (source[cursor] === "$" && source[cursor + 1] === "{") {
|
|
1521
|
+
collectClassTokens(target, decodeJavaScriptString(source.slice(quasiStart, cursor)));
|
|
1522
|
+
const expressionEnd = findBalancedCodeEnd(source, cursor + 2);
|
|
1523
|
+
collectExpressionTokens(target, source.slice(cursor + 2, expressionEnd));
|
|
1524
|
+
cursor = expressionEnd + 1;
|
|
1525
|
+
quasiStart = cursor;
|
|
1526
|
+
continue;
|
|
1527
|
+
}
|
|
1528
|
+
cursor++;
|
|
1529
|
+
}
|
|
1530
|
+
collectClassTokens(target, decodeJavaScriptString(source.slice(quasiStart)));
|
|
1531
|
+
return source.length;
|
|
1532
|
+
}
|
|
1533
|
+
function collectExpressionTokens(target, expression) {
|
|
1534
|
+
let cursor = 0;
|
|
1535
|
+
let pendingLiteral = "";
|
|
1536
|
+
let previousLiteralEnd = -1;
|
|
1537
|
+
const flushPending = () => {
|
|
1538
|
+
if (pendingLiteral) collectClassTokens(target, pendingLiteral);
|
|
1539
|
+
pendingLiteral = "";
|
|
1540
|
+
};
|
|
1541
|
+
while (cursor < expression.length) {
|
|
1542
|
+
const character = expression[cursor];
|
|
1543
|
+
if (character === "/" && (expression[cursor + 1] === "/" || expression[cursor + 1] === "*")) {
|
|
1544
|
+
cursor = commentEnd(expression, cursor);
|
|
1545
|
+
continue;
|
|
1546
|
+
}
|
|
1547
|
+
if (character === "/" && isRegexStart(expression, cursor)) {
|
|
1548
|
+
cursor = regexEnd(expression, cursor);
|
|
1549
|
+
continue;
|
|
1550
|
+
}
|
|
1551
|
+
if (character === "`") {
|
|
1552
|
+
flushPending();
|
|
1553
|
+
cursor = collectTemplateTokens(target, expression, cursor);
|
|
1554
|
+
previousLiteralEnd = -1;
|
|
1555
|
+
continue;
|
|
1306
1556
|
}
|
|
1307
|
-
|
|
1308
|
-
let matchEnd = -1;
|
|
1309
|
-
let cursor = end;
|
|
1310
|
-
while (cursor < block.length && /\s/.test(block[cursor])) {
|
|
1557
|
+
if (character !== '"' && character !== "'") {
|
|
1311
1558
|
cursor++;
|
|
1559
|
+
continue;
|
|
1312
1560
|
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1561
|
+
const end = quotedEnd(expression, cursor, character);
|
|
1562
|
+
const decoded = decodeJavaScriptString(expression.slice(cursor + 1, end - 1));
|
|
1563
|
+
const joinsPrevious = previousLiteralEnd >= 0 && expression.slice(previousLiteralEnd, cursor).trim() === "+";
|
|
1564
|
+
if (!joinsPrevious) flushPending();
|
|
1565
|
+
pendingLiteral += decoded;
|
|
1566
|
+
previousLiteralEnd = end;
|
|
1567
|
+
cursor = end;
|
|
1568
|
+
}
|
|
1569
|
+
flushPending();
|
|
1570
|
+
}
|
|
1571
|
+
function triviaEnd(source, start) {
|
|
1572
|
+
let cursor = start;
|
|
1573
|
+
while (cursor < source.length) {
|
|
1574
|
+
if (/\s/.test(source[cursor])) cursor++;
|
|
1575
|
+
else if (source[cursor] === "/" && (source[cursor + 1] === "/" || source[cursor + 1] === "*")) {
|
|
1576
|
+
cursor = commentEnd(source, cursor);
|
|
1577
|
+
} else break;
|
|
1578
|
+
}
|
|
1579
|
+
return cursor;
|
|
1580
|
+
}
|
|
1581
|
+
function propertyExpressionEnd(source, start) {
|
|
1582
|
+
let cursor = start;
|
|
1583
|
+
let parenDepth = 0;
|
|
1584
|
+
let bracketDepth = 0;
|
|
1585
|
+
let braceDepth = 0;
|
|
1586
|
+
while (cursor < source.length) {
|
|
1587
|
+
const regionEnd = lexicalRegionEnd(source, cursor);
|
|
1588
|
+
if (regionEnd !== cursor) {
|
|
1589
|
+
cursor = regionEnd;
|
|
1590
|
+
continue;
|
|
1319
1591
|
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1592
|
+
const character = source[cursor];
|
|
1593
|
+
if (character === "(") parenDepth++;
|
|
1594
|
+
else if (character === ")") parenDepth--;
|
|
1595
|
+
else if (character === "[") bracketDepth++;
|
|
1596
|
+
else if (character === "]") bracketDepth--;
|
|
1597
|
+
else if (character === "{") braceDepth++;
|
|
1598
|
+
else if (character === "}" && braceDepth > 0) braceDepth--;
|
|
1599
|
+
else if ((character === "," || character === ";" || character === "}") && parenDepth === 0 && bracketDepth === 0 && braceDepth === 0)
|
|
1600
|
+
return cursor;
|
|
1601
|
+
cursor++;
|
|
1602
|
+
}
|
|
1603
|
+
return source.length;
|
|
1604
|
+
}
|
|
1605
|
+
function isClassSink(source, start, end) {
|
|
1606
|
+
const name = source.slice(start, end);
|
|
1607
|
+
if (name !== "class" && name !== "className") return false;
|
|
1608
|
+
let previous = start - 1;
|
|
1609
|
+
while (previous >= 0 && /\s/.test(source[previous])) previous--;
|
|
1610
|
+
return source[previous] !== "." && source[previous] !== "-";
|
|
1611
|
+
}
|
|
1612
|
+
function collectClassDirective(target, source, sinkStart, valueStart) {
|
|
1613
|
+
if (!/[\w$-]/.test(source[valueStart] ?? "")) return null;
|
|
1614
|
+
let directiveEnd = valueStart;
|
|
1615
|
+
while (/[\w$-]/.test(source[directiveEnd] ?? "")) directiveEnd++;
|
|
1616
|
+
const equals = triviaEnd(source, directiveEnd);
|
|
1617
|
+
if (source[equals] !== "=") {
|
|
1618
|
+
const insideMarkupTag = source.lastIndexOf("<", sinkStart) > source.lastIndexOf(">", sinkStart);
|
|
1619
|
+
const next = source[equals] ?? "";
|
|
1620
|
+
const continuesMarkupTag = next === "/" || next === ">" || next === "{" || /[A-Z_:]/i.test(next);
|
|
1621
|
+
if (!insideMarkupTag || !continuesMarkupTag) return null;
|
|
1622
|
+
collectClassTokens(target, source.slice(valueStart, directiveEnd));
|
|
1623
|
+
return directiveEnd;
|
|
1624
|
+
}
|
|
1625
|
+
const directive = source.slice(valueStart, directiveEnd);
|
|
1626
|
+
const directiveValueStart = triviaEnd(source, equals + 1);
|
|
1627
|
+
const directiveQuote = source[directiveValueStart];
|
|
1628
|
+
if (directive !== "list") collectClassTokens(target, directive);
|
|
1629
|
+
if (directiveQuote === "{") {
|
|
1630
|
+
const end = findBalancedCodeEnd(source, directiveValueStart + 1);
|
|
1631
|
+
if (directive === "list") {
|
|
1632
|
+
collectExpressionTokens(target, source.slice(directiveValueStart + 1, end));
|
|
1633
|
+
}
|
|
1634
|
+
return end + 1;
|
|
1635
|
+
}
|
|
1636
|
+
if (directive === "list" && (directiveQuote === '"' || directiveQuote === "'")) {
|
|
1637
|
+
const end = quotedEnd(source, directiveValueStart, directiveQuote);
|
|
1638
|
+
collectExpressionTokens(target, source.slice(directiveValueStart, end));
|
|
1639
|
+
return end;
|
|
1640
|
+
}
|
|
1641
|
+
return directiveValueStart;
|
|
1642
|
+
}
|
|
1643
|
+
function collectClassSink(target, source, start, nameEnd) {
|
|
1644
|
+
const operatorStart = triviaEnd(source, nameEnd);
|
|
1645
|
+
const operator = source[operatorStart];
|
|
1646
|
+
if (operator !== "=" && operator !== ":") return nameEnd;
|
|
1647
|
+
const valueStart = triviaEnd(source, operatorStart + 1);
|
|
1648
|
+
const quote = source[valueStart];
|
|
1649
|
+
const vueBinding = operator === "=" && source.slice(Math.max(0, start - 1), start) === ":";
|
|
1650
|
+
if (operator === ":" && valueStart === operatorStart + 1) {
|
|
1651
|
+
const directiveEnd = collectClassDirective(target, source, start, valueStart);
|
|
1652
|
+
if (directiveEnd !== null) return directiveEnd;
|
|
1653
|
+
}
|
|
1654
|
+
if (quote === '"' || quote === "'") {
|
|
1655
|
+
const end = quotedEnd(source, valueStart, quote);
|
|
1656
|
+
const value = source.slice(valueStart + 1, end - 1);
|
|
1657
|
+
if (vueBinding) collectExpressionTokens(target, decodeAttributeWhitespace(value));
|
|
1658
|
+
else collectClassTokens(target, decodeAttributeWhitespace(value));
|
|
1659
|
+
return end;
|
|
1660
|
+
}
|
|
1661
|
+
if (operator === "=" && quote === "{") {
|
|
1662
|
+
const end = findBalancedCodeEnd(source, valueStart + 1);
|
|
1663
|
+
collectExpressionTokens(target, source.slice(valueStart + 1, end));
|
|
1664
|
+
return end + 1;
|
|
1665
|
+
}
|
|
1666
|
+
if (operator === ":") {
|
|
1667
|
+
const end = propertyExpressionEnd(source, valueStart);
|
|
1668
|
+
collectExpressionTokens(target, source.slice(valueStart, end));
|
|
1669
|
+
return end;
|
|
1670
|
+
}
|
|
1671
|
+
return valueStart;
|
|
1672
|
+
}
|
|
1673
|
+
function collectAuthoredClassNames(source) {
|
|
1674
|
+
const classes = /* @__PURE__ */ new Set();
|
|
1675
|
+
let cursor = 0;
|
|
1676
|
+
while (cursor < source.length) {
|
|
1677
|
+
if (source[cursor] === '"' || source[cursor] === "'") {
|
|
1678
|
+
const keyEnd = quotedEnd(source, cursor, source[cursor]);
|
|
1679
|
+
const key = decodeJavaScriptString(source.slice(cursor + 1, keyEnd - 1));
|
|
1680
|
+
cursor = key === "class" || key === "className" ? collectClassSink(classes, source, cursor, keyEnd) : keyEnd;
|
|
1681
|
+
continue;
|
|
1322
1682
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1683
|
+
const regionEnd = lexicalRegionEnd(source, cursor);
|
|
1684
|
+
if (regionEnd !== cursor) {
|
|
1685
|
+
cursor = regionEnd;
|
|
1325
1686
|
continue;
|
|
1326
1687
|
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1688
|
+
if (!/[A-Z_$]/i.test(source[cursor])) {
|
|
1689
|
+
cursor++;
|
|
1690
|
+
continue;
|
|
1691
|
+
}
|
|
1692
|
+
let nameEnd = cursor + 1;
|
|
1693
|
+
while (/[\w$]/.test(source[nameEnd] ?? "")) nameEnd++;
|
|
1694
|
+
cursor = isClassSink(source, cursor, nameEnd) ? collectClassSink(classes, source, cursor, nameEnd) : nameEnd;
|
|
1329
1695
|
}
|
|
1330
|
-
return
|
|
1696
|
+
return classes;
|
|
1331
1697
|
}
|
|
1332
1698
|
|
|
1333
1699
|
const GLOB_MAGIC_RE = /[*?[\]{}]/;
|
|
1334
1700
|
const DEFAULT_IGNORED_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", ".next", ".turbo", "dist", "build"]);
|
|
1335
1701
|
function normalizeFileId(id) {
|
|
1336
|
-
return id.split(/[?#]/, 1)[0]
|
|
1702
|
+
return transformCache.normalizePathSeparators(id.split(/[?#]/, 1)[0]);
|
|
1337
1703
|
}
|
|
1338
1704
|
function normalizeRoot(rootDir) {
|
|
1339
|
-
return path__namespace.resolve(rootDir)
|
|
1705
|
+
return transformCache.normalizePathSeparators(path__namespace.resolve(rootDir));
|
|
1340
1706
|
}
|
|
1341
1707
|
function hasGlobMagic(pattern) {
|
|
1342
1708
|
return GLOB_MAGIC_RE.test(pattern);
|
|
@@ -1345,7 +1711,7 @@ function escapeRegExp(ch) {
|
|
|
1345
1711
|
return /[|\\{}()[\]^$+?.]/.test(ch) ? `\\${ch}` : ch;
|
|
1346
1712
|
}
|
|
1347
1713
|
function globToRegExp(pattern) {
|
|
1348
|
-
const normalized =
|
|
1714
|
+
const normalized = transformCache.normalizePathSeparators(pattern);
|
|
1349
1715
|
let out = "^";
|
|
1350
1716
|
for (let i = 0; i < normalized.length; i++) {
|
|
1351
1717
|
const ch = normalized[i];
|
|
@@ -1368,7 +1734,7 @@ function globToRegExp(pattern) {
|
|
|
1368
1734
|
function relativeToRoot(file, rootDir) {
|
|
1369
1735
|
const root = normalizeRoot(rootDir);
|
|
1370
1736
|
const normalizedFile = normalizeFileId(file);
|
|
1371
|
-
return path__namespace.posix.relative(root, normalizedFile)
|
|
1737
|
+
return transformCache.normalizePathSeparators(path__namespace.posix.relative(root, normalizedFile));
|
|
1372
1738
|
}
|
|
1373
1739
|
function matchesPattern(id, pattern, rootDir) {
|
|
1374
1740
|
const file = normalizeFileId(id);
|
|
@@ -1377,7 +1743,7 @@ function matchesPattern(id, pattern, rootDir) {
|
|
|
1377
1743
|
pattern.lastIndex = 0;
|
|
1378
1744
|
return pattern.test(file) || pattern.test(relative);
|
|
1379
1745
|
}
|
|
1380
|
-
const normalizedPattern =
|
|
1746
|
+
const normalizedPattern = transformCache.normalizePathSeparators(pattern);
|
|
1381
1747
|
if (hasGlobMagic(normalizedPattern)) {
|
|
1382
1748
|
const re = globToRegExp(normalizedPattern);
|
|
1383
1749
|
return re.test(file) || re.test(relative);
|
|
@@ -1392,27 +1758,36 @@ function matchesAnyPattern(id, patterns, rootDir) {
|
|
|
1392
1758
|
const list = Array.isArray(patterns) ? patterns : [patterns];
|
|
1393
1759
|
return list.some((pattern) => matchesPattern(id, pattern, rootDir));
|
|
1394
1760
|
}
|
|
1761
|
+
function collectDirectoryFiles(dir, files) {
|
|
1762
|
+
let entries;
|
|
1763
|
+
try {
|
|
1764
|
+
entries = fs__namespace.readdirSync(dir, { withFileTypes: true });
|
|
1765
|
+
} catch {
|
|
1766
|
+
return;
|
|
1767
|
+
}
|
|
1768
|
+
for (const entry of entries) {
|
|
1769
|
+
const full = path__namespace.join(dir, entry.name);
|
|
1770
|
+
if (entry.isDirectory()) {
|
|
1771
|
+
if (!DEFAULT_IGNORED_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
|
|
1772
|
+
collectDirectoryFiles(full, files);
|
|
1773
|
+
}
|
|
1774
|
+
} else {
|
|
1775
|
+
files.add(path__namespace.resolve(full));
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
function isExpandedPatternMatch(file, patterns, rootDir) {
|
|
1780
|
+
return patterns.some((pattern) => {
|
|
1781
|
+
if (hasGlobMagic(pattern)) {
|
|
1782
|
+
return matchesPattern(file, pattern, rootDir);
|
|
1783
|
+
}
|
|
1784
|
+
const resolved = path__namespace.isAbsolute(pattern) ? pattern : path__namespace.join(rootDir, pattern);
|
|
1785
|
+
return normalizeFileId(path__namespace.resolve(resolved)) === normalizeFileId(file);
|
|
1786
|
+
});
|
|
1787
|
+
}
|
|
1395
1788
|
function expandFilePatterns(rootDir, patterns) {
|
|
1396
1789
|
const list = Array.isArray(patterns) ? patterns : [patterns];
|
|
1397
1790
|
const files = /* @__PURE__ */ new Set();
|
|
1398
|
-
const walk = (dir) => {
|
|
1399
|
-
let entries;
|
|
1400
|
-
try {
|
|
1401
|
-
entries = fs__namespace.readdirSync(dir, { withFileTypes: true });
|
|
1402
|
-
} catch {
|
|
1403
|
-
return;
|
|
1404
|
-
}
|
|
1405
|
-
for (const entry of entries) {
|
|
1406
|
-
const full = path__namespace.join(dir, entry.name);
|
|
1407
|
-
if (entry.isDirectory()) {
|
|
1408
|
-
if (!DEFAULT_IGNORED_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
|
|
1409
|
-
walk(full);
|
|
1410
|
-
}
|
|
1411
|
-
} else {
|
|
1412
|
-
files.add(path__namespace.resolve(full));
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1415
|
-
};
|
|
1416
1791
|
let needsWalk = false;
|
|
1417
1792
|
for (const pattern of list) {
|
|
1418
1793
|
const resolved = path__namespace.isAbsolute(pattern) ? pattern : path__namespace.join(rootDir, pattern);
|
|
@@ -1425,30 +1800,25 @@ function expandFilePatterns(rootDir, patterns) {
|
|
|
1425
1800
|
}
|
|
1426
1801
|
}
|
|
1427
1802
|
if (needsWalk) {
|
|
1428
|
-
|
|
1803
|
+
collectDirectoryFiles(rootDir, files);
|
|
1429
1804
|
for (const file of Array.from(files)) {
|
|
1430
|
-
if (!list
|
|
1431
|
-
(
|
|
1432
|
-
)) {
|
|
1433
|
-
const isLiteralMatch = list.some((pattern) => {
|
|
1434
|
-
if (hasGlobMagic(pattern)) {
|
|
1435
|
-
return false;
|
|
1436
|
-
}
|
|
1437
|
-
const resolved = path__namespace.isAbsolute(pattern) ? pattern : path__namespace.join(rootDir, pattern);
|
|
1438
|
-
return normalizeFileId(path__namespace.resolve(resolved)) === normalizeFileId(file);
|
|
1439
|
-
});
|
|
1440
|
-
if (!isLiteralMatch) {
|
|
1441
|
-
files.delete(file);
|
|
1442
|
-
}
|
|
1805
|
+
if (!isExpandedPatternMatch(file, list, rootDir)) {
|
|
1806
|
+
files.delete(file);
|
|
1443
1807
|
}
|
|
1444
1808
|
}
|
|
1445
1809
|
}
|
|
1446
1810
|
return htmlEscape.sortStrings(files);
|
|
1447
1811
|
}
|
|
1448
1812
|
|
|
1813
|
+
const LINE_SEPARATOR$1 = String.fromCodePoint(8232);
|
|
1814
|
+
const PARAGRAPH_SEPARATOR$1 = String.fromCodePoint(8233);
|
|
1449
1815
|
function safeJsonForScriptTag(value, prettyPrint = false) {
|
|
1450
1816
|
const json = prettyPrint ? JSON.stringify(value, null, 2) : JSON.stringify(value);
|
|
1451
|
-
|
|
1817
|
+
let escaped = htmlEscape.replaceEveryLiteral(json, "<", htmlEscape.unicodeEscape("003C"));
|
|
1818
|
+
escaped = htmlEscape.replaceEveryLiteral(escaped, ">", htmlEscape.unicodeEscape("003E"));
|
|
1819
|
+
escaped = htmlEscape.replaceEveryLiteral(escaped, "&", htmlEscape.unicodeEscape("0026"));
|
|
1820
|
+
escaped = htmlEscape.replaceEveryLiteral(escaped, LINE_SEPARATOR$1, htmlEscape.unicodeEscape("2028"));
|
|
1821
|
+
return htmlEscape.replaceEveryLiteral(escaped, PARAGRAPH_SEPARATOR$1, htmlEscape.unicodeEscape("2029"));
|
|
1452
1822
|
}
|
|
1453
1823
|
function injectHtmlOpeningAttr(html, attr) {
|
|
1454
1824
|
const lower = html.toLowerCase();
|
|
@@ -1580,11 +1950,17 @@ function injectRecoveryManifest(html, manifest) {
|
|
|
1580
1950
|
return html + scriptTag;
|
|
1581
1951
|
}
|
|
1582
1952
|
|
|
1953
|
+
const LINE_SEPARATOR = String.fromCodePoint(8232);
|
|
1954
|
+
const PARAGRAPH_SEPARATOR = String.fromCodePoint(8233);
|
|
1583
1955
|
function escapeJsonForInlineScript(json) {
|
|
1584
|
-
|
|
1956
|
+
let escaped = htmlEscape.replaceEveryLiteral(json, "`", htmlEscape.unicodeEscape("0060"));
|
|
1957
|
+
escaped = htmlEscape.replaceEveryLiteral(escaped, "$", htmlEscape.unicodeEscape("0024"));
|
|
1958
|
+
escaped = htmlEscape.replaceEveryLiteral(escaped, "<", htmlEscape.unicodeEscape("003c"));
|
|
1959
|
+
escaped = htmlEscape.replaceEveryLiteral(escaped, LINE_SEPARATOR, htmlEscape.unicodeEscape("2028"));
|
|
1960
|
+
return htmlEscape.replaceEveryLiteral(escaped, PARAGRAPH_SEPARATOR, htmlEscape.unicodeEscape("2029"));
|
|
1585
1961
|
}
|
|
1586
1962
|
function escapeForDoubleQuotedString(value) {
|
|
1587
|
-
return
|
|
1963
|
+
return htmlEscape.escapeDoubleQuotedString(value);
|
|
1588
1964
|
}
|
|
1589
1965
|
|
|
1590
1966
|
function isParserMode(value) {
|
|
@@ -1631,15 +2007,13 @@ function isSameFileVersion(before, after) {
|
|
|
1631
2007
|
return before.dev === after.dev && before.ino === after.ino && before.size === after.size && before.mtimeNs === after.mtimeNs && before.ctimeNs === after.ctimeNs;
|
|
1632
2008
|
}
|
|
1633
2009
|
|
|
1634
|
-
function escapeTsString(value) {
|
|
1635
|
-
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
|
|
1636
|
-
}
|
|
1637
2010
|
function generateThemeDts(opts) {
|
|
1638
2011
|
const { theme, sourceFiles } = opts;
|
|
1639
2012
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1640
|
-
const
|
|
1641
|
-
const
|
|
1642
|
-
const
|
|
2013
|
+
const withoutCarriageReturns = htmlEscape.replaceEveryLiteral(sourceFiles.join(", "), "\r", " ");
|
|
2014
|
+
const sources = htmlEscape.replaceEveryLiteral(withoutCarriageReturns, "\n", " ");
|
|
2015
|
+
const toUnion = (tokens) => tokens.map((t) => `'${htmlEscape.escapeSingleQuotedString(t)}'`).join(" | ");
|
|
2016
|
+
const quoteKey = (key) => /^[a-z_$][\w$]*$/i.test(key) ? key : `'${htmlEscape.escapeSingleQuotedString(key)}'`;
|
|
1643
2017
|
const entries = [];
|
|
1644
2018
|
if (theme.colors.length > 0) {
|
|
1645
2019
|
entries.push(` colors: ${toUnion(theme.colors)};`);
|
|
@@ -1777,6 +2151,15 @@ function createThemeGroupsModule(tokens) {
|
|
|
1777
2151
|
].join("\n");
|
|
1778
2152
|
}
|
|
1779
2153
|
|
|
2154
|
+
function registerWebpackAssetProcessor(compiler, processAssets) {
|
|
2155
|
+
compiler.hooks.compilation.tap("csszyx:post", (compilation) => {
|
|
2156
|
+
const stage = compiler.webpack?.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE || compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE;
|
|
2157
|
+
compilation.hooks.processAssets.tap(
|
|
2158
|
+
{ name: "csszyx:post", stage: stage || 400 },
|
|
2159
|
+
(assets) => processAssets(assets, compilation, compiler)
|
|
2160
|
+
);
|
|
2161
|
+
});
|
|
2162
|
+
}
|
|
1780
2163
|
const CHECKSUM_PLACEHOLDER = "___CSSZYX_CHECKSUM___";
|
|
1781
2164
|
const MANGLE_MAP_PLACEHOLDER = "___CSSZYX_MANGLE_MAP___";
|
|
1782
2165
|
const VAR_MANGLE_MAP_PLACEHOLDER = "___CSSZYX_VAR_MANGLE_MAP___";
|
|
@@ -1788,7 +2171,6 @@ const TRANSFORM_MEMORY_CACHE_MAX_CODE_CHARS = 32e6;
|
|
|
1788
2171
|
const MAX_SAFELIST_CLASSES = 1e5;
|
|
1789
2172
|
const DEFAULT_VAR_MANGLE_MAP_MAX_BYTES = 100 * 1024;
|
|
1790
2173
|
const GLOBAL_VAR_ALIAS_MAP_OWNER = "\0csszyx:global-var-aliases";
|
|
1791
|
-
const DIRECTIVE_PROLOGUE_PREFIX_RE = /^((?:\s|\/\/[^\n]*\n|\/\*(?:[^*]|\*(?!\/))*\*\/)*)(['"]use (?:client|server)['"];?\s*)/;
|
|
1792
2174
|
function findOpeningTag(source, tag) {
|
|
1793
2175
|
const lower = source.toLowerCase();
|
|
1794
2176
|
const marker = `<${tag}`;
|
|
@@ -1814,9 +2196,9 @@ let _hasWarnedTransformCacheVersion = false;
|
|
|
1814
2196
|
let _hasWarnedNativeFallback = false;
|
|
1815
2197
|
const _loggedActiveParsers = /* @__PURE__ */ new Set();
|
|
1816
2198
|
const _babelFallbackFiles = /* @__PURE__ */ new Set();
|
|
1817
|
-
const requireFromHere = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.
|
|
2199
|
+
const requireFromHere = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.DtPQz8Kg.cjs', document.baseURI).href)));
|
|
1818
2200
|
const PLUGIN_VERSION = findPackageVersionFromFile(
|
|
1819
|
-
node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.
|
|
2201
|
+
node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.DtPQz8Kg.cjs', document.baseURI).href))),
|
|
1820
2202
|
UNKNOWN_PACKAGE_VERSION
|
|
1821
2203
|
);
|
|
1822
2204
|
const COMPILER_VERSION = findPackageVersionFromModule("@csszyx/compiler", UNKNOWN_PACKAGE_VERSION);
|
|
@@ -1861,10 +2243,10 @@ function stripCssBlockComments(code) {
|
|
|
1861
2243
|
let i = 0;
|
|
1862
2244
|
const n = code.length;
|
|
1863
2245
|
while (i < n) {
|
|
1864
|
-
if (code.
|
|
2246
|
+
if (code.codePointAt(i) === SLASH && code.codePointAt(i + 1) === STAR) {
|
|
1865
2247
|
out += code.slice(last, i);
|
|
1866
2248
|
i += 2;
|
|
1867
|
-
while (i < n && !(code.
|
|
2249
|
+
while (i < n && !(code.codePointAt(i) === STAR && code.codePointAt(i + 1) === SLASH)) {
|
|
1868
2250
|
i++;
|
|
1869
2251
|
}
|
|
1870
2252
|
i += 2;
|
|
@@ -1970,9 +2352,17 @@ function shouldEmitWarning(quiet, devOnly, isProduction) {
|
|
|
1970
2352
|
return true;
|
|
1971
2353
|
}
|
|
1972
2354
|
function normalizeForMatch(p) {
|
|
1973
|
-
const n =
|
|
2355
|
+
const n = transformCache.normalizePathSeparators(p);
|
|
1974
2356
|
return n.length > 1 && n.endsWith("/") ? n.slice(0, -1) : n;
|
|
1975
2357
|
}
|
|
2358
|
+
function findJsxExpressionEnd(code, bodyStart) {
|
|
2359
|
+
return findBalancedCodeEnd(code, bodyStart);
|
|
2360
|
+
}
|
|
2361
|
+
function warnPrescanBudgetSkip(filePath) {
|
|
2362
|
+
console.warn(
|
|
2363
|
+
`[csszyx] prescan skipped ${filePath}: the file exceeds the AST node budget, so NONE of its classes reached the safelist and their CSS will not be generated. Raise \`build.astBudgetLimit\` in the csszyx plugin options, or split the file.`
|
|
2364
|
+
);
|
|
2365
|
+
}
|
|
1976
2366
|
function resolveCompileSourceDirs(root, sources, realpathDir = (p) => {
|
|
1977
2367
|
try {
|
|
1978
2368
|
const real = fs__namespace.realpathSync(p);
|
|
@@ -2025,6 +2415,9 @@ function fileMayContainSafelistableSz(content) {
|
|
|
2025
2415
|
// engine-parity harness caught its classes missing on all engines.
|
|
2026
2416
|
content.includes("dynamic(");
|
|
2027
2417
|
}
|
|
2418
|
+
function mangleEligibleClasses(ownedClasses, authoredClasses) {
|
|
2419
|
+
return compiler.sortStrings([...ownedClasses].filter((className) => !authoredClasses.has(className)));
|
|
2420
|
+
}
|
|
2028
2421
|
function isPackagesSkippedSource(id, sourceDirs = []) {
|
|
2029
2422
|
const p = normalizeForMatch(id);
|
|
2030
2423
|
if (p.includes("node_modules")) {
|
|
@@ -2045,8 +2438,8 @@ ${list}
|
|
|
2045
2438
|
Add the package directory to \`compileSources\` (or move the file out of packages/) \u2014 otherwise their \`sz\` produces no CSS.`;
|
|
2046
2439
|
}
|
|
2047
2440
|
function computeSafelistRelPath(rootDir, safelistFilename, cssId) {
|
|
2048
|
-
const safelistPath = path__namespace.join(rootDir, safelistFilename)
|
|
2049
|
-
const cssDir = path__namespace.dirname(cssId)
|
|
2441
|
+
const safelistPath = transformCache.normalizePathSeparators(path__namespace.join(rootDir, safelistFilename));
|
|
2442
|
+
const cssDir = transformCache.normalizePathSeparators(path__namespace.dirname(cssId));
|
|
2050
2443
|
let relPath = path__namespace.posix.relative(cssDir, safelistPath);
|
|
2051
2444
|
if (!relPath.startsWith(".")) {
|
|
2052
2445
|
relPath = `./${relPath}`;
|
|
@@ -2220,7 +2613,10 @@ function normalizeGlobalVarAliasesForCache(aliases) {
|
|
|
2220
2613
|
if (!aliases) {
|
|
2221
2614
|
return [];
|
|
2222
2615
|
}
|
|
2223
|
-
|
|
2616
|
+
let entries;
|
|
2617
|
+
if (aliases instanceof Map) entries = aliases.entries();
|
|
2618
|
+
else if (Array.isArray(aliases)) entries = aliases;
|
|
2619
|
+
else entries = Object.entries(aliases);
|
|
2224
2620
|
const normalized = /* @__PURE__ */ new Map();
|
|
2225
2621
|
for (const [original, alias] of entries) {
|
|
2226
2622
|
if (original.startsWith("--") && alias.startsWith("--")) {
|
|
@@ -2425,7 +2821,7 @@ function findPackageVersionFromFile(file, fallback) {
|
|
|
2425
2821
|
}
|
|
2426
2822
|
}
|
|
2427
2823
|
function normalizeSourceFilename(filename) {
|
|
2428
|
-
return
|
|
2824
|
+
return transformCache.normalizePathSeparators(filename);
|
|
2429
2825
|
}
|
|
2430
2826
|
const SCRIPT_ID_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"];
|
|
2431
2827
|
const SOURCE_MODULE_EXTENSIONS = [...SCRIPT_ID_EXTENSIONS, ".cts", ".mts", ".cjs", ".mjs"];
|
|
@@ -2433,11 +2829,26 @@ function matchesScriptExtension(id, extensions) {
|
|
|
2433
2829
|
return extensions.some((ext) => id.endsWith(ext) || id.includes(`${ext}?`));
|
|
2434
2830
|
}
|
|
2435
2831
|
function insertRuntimeImport(code, importStmt) {
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2832
|
+
return runtimeImportScan.insertAfterUseDirective(code, importStmt);
|
|
2833
|
+
}
|
|
2834
|
+
function scanClassExpression(source, from) {
|
|
2835
|
+
let depth = 0;
|
|
2836
|
+
let index = from;
|
|
2837
|
+
while (index < source.length) {
|
|
2838
|
+
const char = source[index];
|
|
2839
|
+
if (char === "(" || char === "[") {
|
|
2840
|
+
depth++;
|
|
2841
|
+
} else if (char === ")" || char === "]") {
|
|
2842
|
+
if (depth === 0) {
|
|
2843
|
+
break;
|
|
2844
|
+
}
|
|
2845
|
+
depth--;
|
|
2846
|
+
} else if (depth === 0 && (char === "," || char === ";" || char === "\n" || char === "}")) {
|
|
2847
|
+
break;
|
|
2848
|
+
}
|
|
2849
|
+
index++;
|
|
2439
2850
|
}
|
|
2440
|
-
return
|
|
2851
|
+
return index;
|
|
2441
2852
|
}
|
|
2442
2853
|
function mangleCodeClassesSync(code, mangleMap) {
|
|
2443
2854
|
function mangleClassString(classString) {
|
|
@@ -2445,6 +2856,58 @@ function mangleCodeClassesSync(code, mangleMap) {
|
|
|
2445
2856
|
return mangleMap[cls.replace(/\\(.)/g, "$1")] || cls;
|
|
2446
2857
|
}).join(" ");
|
|
2447
2858
|
}
|
|
2859
|
+
function mangleClassTemplate(fullMatch, templateContent) {
|
|
2860
|
+
let changed = false;
|
|
2861
|
+
let output = "";
|
|
2862
|
+
let cursor = 0;
|
|
2863
|
+
while (cursor < templateContent.length) {
|
|
2864
|
+
const interpolationStart = templateContent.indexOf("${", cursor);
|
|
2865
|
+
const quasiEnd = interpolationStart === -1 ? templateContent.length : interpolationStart;
|
|
2866
|
+
const quasi = mangleTemplateQuasi(templateContent.slice(cursor, quasiEnd));
|
|
2867
|
+
output += quasi.value;
|
|
2868
|
+
changed ||= quasi.changed;
|
|
2869
|
+
if (interpolationStart === -1) break;
|
|
2870
|
+
const interpolationEnd = findTemplateInterpolationEnd(
|
|
2871
|
+
templateContent,
|
|
2872
|
+
interpolationStart + 2
|
|
2873
|
+
);
|
|
2874
|
+
const inner = templateContent.slice(interpolationStart + 2, interpolationEnd - 1);
|
|
2875
|
+
const interpolation = mangleTemplateInterpolation(inner);
|
|
2876
|
+
output += `\${${interpolation.value}}`;
|
|
2877
|
+
changed ||= interpolation.changed;
|
|
2878
|
+
cursor = interpolationEnd;
|
|
2879
|
+
}
|
|
2880
|
+
return changed ? `className:\`${output}\`` : fullMatch;
|
|
2881
|
+
}
|
|
2882
|
+
function mangleTemplateQuasi(quasi) {
|
|
2883
|
+
const trimmed = quasi.trim();
|
|
2884
|
+
if (!trimmed) return { value: quasi, changed: false };
|
|
2885
|
+
const mangled = mangleClassString(trimmed);
|
|
2886
|
+
return {
|
|
2887
|
+
value: mangled === trimmed ? quasi : quasi.replace(trimmed, mangled),
|
|
2888
|
+
changed: mangled !== trimmed
|
|
2889
|
+
};
|
|
2890
|
+
}
|
|
2891
|
+
function findTemplateInterpolationEnd(templateContent, bodyStart) {
|
|
2892
|
+
let depth = 0;
|
|
2893
|
+
for (let cursor = bodyStart; cursor < templateContent.length; cursor++) {
|
|
2894
|
+
if (templateContent[cursor] === "{") depth++;
|
|
2895
|
+
else if (templateContent[cursor] === "}" && depth-- === 0) return cursor + 1;
|
|
2896
|
+
}
|
|
2897
|
+
return templateContent.length;
|
|
2898
|
+
}
|
|
2899
|
+
function mangleTemplateInterpolation(inner) {
|
|
2900
|
+
let changed = false;
|
|
2901
|
+
const value = inner.replace(/"([^"]*)"/g, (quoted, classString) => {
|
|
2902
|
+
const parts = classString.split(/\s+/).filter(Boolean);
|
|
2903
|
+
if (parts.length === 0) return quoted;
|
|
2904
|
+
const mangled = parts.map((className) => mangleMap[className] || className).join(" ");
|
|
2905
|
+
if (mangled === classString) return quoted;
|
|
2906
|
+
changed = true;
|
|
2907
|
+
return `"${mangled}"`;
|
|
2908
|
+
});
|
|
2909
|
+
return { value, changed };
|
|
2910
|
+
}
|
|
2448
2911
|
let result = code.replace(/(?:class(?:Name)?|sz)[:=]\s*"((?:[^"\\]|\\.)*)"/g, (match, classes) => {
|
|
2449
2912
|
const mangled = mangleClassString(classes);
|
|
2450
2913
|
if (mangled === classes) {
|
|
@@ -2458,92 +2921,7 @@ function mangleCodeClassesSync(code, mangleMap) {
|
|
|
2458
2921
|
}
|
|
2459
2922
|
return match.replace(classes, mangled);
|
|
2460
2923
|
});
|
|
2461
|
-
result = result.replace(/className:\s*`([^`]+)`/g,
|
|
2462
|
-
let changed = false;
|
|
2463
|
-
let out = "";
|
|
2464
|
-
let i = 0;
|
|
2465
|
-
while (i < tplContent.length) {
|
|
2466
|
-
const interStart = tplContent.indexOf("${", i);
|
|
2467
|
-
if (interStart === -1) {
|
|
2468
|
-
const quasi2 = tplContent.slice(i);
|
|
2469
|
-
const trimmed2 = quasi2.trim();
|
|
2470
|
-
if (trimmed2) {
|
|
2471
|
-
const m = mangleClassString(trimmed2);
|
|
2472
|
-
if (m !== trimmed2) {
|
|
2473
|
-
changed = true;
|
|
2474
|
-
out += quasi2.replace(trimmed2, m);
|
|
2475
|
-
} else {
|
|
2476
|
-
out += quasi2;
|
|
2477
|
-
}
|
|
2478
|
-
} else {
|
|
2479
|
-
out += quasi2;
|
|
2480
|
-
}
|
|
2481
|
-
break;
|
|
2482
|
-
}
|
|
2483
|
-
const quasi = tplContent.slice(i, interStart);
|
|
2484
|
-
const trimmed = quasi.trim();
|
|
2485
|
-
if (trimmed) {
|
|
2486
|
-
const m = mangleClassString(trimmed);
|
|
2487
|
-
if (m !== trimmed) {
|
|
2488
|
-
changed = true;
|
|
2489
|
-
out += quasi.replace(trimmed, m);
|
|
2490
|
-
} else {
|
|
2491
|
-
out += quasi;
|
|
2492
|
-
}
|
|
2493
|
-
} else {
|
|
2494
|
-
out += quasi;
|
|
2495
|
-
}
|
|
2496
|
-
let j = interStart + 2;
|
|
2497
|
-
let depth = 0;
|
|
2498
|
-
while (j < tplContent.length) {
|
|
2499
|
-
if (tplContent[j] === "{") {
|
|
2500
|
-
depth++;
|
|
2501
|
-
} else if (tplContent[j] === "}") {
|
|
2502
|
-
if (depth === 0) {
|
|
2503
|
-
j++;
|
|
2504
|
-
break;
|
|
2505
|
-
}
|
|
2506
|
-
depth--;
|
|
2507
|
-
}
|
|
2508
|
-
j++;
|
|
2509
|
-
}
|
|
2510
|
-
const interInner = tplContent.slice(interStart + 2, j - 1);
|
|
2511
|
-
const mangledInner = interInner.replace(/"([^"]*)"/g, (qm, inner) => {
|
|
2512
|
-
const parts = inner.split(/\s+/).filter(Boolean);
|
|
2513
|
-
if (parts.length === 0) {
|
|
2514
|
-
return qm;
|
|
2515
|
-
}
|
|
2516
|
-
const m = parts.map((p) => mangleMap[p] || p).join(" ");
|
|
2517
|
-
if (m === inner) {
|
|
2518
|
-
return qm;
|
|
2519
|
-
}
|
|
2520
|
-
changed = true;
|
|
2521
|
-
return `"${m}"`;
|
|
2522
|
-
});
|
|
2523
|
-
out += `\${${mangledInner}}`;
|
|
2524
|
-
i = j;
|
|
2525
|
-
}
|
|
2526
|
-
return changed ? `className:\`${out}\`` : fullMatch;
|
|
2527
|
-
});
|
|
2528
|
-
function scanClassExpression(source, from) {
|
|
2529
|
-
let depth = 0;
|
|
2530
|
-
let j = from;
|
|
2531
|
-
while (j < source.length) {
|
|
2532
|
-
const ch = source[j];
|
|
2533
|
-
if (ch === "(" || ch === "[") {
|
|
2534
|
-
depth++;
|
|
2535
|
-
} else if (ch === ")" || ch === "]") {
|
|
2536
|
-
if (depth === 0) {
|
|
2537
|
-
break;
|
|
2538
|
-
}
|
|
2539
|
-
depth--;
|
|
2540
|
-
} else if (depth === 0 && (ch === "," || ch === ";" || ch === "\n" || ch === "}")) {
|
|
2541
|
-
break;
|
|
2542
|
-
}
|
|
2543
|
-
j++;
|
|
2544
|
-
}
|
|
2545
|
-
return j;
|
|
2546
|
-
}
|
|
2924
|
+
result = result.replace(/className:\s*`([^`]+)`/g, mangleClassTemplate);
|
|
2547
2925
|
function mangleTernaryClassStrings(expr) {
|
|
2548
2926
|
const qIdx = expr.indexOf("?");
|
|
2549
2927
|
if (qIdx === -1 || !expr.slice(qIdx).includes(":")) {
|
|
@@ -2751,7 +3129,12 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2751
3129
|
}
|
|
2752
3130
|
if (!_loggedActiveParsers.has(parserMode)) {
|
|
2753
3131
|
_loggedActiveParsers.add(parserMode);
|
|
2754
|
-
|
|
3132
|
+
let detail = parserMode;
|
|
3133
|
+
if (parserDegraded) {
|
|
3134
|
+
detail = "oxc (degraded from default `rust`: no native binary for this platform)";
|
|
3135
|
+
} else if (parserMode === "rust") {
|
|
3136
|
+
detail = "rust (native engine)";
|
|
3137
|
+
}
|
|
2755
3138
|
console.warn(`[csszyx] active parser: ${detail}`);
|
|
2756
3139
|
}
|
|
2757
3140
|
}
|
|
@@ -2772,6 +3155,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2772
3155
|
skipWarningEmitted: false,
|
|
2773
3156
|
classesCapped: false,
|
|
2774
3157
|
ownedClasses: /* @__PURE__ */ new Set(),
|
|
3158
|
+
authoredClasses: /* @__PURE__ */ new Set(),
|
|
2775
3159
|
mangleMap: {},
|
|
2776
3160
|
varMangleEntriesByFile: /* @__PURE__ */ new Map(),
|
|
2777
3161
|
varMangleMap: Object.fromEntries(earlyGlobalVarAliasEntries),
|
|
@@ -2888,53 +3272,76 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2888
3272
|
}
|
|
2889
3273
|
const cacheKey = cacheEnabled ? transformCache.createTransformCacheKey(cacheInput) : null;
|
|
2890
3274
|
if (cacheEnabled && cacheKey) {
|
|
2891
|
-
const
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
if (cached)
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
3275
|
+
const cached = findConfiguredTransformCacheEntry(
|
|
3276
|
+
cacheRoot,
|
|
3277
|
+
cacheInput,
|
|
3278
|
+
cacheKey,
|
|
3279
|
+
effectiveFilename,
|
|
3280
|
+
astBudget
|
|
3281
|
+
);
|
|
3282
|
+
if (cached) return cached;
|
|
3283
|
+
}
|
|
3284
|
+
const execution = runConfiguredParser(source, effectiveFilename, compilerOptions);
|
|
3285
|
+
if (cacheEnabled && cacheKey && execution.cacheable) {
|
|
3286
|
+
transformCache.writeTransformCache(cacheRoot, cacheInput, execution.result, cacheKey);
|
|
3287
|
+
rememberTransformCacheEntry(cacheKey.key, execution.result);
|
|
3288
|
+
}
|
|
3289
|
+
return execution.result;
|
|
3290
|
+
}
|
|
3291
|
+
function findConfiguredTransformCacheEntry(cacheRoot, cacheInput, cacheKey, effectiveFilename, astBudget) {
|
|
3292
|
+
const memoryCached = transformMemoryCache.get(cacheKey.key);
|
|
3293
|
+
if (memoryCached) {
|
|
3294
|
+
transformMemoryCache.delete(cacheKey.key);
|
|
3295
|
+
transformMemoryCache.set(cacheKey.key, memoryCached);
|
|
3296
|
+
return memoryCached;
|
|
3297
|
+
}
|
|
3298
|
+
const diskCached = transformCache.readTransformCache(cacheRoot, cacheInput, cacheKey);
|
|
3299
|
+
if (diskCached) {
|
|
3300
|
+
rememberTransformCacheEntry(cacheKey.key, diskCached);
|
|
3301
|
+
return diskCached;
|
|
3302
|
+
}
|
|
3303
|
+
if (astBudget !== void 0) return null;
|
|
3304
|
+
const handoff = prescanResultHandoff.get(effectiveFilename);
|
|
3305
|
+
if (!handoff) return null;
|
|
3306
|
+
prescanResultHandoff.delete(effectiveFilename);
|
|
3307
|
+
return handoff.inputSha256 === cacheKey.inputSha256 ? handoff.result : null;
|
|
3308
|
+
}
|
|
3309
|
+
function runConfiguredParser(source, effectiveFilename, compilerOptions) {
|
|
2913
3310
|
if (parserMode === "babel") {
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
try {
|
|
2919
|
-
result = compiler.transformOxc(source, effectiveFilename, compilerOptions);
|
|
2920
|
-
} catch (err) {
|
|
2921
|
-
result = compiler.transformSourceCode(source, effectiveFilename, compilerOptions);
|
|
2922
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
2923
|
-
result.diagnostics.push(
|
|
2924
|
-
`[csszyx] oxc parser fell back to Babel for ${effectiveFilename}: ${reason}`
|
|
2925
|
-
);
|
|
2926
|
-
if (!_babelFallbackFiles.has(effectiveFilename)) {
|
|
2927
|
-
_babelFallbackFiles.add(effectiveFilename);
|
|
2928
|
-
console.warn(
|
|
2929
|
-
`[csszyx] oxc parser fell back to Babel for ${effectiveFilename}: ${reason} (${_babelFallbackFiles.size} file(s) so far). Output is still correct; this usually means the file uses a syntax the oxc lane does not yet handle.`
|
|
2930
|
-
);
|
|
2931
|
-
}
|
|
2932
|
-
return result;
|
|
2933
|
-
}
|
|
3311
|
+
return {
|
|
3312
|
+
result: compiler.transformSourceCode(source, effectiveFilename, compilerOptions),
|
|
3313
|
+
cacheable: true
|
|
3314
|
+
};
|
|
2934
3315
|
}
|
|
2935
|
-
if (
|
|
2936
|
-
|
|
2937
|
-
|
|
3316
|
+
if (parserMode === "rust") {
|
|
3317
|
+
return {
|
|
3318
|
+
result: compiler.transformRust(source, effectiveFilename, compilerOptions),
|
|
3319
|
+
cacheable: true
|
|
3320
|
+
};
|
|
3321
|
+
}
|
|
3322
|
+
try {
|
|
3323
|
+
return {
|
|
3324
|
+
result: compiler.transformOxc(source, effectiveFilename, compilerOptions),
|
|
3325
|
+
cacheable: true
|
|
3326
|
+
};
|
|
3327
|
+
} catch (error) {
|
|
3328
|
+
return {
|
|
3329
|
+
result: runBabelFallback(source, effectiveFilename, compilerOptions, error),
|
|
3330
|
+
cacheable: false
|
|
3331
|
+
};
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
function runBabelFallback(source, effectiveFilename, compilerOptions, error) {
|
|
3335
|
+
const result = compiler.transformSourceCode(source, effectiveFilename, compilerOptions);
|
|
3336
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
3337
|
+
result.diagnostics.push(
|
|
3338
|
+
`[csszyx] oxc parser fell back to Babel for ${effectiveFilename}: ${reason}`
|
|
3339
|
+
);
|
|
3340
|
+
if (!_babelFallbackFiles.has(effectiveFilename)) {
|
|
3341
|
+
_babelFallbackFiles.add(effectiveFilename);
|
|
3342
|
+
console.warn(
|
|
3343
|
+
`[csszyx] oxc parser fell back to Babel for ${effectiveFilename}: ${reason} (${_babelFallbackFiles.size} file(s) so far). Output is still correct; this usually means the file uses a syntax the oxc lane does not yet handle.`
|
|
3344
|
+
);
|
|
2938
3345
|
}
|
|
2939
3346
|
return result;
|
|
2940
3347
|
}
|
|
@@ -2973,11 +3380,19 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2973
3380
|
const compilerOptions = createCompilerOptions(prescanAstBudget);
|
|
2974
3381
|
const cacheRoot = transformCache.resolveTransformCacheDir(state.rootDir, options.build?.cacheDir);
|
|
2975
3382
|
const results = /* @__PURE__ */ new Map();
|
|
2976
|
-
|
|
2977
|
-
if (cacheEnabled) {
|
|
2978
|
-
evictTransformCacheOnce();
|
|
2979
|
-
}
|
|
3383
|
+
if (cacheEnabled) evictTransformCacheOnce();
|
|
2980
3384
|
compiler.ensureRustTransformAvailable();
|
|
3385
|
+
const misses = collectRustPrescanMisses(files, compilerOptions, cacheRoot, results);
|
|
3386
|
+
if (misses.length === 0) return orderPrescanResults(files, results);
|
|
3387
|
+
try {
|
|
3388
|
+
runRustPrescanBatch(misses, compilerOptions, cacheRoot, results);
|
|
3389
|
+
} catch {
|
|
3390
|
+
runRustPrescanFallback(misses, results);
|
|
3391
|
+
}
|
|
3392
|
+
return orderPrescanResults(files, results);
|
|
3393
|
+
}
|
|
3394
|
+
function collectRustPrescanMisses(files, compilerOptions, cacheRoot, results) {
|
|
3395
|
+
const misses = [];
|
|
2981
3396
|
for (const file of files) {
|
|
2982
3397
|
const effectiveFilename = normalizeSourceFilename(file.filePath);
|
|
2983
3398
|
const cacheInput = createConfiguredTransformCacheInput(
|
|
@@ -2986,79 +3401,54 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2986
3401
|
compilerOptions
|
|
2987
3402
|
);
|
|
2988
3403
|
const cacheKey = cacheEnabled ? transformCache.createTransformCacheKey(cacheInput) : null;
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
if (memoryCached) {
|
|
2992
|
-
transformMemoryCache.delete(cacheKey.key);
|
|
2993
|
-
transformMemoryCache.set(cacheKey.key, memoryCached);
|
|
2994
|
-
results.set(file.filePath, memoryCached);
|
|
2995
|
-
continue;
|
|
2996
|
-
}
|
|
2997
|
-
const cached = transformCache.readTransformCache(cacheRoot, cacheInput, cacheKey);
|
|
2998
|
-
if (cached) {
|
|
2999
|
-
rememberTransformCacheEntry(cacheKey.key, cached);
|
|
3000
|
-
results.set(file.filePath, cached);
|
|
3001
|
-
continue;
|
|
3002
|
-
}
|
|
3003
|
-
}
|
|
3004
|
-
misses.push({
|
|
3005
|
-
filePath: file.filePath,
|
|
3006
|
-
effectiveFilename,
|
|
3007
|
-
content: file.content,
|
|
3404
|
+
const cached = cacheKey ? findConfiguredTransformCacheEntry(
|
|
3405
|
+
cacheRoot,
|
|
3008
3406
|
cacheInput,
|
|
3009
|
-
cacheKey
|
|
3010
|
-
|
|
3407
|
+
cacheKey,
|
|
3408
|
+
effectiveFilename,
|
|
3409
|
+
prescanAstBudget
|
|
3410
|
+
) : null;
|
|
3411
|
+
if (cached) results.set(file.filePath, cached);
|
|
3412
|
+
else misses.push({ ...file, effectiveFilename, cacheInput, cacheKey });
|
|
3011
3413
|
}
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3414
|
+
return misses;
|
|
3415
|
+
}
|
|
3416
|
+
function runRustPrescanBatch(misses, compilerOptions, cacheRoot, results) {
|
|
3417
|
+
const batchResults = compiler.transformRustBatch(
|
|
3418
|
+
misses.map((file) => ({ filename: file.effectiveFilename, source: file.content })),
|
|
3419
|
+
compilerOptions
|
|
3420
|
+
);
|
|
3421
|
+
for (let index = 0; index < misses.length; index++) {
|
|
3422
|
+
const miss = misses[index];
|
|
3423
|
+
const result = batchResults[index];
|
|
3424
|
+
if (!miss || !result) continue;
|
|
3425
|
+
cacheRustPrescanResult(miss, result, cacheRoot);
|
|
3426
|
+
results.set(miss.filePath, result);
|
|
3017
3427
|
}
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
const
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
if (cacheEnabled && miss.cacheKey) {
|
|
3033
|
-
transformCache.writeTransformCache(cacheRoot, miss.cacheInput, result, miss.cacheKey);
|
|
3034
|
-
rememberTransformCacheEntry(miss.cacheKey.key, result);
|
|
3035
|
-
}
|
|
3428
|
+
}
|
|
3429
|
+
function cacheRustPrescanResult(miss, result, cacheRoot) {
|
|
3430
|
+
if (!cacheEnabled || !miss.cacheKey) return;
|
|
3431
|
+
transformCache.writeTransformCache(cacheRoot, miss.cacheInput, result, miss.cacheKey);
|
|
3432
|
+
rememberTransformCacheEntry(miss.cacheKey.key, result);
|
|
3433
|
+
}
|
|
3434
|
+
function runRustPrescanFallback(misses, results) {
|
|
3435
|
+
for (const miss of misses) {
|
|
3436
|
+
try {
|
|
3437
|
+
const result = transformConfiguredSource(
|
|
3438
|
+
miss.content,
|
|
3439
|
+
miss.effectiveFilename,
|
|
3440
|
+
prescanAstBudget
|
|
3441
|
+
);
|
|
3036
3442
|
results.set(miss.filePath, result);
|
|
3037
|
-
}
|
|
3038
|
-
} catch {
|
|
3039
|
-
for (const miss of misses) {
|
|
3040
|
-
try {
|
|
3041
|
-
results.set(
|
|
3042
|
-
miss.filePath,
|
|
3043
|
-
transformConfiguredSource(
|
|
3044
|
-
miss.content,
|
|
3045
|
-
miss.effectiveFilename,
|
|
3046
|
-
prescanAstBudget
|
|
3047
|
-
)
|
|
3048
|
-
);
|
|
3049
|
-
} catch {
|
|
3050
|
-
}
|
|
3443
|
+
} catch {
|
|
3051
3444
|
}
|
|
3052
3445
|
}
|
|
3053
|
-
return files.map((file) => {
|
|
3054
|
-
const result = results.get(file.filePath);
|
|
3055
|
-
return result ? { filePath: file.filePath, result } : null;
|
|
3056
|
-
}).filter((entry) => entry !== null);
|
|
3057
3446
|
}
|
|
3058
|
-
function
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3447
|
+
function orderPrescanResults(files, results) {
|
|
3448
|
+
return files.flatMap((file) => {
|
|
3449
|
+
const result = results.get(file.filePath);
|
|
3450
|
+
return result ? [{ filePath: file.filePath, result }] : [];
|
|
3451
|
+
});
|
|
3062
3452
|
}
|
|
3063
3453
|
function transformPrescanSourcesIndividually(files) {
|
|
3064
3454
|
const results = [];
|
|
@@ -3125,11 +3515,12 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3125
3515
|
return;
|
|
3126
3516
|
}
|
|
3127
3517
|
const safelistPath = path__namespace.join(state.rootDir, SAFELIST_FILENAME);
|
|
3128
|
-
const
|
|
3518
|
+
const classNames = Array.from(classes);
|
|
3519
|
+
const classList = htmlEscape.escapeHtmlAttribute(classNames.join(" "));
|
|
3129
3520
|
const content = `<!-- Auto-generated by csszyx \u2014 DO NOT EDIT -->
|
|
3130
3521
|
<!-- Tailwind CSS scans this file for class name detection -->
|
|
3131
3522
|
<div class="${classList}"><div class="${classList}">x</div><div class="${classList}">x</div></div>
|
|
3132
|
-
|
|
3523
|
+
` + htmlEscape.renderTailwindScannerCandidates(classNames);
|
|
3133
3524
|
try {
|
|
3134
3525
|
let existing = "";
|
|
3135
3526
|
try {
|
|
@@ -3159,12 +3550,56 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3159
3550
|
state.skippedSzFiles.add(filePath);
|
|
3160
3551
|
}
|
|
3161
3552
|
}
|
|
3553
|
+
function processPrescanTransform(filePath, content, result, discoveredClasses, rawDiscoveredClasses) {
|
|
3554
|
+
const budgetExceeded = result.diagnostics.some(
|
|
3555
|
+
(diagnostic) => diagnostic.includes("AST budget exceeded")
|
|
3556
|
+
);
|
|
3557
|
+
if (cacheEnabled && !budgetExceeded && content !== void 0) {
|
|
3558
|
+
prescanResultHandoff.set(normalizeSourceFilename(filePath), {
|
|
3559
|
+
inputSha256: node_crypto.createHash("sha256").update(content).digest("hex"),
|
|
3560
|
+
result
|
|
3561
|
+
});
|
|
3562
|
+
}
|
|
3563
|
+
if (budgetExceeded) {
|
|
3564
|
+
warnPrescanBudgetSkip(filePath);
|
|
3565
|
+
return;
|
|
3566
|
+
}
|
|
3567
|
+
const parseFailed = result.diagnostics.some(
|
|
3568
|
+
(diagnostic) => diagnostic.includes("[csszyx] parse error in ")
|
|
3569
|
+
);
|
|
3570
|
+
if (result.classes.size === 0 && result.rawClassNames.size === 0 && parseFailed) {
|
|
3571
|
+
console.warn(
|
|
3572
|
+
`[csszyx] prescan skipped ${filePath}: the file failed to parse, so none of its classes reached the safelist. Fix the syntax error (or check the file extension matches its contents).`
|
|
3573
|
+
);
|
|
3574
|
+
return;
|
|
3575
|
+
}
|
|
3576
|
+
if (!result.transformed && result.classes.size === 0) {
|
|
3577
|
+
return;
|
|
3578
|
+
}
|
|
3579
|
+
collectPrescanResult(result, filePath, discoveredClasses, rawDiscoveredClasses);
|
|
3580
|
+
}
|
|
3162
3581
|
function prescanAndWriteClasses() {
|
|
3163
3582
|
refreshCompileSourceDirs();
|
|
3164
3583
|
const prescanStarted = node_perf_hooks.performance.now();
|
|
3165
3584
|
const discoveredClasses = /* @__PURE__ */ new Set();
|
|
3166
3585
|
const rawDiscoveredClasses = /* @__PURE__ */ new Set();
|
|
3167
3586
|
const prescanSources = [];
|
|
3587
|
+
function collectPrescanSource(filePath) {
|
|
3588
|
+
if (!shouldProcessSource(filePath)) {
|
|
3589
|
+
recordPackagesSkipIfSz(filePath);
|
|
3590
|
+
return;
|
|
3591
|
+
}
|
|
3592
|
+
let content;
|
|
3593
|
+
try {
|
|
3594
|
+
content = fs__namespace.readFileSync(filePath, "utf-8");
|
|
3595
|
+
} catch {
|
|
3596
|
+
return;
|
|
3597
|
+
}
|
|
3598
|
+
recordAuthoredClasses(content);
|
|
3599
|
+
if (fileMayContainSafelistableSz(content)) {
|
|
3600
|
+
prescanSources.push({ filePath, content });
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3168
3603
|
function scanDir(dir) {
|
|
3169
3604
|
let entries;
|
|
3170
3605
|
try {
|
|
@@ -3177,22 +3612,10 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3177
3612
|
if (!IGNORE_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
|
|
3178
3613
|
scanDir(path__namespace.join(dir, entry.name));
|
|
3179
3614
|
}
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
continue;
|
|
3185
|
-
}
|
|
3186
|
-
let content;
|
|
3187
|
-
try {
|
|
3188
|
-
content = fs__namespace.readFileSync(filePath, "utf-8");
|
|
3189
|
-
} catch {
|
|
3190
|
-
continue;
|
|
3191
|
-
}
|
|
3192
|
-
if (!fileMayContainSafelistableSz(content)) {
|
|
3193
|
-
continue;
|
|
3194
|
-
}
|
|
3195
|
-
prescanSources.push({ filePath, content });
|
|
3615
|
+
continue;
|
|
3616
|
+
}
|
|
3617
|
+
if (SOURCE_EXTENSIONS.has(path__namespace.extname(entry.name))) {
|
|
3618
|
+
collectPrescanSource(path__namespace.join(dir, entry.name));
|
|
3196
3619
|
}
|
|
3197
3620
|
}
|
|
3198
3621
|
}
|
|
@@ -3208,29 +3631,13 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3208
3631
|
prescanSources.map((file) => [file.filePath, file.content])
|
|
3209
3632
|
);
|
|
3210
3633
|
for (const { filePath, result } of transformPrescanSources(prescanSources)) {
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
}
|
|
3219
|
-
}
|
|
3220
|
-
if (result.diagnostics.some((d) => d.includes("AST budget exceeded"))) {
|
|
3221
|
-
warnPrescanBudgetSkip(filePath);
|
|
3222
|
-
continue;
|
|
3223
|
-
}
|
|
3224
|
-
if (result.classes.size === 0 && result.rawClassNames.size === 0 && result.diagnostics.some((d) => d.includes("[csszyx] parse error in "))) {
|
|
3225
|
-
console.warn(
|
|
3226
|
-
`[csszyx] prescan skipped ${filePath}: the file failed to parse, so none of its classes reached the safelist. Fix the syntax error (or check the file extension matches its contents).`
|
|
3227
|
-
);
|
|
3228
|
-
continue;
|
|
3229
|
-
}
|
|
3230
|
-
if (!result.transformed && result.classes.size === 0) {
|
|
3231
|
-
continue;
|
|
3232
|
-
}
|
|
3233
|
-
collectPrescanResult(result, filePath, discoveredClasses, rawDiscoveredClasses);
|
|
3634
|
+
processPrescanTransform(
|
|
3635
|
+
filePath,
|
|
3636
|
+
prescanContentByPath.get(filePath),
|
|
3637
|
+
result,
|
|
3638
|
+
discoveredClasses,
|
|
3639
|
+
rawDiscoveredClasses
|
|
3640
|
+
);
|
|
3234
3641
|
}
|
|
3235
3642
|
for (const cls of discoveredClasses) {
|
|
3236
3643
|
addSafelistClass(cls);
|
|
@@ -3291,7 +3698,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3291
3698
|
for (const kv of objStr.matchAll(numKv)) {
|
|
3292
3699
|
try {
|
|
3293
3700
|
collectTransformClasses(
|
|
3294
|
-
compiler.transform({ [kv[1]]: parseFloat(kv[2]) }),
|
|
3701
|
+
compiler.transform({ [kv[1]]: Number.parseFloat(kv[2]) }),
|
|
3295
3702
|
discoveredClasses
|
|
3296
3703
|
);
|
|
3297
3704
|
} catch {
|
|
@@ -3315,51 +3722,51 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3315
3722
|
discoveredClasses.add(cls);
|
|
3316
3723
|
}
|
|
3317
3724
|
}
|
|
3318
|
-
function
|
|
3319
|
-
const
|
|
3320
|
-
|
|
3321
|
-
for (const classPattern of [dqPattern, sqPattern]) {
|
|
3322
|
-
for (const match of code.matchAll(classPattern)) {
|
|
3323
|
-
const classes = match[1].split(/\s+/).filter(Boolean);
|
|
3324
|
-
for (const cls of classes) {
|
|
3325
|
-
addSafelistClass(cls);
|
|
3326
|
-
}
|
|
3327
|
-
}
|
|
3725
|
+
function addSafelistClasses(value) {
|
|
3726
|
+
for (const className of value.split(/\s+/).filter(Boolean)) {
|
|
3727
|
+
addSafelistClass(className);
|
|
3328
3728
|
}
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
}
|
|
3339
|
-
i++;
|
|
3729
|
+
}
|
|
3730
|
+
function collectQuotedAttributeClasses(code) {
|
|
3731
|
+
const patterns = [
|
|
3732
|
+
/(?:class(?:Name)?|sz)[:=]\s*"([^"]*)"/g,
|
|
3733
|
+
/(?:class(?:Name)?|sz)[:=]\s*'([^']*)'/g
|
|
3734
|
+
];
|
|
3735
|
+
for (const pattern of patterns) {
|
|
3736
|
+
for (const match of code.matchAll(pattern)) {
|
|
3737
|
+
addSafelistClasses(match[1] ?? "");
|
|
3340
3738
|
}
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
function collectExpressionClasses(code) {
|
|
3742
|
+
for (const match of code.matchAll(/className=\{/g)) {
|
|
3743
|
+
const bodyStart = (match.index ?? 0) + match[0].length;
|
|
3744
|
+
const expression = code.slice(bodyStart, findJsxExpressionEnd(code, bodyStart));
|
|
3745
|
+
for (const stringMatch of expression.matchAll(/"([^"]+)"|'([^']+)'/g)) {
|
|
3746
|
+
addSafelistClasses(stringMatch[1] ?? stringMatch[2] ?? "");
|
|
3349
3747
|
}
|
|
3350
3748
|
}
|
|
3351
3749
|
}
|
|
3750
|
+
function extractClasses(code) {
|
|
3751
|
+
collectQuotedAttributeClasses(code);
|
|
3752
|
+
collectExpressionClasses(code);
|
|
3753
|
+
}
|
|
3754
|
+
function recordAuthoredClasses(code) {
|
|
3755
|
+
for (const className of collectAuthoredClassNames(code)) {
|
|
3756
|
+
addSafelistClass(className);
|
|
3757
|
+
state.authoredClasses.add(className);
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3352
3760
|
function finalizeMangleMap() {
|
|
3353
|
-
const sortedClasses = Array.from(state.ownedClasses);
|
|
3354
3761
|
const newMap = {};
|
|
3355
3762
|
let tokenIndex = 0;
|
|
3356
|
-
for (
|
|
3763
|
+
for (const className of mangleEligibleClasses(state.ownedClasses, state.authoredClasses)) {
|
|
3357
3764
|
let token = core.encode(tokenIndex);
|
|
3358
|
-
while (mangleReserved.has(token)) {
|
|
3765
|
+
while (mangleReserved.has(token) || state.authoredClasses.has(token)) {
|
|
3359
3766
|
tokenIndex++;
|
|
3360
3767
|
token = core.encode(tokenIndex);
|
|
3361
3768
|
}
|
|
3362
|
-
newMap[
|
|
3769
|
+
newMap[className] = token;
|
|
3363
3770
|
tokenIndex++;
|
|
3364
3771
|
}
|
|
3365
3772
|
state.mangleMap = newMap;
|
|
@@ -3372,6 +3779,24 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3372
3779
|
function mangleCodeClasses(code) {
|
|
3373
3780
|
return mangleCodeClassesSync(code, state.mangleMap);
|
|
3374
3781
|
}
|
|
3782
|
+
function mangleHtmlClassList(classes) {
|
|
3783
|
+
const output = [];
|
|
3784
|
+
for (const className of classes.split(/\s+/)) {
|
|
3785
|
+
if (className) output.push(state.mangleMap[className] || className);
|
|
3786
|
+
}
|
|
3787
|
+
return output.join(" ");
|
|
3788
|
+
}
|
|
3789
|
+
function replaceDoubleQuotedHtmlClass(match, classes) {
|
|
3790
|
+
const output = mangleHtmlClassList(classes);
|
|
3791
|
+
return output !== classes ? `class="${output}"` : match;
|
|
3792
|
+
}
|
|
3793
|
+
function replaceSingleQuotedHtmlClass(match, classes) {
|
|
3794
|
+
const output = mangleHtmlClassList(classes);
|
|
3795
|
+
return output !== classes ? `class='${output}'` : match;
|
|
3796
|
+
}
|
|
3797
|
+
function mangleHtmlClasses(source) {
|
|
3798
|
+
return source.replace(/\bclass="([^"]*)"/g, replaceDoubleQuotedHtmlClass).replace(/\bclass='([^']*)'/g, replaceSingleQuotedHtmlClass);
|
|
3799
|
+
}
|
|
3375
3800
|
function replacePlaceholders(code) {
|
|
3376
3801
|
let result = code;
|
|
3377
3802
|
if (result.includes(CHECKSUM_PLACEHOLDER)) {
|
|
@@ -3389,6 +3814,147 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3389
3814
|
}
|
|
3390
3815
|
return result;
|
|
3391
3816
|
}
|
|
3817
|
+
function unchangedPreTransform(code) {
|
|
3818
|
+
return {
|
|
3819
|
+
code,
|
|
3820
|
+
transformed: false,
|
|
3821
|
+
usesRuntime: false,
|
|
3822
|
+
usesMerge: false,
|
|
3823
|
+
usesSzcn: false,
|
|
3824
|
+
usesSzPart: false,
|
|
3825
|
+
usesColorVar: false,
|
|
3826
|
+
usesSpacingVar: false,
|
|
3827
|
+
usesUnitVar: false
|
|
3828
|
+
};
|
|
3829
|
+
}
|
|
3830
|
+
function transformTailwindCssEntry(code, id) {
|
|
3831
|
+
state.sawAnyCss = true;
|
|
3832
|
+
if (!cssImportsTailwind(code)) return null;
|
|
3833
|
+
state.sawTailwindEntry = true;
|
|
3834
|
+
if (cssHasContentScope(code)) state.tailwindEntryScoped = true;
|
|
3835
|
+
if (!hasInjectableTailwindCandidate(state.classes)) return null;
|
|
3836
|
+
const relPath = computeSafelistRelPath(state.rootDir, SAFELIST_FILENAME, id);
|
|
3837
|
+
const transformed = appendTailwindSourceDirective(code, relPath);
|
|
3838
|
+
return transformed === null ? null : { code: transformed, map: null };
|
|
3839
|
+
}
|
|
3840
|
+
function reportTransformDiagnostics(result, id, warn) {
|
|
3841
|
+
for (const message of result.diagnostics) {
|
|
3842
|
+
if (message.includes("unresolvable sz spread")) {
|
|
3843
|
+
state.spreadWarnings.add(`${id}
|
|
3844
|
+
${message}`);
|
|
3845
|
+
} else if (message.includes("AST budget exceeded")) {
|
|
3846
|
+
console.warn(`[csszyx] ${id}
|
|
3847
|
+
${message}`);
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
if (quiet || result.diagnostics.length === 0 || process.env.NODE_ENV === "production") {
|
|
3851
|
+
return;
|
|
3852
|
+
}
|
|
3853
|
+
for (const message of result.diagnostics) {
|
|
3854
|
+
if (message.includes("unresolvable sz spread") || message.includes("AST budget exceeded")) {
|
|
3855
|
+
continue;
|
|
3856
|
+
}
|
|
3857
|
+
warn(`[csszyx] ${id}
|
|
3858
|
+
${message}`);
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
function compilerPreTransformOutput(result) {
|
|
3862
|
+
return {
|
|
3863
|
+
code: result.code,
|
|
3864
|
+
transformed: result.transformed,
|
|
3865
|
+
usesRuntime: result.usesRuntime,
|
|
3866
|
+
usesMerge: result.usesMerge,
|
|
3867
|
+
usesSzcn: result.usesSzcn,
|
|
3868
|
+
usesSzPart: result.usesSzPart,
|
|
3869
|
+
usesColorVar: result.usesColorVar,
|
|
3870
|
+
usesSpacingVar: result.usesSpacingVar,
|
|
3871
|
+
usesUnitVar: result.usesUnitVar,
|
|
3872
|
+
szClasses: result.classes
|
|
3873
|
+
};
|
|
3874
|
+
}
|
|
3875
|
+
function transformSzSource(code, id, warn) {
|
|
3876
|
+
if (id.endsWith(".vue")) {
|
|
3877
|
+
const result2 = vueAdapter.preprocess(code, options);
|
|
3878
|
+
return { ...unchangedPreTransform(result2.code), transformed: result2.transformed };
|
|
3879
|
+
}
|
|
3880
|
+
if (id.endsWith(".svelte")) {
|
|
3881
|
+
const result2 = svelteAdapter.preprocess(code, options);
|
|
3882
|
+
return result2 ? { ...unchangedPreTransform(result2.code), transformed: true } : unchangedPreTransform(code);
|
|
3883
|
+
}
|
|
3884
|
+
const transformStarted = node_perf_hooks.performance.now();
|
|
3885
|
+
const result = transformConfiguredSource(code, id);
|
|
3886
|
+
traceBenchTiming("transform-hook", id, node_perf_hooks.performance.now() - transformStarted);
|
|
3887
|
+
recordFileVarMangleEntries(state, id, cssVariableEntries(result));
|
|
3888
|
+
recordFileCSSVariableMetrics(state, id, result.code);
|
|
3889
|
+
reportTransformDiagnostics(result, id, warn);
|
|
3890
|
+
for (const [token, data] of result.recoveryTokens) state.recoveryTokens.set(token, data);
|
|
3891
|
+
return compilerPreTransformOutput(result);
|
|
3892
|
+
}
|
|
3893
|
+
function injectLayoutHydration(code, id) {
|
|
3894
|
+
if (!code.includes("<html") || !/(?:layout|Root|Document|app)\.tsx?$/i.test(id)) {
|
|
3895
|
+
return null;
|
|
3896
|
+
}
|
|
3897
|
+
let transformedCode = code;
|
|
3898
|
+
const attrName = options.production?.minify ? "data-sz-cs" : "data-sz-checksum";
|
|
3899
|
+
const htmlTag = findOpeningTag(transformedCode, "html");
|
|
3900
|
+
if (htmlTag) {
|
|
3901
|
+
transformedCode = `${transformedCode.slice(0, htmlTag.close)} ${attrName}="${CHECKSUM_PLACEHOLDER}"${transformedCode.slice(htmlTag.close)}`;
|
|
3902
|
+
}
|
|
3903
|
+
const debugScript = `<script dangerouslySetInnerHTML={{__html: \`(function(){var m=${MANGLE_MAP_PLACEHOLDER};var vm=${VAR_MANGLE_MAP_PLACEHOLDER};var gp=decodeURIComponent(${escapeJsonForInlineScript(JSON.stringify(encodedGlobalVarAliasPrefix))});var r={};var vr={};for(var k in m)r[m[k]]=k;for(var vk in vm){var vv=vm[vk];var vs=Array.isArray(vv)?vv:[vv];for(var vi=0;vi<vs.length;vi++)(vr[vs[vi]]||(vr[vs[vi]]=[])).push(vk)}window.__csszyx={mangleMap:m,varMangleMap:vm,checksum:"${CHECKSUM_PLACEHOLDER}",decode:function(c){return r[c]},encode:function(c){return m[c]},decodeVar:function(v){return vr[v]||[]},encodeVar:function(v){return vm[v]},decodeGlobalVar:function(v){var a=vr[v]||[];return v.indexOf(gp)===0?a[0]:void 0},decodeAll:function(el){return(el.className||"").split(" ").map(function(c){return r[c]||c})}}})()\`}} />`;
|
|
3904
|
+
const bodyTag = findOpeningTag(transformedCode, "body");
|
|
3905
|
+
if (bodyTag) {
|
|
3906
|
+
transformedCode = `${transformedCode.slice(0, bodyTag.close + 1)}${debugScript}${transformedCode.slice(bodyTag.close + 1)}`;
|
|
3907
|
+
}
|
|
3908
|
+
return transformedCode;
|
|
3909
|
+
}
|
|
3910
|
+
function requiredRuntimeHelpers(output) {
|
|
3911
|
+
const helpers = [];
|
|
3912
|
+
if (output.usesRuntime) helpers.push("_sz");
|
|
3913
|
+
if (output.usesMerge) helpers.push("_szMerge");
|
|
3914
|
+
if (output.usesSzcn) helpers.push("_szcn");
|
|
3915
|
+
if (output.usesSzPart) helpers.push("_szPart");
|
|
3916
|
+
if (output.usesColorVar) helpers.push("__szColorVar");
|
|
3917
|
+
if (output.usesSpacingVar) helpers.push("__szSpacingVar");
|
|
3918
|
+
if (output.usesUnitVar) helpers.push("__szUnitVar");
|
|
3919
|
+
return helpers;
|
|
3920
|
+
}
|
|
3921
|
+
function injectRuntimeHelpers(code, output) {
|
|
3922
|
+
const imports = requiredRuntimeHelpers(output);
|
|
3923
|
+
const hasRuntimeImport = imports.length > 0 && code.includes("@csszyx/runtime");
|
|
3924
|
+
const needed = hasRuntimeImport ? imports.filter((name) => !runtimeImportScan.importsRuntimeHelper(code, name)) : imports;
|
|
3925
|
+
if (needed.length === 0) return null;
|
|
3926
|
+
const existingImport = runtimeImportScan.findRuntimeImportClause(code);
|
|
3927
|
+
if (existingImport) {
|
|
3928
|
+
return code.replace(
|
|
3929
|
+
existingImport.statement,
|
|
3930
|
+
`${existingImport.prefixWithBody}, ${needed.join(", ")} } from '@csszyx/runtime'`
|
|
3931
|
+
);
|
|
3932
|
+
}
|
|
3933
|
+
const importStatement = `import { ${needed.join(", ")} } from '@csszyx/runtime';
|
|
3934
|
+
`;
|
|
3935
|
+
return insertRuntimeImport(code, importStatement);
|
|
3936
|
+
}
|
|
3937
|
+
function injectThemeGroups(code, transformedCode, id, usesSzcn) {
|
|
3938
|
+
if (!usesSzcn && !/\bszcn\s*\(/.test(code) || transformedCode.includes(THEME_GROUPS_VIRTUAL_ID) || !shouldProcessSource(id)) {
|
|
3939
|
+
return null;
|
|
3940
|
+
}
|
|
3941
|
+
return `import '${THEME_GROUPS_VIRTUAL_ID}';
|
|
3942
|
+
${transformedCode}`;
|
|
3943
|
+
}
|
|
3944
|
+
function collectPreTransformClasses(output) {
|
|
3945
|
+
if (!output.transformed && !output.code.includes("class=") && !output.code.includes("className=")) {
|
|
3946
|
+
return null;
|
|
3947
|
+
}
|
|
3948
|
+
if (output.szClasses) {
|
|
3949
|
+
for (const className of output.szClasses) {
|
|
3950
|
+
addSafelistClass(className);
|
|
3951
|
+
state.ownedClasses.add(className);
|
|
3952
|
+
}
|
|
3953
|
+
} else {
|
|
3954
|
+
extractClasses(output.code);
|
|
3955
|
+
}
|
|
3956
|
+
return { code: output.code, map: null };
|
|
3957
|
+
}
|
|
3392
3958
|
const prePlugin = unplugin$1.createUnplugin(
|
|
3393
3959
|
(_pluginOptions) => ({
|
|
3394
3960
|
name: "csszyx:pre",
|
|
@@ -3475,166 +4041,41 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3475
4041
|
}
|
|
3476
4042
|
if (shouldProcessSource(id)) {
|
|
3477
4043
|
trackGlobalVarSourceFile(id, code);
|
|
4044
|
+
recordAuthoredClasses(code);
|
|
3478
4045
|
}
|
|
3479
4046
|
if (matchesScriptExtension(id, SCRIPT_ID_EXTENSIONS)) {
|
|
3480
4047
|
assertNoRSCBoundaryViolation(code, id);
|
|
3481
4048
|
}
|
|
3482
4049
|
if (matchesScriptExtension(id, [".css"])) {
|
|
3483
|
-
|
|
3484
|
-
if (cssImportsTailwind(code)) {
|
|
3485
|
-
state.sawTailwindEntry = true;
|
|
3486
|
-
if (cssHasContentScope(code)) {
|
|
3487
|
-
state.tailwindEntryScoped = true;
|
|
3488
|
-
}
|
|
3489
|
-
if (hasInjectableTailwindCandidate(state.classes)) {
|
|
3490
|
-
const relPath = computeSafelistRelPath(
|
|
3491
|
-
state.rootDir,
|
|
3492
|
-
SAFELIST_FILENAME,
|
|
3493
|
-
id
|
|
3494
|
-
);
|
|
3495
|
-
const transformed2 = appendTailwindSourceDirective(code, relPath);
|
|
3496
|
-
if (transformed2 !== null) {
|
|
3497
|
-
return { code: transformed2, map: null };
|
|
3498
|
-
}
|
|
3499
|
-
}
|
|
3500
|
-
}
|
|
3501
|
-
return null;
|
|
4050
|
+
return transformTailwindCssEntry(code, id);
|
|
3502
4051
|
}
|
|
3503
|
-
let transformedCode = code;
|
|
3504
|
-
let usesRuntime = false;
|
|
3505
|
-
let usesMerge = false;
|
|
3506
|
-
let usesSzcn = false;
|
|
3507
|
-
let usesSzPart = false;
|
|
3508
|
-
let usesColorVar = false;
|
|
3509
|
-
let transformed = false;
|
|
3510
|
-
let szClasses;
|
|
3511
4052
|
const hasSzProp = code.includes("sz=") || code.includes("szs=") || /\bsz\s*:\s*["'{]/.test(code) || code.includes('sz: "');
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
const result = vueAdapter.preprocess(code, options);
|
|
3515
|
-
if (result.transformed) {
|
|
3516
|
-
transformedCode = result.code;
|
|
3517
|
-
transformed = true;
|
|
3518
|
-
}
|
|
3519
|
-
} else if (id.endsWith(".svelte")) {
|
|
3520
|
-
const result = svelteAdapter.preprocess(code, options);
|
|
3521
|
-
if (result) {
|
|
3522
|
-
transformedCode = result.code;
|
|
3523
|
-
transformed = true;
|
|
3524
|
-
}
|
|
3525
|
-
} else {
|
|
3526
|
-
const transformStarted = node_perf_hooks.performance.now();
|
|
3527
|
-
const result = transformConfiguredSource(code, id);
|
|
3528
|
-
traceBenchTiming(
|
|
3529
|
-
"transform-hook",
|
|
3530
|
-
id,
|
|
3531
|
-
node_perf_hooks.performance.now() - transformStarted
|
|
3532
|
-
);
|
|
3533
|
-
transformedCode = result.code;
|
|
3534
|
-
usesRuntime = result.usesRuntime;
|
|
3535
|
-
usesMerge = result.usesMerge;
|
|
3536
|
-
usesSzcn = result.usesSzcn;
|
|
3537
|
-
usesSzPart = result.usesSzPart;
|
|
3538
|
-
usesColorVar = result.usesColorVar;
|
|
3539
|
-
transformed = result.transformed;
|
|
3540
|
-
szClasses = result.classes;
|
|
3541
|
-
recordFileVarMangleEntries(state, id, cssVariableEntries(result));
|
|
3542
|
-
recordFileCSSVariableMetrics(state, id, result.code);
|
|
3543
|
-
for (const msg of result.diagnostics) {
|
|
3544
|
-
if (msg.includes("unresolvable sz spread")) {
|
|
3545
|
-
state.spreadWarnings.add(`${id}
|
|
3546
|
-
${msg}`);
|
|
3547
|
-
} else if (msg.includes("AST budget exceeded")) {
|
|
3548
|
-
console.warn(`[csszyx] ${id}
|
|
3549
|
-
${msg}`);
|
|
3550
|
-
}
|
|
3551
|
-
}
|
|
3552
|
-
if (!quiet && result.diagnostics.length > 0 && process.env.NODE_ENV !== "production") {
|
|
3553
|
-
for (const msg of result.diagnostics) {
|
|
3554
|
-
if (msg.includes("unresolvable sz spread") || msg.includes("AST budget exceeded")) {
|
|
3555
|
-
continue;
|
|
3556
|
-
}
|
|
3557
|
-
this.warn(`[csszyx] ${id}
|
|
3558
|
-
${msg}`);
|
|
3559
|
-
}
|
|
3560
|
-
}
|
|
3561
|
-
for (const [token, data] of result.recoveryTokens) {
|
|
3562
|
-
state.recoveryTokens.set(token, data);
|
|
3563
|
-
}
|
|
3564
|
-
}
|
|
3565
|
-
} else if (shouldProcessSource(id)) {
|
|
4053
|
+
const output = hasSzProp ? transformSzSource(code, id, (message) => this.warn(message)) : unchangedPreTransform(code);
|
|
4054
|
+
if (!hasSzProp && shouldProcessSource(id)) {
|
|
3566
4055
|
recordFileVarMangleEntries(state, id, []);
|
|
3567
4056
|
recordFileCSSVariableMetrics(state, id, null);
|
|
3568
4057
|
}
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
transformedCode = `${transformedCode.slice(0, htmlTag.close)} ${attrName}="${CHECKSUM_PLACEHOLDER}"${transformedCode.slice(htmlTag.close)}`;
|
|
3574
|
-
}
|
|
3575
|
-
const debugScript = `<script dangerouslySetInnerHTML={{__html: \`(function(){var m=${MANGLE_MAP_PLACEHOLDER};var vm=${VAR_MANGLE_MAP_PLACEHOLDER};var gp=decodeURIComponent(${escapeJsonForInlineScript(JSON.stringify(encodedGlobalVarAliasPrefix))});var r={};var vr={};for(var k in m)r[m[k]]=k;for(var vk in vm){var vv=vm[vk];var vs=Array.isArray(vv)?vv:[vv];for(var vi=0;vi<vs.length;vi++)(vr[vs[vi]]||(vr[vs[vi]]=[])).push(vk)}window.__csszyx={mangleMap:m,varMangleMap:vm,checksum:"${CHECKSUM_PLACEHOLDER}",decode:function(c){return r[c]},encode:function(c){return m[c]},decodeVar:function(v){return vr[v]||[]},encodeVar:function(v){return vm[v]},decodeGlobalVar:function(v){var a=vr[v]||[];return v.indexOf(gp)===0?a[0]:void 0},decodeAll:function(el){return(el.className||"").split(" ").map(function(c){return r[c]||c})}}})()\`}} />`;
|
|
3576
|
-
const bodyTag = findOpeningTag(transformedCode, "body");
|
|
3577
|
-
if (bodyTag) {
|
|
3578
|
-
transformedCode = `${transformedCode.slice(0, bodyTag.close + 1)}${debugScript}${transformedCode.slice(bodyTag.close + 1)}`;
|
|
3579
|
-
}
|
|
3580
|
-
transformed = true;
|
|
4058
|
+
const layoutCode = injectLayoutHydration(output.code, id);
|
|
4059
|
+
if (layoutCode !== null) {
|
|
4060
|
+
output.code = layoutCode;
|
|
4061
|
+
output.transformed = true;
|
|
3581
4062
|
}
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
}
|
|
3587
|
-
if (usesMerge) {
|
|
3588
|
-
imports.push("_szMerge");
|
|
3589
|
-
}
|
|
3590
|
-
if (usesSzcn) {
|
|
3591
|
-
imports.push("_szcn");
|
|
3592
|
-
}
|
|
3593
|
-
if (usesSzPart) {
|
|
3594
|
-
imports.push("_szPart");
|
|
3595
|
-
}
|
|
3596
|
-
if (usesColorVar) {
|
|
3597
|
-
imports.push("__szColorVar");
|
|
3598
|
-
}
|
|
3599
|
-
const hasRuntimeImport = imports.length > 0 && transformedCode.includes("@csszyx/runtime");
|
|
3600
|
-
const needed = hasRuntimeImport ? imports.filter((name) => !runtimeImportScan.importsRuntimeHelper(transformedCode, name)) : imports;
|
|
3601
|
-
if (needed.length > 0) {
|
|
3602
|
-
const existingImport = runtimeImportScan.findRuntimeImportClause(transformedCode);
|
|
3603
|
-
if (existingImport) {
|
|
3604
|
-
transformedCode = transformedCode.replace(
|
|
3605
|
-
existingImport.statement,
|
|
3606
|
-
`${existingImport.prefixWithBody}, ${needed.join(", ")} } from '@csszyx/runtime'`
|
|
3607
|
-
);
|
|
3608
|
-
} else {
|
|
3609
|
-
const importStmt = `import { ${needed.join(", ")} } from '@csszyx/runtime';
|
|
3610
|
-
`;
|
|
3611
|
-
transformedCode = insertRuntimeImport(transformedCode, importStmt);
|
|
3612
|
-
}
|
|
3613
|
-
transformed = true;
|
|
3614
|
-
}
|
|
4063
|
+
const runtimeCode = injectRuntimeHelpers(output.code, output);
|
|
4064
|
+
if (runtimeCode !== null) {
|
|
4065
|
+
output.code = runtimeCode;
|
|
4066
|
+
output.transformed = true;
|
|
3615
4067
|
}
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
transformed = true;
|
|
4068
|
+
const themedCode = injectThemeGroups(code, output.code, id, output.usesSzcn);
|
|
4069
|
+
if (themedCode !== null) {
|
|
4070
|
+
output.code = themedCode;
|
|
4071
|
+
output.transformed = true;
|
|
3620
4072
|
}
|
|
3621
4073
|
if (matchesScriptExtension(id, SCRIPT_ID_EXTENSIONS)) {
|
|
3622
|
-
assertNoRSCBoundaryViolation(
|
|
3623
|
-
const record = createRSCModuleRecord(
|
|
4074
|
+
assertNoRSCBoundaryViolation(output.code, id);
|
|
4075
|
+
const record = createRSCModuleRecord(output.code, id);
|
|
3624
4076
|
state.rscModules.set(record.id, record);
|
|
3625
4077
|
}
|
|
3626
|
-
|
|
3627
|
-
if (szClasses !== void 0) {
|
|
3628
|
-
for (const cls of szClasses) {
|
|
3629
|
-
addSafelistClass(cls);
|
|
3630
|
-
state.ownedClasses.add(cls);
|
|
3631
|
-
}
|
|
3632
|
-
} else {
|
|
3633
|
-
extractClasses(transformedCode);
|
|
3634
|
-
}
|
|
3635
|
-
return { code: transformedCode, map: null };
|
|
3636
|
-
}
|
|
3637
|
-
return null;
|
|
4078
|
+
return collectPreTransformClasses(output);
|
|
3638
4079
|
},
|
|
3639
4080
|
/** Finalizes the mangle map after all source modules have been processed. */
|
|
3640
4081
|
buildEnd() {
|
|
@@ -3843,6 +4284,166 @@ ${transformedCode}`;
|
|
|
3843
4284
|
}
|
|
3844
4285
|
})
|
|
3845
4286
|
);
|
|
4287
|
+
function createBundleManifest(includeMangleMap) {
|
|
4288
|
+
const manifest = {
|
|
4289
|
+
version: "0.4.0",
|
|
4290
|
+
buildId: state.checksum,
|
|
4291
|
+
classes: Object.keys(state.mangleMap)
|
|
4292
|
+
};
|
|
4293
|
+
if (includeMangleMap && Object.keys(state.mangleMap).length > 0) {
|
|
4294
|
+
manifest.mangleMap = state.mangleMap;
|
|
4295
|
+
}
|
|
4296
|
+
if (Object.keys(state.varMangleMap).length > 0) {
|
|
4297
|
+
manifest.varMangleMap = state.varMangleMap;
|
|
4298
|
+
}
|
|
4299
|
+
const globalVarAliases = extractGlobalVarAliasesForManifest(
|
|
4300
|
+
state.varMangleMap,
|
|
4301
|
+
globalVarAliasPrefix,
|
|
4302
|
+
state.globalVarValidationResult
|
|
4303
|
+
);
|
|
4304
|
+
if (Object.keys(globalVarAliases).length > 0) {
|
|
4305
|
+
manifest.globalVarAliases = globalVarAliases;
|
|
4306
|
+
}
|
|
4307
|
+
if (hasCSSVariableMetrics(state.cssVarMetrics)) {
|
|
4308
|
+
manifest.cssVarMetrics = state.cssVarMetrics;
|
|
4309
|
+
}
|
|
4310
|
+
return manifest;
|
|
4311
|
+
}
|
|
4312
|
+
function isCssSyntaxError(error) {
|
|
4313
|
+
return !!error && typeof error === "object" && "name" in error && error.name === "CssSyntaxError";
|
|
4314
|
+
}
|
|
4315
|
+
function rewriteOutputCss(source, file, shouldMangle, mangledSources, externalClasses) {
|
|
4316
|
+
let css = rewriteCssWithValidatedGlobalVarPlan(
|
|
4317
|
+
source,
|
|
4318
|
+
file,
|
|
4319
|
+
state.globalVarValidationResult
|
|
4320
|
+
);
|
|
4321
|
+
if (!shouldMangle) return css;
|
|
4322
|
+
try {
|
|
4323
|
+
const result = cssMangler.mangleCSSSync(css, state.mangleMap, {
|
|
4324
|
+
debug: options.development?.debug,
|
|
4325
|
+
from: file
|
|
4326
|
+
});
|
|
4327
|
+
for (const className of result.mangledClasses) mangledSources.add(className);
|
|
4328
|
+
for (const className of result.unmangledClasses) externalClasses.add(className);
|
|
4329
|
+
if (result.transformedCount > 0) css = result.css;
|
|
4330
|
+
return css;
|
|
4331
|
+
} catch (error) {
|
|
4332
|
+
if (isCssSyntaxError(error)) return css;
|
|
4333
|
+
throw error;
|
|
4334
|
+
}
|
|
4335
|
+
}
|
|
4336
|
+
function reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses) {
|
|
4337
|
+
if (!shouldMangle) return;
|
|
4338
|
+
const message = mangleHybridHazardMessage(
|
|
4339
|
+
collectMangleHybridHazards(state.mangleMap, mangledSources, externalClasses)
|
|
4340
|
+
);
|
|
4341
|
+
if (message) console.warn(message);
|
|
4342
|
+
}
|
|
4343
|
+
function rewriteWebpackCodeAsset(file, source, shouldMangle, compilation, compiler) {
|
|
4344
|
+
if (shouldMangle && file.endsWith(".html")) {
|
|
4345
|
+
const mangledHtml = mangleHtmlClasses(source);
|
|
4346
|
+
if (mangledHtml !== source) {
|
|
4347
|
+
compilation.updateAsset(file, new compiler.webpack.sources.RawSource(mangledHtml));
|
|
4348
|
+
}
|
|
4349
|
+
return;
|
|
4350
|
+
}
|
|
4351
|
+
if (!file.endsWith(".js")) return;
|
|
4352
|
+
const rewritten = shouldMangle ? replacePlaceholders(mangleCodeClasses(source)) : replacePlaceholders(source);
|
|
4353
|
+
if (rewritten !== source) {
|
|
4354
|
+
compilation.updateAsset(file, new compiler.webpack.sources.RawSource(rewritten));
|
|
4355
|
+
}
|
|
4356
|
+
}
|
|
4357
|
+
function processWebpackAssets(assets, compilation, compiler) {
|
|
4358
|
+
finalizeMangleMap();
|
|
4359
|
+
state.globalVarValidationResult = validateGlobalVarBundleInputs(
|
|
4360
|
+
collectWebpackGlobalVarCssAssets(assets)
|
|
4361
|
+
);
|
|
4362
|
+
const shouldMangle = manglingEnabled && compiler.options.mode !== "development" && Object.keys(state.mangleMap).length > 0;
|
|
4363
|
+
const manifest = createBundleManifest(shouldMangle);
|
|
4364
|
+
compilation.emitAsset(
|
|
4365
|
+
"csszyx-manifest.json",
|
|
4366
|
+
new compiler.webpack.sources.RawSource(JSON.stringify(manifest))
|
|
4367
|
+
);
|
|
4368
|
+
if (shouldEmitGlobalVarMapAsset(globalVarMangleConfig)) {
|
|
4369
|
+
const globalVarMap = createGlobalVarMapAssetSource(
|
|
4370
|
+
state.varMangleMap,
|
|
4371
|
+
globalVarAliasPrefix,
|
|
4372
|
+
state.globalVarValidationResult
|
|
4373
|
+
);
|
|
4374
|
+
if (globalVarMap) {
|
|
4375
|
+
compilation.emitAsset(
|
|
4376
|
+
".csszyx/global-var-map.json",
|
|
4377
|
+
new compiler.webpack.sources.RawSource(globalVarMap)
|
|
4378
|
+
);
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4381
|
+
const mangledSources = /* @__PURE__ */ new Set();
|
|
4382
|
+
const externalClasses = /* @__PURE__ */ new Set();
|
|
4383
|
+
for (const file in assets) {
|
|
4384
|
+
const source = assets[file].source().toString();
|
|
4385
|
+
if (file.endsWith(".css")) {
|
|
4386
|
+
const css = rewriteOutputCss(
|
|
4387
|
+
source,
|
|
4388
|
+
file,
|
|
4389
|
+
shouldMangle,
|
|
4390
|
+
mangledSources,
|
|
4391
|
+
externalClasses
|
|
4392
|
+
);
|
|
4393
|
+
if (css !== source) {
|
|
4394
|
+
compilation.updateAsset(file, new compiler.webpack.sources.RawSource(css));
|
|
4395
|
+
}
|
|
4396
|
+
} else {
|
|
4397
|
+
rewriteWebpackCodeAsset(file, source, shouldMangle, compilation, compiler);
|
|
4398
|
+
}
|
|
4399
|
+
}
|
|
4400
|
+
reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses);
|
|
4401
|
+
}
|
|
4402
|
+
function rewriteViteBundleEntry(chunk, file, shouldMangle, mangledSources, externalClasses) {
|
|
4403
|
+
if (chunk.type === "asset" && chunk.fileName.endsWith(".css") && chunk.source !== void 0) {
|
|
4404
|
+
const originalCss = chunk.source.toString();
|
|
4405
|
+
const css = rewriteOutputCss(
|
|
4406
|
+
originalCss,
|
|
4407
|
+
file,
|
|
4408
|
+
shouldMangle,
|
|
4409
|
+
mangledSources,
|
|
4410
|
+
externalClasses
|
|
4411
|
+
);
|
|
4412
|
+
if (css !== originalCss) chunk.source = css;
|
|
4413
|
+
return;
|
|
4414
|
+
}
|
|
4415
|
+
if (chunk.type !== "chunk" || chunk.code === void 0) return;
|
|
4416
|
+
const rewritten = shouldMangle ? replacePlaceholders(mangleCodeClasses(chunk.code)) : replacePlaceholders(chunk.code);
|
|
4417
|
+
if (rewritten !== chunk.code) chunk.code = rewritten;
|
|
4418
|
+
}
|
|
4419
|
+
function processRollupBundle(bundle, emitAsset) {
|
|
4420
|
+
finalizeMangleMap();
|
|
4421
|
+
state.globalVarValidationResult = validateGlobalVarBundleInputs(
|
|
4422
|
+
collectRollupGlobalVarCssAssets(bundle)
|
|
4423
|
+
);
|
|
4424
|
+
const shouldMangle = manglingEnabled && Object.keys(state.mangleMap).length > 0;
|
|
4425
|
+
emitAsset("csszyx-manifest.json", JSON.stringify(createBundleManifest(shouldMangle)));
|
|
4426
|
+
if (shouldEmitGlobalVarMapAsset(globalVarMangleConfig)) {
|
|
4427
|
+
const globalVarMap = createGlobalVarMapAssetSource(
|
|
4428
|
+
state.varMangleMap,
|
|
4429
|
+
globalVarAliasPrefix,
|
|
4430
|
+
state.globalVarValidationResult
|
|
4431
|
+
);
|
|
4432
|
+
if (globalVarMap) emitAsset(".csszyx/global-var-map.json", globalVarMap);
|
|
4433
|
+
}
|
|
4434
|
+
const mangledSources = /* @__PURE__ */ new Set();
|
|
4435
|
+
const externalClasses = /* @__PURE__ */ new Set();
|
|
4436
|
+
for (const file in bundle) {
|
|
4437
|
+
rewriteViteBundleEntry(
|
|
4438
|
+
bundle[file],
|
|
4439
|
+
file,
|
|
4440
|
+
shouldMangle,
|
|
4441
|
+
mangledSources,
|
|
4442
|
+
externalClasses
|
|
4443
|
+
);
|
|
4444
|
+
}
|
|
4445
|
+
reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses);
|
|
4446
|
+
}
|
|
3846
4447
|
const postPlugin = unplugin$1.createUnplugin(() => ({
|
|
3847
4448
|
name: "csszyx:post",
|
|
3848
4449
|
enforce: "post",
|
|
@@ -3853,278 +4454,20 @@ ${transformedCode}`;
|
|
|
3853
4454
|
* @param compiler - the Webpack compiler instance
|
|
3854
4455
|
*/
|
|
3855
4456
|
webpack(compiler) {
|
|
3856
|
-
compiler
|
|
3857
|
-
const stage = compiler.webpack?.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE || compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE;
|
|
3858
|
-
compilation.hooks.processAssets.tap(
|
|
3859
|
-
{
|
|
3860
|
-
name: "csszyx:post",
|
|
3861
|
-
stage: stage || 400
|
|
3862
|
-
// Fallback integer
|
|
3863
|
-
},
|
|
3864
|
-
(assets) => {
|
|
3865
|
-
finalizeMangleMap();
|
|
3866
|
-
state.globalVarValidationResult = validateGlobalVarBundleInputs(
|
|
3867
|
-
collectWebpackGlobalVarCssAssets(assets)
|
|
3868
|
-
);
|
|
3869
|
-
const isWebpackDevMode = compiler.options.mode === "development";
|
|
3870
|
-
const manifestData = {
|
|
3871
|
-
version: "0.4.0",
|
|
3872
|
-
buildId: state.checksum,
|
|
3873
|
-
classes: Object.keys(state.mangleMap)
|
|
3874
|
-
};
|
|
3875
|
-
if (manglingEnabled && !isWebpackDevMode && Object.keys(state.mangleMap).length > 0) {
|
|
3876
|
-
manifestData.mangleMap = state.mangleMap;
|
|
3877
|
-
}
|
|
3878
|
-
if (Object.keys(state.varMangleMap).length > 0) {
|
|
3879
|
-
manifestData.varMangleMap = state.varMangleMap;
|
|
3880
|
-
}
|
|
3881
|
-
const globalVarAliases = extractGlobalVarAliasesForManifest(
|
|
3882
|
-
state.varMangleMap,
|
|
3883
|
-
globalVarAliasPrefix,
|
|
3884
|
-
state.globalVarValidationResult
|
|
3885
|
-
);
|
|
3886
|
-
if (Object.keys(globalVarAliases).length > 0) {
|
|
3887
|
-
manifestData.globalVarAliases = globalVarAliases;
|
|
3888
|
-
}
|
|
3889
|
-
if (hasCSSVariableMetrics(state.cssVarMetrics)) {
|
|
3890
|
-
manifestData.cssVarMetrics = state.cssVarMetrics;
|
|
3891
|
-
}
|
|
3892
|
-
compilation.emitAsset(
|
|
3893
|
-
"csszyx-manifest.json",
|
|
3894
|
-
new compiler.webpack.sources.RawSource(JSON.stringify(manifestData))
|
|
3895
|
-
);
|
|
3896
|
-
if (shouldEmitGlobalVarMapAsset(globalVarMangleConfig)) {
|
|
3897
|
-
const globalVarMapAsset = createGlobalVarMapAssetSource(
|
|
3898
|
-
state.varMangleMap,
|
|
3899
|
-
globalVarAliasPrefix,
|
|
3900
|
-
state.globalVarValidationResult
|
|
3901
|
-
);
|
|
3902
|
-
if (globalVarMapAsset) {
|
|
3903
|
-
compilation.emitAsset(
|
|
3904
|
-
".csszyx/global-var-map.json",
|
|
3905
|
-
new compiler.webpack.sources.RawSource(globalVarMapAsset)
|
|
3906
|
-
);
|
|
3907
|
-
}
|
|
3908
|
-
}
|
|
3909
|
-
const mangledSources = /* @__PURE__ */ new Set();
|
|
3910
|
-
const externalClasses = /* @__PURE__ */ new Set();
|
|
3911
|
-
for (const file in assets) {
|
|
3912
|
-
const asset = assets[file];
|
|
3913
|
-
const source = asset.source().toString();
|
|
3914
|
-
if (file.endsWith(".css")) {
|
|
3915
|
-
let css = rewriteCssWithValidatedGlobalVarPlan(
|
|
3916
|
-
source,
|
|
3917
|
-
file,
|
|
3918
|
-
state.globalVarValidationResult
|
|
3919
|
-
);
|
|
3920
|
-
if (manglingEnabled && !isWebpackDevMode && Object.keys(state.mangleMap).length > 0) {
|
|
3921
|
-
try {
|
|
3922
|
-
const result = cssMangler.mangleCSSSync(css, state.mangleMap, {
|
|
3923
|
-
debug: options.development?.debug,
|
|
3924
|
-
from: file
|
|
3925
|
-
});
|
|
3926
|
-
for (const c of result.mangledClasses) {
|
|
3927
|
-
mangledSources.add(c);
|
|
3928
|
-
}
|
|
3929
|
-
for (const c of result.unmangledClasses) {
|
|
3930
|
-
externalClasses.add(c);
|
|
3931
|
-
}
|
|
3932
|
-
if (result.transformedCount > 0) {
|
|
3933
|
-
css = result.css;
|
|
3934
|
-
}
|
|
3935
|
-
} catch (e) {
|
|
3936
|
-
if (e && typeof e === "object" && "name" in e && e.name === "CssSyntaxError") ; else {
|
|
3937
|
-
throw e;
|
|
3938
|
-
}
|
|
3939
|
-
}
|
|
3940
|
-
}
|
|
3941
|
-
if (css !== source) {
|
|
3942
|
-
compilation.updateAsset(
|
|
3943
|
-
file,
|
|
3944
|
-
new compiler.webpack.sources.RawSource(css)
|
|
3945
|
-
);
|
|
3946
|
-
}
|
|
3947
|
-
continue;
|
|
3948
|
-
}
|
|
3949
|
-
if (manglingEnabled && !isWebpackDevMode && Object.keys(state.mangleMap).length > 0) {
|
|
3950
|
-
if (file.endsWith(".html")) {
|
|
3951
|
-
const mangledHtml = source.replace(
|
|
3952
|
-
/\bclass="([^"]*)"/g,
|
|
3953
|
-
(_m, cls) => {
|
|
3954
|
-
const out = cls.split(/\s+/).filter(Boolean).map((c) => state.mangleMap[c] || c).join(" ");
|
|
3955
|
-
return out !== cls ? `class="${out}"` : _m;
|
|
3956
|
-
}
|
|
3957
|
-
).replace(
|
|
3958
|
-
/\bclass='([^']*)'/g,
|
|
3959
|
-
(_m, cls) => {
|
|
3960
|
-
const out = cls.split(/\s+/).filter(Boolean).map((c) => state.mangleMap[c] || c).join(" ");
|
|
3961
|
-
return out !== cls ? `class='${out}'` : _m;
|
|
3962
|
-
}
|
|
3963
|
-
);
|
|
3964
|
-
if (mangledHtml !== source) {
|
|
3965
|
-
compilation.updateAsset(
|
|
3966
|
-
file,
|
|
3967
|
-
new compiler.webpack.sources.RawSource(mangledHtml)
|
|
3968
|
-
);
|
|
3969
|
-
continue;
|
|
3970
|
-
}
|
|
3971
|
-
} else if (file.endsWith(".js")) {
|
|
3972
|
-
let mangled = mangleCodeClasses(source);
|
|
3973
|
-
mangled = replacePlaceholders(mangled);
|
|
3974
|
-
if (mangled !== source) {
|
|
3975
|
-
compilation.updateAsset(
|
|
3976
|
-
file,
|
|
3977
|
-
new compiler.webpack.sources.RawSource(mangled)
|
|
3978
|
-
);
|
|
3979
|
-
continue;
|
|
3980
|
-
}
|
|
3981
|
-
}
|
|
3982
|
-
}
|
|
3983
|
-
if (file.endsWith(".js") && (source.includes(CHECKSUM_PLACEHOLDER) || source.includes(MANGLE_MAP_PLACEHOLDER))) {
|
|
3984
|
-
const replaced = replacePlaceholders(source);
|
|
3985
|
-
if (replaced !== source) {
|
|
3986
|
-
compilation.updateAsset(
|
|
3987
|
-
file,
|
|
3988
|
-
new compiler.webpack.sources.RawSource(replaced)
|
|
3989
|
-
);
|
|
3990
|
-
}
|
|
3991
|
-
}
|
|
3992
|
-
}
|
|
3993
|
-
if (manglingEnabled && !isWebpackDevMode && Object.keys(state.mangleMap).length > 0) {
|
|
3994
|
-
const hazardMessage = mangleHybridHazardMessage(
|
|
3995
|
-
collectMangleHybridHazards(
|
|
3996
|
-
state.mangleMap,
|
|
3997
|
-
mangledSources,
|
|
3998
|
-
externalClasses
|
|
3999
|
-
)
|
|
4000
|
-
);
|
|
4001
|
-
if (hazardMessage) {
|
|
4002
|
-
console.warn(hazardMessage);
|
|
4003
|
-
}
|
|
4004
|
-
}
|
|
4005
|
-
}
|
|
4006
|
-
);
|
|
4007
|
-
});
|
|
4457
|
+
registerWebpackAssetProcessor(compiler, processWebpackAssets);
|
|
4008
4458
|
},
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
);
|
|
4020
|
-
|
|
4021
|
-
version: "0.4.0",
|
|
4022
|
-
buildId: state.checksum,
|
|
4023
|
-
classes: Object.keys(state.mangleMap)
|
|
4024
|
-
};
|
|
4025
|
-
if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
|
|
4026
|
-
manifestData.mangleMap = state.mangleMap;
|
|
4027
|
-
}
|
|
4028
|
-
if (Object.keys(state.varMangleMap).length > 0) {
|
|
4029
|
-
manifestData.varMangleMap = state.varMangleMap;
|
|
4030
|
-
}
|
|
4031
|
-
const globalVarAliases = extractGlobalVarAliasesForManifest(
|
|
4032
|
-
state.varMangleMap,
|
|
4033
|
-
globalVarAliasPrefix,
|
|
4034
|
-
state.globalVarValidationResult
|
|
4035
|
-
);
|
|
4036
|
-
if (Object.keys(globalVarAliases).length > 0) {
|
|
4037
|
-
manifestData.globalVarAliases = globalVarAliases;
|
|
4038
|
-
}
|
|
4039
|
-
if (hasCSSVariableMetrics(state.cssVarMetrics)) {
|
|
4040
|
-
manifestData.cssVarMetrics = state.cssVarMetrics;
|
|
4041
|
-
}
|
|
4042
|
-
this.emitFile({
|
|
4043
|
-
type: "asset",
|
|
4044
|
-
fileName: "csszyx-manifest.json",
|
|
4045
|
-
source: JSON.stringify(manifestData)
|
|
4046
|
-
});
|
|
4047
|
-
if (shouldEmitGlobalVarMapAsset(globalVarMangleConfig)) {
|
|
4048
|
-
const globalVarMapAsset = createGlobalVarMapAssetSource(
|
|
4049
|
-
state.varMangleMap,
|
|
4050
|
-
globalVarAliasPrefix,
|
|
4051
|
-
state.globalVarValidationResult
|
|
4052
|
-
);
|
|
4053
|
-
if (globalVarMapAsset) {
|
|
4054
|
-
this.emitFile({
|
|
4055
|
-
type: "asset",
|
|
4056
|
-
fileName: ".csszyx/global-var-map.json",
|
|
4057
|
-
source: globalVarMapAsset
|
|
4058
|
-
});
|
|
4059
|
-
}
|
|
4060
|
-
}
|
|
4061
|
-
const mangledSources = /* @__PURE__ */ new Set();
|
|
4062
|
-
const externalClasses = /* @__PURE__ */ new Set();
|
|
4063
|
-
for (const file in bundle) {
|
|
4064
|
-
const chunk = bundle[file];
|
|
4065
|
-
if (chunk.type === "asset" && chunk.fileName.endsWith(".css")) {
|
|
4066
|
-
const originalCss = chunk.source.toString();
|
|
4067
|
-
let css = rewriteCssWithValidatedGlobalVarPlan(
|
|
4068
|
-
originalCss,
|
|
4069
|
-
file,
|
|
4070
|
-
state.globalVarValidationResult
|
|
4071
|
-
);
|
|
4072
|
-
if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
|
|
4073
|
-
try {
|
|
4074
|
-
const result = cssMangler.mangleCSSSync(css, state.mangleMap, {
|
|
4075
|
-
debug: options.development?.debug,
|
|
4076
|
-
from: file
|
|
4077
|
-
});
|
|
4078
|
-
for (const c of result.mangledClasses) {
|
|
4079
|
-
mangledSources.add(c);
|
|
4080
|
-
}
|
|
4081
|
-
for (const c of result.unmangledClasses) {
|
|
4082
|
-
externalClasses.add(c);
|
|
4083
|
-
}
|
|
4084
|
-
if (result.transformedCount > 0) {
|
|
4085
|
-
css = result.css;
|
|
4086
|
-
}
|
|
4087
|
-
} catch (e) {
|
|
4088
|
-
if (e && typeof e === "object" && "name" in e && e.name === "CssSyntaxError") ; else {
|
|
4089
|
-
throw e;
|
|
4090
|
-
}
|
|
4091
|
-
}
|
|
4092
|
-
}
|
|
4093
|
-
if (css !== originalCss) {
|
|
4094
|
-
chunk.source = css;
|
|
4095
|
-
}
|
|
4096
|
-
continue;
|
|
4097
|
-
}
|
|
4098
|
-
if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
|
|
4099
|
-
if (chunk.type === "chunk") {
|
|
4100
|
-
let mangledCode = mangleCodeClasses(chunk.code);
|
|
4101
|
-
mangledCode = replacePlaceholders(mangledCode);
|
|
4102
|
-
if (mangledCode !== chunk.code) {
|
|
4103
|
-
chunk.code = mangledCode;
|
|
4104
|
-
}
|
|
4105
|
-
continue;
|
|
4106
|
-
}
|
|
4107
|
-
}
|
|
4108
|
-
if (chunk.type === "chunk" && (chunk.code.includes(CHECKSUM_PLACEHOLDER) || chunk.code.includes(MANGLE_MAP_PLACEHOLDER))) {
|
|
4109
|
-
const replaced = replacePlaceholders(chunk.code);
|
|
4110
|
-
if (replaced !== chunk.code) {
|
|
4111
|
-
chunk.code = replaced;
|
|
4112
|
-
}
|
|
4113
|
-
}
|
|
4114
|
-
}
|
|
4115
|
-
if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
|
|
4116
|
-
const hazardMessage = mangleHybridHazardMessage(
|
|
4117
|
-
collectMangleHybridHazards(
|
|
4118
|
-
state.mangleMap,
|
|
4119
|
-
mangledSources,
|
|
4120
|
-
externalClasses
|
|
4121
|
-
)
|
|
4122
|
-
);
|
|
4123
|
-
if (hazardMessage) {
|
|
4124
|
-
console.warn(hazardMessage);
|
|
4125
|
-
}
|
|
4126
|
-
}
|
|
4127
|
-
}
|
|
4459
|
+
/**
|
|
4460
|
+
* Rollup-compatible hook used by both pure Rollup and Vite adapters.
|
|
4461
|
+
*
|
|
4462
|
+
* @param this Rollup-compatible output hook context.
|
|
4463
|
+
* @param this.emitFile Output asset emitter.
|
|
4464
|
+
* @param _options Output options (unused).
|
|
4465
|
+
* @param bundle Complete Rollup output bundle.
|
|
4466
|
+
*/
|
|
4467
|
+
generateBundle(_options, bundle) {
|
|
4468
|
+
processRollupBundle(bundle, (fileName, source) => {
|
|
4469
|
+
this.emitFile({ type: "asset", fileName, source });
|
|
4470
|
+
});
|
|
4128
4471
|
}
|
|
4129
4472
|
}));
|
|
4130
4473
|
return { prePlugin, postPlugin };
|
|
@@ -4156,7 +4499,16 @@ const rollupPlugin = (options = {}) => {
|
|
|
4156
4499
|
];
|
|
4157
4500
|
};
|
|
4158
4501
|
const esbuildPlugin = (options = {}) => {
|
|
4159
|
-
|
|
4502
|
+
if (options.production?.mangle === true) {
|
|
4503
|
+
console.warn(
|
|
4504
|
+
"[csszyx] production.mangle is not supported by the esbuild adapter; class mangling is disabled so emitted JS and CSS keep matching names."
|
|
4505
|
+
);
|
|
4506
|
+
}
|
|
4507
|
+
const safeOptions = {
|
|
4508
|
+
...options,
|
|
4509
|
+
production: { ...options.production, mangle: false }
|
|
4510
|
+
};
|
|
4511
|
+
const { prePlugin, postPlugin } = createCsszyxPlugins(safeOptions);
|
|
4160
4512
|
return {
|
|
4161
4513
|
name: "csszyx",
|
|
4162
4514
|
/**
|
|
@@ -4165,8 +4517,8 @@ const esbuildPlugin = (options = {}) => {
|
|
|
4165
4517
|
*/
|
|
4166
4518
|
setup(build) {
|
|
4167
4519
|
const b = build;
|
|
4168
|
-
prePlugin.esbuild(
|
|
4169
|
-
postPlugin.esbuild(
|
|
4520
|
+
prePlugin.esbuild(safeOptions).setup(b);
|
|
4521
|
+
postPlugin.esbuild(safeOptions).setup(b);
|
|
4170
4522
|
}
|
|
4171
4523
|
};
|
|
4172
4524
|
};
|
|
@@ -4200,6 +4552,7 @@ exports.isPackagesSkippedSource = isPackagesSkippedSource;
|
|
|
4200
4552
|
exports.isRSCServerModule = isRSCServerModule;
|
|
4201
4553
|
exports.isTailwindReservedGlobalVar = isTailwindReservedGlobalVar;
|
|
4202
4554
|
exports.mangleCodeClassesSync = mangleCodeClassesSync;
|
|
4555
|
+
exports.mangleEligibleClasses = mangleEligibleClasses;
|
|
4203
4556
|
exports.mangleHybridHazardMessage = mangleHybridHazardMessage;
|
|
4204
4557
|
exports.mergeThemes = mergeThemes;
|
|
4205
4558
|
exports.missingTailwindEntryMessage = missingTailwindEntryMessage;
|