@csszyx/unplugin 0.14.4 → 0.15.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/README.md +4 -3
- package/dist/index.cjs +8 -7
- package/dist/index.d.cts +70 -3
- package/dist/index.d.mts +70 -3
- package/dist/index.mjs +4 -4
- package/dist/next-config.d.cts +1 -2
- package/dist/next-config.d.mts +1 -2
- package/dist/next-prebuild.cjs +9 -5
- package/dist/next-prebuild.d.cts +4 -2
- package/dist/next-prebuild.d.mts +4 -2
- package/dist/next-prebuild.mjs +8 -4
- package/dist/next-turbo-loader.cjs +20 -14
- package/dist/next-turbo-loader.d.cts +1 -1
- package/dist/next-turbo-loader.d.mts +1 -1
- package/dist/next-turbo-loader.mjs +19 -13
- package/dist/next-watcher.cjs +2 -2
- package/dist/next-watcher.d.cts +2 -2
- package/dist/next-watcher.d.mts +2 -2
- package/dist/next-watcher.mjs +2 -2
- package/dist/postcss.cjs +124 -0
- package/dist/postcss.d.cts +42 -0
- package/dist/postcss.d.mts +42 -0
- package/dist/postcss.mjs +107 -0
- package/dist/shared/{unplugin.NlPvn5P4.mjs → unplugin.AGR7mihU.mjs} +2 -6
- package/dist/shared/{unplugin.BnRf0Tvd.mjs → unplugin.BGufkSFT.mjs} +297 -173
- package/dist/shared/{unplugin.BXYakiXt.d.cts → unplugin.BHfqCocB.d.cts} +53 -55
- package/dist/shared/{unplugin.BXYakiXt.d.mts → unplugin.BHfqCocB.d.mts} +53 -55
- package/dist/shared/{unplugin.RGzhYt-D.cjs → unplugin.BLbrShMZ.cjs} +344 -221
- package/dist/shared/{unplugin.DVbPNK3W.cjs → unplugin.BbBYWFGT.cjs} +6 -6
- package/dist/shared/{unplugin.BZPdvVcj.mjs → unplugin.BourSpnZ.mjs} +105 -127
- package/dist/shared/{unplugin.CPEWNSA0.d.cts → unplugin.C2ilavL1.d.cts} +2 -0
- package/dist/shared/{unplugin.CPEWNSA0.d.mts → unplugin.C2ilavL1.d.mts} +2 -0
- package/dist/shared/{unplugin.D8BxOOkA.cjs → unplugin.C7i0agiO.cjs} +121 -142
- package/dist/shared/{unplugin.CdZxp0x-.d.mts → unplugin.CXCaQ3-s.d.cts} +1 -1
- package/dist/shared/{unplugin.xeED_qwh.d.cts → unplugin.CbNydVwv.d.mts} +1 -1
- package/dist/shared/unplugin.CqJS0BbD.mjs +211 -0
- package/dist/shared/{unplugin.VtXstzEh.cjs → unplugin.DX3rYT4P.cjs} +6 -11
- package/dist/shared/{unplugin.Cji6O5jv.cjs → unplugin.Dai5wlZ3.cjs} +27 -19
- package/dist/shared/{unplugin.DN95k991.mjs → unplugin.Dbc26ty6.mjs} +2 -2
- package/dist/shared/{unplugin.BU0O4IkX.mjs → unplugin.DmCOQc-b.mjs} +22 -16
- package/dist/shared/unplugin.KnDCM-sr.cjs +241 -0
- package/dist/vite.cjs +4 -4
- package/dist/vite.d.cts +2 -2
- package/dist/vite.d.mts +1 -1
- package/dist/vite.mjs +4 -4
- package/dist/webpack.cjs +4 -4
- package/dist/webpack.d.cts +2 -1
- package/dist/webpack.d.mts +1 -1
- package/dist/webpack.mjs +4 -4
- package/package.json +19 -9
- package/dist/shared/unplugin.B3XoSRB8.mjs +0 -40
- package/dist/shared/unplugin.BkRah5Ot.cjs +0 -48
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
|
|
4
|
+
function sortStrings(values) {
|
|
5
|
+
return [...values].sort((a, b) => {
|
|
6
|
+
if (a < b) return -1;
|
|
7
|
+
if (a > b) return 1;
|
|
8
|
+
return 0;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const WINDOWS_PATH_SEPARATOR = String.fromCodePoint(92);
|
|
13
|
+
function normalizePathSeparators(value) {
|
|
14
|
+
return value.split(WINDOWS_PATH_SEPARATOR).join("/");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const SAFELIST_HEADER = "# Auto-generated by csszyx \u2014 DO NOT EDIT\n# Tailwind scans this file for class names, one per line.\n";
|
|
18
|
+
function renderSafelistFile(classNames) {
|
|
19
|
+
if (classNames.length === 0) {
|
|
20
|
+
return SAFELIST_HEADER;
|
|
21
|
+
}
|
|
22
|
+
return `${SAFELIST_HEADER}${classNames.join("\n")}
|
|
23
|
+
`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const SAFELIST_FILE = ".csszyx/csszyx-classes.txt";
|
|
27
|
+
const LEGACY_SAFELIST_FILES = [
|
|
28
|
+
"csszyx-classes.html",
|
|
29
|
+
".csszyx/next-loader-classes.html"
|
|
30
|
+
];
|
|
31
|
+
const LEGACY_HTML_MARKERS = [
|
|
32
|
+
"<!-- Auto-generated by csszyx",
|
|
33
|
+
"<!-- csszyx Next safelist",
|
|
34
|
+
"<!-- csszyx exact scanner candidates -->"
|
|
35
|
+
];
|
|
36
|
+
function removeLegacySafelists(rootDir, warn) {
|
|
37
|
+
for (const legacy of LEGACY_SAFELIST_FILES) {
|
|
38
|
+
const file = path.join(rootDir, legacy);
|
|
39
|
+
let content;
|
|
40
|
+
try {
|
|
41
|
+
content = fs.readFileSync(file, "utf8");
|
|
42
|
+
} catch {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!LEGACY_HTML_MARKERS.some((marker) => content.includes(marker))) continue;
|
|
46
|
+
try {
|
|
47
|
+
fs.rmSync(file, { force: true });
|
|
48
|
+
} catch (error) {
|
|
49
|
+
const { message } = error;
|
|
50
|
+
warn(`[csszyx] could not remove ${legacy}: ${message}. Delete it by hand.`);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
warn(
|
|
54
|
+
`[csszyx] removed ${legacy}: the safelist now lives at ${SAFELIST_FILE}. Update any hand-written @source that named the old file, or drop it and list '@csszyx/unplugin/postcss' before '@tailwindcss/postcss' in postcss.config.`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const LEGACY_SAFELIST_BASENAMES = new Set(
|
|
59
|
+
LEGACY_SAFELIST_FILES.map((file) => path.posix.basename(file))
|
|
60
|
+
);
|
|
61
|
+
function isDanglingLegacySource(target, cssFile) {
|
|
62
|
+
if (!LEGACY_SAFELIST_BASENAMES.has(path.posix.basename(target))) return false;
|
|
63
|
+
return !fs.existsSync(path.resolve(path.dirname(cssFile), target));
|
|
64
|
+
}
|
|
65
|
+
function findLegacySourceDirective(code, cssFile) {
|
|
66
|
+
const withoutComments = stripCssBlockComments(code);
|
|
67
|
+
for (const match of withoutComments.matchAll(/@source\s+(["'])([^"']+)\1/g)) {
|
|
68
|
+
const target = match[2];
|
|
69
|
+
if (isDanglingLegacySource(target, cssFile)) {
|
|
70
|
+
return { directive: match[0], target };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const SKIPPED_DIRS = /* @__PURE__ */ new Set([
|
|
76
|
+
"node_modules",
|
|
77
|
+
".git",
|
|
78
|
+
".csszyx",
|
|
79
|
+
"dist",
|
|
80
|
+
"build",
|
|
81
|
+
"out",
|
|
82
|
+
"coverage",
|
|
83
|
+
".turbo",
|
|
84
|
+
".vercel"
|
|
85
|
+
]);
|
|
86
|
+
const STYLESHEET_EXTENSIONS = /* @__PURE__ */ new Set([".css", ".pcss", ".postcss"]);
|
|
87
|
+
function findLegacySourceStylesheet(rootDir) {
|
|
88
|
+
const pending = [rootDir];
|
|
89
|
+
while (pending.length > 0) {
|
|
90
|
+
const dir = pending.pop();
|
|
91
|
+
for (const entry of readDirectory(dir)) {
|
|
92
|
+
if (entry.isDirectory()) {
|
|
93
|
+
if (!isSkippedDirectory(entry.name)) pending.push(path.join(dir, entry.name));
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const found = readLegacySourceDirective(dir, entry);
|
|
97
|
+
if (found !== null) return found;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
function readDirectory(dir) {
|
|
103
|
+
try {
|
|
104
|
+
return fs.readdirSync(dir, { withFileTypes: true });
|
|
105
|
+
} catch {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function isSkippedDirectory(name) {
|
|
110
|
+
return SKIPPED_DIRS.has(name) || name.startsWith(".next");
|
|
111
|
+
}
|
|
112
|
+
function readLegacySourceDirective(dir, entry) {
|
|
113
|
+
if (!entry.isFile() || !STYLESHEET_EXTENSIONS.has(path.extname(entry.name))) return null;
|
|
114
|
+
const file = path.join(dir, entry.name);
|
|
115
|
+
const code = fs.readFileSync(file, "utf8");
|
|
116
|
+
if (!code.includes("@source")) return null;
|
|
117
|
+
const found = findLegacySourceDirective(code, file);
|
|
118
|
+
return found === null ? null : { file, ...found };
|
|
119
|
+
}
|
|
120
|
+
const ROOTS_WITHOUT_LEGACY_SOURCE = /* @__PURE__ */ new Set();
|
|
121
|
+
function assertNoLegacySourceStylesheet(rootDir) {
|
|
122
|
+
if (ROOTS_WITHOUT_LEGACY_SOURCE.has(rootDir)) return;
|
|
123
|
+
const found = findLegacySourceStylesheet(rootDir);
|
|
124
|
+
if (found !== null) throw new Error(legacySourceMessage(found.file, found.target));
|
|
125
|
+
ROOTS_WITHOUT_LEGACY_SOURCE.add(rootDir);
|
|
126
|
+
}
|
|
127
|
+
const CSSZYX_POSTCSS_PLUGIN = "@csszyx/unplugin/postcss";
|
|
128
|
+
const POSTCSS_CONFIG_FILES = [
|
|
129
|
+
".postcssrc.json",
|
|
130
|
+
"postcss.config.json",
|
|
131
|
+
".postcssrc.js",
|
|
132
|
+
"postcss.config.js",
|
|
133
|
+
"postcss.config.mjs",
|
|
134
|
+
"postcss.config.cjs"
|
|
135
|
+
];
|
|
136
|
+
function findPostcssConfigWithoutCsszyx(rootDir) {
|
|
137
|
+
const packageJson = path.join(rootDir, "package.json");
|
|
138
|
+
let postcssKey;
|
|
139
|
+
try {
|
|
140
|
+
postcssKey = JSON.parse(fs.readFileSync(packageJson, "utf8")).postcss;
|
|
141
|
+
} catch {
|
|
142
|
+
postcssKey = void 0;
|
|
143
|
+
}
|
|
144
|
+
if (postcssKey !== void 0) {
|
|
145
|
+
return JSON.stringify(postcssKey).includes(CSSZYX_POSTCSS_PLUGIN) ? null : packageJson;
|
|
146
|
+
}
|
|
147
|
+
for (const name of POSTCSS_CONFIG_FILES) {
|
|
148
|
+
const file = path.join(rootDir, name);
|
|
149
|
+
let text;
|
|
150
|
+
try {
|
|
151
|
+
text = fs.readFileSync(file, "utf8");
|
|
152
|
+
} catch {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
return text.includes(CSSZYX_POSTCSS_PLUGIN) ? null : file;
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
function missingPostcssPluginMessage(configFile) {
|
|
160
|
+
return `[csszyx] ${configFile} does not list '@csszyx/unplugin/postcss'. Next.js reads the safelist only through that plugin: list it before '@tailwindcss/postcss', or no sz class gets CSS.`;
|
|
161
|
+
}
|
|
162
|
+
function legacySourceMessage(cssFile, target) {
|
|
163
|
+
return `[csszyx] ${cssFile}: @source "${target}" names the old safelist, which csszyx no longer writes. The safelist is now ${SAFELIST_FILE}, and csszyx adds the directive itself: remove this line. Vite, Rollup and webpack inject it; on Next.js list '@csszyx/unplugin/postcss' before '@tailwindcss/postcss' in postcss.config.`;
|
|
164
|
+
}
|
|
165
|
+
const TAILWIND_SPECIFIER = String.raw`["']tailwindcss(?:\/[^"']*)?["']`;
|
|
166
|
+
const TAILWIND_IMPORT = new RegExp(String.raw`@import\s+${TAILWIND_SPECIFIER}`);
|
|
167
|
+
function computeSafelistRelPath(rootDir, safelistFilename, cssId) {
|
|
168
|
+
const safelistPath = normalizePathSeparators(path.join(rootDir, safelistFilename));
|
|
169
|
+
const cssDir = normalizePathSeparators(path.dirname(cssId));
|
|
170
|
+
let relPath = path.posix.relative(cssDir, safelistPath);
|
|
171
|
+
if (!relPath.startsWith("./") && !relPath.startsWith("../")) {
|
|
172
|
+
relPath = `./${relPath}`;
|
|
173
|
+
}
|
|
174
|
+
return relPath;
|
|
175
|
+
}
|
|
176
|
+
function appendTailwindSourceDirective(code, relPath) {
|
|
177
|
+
const directive = `@source "${relPath}";`;
|
|
178
|
+
if (code.includes(directive)) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
const separator = code.length === 0 || code.endsWith("\n") ? "" : "\n";
|
|
182
|
+
return `${code}${separator}${directive}
|
|
183
|
+
`;
|
|
184
|
+
}
|
|
185
|
+
function stripCssBlockComments(code) {
|
|
186
|
+
const SLASH = 47;
|
|
187
|
+
const STAR = 42;
|
|
188
|
+
let out = "";
|
|
189
|
+
let last = 0;
|
|
190
|
+
let i = 0;
|
|
191
|
+
const n = code.length;
|
|
192
|
+
while (i < n) {
|
|
193
|
+
if (code.codePointAt(i) === SLASH && code.codePointAt(i + 1) === STAR) {
|
|
194
|
+
out += code.slice(last, i);
|
|
195
|
+
i += 2;
|
|
196
|
+
while (i < n && !(code.codePointAt(i) === STAR && code.codePointAt(i + 1) === SLASH)) {
|
|
197
|
+
i++;
|
|
198
|
+
}
|
|
199
|
+
i += 2;
|
|
200
|
+
last = i;
|
|
201
|
+
} else {
|
|
202
|
+
i++;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return out + code.slice(last);
|
|
206
|
+
}
|
|
207
|
+
function cssImportsTailwind(code) {
|
|
208
|
+
return TAILWIND_IMPORT.test(stripCssBlockComments(code));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export { SAFELIST_FILE as S, appendTailwindSourceDirective as a, cssImportsTailwind as b, computeSafelistRelPath as c, removeLegacySafelists as d, assertNoLegacySourceStylesheet as e, findPostcssConfigWithoutCsszyx as f, stripCssBlockComments as g, findLegacySourceDirective as h, legacySourceMessage as l, missingPostcssPluginMessage as m, normalizePathSeparators as n, renderSafelistFile as r, sortStrings as s };
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const compiler = require('@csszyx/compiler');
|
|
5
|
+
const safelistSource = require('./unplugin.KnDCM-sr.cjs');
|
|
5
6
|
const fs = require('node:fs');
|
|
6
7
|
const node_crypto = require('node:crypto');
|
|
7
8
|
|
|
@@ -20,11 +21,6 @@ function _interopNamespaceCompat(e) {
|
|
|
20
21
|
const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
|
|
21
22
|
const fs__namespace = /*#__PURE__*/_interopNamespaceCompat(fs);
|
|
22
23
|
|
|
23
|
-
const WINDOWS_PATH_SEPARATOR = String.fromCodePoint(92);
|
|
24
|
-
function normalizePathSeparators(value) {
|
|
25
|
-
return value.split(WINDOWS_PATH_SEPARATOR).join("/");
|
|
26
|
-
}
|
|
27
|
-
|
|
28
24
|
const TSCONFIG_CANDIDATES = ["tsconfig.json", "jsconfig.json", "tsconfig.app.json"];
|
|
29
25
|
const MAX_EXTENDS_DEPTH = 8;
|
|
30
26
|
function collectSpecifierAliases(rootDir, resolveAlias) {
|
|
@@ -115,12 +111,12 @@ function aliasedSpecifierBases(specifier, aliases) {
|
|
|
115
111
|
continue;
|
|
116
112
|
}
|
|
117
113
|
if (!specifier.startsWith(alias.find)) continue;
|
|
118
|
-
bases.push(normalizePathSeparators(alias.replacement + specifier.slice(alias.find.length)));
|
|
114
|
+
bases.push(safelistSource.normalizePathSeparators(alias.replacement + specifier.slice(alias.find.length)));
|
|
119
115
|
}
|
|
120
116
|
return bases;
|
|
121
117
|
}
|
|
122
118
|
function absolute(directory, target) {
|
|
123
|
-
const resolved = normalizePathSeparators(path__namespace.resolve(directory, target));
|
|
119
|
+
const resolved = safelistSource.normalizePathSeparators(path__namespace.resolve(directory, target));
|
|
124
120
|
const declaredTrailingSlash = target.endsWith("/") || target.endsWith("\\");
|
|
125
121
|
return declaredTrailingSlash && !resolved.endsWith("/") ? `${resolved}/` : resolved;
|
|
126
122
|
}
|
|
@@ -189,7 +185,7 @@ function recordSzObjectRegistryFile(registry, filePath, content) {
|
|
|
189
185
|
);
|
|
190
186
|
}
|
|
191
187
|
function replaceEntriesOfKind(registry, filePath, kind, entries) {
|
|
192
|
-
const key = normalizePathSeparators(filePath);
|
|
188
|
+
const key = safelistSource.normalizePathSeparators(filePath);
|
|
193
189
|
const byName = emptyNameIndex();
|
|
194
190
|
for (const [name, recorded] of Object.entries(registry.get(key) ?? {})) {
|
|
195
191
|
if (recorded.kind !== kind) byName[name] = recorded;
|
|
@@ -211,7 +207,7 @@ const EMITTED_EXTENSION_SOURCES = [
|
|
|
211
207
|
[".cjs", [".cts"]]
|
|
212
208
|
];
|
|
213
209
|
function recordCrossModuleForwards(index, filePath, content) {
|
|
214
|
-
const key = normalizePathSeparators(filePath);
|
|
210
|
+
const key = safelistSource.normalizePathSeparators(filePath);
|
|
215
211
|
const forwards = compiler.extractCrossModuleForwards(content, filePath);
|
|
216
212
|
if (forwards.length === 0) index.delete(key);
|
|
217
213
|
else index.set(key, forwards);
|
|
@@ -321,7 +317,7 @@ function importedSpecifiersIn(source) {
|
|
|
321
317
|
}
|
|
322
318
|
function specifierBases(specifier, directory, aliases) {
|
|
323
319
|
if (specifier.startsWith(".")) {
|
|
324
|
-
return [normalizePathSeparators(path__namespace.resolve(directory, specifier))];
|
|
320
|
+
return [safelistSource.normalizePathSeparators(path__namespace.resolve(directory, specifier))];
|
|
325
321
|
}
|
|
326
322
|
return aliasedSpecifierBases(specifier, aliases);
|
|
327
323
|
}
|
|
@@ -574,7 +570,6 @@ exports.forwardVisitKey = forwardVisitKey;
|
|
|
574
570
|
exports.importedSpecifiersIn = importedSpecifiersIn;
|
|
575
571
|
exports.isReadableProviderFile = isReadableProviderFile;
|
|
576
572
|
exports.mayExportSzvFactories = mayExportSzvFactories;
|
|
577
|
-
exports.normalizePathSeparators = normalizePathSeparators;
|
|
578
573
|
exports.readTransformCache = readTransformCache;
|
|
579
574
|
exports.recordCrossModuleForwards = recordCrossModuleForwards;
|
|
580
575
|
exports.recordResolvedEntry = recordResolvedEntry;
|
|
@@ -5,7 +5,7 @@ const fs = require('node:fs');
|
|
|
5
5
|
const node_crypto = require('node:crypto');
|
|
6
6
|
const node_os = require('node:os');
|
|
7
7
|
const lockfile = require('proper-lockfile');
|
|
8
|
-
const
|
|
8
|
+
const safelistSource = require('./unplugin.KnDCM-sr.cjs');
|
|
9
9
|
|
|
10
10
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
11
11
|
|
|
@@ -29,9 +29,10 @@ const DEFAULT_RENAME_RETRIES = 5;
|
|
|
29
29
|
const DEFAULT_RENAME_RETRY_DELAY_MS = 10;
|
|
30
30
|
const DEFAULT_STALE_LOCK_MS = 3e4;
|
|
31
31
|
const STALE_RECOVERY_DISABLED_MS = 2147483647;
|
|
32
|
-
function resolveNextSafelistStatePaths(rootDir, cacheDir = ".csszyx/cache", outputFile =
|
|
32
|
+
function resolveNextSafelistStatePaths(rootDir, cacheDir = ".csszyx/cache", outputFile = safelistSource.SAFELIST_FILE) {
|
|
33
33
|
const resolvedCacheDir = path__namespace.resolve(rootDir, cacheDir);
|
|
34
34
|
return {
|
|
35
|
+
rootDir: path__namespace.resolve(rootDir),
|
|
35
36
|
cacheDir: resolvedCacheDir,
|
|
36
37
|
shardsDir: path__namespace.join(resolvedCacheDir, "safelist-shards"),
|
|
37
38
|
snapshotPath: path__namespace.join(resolvedCacheDir, "safelist.snapshot.json"),
|
|
@@ -62,13 +63,14 @@ function materializeNextSafelist(paths, options = {}) {
|
|
|
62
63
|
recordsBySource.set(record.data.sourcePath, record);
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
|
-
const sortedSources = [...recordsBySource.values()].map(({ data }) => [data.sourcePath,
|
|
66
|
-
const classNames =
|
|
66
|
+
const sortedSources = [...recordsBySource.values()].map(({ data }) => [data.sourcePath, safelistSource.sortStrings(new Set(data.classes))]).sort(([left], [right]) => left.localeCompare(right));
|
|
67
|
+
const classNames = safelistSource.sortStrings(new Set(sortedSources.flatMap(([, classSet]) => classSet)));
|
|
67
68
|
const snapshot = {
|
|
68
69
|
version: 1,
|
|
69
70
|
sources: sortedSources.map(([sourcePath, classSet]) => [sourcePath, classSet])
|
|
70
71
|
};
|
|
71
|
-
atomicWriteFileSync(paths.outputPath,
|
|
72
|
+
atomicWriteFileSync(paths.outputPath, safelistSource.renderSafelistFile(classNames), options);
|
|
73
|
+
safelistSource.removeLegacySafelists(paths.rootDir, console.warn);
|
|
72
74
|
atomicWriteFileSync(paths.snapshotPath, `${JSON.stringify(snapshot, null, 2)}
|
|
73
75
|
`, options);
|
|
74
76
|
return {
|
|
@@ -100,14 +102,14 @@ function acquireNextSafelistStateLock(lockPath, pidOrOptions = {}) {
|
|
|
100
102
|
} catch (error) {
|
|
101
103
|
const existing2 = readLockMetadata(lockPath);
|
|
102
104
|
if (existing2) {
|
|
103
|
-
throw new
|
|
105
|
+
throw new NextSafelistStateLockedError(existing2);
|
|
104
106
|
}
|
|
105
107
|
throw error;
|
|
106
108
|
}
|
|
107
109
|
const existing = readLockMetadata(lockPath);
|
|
108
110
|
if (existing && isLockLive(existing, options)) {
|
|
109
111
|
releaseAdvisory();
|
|
110
|
-
throw new
|
|
112
|
+
throw new NextSafelistStateLockedError(existing);
|
|
111
113
|
}
|
|
112
114
|
try {
|
|
113
115
|
atomicWriteFileSync(lockPath, `${JSON.stringify(metadata, null, 2)}
|
|
@@ -195,7 +197,7 @@ function sameClasses(left, right) {
|
|
|
195
197
|
}
|
|
196
198
|
function normalizeShardInput(input) {
|
|
197
199
|
const sourcePath = path__namespace.resolve(input.sourcePath);
|
|
198
|
-
const classes =
|
|
200
|
+
const classes = safelistSource.sortStrings(
|
|
199
201
|
new Set(input.classes.map((className) => className.trim()).filter(Boolean))
|
|
200
202
|
);
|
|
201
203
|
const cacheKey = input.cacheKey ?? node_crypto.createHash("sha256").update(sourcePath).update("\0").update(input.sourceHash).digest("hex");
|
|
@@ -252,15 +254,6 @@ function normalizeShardRecord(filePath, data) {
|
|
|
252
254
|
})
|
|
253
255
|
};
|
|
254
256
|
}
|
|
255
|
-
function renderTailwindSourceHtml(classNames) {
|
|
256
|
-
if (classNames.length === 0) {
|
|
257
|
-
return "<!-- csszyx Next safelist: empty -->\n";
|
|
258
|
-
}
|
|
259
|
-
const structuralHtml = classNames.map((className) => `<div class="${htmlEscape.escapeHtmlAttribute(className)}"></div>`).join("\n");
|
|
260
|
-
const scannerCandidates = htmlEscape.renderTailwindScannerCandidates(classNames);
|
|
261
|
-
return `${structuralHtml}
|
|
262
|
-
${scannerCandidates}`;
|
|
263
|
-
}
|
|
264
257
|
function createLockMetadata(options) {
|
|
265
258
|
const now = new Date(options.now ?? Date.now()).toISOString();
|
|
266
259
|
const pid = options.pid ?? process.pid;
|
|
@@ -357,6 +350,18 @@ function isProcessAlive(pid) {
|
|
|
357
350
|
return false;
|
|
358
351
|
}
|
|
359
352
|
}
|
|
353
|
+
class NextSafelistStateLockedError extends Error {
|
|
354
|
+
holder;
|
|
355
|
+
/**
|
|
356
|
+
* @param holder - metadata read from the lock file.
|
|
357
|
+
*/
|
|
358
|
+
constructor(holder) {
|
|
359
|
+
super(formatLiveLockError(holder));
|
|
360
|
+
this.name = "NextSafelistStateLockedError";
|
|
361
|
+
this.holder = holder;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const NEXT_WATCH_LOCK_COMMAND = "csszyx next watch";
|
|
360
365
|
function formatLiveLockError(metadata) {
|
|
361
366
|
return [
|
|
362
367
|
`csszyx Next safelist state is already locked by process ${metadata.pid}.`,
|
|
@@ -410,7 +415,7 @@ function stableStringify(value) {
|
|
|
410
415
|
}
|
|
411
416
|
function pickEnv(env, envKeys) {
|
|
412
417
|
const selected = {};
|
|
413
|
-
for (const key of
|
|
418
|
+
for (const key of safelistSource.sortStrings(new Set(envKeys))) {
|
|
414
419
|
const value = env[key];
|
|
415
420
|
if (value !== void 0) {
|
|
416
421
|
selected[key] = value;
|
|
@@ -535,6 +540,7 @@ function isNestedPackageRoot(parentRoot, candidateRoot) {
|
|
|
535
540
|
|
|
536
541
|
function createNextStateContext(input) {
|
|
537
542
|
const rootResolution = resolveNextAppRoot(input);
|
|
543
|
+
safelistSource.assertNoLegacySourceStylesheet(rootResolution.root);
|
|
538
544
|
const cacheDir = resolveNextAppCacheDir(rootResolution.root, input.cacheDir);
|
|
539
545
|
const identity = createNextCacheIdentity({
|
|
540
546
|
root: rootResolution.root,
|
|
@@ -598,7 +604,7 @@ function runNextWatcherCycle(context, options = {}) {
|
|
|
598
604
|
const lock = acquireNextSafelistStateLock(lockPath, {
|
|
599
605
|
root: context.root,
|
|
600
606
|
mode: context.manifestExpectation.mode,
|
|
601
|
-
command:
|
|
607
|
+
command: NEXT_WATCH_LOCK_COMMAND,
|
|
602
608
|
...options.lockOptions
|
|
603
609
|
});
|
|
604
610
|
try {
|
|
@@ -632,6 +638,8 @@ function runNextWatcherCycle(context, options = {}) {
|
|
|
632
638
|
}
|
|
633
639
|
}
|
|
634
640
|
|
|
641
|
+
exports.NEXT_WATCH_LOCK_COMMAND = NEXT_WATCH_LOCK_COMMAND;
|
|
642
|
+
exports.NextSafelistStateLockedError = NextSafelistStateLockedError;
|
|
635
643
|
exports.createNextStateContext = createNextStateContext;
|
|
636
644
|
exports.readNextGenerationManifest = readNextGenerationManifest;
|
|
637
645
|
exports.runNextWatcherCycle = runNextWatcherCycle;
|
|
@@ -2,9 +2,9 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { extractCrossModuleForwards, extractCrossModuleRegistryEntries, ensureRustTransformAvailable, transformRust, transformWasm, transform } from '@csszyx/compiler';
|
|
4
4
|
import { DEFAULT_IMPORTED_STATIC_SZ } from '@csszyx/types';
|
|
5
|
-
import { c as collectSpecifierAliases, i as importedSpecifiersIn, s as specifierBases, a as resolveProviderPathWith,
|
|
5
|
+
import { c as collectSpecifierAliases, i as importedSpecifiersIn, s as specifierBases, a as resolveProviderPathWith, b as recordResolvedEntry, f as forwardVisitKey, M as MAX_FORWARD_HOPS, d as isReadableProviderFile, e as createTransformCacheKey, g as readTransformCache, w as writeTransformCache } from './unplugin.AGR7mihU.mjs';
|
|
6
|
+
import { n as normalizePathSeparators, s as sortStrings } from './unplugin.CqJS0BbD.mjs';
|
|
6
7
|
import { createHash } from 'node:crypto';
|
|
7
|
-
import { s as sortStrings } from './unplugin.B3XoSRB8.mjs';
|
|
8
8
|
|
|
9
9
|
function resolveImportedStaticSz(value) {
|
|
10
10
|
return value ?? DEFAULT_IMPORTED_STATIC_SZ;
|
|
@@ -3,15 +3,16 @@ import * as fs from 'node:fs';
|
|
|
3
3
|
import { createHash, randomUUID } from 'node:crypto';
|
|
4
4
|
import { hostname } from 'node:os';
|
|
5
5
|
import lockfile from 'proper-lockfile';
|
|
6
|
-
import { s as sortStrings,
|
|
6
|
+
import { S as SAFELIST_FILE, s as sortStrings, r as renderSafelistFile, d as removeLegacySafelists, e as assertNoLegacySourceStylesheet } from './unplugin.CqJS0BbD.mjs';
|
|
7
7
|
|
|
8
8
|
const DEFAULT_RENAME_RETRIES = 5;
|
|
9
9
|
const DEFAULT_RENAME_RETRY_DELAY_MS = 10;
|
|
10
10
|
const DEFAULT_STALE_LOCK_MS = 3e4;
|
|
11
11
|
const STALE_RECOVERY_DISABLED_MS = 2147483647;
|
|
12
|
-
function resolveNextSafelistStatePaths(rootDir, cacheDir = ".csszyx/cache", outputFile =
|
|
12
|
+
function resolveNextSafelistStatePaths(rootDir, cacheDir = ".csszyx/cache", outputFile = SAFELIST_FILE) {
|
|
13
13
|
const resolvedCacheDir = path.resolve(rootDir, cacheDir);
|
|
14
14
|
return {
|
|
15
|
+
rootDir: path.resolve(rootDir),
|
|
15
16
|
cacheDir: resolvedCacheDir,
|
|
16
17
|
shardsDir: path.join(resolvedCacheDir, "safelist-shards"),
|
|
17
18
|
snapshotPath: path.join(resolvedCacheDir, "safelist.snapshot.json"),
|
|
@@ -48,7 +49,8 @@ function materializeNextSafelist(paths, options = {}) {
|
|
|
48
49
|
version: 1,
|
|
49
50
|
sources: sortedSources.map(([sourcePath, classSet]) => [sourcePath, classSet])
|
|
50
51
|
};
|
|
51
|
-
atomicWriteFileSync(paths.outputPath,
|
|
52
|
+
atomicWriteFileSync(paths.outputPath, renderSafelistFile(classNames), options);
|
|
53
|
+
removeLegacySafelists(paths.rootDir, console.warn);
|
|
52
54
|
atomicWriteFileSync(paths.snapshotPath, `${JSON.stringify(snapshot, null, 2)}
|
|
53
55
|
`, options);
|
|
54
56
|
return {
|
|
@@ -80,14 +82,14 @@ function acquireNextSafelistStateLock(lockPath, pidOrOptions = {}) {
|
|
|
80
82
|
} catch (error) {
|
|
81
83
|
const existing2 = readLockMetadata(lockPath);
|
|
82
84
|
if (existing2) {
|
|
83
|
-
throw new
|
|
85
|
+
throw new NextSafelistStateLockedError(existing2);
|
|
84
86
|
}
|
|
85
87
|
throw error;
|
|
86
88
|
}
|
|
87
89
|
const existing = readLockMetadata(lockPath);
|
|
88
90
|
if (existing && isLockLive(existing, options)) {
|
|
89
91
|
releaseAdvisory();
|
|
90
|
-
throw new
|
|
92
|
+
throw new NextSafelistStateLockedError(existing);
|
|
91
93
|
}
|
|
92
94
|
try {
|
|
93
95
|
atomicWriteFileSync(lockPath, `${JSON.stringify(metadata, null, 2)}
|
|
@@ -232,15 +234,6 @@ function normalizeShardRecord(filePath, data) {
|
|
|
232
234
|
})
|
|
233
235
|
};
|
|
234
236
|
}
|
|
235
|
-
function renderTailwindSourceHtml(classNames) {
|
|
236
|
-
if (classNames.length === 0) {
|
|
237
|
-
return "<!-- csszyx Next safelist: empty -->\n";
|
|
238
|
-
}
|
|
239
|
-
const structuralHtml = classNames.map((className) => `<div class="${escapeHtmlAttribute(className)}"></div>`).join("\n");
|
|
240
|
-
const scannerCandidates = renderTailwindScannerCandidates(classNames);
|
|
241
|
-
return `${structuralHtml}
|
|
242
|
-
${scannerCandidates}`;
|
|
243
|
-
}
|
|
244
237
|
function createLockMetadata(options) {
|
|
245
238
|
const now = new Date(options.now ?? Date.now()).toISOString();
|
|
246
239
|
const pid = options.pid ?? process.pid;
|
|
@@ -337,6 +330,18 @@ function isProcessAlive(pid) {
|
|
|
337
330
|
return false;
|
|
338
331
|
}
|
|
339
332
|
}
|
|
333
|
+
class NextSafelistStateLockedError extends Error {
|
|
334
|
+
holder;
|
|
335
|
+
/**
|
|
336
|
+
* @param holder - metadata read from the lock file.
|
|
337
|
+
*/
|
|
338
|
+
constructor(holder) {
|
|
339
|
+
super(formatLiveLockError(holder));
|
|
340
|
+
this.name = "NextSafelistStateLockedError";
|
|
341
|
+
this.holder = holder;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
const NEXT_WATCH_LOCK_COMMAND = "csszyx next watch";
|
|
340
345
|
function formatLiveLockError(metadata) {
|
|
341
346
|
return [
|
|
342
347
|
`csszyx Next safelist state is already locked by process ${metadata.pid}.`,
|
|
@@ -515,6 +520,7 @@ function isNestedPackageRoot(parentRoot, candidateRoot) {
|
|
|
515
520
|
|
|
516
521
|
function createNextStateContext(input) {
|
|
517
522
|
const rootResolution = resolveNextAppRoot(input);
|
|
523
|
+
assertNoLegacySourceStylesheet(rootResolution.root);
|
|
518
524
|
const cacheDir = resolveNextAppCacheDir(rootResolution.root, input.cacheDir);
|
|
519
525
|
const identity = createNextCacheIdentity({
|
|
520
526
|
root: rootResolution.root,
|
|
@@ -578,7 +584,7 @@ function runNextWatcherCycle(context, options = {}) {
|
|
|
578
584
|
const lock = acquireNextSafelistStateLock(lockPath, {
|
|
579
585
|
root: context.root,
|
|
580
586
|
mode: context.manifestExpectation.mode,
|
|
581
|
-
command:
|
|
587
|
+
command: NEXT_WATCH_LOCK_COMMAND,
|
|
582
588
|
...options.lockOptions
|
|
583
589
|
});
|
|
584
590
|
try {
|
|
@@ -612,4 +618,4 @@ function runNextWatcherCycle(context, options = {}) {
|
|
|
612
618
|
}
|
|
613
619
|
}
|
|
614
620
|
|
|
615
|
-
export {
|
|
621
|
+
export { NextSafelistStateLockedError as N, NEXT_WATCH_LOCK_COMMAND as a, readNextGenerationManifest as b, createNextStateContext as c, runNextWatcherCycle as r, validateNextGenerationManifest as v, writeNextSafelistShard as w };
|