@csszyx/unplugin 0.9.9 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +16 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.mts +4 -2
- package/dist/index.mjs +2 -1
- package/dist/next-prebuild.cjs +2 -1
- package/dist/next-prebuild.mjs +2 -1
- package/dist/next-turbo-loader.cjs +14 -2
- package/dist/next-turbo-loader.mjs +14 -2
- package/dist/next-watcher.cjs +2 -1
- package/dist/next-watcher.mjs +2 -1
- package/dist/shared/unplugin.3UumZ5gn.mjs +5 -0
- package/dist/shared/{unplugin.CMNZChGZ.d.cts → unplugin.BqLCtc84.d.cts} +164 -2
- package/dist/shared/{unplugin.CMNZChGZ.d.mts → unplugin.BqLCtc84.d.mts} +164 -2
- package/dist/shared/{unplugin.CMsKFZ-l.mjs → unplugin.CLXpKBe4.mjs} +362 -90
- package/dist/shared/{unplugin.BtQzlC2C.mjs → unplugin.CLjhn81z.mjs} +47 -4
- package/dist/shared/{unplugin.s62yJbu1.cjs → unplugin.Cwe-dz1f.cjs} +48 -5
- package/dist/shared/{unplugin.Dfao2VkS.cjs → unplugin.Dk6ddrZX.cjs} +377 -91
- package/dist/shared/unplugin.DoBHTRra.cjs +7 -0
- package/dist/vite.cjs +2 -1
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.mts +1 -1
- package/dist/vite.mjs +2 -1
- package/dist/webpack.cjs +2 -1
- package/dist/webpack.d.cts +1 -1
- package/dist/webpack.d.mts +1 -1
- package/dist/webpack.mjs +2 -1
- package/package.json +8 -8
|
@@ -13,6 +13,7 @@ import { isTailwindReservedCustomProperty, CSSZYX_GLOBAL_ALIAS_PREFIX, isCsszyxG
|
|
|
13
13
|
import { preprocess } from '@csszyx/vue-adapter';
|
|
14
14
|
import { createUnplugin } from 'unplugin';
|
|
15
15
|
import { mangleCSSSync } from '../css-mangler.mjs';
|
|
16
|
+
import { e as escapeHtmlAttribute } from './unplugin.3UumZ5gn.mjs';
|
|
16
17
|
import { createHash } from 'node:crypto';
|
|
17
18
|
import { r as resolveTransformCacheDir, c as createTransformCacheKey, a as readTransformCache, w as writeTransformCache, e as evictOldTransformCacheEntries } from './unplugin.BpWUtI9U.mjs';
|
|
18
19
|
import postcss from 'postcss';
|
|
@@ -454,15 +455,7 @@ const CLIENT_RUNTIME_MODULES = /* @__PURE__ */ new Set(["csszyx/browser"]);
|
|
|
454
455
|
const CLIENT_RUNTIME_MODULE_ROOTS = ["@csszyx/dynamic", "csszyx/dynamic"];
|
|
455
456
|
const normalizedModuleIdCache = /* @__PURE__ */ new Map();
|
|
456
457
|
const resolvedLocalModuleCache = /* @__PURE__ */ new Map();
|
|
457
|
-
const FORBIDDEN_SYMBOLS = /* @__PURE__ */ new Set([
|
|
458
|
-
"_sz",
|
|
459
|
-
"_sz2",
|
|
460
|
-
"_sz3",
|
|
461
|
-
"_szIf",
|
|
462
|
-
"_szMerge",
|
|
463
|
-
"_szSwitch",
|
|
464
|
-
"__csszyx_runtime__"
|
|
465
|
-
]);
|
|
458
|
+
const FORBIDDEN_SYMBOLS = /* @__PURE__ */ new Set(["_sz", "_sz2", "_sz3", "_szMerge", "__csszyx_runtime__"]);
|
|
466
459
|
function hasUseServerDirective(code) {
|
|
467
460
|
for (const statement of readDirectivePrologue(code)) {
|
|
468
461
|
if (SERVER_DIRECTIVE_RE.test(statement)) {
|
|
@@ -841,7 +834,10 @@ function resolveLocalModule(importer, source) {
|
|
|
841
834
|
const cacheKey = `${importer}\0${source}`;
|
|
842
835
|
const cached = resolvedLocalModuleCache.get(cacheKey);
|
|
843
836
|
if (cached) {
|
|
844
|
-
|
|
837
|
+
if (fs.existsSync(cached)) {
|
|
838
|
+
return cached;
|
|
839
|
+
}
|
|
840
|
+
resolvedLocalModuleCache.delete(cacheKey);
|
|
845
841
|
}
|
|
846
842
|
const base = source.startsWith("/") ? source : path.resolve(path.dirname(importer), source);
|
|
847
843
|
const candidates = [
|
|
@@ -1006,7 +1002,14 @@ function stripCommentsForImportScan(code) {
|
|
|
1006
1002
|
return out;
|
|
1007
1003
|
}
|
|
1008
1004
|
|
|
1009
|
-
const EMPTY_THEME = {
|
|
1005
|
+
const EMPTY_THEME = {
|
|
1006
|
+
colors: [],
|
|
1007
|
+
spacings: [],
|
|
1008
|
+
fonts: [],
|
|
1009
|
+
radii: [],
|
|
1010
|
+
shadows: [],
|
|
1011
|
+
breakpoints: []
|
|
1012
|
+
};
|
|
1010
1013
|
function stripLayerWrappers(css) {
|
|
1011
1014
|
let result = "";
|
|
1012
1015
|
let i = 0;
|
|
@@ -1074,12 +1077,15 @@ function categorizeProperty(prop) {
|
|
|
1074
1077
|
["spacing-", "spacings"],
|
|
1075
1078
|
["font-", "fonts"],
|
|
1076
1079
|
["radius-", "radii"],
|
|
1077
|
-
["shadow-", "shadows"]
|
|
1080
|
+
["shadow-", "shadows"],
|
|
1081
|
+
["breakpoint-", "breakpoints"]
|
|
1078
1082
|
];
|
|
1079
1083
|
for (const [prefix, category] of categoryMap) {
|
|
1080
1084
|
if (prop.startsWith(prefix)) {
|
|
1081
1085
|
let token = prop.slice(prefix.length);
|
|
1082
|
-
|
|
1086
|
+
if (category !== "breakpoints") {
|
|
1087
|
+
token = token.replace(/-\d+$/, "");
|
|
1088
|
+
}
|
|
1083
1089
|
if (token) {
|
|
1084
1090
|
return { category, token };
|
|
1085
1091
|
}
|
|
@@ -1093,7 +1099,8 @@ function parseThemeBlocks(cssContent) {
|
|
|
1093
1099
|
spacings: /* @__PURE__ */ new Set(),
|
|
1094
1100
|
fonts: /* @__PURE__ */ new Set(),
|
|
1095
1101
|
radii: /* @__PURE__ */ new Set(),
|
|
1096
|
-
shadows: /* @__PURE__ */ new Set()
|
|
1102
|
+
shadows: /* @__PURE__ */ new Set(),
|
|
1103
|
+
breakpoints: /* @__PURE__ */ new Set()
|
|
1097
1104
|
};
|
|
1098
1105
|
const stripped = stripLayerWrappers(cssContent);
|
|
1099
1106
|
const blocks = extractThemeBlocks(stripped);
|
|
@@ -1111,7 +1118,8 @@ function parseThemeBlocks(cssContent) {
|
|
|
1111
1118
|
spacings: [...result.spacings].sort(),
|
|
1112
1119
|
fonts: [...result.fonts].sort(),
|
|
1113
1120
|
radii: [...result.radii].sort(),
|
|
1114
|
-
shadows: [...result.shadows].sort()
|
|
1121
|
+
shadows: [...result.shadows].sort(),
|
|
1122
|
+
breakpoints: [...result.breakpoints].sort()
|
|
1115
1123
|
};
|
|
1116
1124
|
}
|
|
1117
1125
|
function mergeThemes(themes) {
|
|
@@ -1123,7 +1131,8 @@ function mergeThemes(themes) {
|
|
|
1123
1131
|
spacings: /* @__PURE__ */ new Set(),
|
|
1124
1132
|
fonts: /* @__PURE__ */ new Set(),
|
|
1125
1133
|
radii: /* @__PURE__ */ new Set(),
|
|
1126
|
-
shadows: /* @__PURE__ */ new Set()
|
|
1134
|
+
shadows: /* @__PURE__ */ new Set(),
|
|
1135
|
+
breakpoints: /* @__PURE__ */ new Set()
|
|
1127
1136
|
};
|
|
1128
1137
|
for (const theme of themes) {
|
|
1129
1138
|
for (const cat of Object.keys(merged)) {
|
|
@@ -1137,7 +1146,8 @@ function mergeThemes(themes) {
|
|
|
1137
1146
|
spacings: [...merged.spacings].sort(),
|
|
1138
1147
|
fonts: [...merged.fonts].sort(),
|
|
1139
1148
|
radii: [...merged.radii].sort(),
|
|
1140
|
-
shadows: [...merged.shadows].sort()
|
|
1149
|
+
shadows: [...merged.shadows].sort(),
|
|
1150
|
+
breakpoints: [...merged.breakpoints].sort()
|
|
1141
1151
|
};
|
|
1142
1152
|
}
|
|
1143
1153
|
function hasTokens(theme) {
|
|
@@ -1425,11 +1435,15 @@ function isSameFileVersion(before, after) {
|
|
|
1425
1435
|
return before.dev === after.dev && before.ino === after.ino && before.size === after.size && before.mtimeNs === after.mtimeNs && before.ctimeNs === after.ctimeNs;
|
|
1426
1436
|
}
|
|
1427
1437
|
|
|
1438
|
+
function escapeTsString(value) {
|
|
1439
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
|
|
1440
|
+
}
|
|
1428
1441
|
function generateThemeDts(opts) {
|
|
1429
1442
|
const { theme, sourceFiles } = opts;
|
|
1430
1443
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1431
|
-
const sources = sourceFiles.join(", ");
|
|
1432
|
-
const toUnion = (tokens) => tokens.map((t) => `'${t}'`).join(" | ");
|
|
1444
|
+
const sources = sourceFiles.join(", ").replace(/[\r\n]/g, " ");
|
|
1445
|
+
const toUnion = (tokens) => tokens.map((t) => `'${escapeTsString(t)}'`).join(" | ");
|
|
1446
|
+
const quoteKey = (key) => /^[a-z_$][\w$]*$/i.test(key) ? key : `'${escapeTsString(key)}'`;
|
|
1433
1447
|
const entries = [];
|
|
1434
1448
|
if (theme.colors.length > 0) {
|
|
1435
1449
|
entries.push(` colors: ${toUnion(theme.colors)};`);
|
|
@@ -1446,19 +1460,36 @@ function generateThemeDts(opts) {
|
|
|
1446
1460
|
if (theme.shadows.length > 0) {
|
|
1447
1461
|
entries.push(` shadows: ${toUnion(theme.shadows)};`);
|
|
1448
1462
|
}
|
|
1449
|
-
|
|
1450
|
-
"// Auto-generated by csszyx theme-scanner \u2014 DO NOT EDIT",
|
|
1451
|
-
`// Source: ${sources}`,
|
|
1452
|
-
`// Updated: ${timestamp}`,
|
|
1453
|
-
"",
|
|
1454
|
-
"declare module '@csszyx/compiler' {",
|
|
1463
|
+
const moduleBody = [
|
|
1455
1464
|
" /**",
|
|
1456
1465
|
" * Custom design tokens extracted from @theme blocks.",
|
|
1457
1466
|
" * These tokens are surfaced in sz prop IntelliSense.",
|
|
1458
1467
|
" */",
|
|
1459
1468
|
" interface CustomTheme {",
|
|
1460
1469
|
...entries,
|
|
1461
|
-
" }"
|
|
1470
|
+
" }"
|
|
1471
|
+
];
|
|
1472
|
+
if (theme.breakpoints.length > 0) {
|
|
1473
|
+
const variantEntries = theme.breakpoints.map(
|
|
1474
|
+
(bp) => ` ${quoteKey(bp)}?: SzPropsBase;`
|
|
1475
|
+
);
|
|
1476
|
+
moduleBody.push(
|
|
1477
|
+
" /**",
|
|
1478
|
+
" * Custom responsive breakpoints from @theme (--breakpoint-*),",
|
|
1479
|
+
" * surfaced as typed sz variant keys.",
|
|
1480
|
+
" */",
|
|
1481
|
+
" interface VariantModifiers {",
|
|
1482
|
+
...variantEntries,
|
|
1483
|
+
" }"
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1486
|
+
return [
|
|
1487
|
+
"// Auto-generated by csszyx theme-scanner \u2014 DO NOT EDIT",
|
|
1488
|
+
`// Source: ${sources}`,
|
|
1489
|
+
`// Updated: ${timestamp}`,
|
|
1490
|
+
"",
|
|
1491
|
+
"declare module '@csszyx/compiler' {",
|
|
1492
|
+
...moduleBody,
|
|
1462
1493
|
"}",
|
|
1463
1494
|
"",
|
|
1464
1495
|
"export {};",
|
|
@@ -1532,6 +1563,7 @@ const UNKNOWN_PACKAGE_VERSION = "0.0.0";
|
|
|
1532
1563
|
const TRANSFORM_CACHE_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
1533
1564
|
const TRANSFORM_CACHE_MAX_ENTRIES = 1e4;
|
|
1534
1565
|
const TRANSFORM_MEMORY_CACHE_MAX_ENTRIES = 1e3;
|
|
1566
|
+
const MAX_SAFELIST_CLASSES = 1e5;
|
|
1535
1567
|
const DEFAULT_VAR_MANGLE_MAP_MAX_BYTES = 100 * 1024;
|
|
1536
1568
|
const GLOBAL_VAR_ALIAS_MAP_OWNER = "\0csszyx:global-var-aliases";
|
|
1537
1569
|
const DIRECTIVE_PROLOGUE_PREFIX_RE = /^((?:\s|\/\/[^\n]*\n|\/\*(?:[^*]|\*(?!\/))*\*\/)*)(['"]use (?:client|server)['"];?\s*)/;
|
|
@@ -1572,6 +1604,133 @@ function resolveNativeCacheIdentity() {
|
|
|
1572
1604
|
}
|
|
1573
1605
|
const BENCH_TRACE_ENABLED = process.env.CSSZYX_BENCH_TRACE === "1";
|
|
1574
1606
|
const BENCH_TRACE_FILE = process.env.CSSZYX_BENCH_TRACE_FILE;
|
|
1607
|
+
function appendTailwindSourceDirective(code, relPath) {
|
|
1608
|
+
const directive = `@source "${relPath}";`;
|
|
1609
|
+
if (code.includes(directive)) {
|
|
1610
|
+
return null;
|
|
1611
|
+
}
|
|
1612
|
+
const separator = code.length === 0 || code.endsWith("\n") ? "" : "\n";
|
|
1613
|
+
return `${code}${separator}${directive}
|
|
1614
|
+
`;
|
|
1615
|
+
}
|
|
1616
|
+
function stripCssBlockComments(code) {
|
|
1617
|
+
const SLASH = 47;
|
|
1618
|
+
const STAR = 42;
|
|
1619
|
+
let out = "";
|
|
1620
|
+
let last = 0;
|
|
1621
|
+
let i = 0;
|
|
1622
|
+
const n = code.length;
|
|
1623
|
+
while (i < n) {
|
|
1624
|
+
if (code.charCodeAt(i) === SLASH && code.charCodeAt(i + 1) === STAR) {
|
|
1625
|
+
out += code.slice(last, i);
|
|
1626
|
+
i += 2;
|
|
1627
|
+
while (i < n && !(code.charCodeAt(i) === STAR && code.charCodeAt(i + 1) === SLASH)) {
|
|
1628
|
+
i++;
|
|
1629
|
+
}
|
|
1630
|
+
i += 2;
|
|
1631
|
+
last = i;
|
|
1632
|
+
} else {
|
|
1633
|
+
i++;
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
return out + code.slice(last);
|
|
1637
|
+
}
|
|
1638
|
+
function cssImportsTailwind(code) {
|
|
1639
|
+
const withoutBlockComments = stripCssBlockComments(code);
|
|
1640
|
+
return /@import\s+["']tailwindcss(?:\/[^"']*)?["']/.test(withoutBlockComments);
|
|
1641
|
+
}
|
|
1642
|
+
function hasInjectableTailwindCandidate(classes) {
|
|
1643
|
+
for (const c of classes) {
|
|
1644
|
+
if (c.length >= 2 && /^[a-z]/.test(c)) {
|
|
1645
|
+
return true;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
return false;
|
|
1649
|
+
}
|
|
1650
|
+
function shouldWarnMissingTailwindEntry(ownedClassCount, sawTailwindEntry) {
|
|
1651
|
+
return ownedClassCount > 0 && !sawTailwindEntry;
|
|
1652
|
+
}
|
|
1653
|
+
function missingTailwindEntryMessage(ownedClassCount) {
|
|
1654
|
+
return `[csszyx] generated ${ownedClassCount} sz class(es) but found no CSS entry importing "tailwindcss" \u2014 those classes will produce no CSS. Import "tailwindcss" in a CSS file (csszyx auto-injects @source for the generated classes) so Tailwind emits their styles.`;
|
|
1655
|
+
}
|
|
1656
|
+
function cssHasContentScope(code) {
|
|
1657
|
+
const s = stripCssBlockComments(code);
|
|
1658
|
+
return /@import\s+["']tailwindcss(?:\/[^"']*)?["']\s+source\(/.test(s) || /@source\s+not\b/.test(s);
|
|
1659
|
+
}
|
|
1660
|
+
function isMonorepoPackage(root) {
|
|
1661
|
+
let dir = path.dirname(path.resolve(root));
|
|
1662
|
+
const { root: fsRoot } = path.parse(dir);
|
|
1663
|
+
while (dir !== fsRoot) {
|
|
1664
|
+
if (fs.existsSync(path.join(dir, "pnpm-workspace.yaml")) || fs.existsSync(path.join(dir, "nx.json")) || fs.existsSync(path.join(dir, "lerna.json"))) {
|
|
1665
|
+
return true;
|
|
1666
|
+
}
|
|
1667
|
+
const pkgPath = path.join(dir, "package.json");
|
|
1668
|
+
if (fs.existsSync(pkgPath)) {
|
|
1669
|
+
try {
|
|
1670
|
+
if ("workspaces" in JSON.parse(fs.readFileSync(pkgPath, "utf8"))) {
|
|
1671
|
+
return true;
|
|
1672
|
+
}
|
|
1673
|
+
} catch {
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
dir = path.dirname(dir);
|
|
1677
|
+
}
|
|
1678
|
+
return false;
|
|
1679
|
+
}
|
|
1680
|
+
function shouldWarnUnscopedMonorepo(sawTailwindEntry, tailwindEntryScoped, inMonorepo) {
|
|
1681
|
+
return sawTailwindEntry && !tailwindEntryScoped && inMonorepo;
|
|
1682
|
+
}
|
|
1683
|
+
function unscopedMonorepoMessage() {
|
|
1684
|
+
return '[csszyx] Tailwind content detection is UNSCOPED in a monorepo. Tailwind v4 climbs to the workspace root and scans sibling packages + docs (.md/.mdx/.txt are not ignored), which can generate phantom or broken url() classes and fail the build. Scope it in your Tailwind CSS entry:\n @import "tailwindcss" source(none);\n @source "."; /* this package, relative to the CSS file */\ncsszyx auto-injects @source for its generated classes, so only your own templates need listing. Guide: https://csszyx.com/docs/monorepo-content-scope/\nSilence (if a broad scan is intentional): csszyx({ contentScopeCheck: false }).';
|
|
1685
|
+
}
|
|
1686
|
+
function isCompilePackageOptedIn(id, compilePackages) {
|
|
1687
|
+
const path2 = id.replace(/\\/g, "/");
|
|
1688
|
+
if (path2.includes("node_modules")) {
|
|
1689
|
+
return false;
|
|
1690
|
+
}
|
|
1691
|
+
return compilePackages.some((name) => path2.includes(`/packages/${name}/`));
|
|
1692
|
+
}
|
|
1693
|
+
function isHardIgnoredPath(id, compilePackages = []) {
|
|
1694
|
+
const path2 = id.replace(/\\/g, "/");
|
|
1695
|
+
if (path2.includes("node_modules")) {
|
|
1696
|
+
return true;
|
|
1697
|
+
}
|
|
1698
|
+
if (path2.includes(".next") && !path2.includes("static")) {
|
|
1699
|
+
return true;
|
|
1700
|
+
}
|
|
1701
|
+
if (path2.includes("/packages/")) {
|
|
1702
|
+
return !isCompilePackageOptedIn(path2, compilePackages);
|
|
1703
|
+
}
|
|
1704
|
+
return false;
|
|
1705
|
+
}
|
|
1706
|
+
function isPackagesSkippedSource(id, compilePackages = []) {
|
|
1707
|
+
const path2 = id.replace(/\\/g, "/");
|
|
1708
|
+
if (path2.includes("node_modules")) {
|
|
1709
|
+
return false;
|
|
1710
|
+
}
|
|
1711
|
+
if (path2.includes(".next") && !path2.includes("static")) {
|
|
1712
|
+
return false;
|
|
1713
|
+
}
|
|
1714
|
+
if (!path2.includes("/packages/")) {
|
|
1715
|
+
return false;
|
|
1716
|
+
}
|
|
1717
|
+
return !isCompilePackageOptedIn(path2, compilePackages);
|
|
1718
|
+
}
|
|
1719
|
+
function skippedSzFilesMessage(files) {
|
|
1720
|
+
const list = files.map((file) => ` - ${file}`).join("\n");
|
|
1721
|
+
return `[csszyx] ${files.length} file(s) under packages/ contain \`sz\` but were skipped by ignore rules:
|
|
1722
|
+
${list}
|
|
1723
|
+
Add the package to \`compilePackages\` (or move the file out of packages/) \u2014 otherwise their \`sz\` produces no CSS.`;
|
|
1724
|
+
}
|
|
1725
|
+
function computeSafelistRelPath(rootDir, safelistFilename, cssId) {
|
|
1726
|
+
const safelistPath = path.join(rootDir, safelistFilename).replace(/\\/g, "/");
|
|
1727
|
+
const cssDir = path.dirname(cssId).replace(/\\/g, "/");
|
|
1728
|
+
let relPath = path.posix.relative(cssDir, safelistPath);
|
|
1729
|
+
if (!relPath.startsWith(".")) {
|
|
1730
|
+
relPath = `./${relPath}`;
|
|
1731
|
+
}
|
|
1732
|
+
return relPath;
|
|
1733
|
+
}
|
|
1575
1734
|
function cssVariableEntries(result) {
|
|
1576
1735
|
const entries = [];
|
|
1577
1736
|
for (const [original, value] of result.cssVariableMap ?? []) {
|
|
@@ -2035,6 +2194,45 @@ function mangleCodeClassesSync(code, mangleMap) {
|
|
|
2035
2194
|
}
|
|
2036
2195
|
return changed ? `className:\`${out}\`` : fullMatch;
|
|
2037
2196
|
});
|
|
2197
|
+
function scanClassExpression(source, from) {
|
|
2198
|
+
let depth = 0;
|
|
2199
|
+
let j = from;
|
|
2200
|
+
while (j < source.length) {
|
|
2201
|
+
const ch = source[j];
|
|
2202
|
+
if (ch === "(" || ch === "[") {
|
|
2203
|
+
depth++;
|
|
2204
|
+
} else if (ch === ")" || ch === "]") {
|
|
2205
|
+
if (depth === 0) {
|
|
2206
|
+
break;
|
|
2207
|
+
}
|
|
2208
|
+
depth--;
|
|
2209
|
+
} else if (depth === 0 && (ch === "," || ch === ";" || ch === "\n" || ch === "}")) {
|
|
2210
|
+
break;
|
|
2211
|
+
}
|
|
2212
|
+
j++;
|
|
2213
|
+
}
|
|
2214
|
+
return j;
|
|
2215
|
+
}
|
|
2216
|
+
function mangleTernaryClassStrings(expr) {
|
|
2217
|
+
const qIdx = expr.indexOf("?");
|
|
2218
|
+
if (qIdx === -1 || !expr.slice(qIdx).includes(":")) {
|
|
2219
|
+
return null;
|
|
2220
|
+
}
|
|
2221
|
+
let changed = false;
|
|
2222
|
+
const mangled = expr.replace(/"([^"]*)"/g, (qm, inner) => {
|
|
2223
|
+
const parts = inner.split(/\s+/).filter(Boolean);
|
|
2224
|
+
if (parts.length === 0) {
|
|
2225
|
+
return qm;
|
|
2226
|
+
}
|
|
2227
|
+
const mangledStr = parts.map((p) => mangleMap[p] || p).join(" ");
|
|
2228
|
+
if (mangledStr !== inner) {
|
|
2229
|
+
changed = true;
|
|
2230
|
+
return `"${mangledStr}"`;
|
|
2231
|
+
}
|
|
2232
|
+
return qm;
|
|
2233
|
+
});
|
|
2234
|
+
return changed ? mangled : null;
|
|
2235
|
+
}
|
|
2038
2236
|
{
|
|
2039
2237
|
const marker = "className:";
|
|
2040
2238
|
let searchFrom = 0;
|
|
@@ -2056,47 +2254,39 @@ function mangleCodeClassesSync(code, mangleMap) {
|
|
|
2056
2254
|
searchFrom = afterColon;
|
|
2057
2255
|
continue;
|
|
2058
2256
|
}
|
|
2059
|
-
|
|
2060
|
-
let j = afterColon;
|
|
2061
|
-
while (j < result.length) {
|
|
2062
|
-
const ch = result[j];
|
|
2063
|
-
if (ch === "(" || ch === "[") {
|
|
2064
|
-
depth++;
|
|
2065
|
-
} else if (ch === ")" || ch === "]") {
|
|
2066
|
-
if (depth === 0) {
|
|
2067
|
-
break;
|
|
2068
|
-
}
|
|
2069
|
-
depth--;
|
|
2070
|
-
} else if (depth === 0 && (ch === "," || ch === ";" || ch === "\n" || ch === "}")) {
|
|
2071
|
-
break;
|
|
2072
|
-
}
|
|
2073
|
-
j++;
|
|
2074
|
-
}
|
|
2257
|
+
const j = scanClassExpression(result, afterColon);
|
|
2075
2258
|
const expr = result.slice(afterColon, j);
|
|
2076
|
-
|
|
2077
|
-
if (qIdx === -1 || !expr.slice(qIdx).includes(":")) {
|
|
2078
|
-
out += expr;
|
|
2079
|
-
searchFrom = j;
|
|
2080
|
-
continue;
|
|
2081
|
-
}
|
|
2082
|
-
let changed = false;
|
|
2083
|
-
const mangled = expr.replace(/"([^"]*)"/g, (qm, inner) => {
|
|
2084
|
-
const parts = inner.split(/\s+/).filter(Boolean);
|
|
2085
|
-
if (parts.length === 0) {
|
|
2086
|
-
return qm;
|
|
2087
|
-
}
|
|
2088
|
-
const mangledStr = parts.map((p) => mangleMap[p] || p).join(" ");
|
|
2089
|
-
if (mangledStr !== inner) {
|
|
2090
|
-
changed = true;
|
|
2091
|
-
return `"${mangledStr}"`;
|
|
2092
|
-
}
|
|
2093
|
-
return qm;
|
|
2094
|
-
});
|
|
2095
|
-
out += changed ? mangled : expr;
|
|
2259
|
+
out += mangleTernaryClassStrings(expr) ?? expr;
|
|
2096
2260
|
searchFrom = j;
|
|
2097
2261
|
}
|
|
2098
2262
|
result = out;
|
|
2099
2263
|
}
|
|
2264
|
+
{
|
|
2265
|
+
const markerRe = /"class(?:Name)?"\s*,\s*/g;
|
|
2266
|
+
let out = "";
|
|
2267
|
+
let copiedTo = 0;
|
|
2268
|
+
let m = markerRe.exec(result);
|
|
2269
|
+
while (m !== null) {
|
|
2270
|
+
const exprStart = m.index + m[0].length;
|
|
2271
|
+
const firstChar = result[exprStart];
|
|
2272
|
+
if (firstChar === '"' || firstChar === "'" || firstChar === "`") {
|
|
2273
|
+
m = markerRe.exec(result);
|
|
2274
|
+
continue;
|
|
2275
|
+
}
|
|
2276
|
+
const j = scanClassExpression(result, exprStart);
|
|
2277
|
+
const expr = result.slice(exprStart, j);
|
|
2278
|
+
const mangled = mangleTernaryClassStrings(expr);
|
|
2279
|
+
if (mangled !== null) {
|
|
2280
|
+
out += result.slice(copiedTo, exprStart) + mangled;
|
|
2281
|
+
copiedTo = j;
|
|
2282
|
+
}
|
|
2283
|
+
markerRe.lastIndex = j;
|
|
2284
|
+
m = markerRe.exec(result);
|
|
2285
|
+
}
|
|
2286
|
+
if (copiedTo > 0) {
|
|
2287
|
+
result = out + result.slice(copiedTo);
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2100
2290
|
result = result.replace(/(?<=(?:[,(]|&&)\s*)"([^"]+)"/g, (match, inner) => {
|
|
2101
2291
|
const tokens = inner.split(/\s+/).filter(Boolean);
|
|
2102
2292
|
if (tokens.length === 0) {
|
|
@@ -2164,6 +2354,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2164
2354
|
"[csszyx] Transform cache disabled because package versions could not be resolved."
|
|
2165
2355
|
);
|
|
2166
2356
|
}
|
|
2357
|
+
const compilePackages = options.compilePackages ?? [];
|
|
2167
2358
|
const parserOverride = process.env.CSSZYX_PARSER;
|
|
2168
2359
|
const defaultParser = DEFAULT_BUILD_CONFIG.parser ?? "rust";
|
|
2169
2360
|
const parserMode = parserOverride === "babel" || parserOverride === "oxc" || parserOverride === "rust" ? parserOverride : options.build?.parser ?? defaultParser;
|
|
@@ -2171,6 +2362,15 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2171
2362
|
const transformMemoryCache = /* @__PURE__ */ new Map();
|
|
2172
2363
|
const state = {
|
|
2173
2364
|
classes: /* @__PURE__ */ new Set(),
|
|
2365
|
+
sawTailwindEntry: false,
|
|
2366
|
+
tailwindWarningEmitted: false,
|
|
2367
|
+
tailwindEntryScoped: false,
|
|
2368
|
+
contentScopeWarningEmitted: false,
|
|
2369
|
+
spreadWarnings: /* @__PURE__ */ new Set(),
|
|
2370
|
+
skippedSzFiles: /* @__PURE__ */ new Set(),
|
|
2371
|
+
skipWarningEmitted: false,
|
|
2372
|
+
classesCapped: false,
|
|
2373
|
+
ownedClasses: /* @__PURE__ */ new Set(),
|
|
2174
2374
|
mangleMap: {},
|
|
2175
2375
|
varMangleEntriesByFile: /* @__PURE__ */ new Map(),
|
|
2176
2376
|
varMangleMap: Object.fromEntries(earlyGlobalVarAliasEntries),
|
|
@@ -2231,7 +2431,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2231
2431
|
return result;
|
|
2232
2432
|
}
|
|
2233
2433
|
function isHardIgnored(id) {
|
|
2234
|
-
return
|
|
2434
|
+
return isHardIgnoredPath(id, compilePackages);
|
|
2235
2435
|
}
|
|
2236
2436
|
function shouldProcessSource(id) {
|
|
2237
2437
|
return !isHardIgnored(id) && !isUserExcluded(id) && isUserIncluded(id) && (/\.[tj]sx?(\?.*)?$/.test(id) || id.endsWith(".vue") || id.endsWith(".svelte"));
|
|
@@ -2437,12 +2637,19 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2437
2637
|
maxEntries: TRANSFORM_CACHE_MAX_ENTRIES
|
|
2438
2638
|
});
|
|
2439
2639
|
}
|
|
2640
|
+
function addSafelistClass(cls) {
|
|
2641
|
+
if (state.classes.size >= MAX_SAFELIST_CLASSES) {
|
|
2642
|
+
state.classesCapped = true;
|
|
2643
|
+
return;
|
|
2644
|
+
}
|
|
2645
|
+
state.classes.add(cls);
|
|
2646
|
+
}
|
|
2440
2647
|
function writeSafelistFile(classes) {
|
|
2441
2648
|
if (classes.size === 0) {
|
|
2442
2649
|
return;
|
|
2443
2650
|
}
|
|
2444
2651
|
const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME);
|
|
2445
|
-
const classList = Array.from(classes).join(" ");
|
|
2652
|
+
const classList = escapeHtmlAttribute(Array.from(classes).join(" "));
|
|
2446
2653
|
const content = `<!-- Auto-generated by csszyx \u2014 DO NOT EDIT -->
|
|
2447
2654
|
<!-- Tailwind CSS scans this file for class name detection -->
|
|
2448
2655
|
<div class="${classList}"><div class="${classList}">x</div><div class="${classList}">x</div></div>
|
|
@@ -2462,6 +2669,20 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2462
2669
|
} catch {
|
|
2463
2670
|
}
|
|
2464
2671
|
}
|
|
2672
|
+
function recordPackagesSkipIfSz(filePath) {
|
|
2673
|
+
if (!isPackagesSkippedSource(filePath, compilePackages)) {
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2676
|
+
let content;
|
|
2677
|
+
try {
|
|
2678
|
+
content = fs.readFileSync(filePath, "utf-8");
|
|
2679
|
+
} catch {
|
|
2680
|
+
return;
|
|
2681
|
+
}
|
|
2682
|
+
if (content.includes("sz=") || content.includes("sz:")) {
|
|
2683
|
+
state.skippedSzFiles.add(filePath);
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2465
2686
|
function prescanAndWriteClasses() {
|
|
2466
2687
|
const prescanStarted = performance.now();
|
|
2467
2688
|
const discoveredClasses = /* @__PURE__ */ new Set();
|
|
@@ -2482,6 +2703,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2482
2703
|
} else if (SOURCE_EXTENSIONS.has(path.extname(entry.name))) {
|
|
2483
2704
|
const filePath = path.join(dir, entry.name);
|
|
2484
2705
|
if (!shouldProcessSource(filePath)) {
|
|
2706
|
+
recordPackagesSkipIfSz(filePath);
|
|
2485
2707
|
continue;
|
|
2486
2708
|
}
|
|
2487
2709
|
let content;
|
|
@@ -2505,7 +2727,8 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2505
2727
|
collectPrescanResult(result, filePath, discoveredClasses, rawDiscoveredClasses);
|
|
2506
2728
|
}
|
|
2507
2729
|
for (const cls of discoveredClasses) {
|
|
2508
|
-
|
|
2730
|
+
addSafelistClass(cls);
|
|
2731
|
+
state.ownedClasses.add(cls);
|
|
2509
2732
|
}
|
|
2510
2733
|
const safelistClasses = /* @__PURE__ */ new Set([...discoveredClasses, ...rawDiscoveredClasses]);
|
|
2511
2734
|
writeSafelistFile(safelistClasses);
|
|
@@ -2593,7 +2816,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2593
2816
|
for (const match of code.matchAll(classPattern)) {
|
|
2594
2817
|
const classes = match[1].split(/\s+/).filter(Boolean);
|
|
2595
2818
|
for (const cls of classes) {
|
|
2596
|
-
|
|
2819
|
+
addSafelistClass(cls);
|
|
2597
2820
|
}
|
|
2598
2821
|
}
|
|
2599
2822
|
}
|
|
@@ -2615,13 +2838,13 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2615
2838
|
const str = strMatch[1] || strMatch[2];
|
|
2616
2839
|
const classes = str.split(/\s+/).filter(Boolean);
|
|
2617
2840
|
for (const cls of classes) {
|
|
2618
|
-
|
|
2841
|
+
addSafelistClass(cls);
|
|
2619
2842
|
}
|
|
2620
2843
|
}
|
|
2621
2844
|
}
|
|
2622
2845
|
}
|
|
2623
2846
|
function finalizeMangleMap() {
|
|
2624
|
-
const sortedClasses = Array.from(state.
|
|
2847
|
+
const sortedClasses = Array.from(state.ownedClasses);
|
|
2625
2848
|
const newMap = {};
|
|
2626
2849
|
for (let i = 0; i < sortedClasses.length; i++) {
|
|
2627
2850
|
newMap[sortedClasses[i]] = encode(i);
|
|
@@ -2668,6 +2891,21 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2668
2891
|
}
|
|
2669
2892
|
return null;
|
|
2670
2893
|
},
|
|
2894
|
+
/**
|
|
2895
|
+
* Restricts the load hook to csszyx's own virtual modules.
|
|
2896
|
+
*
|
|
2897
|
+
* Without this, unplugin's webpack adapter registers its load
|
|
2898
|
+
* loader with `type: 'javascript/auto'` for every module (its
|
|
2899
|
+
* include defaults to all ids when no loadInclude exists). That
|
|
2900
|
+
* corrupts binary asset modules (images, fonts) in webpack apps —
|
|
2901
|
+
* Next.js builds fail with "not a valid image file" / "Module
|
|
2902
|
+
* parse failed" on assets that build fine without csszyx.
|
|
2903
|
+
* @param id - the module ID webpack is about to load
|
|
2904
|
+
* @returns true only for csszyx virtual modules
|
|
2905
|
+
*/
|
|
2906
|
+
loadInclude(id) {
|
|
2907
|
+
return id === RESOLVED_VIRTUAL_MODULE_ID || id === RESOLVED_VIRTUAL_CHECKSUM_ID;
|
|
2908
|
+
},
|
|
2671
2909
|
/**
|
|
2672
2910
|
* Loads virtual module content — generates mangle map or checksum module code.
|
|
2673
2911
|
* @param id - the resolved module ID to load
|
|
@@ -2691,7 +2929,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2691
2929
|
},
|
|
2692
2930
|
/**
|
|
2693
2931
|
* Filters files for the pre-transform phase — source files plus CSS files.
|
|
2694
|
-
* CSS files need special handling to
|
|
2932
|
+
* CSS files need special handling to append an @source directive for Tailwind class discovery.
|
|
2695
2933
|
* @param id - the file path to check for inclusion
|
|
2696
2934
|
* @returns true if the file should be transformed, false otherwise
|
|
2697
2935
|
*/
|
|
@@ -2703,7 +2941,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2703
2941
|
},
|
|
2704
2942
|
/**
|
|
2705
2943
|
* Core transform: detects sz prop, compiles to className, injects runtime, collects classes.
|
|
2706
|
-
* For CSS files:
|
|
2944
|
+
* For CSS files: appends an @source directive so Tailwind generates CSS for sz-derived classes.
|
|
2707
2945
|
* @param code - the source code to transform
|
|
2708
2946
|
* @param id - the file path of the module being transformed
|
|
2709
2947
|
* @returns transformed code with source map, or null if no changes were made
|
|
@@ -2719,24 +2957,19 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2719
2957
|
assertNoRSCBoundaryViolation(code, id);
|
|
2720
2958
|
}
|
|
2721
2959
|
if (/\.css(\?.*)?$/.test(id)) {
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
const sourceDirective = `@source "${relPath}";
|
|
2733
|
-
`;
|
|
2734
|
-
const transformed2 = code.replace(
|
|
2735
|
-
/(@import\s+["']tailwindcss[^"']*["'];)/,
|
|
2736
|
-
`$1
|
|
2737
|
-
${sourceDirective}`
|
|
2960
|
+
if (cssImportsTailwind(code)) {
|
|
2961
|
+
state.sawTailwindEntry = true;
|
|
2962
|
+
if (cssHasContentScope(code)) {
|
|
2963
|
+
state.tailwindEntryScoped = true;
|
|
2964
|
+
}
|
|
2965
|
+
if (hasInjectableTailwindCandidate(state.classes)) {
|
|
2966
|
+
const relPath = computeSafelistRelPath(
|
|
2967
|
+
state.rootDir,
|
|
2968
|
+
SAFELIST_FILENAME,
|
|
2969
|
+
id
|
|
2738
2970
|
);
|
|
2739
|
-
|
|
2971
|
+
const transformed2 = appendTailwindSourceDirective(code, relPath);
|
|
2972
|
+
if (transformed2 !== null) {
|
|
2740
2973
|
return { code: transformed2, map: null };
|
|
2741
2974
|
}
|
|
2742
2975
|
}
|
|
@@ -2779,8 +3012,15 @@ ${sourceDirective}`
|
|
|
2779
3012
|
szClasses = result.classes;
|
|
2780
3013
|
recordFileVarMangleEntries(state, id, cssVariableEntries(result));
|
|
2781
3014
|
recordFileCSSVariableMetrics(state, id, result.code);
|
|
3015
|
+
for (const msg of result.diagnostics) {
|
|
3016
|
+
if (msg.includes("unresolvable sz spread")) {
|
|
3017
|
+
state.spreadWarnings.add(`${id}
|
|
3018
|
+
${msg}`);
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
2782
3021
|
if (result.diagnostics.length > 0 && process.env.NODE_ENV !== "production") {
|
|
2783
3022
|
for (const msg of result.diagnostics) {
|
|
3023
|
+
if (msg.includes("unresolvable sz spread")) continue;
|
|
2784
3024
|
this.warn(`[csszyx] ${id}
|
|
2785
3025
|
${msg}`);
|
|
2786
3026
|
}
|
|
@@ -2848,7 +3088,8 @@ ${sourceDirective}`
|
|
|
2848
3088
|
if (transformed || transformedCode.includes("class=") || transformedCode.includes("className=")) {
|
|
2849
3089
|
if (szClasses !== void 0) {
|
|
2850
3090
|
for (const cls of szClasses) {
|
|
2851
|
-
|
|
3091
|
+
addSafelistClass(cls);
|
|
3092
|
+
state.ownedClasses.add(cls);
|
|
2852
3093
|
}
|
|
2853
3094
|
} else {
|
|
2854
3095
|
extractClasses(transformedCode);
|
|
@@ -2861,6 +3102,36 @@ ${sourceDirective}`
|
|
|
2861
3102
|
buildEnd() {
|
|
2862
3103
|
finalizeMangleMap();
|
|
2863
3104
|
assertNoRSCGraphViolation(state.rscModules);
|
|
3105
|
+
if (!state.tailwindWarningEmitted && shouldWarnMissingTailwindEntry(state.ownedClasses.size, state.sawTailwindEntry)) {
|
|
3106
|
+
state.tailwindWarningEmitted = true;
|
|
3107
|
+
console.warn(missingTailwindEntryMessage(state.ownedClasses.size));
|
|
3108
|
+
}
|
|
3109
|
+
if (!state.contentScopeWarningEmitted && options.contentScopeCheck !== false && state.sawTailwindEntry && !state.tailwindEntryScoped) {
|
|
3110
|
+
if (state.inMonorepo === void 0) {
|
|
3111
|
+
state.inMonorepo = isMonorepoPackage(state.rootDir);
|
|
3112
|
+
}
|
|
3113
|
+
if (shouldWarnUnscopedMonorepo(
|
|
3114
|
+
state.sawTailwindEntry,
|
|
3115
|
+
state.tailwindEntryScoped,
|
|
3116
|
+
state.inMonorepo
|
|
3117
|
+
)) {
|
|
3118
|
+
state.contentScopeWarningEmitted = true;
|
|
3119
|
+
console.warn(unscopedMonorepoMessage());
|
|
3120
|
+
}
|
|
3121
|
+
}
|
|
3122
|
+
if (!state.skipWarningEmitted && state.skippedSzFiles.size > 0) {
|
|
3123
|
+
state.skipWarningEmitted = true;
|
|
3124
|
+
console.warn(skippedSzFilesMessage([...state.skippedSzFiles].sort()));
|
|
3125
|
+
}
|
|
3126
|
+
if (state.classesCapped) {
|
|
3127
|
+
console.warn(
|
|
3128
|
+
`[csszyx] safelist exceeded ${MAX_SAFELIST_CLASSES} classes; additional classes were dropped. This usually means an unbounded set of arbitrary values reached an sz prop.`
|
|
3129
|
+
);
|
|
3130
|
+
}
|
|
3131
|
+
for (const warning of state.spreadWarnings) {
|
|
3132
|
+
console.warn(`[csszyx] ${warning}`);
|
|
3133
|
+
}
|
|
3134
|
+
state.spreadWarnings.clear();
|
|
2864
3135
|
if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
|
|
2865
3136
|
globalThis.__csszyx_ssr_mangle_map = state.mangleMap;
|
|
2866
3137
|
}
|
|
@@ -2960,7 +3231,8 @@ ${sourceDirective}`
|
|
|
2960
3231
|
const sizeBefore = state.classes.size;
|
|
2961
3232
|
recordGlobalVarSourceFile(state, ctx.file, fileContent);
|
|
2962
3233
|
for (const cls of result.classes) {
|
|
2963
|
-
|
|
3234
|
+
addSafelistClass(cls);
|
|
3235
|
+
state.ownedClasses.add(cls);
|
|
2964
3236
|
}
|
|
2965
3237
|
recordFileVarMangleEntries(state, ctx.file, cssVariableEntries(result));
|
|
2966
3238
|
recordFileCSSVariableMetrics(state, ctx.file, result.code);
|
|
@@ -3299,4 +3571,4 @@ const esbuildPlugin = (options = {}) => {
|
|
|
3299
3571
|
};
|
|
3300
3572
|
};
|
|
3301
3573
|
|
|
3302
|
-
export {
|
|
3574
|
+
export { mangleCodeClassesSync as A, mergeThemes as B, missingTailwindEntryMessage as C, normalizeGlobalVarAliasesForCache as D, parseThemeBlocks as E, planGlobalVarAliases as F, readGlobalVarScanCache as G, resolveGlobalVarScanCacheDir as H, resolveNativeCacheIdentity as I, rewriteGlobalVarCssAliases as J, rollupPlugin as K, scanGlobalVarCss as L, shouldWarnMissingTailwindEntry as M, shouldWarnUnscopedMonorepo as N, skippedSzFilesMessage as O, unscopedMonorepoMessage as P, validateGlobalVarAliasInputs as Q, vitePlugin as R, webpackPlugin as S, writeGlobalVarScanCache as T, appendTailwindSourceDirective as a, assertNoRSCBoundaryViolation as b, assertNoRSCGraphViolation as c, computeSafelistRelPath as d, createGlobalVarAliasValidationOptions as e, createGlobalVarMapAssetSource as f, createGlobalVarScanCacheKey as g, createRSCModuleRecord as h, cssHasContentScope as i, cssImportsTailwind as j, deleteRSCModuleRecord as k, esbuildPlugin as l, extractGlobalVarAliasesForManifest as m, findRSCBoundaryViolation as n, findRSCGraphViolation as o, hasInjectableTailwindCandidate as p, hasTokens as q, hasUseClientDirective as r, hasUseServerDirective as s, isCompilePackageOptedIn as t, unplugin as u, isHardIgnoredPath as v, isMonorepoPackage as w, isPackagesSkippedSource as x, isRSCServerModule as y, isTailwindReservedGlobalVar as z };
|