tailwindcss-patch 9.5.1 → 10.0.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/bin/tw-patch.js +1 -1
- package/dist/{validate-CgrG4aAY.d.mts → cli-BF06JrJm.d.ts} +6 -2
- package/dist/{validate-Cu1G06lO.mjs → cli-BvMS3VVq.js} +676 -33
- package/dist/cli.js +9 -10
- package/dist/commands/cli-runtime.d.ts +1 -7
- package/dist/commands/cli-runtime.js +2 -9
- package/dist/index.d.ts +5 -6
- package/dist/index.js +14 -329
- package/package.json +24 -20
- package/src/babel/index.ts +3 -10
- package/src/commands/migration-source.ts +1 -1
- package/src/index.bundle.ts +5 -14
- package/src/patching/operations/export-context/postcss-v2.ts +1 -1
- package/src/patching/operations/export-context/postcss-v3.ts +1 -1
- package/dist/cli-Bv15iTiT.mjs +0 -655
- package/dist/cli-Db2YAbkN.js +0 -671
- package/dist/cli.d.mts +0 -1
- package/dist/cli.mjs +0 -21
- package/dist/commands/cli-runtime.d.mts +0 -8
- package/dist/commands/cli-runtime.mjs +0 -3
- package/dist/dist-wp0o36Ns.js +0 -21
- package/dist/index.d.mts +0 -93
- package/dist/index.mjs +0 -66
- package/dist/validate-B5-08lrU.d.ts +0 -599
- package/dist/validate-C8oLv32F.js +0 -3282
- /package/dist/{dist-CxmNpfyy.mjs → dist-CxmNpfyy.js} +0 -0
|
@@ -1,3282 +0,0 @@
|
|
|
1
|
-
//#region \0rolldown/runtime.js
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
-
key = keys[i];
|
|
11
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
-
get: ((k) => from[k]).bind(null, key),
|
|
13
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
-
value: mod,
|
|
20
|
-
enumerable: true
|
|
21
|
-
}) : target, mod));
|
|
22
|
-
//#endregion
|
|
23
|
-
let node_module = require("node:module");
|
|
24
|
-
let node_process = require("node:process");
|
|
25
|
-
node_process = __toESM(node_process);
|
|
26
|
-
let fs_extra = require("fs-extra");
|
|
27
|
-
fs_extra = __toESM(fs_extra);
|
|
28
|
-
let local_pkg = require("local-pkg");
|
|
29
|
-
let pathe = require("pathe");
|
|
30
|
-
pathe = __toESM(pathe);
|
|
31
|
-
let semver = require("semver");
|
|
32
|
-
let node_crypto = require("node:crypto");
|
|
33
|
-
let consola = require("consola");
|
|
34
|
-
let node_url = require("node:url");
|
|
35
|
-
let _tailwindcss_mangle_engine = require("@tailwindcss-mangle/engine");
|
|
36
|
-
let _babel_types = require("@babel/types");
|
|
37
|
-
_babel_types = __toESM(_babel_types);
|
|
38
|
-
let _babel_generator = require("@babel/generator");
|
|
39
|
-
_babel_generator = __toESM(_babel_generator);
|
|
40
|
-
let _babel_traverse = require("@babel/traverse");
|
|
41
|
-
_babel_traverse = __toESM(_babel_traverse);
|
|
42
|
-
let _babel_parser = require("@babel/parser");
|
|
43
|
-
let postcss = require("postcss");
|
|
44
|
-
postcss = __toESM(postcss);
|
|
45
|
-
let tailwindcss_config = require("tailwindcss-config");
|
|
46
|
-
//#region package.json
|
|
47
|
-
var version = "9.5.1";
|
|
48
|
-
//#endregion
|
|
49
|
-
//#region src/constants.ts
|
|
50
|
-
const pkgName = "tailwindcss-patch";
|
|
51
|
-
const pkgVersion = version;
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region src/cache/context.ts
|
|
54
|
-
const DEFAULT_TAILWIND_CONFIG_FILES = [
|
|
55
|
-
"tailwind.config.js",
|
|
56
|
-
"tailwind.config.cjs",
|
|
57
|
-
"tailwind.config.mjs",
|
|
58
|
-
"tailwind.config.ts",
|
|
59
|
-
"tailwind.config.cts",
|
|
60
|
-
"tailwind.config.mts"
|
|
61
|
-
];
|
|
62
|
-
function normalizePathname(value) {
|
|
63
|
-
return pathe.default.normalize(value).replaceAll("\\", "/");
|
|
64
|
-
}
|
|
65
|
-
function resolveRealpathSyncSafe(value) {
|
|
66
|
-
const resolved = pathe.default.resolve(value);
|
|
67
|
-
try {
|
|
68
|
-
return normalizePathname(fs_extra.default.realpathSync(resolved));
|
|
69
|
-
} catch {
|
|
70
|
-
return normalizePathname(resolved);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
function resolveFileMtimeMsSync(value) {
|
|
74
|
-
if (!value) return;
|
|
75
|
-
try {
|
|
76
|
-
const stat = fs_extra.default.statSync(value);
|
|
77
|
-
if (!stat.isFile()) return;
|
|
78
|
-
return stat.mtimeMs;
|
|
79
|
-
} catch {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
function resolveTailwindConfigPath(options, majorVersion) {
|
|
84
|
-
const tailwind = options.tailwind;
|
|
85
|
-
const baseDir = tailwind.cwd ?? options.projectRoot;
|
|
86
|
-
const configured = (() => {
|
|
87
|
-
if (majorVersion === 2 && tailwind.v2?.config) return tailwind.v2.config;
|
|
88
|
-
if (majorVersion === 3 && tailwind.v3?.config) return tailwind.v3.config;
|
|
89
|
-
return tailwind.config;
|
|
90
|
-
})();
|
|
91
|
-
if (configured) {
|
|
92
|
-
const absolute = pathe.default.isAbsolute(configured) ? configured : pathe.default.resolve(baseDir, configured);
|
|
93
|
-
if (fs_extra.default.pathExistsSync(absolute)) return resolveRealpathSyncSafe(absolute);
|
|
94
|
-
}
|
|
95
|
-
for (const candidate of DEFAULT_TAILWIND_CONFIG_FILES) {
|
|
96
|
-
const absolute = pathe.default.resolve(baseDir, candidate);
|
|
97
|
-
if (fs_extra.default.pathExistsSync(absolute)) return resolveRealpathSyncSafe(absolute);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function stableSerialize(input) {
|
|
101
|
-
if (input === null) return "null";
|
|
102
|
-
if (typeof input === "string") return JSON.stringify(input);
|
|
103
|
-
if (typeof input === "number" || typeof input === "boolean") return JSON.stringify(input);
|
|
104
|
-
if (Array.isArray(input)) return `[${input.map((item) => stableSerialize(item)).join(",")}]`;
|
|
105
|
-
if (typeof input === "object") return `{${Object.entries(input).filter(([, value]) => value !== void 0).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => `${JSON.stringify(key)}:${stableSerialize(value)}`).join(",")}}`;
|
|
106
|
-
return JSON.stringify(String(input));
|
|
107
|
-
}
|
|
108
|
-
function hash(input) {
|
|
109
|
-
return (0, node_crypto.createHash)("sha256").update(input).digest("hex");
|
|
110
|
-
}
|
|
111
|
-
function toFingerprintOptions(normalized) {
|
|
112
|
-
return {
|
|
113
|
-
overwrite: normalized.overwrite,
|
|
114
|
-
output: {
|
|
115
|
-
removeUniversalSelector: normalized.output.removeUniversalSelector,
|
|
116
|
-
format: normalized.output.format
|
|
117
|
-
},
|
|
118
|
-
features: normalized.features,
|
|
119
|
-
tailwind: {
|
|
120
|
-
packageName: normalized.tailwind.packageName,
|
|
121
|
-
cwd: normalized.tailwind.cwd,
|
|
122
|
-
config: normalized.tailwind.config,
|
|
123
|
-
postcssPlugin: normalized.tailwind.postcssPlugin,
|
|
124
|
-
versionHint: normalized.tailwind.versionHint,
|
|
125
|
-
v2: normalized.tailwind.v2,
|
|
126
|
-
v3: normalized.tailwind.v3,
|
|
127
|
-
v4: normalized.tailwind.v4
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
function createCacheContextDescriptor(options, packageInfo, majorVersion) {
|
|
132
|
-
const projectRootRealpath = resolveRealpathSyncSafe(options.projectRoot);
|
|
133
|
-
const processCwdRealpath = resolveRealpathSyncSafe(node_process.default.cwd());
|
|
134
|
-
const cacheCwdRealpath = resolveRealpathSyncSafe(options.cache.cwd);
|
|
135
|
-
const tailwindPackageRootRealpath = resolveRealpathSyncSafe(packageInfo.rootPath);
|
|
136
|
-
const tailwindConfigPath = resolveTailwindConfigPath(options, majorVersion);
|
|
137
|
-
const tailwindConfigMtimeMs = resolveFileMtimeMsSync(tailwindConfigPath);
|
|
138
|
-
const optionsHash = hash(stableSerialize(toFingerprintOptions(options)));
|
|
139
|
-
const metadata = {
|
|
140
|
-
fingerprintVersion: 1,
|
|
141
|
-
projectRootRealpath,
|
|
142
|
-
processCwdRealpath,
|
|
143
|
-
cacheCwdRealpath,
|
|
144
|
-
...tailwindConfigPath === void 0 ? {} : { tailwindConfigPath },
|
|
145
|
-
...tailwindConfigMtimeMs === void 0 ? {} : { tailwindConfigMtimeMs },
|
|
146
|
-
tailwindPackageRootRealpath,
|
|
147
|
-
tailwindPackageVersion: packageInfo.version ?? "unknown",
|
|
148
|
-
patcherVersion: pkgVersion,
|
|
149
|
-
majorVersion,
|
|
150
|
-
optionsHash
|
|
151
|
-
};
|
|
152
|
-
return {
|
|
153
|
-
fingerprint: hash(stableSerialize(metadata)),
|
|
154
|
-
metadata
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
function explainContextMismatch(current, cached) {
|
|
158
|
-
const reasons = [];
|
|
159
|
-
if (current.projectRootRealpath !== cached.projectRootRealpath) reasons.push(`project-root changed: ${cached.projectRootRealpath} -> ${current.projectRootRealpath}`);
|
|
160
|
-
if (current.processCwdRealpath !== cached.processCwdRealpath) reasons.push(`process-cwd changed: ${cached.processCwdRealpath} -> ${current.processCwdRealpath}`);
|
|
161
|
-
if (current.cacheCwdRealpath !== cached.cacheCwdRealpath) reasons.push(`cache-cwd changed: ${cached.cacheCwdRealpath} -> ${current.cacheCwdRealpath}`);
|
|
162
|
-
if ((current.tailwindConfigPath ?? "") !== (cached.tailwindConfigPath ?? "")) reasons.push(`tailwind-config path changed: ${cached.tailwindConfigPath ?? "<none>"} -> ${current.tailwindConfigPath ?? "<none>"}`);
|
|
163
|
-
if ((current.tailwindConfigMtimeMs ?? -1) !== (cached.tailwindConfigMtimeMs ?? -1)) reasons.push("tailwind-config mtime changed");
|
|
164
|
-
if (current.tailwindPackageRootRealpath !== cached.tailwindPackageRootRealpath) reasons.push(`tailwind-package root changed: ${cached.tailwindPackageRootRealpath} -> ${current.tailwindPackageRootRealpath}`);
|
|
165
|
-
if (current.tailwindPackageVersion !== cached.tailwindPackageVersion) reasons.push(`tailwind-package version changed: ${cached.tailwindPackageVersion} -> ${current.tailwindPackageVersion}`);
|
|
166
|
-
if (current.patcherVersion !== cached.patcherVersion) reasons.push(`patcher version changed: ${cached.patcherVersion} -> ${current.patcherVersion}`);
|
|
167
|
-
if (current.majorVersion !== cached.majorVersion) reasons.push(`major version changed: ${cached.majorVersion} -> ${current.majorVersion}`);
|
|
168
|
-
if (current.optionsHash !== cached.optionsHash) reasons.push(`patch options hash changed: ${cached.optionsHash.slice(0, 12)} -> ${current.optionsHash.slice(0, 12)}`);
|
|
169
|
-
return reasons;
|
|
170
|
-
}
|
|
171
|
-
//#endregion
|
|
172
|
-
//#region src/logger.ts
|
|
173
|
-
const logger = (0, consola.createConsola)();
|
|
174
|
-
//#endregion
|
|
175
|
-
//#region src/cache/store.ts
|
|
176
|
-
function isErrnoException(error) {
|
|
177
|
-
return error instanceof Error && typeof error.code === "string";
|
|
178
|
-
}
|
|
179
|
-
function isAccessDenied(error) {
|
|
180
|
-
return isErrnoException(error) && Boolean(error.code && [
|
|
181
|
-
"EPERM",
|
|
182
|
-
"EBUSY",
|
|
183
|
-
"EACCES"
|
|
184
|
-
].includes(error.code));
|
|
185
|
-
}
|
|
186
|
-
function toStringArray(value) {
|
|
187
|
-
if (!Array.isArray(value)) return [];
|
|
188
|
-
return value.filter((item) => typeof item === "string");
|
|
189
|
-
}
|
|
190
|
-
function asObject(value) {
|
|
191
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
192
|
-
return value;
|
|
193
|
-
}
|
|
194
|
-
function toReadMeta(meta) {
|
|
195
|
-
return {
|
|
196
|
-
...meta,
|
|
197
|
-
details: [...meta.details]
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
function cloneEntry(entry) {
|
|
201
|
-
return {
|
|
202
|
-
context: { ...entry.context },
|
|
203
|
-
values: [...entry.values],
|
|
204
|
-
updatedAt: entry.updatedAt
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
var CacheStore = class {
|
|
208
|
-
options;
|
|
209
|
-
context;
|
|
210
|
-
driver;
|
|
211
|
-
lockPath;
|
|
212
|
-
memoryCache = null;
|
|
213
|
-
memoryIndex = null;
|
|
214
|
-
lastReadMeta = {
|
|
215
|
-
hit: false,
|
|
216
|
-
reason: "context-not-found",
|
|
217
|
-
details: []
|
|
218
|
-
};
|
|
219
|
-
constructor(options, context) {
|
|
220
|
-
this.options = options;
|
|
221
|
-
this.context = context;
|
|
222
|
-
this.driver = options.driver ?? "file";
|
|
223
|
-
this.lockPath = `${this.options.path}.lock`;
|
|
224
|
-
}
|
|
225
|
-
isContextAware() {
|
|
226
|
-
return this.context !== void 0;
|
|
227
|
-
}
|
|
228
|
-
createEmptyIndex() {
|
|
229
|
-
return {
|
|
230
|
-
schemaVersion: 2,
|
|
231
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
232
|
-
contexts: {}
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
async ensureDir() {
|
|
236
|
-
await fs_extra.default.ensureDir(this.options.dir);
|
|
237
|
-
}
|
|
238
|
-
ensureDirSync() {
|
|
239
|
-
fs_extra.default.ensureDirSync(this.options.dir);
|
|
240
|
-
}
|
|
241
|
-
createTempPath() {
|
|
242
|
-
const uniqueSuffix = `${node_process.default.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
243
|
-
return `${this.options.path}.${uniqueSuffix}.tmp`;
|
|
244
|
-
}
|
|
245
|
-
async replaceCacheFile(tempPath) {
|
|
246
|
-
try {
|
|
247
|
-
await fs_extra.default.rename(tempPath, this.options.path);
|
|
248
|
-
return true;
|
|
249
|
-
} catch (error) {
|
|
250
|
-
if (isErrnoException(error) && (error.code === "EEXIST" || error.code === "EPERM")) {
|
|
251
|
-
try {
|
|
252
|
-
await fs_extra.default.remove(this.options.path);
|
|
253
|
-
} catch (removeError) {
|
|
254
|
-
if (isAccessDenied(removeError)) {
|
|
255
|
-
logger.debug("Tailwind class cache locked or read-only, skipping update.", removeError);
|
|
256
|
-
return false;
|
|
257
|
-
}
|
|
258
|
-
if (!isErrnoException(removeError) || removeError.code !== "ENOENT") throw removeError;
|
|
259
|
-
}
|
|
260
|
-
await fs_extra.default.rename(tempPath, this.options.path);
|
|
261
|
-
return true;
|
|
262
|
-
}
|
|
263
|
-
throw error;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
replaceCacheFileSync(tempPath) {
|
|
267
|
-
try {
|
|
268
|
-
fs_extra.default.renameSync(tempPath, this.options.path);
|
|
269
|
-
return true;
|
|
270
|
-
} catch (error) {
|
|
271
|
-
if (isErrnoException(error) && (error.code === "EEXIST" || error.code === "EPERM")) {
|
|
272
|
-
try {
|
|
273
|
-
fs_extra.default.removeSync(this.options.path);
|
|
274
|
-
} catch (removeError) {
|
|
275
|
-
if (isAccessDenied(removeError)) {
|
|
276
|
-
logger.debug("Tailwind class cache locked or read-only, skipping update.", removeError);
|
|
277
|
-
return false;
|
|
278
|
-
}
|
|
279
|
-
if (!isErrnoException(removeError) || removeError.code !== "ENOENT") throw removeError;
|
|
280
|
-
}
|
|
281
|
-
fs_extra.default.renameSync(tempPath, this.options.path);
|
|
282
|
-
return true;
|
|
283
|
-
}
|
|
284
|
-
throw error;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
async cleanupTempFile(tempPath) {
|
|
288
|
-
try {
|
|
289
|
-
await fs_extra.default.remove(tempPath);
|
|
290
|
-
} catch {}
|
|
291
|
-
}
|
|
292
|
-
cleanupTempFileSync(tempPath) {
|
|
293
|
-
try {
|
|
294
|
-
fs_extra.default.removeSync(tempPath);
|
|
295
|
-
} catch {}
|
|
296
|
-
}
|
|
297
|
-
async delay(ms) {
|
|
298
|
-
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
299
|
-
}
|
|
300
|
-
async acquireLock() {
|
|
301
|
-
await fs_extra.default.ensureDir(this.options.dir);
|
|
302
|
-
const maxAttempts = 40;
|
|
303
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) try {
|
|
304
|
-
await fs_extra.default.writeFile(this.lockPath, `${node_process.default.pid}\n${Date.now()}`, { flag: "wx" });
|
|
305
|
-
return true;
|
|
306
|
-
} catch (error) {
|
|
307
|
-
if (!isErrnoException(error) || error.code !== "EEXIST") {
|
|
308
|
-
logger.debug("Unable to acquire cache lock.", error);
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
try {
|
|
312
|
-
const stat = await fs_extra.default.stat(this.lockPath);
|
|
313
|
-
if (Date.now() - stat.mtimeMs > 3e4) {
|
|
314
|
-
await fs_extra.default.remove(this.lockPath);
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
} catch {}
|
|
318
|
-
await this.delay(25);
|
|
319
|
-
}
|
|
320
|
-
logger.debug("Timed out while waiting for cache lock; skipping cache mutation.");
|
|
321
|
-
return false;
|
|
322
|
-
}
|
|
323
|
-
releaseLockSyncOrAsync(sync) {
|
|
324
|
-
if (sync) {
|
|
325
|
-
try {
|
|
326
|
-
fs_extra.default.removeSync(this.lockPath);
|
|
327
|
-
} catch {}
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
return fs_extra.default.remove(this.lockPath).catch(() => void 0);
|
|
331
|
-
}
|
|
332
|
-
acquireLockSync() {
|
|
333
|
-
fs_extra.default.ensureDirSync(this.options.dir);
|
|
334
|
-
const maxAttempts = 40;
|
|
335
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) try {
|
|
336
|
-
fs_extra.default.writeFileSync(this.lockPath, `${node_process.default.pid}\n${Date.now()}`, { flag: "wx" });
|
|
337
|
-
return true;
|
|
338
|
-
} catch (error) {
|
|
339
|
-
if (!isErrnoException(error) || error.code !== "EEXIST") {
|
|
340
|
-
logger.debug("Unable to acquire cache lock.", error);
|
|
341
|
-
return false;
|
|
342
|
-
}
|
|
343
|
-
try {
|
|
344
|
-
const stat = fs_extra.default.statSync(this.lockPath);
|
|
345
|
-
if (Date.now() - stat.mtimeMs > 3e4) {
|
|
346
|
-
fs_extra.default.removeSync(this.lockPath);
|
|
347
|
-
continue;
|
|
348
|
-
}
|
|
349
|
-
} catch {}
|
|
350
|
-
const start = Date.now();
|
|
351
|
-
while (Date.now() - start < 25);
|
|
352
|
-
}
|
|
353
|
-
logger.debug("Timed out while waiting for cache lock; skipping cache mutation.");
|
|
354
|
-
return false;
|
|
355
|
-
}
|
|
356
|
-
async withFileLock(fn) {
|
|
357
|
-
if (!await this.acquireLock()) return;
|
|
358
|
-
try {
|
|
359
|
-
return await fn();
|
|
360
|
-
} finally {
|
|
361
|
-
await this.releaseLockSyncOrAsync(false);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
withFileLockSync(fn) {
|
|
365
|
-
if (!this.acquireLockSync()) return;
|
|
366
|
-
try {
|
|
367
|
-
return fn();
|
|
368
|
-
} finally {
|
|
369
|
-
this.releaseLockSyncOrAsync(true);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
normalizeContextEntry(value) {
|
|
373
|
-
const record = asObject(value);
|
|
374
|
-
if (!record) return;
|
|
375
|
-
const values = toStringArray(record["values"]);
|
|
376
|
-
if (values.length === 0) return;
|
|
377
|
-
const contextRecord = asObject(record["context"]);
|
|
378
|
-
if (!contextRecord) return;
|
|
379
|
-
const { fingerprintVersion, projectRootRealpath, processCwdRealpath, cacheCwdRealpath, tailwindConfigPath, tailwindConfigMtimeMs, tailwindPackageRootRealpath, tailwindPackageVersion, patcherVersion, majorVersion, optionsHash } = contextRecord;
|
|
380
|
-
if (fingerprintVersion !== 1 || typeof projectRootRealpath !== "string" || typeof processCwdRealpath !== "string" || typeof cacheCwdRealpath !== "string" || typeof tailwindPackageRootRealpath !== "string" || typeof tailwindPackageVersion !== "string" || typeof patcherVersion !== "string" || majorVersion !== 2 && majorVersion !== 3 && majorVersion !== 4 || typeof optionsHash !== "string") return;
|
|
381
|
-
return {
|
|
382
|
-
context: {
|
|
383
|
-
fingerprintVersion,
|
|
384
|
-
projectRootRealpath,
|
|
385
|
-
processCwdRealpath,
|
|
386
|
-
cacheCwdRealpath,
|
|
387
|
-
...typeof tailwindConfigPath === "string" ? { tailwindConfigPath } : {},
|
|
388
|
-
...typeof tailwindConfigMtimeMs === "number" ? { tailwindConfigMtimeMs } : {},
|
|
389
|
-
tailwindPackageRootRealpath,
|
|
390
|
-
tailwindPackageVersion,
|
|
391
|
-
patcherVersion,
|
|
392
|
-
majorVersion,
|
|
393
|
-
optionsHash
|
|
394
|
-
},
|
|
395
|
-
values,
|
|
396
|
-
updatedAt: typeof record["updatedAt"] === "string" ? record["updatedAt"] : (/* @__PURE__ */ new Date(0)).toISOString()
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
normalizeIndexFile(payload) {
|
|
400
|
-
if (Array.isArray(payload)) return {
|
|
401
|
-
kind: "legacy",
|
|
402
|
-
data: toStringArray(payload)
|
|
403
|
-
};
|
|
404
|
-
const record = asObject(payload);
|
|
405
|
-
if (!record) return { kind: "invalid" };
|
|
406
|
-
if (record["schemaVersion"] !== 2) return { kind: "invalid" };
|
|
407
|
-
const contextsRecord = asObject(record["contexts"]);
|
|
408
|
-
if (!contextsRecord) return { kind: "invalid" };
|
|
409
|
-
const contexts = {};
|
|
410
|
-
for (const [fingerprint, value] of Object.entries(contextsRecord)) {
|
|
411
|
-
if (typeof fingerprint !== "string" || !fingerprint) continue;
|
|
412
|
-
const entry = this.normalizeContextEntry(value);
|
|
413
|
-
if (!entry) continue;
|
|
414
|
-
contexts[fingerprint] = entry;
|
|
415
|
-
}
|
|
416
|
-
return {
|
|
417
|
-
kind: "v2",
|
|
418
|
-
data: {
|
|
419
|
-
schemaVersion: 2,
|
|
420
|
-
updatedAt: typeof record["updatedAt"] === "string" ? record["updatedAt"] : (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
421
|
-
contexts
|
|
422
|
-
}
|
|
423
|
-
};
|
|
424
|
-
}
|
|
425
|
-
async readParsedCacheFile(cleanupInvalid) {
|
|
426
|
-
try {
|
|
427
|
-
if (!await fs_extra.default.pathExists(this.options.path)) return { kind: "empty" };
|
|
428
|
-
const payload = await fs_extra.default.readJSON(this.options.path);
|
|
429
|
-
const normalized = this.normalizeIndexFile(payload);
|
|
430
|
-
if (normalized.kind !== "invalid") return normalized;
|
|
431
|
-
if (cleanupInvalid) {
|
|
432
|
-
logger.warn("Unable to read Tailwind class cache index, removing invalid file.");
|
|
433
|
-
await fs_extra.default.remove(this.options.path);
|
|
434
|
-
}
|
|
435
|
-
return { kind: "invalid" };
|
|
436
|
-
} catch (error) {
|
|
437
|
-
if (isErrnoException(error) && error.code === "ENOENT") return { kind: "empty" };
|
|
438
|
-
logger.warn("Unable to read Tailwind class cache index, removing invalid file.", error);
|
|
439
|
-
if (cleanupInvalid) try {
|
|
440
|
-
await fs_extra.default.remove(this.options.path);
|
|
441
|
-
} catch (cleanupError) {
|
|
442
|
-
logger.error("Failed to clean up invalid cache file", cleanupError);
|
|
443
|
-
}
|
|
444
|
-
return { kind: "invalid" };
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
readParsedCacheFileSync(cleanupInvalid) {
|
|
448
|
-
try {
|
|
449
|
-
if (!fs_extra.default.pathExistsSync(this.options.path)) return { kind: "empty" };
|
|
450
|
-
const payload = fs_extra.default.readJSONSync(this.options.path);
|
|
451
|
-
const normalized = this.normalizeIndexFile(payload);
|
|
452
|
-
if (normalized.kind !== "invalid") return normalized;
|
|
453
|
-
if (cleanupInvalid) {
|
|
454
|
-
logger.warn("Unable to read Tailwind class cache index, removing invalid file.");
|
|
455
|
-
fs_extra.default.removeSync(this.options.path);
|
|
456
|
-
}
|
|
457
|
-
return { kind: "invalid" };
|
|
458
|
-
} catch (error) {
|
|
459
|
-
if (isErrnoException(error) && error.code === "ENOENT") return { kind: "empty" };
|
|
460
|
-
logger.warn("Unable to read Tailwind class cache index, removing invalid file.", error);
|
|
461
|
-
if (cleanupInvalid) try {
|
|
462
|
-
fs_extra.default.removeSync(this.options.path);
|
|
463
|
-
} catch (cleanupError) {
|
|
464
|
-
logger.error("Failed to clean up invalid cache file", cleanupError);
|
|
465
|
-
}
|
|
466
|
-
return { kind: "invalid" };
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
findProjectMatch(index) {
|
|
470
|
-
if (!this.context) return;
|
|
471
|
-
const current = this.context.metadata.projectRootRealpath;
|
|
472
|
-
return Object.entries(index.contexts).find(([, entry]) => entry.context.projectRootRealpath === current);
|
|
473
|
-
}
|
|
474
|
-
async writeIndexFile(index) {
|
|
475
|
-
const tempPath = this.createTempPath();
|
|
476
|
-
try {
|
|
477
|
-
await this.ensureDir();
|
|
478
|
-
await fs_extra.default.writeJSON(tempPath, index);
|
|
479
|
-
if (await this.replaceCacheFile(tempPath)) return this.options.path;
|
|
480
|
-
await this.cleanupTempFile(tempPath);
|
|
481
|
-
return;
|
|
482
|
-
} catch (error) {
|
|
483
|
-
await this.cleanupTempFile(tempPath);
|
|
484
|
-
logger.error("Unable to persist Tailwind class cache", error);
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
writeIndexFileSync(index) {
|
|
489
|
-
const tempPath = this.createTempPath();
|
|
490
|
-
try {
|
|
491
|
-
this.ensureDirSync();
|
|
492
|
-
fs_extra.default.writeJSONSync(tempPath, index);
|
|
493
|
-
if (this.replaceCacheFileSync(tempPath)) return this.options.path;
|
|
494
|
-
this.cleanupTempFileSync(tempPath);
|
|
495
|
-
return;
|
|
496
|
-
} catch (error) {
|
|
497
|
-
this.cleanupTempFileSync(tempPath);
|
|
498
|
-
logger.error("Unable to persist Tailwind class cache", error);
|
|
499
|
-
return;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
async write(data) {
|
|
503
|
-
if (!this.options.enabled) return;
|
|
504
|
-
if (this.driver === "noop") return;
|
|
505
|
-
if (this.driver === "memory") {
|
|
506
|
-
if (!this.isContextAware()) {
|
|
507
|
-
this.memoryCache = new Set(data);
|
|
508
|
-
return "memory";
|
|
509
|
-
}
|
|
510
|
-
const index = this.memoryIndex ?? this.createEmptyIndex();
|
|
511
|
-
if (!this.context) return "memory";
|
|
512
|
-
index.contexts[this.context.fingerprint] = {
|
|
513
|
-
context: { ...this.context.metadata },
|
|
514
|
-
values: Array.from(data),
|
|
515
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
516
|
-
};
|
|
517
|
-
index.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
518
|
-
this.memoryIndex = index;
|
|
519
|
-
return "memory";
|
|
520
|
-
}
|
|
521
|
-
if (!this.isContextAware()) {
|
|
522
|
-
const tempPath = this.createTempPath();
|
|
523
|
-
try {
|
|
524
|
-
await this.ensureDir();
|
|
525
|
-
await fs_extra.default.writeJSON(tempPath, Array.from(data));
|
|
526
|
-
if (await this.replaceCacheFile(tempPath)) return this.options.path;
|
|
527
|
-
await this.cleanupTempFile(tempPath);
|
|
528
|
-
return;
|
|
529
|
-
} catch (error) {
|
|
530
|
-
await this.cleanupTempFile(tempPath);
|
|
531
|
-
logger.error("Unable to persist Tailwind class cache", error);
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
return await this.withFileLock(async () => {
|
|
536
|
-
const parsed = await this.readParsedCacheFile(false);
|
|
537
|
-
const index = parsed.kind === "v2" ? parsed.data : this.createEmptyIndex();
|
|
538
|
-
if (this.context) index.contexts[this.context.fingerprint] = {
|
|
539
|
-
context: { ...this.context.metadata },
|
|
540
|
-
values: Array.from(data),
|
|
541
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
542
|
-
};
|
|
543
|
-
index.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
544
|
-
return this.writeIndexFile(index);
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
writeSync(data) {
|
|
548
|
-
if (!this.options.enabled) return;
|
|
549
|
-
if (this.driver === "noop") return;
|
|
550
|
-
if (this.driver === "memory") {
|
|
551
|
-
if (!this.isContextAware()) {
|
|
552
|
-
this.memoryCache = new Set(data);
|
|
553
|
-
return "memory";
|
|
554
|
-
}
|
|
555
|
-
const index = this.memoryIndex ?? this.createEmptyIndex();
|
|
556
|
-
if (!this.context) return "memory";
|
|
557
|
-
index.contexts[this.context.fingerprint] = {
|
|
558
|
-
context: { ...this.context.metadata },
|
|
559
|
-
values: Array.from(data),
|
|
560
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
561
|
-
};
|
|
562
|
-
index.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
563
|
-
this.memoryIndex = index;
|
|
564
|
-
return "memory";
|
|
565
|
-
}
|
|
566
|
-
if (!this.isContextAware()) {
|
|
567
|
-
const tempPath = this.createTempPath();
|
|
568
|
-
try {
|
|
569
|
-
this.ensureDirSync();
|
|
570
|
-
fs_extra.default.writeJSONSync(tempPath, Array.from(data));
|
|
571
|
-
if (this.replaceCacheFileSync(tempPath)) return this.options.path;
|
|
572
|
-
this.cleanupTempFileSync(tempPath);
|
|
573
|
-
return;
|
|
574
|
-
} catch (error) {
|
|
575
|
-
this.cleanupTempFileSync(tempPath);
|
|
576
|
-
logger.error("Unable to persist Tailwind class cache", error);
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
return this.withFileLockSync(() => {
|
|
581
|
-
const parsed = this.readParsedCacheFileSync(false);
|
|
582
|
-
const index = parsed.kind === "v2" ? parsed.data : this.createEmptyIndex();
|
|
583
|
-
if (this.context) index.contexts[this.context.fingerprint] = {
|
|
584
|
-
context: { ...this.context.metadata },
|
|
585
|
-
values: Array.from(data),
|
|
586
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
587
|
-
};
|
|
588
|
-
index.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
589
|
-
return this.writeIndexFileSync(index);
|
|
590
|
-
});
|
|
591
|
-
}
|
|
592
|
-
async readWithMeta() {
|
|
593
|
-
if (!this.options.enabled) return {
|
|
594
|
-
data: /* @__PURE__ */ new Set(),
|
|
595
|
-
meta: {
|
|
596
|
-
hit: false,
|
|
597
|
-
reason: "cache-disabled",
|
|
598
|
-
details: ["cache disabled"]
|
|
599
|
-
}
|
|
600
|
-
};
|
|
601
|
-
if (this.driver === "noop") return {
|
|
602
|
-
data: /* @__PURE__ */ new Set(),
|
|
603
|
-
meta: {
|
|
604
|
-
hit: false,
|
|
605
|
-
reason: "noop-driver",
|
|
606
|
-
details: ["cache driver is noop"]
|
|
607
|
-
}
|
|
608
|
-
};
|
|
609
|
-
if (this.driver === "memory") {
|
|
610
|
-
if (!this.isContextAware()) {
|
|
611
|
-
const cache = new Set(this.memoryCache ?? []);
|
|
612
|
-
return {
|
|
613
|
-
data: cache,
|
|
614
|
-
meta: {
|
|
615
|
-
hit: cache.size > 0,
|
|
616
|
-
reason: cache.size > 0 ? "hit" : "context-not-found",
|
|
617
|
-
details: cache.size > 0 ? ["memory cache hit"] : ["memory cache miss"]
|
|
618
|
-
}
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
const index = this.memoryIndex;
|
|
622
|
-
if (!index || !this.context) return {
|
|
623
|
-
data: /* @__PURE__ */ new Set(),
|
|
624
|
-
meta: {
|
|
625
|
-
hit: false,
|
|
626
|
-
reason: "context-not-found",
|
|
627
|
-
...this.context?.fingerprint === void 0 ? {} : { fingerprint: this.context.fingerprint },
|
|
628
|
-
schemaVersion: 2,
|
|
629
|
-
details: ["no in-memory cache index for current context"]
|
|
630
|
-
}
|
|
631
|
-
};
|
|
632
|
-
const entry = index.contexts[this.context.fingerprint];
|
|
633
|
-
if (entry) return {
|
|
634
|
-
data: new Set(entry.values),
|
|
635
|
-
meta: {
|
|
636
|
-
hit: true,
|
|
637
|
-
reason: "hit",
|
|
638
|
-
fingerprint: this.context.fingerprint,
|
|
639
|
-
schemaVersion: 2,
|
|
640
|
-
details: ["memory cache hit"]
|
|
641
|
-
}
|
|
642
|
-
};
|
|
643
|
-
const projectMatch = this.findProjectMatch(index);
|
|
644
|
-
if (projectMatch && this.context) {
|
|
645
|
-
const [, matchedEntry] = projectMatch;
|
|
646
|
-
return {
|
|
647
|
-
data: /* @__PURE__ */ new Set(),
|
|
648
|
-
meta: {
|
|
649
|
-
hit: false,
|
|
650
|
-
reason: "context-mismatch",
|
|
651
|
-
fingerprint: this.context.fingerprint,
|
|
652
|
-
schemaVersion: 2,
|
|
653
|
-
details: explainContextMismatch(this.context.metadata, matchedEntry.context)
|
|
654
|
-
}
|
|
655
|
-
};
|
|
656
|
-
}
|
|
657
|
-
return {
|
|
658
|
-
data: /* @__PURE__ */ new Set(),
|
|
659
|
-
meta: {
|
|
660
|
-
hit: false,
|
|
661
|
-
reason: "context-not-found",
|
|
662
|
-
fingerprint: this.context.fingerprint,
|
|
663
|
-
schemaVersion: 2,
|
|
664
|
-
details: ["context fingerprint not found in memory cache index"]
|
|
665
|
-
}
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
const parsed = await this.readParsedCacheFile(true);
|
|
669
|
-
if (parsed.kind === "empty") return {
|
|
670
|
-
data: /* @__PURE__ */ new Set(),
|
|
671
|
-
meta: {
|
|
672
|
-
hit: false,
|
|
673
|
-
reason: "file-missing",
|
|
674
|
-
details: ["cache file not found"]
|
|
675
|
-
}
|
|
676
|
-
};
|
|
677
|
-
if (parsed.kind === "invalid") return {
|
|
678
|
-
data: /* @__PURE__ */ new Set(),
|
|
679
|
-
meta: {
|
|
680
|
-
hit: false,
|
|
681
|
-
reason: "invalid-schema",
|
|
682
|
-
details: ["cache schema invalid and has been reset"]
|
|
683
|
-
}
|
|
684
|
-
};
|
|
685
|
-
if (!this.isContextAware()) {
|
|
686
|
-
if (parsed.kind === "legacy") return {
|
|
687
|
-
data: new Set(parsed.data),
|
|
688
|
-
meta: {
|
|
689
|
-
hit: parsed.data.length > 0,
|
|
690
|
-
reason: parsed.data.length > 0 ? "hit" : "context-not-found",
|
|
691
|
-
details: ["legacy cache format"]
|
|
692
|
-
}
|
|
693
|
-
};
|
|
694
|
-
const union = Object.values(parsed.data.contexts).flatMap((entry) => entry.values);
|
|
695
|
-
return {
|
|
696
|
-
data: new Set(union),
|
|
697
|
-
meta: {
|
|
698
|
-
hit: union.length > 0,
|
|
699
|
-
reason: union.length > 0 ? "hit" : "context-not-found",
|
|
700
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
701
|
-
details: ["context-less read merged all cache entries"]
|
|
702
|
-
}
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
if (parsed.kind === "legacy") return {
|
|
706
|
-
data: /* @__PURE__ */ new Set(),
|
|
707
|
-
meta: {
|
|
708
|
-
hit: false,
|
|
709
|
-
reason: "legacy-schema",
|
|
710
|
-
...this.context?.fingerprint === void 0 ? {} : { fingerprint: this.context.fingerprint },
|
|
711
|
-
details: ["legacy cache schema detected; rebuilding cache with context fingerprint"]
|
|
712
|
-
}
|
|
713
|
-
};
|
|
714
|
-
if (!this.context) return {
|
|
715
|
-
data: /* @__PURE__ */ new Set(),
|
|
716
|
-
meta: {
|
|
717
|
-
hit: false,
|
|
718
|
-
reason: "context-not-found",
|
|
719
|
-
details: ["cache context missing"]
|
|
720
|
-
}
|
|
721
|
-
};
|
|
722
|
-
const entry = parsed.data.contexts[this.context.fingerprint];
|
|
723
|
-
if (entry) {
|
|
724
|
-
const mismatchReasons = explainContextMismatch(this.context.metadata, entry.context);
|
|
725
|
-
if (mismatchReasons.length === 0) return {
|
|
726
|
-
data: new Set(entry.values),
|
|
727
|
-
meta: {
|
|
728
|
-
hit: true,
|
|
729
|
-
reason: "hit",
|
|
730
|
-
fingerprint: this.context.fingerprint,
|
|
731
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
732
|
-
details: [`context fingerprint ${this.context.fingerprint.slice(0, 12)} matched`]
|
|
733
|
-
}
|
|
734
|
-
};
|
|
735
|
-
return {
|
|
736
|
-
data: /* @__PURE__ */ new Set(),
|
|
737
|
-
meta: {
|
|
738
|
-
hit: false,
|
|
739
|
-
reason: "context-mismatch",
|
|
740
|
-
fingerprint: this.context.fingerprint,
|
|
741
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
742
|
-
details: mismatchReasons
|
|
743
|
-
}
|
|
744
|
-
};
|
|
745
|
-
}
|
|
746
|
-
const projectMatch = this.findProjectMatch(parsed.data);
|
|
747
|
-
if (projectMatch) {
|
|
748
|
-
const [matchedFingerprint, matchedEntry] = projectMatch;
|
|
749
|
-
return {
|
|
750
|
-
data: /* @__PURE__ */ new Set(),
|
|
751
|
-
meta: {
|
|
752
|
-
hit: false,
|
|
753
|
-
reason: "context-mismatch",
|
|
754
|
-
fingerprint: this.context.fingerprint,
|
|
755
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
756
|
-
details: [`nearest context fingerprint: ${matchedFingerprint.slice(0, 12)}`, ...explainContextMismatch(this.context.metadata, matchedEntry.context)]
|
|
757
|
-
}
|
|
758
|
-
};
|
|
759
|
-
}
|
|
760
|
-
return {
|
|
761
|
-
data: /* @__PURE__ */ new Set(),
|
|
762
|
-
meta: {
|
|
763
|
-
hit: false,
|
|
764
|
-
reason: "context-not-found",
|
|
765
|
-
fingerprint: this.context.fingerprint,
|
|
766
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
767
|
-
details: ["context fingerprint not found in cache index"]
|
|
768
|
-
}
|
|
769
|
-
};
|
|
770
|
-
}
|
|
771
|
-
readWithMetaSync() {
|
|
772
|
-
if (!this.options.enabled) return {
|
|
773
|
-
data: /* @__PURE__ */ new Set(),
|
|
774
|
-
meta: {
|
|
775
|
-
hit: false,
|
|
776
|
-
reason: "cache-disabled",
|
|
777
|
-
details: ["cache disabled"]
|
|
778
|
-
}
|
|
779
|
-
};
|
|
780
|
-
if (this.driver === "noop") return {
|
|
781
|
-
data: /* @__PURE__ */ new Set(),
|
|
782
|
-
meta: {
|
|
783
|
-
hit: false,
|
|
784
|
-
reason: "noop-driver",
|
|
785
|
-
details: ["cache driver is noop"]
|
|
786
|
-
}
|
|
787
|
-
};
|
|
788
|
-
if (this.driver === "memory") {
|
|
789
|
-
if (!this.isContextAware()) {
|
|
790
|
-
const cache = new Set(this.memoryCache ?? []);
|
|
791
|
-
return {
|
|
792
|
-
data: cache,
|
|
793
|
-
meta: {
|
|
794
|
-
hit: cache.size > 0,
|
|
795
|
-
reason: cache.size > 0 ? "hit" : "context-not-found",
|
|
796
|
-
details: cache.size > 0 ? ["memory cache hit"] : ["memory cache miss"]
|
|
797
|
-
}
|
|
798
|
-
};
|
|
799
|
-
}
|
|
800
|
-
const index = this.memoryIndex;
|
|
801
|
-
if (!index || !this.context) return {
|
|
802
|
-
data: /* @__PURE__ */ new Set(),
|
|
803
|
-
meta: {
|
|
804
|
-
hit: false,
|
|
805
|
-
reason: "context-not-found",
|
|
806
|
-
...this.context?.fingerprint === void 0 ? {} : { fingerprint: this.context.fingerprint },
|
|
807
|
-
schemaVersion: 2,
|
|
808
|
-
details: ["no in-memory cache index for current context"]
|
|
809
|
-
}
|
|
810
|
-
};
|
|
811
|
-
const entry = index.contexts[this.context.fingerprint];
|
|
812
|
-
if (entry) return {
|
|
813
|
-
data: new Set(entry.values),
|
|
814
|
-
meta: {
|
|
815
|
-
hit: true,
|
|
816
|
-
reason: "hit",
|
|
817
|
-
fingerprint: this.context.fingerprint,
|
|
818
|
-
schemaVersion: 2,
|
|
819
|
-
details: ["memory cache hit"]
|
|
820
|
-
}
|
|
821
|
-
};
|
|
822
|
-
const projectMatch = this.findProjectMatch(index);
|
|
823
|
-
if (projectMatch && this.context) {
|
|
824
|
-
const [, matchedEntry] = projectMatch;
|
|
825
|
-
return {
|
|
826
|
-
data: /* @__PURE__ */ new Set(),
|
|
827
|
-
meta: {
|
|
828
|
-
hit: false,
|
|
829
|
-
reason: "context-mismatch",
|
|
830
|
-
fingerprint: this.context.fingerprint,
|
|
831
|
-
schemaVersion: 2,
|
|
832
|
-
details: explainContextMismatch(this.context.metadata, matchedEntry.context)
|
|
833
|
-
}
|
|
834
|
-
};
|
|
835
|
-
}
|
|
836
|
-
return {
|
|
837
|
-
data: /* @__PURE__ */ new Set(),
|
|
838
|
-
meta: {
|
|
839
|
-
hit: false,
|
|
840
|
-
reason: "context-not-found",
|
|
841
|
-
fingerprint: this.context.fingerprint,
|
|
842
|
-
schemaVersion: 2,
|
|
843
|
-
details: ["context fingerprint not found in memory cache index"]
|
|
844
|
-
}
|
|
845
|
-
};
|
|
846
|
-
}
|
|
847
|
-
const parsed = this.readParsedCacheFileSync(true);
|
|
848
|
-
if (parsed.kind === "empty") return {
|
|
849
|
-
data: /* @__PURE__ */ new Set(),
|
|
850
|
-
meta: {
|
|
851
|
-
hit: false,
|
|
852
|
-
reason: "file-missing",
|
|
853
|
-
details: ["cache file not found"]
|
|
854
|
-
}
|
|
855
|
-
};
|
|
856
|
-
if (parsed.kind === "invalid") return {
|
|
857
|
-
data: /* @__PURE__ */ new Set(),
|
|
858
|
-
meta: {
|
|
859
|
-
hit: false,
|
|
860
|
-
reason: "invalid-schema",
|
|
861
|
-
details: ["cache schema invalid and has been reset"]
|
|
862
|
-
}
|
|
863
|
-
};
|
|
864
|
-
if (!this.isContextAware()) {
|
|
865
|
-
if (parsed.kind === "legacy") return {
|
|
866
|
-
data: new Set(parsed.data),
|
|
867
|
-
meta: {
|
|
868
|
-
hit: parsed.data.length > 0,
|
|
869
|
-
reason: parsed.data.length > 0 ? "hit" : "context-not-found",
|
|
870
|
-
details: ["legacy cache format"]
|
|
871
|
-
}
|
|
872
|
-
};
|
|
873
|
-
const union = Object.values(parsed.data.contexts).flatMap((entry) => entry.values);
|
|
874
|
-
return {
|
|
875
|
-
data: new Set(union),
|
|
876
|
-
meta: {
|
|
877
|
-
hit: union.length > 0,
|
|
878
|
-
reason: union.length > 0 ? "hit" : "context-not-found",
|
|
879
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
880
|
-
details: ["context-less read merged all cache entries"]
|
|
881
|
-
}
|
|
882
|
-
};
|
|
883
|
-
}
|
|
884
|
-
if (parsed.kind === "legacy") return {
|
|
885
|
-
data: /* @__PURE__ */ new Set(),
|
|
886
|
-
meta: {
|
|
887
|
-
hit: false,
|
|
888
|
-
reason: "legacy-schema",
|
|
889
|
-
...this.context?.fingerprint === void 0 ? {} : { fingerprint: this.context.fingerprint },
|
|
890
|
-
details: ["legacy cache schema detected; rebuilding cache with context fingerprint"]
|
|
891
|
-
}
|
|
892
|
-
};
|
|
893
|
-
if (!this.context) return {
|
|
894
|
-
data: /* @__PURE__ */ new Set(),
|
|
895
|
-
meta: {
|
|
896
|
-
hit: false,
|
|
897
|
-
reason: "context-not-found",
|
|
898
|
-
details: ["cache context missing"]
|
|
899
|
-
}
|
|
900
|
-
};
|
|
901
|
-
const entry = parsed.data.contexts[this.context.fingerprint];
|
|
902
|
-
if (entry) {
|
|
903
|
-
const mismatchReasons = explainContextMismatch(this.context.metadata, entry.context);
|
|
904
|
-
if (mismatchReasons.length === 0) return {
|
|
905
|
-
data: new Set(entry.values),
|
|
906
|
-
meta: {
|
|
907
|
-
hit: true,
|
|
908
|
-
reason: "hit",
|
|
909
|
-
fingerprint: this.context.fingerprint,
|
|
910
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
911
|
-
details: [`context fingerprint ${this.context.fingerprint.slice(0, 12)} matched`]
|
|
912
|
-
}
|
|
913
|
-
};
|
|
914
|
-
return {
|
|
915
|
-
data: /* @__PURE__ */ new Set(),
|
|
916
|
-
meta: {
|
|
917
|
-
hit: false,
|
|
918
|
-
reason: "context-mismatch",
|
|
919
|
-
fingerprint: this.context.fingerprint,
|
|
920
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
921
|
-
details: mismatchReasons
|
|
922
|
-
}
|
|
923
|
-
};
|
|
924
|
-
}
|
|
925
|
-
const projectMatch = this.findProjectMatch(parsed.data);
|
|
926
|
-
if (projectMatch) {
|
|
927
|
-
const [matchedFingerprint, matchedEntry] = projectMatch;
|
|
928
|
-
return {
|
|
929
|
-
data: /* @__PURE__ */ new Set(),
|
|
930
|
-
meta: {
|
|
931
|
-
hit: false,
|
|
932
|
-
reason: "context-mismatch",
|
|
933
|
-
fingerprint: this.context.fingerprint,
|
|
934
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
935
|
-
details: [`nearest context fingerprint: ${matchedFingerprint.slice(0, 12)}`, ...explainContextMismatch(this.context.metadata, matchedEntry.context)]
|
|
936
|
-
}
|
|
937
|
-
};
|
|
938
|
-
}
|
|
939
|
-
return {
|
|
940
|
-
data: /* @__PURE__ */ new Set(),
|
|
941
|
-
meta: {
|
|
942
|
-
hit: false,
|
|
943
|
-
reason: "context-not-found",
|
|
944
|
-
fingerprint: this.context.fingerprint,
|
|
945
|
-
schemaVersion: parsed.data.schemaVersion,
|
|
946
|
-
details: ["context fingerprint not found in cache index"]
|
|
947
|
-
}
|
|
948
|
-
};
|
|
949
|
-
}
|
|
950
|
-
async read() {
|
|
951
|
-
const result = await this.readWithMeta();
|
|
952
|
-
this.lastReadMeta = toReadMeta(result.meta);
|
|
953
|
-
return new Set(result.data);
|
|
954
|
-
}
|
|
955
|
-
readSync() {
|
|
956
|
-
const result = this.readWithMetaSync();
|
|
957
|
-
this.lastReadMeta = toReadMeta(result.meta);
|
|
958
|
-
return new Set(result.data);
|
|
959
|
-
}
|
|
960
|
-
getLastReadMeta() {
|
|
961
|
-
return toReadMeta(this.lastReadMeta);
|
|
962
|
-
}
|
|
963
|
-
countEntriesFromParsed(parsed) {
|
|
964
|
-
if (parsed.kind === "legacy") return {
|
|
965
|
-
contexts: parsed.data.length ? 1 : 0,
|
|
966
|
-
entries: parsed.data.length
|
|
967
|
-
};
|
|
968
|
-
if (parsed.kind === "v2") {
|
|
969
|
-
const values = Object.values(parsed.data.contexts);
|
|
970
|
-
return {
|
|
971
|
-
contexts: values.length,
|
|
972
|
-
entries: values.reduce((acc, item) => acc + item.values.length, 0)
|
|
973
|
-
};
|
|
974
|
-
}
|
|
975
|
-
return {
|
|
976
|
-
contexts: 0,
|
|
977
|
-
entries: 0
|
|
978
|
-
};
|
|
979
|
-
}
|
|
980
|
-
async clear(options) {
|
|
981
|
-
const scope = options?.scope ?? "current";
|
|
982
|
-
if (!this.options.enabled || this.driver === "noop") return {
|
|
983
|
-
scope,
|
|
984
|
-
filesRemoved: 0,
|
|
985
|
-
entriesRemoved: 0,
|
|
986
|
-
contextsRemoved: 0
|
|
987
|
-
};
|
|
988
|
-
if (this.driver === "memory") {
|
|
989
|
-
if (!this.isContextAware() || scope === "all") {
|
|
990
|
-
const entriesRemoved = this.memoryCache?.size ?? (this.memoryIndex ? this.countEntriesFromParsed({
|
|
991
|
-
kind: "v2",
|
|
992
|
-
data: this.memoryIndex
|
|
993
|
-
}).entries : 0);
|
|
994
|
-
const contextsRemoved = this.memoryIndex ? Object.keys(this.memoryIndex.contexts).length : this.memoryCache?.size ? 1 : 0;
|
|
995
|
-
this.memoryCache = null;
|
|
996
|
-
this.memoryIndex = null;
|
|
997
|
-
return {
|
|
998
|
-
scope,
|
|
999
|
-
filesRemoved: 0,
|
|
1000
|
-
entriesRemoved,
|
|
1001
|
-
contextsRemoved
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
if (!this.context || !this.memoryIndex) return {
|
|
1005
|
-
scope,
|
|
1006
|
-
filesRemoved: 0,
|
|
1007
|
-
entriesRemoved: 0,
|
|
1008
|
-
contextsRemoved: 0
|
|
1009
|
-
};
|
|
1010
|
-
const entry = this.memoryIndex.contexts[this.context.fingerprint];
|
|
1011
|
-
if (!entry) return {
|
|
1012
|
-
scope,
|
|
1013
|
-
filesRemoved: 0,
|
|
1014
|
-
entriesRemoved: 0,
|
|
1015
|
-
contextsRemoved: 0
|
|
1016
|
-
};
|
|
1017
|
-
const entriesRemoved = entry.values.length;
|
|
1018
|
-
delete this.memoryIndex.contexts[this.context.fingerprint];
|
|
1019
|
-
return {
|
|
1020
|
-
scope,
|
|
1021
|
-
filesRemoved: 0,
|
|
1022
|
-
entriesRemoved,
|
|
1023
|
-
contextsRemoved: 1
|
|
1024
|
-
};
|
|
1025
|
-
}
|
|
1026
|
-
return await this.withFileLock(async () => {
|
|
1027
|
-
const parsed = await this.readParsedCacheFile(false);
|
|
1028
|
-
if (parsed.kind === "empty") return {
|
|
1029
|
-
scope,
|
|
1030
|
-
filesRemoved: 0,
|
|
1031
|
-
entriesRemoved: 0,
|
|
1032
|
-
contextsRemoved: 0
|
|
1033
|
-
};
|
|
1034
|
-
if (!this.isContextAware() || scope === "all") {
|
|
1035
|
-
const counts = this.countEntriesFromParsed(parsed);
|
|
1036
|
-
await fs_extra.default.remove(this.options.path);
|
|
1037
|
-
return {
|
|
1038
|
-
scope,
|
|
1039
|
-
filesRemoved: 1,
|
|
1040
|
-
entriesRemoved: counts.entries,
|
|
1041
|
-
contextsRemoved: counts.contexts
|
|
1042
|
-
};
|
|
1043
|
-
}
|
|
1044
|
-
if (parsed.kind !== "v2" || !this.context) {
|
|
1045
|
-
const counts = this.countEntriesFromParsed(parsed);
|
|
1046
|
-
await fs_extra.default.remove(this.options.path);
|
|
1047
|
-
return {
|
|
1048
|
-
scope,
|
|
1049
|
-
filesRemoved: 1,
|
|
1050
|
-
entriesRemoved: counts.entries,
|
|
1051
|
-
contextsRemoved: counts.contexts
|
|
1052
|
-
};
|
|
1053
|
-
}
|
|
1054
|
-
const entry = parsed.data.contexts[this.context.fingerprint];
|
|
1055
|
-
if (!entry) return {
|
|
1056
|
-
scope,
|
|
1057
|
-
filesRemoved: 0,
|
|
1058
|
-
entriesRemoved: 0,
|
|
1059
|
-
contextsRemoved: 0
|
|
1060
|
-
};
|
|
1061
|
-
const entriesRemoved = entry.values.length;
|
|
1062
|
-
delete parsed.data.contexts[this.context.fingerprint];
|
|
1063
|
-
if (Object.keys(parsed.data.contexts).length === 0) {
|
|
1064
|
-
await fs_extra.default.remove(this.options.path);
|
|
1065
|
-
return {
|
|
1066
|
-
scope,
|
|
1067
|
-
filesRemoved: 1,
|
|
1068
|
-
entriesRemoved,
|
|
1069
|
-
contextsRemoved: 1
|
|
1070
|
-
};
|
|
1071
|
-
}
|
|
1072
|
-
parsed.data.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1073
|
-
await this.writeIndexFile(parsed.data);
|
|
1074
|
-
return {
|
|
1075
|
-
scope,
|
|
1076
|
-
filesRemoved: 0,
|
|
1077
|
-
entriesRemoved,
|
|
1078
|
-
contextsRemoved: 1
|
|
1079
|
-
};
|
|
1080
|
-
}) ?? {
|
|
1081
|
-
scope,
|
|
1082
|
-
filesRemoved: 0,
|
|
1083
|
-
entriesRemoved: 0,
|
|
1084
|
-
contextsRemoved: 0
|
|
1085
|
-
};
|
|
1086
|
-
}
|
|
1087
|
-
clearSync(options) {
|
|
1088
|
-
const scope = options?.scope ?? "current";
|
|
1089
|
-
if (!this.options.enabled || this.driver === "noop") return {
|
|
1090
|
-
scope,
|
|
1091
|
-
filesRemoved: 0,
|
|
1092
|
-
entriesRemoved: 0,
|
|
1093
|
-
contextsRemoved: 0
|
|
1094
|
-
};
|
|
1095
|
-
if (this.driver === "memory") {
|
|
1096
|
-
if (!this.isContextAware() || scope === "all") {
|
|
1097
|
-
const entriesRemoved = this.memoryCache?.size ?? (this.memoryIndex ? this.countEntriesFromParsed({
|
|
1098
|
-
kind: "v2",
|
|
1099
|
-
data: this.memoryIndex
|
|
1100
|
-
}).entries : 0);
|
|
1101
|
-
const contextsRemoved = this.memoryIndex ? Object.keys(this.memoryIndex.contexts).length : this.memoryCache?.size ? 1 : 0;
|
|
1102
|
-
this.memoryCache = null;
|
|
1103
|
-
this.memoryIndex = null;
|
|
1104
|
-
return {
|
|
1105
|
-
scope,
|
|
1106
|
-
filesRemoved: 0,
|
|
1107
|
-
entriesRemoved,
|
|
1108
|
-
contextsRemoved
|
|
1109
|
-
};
|
|
1110
|
-
}
|
|
1111
|
-
if (!this.context || !this.memoryIndex) return {
|
|
1112
|
-
scope,
|
|
1113
|
-
filesRemoved: 0,
|
|
1114
|
-
entriesRemoved: 0,
|
|
1115
|
-
contextsRemoved: 0
|
|
1116
|
-
};
|
|
1117
|
-
const entry = this.memoryIndex.contexts[this.context.fingerprint];
|
|
1118
|
-
if (!entry) return {
|
|
1119
|
-
scope,
|
|
1120
|
-
filesRemoved: 0,
|
|
1121
|
-
entriesRemoved: 0,
|
|
1122
|
-
contextsRemoved: 0
|
|
1123
|
-
};
|
|
1124
|
-
const entriesRemoved = entry.values.length;
|
|
1125
|
-
delete this.memoryIndex.contexts[this.context.fingerprint];
|
|
1126
|
-
return {
|
|
1127
|
-
scope,
|
|
1128
|
-
filesRemoved: 0,
|
|
1129
|
-
entriesRemoved,
|
|
1130
|
-
contextsRemoved: 1
|
|
1131
|
-
};
|
|
1132
|
-
}
|
|
1133
|
-
return this.withFileLockSync(() => {
|
|
1134
|
-
const parsed = this.readParsedCacheFileSync(false);
|
|
1135
|
-
if (parsed.kind === "empty") return {
|
|
1136
|
-
scope,
|
|
1137
|
-
filesRemoved: 0,
|
|
1138
|
-
entriesRemoved: 0,
|
|
1139
|
-
contextsRemoved: 0
|
|
1140
|
-
};
|
|
1141
|
-
if (!this.isContextAware() || scope === "all") {
|
|
1142
|
-
const counts = this.countEntriesFromParsed(parsed);
|
|
1143
|
-
fs_extra.default.removeSync(this.options.path);
|
|
1144
|
-
return {
|
|
1145
|
-
scope,
|
|
1146
|
-
filesRemoved: 1,
|
|
1147
|
-
entriesRemoved: counts.entries,
|
|
1148
|
-
contextsRemoved: counts.contexts
|
|
1149
|
-
};
|
|
1150
|
-
}
|
|
1151
|
-
if (parsed.kind !== "v2" || !this.context) {
|
|
1152
|
-
const counts = this.countEntriesFromParsed(parsed);
|
|
1153
|
-
fs_extra.default.removeSync(this.options.path);
|
|
1154
|
-
return {
|
|
1155
|
-
scope,
|
|
1156
|
-
filesRemoved: 1,
|
|
1157
|
-
entriesRemoved: counts.entries,
|
|
1158
|
-
contextsRemoved: counts.contexts
|
|
1159
|
-
};
|
|
1160
|
-
}
|
|
1161
|
-
const entry = parsed.data.contexts[this.context.fingerprint];
|
|
1162
|
-
if (!entry) return {
|
|
1163
|
-
scope,
|
|
1164
|
-
filesRemoved: 0,
|
|
1165
|
-
entriesRemoved: 0,
|
|
1166
|
-
contextsRemoved: 0
|
|
1167
|
-
};
|
|
1168
|
-
const entriesRemoved = entry.values.length;
|
|
1169
|
-
delete parsed.data.contexts[this.context.fingerprint];
|
|
1170
|
-
if (Object.keys(parsed.data.contexts).length === 0) {
|
|
1171
|
-
fs_extra.default.removeSync(this.options.path);
|
|
1172
|
-
return {
|
|
1173
|
-
scope,
|
|
1174
|
-
filesRemoved: 1,
|
|
1175
|
-
entriesRemoved,
|
|
1176
|
-
contextsRemoved: 1
|
|
1177
|
-
};
|
|
1178
|
-
}
|
|
1179
|
-
parsed.data.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1180
|
-
this.writeIndexFileSync(parsed.data);
|
|
1181
|
-
return {
|
|
1182
|
-
scope,
|
|
1183
|
-
filesRemoved: 0,
|
|
1184
|
-
entriesRemoved,
|
|
1185
|
-
contextsRemoved: 1
|
|
1186
|
-
};
|
|
1187
|
-
}) ?? {
|
|
1188
|
-
scope,
|
|
1189
|
-
filesRemoved: 0,
|
|
1190
|
-
entriesRemoved: 0,
|
|
1191
|
-
contextsRemoved: 0
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
|
-
readIndexSnapshot() {
|
|
1195
|
-
if (this.driver === "memory") return this.memoryIndex ? {
|
|
1196
|
-
...this.memoryIndex,
|
|
1197
|
-
contexts: Object.fromEntries(Object.entries(this.memoryIndex.contexts).map(([key, value]) => [key, cloneEntry(value)]))
|
|
1198
|
-
} : void 0;
|
|
1199
|
-
const parsed = this.readParsedCacheFileSync(false);
|
|
1200
|
-
if (parsed.kind !== "v2") return;
|
|
1201
|
-
return {
|
|
1202
|
-
...parsed.data,
|
|
1203
|
-
contexts: Object.fromEntries(Object.entries(parsed.data.contexts).map(([key, value]) => [key, cloneEntry(value)]))
|
|
1204
|
-
};
|
|
1205
|
-
}
|
|
1206
|
-
};
|
|
1207
|
-
//#endregion
|
|
1208
|
-
//#region src/options/legacy.ts
|
|
1209
|
-
const deprecatedRegistryMapping = {
|
|
1210
|
-
output: "extract",
|
|
1211
|
-
tailwind: "tailwindcss"
|
|
1212
|
-
};
|
|
1213
|
-
const deprecatedTailwindMapping = {
|
|
1214
|
-
package: "packageName",
|
|
1215
|
-
legacy: "v2",
|
|
1216
|
-
classic: "v3",
|
|
1217
|
-
next: "v4"
|
|
1218
|
-
};
|
|
1219
|
-
function assertNoDeprecatedRegistryOptions(registry) {
|
|
1220
|
-
const usedRegistryKeys = Object.keys(deprecatedRegistryMapping).filter((key) => Object.hasOwn(registry, key));
|
|
1221
|
-
if (usedRegistryKeys.length > 0) {
|
|
1222
|
-
const mapping = usedRegistryKeys.map((key) => `${key} -> ${deprecatedRegistryMapping[key]}`).join(", ");
|
|
1223
|
-
throw new Error(`Legacy registry fields are no longer supported: ${usedRegistryKeys.join(", ")}. Use the modern fields instead: ${mapping}.`);
|
|
1224
|
-
}
|
|
1225
|
-
const tailwind = registry.tailwindcss;
|
|
1226
|
-
if (!tailwind) return;
|
|
1227
|
-
const usedTailwindKeys = Object.keys(deprecatedTailwindMapping).filter((key) => Object.hasOwn(tailwind, key));
|
|
1228
|
-
if (usedTailwindKeys.length > 0) {
|
|
1229
|
-
const mapping = usedTailwindKeys.map((key) => `${key} -> tailwindcss.${deprecatedTailwindMapping[key]}`).join(", ");
|
|
1230
|
-
throw new Error(`Legacy "registry.tailwindcss" fields are no longer supported: ${usedTailwindKeys.join(", ")}. Use the modern fields instead: ${mapping}.`);
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
function fromUnifiedConfig(registry) {
|
|
1234
|
-
if (!registry) return {};
|
|
1235
|
-
assertNoDeprecatedRegistryOptions(registry);
|
|
1236
|
-
const extract = registry.extract ? {
|
|
1237
|
-
...registry.extract.write === void 0 ? {} : { write: registry.extract.write },
|
|
1238
|
-
...registry.extract.file === void 0 ? {} : { file: registry.extract.file },
|
|
1239
|
-
...registry.extract.format === void 0 ? {} : { format: registry.extract.format },
|
|
1240
|
-
...registry.extract.pretty === void 0 ? {} : { pretty: registry.extract.pretty },
|
|
1241
|
-
...registry.extract.removeUniversalSelector === void 0 ? {} : { removeUniversalSelector: registry.extract.removeUniversalSelector }
|
|
1242
|
-
} : void 0;
|
|
1243
|
-
const tailwindcss = registry.tailwindcss ? {
|
|
1244
|
-
...registry.tailwindcss.version === void 0 ? {} : { version: registry.tailwindcss.version },
|
|
1245
|
-
...registry.tailwindcss.packageName === void 0 ? {} : { packageName: registry.tailwindcss.packageName },
|
|
1246
|
-
...registry.tailwindcss.resolve === void 0 ? {} : { resolve: registry.tailwindcss.resolve },
|
|
1247
|
-
...registry.tailwindcss.config === void 0 ? {} : { config: registry.tailwindcss.config },
|
|
1248
|
-
...registry.tailwindcss.cwd === void 0 ? {} : { cwd: registry.tailwindcss.cwd },
|
|
1249
|
-
...registry.tailwindcss.v2 === void 0 ? {} : { v2: registry.tailwindcss.v2 },
|
|
1250
|
-
...registry.tailwindcss.v3 === void 0 ? {} : { v3: registry.tailwindcss.v3 },
|
|
1251
|
-
...registry.tailwindcss.v4 === void 0 ? {} : { v4: registry.tailwindcss.v4 }
|
|
1252
|
-
} : void 0;
|
|
1253
|
-
const apply = registry.apply ? {
|
|
1254
|
-
...registry.apply.overwrite === void 0 ? {} : { overwrite: registry.apply.overwrite },
|
|
1255
|
-
...registry.apply.exposeContext === void 0 ? {} : { exposeContext: registry.apply.exposeContext },
|
|
1256
|
-
...registry.apply.extendLengthUnits === void 0 ? {} : { extendLengthUnits: registry.apply.extendLengthUnits }
|
|
1257
|
-
} : void 0;
|
|
1258
|
-
return {
|
|
1259
|
-
...registry.projectRoot === void 0 ? {} : { projectRoot: registry.projectRoot },
|
|
1260
|
-
...apply === void 0 ? {} : { apply },
|
|
1261
|
-
...registry.cache === void 0 ? {} : { cache: registry.cache },
|
|
1262
|
-
...registry.filter === void 0 ? {} : { filter: registry.filter },
|
|
1263
|
-
...extract === void 0 ? {} : { extract },
|
|
1264
|
-
...tailwindcss === void 0 ? {} : { tailwindcss }
|
|
1265
|
-
};
|
|
1266
|
-
}
|
|
1267
|
-
//#endregion
|
|
1268
|
-
//#region src/options/normalize.ts
|
|
1269
|
-
function resolveRealpathSafe(value) {
|
|
1270
|
-
const resolved = pathe.default.resolve(value);
|
|
1271
|
-
try {
|
|
1272
|
-
return pathe.default.normalize(fs_extra.default.realpathSync(resolved));
|
|
1273
|
-
} catch {
|
|
1274
|
-
return pathe.default.normalize(resolved);
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
function toPrettyValue(value) {
|
|
1278
|
-
if (typeof value === "number") return value > 0 ? value : false;
|
|
1279
|
-
if (value === true) return 2;
|
|
1280
|
-
return false;
|
|
1281
|
-
}
|
|
1282
|
-
function normalizeCacheDriver(driver) {
|
|
1283
|
-
if (driver === "memory" || driver === "noop") return driver;
|
|
1284
|
-
return "file";
|
|
1285
|
-
}
|
|
1286
|
-
function normalizeCacheOptions(cache, projectRoot) {
|
|
1287
|
-
let enabled = false;
|
|
1288
|
-
let cwd = resolveRealpathSafe(projectRoot);
|
|
1289
|
-
let dir = pathe.default.resolve(cwd, "node_modules/.cache", pkgName);
|
|
1290
|
-
let file = "class-cache.json";
|
|
1291
|
-
let strategy = "merge";
|
|
1292
|
-
let driver = "file";
|
|
1293
|
-
if (typeof cache === "boolean") enabled = cache;
|
|
1294
|
-
else if (typeof cache === "object" && cache) {
|
|
1295
|
-
enabled = cache.enabled ?? true;
|
|
1296
|
-
cwd = cache.cwd ? resolveRealpathSafe(cache.cwd) : cwd;
|
|
1297
|
-
dir = cache.dir ? pathe.default.resolve(cache.dir) : pathe.default.resolve(cwd, "node_modules/.cache", pkgName);
|
|
1298
|
-
file = cache.file ?? file;
|
|
1299
|
-
strategy = cache.strategy ?? strategy;
|
|
1300
|
-
driver = normalizeCacheDriver(cache.driver);
|
|
1301
|
-
}
|
|
1302
|
-
const filename = pathe.default.resolve(dir, file);
|
|
1303
|
-
return {
|
|
1304
|
-
enabled,
|
|
1305
|
-
cwd,
|
|
1306
|
-
dir,
|
|
1307
|
-
file,
|
|
1308
|
-
path: filename,
|
|
1309
|
-
strategy,
|
|
1310
|
-
driver
|
|
1311
|
-
};
|
|
1312
|
-
}
|
|
1313
|
-
function normalizeOutputOptions(output) {
|
|
1314
|
-
return {
|
|
1315
|
-
enabled: output?.write ?? true,
|
|
1316
|
-
file: output?.file ?? ".tw-patch/tw-class-list.json",
|
|
1317
|
-
format: output?.format ?? "json",
|
|
1318
|
-
pretty: toPrettyValue(output?.pretty ?? true),
|
|
1319
|
-
removeUniversalSelector: output?.removeUniversalSelector ?? true
|
|
1320
|
-
};
|
|
1321
|
-
}
|
|
1322
|
-
function normalizeExposeContextOptions(exposeContext) {
|
|
1323
|
-
if (exposeContext === false) return {
|
|
1324
|
-
enabled: false,
|
|
1325
|
-
refProperty: "contextRef"
|
|
1326
|
-
};
|
|
1327
|
-
if (typeof exposeContext === "object" && exposeContext) return {
|
|
1328
|
-
enabled: true,
|
|
1329
|
-
refProperty: exposeContext.refProperty ?? "contextRef"
|
|
1330
|
-
};
|
|
1331
|
-
return {
|
|
1332
|
-
enabled: true,
|
|
1333
|
-
refProperty: "contextRef"
|
|
1334
|
-
};
|
|
1335
|
-
}
|
|
1336
|
-
function normalizeExtendLengthUnitsOptions(extend) {
|
|
1337
|
-
if (extend === false || extend === void 0) return null;
|
|
1338
|
-
if (extend.enabled === false) return null;
|
|
1339
|
-
const base = {
|
|
1340
|
-
units: ["rpx"],
|
|
1341
|
-
overwrite: true
|
|
1342
|
-
};
|
|
1343
|
-
return {
|
|
1344
|
-
...base,
|
|
1345
|
-
...extend,
|
|
1346
|
-
enabled: extend.enabled ?? true,
|
|
1347
|
-
units: extend.units ?? base.units,
|
|
1348
|
-
overwrite: extend.overwrite ?? base.overwrite
|
|
1349
|
-
};
|
|
1350
|
-
}
|
|
1351
|
-
function normalizeTailwindV4Options(v4, fallbackBase) {
|
|
1352
|
-
const configuredBase = v4?.base ? pathe.default.resolve(v4.base) : void 0;
|
|
1353
|
-
const base = configuredBase ?? fallbackBase;
|
|
1354
|
-
const resolveV4Path = (value) => pathe.default.isAbsolute(value) ? pathe.default.resolve(value) : pathe.default.resolve(fallbackBase, value);
|
|
1355
|
-
const cssSources = Array.isArray(v4?.cssSources) ? v4.cssSources.filter((source) => typeof source?.css === "string").map((source) => ({
|
|
1356
|
-
css: source.css,
|
|
1357
|
-
...source.base === void 0 ? {} : { base: resolveV4Path(source.base) },
|
|
1358
|
-
...source.file === void 0 ? {} : { file: resolveV4Path(source.file) },
|
|
1359
|
-
...source.dependencies === void 0 ? {} : { dependencies: source.dependencies.filter(Boolean).map(resolveV4Path) }
|
|
1360
|
-
})) : [];
|
|
1361
|
-
const cssEntries = Array.isArray(v4?.cssEntries) ? v4.cssEntries.filter((entry) => Boolean(entry)).map((entry) => pathe.default.resolve(entry)) : [];
|
|
1362
|
-
const userSources = v4?.sources;
|
|
1363
|
-
const hasUserDefinedSources = Boolean(userSources?.length);
|
|
1364
|
-
const sources = hasUserDefinedSources ? userSources : [{
|
|
1365
|
-
base: fallbackBase,
|
|
1366
|
-
pattern: "**/*",
|
|
1367
|
-
negated: false
|
|
1368
|
-
}];
|
|
1369
|
-
return {
|
|
1370
|
-
base,
|
|
1371
|
-
...configuredBase === void 0 ? {} : { configuredBase },
|
|
1372
|
-
...v4?.css === void 0 ? {} : { css: v4.css },
|
|
1373
|
-
cssSources,
|
|
1374
|
-
cssEntries,
|
|
1375
|
-
sources,
|
|
1376
|
-
hasUserDefinedSources,
|
|
1377
|
-
bareArbitraryValues: v4?.bareArbitraryValues === true ? {} : typeof v4?.bareArbitraryValues === "object" && v4.bareArbitraryValues !== null ? { ...v4.bareArbitraryValues } : false
|
|
1378
|
-
};
|
|
1379
|
-
}
|
|
1380
|
-
function normalizeTailwindOptions(tailwind, projectRoot, shouldDefaultResolveFromCwd) {
|
|
1381
|
-
const packageName = tailwind?.packageName ?? "tailwindcss";
|
|
1382
|
-
const versionHint = tailwind?.version;
|
|
1383
|
-
const cwd = tailwind?.cwd ?? projectRoot;
|
|
1384
|
-
const resolve = tailwind?.resolve ?? (shouldDefaultResolveFromCwd ? { paths: [cwd] } : void 0);
|
|
1385
|
-
const config = tailwind?.config;
|
|
1386
|
-
const postcssPlugin = tailwind?.postcssPlugin;
|
|
1387
|
-
const v4 = normalizeTailwindV4Options(tailwind?.v4, cwd);
|
|
1388
|
-
return {
|
|
1389
|
-
packageName,
|
|
1390
|
-
cwd,
|
|
1391
|
-
...versionHint === void 0 ? {} : { versionHint },
|
|
1392
|
-
...resolve === void 0 ? {} : { resolve },
|
|
1393
|
-
...config === void 0 ? {} : { config },
|
|
1394
|
-
...postcssPlugin === void 0 ? {} : { postcssPlugin },
|
|
1395
|
-
...tailwind?.v2 === void 0 ? {} : { v2: tailwind.v2 },
|
|
1396
|
-
...tailwind?.v3 === void 0 ? {} : { v3: tailwind.v3 },
|
|
1397
|
-
v4
|
|
1398
|
-
};
|
|
1399
|
-
}
|
|
1400
|
-
const deprecatedOptionMapping = {
|
|
1401
|
-
cwd: "projectRoot",
|
|
1402
|
-
overwrite: "apply.overwrite",
|
|
1403
|
-
tailwind: "tailwindcss",
|
|
1404
|
-
features: "apply",
|
|
1405
|
-
output: "extract"
|
|
1406
|
-
};
|
|
1407
|
-
function assertNoDeprecatedOptions(options) {
|
|
1408
|
-
const used = Object.keys(deprecatedOptionMapping).filter((key) => Object.hasOwn(options, key));
|
|
1409
|
-
if (used.length === 0) return;
|
|
1410
|
-
const mapping = used.map((key) => `${key} -> ${deprecatedOptionMapping[key]}`).join(", ");
|
|
1411
|
-
throw new Error(`Legacy TailwindcssPatcher options are no longer supported: ${used.join(", ")}. Use the modern fields instead: ${mapping}.`);
|
|
1412
|
-
}
|
|
1413
|
-
function normalizeOptions(options = {}) {
|
|
1414
|
-
assertNoDeprecatedOptions(options);
|
|
1415
|
-
const projectRoot = resolveRealpathSafe(options.projectRoot ? pathe.default.resolve(options.projectRoot) : node_process.default.cwd());
|
|
1416
|
-
const overwrite = options.apply?.overwrite ?? true;
|
|
1417
|
-
const output = normalizeOutputOptions(options.extract);
|
|
1418
|
-
const cache = normalizeCacheOptions(options.cache, projectRoot);
|
|
1419
|
-
const tailwind = normalizeTailwindOptions(options.tailwindcss, projectRoot, options.projectRoot !== void 0 || options.tailwindcss?.cwd !== void 0);
|
|
1420
|
-
const exposeContext = normalizeExposeContextOptions(options.apply?.exposeContext);
|
|
1421
|
-
const extendLengthUnits = normalizeExtendLengthUnitsOptions(options.apply?.extendLengthUnits);
|
|
1422
|
-
const filter = (className) => {
|
|
1423
|
-
if (output.removeUniversalSelector && className === "*") return false;
|
|
1424
|
-
if (typeof options.filter === "function") return options.filter(className) !== false;
|
|
1425
|
-
return true;
|
|
1426
|
-
};
|
|
1427
|
-
return {
|
|
1428
|
-
projectRoot,
|
|
1429
|
-
overwrite,
|
|
1430
|
-
tailwind,
|
|
1431
|
-
features: {
|
|
1432
|
-
exposeContext,
|
|
1433
|
-
extendLengthUnits
|
|
1434
|
-
},
|
|
1435
|
-
output,
|
|
1436
|
-
cache,
|
|
1437
|
-
filter
|
|
1438
|
-
};
|
|
1439
|
-
}
|
|
1440
|
-
//#endregion
|
|
1441
|
-
//#region src/config/workspace.ts
|
|
1442
|
-
let configModulePromise;
|
|
1443
|
-
let defuPromise;
|
|
1444
|
-
function isNodeError$1(error) {
|
|
1445
|
-
return !!error && typeof error === "object" && ("code" in error || "message" in error);
|
|
1446
|
-
}
|
|
1447
|
-
function isMissingModuleError(error, pkgName) {
|
|
1448
|
-
if (!isNodeError$1(error)) return false;
|
|
1449
|
-
const code = error.code;
|
|
1450
|
-
if (code !== "MODULE_NOT_FOUND" && code !== "ERR_MODULE_NOT_FOUND") return false;
|
|
1451
|
-
const message = error.message ?? "";
|
|
1452
|
-
return message.includes(pkgName) || message.includes(`${pkgName}/dist/`);
|
|
1453
|
-
}
|
|
1454
|
-
function isMissingConfigModuleError(error) {
|
|
1455
|
-
return isMissingModuleError(error, "@tailwindcss-mangle/config");
|
|
1456
|
-
}
|
|
1457
|
-
function isMissingSharedModuleError(error) {
|
|
1458
|
-
return isMissingModuleError(error, "@tailwindcss-mangle/shared");
|
|
1459
|
-
}
|
|
1460
|
-
async function loadWorkspaceConfigModule() {
|
|
1461
|
-
if (!configModulePromise) configModulePromise = import("@tailwindcss-mangle/config").catch(async (error) => {
|
|
1462
|
-
if (!isMissingConfigModuleError(error)) throw error;
|
|
1463
|
-
return import((0, node_url.pathToFileURL)(pathe.default.resolve(__dirname, "../../../config/src/index.ts")).href);
|
|
1464
|
-
});
|
|
1465
|
-
return configModulePromise;
|
|
1466
|
-
}
|
|
1467
|
-
async function loadWorkspaceDefu() {
|
|
1468
|
-
if (!defuPromise) defuPromise = Promise.resolve().then(() => require("./dist-wp0o36Ns.js")).then((mod) => mod.defu).catch(async (error) => {
|
|
1469
|
-
if (!isMissingSharedModuleError(error)) throw error;
|
|
1470
|
-
return (await import((0, node_url.pathToFileURL)(pathe.default.resolve(__dirname, "../../../shared/src/utils.ts")).href)).defu;
|
|
1471
|
-
});
|
|
1472
|
-
return defuPromise;
|
|
1473
|
-
}
|
|
1474
|
-
async function loadPatchOptionsForWorkspace(cwd, overrides) {
|
|
1475
|
-
const merge = await loadWorkspaceDefu();
|
|
1476
|
-
const { config } = await (await loadWorkspaceConfigModule()).getConfig(cwd);
|
|
1477
|
-
if (config && typeof config === "object" && "patch" in config && config.patch !== void 0) throw new Error("Legacy workspace config field \"patch\" is no longer supported. Move patcher options under \"registry\".");
|
|
1478
|
-
const base = config?.registry ? fromUnifiedConfig(config.registry) : {};
|
|
1479
|
-
return merge(overrides ?? {}, base, { projectRoot: cwd });
|
|
1480
|
-
}
|
|
1481
|
-
//#endregion
|
|
1482
|
-
//#region src/utils.ts
|
|
1483
|
-
function isObject(val) {
|
|
1484
|
-
return val !== null && typeof val === "object" && Array.isArray(val) === false;
|
|
1485
|
-
}
|
|
1486
|
-
/**
|
|
1487
|
-
* Apply the changes to the string such that a change in the length
|
|
1488
|
-
* of the string does not break the indexes of the subsequent changes.
|
|
1489
|
-
*/
|
|
1490
|
-
function spliceChangesIntoString(str, changes) {
|
|
1491
|
-
const firstChange = changes[0];
|
|
1492
|
-
if (!firstChange) return str;
|
|
1493
|
-
changes.sort((a, b) => {
|
|
1494
|
-
return a.end - b.end || a.start - b.start;
|
|
1495
|
-
});
|
|
1496
|
-
let result = "";
|
|
1497
|
-
let previous = firstChange;
|
|
1498
|
-
result += str.slice(0, previous.start);
|
|
1499
|
-
result += previous.replacement;
|
|
1500
|
-
for (let i = 1; i < changes.length; ++i) {
|
|
1501
|
-
const change = changes[i];
|
|
1502
|
-
if (!change) continue;
|
|
1503
|
-
result += str.slice(previous.end, change.start);
|
|
1504
|
-
result += change.replacement;
|
|
1505
|
-
previous = change;
|
|
1506
|
-
}
|
|
1507
|
-
result += str.slice(previous.end);
|
|
1508
|
-
return result;
|
|
1509
|
-
}
|
|
1510
|
-
//#endregion
|
|
1511
|
-
//#region src/runtime/class-collector.ts
|
|
1512
|
-
function collectRuntimeCandidateKeys(context) {
|
|
1513
|
-
const candidateRuleCache = context.candidateRuleCache;
|
|
1514
|
-
if (candidateRuleCache instanceof Map && candidateRuleCache.size > 0) return candidateRuleCache.keys();
|
|
1515
|
-
return context.classCache.keys();
|
|
1516
|
-
}
|
|
1517
|
-
function collectClassesFromContexts(contexts, filter) {
|
|
1518
|
-
const set = /* @__PURE__ */ new Set();
|
|
1519
|
-
for (const context of contexts) {
|
|
1520
|
-
if (!isObject(context) || !context.classCache) continue;
|
|
1521
|
-
for (const key of collectRuntimeCandidateKeys(context)) {
|
|
1522
|
-
const className = key.toString();
|
|
1523
|
-
if (filter(className)) set.add(className);
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
return set;
|
|
1527
|
-
}
|
|
1528
|
-
async function collectClassesFromTailwindV4(options) {
|
|
1529
|
-
const set = /* @__PURE__ */ new Set();
|
|
1530
|
-
const v4Options = options.tailwind.v4;
|
|
1531
|
-
if (!v4Options) return set;
|
|
1532
|
-
const toAbsolute = (value) => {
|
|
1533
|
-
if (!value) return;
|
|
1534
|
-
return pathe.default.isAbsolute(value) ? value : pathe.default.resolve(options.projectRoot, value);
|
|
1535
|
-
};
|
|
1536
|
-
const resolvedConfiguredBase = toAbsolute(v4Options.configuredBase);
|
|
1537
|
-
const resolvedDefaultBase = toAbsolute(v4Options.base) ?? node_process.default.cwd();
|
|
1538
|
-
const resolveSources = (base) => {
|
|
1539
|
-
if (!v4Options.sources?.length) return;
|
|
1540
|
-
return v4Options.sources.map((source) => ({
|
|
1541
|
-
base: source.base ?? base,
|
|
1542
|
-
pattern: source.pattern,
|
|
1543
|
-
negated: source.negated
|
|
1544
|
-
}));
|
|
1545
|
-
};
|
|
1546
|
-
const addCandidates = async (extractOptions) => {
|
|
1547
|
-
const candidates = await (0, _tailwindcss_mangle_engine.extractValidCandidates)(extractOptions);
|
|
1548
|
-
for (const candidate of candidates) if (options.filter(candidate)) set.add(candidate);
|
|
1549
|
-
};
|
|
1550
|
-
if (v4Options.cssSources.length > 0) for (const source of v4Options.cssSources) {
|
|
1551
|
-
const sourceFile = toAbsolute(source.file);
|
|
1552
|
-
const sourceBase = toAbsolute(source.base) ?? (sourceFile ? pathe.default.dirname(sourceFile) : resolvedDefaultBase);
|
|
1553
|
-
const designSystemBases = resolvedConfiguredBase && resolvedConfiguredBase !== sourceBase ? [sourceBase, resolvedConfiguredBase] : [sourceBase];
|
|
1554
|
-
const sources = resolveSources(sourceBase);
|
|
1555
|
-
const firstBase = designSystemBases[0] ?? sourceBase;
|
|
1556
|
-
await addCandidates({
|
|
1557
|
-
cwd: options.projectRoot,
|
|
1558
|
-
base: firstBase,
|
|
1559
|
-
baseFallbacks: designSystemBases.slice(1),
|
|
1560
|
-
css: source.css,
|
|
1561
|
-
...v4Options.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: v4Options.bareArbitraryValues },
|
|
1562
|
-
...sources === void 0 ? {} : { sources }
|
|
1563
|
-
});
|
|
1564
|
-
}
|
|
1565
|
-
if (v4Options.cssEntries.length > 0) for (const entry of v4Options.cssEntries) {
|
|
1566
|
-
const filePath = pathe.default.isAbsolute(entry) ? entry : pathe.default.resolve(options.projectRoot, entry);
|
|
1567
|
-
if (!await fs_extra.default.pathExists(filePath)) continue;
|
|
1568
|
-
const css = await fs_extra.default.readFile(filePath, "utf8");
|
|
1569
|
-
const entryDir = pathe.default.dirname(filePath);
|
|
1570
|
-
const designSystemBases = resolvedConfiguredBase && resolvedConfiguredBase !== entryDir ? [entryDir, resolvedConfiguredBase] : [entryDir];
|
|
1571
|
-
const sources = resolveSources(resolvedConfiguredBase ?? entryDir);
|
|
1572
|
-
const firstBase = designSystemBases[0] ?? entryDir;
|
|
1573
|
-
await addCandidates({
|
|
1574
|
-
cwd: options.projectRoot,
|
|
1575
|
-
base: firstBase,
|
|
1576
|
-
baseFallbacks: designSystemBases.slice(1),
|
|
1577
|
-
css,
|
|
1578
|
-
...v4Options.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: v4Options.bareArbitraryValues },
|
|
1579
|
-
...sources === void 0 ? {} : { sources }
|
|
1580
|
-
});
|
|
1581
|
-
}
|
|
1582
|
-
else if (v4Options.cssSources.length === 0) {
|
|
1583
|
-
const baseForCss = resolvedConfiguredBase ?? resolvedDefaultBase;
|
|
1584
|
-
const sources = resolveSources(baseForCss);
|
|
1585
|
-
await addCandidates({
|
|
1586
|
-
cwd: options.projectRoot,
|
|
1587
|
-
base: baseForCss,
|
|
1588
|
-
...v4Options.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: v4Options.bareArbitraryValues },
|
|
1589
|
-
...v4Options.css === void 0 ? {} : { css: v4Options.css },
|
|
1590
|
-
...sources === void 0 ? {} : { sources }
|
|
1591
|
-
});
|
|
1592
|
-
}
|
|
1593
|
-
return set;
|
|
1594
|
-
}
|
|
1595
|
-
//#endregion
|
|
1596
|
-
//#region src/runtime/context-registry.ts
|
|
1597
|
-
const require$1 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
1598
|
-
function resolveRuntimeEntry(packageInfo, majorVersion) {
|
|
1599
|
-
const root = packageInfo.rootPath;
|
|
1600
|
-
if (majorVersion === 2) {
|
|
1601
|
-
const jitIndex = pathe.default.join(root, "lib/jit/index.js");
|
|
1602
|
-
if (fs_extra.default.existsSync(jitIndex)) return jitIndex;
|
|
1603
|
-
} else if (majorVersion === 3) {
|
|
1604
|
-
const plugin = pathe.default.join(root, "lib/plugin.js");
|
|
1605
|
-
const index = pathe.default.join(root, "lib/index.js");
|
|
1606
|
-
if (fs_extra.default.existsSync(plugin)) return plugin;
|
|
1607
|
-
if (fs_extra.default.existsSync(index)) return index;
|
|
1608
|
-
}
|
|
1609
|
-
}
|
|
1610
|
-
function loadRuntimeContexts(packageInfo, majorVersion, refProperty) {
|
|
1611
|
-
if (majorVersion === 4) return [];
|
|
1612
|
-
const entry = resolveRuntimeEntry(packageInfo, majorVersion);
|
|
1613
|
-
if (!entry) return [];
|
|
1614
|
-
const moduleExports = require$1(entry);
|
|
1615
|
-
if (!moduleExports) return [];
|
|
1616
|
-
const ref = moduleExports[refProperty];
|
|
1617
|
-
if (!ref) return [];
|
|
1618
|
-
if (Array.isArray(ref)) return ref;
|
|
1619
|
-
if (typeof ref === "object" && Array.isArray(ref.value)) return ref.value;
|
|
1620
|
-
return [];
|
|
1621
|
-
}
|
|
1622
|
-
//#endregion
|
|
1623
|
-
//#region src/babel/index.ts
|
|
1624
|
-
function _interopDefaultCompat(e) {
|
|
1625
|
-
return e && typeof e === "object" && "default" in e ? e.default : e;
|
|
1626
|
-
}
|
|
1627
|
-
const generate$1 = _interopDefaultCompat(_babel_generator.default);
|
|
1628
|
-
const traverse = _interopDefaultCompat(_babel_traverse.default);
|
|
1629
|
-
//#endregion
|
|
1630
|
-
//#region src/patching/operations/export-context/postcss-v2.ts
|
|
1631
|
-
const IDENTIFIER_RE$1 = /^[A-Z_$][\w$]*$/i;
|
|
1632
|
-
function toIdentifierName$1(property) {
|
|
1633
|
-
if (!property) return "contextRef";
|
|
1634
|
-
const sanitized = property.replace(/[^\w$]/gu, "_");
|
|
1635
|
-
if (/^\d/.test(sanitized)) return `_${sanitized}`;
|
|
1636
|
-
return sanitized || "contextRef";
|
|
1637
|
-
}
|
|
1638
|
-
function createExportsMember(property) {
|
|
1639
|
-
if (IDENTIFIER_RE$1.test(property)) return _babel_types.memberExpression(_babel_types.identifier("exports"), _babel_types.identifier(property));
|
|
1640
|
-
return _babel_types.memberExpression(_babel_types.identifier("exports"), _babel_types.stringLiteral(property), true);
|
|
1641
|
-
}
|
|
1642
|
-
function transformProcessTailwindFeaturesReturnContextV2(content) {
|
|
1643
|
-
const ast = (0, _babel_parser.parse)(content, { sourceType: "unambiguous" });
|
|
1644
|
-
let hasPatched = false;
|
|
1645
|
-
traverse(ast, { FunctionDeclaration(path) {
|
|
1646
|
-
const node = path.node;
|
|
1647
|
-
if (node.id?.name !== "processTailwindFeatures" || node.body.body.length !== 1 || !_babel_types.isReturnStatement(node.body.body[0])) return;
|
|
1648
|
-
const returnStatement = node.body.body[0];
|
|
1649
|
-
if (!_babel_types.isFunctionExpression(returnStatement.argument)) return;
|
|
1650
|
-
const body = returnStatement.argument.body.body;
|
|
1651
|
-
const lastStatement = body[body.length - 1];
|
|
1652
|
-
const alreadyReturnsContext = Boolean(_babel_types.isReturnStatement(lastStatement) && _babel_types.isIdentifier(lastStatement.argument) && lastStatement.argument.name === "context");
|
|
1653
|
-
hasPatched = alreadyReturnsContext;
|
|
1654
|
-
if (!alreadyReturnsContext) body.push(_babel_types.returnStatement(_babel_types.identifier("context")));
|
|
1655
|
-
} });
|
|
1656
|
-
return {
|
|
1657
|
-
code: hasPatched ? content : generate$1(ast).code,
|
|
1658
|
-
hasPatched
|
|
1659
|
-
};
|
|
1660
|
-
}
|
|
1661
|
-
function transformPostcssPluginV2(content, options) {
|
|
1662
|
-
const refIdentifier = _babel_types.identifier(toIdentifierName$1(options.refProperty));
|
|
1663
|
-
const exportMember = createExportsMember(options.refProperty);
|
|
1664
|
-
const valueMember = _babel_types.memberExpression(refIdentifier, _babel_types.identifier("value"));
|
|
1665
|
-
const ast = (0, _babel_parser.parse)(content);
|
|
1666
|
-
let hasPatched = false;
|
|
1667
|
-
traverse(ast, {
|
|
1668
|
-
Program(path) {
|
|
1669
|
-
const program = path.node;
|
|
1670
|
-
const index = program.body.findIndex((statement) => {
|
|
1671
|
-
return _babel_types.isFunctionDeclaration(statement) && statement.id?.name === "_default";
|
|
1672
|
-
});
|
|
1673
|
-
if (index === -1) return;
|
|
1674
|
-
const previous = program.body[index - 1];
|
|
1675
|
-
const beforePrevious = program.body[index - 2];
|
|
1676
|
-
const alreadyHasVariable = Boolean(previous && _babel_types.isVariableDeclaration(previous) && previous.declarations.length === 1 && (() => {
|
|
1677
|
-
const declaration = previous.declarations[0];
|
|
1678
|
-
return Boolean(declaration && _babel_types.isIdentifier(declaration.id) && declaration.id.name === refIdentifier.name);
|
|
1679
|
-
})());
|
|
1680
|
-
const alreadyAssignsExports = Boolean(beforePrevious && _babel_types.isExpressionStatement(beforePrevious) && _babel_types.isAssignmentExpression(beforePrevious.expression) && _babel_types.isMemberExpression(beforePrevious.expression.left) && _babel_types.isIdentifier(beforePrevious.expression.right) && beforePrevious.expression.right.name === refIdentifier.name && generate$1(beforePrevious.expression.left).code === generate$1(exportMember).code);
|
|
1681
|
-
hasPatched = alreadyHasVariable && alreadyAssignsExports;
|
|
1682
|
-
if (!alreadyHasVariable) program.body.splice(index, 0, _babel_types.variableDeclaration("var", [_babel_types.variableDeclarator(refIdentifier, _babel_types.objectExpression([_babel_types.objectProperty(_babel_types.identifier("value"), _babel_types.arrayExpression())]))]), _babel_types.expressionStatement(_babel_types.assignmentExpression("=", exportMember, refIdentifier)));
|
|
1683
|
-
},
|
|
1684
|
-
FunctionDeclaration(path) {
|
|
1685
|
-
if (hasPatched) return;
|
|
1686
|
-
const fn = path.node;
|
|
1687
|
-
if (fn.id?.name !== "_default") return;
|
|
1688
|
-
if (fn.body.body.length !== 1 || !_babel_types.isReturnStatement(fn.body.body[0])) return;
|
|
1689
|
-
const returnStatement = fn.body.body[0];
|
|
1690
|
-
if (!_babel_types.isCallExpression(returnStatement.argument) || !_babel_types.isMemberExpression(returnStatement.argument.callee) || !_babel_types.isArrayExpression(returnStatement.argument.callee.object)) return;
|
|
1691
|
-
const fnExpression = returnStatement.argument.callee.object.elements[1];
|
|
1692
|
-
if (!fnExpression || !_babel_types.isFunctionExpression(fnExpression)) return;
|
|
1693
|
-
const statements = fnExpression.body.body;
|
|
1694
|
-
if (_babel_types.isExpressionStatement(statements[0]) && _babel_types.isAssignmentExpression(statements[0].expression) && _babel_types.isNumericLiteral(statements[0].expression.right)) {
|
|
1695
|
-
hasPatched = true;
|
|
1696
|
-
return;
|
|
1697
|
-
}
|
|
1698
|
-
const lastStatement = statements[statements.length - 1];
|
|
1699
|
-
if (lastStatement && _babel_types.isExpressionStatement(lastStatement)) statements[statements.length - 1] = _babel_types.expressionStatement(_babel_types.callExpression(_babel_types.memberExpression(valueMember, _babel_types.identifier("push")), [lastStatement.expression]));
|
|
1700
|
-
const index = statements.findIndex((statement) => _babel_types.isIfStatement(statement));
|
|
1701
|
-
if (index > -1) {
|
|
1702
|
-
const ifStatement = statements[index];
|
|
1703
|
-
if (_babel_types.isBlockStatement(ifStatement.consequent) && ifStatement.consequent.body[1] && _babel_types.isForOfStatement(ifStatement.consequent.body[1])) {
|
|
1704
|
-
const forOf = ifStatement.consequent.body[1];
|
|
1705
|
-
if (_babel_types.isBlockStatement(forOf.body) && forOf.body.body.length === 1) {
|
|
1706
|
-
const nestedIf = forOf.body.body[0];
|
|
1707
|
-
if (nestedIf && _babel_types.isIfStatement(nestedIf) && _babel_types.isBlockStatement(nestedIf.consequent) && nestedIf.consequent.body.length === 1 && _babel_types.isExpressionStatement(nestedIf.consequent.body[0])) nestedIf.consequent.body[0] = _babel_types.expressionStatement(_babel_types.callExpression(_babel_types.memberExpression(valueMember, _babel_types.identifier("push")), [nestedIf.consequent.body[0].expression]));
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
statements.unshift(_babel_types.expressionStatement(_babel_types.assignmentExpression("=", _babel_types.memberExpression(valueMember, _babel_types.identifier("length")), _babel_types.numericLiteral(0))));
|
|
1712
|
-
}
|
|
1713
|
-
});
|
|
1714
|
-
return {
|
|
1715
|
-
code: hasPatched ? content : generate$1(ast).code,
|
|
1716
|
-
hasPatched
|
|
1717
|
-
};
|
|
1718
|
-
}
|
|
1719
|
-
//#endregion
|
|
1720
|
-
//#region src/patching/operations/export-context/postcss-v3.ts
|
|
1721
|
-
const IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
|
|
1722
|
-
function toIdentifierName(property) {
|
|
1723
|
-
if (!property) return "contextRef";
|
|
1724
|
-
const sanitized = property.replace(/[^\w$]/gu, "_");
|
|
1725
|
-
if (/^\d/.test(sanitized)) return `_${sanitized}`;
|
|
1726
|
-
return sanitized || "contextRef";
|
|
1727
|
-
}
|
|
1728
|
-
function createModuleExportsMember(property) {
|
|
1729
|
-
const object = _babel_types.memberExpression(_babel_types.identifier("module"), _babel_types.identifier("exports"));
|
|
1730
|
-
if (IDENTIFIER_RE.test(property)) return _babel_types.memberExpression(object, _babel_types.identifier(property));
|
|
1731
|
-
return _babel_types.memberExpression(object, _babel_types.stringLiteral(property), true);
|
|
1732
|
-
}
|
|
1733
|
-
function transformProcessTailwindFeaturesReturnContext(content) {
|
|
1734
|
-
const ast = (0, _babel_parser.parse)(content);
|
|
1735
|
-
let hasPatched = false;
|
|
1736
|
-
traverse(ast, { FunctionDeclaration(path) {
|
|
1737
|
-
const node = path.node;
|
|
1738
|
-
if (node.id?.name !== "processTailwindFeatures" || node.body.body.length !== 1) return;
|
|
1739
|
-
const [returnStatement] = node.body.body;
|
|
1740
|
-
if (!_babel_types.isReturnStatement(returnStatement) || !_babel_types.isFunctionExpression(returnStatement.argument)) return;
|
|
1741
|
-
const body = returnStatement.argument.body.body;
|
|
1742
|
-
const lastStatement = body[body.length - 1];
|
|
1743
|
-
const alreadyReturnsContext = Boolean(_babel_types.isReturnStatement(lastStatement) && _babel_types.isIdentifier(lastStatement.argument) && lastStatement.argument.name === "context");
|
|
1744
|
-
hasPatched = alreadyReturnsContext;
|
|
1745
|
-
if (!alreadyReturnsContext) body.push(_babel_types.returnStatement(_babel_types.identifier("context")));
|
|
1746
|
-
} });
|
|
1747
|
-
return {
|
|
1748
|
-
code: hasPatched ? content : generate$1(ast).code,
|
|
1749
|
-
hasPatched
|
|
1750
|
-
};
|
|
1751
|
-
}
|
|
1752
|
-
function transformPostcssPlugin(content, { refProperty }) {
|
|
1753
|
-
const ast = (0, _babel_parser.parse)(content);
|
|
1754
|
-
const refIdentifier = _babel_types.identifier(toIdentifierName(refProperty));
|
|
1755
|
-
const moduleExportsMember = createModuleExportsMember(refProperty);
|
|
1756
|
-
const valueMember = _babel_types.memberExpression(refIdentifier, _babel_types.identifier("value"));
|
|
1757
|
-
let hasPatched = false;
|
|
1758
|
-
traverse(ast, {
|
|
1759
|
-
Program(path) {
|
|
1760
|
-
const program = path.node;
|
|
1761
|
-
const index = program.body.findIndex((statement) => {
|
|
1762
|
-
return _babel_types.isExpressionStatement(statement) && _babel_types.isAssignmentExpression(statement.expression) && _babel_types.isMemberExpression(statement.expression.left) && _babel_types.isFunctionExpression(statement.expression.right) && statement.expression.right.id?.name === "tailwindcss";
|
|
1763
|
-
});
|
|
1764
|
-
if (index === -1) return;
|
|
1765
|
-
const previousStatement = program.body[index - 1];
|
|
1766
|
-
const lastStatement = program.body[program.body.length - 1];
|
|
1767
|
-
const alreadyHasVariable = Boolean(previousStatement && _babel_types.isVariableDeclaration(previousStatement) && previousStatement.declarations.length === 1 && (() => {
|
|
1768
|
-
const declaration = previousStatement.declarations[0];
|
|
1769
|
-
return Boolean(declaration && _babel_types.isIdentifier(declaration.id) && declaration.id.name === refIdentifier.name);
|
|
1770
|
-
})());
|
|
1771
|
-
const alreadyAssignsModuleExports = Boolean(_babel_types.isExpressionStatement(lastStatement) && _babel_types.isAssignmentExpression(lastStatement.expression) && _babel_types.isMemberExpression(lastStatement.expression.left) && _babel_types.isIdentifier(lastStatement.expression.right) && lastStatement.expression.right.name === refIdentifier.name && generate$1(lastStatement.expression.left).code === generate$1(moduleExportsMember).code);
|
|
1772
|
-
hasPatched = alreadyHasVariable && alreadyAssignsModuleExports;
|
|
1773
|
-
if (!alreadyHasVariable) program.body.splice(index, 0, _babel_types.variableDeclaration("const", [_babel_types.variableDeclarator(refIdentifier, _babel_types.objectExpression([_babel_types.objectProperty(_babel_types.identifier("value"), _babel_types.arrayExpression())]))]));
|
|
1774
|
-
if (!alreadyAssignsModuleExports) program.body.push(_babel_types.expressionStatement(_babel_types.assignmentExpression("=", moduleExportsMember, refIdentifier)));
|
|
1775
|
-
},
|
|
1776
|
-
FunctionExpression(path) {
|
|
1777
|
-
if (hasPatched) return;
|
|
1778
|
-
const fn = path.node;
|
|
1779
|
-
if (fn.id?.name !== "tailwindcss" || fn.body.body.length !== 1) return;
|
|
1780
|
-
const [returnStatement] = fn.body.body;
|
|
1781
|
-
if (!returnStatement || !_babel_types.isReturnStatement(returnStatement) || !_babel_types.isObjectExpression(returnStatement.argument)) return;
|
|
1782
|
-
const properties = returnStatement.argument.properties;
|
|
1783
|
-
if (properties.length !== 2) return;
|
|
1784
|
-
const pluginsProperty = properties.find((prop) => _babel_types.isObjectProperty(prop) && _babel_types.isIdentifier(prop.key) && prop.key.name === "plugins");
|
|
1785
|
-
if (!pluginsProperty || !_babel_types.isObjectProperty(pluginsProperty) || !_babel_types.isCallExpression(pluginsProperty.value) || !_babel_types.isMemberExpression(pluginsProperty.value.callee) || !_babel_types.isArrayExpression(pluginsProperty.value.callee.object)) return;
|
|
1786
|
-
const targetPlugin = pluginsProperty.value.callee.object.elements[1];
|
|
1787
|
-
if (!targetPlugin || !_babel_types.isFunctionExpression(targetPlugin)) return;
|
|
1788
|
-
const statements = targetPlugin.body.body;
|
|
1789
|
-
const last = statements[statements.length - 1];
|
|
1790
|
-
if (last && _babel_types.isExpressionStatement(last)) statements[statements.length - 1] = _babel_types.expressionStatement(_babel_types.callExpression(_babel_types.memberExpression(valueMember, _babel_types.identifier("push")), [last.expression]));
|
|
1791
|
-
const index = statements.findIndex((s) => _babel_types.isIfStatement(s));
|
|
1792
|
-
if (index > -1) {
|
|
1793
|
-
const ifStatement = statements[index];
|
|
1794
|
-
if (_babel_types.isBlockStatement(ifStatement.consequent)) {
|
|
1795
|
-
const [, second] = ifStatement.consequent.body;
|
|
1796
|
-
if (second && _babel_types.isForOfStatement(second) && _babel_types.isBlockStatement(second.body)) {
|
|
1797
|
-
const bodyStatement = second.body.body[0];
|
|
1798
|
-
if (bodyStatement && _babel_types.isIfStatement(bodyStatement) && _babel_types.isBlockStatement(bodyStatement.consequent) && bodyStatement.consequent.body.length === 1 && _babel_types.isExpressionStatement(bodyStatement.consequent.body[0])) bodyStatement.consequent.body[0] = _babel_types.expressionStatement(_babel_types.callExpression(_babel_types.memberExpression(valueMember, _babel_types.identifier("push")), [bodyStatement.consequent.body[0].expression]));
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
statements.unshift(_babel_types.expressionStatement(_babel_types.assignmentExpression("=", _babel_types.memberExpression(valueMember, _babel_types.identifier("length")), _babel_types.numericLiteral(0))));
|
|
1803
|
-
}
|
|
1804
|
-
});
|
|
1805
|
-
return {
|
|
1806
|
-
code: hasPatched ? content : generate$1(ast).code,
|
|
1807
|
-
hasPatched
|
|
1808
|
-
};
|
|
1809
|
-
}
|
|
1810
|
-
//#endregion
|
|
1811
|
-
//#region src/patching/operations/export-context/index.ts
|
|
1812
|
-
function writeFileIfRequired(filePath, code, overwrite, successMessage) {
|
|
1813
|
-
if (!overwrite) return;
|
|
1814
|
-
fs_extra.default.writeFileSync(filePath, code, { encoding: "utf8" });
|
|
1815
|
-
logger.success(successMessage);
|
|
1816
|
-
}
|
|
1817
|
-
function applyExposeContextPatch(params) {
|
|
1818
|
-
const { rootDir, refProperty, overwrite, majorVersion } = params;
|
|
1819
|
-
const result = {
|
|
1820
|
-
applied: false,
|
|
1821
|
-
files: {}
|
|
1822
|
-
};
|
|
1823
|
-
if (majorVersion === 3) {
|
|
1824
|
-
const processFileRelative = "lib/processTailwindFeatures.js";
|
|
1825
|
-
const processFilePath = pathe.default.resolve(rootDir, processFileRelative);
|
|
1826
|
-
if (fs_extra.default.existsSync(processFilePath)) {
|
|
1827
|
-
const { code, hasPatched } = transformProcessTailwindFeaturesReturnContext(fs_extra.default.readFileSync(processFilePath, "utf8"));
|
|
1828
|
-
result.files[processFileRelative] = code;
|
|
1829
|
-
if (!hasPatched) {
|
|
1830
|
-
writeFileIfRequired(processFilePath, code, overwrite, "Patched Tailwind CSS processTailwindFeatures to expose runtime context.");
|
|
1831
|
-
result.applied = true;
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
const pluginRelative = ["lib/plugin.js", "lib/index.js"].find((candidate) => fs_extra.default.existsSync(pathe.default.resolve(rootDir, candidate)));
|
|
1835
|
-
if (pluginRelative) {
|
|
1836
|
-
const pluginPath = pathe.default.resolve(rootDir, pluginRelative);
|
|
1837
|
-
const { code, hasPatched } = transformPostcssPlugin(fs_extra.default.readFileSync(pluginPath, "utf8"), { refProperty });
|
|
1838
|
-
result.files[pluginRelative] = code;
|
|
1839
|
-
if (!hasPatched) {
|
|
1840
|
-
writeFileIfRequired(pluginPath, code, overwrite, "Patched Tailwind CSS plugin entry to collect runtime contexts.");
|
|
1841
|
-
result.applied = true;
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
|
-
} else if (majorVersion === 2) {
|
|
1845
|
-
const processFileRelative = "lib/jit/processTailwindFeatures.js";
|
|
1846
|
-
const processFilePath = pathe.default.resolve(rootDir, processFileRelative);
|
|
1847
|
-
if (fs_extra.default.existsSync(processFilePath)) {
|
|
1848
|
-
const { code, hasPatched } = transformProcessTailwindFeaturesReturnContextV2(fs_extra.default.readFileSync(processFilePath, "utf8"));
|
|
1849
|
-
result.files[processFileRelative] = code;
|
|
1850
|
-
if (!hasPatched) {
|
|
1851
|
-
writeFileIfRequired(processFilePath, code, overwrite, "Patched Tailwind CSS JIT processTailwindFeatures to expose runtime context.");
|
|
1852
|
-
result.applied = true;
|
|
1853
|
-
}
|
|
1854
|
-
}
|
|
1855
|
-
const pluginRelative = "lib/jit/index.js";
|
|
1856
|
-
const pluginPath = pathe.default.resolve(rootDir, pluginRelative);
|
|
1857
|
-
if (fs_extra.default.existsSync(pluginPath)) {
|
|
1858
|
-
const { code, hasPatched } = transformPostcssPluginV2(fs_extra.default.readFileSync(pluginPath, "utf8"), { refProperty });
|
|
1859
|
-
result.files[pluginRelative] = code;
|
|
1860
|
-
if (!hasPatched) {
|
|
1861
|
-
writeFileIfRequired(pluginPath, code, overwrite, "Patched Tailwind CSS JIT entry to collect runtime contexts.");
|
|
1862
|
-
result.applied = true;
|
|
1863
|
-
}
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
return result;
|
|
1867
|
-
}
|
|
1868
|
-
//#endregion
|
|
1869
|
-
//#region src/patching/operations/extend-length-units.ts
|
|
1870
|
-
function updateLengthUnitsArray(content, options) {
|
|
1871
|
-
const { variableName = "lengthUnits", units } = options;
|
|
1872
|
-
const ast = (0, _babel_parser.parse)(content);
|
|
1873
|
-
let arrayRef;
|
|
1874
|
-
let changed = false;
|
|
1875
|
-
traverse(ast, { Identifier(path) {
|
|
1876
|
-
if (path.node.name === variableName && _babel_types.isVariableDeclarator(path.parent) && _babel_types.isArrayExpression(path.parent.init)) {
|
|
1877
|
-
arrayRef = path.parent.init;
|
|
1878
|
-
const existing = new Set(path.parent.init.elements.map((element) => _babel_types.isStringLiteral(element) ? element.value : void 0).filter(Boolean));
|
|
1879
|
-
for (const unit of units) if (!existing.has(unit)) {
|
|
1880
|
-
path.parent.init.elements = path.parent.init.elements.map((element) => {
|
|
1881
|
-
if (_babel_types.isStringLiteral(element)) return _babel_types.stringLiteral(element.value);
|
|
1882
|
-
return element;
|
|
1883
|
-
});
|
|
1884
|
-
path.parent.init.elements.push(_babel_types.stringLiteral(unit));
|
|
1885
|
-
changed = true;
|
|
1886
|
-
}
|
|
1887
|
-
}
|
|
1888
|
-
} });
|
|
1889
|
-
return {
|
|
1890
|
-
...arrayRef === void 0 ? {} : { arrayRef },
|
|
1891
|
-
changed
|
|
1892
|
-
};
|
|
1893
|
-
}
|
|
1894
|
-
function applyExtendLengthUnitsPatchV3(rootDir, options) {
|
|
1895
|
-
if (!options.enabled) return {
|
|
1896
|
-
changed: false,
|
|
1897
|
-
code: void 0
|
|
1898
|
-
};
|
|
1899
|
-
const opts = {
|
|
1900
|
-
...options,
|
|
1901
|
-
lengthUnitsFilePath: options.lengthUnitsFilePath ?? "lib/util/dataTypes.js",
|
|
1902
|
-
variableName: options.variableName ?? "lengthUnits"
|
|
1903
|
-
};
|
|
1904
|
-
const dataTypesFilePath = pathe.default.resolve(rootDir, opts.lengthUnitsFilePath);
|
|
1905
|
-
if (!fs_extra.default.existsSync(dataTypesFilePath)) return {
|
|
1906
|
-
changed: false,
|
|
1907
|
-
code: void 0
|
|
1908
|
-
};
|
|
1909
|
-
const content = fs_extra.default.readFileSync(dataTypesFilePath, "utf8");
|
|
1910
|
-
const { arrayRef, changed } = updateLengthUnitsArray(content, opts);
|
|
1911
|
-
if (!arrayRef || !changed) return {
|
|
1912
|
-
changed: false,
|
|
1913
|
-
code: void 0
|
|
1914
|
-
};
|
|
1915
|
-
const { code } = generate$1(arrayRef, { jsescOption: { quotes: "single" } });
|
|
1916
|
-
if (arrayRef.start != null && arrayRef.end != null) {
|
|
1917
|
-
const nextCode = `${content.slice(0, arrayRef.start)}${code}${content.slice(arrayRef.end)}`;
|
|
1918
|
-
if (opts.overwrite) {
|
|
1919
|
-
const target = opts.destPath ? pathe.default.resolve(opts.destPath) : dataTypesFilePath;
|
|
1920
|
-
fs_extra.default.writeFileSync(target, nextCode, "utf8");
|
|
1921
|
-
logger.success("Patched Tailwind CSS length unit list (v3).");
|
|
1922
|
-
}
|
|
1923
|
-
return {
|
|
1924
|
-
changed: true,
|
|
1925
|
-
code: nextCode
|
|
1926
|
-
};
|
|
1927
|
-
}
|
|
1928
|
-
return {
|
|
1929
|
-
changed: false,
|
|
1930
|
-
code: void 0
|
|
1931
|
-
};
|
|
1932
|
-
}
|
|
1933
|
-
function applyExtendLengthUnitsPatchV4(rootDir, options) {
|
|
1934
|
-
if (!options.enabled) return {
|
|
1935
|
-
files: [],
|
|
1936
|
-
changed: false
|
|
1937
|
-
};
|
|
1938
|
-
const opts = { ...options };
|
|
1939
|
-
const distDir = pathe.default.resolve(rootDir, "dist");
|
|
1940
|
-
if (!fs_extra.default.existsSync(distDir)) return {
|
|
1941
|
-
files: [],
|
|
1942
|
-
changed: false
|
|
1943
|
-
};
|
|
1944
|
-
const chunkNames = fs_extra.default.readdirSync(distDir).filter((entry) => entry.endsWith(".js") || entry.endsWith(".mjs"));
|
|
1945
|
-
const pattern = /\[\s*["']cm["'],\s*["']mm["'],[\w,"']+\]/;
|
|
1946
|
-
const candidates = chunkNames.map((chunkName) => {
|
|
1947
|
-
const file = pathe.default.join(distDir, chunkName);
|
|
1948
|
-
const code = fs_extra.default.readFileSync(file, "utf8");
|
|
1949
|
-
const match = pattern.exec(code);
|
|
1950
|
-
if (!match) return null;
|
|
1951
|
-
return {
|
|
1952
|
-
file,
|
|
1953
|
-
code,
|
|
1954
|
-
match,
|
|
1955
|
-
hasPatched: false
|
|
1956
|
-
};
|
|
1957
|
-
}).filter((candidate) => candidate !== null);
|
|
1958
|
-
for (const item of candidates) {
|
|
1959
|
-
const { code, file, match } = item;
|
|
1960
|
-
const ast = (0, _babel_parser.parse)(match[0], { sourceType: "unambiguous" });
|
|
1961
|
-
traverse(ast, { ArrayExpression(path) {
|
|
1962
|
-
for (const unit of opts.units) {
|
|
1963
|
-
if (path.node.elements.some((element) => _babel_types.isStringLiteral(element) && element.value === unit)) {
|
|
1964
|
-
item.hasPatched = true;
|
|
1965
|
-
return;
|
|
1966
|
-
}
|
|
1967
|
-
path.node.elements.push(_babel_types.stringLiteral(unit));
|
|
1968
|
-
}
|
|
1969
|
-
} });
|
|
1970
|
-
if (item.hasPatched) continue;
|
|
1971
|
-
const { code: replacement } = generate$1(ast, { minified: true });
|
|
1972
|
-
const start = match.index ?? 0;
|
|
1973
|
-
item.code = spliceChangesIntoString(code, [{
|
|
1974
|
-
start,
|
|
1975
|
-
end: start + match[0].length,
|
|
1976
|
-
replacement: replacement.endsWith(";") ? replacement.slice(0, -1) : replacement
|
|
1977
|
-
}]);
|
|
1978
|
-
if (opts.overwrite) fs_extra.default.writeFileSync(file, item.code, "utf8");
|
|
1979
|
-
}
|
|
1980
|
-
if (candidates.some((file) => !file.hasPatched)) logger.success("Patched Tailwind CSS length unit list (v4).");
|
|
1981
|
-
return {
|
|
1982
|
-
changed: candidates.some((file) => !file.hasPatched),
|
|
1983
|
-
files: candidates
|
|
1984
|
-
};
|
|
1985
|
-
}
|
|
1986
|
-
//#endregion
|
|
1987
|
-
//#region src/patching/patch-runner.ts
|
|
1988
|
-
function applyTailwindPatches(context) {
|
|
1989
|
-
const { packageInfo, options, majorVersion } = context;
|
|
1990
|
-
const results = {};
|
|
1991
|
-
if (options.features.exposeContext.enabled && (majorVersion === 2 || majorVersion === 3)) results.exposeContext = applyExposeContextPatch({
|
|
1992
|
-
rootDir: packageInfo.rootPath,
|
|
1993
|
-
refProperty: options.features.exposeContext.refProperty,
|
|
1994
|
-
overwrite: options.overwrite,
|
|
1995
|
-
majorVersion
|
|
1996
|
-
});
|
|
1997
|
-
if (options.features.extendLengthUnits?.enabled) {
|
|
1998
|
-
if (majorVersion === 3) results.extendLengthUnits = applyExtendLengthUnitsPatchV3(packageInfo.rootPath, options.features.extendLengthUnits);
|
|
1999
|
-
else if (majorVersion === 4) results.extendLengthUnits = applyExtendLengthUnitsPatchV4(packageInfo.rootPath, options.features.extendLengthUnits);
|
|
2000
|
-
}
|
|
2001
|
-
return results;
|
|
2002
|
-
}
|
|
2003
|
-
//#endregion
|
|
2004
|
-
//#region src/runtime/process-tailwindcss.ts
|
|
2005
|
-
function createCwdRequire(cwd) {
|
|
2006
|
-
return (0, node_module.createRequire)(pathe.default.join(cwd, "package.json"));
|
|
2007
|
-
}
|
|
2008
|
-
function resolveModuleEntry(id, moduleRequire) {
|
|
2009
|
-
return pathe.default.isAbsolute(id) ? id : moduleRequire.resolve(id);
|
|
2010
|
-
}
|
|
2011
|
-
function resolvePackageRootFromEntry(entry) {
|
|
2012
|
-
let current = pathe.default.dirname(entry);
|
|
2013
|
-
while (current && current !== pathe.default.dirname(current)) {
|
|
2014
|
-
const packageJsonPath = pathe.default.join(current, "package.json");
|
|
2015
|
-
if (fs_extra.default.pathExistsSync(packageJsonPath)) return current;
|
|
2016
|
-
current = pathe.default.dirname(current);
|
|
2017
|
-
}
|
|
2018
|
-
}
|
|
2019
|
-
function resolveCacheKey(moduleRequire, entry) {
|
|
2020
|
-
try {
|
|
2021
|
-
return moduleRequire.resolve(entry);
|
|
2022
|
-
} catch {
|
|
2023
|
-
return entry;
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
function clearTailwindV3RuntimeState(pluginName, moduleRequire) {
|
|
2027
|
-
try {
|
|
2028
|
-
const root = resolvePackageRootFromEntry(resolveModuleEntry(pluginName, moduleRequire));
|
|
2029
|
-
if (!root) return;
|
|
2030
|
-
const sharedStatePath = pathe.default.join(root, "lib/lib/sharedState.js");
|
|
2031
|
-
if (!fs_extra.default.pathExistsSync(sharedStatePath)) return;
|
|
2032
|
-
const sharedStateKey = resolveCacheKey(moduleRequire, sharedStatePath);
|
|
2033
|
-
const sharedState = moduleRequire.cache[sharedStateKey]?.exports;
|
|
2034
|
-
sharedState?.contextMap?.clear();
|
|
2035
|
-
sharedState?.configContextMap?.clear();
|
|
2036
|
-
sharedState?.contextSourcesMap?.clear();
|
|
2037
|
-
sharedState?.sourceHashMap?.clear();
|
|
2038
|
-
for (const candidate of ["lib/plugin.js", "lib/index.js"]) {
|
|
2039
|
-
const runtimeEntry = pathe.default.join(root, candidate);
|
|
2040
|
-
if (!fs_extra.default.pathExistsSync(runtimeEntry)) continue;
|
|
2041
|
-
const runtimeKey = resolveCacheKey(moduleRequire, runtimeEntry);
|
|
2042
|
-
const runtimeModule = moduleRequire.cache[runtimeKey]?.exports;
|
|
2043
|
-
runtimeModule?.contextRef?.value?.splice(0, runtimeModule.contextRef.value.length);
|
|
2044
|
-
break;
|
|
2045
|
-
}
|
|
2046
|
-
} catch {}
|
|
2047
|
-
}
|
|
2048
|
-
async function resolveConfigPath(options) {
|
|
2049
|
-
if (options.config && pathe.default.isAbsolute(options.config)) return options.config;
|
|
2050
|
-
const result = await (0, tailwindcss_config.loadConfig)({ cwd: options.cwd });
|
|
2051
|
-
if (!result) throw new Error(`Unable to locate Tailwind CSS config from ${options.cwd}`);
|
|
2052
|
-
return result.filepath;
|
|
2053
|
-
}
|
|
2054
|
-
async function runTailwindBuild(options) {
|
|
2055
|
-
const configPath = await resolveConfigPath(options);
|
|
2056
|
-
const pluginName = options.postcssPlugin ?? (options.majorVersion === 4 ? "@tailwindcss/postcss" : "tailwindcss");
|
|
2057
|
-
const moduleRequire = createCwdRequire(options.cwd);
|
|
2058
|
-
if (options.majorVersion === 3) clearTailwindV3RuntimeState(pluginName, moduleRequire);
|
|
2059
|
-
if (options.majorVersion === 4) return (0, postcss.default)([moduleRequire(pluginName)({ config: configPath })]).process("@import 'tailwindcss';", { from: void 0 });
|
|
2060
|
-
return (0, postcss.default)([moduleRequire(pluginName)({ config: configPath })]).process("@tailwind base;@tailwind components;@tailwind utilities;", { from: void 0 });
|
|
2061
|
-
}
|
|
2062
|
-
//#endregion
|
|
2063
|
-
//#region src/patching/status.ts
|
|
2064
|
-
function inspectLengthUnitsArray(content, variableName, units) {
|
|
2065
|
-
const ast = (0, _babel_parser.parse)(content);
|
|
2066
|
-
let found = false;
|
|
2067
|
-
let missingUnits = [];
|
|
2068
|
-
traverse(ast, { Identifier(path) {
|
|
2069
|
-
if (path.node.name === variableName && _babel_types.isVariableDeclarator(path.parent) && _babel_types.isArrayExpression(path.parent.init)) {
|
|
2070
|
-
found = true;
|
|
2071
|
-
const existing = new Set(path.parent.init.elements.map((element) => _babel_types.isStringLiteral(element) ? element.value : void 0).filter(Boolean));
|
|
2072
|
-
missingUnits = units.filter((unit) => !existing.has(unit));
|
|
2073
|
-
path.stop();
|
|
2074
|
-
}
|
|
2075
|
-
} });
|
|
2076
|
-
return {
|
|
2077
|
-
found,
|
|
2078
|
-
missingUnits
|
|
2079
|
-
};
|
|
2080
|
-
}
|
|
2081
|
-
function checkExposeContextPatch(context) {
|
|
2082
|
-
const { packageInfo, options, majorVersion } = context;
|
|
2083
|
-
const refProperty = options.features.exposeContext.refProperty;
|
|
2084
|
-
if (!options.features.exposeContext.enabled) return {
|
|
2085
|
-
name: "exposeContext",
|
|
2086
|
-
status: "skipped",
|
|
2087
|
-
reason: "exposeContext feature disabled",
|
|
2088
|
-
files: []
|
|
2089
|
-
};
|
|
2090
|
-
if (majorVersion === 4) return {
|
|
2091
|
-
name: "exposeContext",
|
|
2092
|
-
status: "unsupported",
|
|
2093
|
-
reason: "Context export patch is only required for Tailwind v2/v3",
|
|
2094
|
-
files: []
|
|
2095
|
-
};
|
|
2096
|
-
const checks = [];
|
|
2097
|
-
function inspectFile(relative, transform) {
|
|
2098
|
-
const filePath = pathe.default.resolve(packageInfo.rootPath, relative);
|
|
2099
|
-
if (!fs_extra.default.existsSync(filePath)) {
|
|
2100
|
-
checks.push({
|
|
2101
|
-
relative,
|
|
2102
|
-
exists: false,
|
|
2103
|
-
patched: false
|
|
2104
|
-
});
|
|
2105
|
-
return;
|
|
2106
|
-
}
|
|
2107
|
-
const { hasPatched } = transform(fs_extra.default.readFileSync(filePath, "utf8"));
|
|
2108
|
-
checks.push({
|
|
2109
|
-
relative,
|
|
2110
|
-
exists: true,
|
|
2111
|
-
patched: hasPatched
|
|
2112
|
-
});
|
|
2113
|
-
}
|
|
2114
|
-
if (majorVersion === 3) {
|
|
2115
|
-
inspectFile("lib/processTailwindFeatures.js", transformProcessTailwindFeaturesReturnContext);
|
|
2116
|
-
const pluginRelative = ["lib/plugin.js", "lib/index.js"].find((candidate) => fs_extra.default.existsSync(pathe.default.resolve(packageInfo.rootPath, candidate)));
|
|
2117
|
-
if (pluginRelative) inspectFile(pluginRelative, (content) => transformPostcssPlugin(content, { refProperty }));
|
|
2118
|
-
else checks.push({
|
|
2119
|
-
relative: "lib/plugin.js",
|
|
2120
|
-
exists: false,
|
|
2121
|
-
patched: false
|
|
2122
|
-
});
|
|
2123
|
-
} else {
|
|
2124
|
-
inspectFile("lib/jit/processTailwindFeatures.js", transformProcessTailwindFeaturesReturnContextV2);
|
|
2125
|
-
inspectFile("lib/jit/index.js", (content) => transformPostcssPluginV2(content, { refProperty }));
|
|
2126
|
-
}
|
|
2127
|
-
const files = checks.filter((check) => check.exists).map((check) => check.relative);
|
|
2128
|
-
const missingFiles = checks.filter((check) => !check.exists);
|
|
2129
|
-
const unpatchedFiles = checks.filter((check) => check.exists && !check.patched);
|
|
2130
|
-
const reasons = [];
|
|
2131
|
-
if (missingFiles.length) reasons.push(`missing files: ${missingFiles.map((item) => item.relative).join(", ")}`);
|
|
2132
|
-
if (unpatchedFiles.length) reasons.push(`unpatched files: ${unpatchedFiles.map((item) => item.relative).join(", ")}`);
|
|
2133
|
-
return {
|
|
2134
|
-
name: "exposeContext",
|
|
2135
|
-
status: reasons.length ? "not-applied" : "applied",
|
|
2136
|
-
...reasons.length ? { reason: reasons.join("; ") } : {},
|
|
2137
|
-
files
|
|
2138
|
-
};
|
|
2139
|
-
}
|
|
2140
|
-
function checkExtendLengthUnitsV3(rootDir, options) {
|
|
2141
|
-
const lengthUnitsFilePath = options.lengthUnitsFilePath ?? "lib/util/dataTypes.js";
|
|
2142
|
-
const variableName = options.variableName ?? "lengthUnits";
|
|
2143
|
-
const target = pathe.default.resolve(rootDir, lengthUnitsFilePath);
|
|
2144
|
-
const files = fs_extra.default.existsSync(target) ? [pathe.default.relative(rootDir, target)] : [];
|
|
2145
|
-
if (!fs_extra.default.existsSync(target)) return {
|
|
2146
|
-
name: "extendLengthUnits",
|
|
2147
|
-
status: "not-applied",
|
|
2148
|
-
reason: `missing ${lengthUnitsFilePath}`,
|
|
2149
|
-
files
|
|
2150
|
-
};
|
|
2151
|
-
const { found, missingUnits } = inspectLengthUnitsArray(fs_extra.default.readFileSync(target, "utf8"), variableName, options.units);
|
|
2152
|
-
if (!found) return {
|
|
2153
|
-
name: "extendLengthUnits",
|
|
2154
|
-
status: "not-applied",
|
|
2155
|
-
reason: `could not locate ${variableName} array in ${lengthUnitsFilePath}`,
|
|
2156
|
-
files
|
|
2157
|
-
};
|
|
2158
|
-
if (missingUnits.length) return {
|
|
2159
|
-
name: "extendLengthUnits",
|
|
2160
|
-
status: "not-applied",
|
|
2161
|
-
reason: `missing units: ${missingUnits.join(", ")}`,
|
|
2162
|
-
files
|
|
2163
|
-
};
|
|
2164
|
-
return {
|
|
2165
|
-
name: "extendLengthUnits",
|
|
2166
|
-
status: "applied",
|
|
2167
|
-
files
|
|
2168
|
-
};
|
|
2169
|
-
}
|
|
2170
|
-
function checkExtendLengthUnitsV4(rootDir, options) {
|
|
2171
|
-
const distDir = pathe.default.resolve(rootDir, "dist");
|
|
2172
|
-
if (!fs_extra.default.existsSync(distDir)) return {
|
|
2173
|
-
name: "extendLengthUnits",
|
|
2174
|
-
status: "not-applied",
|
|
2175
|
-
reason: "dist directory not found for Tailwind v4 package",
|
|
2176
|
-
files: []
|
|
2177
|
-
};
|
|
2178
|
-
const result = applyExtendLengthUnitsPatchV4(rootDir, {
|
|
2179
|
-
...options,
|
|
2180
|
-
enabled: true,
|
|
2181
|
-
overwrite: false
|
|
2182
|
-
});
|
|
2183
|
-
if (result.files.length === 0) return {
|
|
2184
|
-
name: "extendLengthUnits",
|
|
2185
|
-
status: "not-applied",
|
|
2186
|
-
reason: "no bundle chunks matched the length unit pattern",
|
|
2187
|
-
files: []
|
|
2188
|
-
};
|
|
2189
|
-
const files = result.files.map((file) => pathe.default.relative(rootDir, file.file));
|
|
2190
|
-
const pending = result.files.filter((file) => !file.hasPatched);
|
|
2191
|
-
if (pending.length) return {
|
|
2192
|
-
name: "extendLengthUnits",
|
|
2193
|
-
status: "not-applied",
|
|
2194
|
-
reason: `missing units in ${pending.length} bundle${pending.length > 1 ? "s" : ""}`,
|
|
2195
|
-
files: pending.map((file) => pathe.default.relative(rootDir, file.file))
|
|
2196
|
-
};
|
|
2197
|
-
return {
|
|
2198
|
-
name: "extendLengthUnits",
|
|
2199
|
-
status: "applied",
|
|
2200
|
-
files
|
|
2201
|
-
};
|
|
2202
|
-
}
|
|
2203
|
-
function checkExtendLengthUnitsPatch(context) {
|
|
2204
|
-
const { packageInfo, options, majorVersion } = context;
|
|
2205
|
-
if (!options.features.extendLengthUnits) return {
|
|
2206
|
-
name: "extendLengthUnits",
|
|
2207
|
-
status: "skipped",
|
|
2208
|
-
reason: "extendLengthUnits feature disabled",
|
|
2209
|
-
files: []
|
|
2210
|
-
};
|
|
2211
|
-
if (majorVersion === 2) return {
|
|
2212
|
-
name: "extendLengthUnits",
|
|
2213
|
-
status: "unsupported",
|
|
2214
|
-
reason: "length unit extension is only applied for Tailwind v3/v4",
|
|
2215
|
-
files: []
|
|
2216
|
-
};
|
|
2217
|
-
if (majorVersion === 3) return checkExtendLengthUnitsV3(packageInfo.rootPath, options.features.extendLengthUnits);
|
|
2218
|
-
return checkExtendLengthUnitsV4(packageInfo.rootPath, options.features.extendLengthUnits);
|
|
2219
|
-
}
|
|
2220
|
-
function getPatchStatusReport(context) {
|
|
2221
|
-
return {
|
|
2222
|
-
package: {
|
|
2223
|
-
name: context.packageInfo.name ?? context.packageInfo.packageJson?.name,
|
|
2224
|
-
version: context.packageInfo.version,
|
|
2225
|
-
root: context.packageInfo.rootPath
|
|
2226
|
-
},
|
|
2227
|
-
majorVersion: context.majorVersion,
|
|
2228
|
-
entries: [checkExposeContextPatch(context), checkExtendLengthUnitsPatch(context)]
|
|
2229
|
-
};
|
|
2230
|
-
}
|
|
2231
|
-
//#endregion
|
|
2232
|
-
//#region src/runtime/collector.ts
|
|
2233
|
-
function resolveTailwindExecutionOptions(normalized, majorVersion) {
|
|
2234
|
-
const base = normalized.tailwind;
|
|
2235
|
-
if (majorVersion === 2 && base.v2) return {
|
|
2236
|
-
cwd: base.v2.cwd ?? base.cwd ?? normalized.projectRoot,
|
|
2237
|
-
config: base.v2.config ?? base.config,
|
|
2238
|
-
postcssPlugin: base.v2.postcssPlugin ?? base.postcssPlugin
|
|
2239
|
-
};
|
|
2240
|
-
if (majorVersion === 3 && base.v3) return {
|
|
2241
|
-
cwd: base.v3.cwd ?? base.cwd ?? normalized.projectRoot,
|
|
2242
|
-
config: base.v3.config ?? base.config,
|
|
2243
|
-
postcssPlugin: base.v3.postcssPlugin ?? base.postcssPlugin
|
|
2244
|
-
};
|
|
2245
|
-
return {
|
|
2246
|
-
cwd: base.cwd ?? normalized.projectRoot,
|
|
2247
|
-
config: base.config,
|
|
2248
|
-
postcssPlugin: base.postcssPlugin
|
|
2249
|
-
};
|
|
2250
|
-
}
|
|
2251
|
-
var BaseCollector = class {
|
|
2252
|
-
packageInfo;
|
|
2253
|
-
options;
|
|
2254
|
-
majorVersion;
|
|
2255
|
-
constructor(packageInfo, options, majorVersion) {
|
|
2256
|
-
this.packageInfo = packageInfo;
|
|
2257
|
-
this.options = options;
|
|
2258
|
-
this.majorVersion = majorVersion;
|
|
2259
|
-
}
|
|
2260
|
-
async patch() {
|
|
2261
|
-
return applyTailwindPatches({
|
|
2262
|
-
packageInfo: this.packageInfo,
|
|
2263
|
-
options: this.options,
|
|
2264
|
-
majorVersion: this.majorVersion
|
|
2265
|
-
});
|
|
2266
|
-
}
|
|
2267
|
-
async getPatchStatus() {
|
|
2268
|
-
return getPatchStatusReport({
|
|
2269
|
-
packageInfo: this.packageInfo,
|
|
2270
|
-
options: this.options,
|
|
2271
|
-
majorVersion: this.majorVersion
|
|
2272
|
-
});
|
|
2273
|
-
}
|
|
2274
|
-
getContexts() {
|
|
2275
|
-
return loadRuntimeContexts(this.packageInfo, this.majorVersion, this.options.features.exposeContext.refProperty);
|
|
2276
|
-
}
|
|
2277
|
-
};
|
|
2278
|
-
var RuntimeCollector = class extends BaseCollector {
|
|
2279
|
-
snapshotFactory;
|
|
2280
|
-
inFlightBuild;
|
|
2281
|
-
constructor(packageInfo, options, majorVersion, snapshotFactory) {
|
|
2282
|
-
super(packageInfo, options, majorVersion);
|
|
2283
|
-
this.snapshotFactory = snapshotFactory;
|
|
2284
|
-
}
|
|
2285
|
-
async collectClassSet() {
|
|
2286
|
-
return collectClassesFromContexts(this.getContexts(), this.options.filter);
|
|
2287
|
-
}
|
|
2288
|
-
getPatchSnapshot() {
|
|
2289
|
-
return this.snapshotFactory();
|
|
2290
|
-
}
|
|
2291
|
-
async runTailwindBuildIfNeeded() {
|
|
2292
|
-
if (this.inFlightBuild) return this.inFlightBuild;
|
|
2293
|
-
const executionOptions = resolveTailwindExecutionOptions(this.options, this.majorVersion);
|
|
2294
|
-
const buildOptions = {
|
|
2295
|
-
cwd: executionOptions.cwd,
|
|
2296
|
-
majorVersion: this.majorVersion,
|
|
2297
|
-
...executionOptions.config === void 0 ? {} : { config: executionOptions.config },
|
|
2298
|
-
...executionOptions.postcssPlugin === void 0 ? {} : { postcssPlugin: executionOptions.postcssPlugin }
|
|
2299
|
-
};
|
|
2300
|
-
this.inFlightBuild = runTailwindBuild(buildOptions).then(() => void 0);
|
|
2301
|
-
try {
|
|
2302
|
-
await this.inFlightBuild;
|
|
2303
|
-
} finally {
|
|
2304
|
-
this.inFlightBuild = void 0;
|
|
2305
|
-
}
|
|
2306
|
-
}
|
|
2307
|
-
};
|
|
2308
|
-
var TailwindV4Collector = class extends BaseCollector {
|
|
2309
|
-
constructor(packageInfo, options, snapshotFactory) {
|
|
2310
|
-
super(packageInfo, options, 4);
|
|
2311
|
-
this.snapshotFactory = snapshotFactory;
|
|
2312
|
-
}
|
|
2313
|
-
snapshotFactory;
|
|
2314
|
-
async collectClassSet() {
|
|
2315
|
-
return collectClassesFromTailwindV4(this.options);
|
|
2316
|
-
}
|
|
2317
|
-
getPatchSnapshot() {
|
|
2318
|
-
return this.snapshotFactory();
|
|
2319
|
-
}
|
|
2320
|
-
};
|
|
2321
|
-
//#endregion
|
|
2322
|
-
//#region src/api/tailwindcss-patcher.ts
|
|
2323
|
-
function resolveInstalledMajorVersion(version) {
|
|
2324
|
-
if (!version) return;
|
|
2325
|
-
const coerced = (0, semver.coerce)(version);
|
|
2326
|
-
if (!coerced) return;
|
|
2327
|
-
const major = coerced.major;
|
|
2328
|
-
if (major === 2 || major === 3 || major === 4) return major;
|
|
2329
|
-
if (major >= 4) return 4;
|
|
2330
|
-
}
|
|
2331
|
-
function validateInstalledVersion(packageVersion, expectedMajor, packageName) {
|
|
2332
|
-
const installedMajor = resolveInstalledMajorVersion(packageVersion);
|
|
2333
|
-
if (installedMajor === void 0) return;
|
|
2334
|
-
if (installedMajor !== expectedMajor) throw new Error(`Configured tailwindcss.version=${expectedMajor}, but resolved package "${packageName}" is version ${packageVersion}. Update the configuration or resolve the correct package.`);
|
|
2335
|
-
}
|
|
2336
|
-
function resolveMajorVersionOrThrow(configuredMajor, packageVersion, packageName) {
|
|
2337
|
-
if (configuredMajor !== void 0) {
|
|
2338
|
-
validateInstalledVersion(packageVersion, configuredMajor, packageName);
|
|
2339
|
-
return configuredMajor;
|
|
2340
|
-
}
|
|
2341
|
-
const installedMajor = resolveInstalledMajorVersion(packageVersion);
|
|
2342
|
-
if (installedMajor !== void 0) return installedMajor;
|
|
2343
|
-
throw new Error(`Unable to infer Tailwind CSS major version from resolved package "${packageName}" (${packageVersion ?? "unknown"}). Set "tailwindcss.version" to 2, 3, or 4 explicitly.`);
|
|
2344
|
-
}
|
|
2345
|
-
function createCollector(packageInfo, options, majorVersion, snapshotFactory) {
|
|
2346
|
-
if (majorVersion === 4) return new TailwindV4Collector(packageInfo, options, snapshotFactory);
|
|
2347
|
-
return new RuntimeCollector(packageInfo, options, majorVersion, snapshotFactory);
|
|
2348
|
-
}
|
|
2349
|
-
function getPackageInfoFromCwd(packageName, cwd, resolvePaths = []) {
|
|
2350
|
-
try {
|
|
2351
|
-
const packageJsonPath = (0, node_module.createRequire)(pathe.default.join(cwd, "package.json")).resolve(`${packageName}/package.json`, { paths: resolvePaths });
|
|
2352
|
-
const packageJson = fs_extra.default.readJSONSync(packageJsonPath);
|
|
2353
|
-
return {
|
|
2354
|
-
name: packageName,
|
|
2355
|
-
version: typeof packageJson.version === "string" ? packageJson.version : void 0,
|
|
2356
|
-
rootPath: pathe.default.dirname(packageJsonPath),
|
|
2357
|
-
packageJsonPath,
|
|
2358
|
-
packageJson
|
|
2359
|
-
};
|
|
2360
|
-
} catch {
|
|
2361
|
-
return;
|
|
2362
|
-
}
|
|
2363
|
-
}
|
|
2364
|
-
function getTailwindPackageInfo(options) {
|
|
2365
|
-
const cwd = options.tailwind.cwd ?? options.projectRoot;
|
|
2366
|
-
return (options.tailwind.resolve?.paths?.length ? getPackageInfoFromCwd(options.tailwind.packageName, cwd, options.tailwind.resolve.paths) : void 0) ?? (0, local_pkg.getPackageInfoSync)(options.tailwind.packageName, options.tailwind.resolve);
|
|
2367
|
-
}
|
|
2368
|
-
var TailwindcssPatcher = class {
|
|
2369
|
-
options;
|
|
2370
|
-
packageInfo;
|
|
2371
|
-
majorVersion;
|
|
2372
|
-
cacheContext;
|
|
2373
|
-
cacheStore;
|
|
2374
|
-
collector;
|
|
2375
|
-
patchMemo;
|
|
2376
|
-
constructor(options = {}) {
|
|
2377
|
-
this.options = normalizeOptions(options);
|
|
2378
|
-
const packageInfo = getTailwindPackageInfo(this.options);
|
|
2379
|
-
if (!packageInfo) throw new Error(`Unable to locate Tailwind CSS package "${this.options.tailwind.packageName}".`);
|
|
2380
|
-
this.packageInfo = packageInfo;
|
|
2381
|
-
this.majorVersion = resolveMajorVersionOrThrow(this.options.tailwind.versionHint, this.packageInfo.version, this.options.tailwind.packageName);
|
|
2382
|
-
this.cacheContext = createCacheContextDescriptor(this.options, this.packageInfo, this.majorVersion);
|
|
2383
|
-
this.cacheStore = new CacheStore(this.options.cache, this.cacheContext);
|
|
2384
|
-
this.collector = createCollector(this.packageInfo, this.options, this.majorVersion, () => this.createPatchSnapshot());
|
|
2385
|
-
}
|
|
2386
|
-
async patch() {
|
|
2387
|
-
const snapshot = this.collector.getPatchSnapshot();
|
|
2388
|
-
if (this.patchMemo && this.patchMemo.snapshot === snapshot) return this.patchMemo.result;
|
|
2389
|
-
const result = await this.collector.patch();
|
|
2390
|
-
this.patchMemo = {
|
|
2391
|
-
result,
|
|
2392
|
-
snapshot: this.collector.getPatchSnapshot()
|
|
2393
|
-
};
|
|
2394
|
-
return result;
|
|
2395
|
-
}
|
|
2396
|
-
async getPatchStatus() {
|
|
2397
|
-
return this.collector.getPatchStatus();
|
|
2398
|
-
}
|
|
2399
|
-
getContexts() {
|
|
2400
|
-
return this.collector.getContexts();
|
|
2401
|
-
}
|
|
2402
|
-
createPatchSnapshot() {
|
|
2403
|
-
const entries = [];
|
|
2404
|
-
const pushSnapshot = (filePath) => {
|
|
2405
|
-
if (!fs_extra.default.pathExistsSync(filePath)) {
|
|
2406
|
-
entries.push(`${filePath}:missing`);
|
|
2407
|
-
return;
|
|
2408
|
-
}
|
|
2409
|
-
const stat = fs_extra.default.statSync(filePath);
|
|
2410
|
-
entries.push(`${filePath}:${stat.size}:${Math.trunc(stat.mtimeMs)}`);
|
|
2411
|
-
};
|
|
2412
|
-
if (this.options.features.exposeContext.enabled && (this.majorVersion === 2 || this.majorVersion === 3)) if (this.majorVersion === 2) {
|
|
2413
|
-
pushSnapshot(pathe.default.resolve(this.packageInfo.rootPath, "lib/jit/processTailwindFeatures.js"));
|
|
2414
|
-
pushSnapshot(pathe.default.resolve(this.packageInfo.rootPath, "lib/jit/index.js"));
|
|
2415
|
-
} else {
|
|
2416
|
-
pushSnapshot(pathe.default.resolve(this.packageInfo.rootPath, "lib/processTailwindFeatures.js"));
|
|
2417
|
-
const pluginPath = ["lib/plugin.js", "lib/index.js"].map((file) => pathe.default.resolve(this.packageInfo.rootPath, file)).find((file) => fs_extra.default.pathExistsSync(file));
|
|
2418
|
-
if (pluginPath) pushSnapshot(pluginPath);
|
|
2419
|
-
}
|
|
2420
|
-
if (this.options.features.extendLengthUnits?.enabled) {
|
|
2421
|
-
if (this.majorVersion === 3) {
|
|
2422
|
-
const target = this.options.features.extendLengthUnits.lengthUnitsFilePath ?? "lib/util/dataTypes.js";
|
|
2423
|
-
pushSnapshot(pathe.default.resolve(this.packageInfo.rootPath, target));
|
|
2424
|
-
} else if (this.majorVersion === 4) {
|
|
2425
|
-
const distDir = pathe.default.resolve(this.packageInfo.rootPath, "dist");
|
|
2426
|
-
if (fs_extra.default.pathExistsSync(distDir)) {
|
|
2427
|
-
const chunkNames = fs_extra.default.readdirSync(distDir).filter((entry) => entry.endsWith(".js") || entry.endsWith(".mjs")).sort();
|
|
2428
|
-
for (const chunkName of chunkNames) pushSnapshot(pathe.default.join(distDir, chunkName));
|
|
2429
|
-
} else entries.push(`${distDir}:missing`);
|
|
2430
|
-
}
|
|
2431
|
-
}
|
|
2432
|
-
return entries.join("|");
|
|
2433
|
-
}
|
|
2434
|
-
async collectClassSet() {
|
|
2435
|
-
if (this.majorVersion === 4) return this.collector.collectClassSet();
|
|
2436
|
-
return collectClassesFromContexts(this.getContexts(), this.options.filter);
|
|
2437
|
-
}
|
|
2438
|
-
async runTailwindBuildIfNeeded() {
|
|
2439
|
-
await this.collector.runTailwindBuildIfNeeded?.();
|
|
2440
|
-
}
|
|
2441
|
-
debugCacheRead(meta) {
|
|
2442
|
-
if (meta.hit) {
|
|
2443
|
-
logger.debug(`[cache] hit fingerprint=${meta.fingerprint?.slice(0, 12) ?? "n/a"} schema=${meta.schemaVersion ?? "legacy"} ${meta.details.join("; ")}`);
|
|
2444
|
-
return;
|
|
2445
|
-
}
|
|
2446
|
-
logger.debug(`[cache] miss reason=${meta.reason} fingerprint=${meta.fingerprint?.slice(0, 12) ?? "n/a"} schema=${meta.schemaVersion ?? "legacy"} ${meta.details.join("; ")}`);
|
|
2447
|
-
}
|
|
2448
|
-
async mergeWithCache(set) {
|
|
2449
|
-
if (!this.options.cache.enabled) return set;
|
|
2450
|
-
const { data: existing, meta } = await this.cacheStore.readWithMeta();
|
|
2451
|
-
this.debugCacheRead(meta);
|
|
2452
|
-
if (this.options.cache.strategy === "merge") {
|
|
2453
|
-
for (const value of existing) set.add(value);
|
|
2454
|
-
const writeTarget = this.areSetsEqual(existing, set) ? void 0 : await this.cacheStore.write(set);
|
|
2455
|
-
if (writeTarget) logger.debug(`[cache] stored ${set.size} classes -> ${writeTarget}`);
|
|
2456
|
-
} else if (set.size > 0) {
|
|
2457
|
-
const writeTarget = this.areSetsEqual(existing, set) ? void 0 : await this.cacheStore.write(set);
|
|
2458
|
-
if (writeTarget) logger.debug(`[cache] stored ${set.size} classes -> ${writeTarget}`);
|
|
2459
|
-
} else return existing;
|
|
2460
|
-
return set;
|
|
2461
|
-
}
|
|
2462
|
-
mergeWithCacheSync(set) {
|
|
2463
|
-
if (!this.options.cache.enabled) return set;
|
|
2464
|
-
const { data: existing, meta } = this.cacheStore.readWithMetaSync();
|
|
2465
|
-
this.debugCacheRead(meta);
|
|
2466
|
-
if (this.options.cache.strategy === "merge") {
|
|
2467
|
-
for (const value of existing) set.add(value);
|
|
2468
|
-
const writeTarget = this.areSetsEqual(existing, set) ? void 0 : this.cacheStore.writeSync(set);
|
|
2469
|
-
if (writeTarget) logger.debug(`[cache] stored ${set.size} classes -> ${writeTarget}`);
|
|
2470
|
-
} else if (set.size > 0) {
|
|
2471
|
-
const writeTarget = this.areSetsEqual(existing, set) ? void 0 : this.cacheStore.writeSync(set);
|
|
2472
|
-
if (writeTarget) logger.debug(`[cache] stored ${set.size} classes -> ${writeTarget}`);
|
|
2473
|
-
} else return existing;
|
|
2474
|
-
return set;
|
|
2475
|
-
}
|
|
2476
|
-
areSetsEqual(a, b) {
|
|
2477
|
-
if (a.size !== b.size) return false;
|
|
2478
|
-
for (const value of a) if (!b.has(value)) return false;
|
|
2479
|
-
return true;
|
|
2480
|
-
}
|
|
2481
|
-
async getClassSet() {
|
|
2482
|
-
await this.runTailwindBuildIfNeeded();
|
|
2483
|
-
const set = await this.collectClassSet();
|
|
2484
|
-
return this.mergeWithCache(set);
|
|
2485
|
-
}
|
|
2486
|
-
getClassSetSync() {
|
|
2487
|
-
if (this.majorVersion === 4) throw new Error("getClassSetSync is not supported for Tailwind CSS v4 projects. Use getClassSet instead.");
|
|
2488
|
-
const contexts = this.getContexts();
|
|
2489
|
-
const set = collectClassesFromContexts(contexts, this.options.filter);
|
|
2490
|
-
const merged = this.mergeWithCacheSync(set);
|
|
2491
|
-
if (contexts.length === 0 && merged.size === 0) return;
|
|
2492
|
-
return merged;
|
|
2493
|
-
}
|
|
2494
|
-
async extract(options) {
|
|
2495
|
-
const shouldWrite = options?.write ?? this.options.output.enabled;
|
|
2496
|
-
const classSet = await this.getClassSet();
|
|
2497
|
-
const classList = Array.from(classSet);
|
|
2498
|
-
const result = {
|
|
2499
|
-
classList,
|
|
2500
|
-
classSet
|
|
2501
|
-
};
|
|
2502
|
-
if (!shouldWrite || !this.options.output.file) return result;
|
|
2503
|
-
const target = pathe.default.resolve(this.options.output.file);
|
|
2504
|
-
await fs_extra.default.ensureDir(pathe.default.dirname(target));
|
|
2505
|
-
if (this.options.output.format === "json") {
|
|
2506
|
-
const spaces = typeof this.options.output.pretty === "number" ? this.options.output.pretty : void 0;
|
|
2507
|
-
await fs_extra.default.writeJSON(target, classList, { spaces });
|
|
2508
|
-
} else await fs_extra.default.writeFile(target, `${classList.join("\n")}\n`, "utf8");
|
|
2509
|
-
logger.success(`Tailwind CSS class list saved to ${target.replace(node_process.default.cwd(), ".")}`);
|
|
2510
|
-
return {
|
|
2511
|
-
...result,
|
|
2512
|
-
filename: target
|
|
2513
|
-
};
|
|
2514
|
-
}
|
|
2515
|
-
async clearCache(options) {
|
|
2516
|
-
const result = await this.cacheStore.clear(options);
|
|
2517
|
-
logger.debug(`[cache] clear scope=${result.scope} contexts=${result.contextsRemoved} entries=${result.entriesRemoved} files=${result.filesRemoved}`);
|
|
2518
|
-
return result;
|
|
2519
|
-
}
|
|
2520
|
-
extractValidCandidates = _tailwindcss_mangle_engine.extractValidCandidates;
|
|
2521
|
-
async collectContentTokens(options) {
|
|
2522
|
-
return (0, _tailwindcss_mangle_engine.extractProjectCandidatesWithPositions)({
|
|
2523
|
-
cwd: options?.cwd ?? this.options.projectRoot,
|
|
2524
|
-
sources: options?.sources ?? this.options.tailwind.v4?.sources ?? []
|
|
2525
|
-
});
|
|
2526
|
-
}
|
|
2527
|
-
async collectContentTokensByFile(options) {
|
|
2528
|
-
const collectContentOptions = {
|
|
2529
|
-
...options?.cwd === void 0 ? {} : { cwd: options.cwd },
|
|
2530
|
-
...options?.sources === void 0 ? {} : { sources: options.sources }
|
|
2531
|
-
};
|
|
2532
|
-
return (0, _tailwindcss_mangle_engine.groupTokensByFile)(await this.collectContentTokens(collectContentOptions), {
|
|
2533
|
-
...options?.key === void 0 ? {} : { key: options.key },
|
|
2534
|
-
...options?.stripAbsolutePaths === void 0 ? {} : { stripAbsolutePaths: options.stripAbsolutePaths }
|
|
2535
|
-
});
|
|
2536
|
-
}
|
|
2537
|
-
};
|
|
2538
|
-
//#endregion
|
|
2539
|
-
//#region src/commands/migration-report.ts
|
|
2540
|
-
const MIGRATION_REPORT_KIND = "tw-patch-migrate-report";
|
|
2541
|
-
const MIGRATION_REPORT_SCHEMA_VERSION = 1;
|
|
2542
|
-
function assertMigrationReportCompatibility(report, reportFile) {
|
|
2543
|
-
if (report.reportKind !== void 0 && report.reportKind !== "tw-patch-migrate-report") throw new Error(`Unsupported report kind "${report.reportKind}" in ${reportFile}.`);
|
|
2544
|
-
if (report.schemaVersion !== void 0 && (!Number.isInteger(report.schemaVersion) || report.schemaVersion > 1)) throw new Error(`Unsupported report schema version "${String(report.schemaVersion)}" in ${reportFile}. Current supported version is 1.`);
|
|
2545
|
-
}
|
|
2546
|
-
//#endregion
|
|
2547
|
-
//#region src/commands/migration-aggregation.ts
|
|
2548
|
-
function createMigrationAggregationState() {
|
|
2549
|
-
return {
|
|
2550
|
-
scannedFiles: 0,
|
|
2551
|
-
changedFiles: 0,
|
|
2552
|
-
writtenFiles: 0,
|
|
2553
|
-
backupsWritten: 0,
|
|
2554
|
-
unchangedFiles: 0,
|
|
2555
|
-
missingFiles: 0,
|
|
2556
|
-
entries: []
|
|
2557
|
-
};
|
|
2558
|
-
}
|
|
2559
|
-
function collectMigrationExecutionResult(state, result) {
|
|
2560
|
-
if (result.missing) {
|
|
2561
|
-
state.missingFiles += 1;
|
|
2562
|
-
return;
|
|
2563
|
-
}
|
|
2564
|
-
state.scannedFiles += 1;
|
|
2565
|
-
state.entries.push(result.entry);
|
|
2566
|
-
if (result.changed) {
|
|
2567
|
-
state.changedFiles += 1;
|
|
2568
|
-
if (result.wrote) state.writtenFiles += 1;
|
|
2569
|
-
if (result.backupWritten) state.backupsWritten += 1;
|
|
2570
|
-
} else state.unchangedFiles += 1;
|
|
2571
|
-
}
|
|
2572
|
-
function buildMigrationReport(state, context) {
|
|
2573
|
-
const { cwd, dryRun, rollbackOnError, backupDirectory, toolName, toolVersion, generatedAt = (/* @__PURE__ */ new Date()).toISOString() } = context;
|
|
2574
|
-
return {
|
|
2575
|
-
reportKind: MIGRATION_REPORT_KIND,
|
|
2576
|
-
schemaVersion: 1,
|
|
2577
|
-
generatedAt,
|
|
2578
|
-
tool: {
|
|
2579
|
-
name: toolName,
|
|
2580
|
-
version: toolVersion
|
|
2581
|
-
},
|
|
2582
|
-
cwd,
|
|
2583
|
-
dryRun,
|
|
2584
|
-
rollbackOnError,
|
|
2585
|
-
...backupDirectory ? { backupDirectory } : {},
|
|
2586
|
-
scannedFiles: state.scannedFiles,
|
|
2587
|
-
changedFiles: state.changedFiles,
|
|
2588
|
-
writtenFiles: state.writtenFiles,
|
|
2589
|
-
backupsWritten: state.backupsWritten,
|
|
2590
|
-
unchangedFiles: state.unchangedFiles,
|
|
2591
|
-
missingFiles: state.missingFiles,
|
|
2592
|
-
entries: state.entries
|
|
2593
|
-
};
|
|
2594
|
-
}
|
|
2595
|
-
//#endregion
|
|
2596
|
-
//#region src/commands/migration-source.ts
|
|
2597
|
-
const ROOT_LEGACY_KEYS = [
|
|
2598
|
-
"cwd",
|
|
2599
|
-
"overwrite",
|
|
2600
|
-
"tailwind",
|
|
2601
|
-
"features",
|
|
2602
|
-
"output",
|
|
2603
|
-
"applyPatches"
|
|
2604
|
-
];
|
|
2605
|
-
function getPropertyKeyName(property) {
|
|
2606
|
-
if (!property.computed && _babel_types.isIdentifier(property.key)) return property.key.name;
|
|
2607
|
-
if (_babel_types.isStringLiteral(property.key)) return property.key.value;
|
|
2608
|
-
}
|
|
2609
|
-
function findObjectProperty(objectExpression, name) {
|
|
2610
|
-
for (const property of objectExpression.properties) {
|
|
2611
|
-
if (!_babel_types.isObjectProperty(property)) continue;
|
|
2612
|
-
if (getPropertyKeyName(property) === name) return property;
|
|
2613
|
-
}
|
|
2614
|
-
}
|
|
2615
|
-
function findObjectExpressionProperty(objectExpression, name) {
|
|
2616
|
-
const property = findObjectProperty(objectExpression, name);
|
|
2617
|
-
if (!property) return;
|
|
2618
|
-
if (_babel_types.isObjectExpression(property.value)) return property.value;
|
|
2619
|
-
}
|
|
2620
|
-
function removeObjectProperty(objectExpression, property) {
|
|
2621
|
-
const index = objectExpression.properties.indexOf(property);
|
|
2622
|
-
if (index >= 0) objectExpression.properties.splice(index, 1);
|
|
2623
|
-
}
|
|
2624
|
-
function hasObjectProperty(objectExpression, name) {
|
|
2625
|
-
return findObjectProperty(objectExpression, name) !== void 0;
|
|
2626
|
-
}
|
|
2627
|
-
function keyAsIdentifier(name) {
|
|
2628
|
-
return _babel_types.identifier(name);
|
|
2629
|
-
}
|
|
2630
|
-
function mergeObjectProperties(target, source) {
|
|
2631
|
-
let changed = false;
|
|
2632
|
-
for (const sourceProperty of source.properties) {
|
|
2633
|
-
if (_babel_types.isSpreadElement(sourceProperty)) {
|
|
2634
|
-
target.properties.push(sourceProperty);
|
|
2635
|
-
changed = true;
|
|
2636
|
-
continue;
|
|
2637
|
-
}
|
|
2638
|
-
const sourceKey = getPropertyKeyName(sourceProperty);
|
|
2639
|
-
if (!sourceKey) {
|
|
2640
|
-
target.properties.push(sourceProperty);
|
|
2641
|
-
changed = true;
|
|
2642
|
-
continue;
|
|
2643
|
-
}
|
|
2644
|
-
if (hasObjectProperty(target, sourceKey)) continue;
|
|
2645
|
-
target.properties.push(sourceProperty);
|
|
2646
|
-
changed = true;
|
|
2647
|
-
}
|
|
2648
|
-
return changed;
|
|
2649
|
-
}
|
|
2650
|
-
function moveProperty(objectExpression, from, to, changes, scope) {
|
|
2651
|
-
const source = findObjectProperty(objectExpression, from);
|
|
2652
|
-
if (!source) return false;
|
|
2653
|
-
const target = findObjectProperty(objectExpression, to);
|
|
2654
|
-
if (!target) {
|
|
2655
|
-
source.key = keyAsIdentifier(to);
|
|
2656
|
-
source.computed = false;
|
|
2657
|
-
source.shorthand = false;
|
|
2658
|
-
changes.add(`${scope}.${from} -> ${scope}.${to}`);
|
|
2659
|
-
return true;
|
|
2660
|
-
}
|
|
2661
|
-
if (_babel_types.isObjectExpression(source.value) && _babel_types.isObjectExpression(target.value)) {
|
|
2662
|
-
if (mergeObjectProperties(target.value, source.value)) changes.add(`${scope}.${from} merged into ${scope}.${to}`);
|
|
2663
|
-
}
|
|
2664
|
-
removeObjectProperty(objectExpression, source);
|
|
2665
|
-
changes.add(`${scope}.${from} removed (preferred ${scope}.${to})`);
|
|
2666
|
-
return true;
|
|
2667
|
-
}
|
|
2668
|
-
function migrateExtractOptions(extract, changes, scope) {
|
|
2669
|
-
let changed = false;
|
|
2670
|
-
changed = moveProperty(extract, "enabled", "write", changes, scope) || changed;
|
|
2671
|
-
changed = moveProperty(extract, "stripUniversalSelector", "removeUniversalSelector", changes, scope) || changed;
|
|
2672
|
-
return changed;
|
|
2673
|
-
}
|
|
2674
|
-
function migrateTailwindOptions(tailwindcss, changes, scope) {
|
|
2675
|
-
let changed = false;
|
|
2676
|
-
changed = moveProperty(tailwindcss, "package", "packageName", changes, scope) || changed;
|
|
2677
|
-
changed = moveProperty(tailwindcss, "legacy", "v2", changes, scope) || changed;
|
|
2678
|
-
changed = moveProperty(tailwindcss, "classic", "v3", changes, scope) || changed;
|
|
2679
|
-
changed = moveProperty(tailwindcss, "next", "v4", changes, scope) || changed;
|
|
2680
|
-
return changed;
|
|
2681
|
-
}
|
|
2682
|
-
function migrateApplyOptions(apply, changes, scope) {
|
|
2683
|
-
return moveProperty(apply, "exportContext", "exposeContext", changes, scope);
|
|
2684
|
-
}
|
|
2685
|
-
function ensureObjectExpressionProperty(objectExpression, name, changes, scope) {
|
|
2686
|
-
const existing = findObjectProperty(objectExpression, name);
|
|
2687
|
-
if (existing) return _babel_types.isObjectExpression(existing.value) ? existing.value : void 0;
|
|
2688
|
-
const value = _babel_types.objectExpression([]);
|
|
2689
|
-
objectExpression.properties.push(_babel_types.objectProperty(keyAsIdentifier(name), value));
|
|
2690
|
-
changes.add(`${scope}.${name} created`);
|
|
2691
|
-
return value;
|
|
2692
|
-
}
|
|
2693
|
-
function moveOverwriteToApply(objectExpression, changes, scope) {
|
|
2694
|
-
const overwrite = findObjectProperty(objectExpression, "overwrite");
|
|
2695
|
-
if (!overwrite) return false;
|
|
2696
|
-
const apply = ensureObjectExpressionProperty(objectExpression, "apply", changes, scope);
|
|
2697
|
-
if (!apply) return false;
|
|
2698
|
-
if (!hasObjectProperty(apply, "overwrite")) {
|
|
2699
|
-
apply.properties.push(_babel_types.objectProperty(keyAsIdentifier("overwrite"), overwrite.value));
|
|
2700
|
-
changes.add(`${scope}.overwrite -> ${scope}.apply.overwrite`);
|
|
2701
|
-
}
|
|
2702
|
-
removeObjectProperty(objectExpression, overwrite);
|
|
2703
|
-
return true;
|
|
2704
|
-
}
|
|
2705
|
-
function hasAnyRootLegacyKeys(objectExpression) {
|
|
2706
|
-
return ROOT_LEGACY_KEYS.some((key) => hasObjectProperty(objectExpression, key));
|
|
2707
|
-
}
|
|
2708
|
-
function migrateOptionObject(objectExpression, scope, changes) {
|
|
2709
|
-
let changed = false;
|
|
2710
|
-
changed = moveProperty(objectExpression, "cwd", "projectRoot", changes, scope) || changed;
|
|
2711
|
-
changed = moveProperty(objectExpression, "tailwind", "tailwindcss", changes, scope) || changed;
|
|
2712
|
-
changed = moveProperty(objectExpression, "features", "apply", changes, scope) || changed;
|
|
2713
|
-
changed = moveProperty(objectExpression, "applyPatches", "apply", changes, scope) || changed;
|
|
2714
|
-
changed = moveProperty(objectExpression, "output", "extract", changes, scope) || changed;
|
|
2715
|
-
changed = moveOverwriteToApply(objectExpression, changes, scope) || changed;
|
|
2716
|
-
const extract = findObjectExpressionProperty(objectExpression, "extract");
|
|
2717
|
-
if (extract) changed = migrateExtractOptions(extract, changes, scope) || changed;
|
|
2718
|
-
const tailwindcss = findObjectExpressionProperty(objectExpression, "tailwindcss");
|
|
2719
|
-
if (tailwindcss) changed = migrateTailwindOptions(tailwindcss, changes, scope) || changed;
|
|
2720
|
-
const apply = findObjectExpressionProperty(objectExpression, "apply");
|
|
2721
|
-
if (apply) changed = migrateApplyOptions(apply, changes, scope) || changed;
|
|
2722
|
-
return changed;
|
|
2723
|
-
}
|
|
2724
|
-
function unwrapExpression(node) {
|
|
2725
|
-
let current = node;
|
|
2726
|
-
while (_babel_types.isTSAsExpression(current) || _babel_types.isTSSatisfiesExpression(current) || _babel_types.isTSTypeAssertion(current) || _babel_types.isParenthesizedExpression(current)) current = current.expression;
|
|
2727
|
-
return current;
|
|
2728
|
-
}
|
|
2729
|
-
function resolveObjectExpressionFromExpression(expression) {
|
|
2730
|
-
const unwrapped = unwrapExpression(expression);
|
|
2731
|
-
if (_babel_types.isObjectExpression(unwrapped)) return unwrapped;
|
|
2732
|
-
if (_babel_types.isCallExpression(unwrapped)) {
|
|
2733
|
-
const [firstArg] = unwrapped.arguments;
|
|
2734
|
-
if (!firstArg || !_babel_types.isExpression(firstArg)) return;
|
|
2735
|
-
const firstArgUnwrapped = unwrapExpression(firstArg);
|
|
2736
|
-
if (_babel_types.isObjectExpression(firstArgUnwrapped)) return firstArgUnwrapped;
|
|
2737
|
-
}
|
|
2738
|
-
}
|
|
2739
|
-
function resolveObjectExpressionFromProgram(program, name) {
|
|
2740
|
-
for (const statement of program.body) {
|
|
2741
|
-
if (!_babel_types.isVariableDeclaration(statement)) continue;
|
|
2742
|
-
for (const declaration of statement.declarations) {
|
|
2743
|
-
if (!_babel_types.isIdentifier(declaration.id) || declaration.id.name !== name || !declaration.init) continue;
|
|
2744
|
-
const objectExpression = resolveObjectExpressionFromExpression(declaration.init);
|
|
2745
|
-
if (objectExpression) return objectExpression;
|
|
2746
|
-
}
|
|
2747
|
-
}
|
|
2748
|
-
}
|
|
2749
|
-
function resolveRootConfigObjectExpression(program) {
|
|
2750
|
-
for (const statement of program.body) {
|
|
2751
|
-
if (!_babel_types.isExportDefaultDeclaration(statement)) continue;
|
|
2752
|
-
const declaration = statement.declaration;
|
|
2753
|
-
if (_babel_types.isIdentifier(declaration)) return resolveObjectExpressionFromProgram(program, declaration.name);
|
|
2754
|
-
const objectExpression = resolveObjectExpressionFromExpression(declaration);
|
|
2755
|
-
if (objectExpression) return objectExpression;
|
|
2756
|
-
}
|
|
2757
|
-
}
|
|
2758
|
-
function migrateConfigSource(source) {
|
|
2759
|
-
const ast = (0, _babel_parser.parse)(source, {
|
|
2760
|
-
sourceType: "module",
|
|
2761
|
-
plugins: ["typescript", "jsx"]
|
|
2762
|
-
});
|
|
2763
|
-
const root = resolveRootConfigObjectExpression(ast.program);
|
|
2764
|
-
if (!root) return {
|
|
2765
|
-
changed: false,
|
|
2766
|
-
code: source,
|
|
2767
|
-
changes: []
|
|
2768
|
-
};
|
|
2769
|
-
const changes = /* @__PURE__ */ new Set();
|
|
2770
|
-
let changed = false;
|
|
2771
|
-
const registry = findObjectExpressionProperty(root, "registry");
|
|
2772
|
-
if (registry) changed = migrateOptionObject(registry, "registry", changes) || changed;
|
|
2773
|
-
const patch = findObjectExpressionProperty(root, "patch");
|
|
2774
|
-
if (patch) changed = migrateOptionObject(patch, "patch", changes) || changed;
|
|
2775
|
-
if (hasAnyRootLegacyKeys(root)) changed = migrateOptionObject(root, "root", changes) || changed;
|
|
2776
|
-
if (!changed) return {
|
|
2777
|
-
changed: false,
|
|
2778
|
-
code: source,
|
|
2779
|
-
changes: []
|
|
2780
|
-
};
|
|
2781
|
-
const generated = (0, _babel_generator.default)(ast, { comments: true }).code;
|
|
2782
|
-
return {
|
|
2783
|
-
changed: true,
|
|
2784
|
-
code: source.endsWith("\n") ? `${generated}\n` : generated,
|
|
2785
|
-
changes: [...changes]
|
|
2786
|
-
};
|
|
2787
|
-
}
|
|
2788
|
-
//#endregion
|
|
2789
|
-
//#region src/commands/migration-target-files.ts
|
|
2790
|
-
const DEFAULT_CONFIG_FILENAMES = [
|
|
2791
|
-
"tailwindcss-patch.config.ts",
|
|
2792
|
-
"tailwindcss-patch.config.js",
|
|
2793
|
-
"tailwindcss-patch.config.mjs",
|
|
2794
|
-
"tailwindcss-patch.config.cjs",
|
|
2795
|
-
"tailwindcss-mangle.config.ts",
|
|
2796
|
-
"tailwindcss-mangle.config.js",
|
|
2797
|
-
"tailwindcss-mangle.config.mjs",
|
|
2798
|
-
"tailwindcss-mangle.config.cjs"
|
|
2799
|
-
];
|
|
2800
|
-
const DEFAULT_CONFIG_FILENAME_SET = new Set(DEFAULT_CONFIG_FILENAMES);
|
|
2801
|
-
const DEFAULT_WORKSPACE_IGNORED_DIRS = new Set([
|
|
2802
|
-
".git",
|
|
2803
|
-
".idea",
|
|
2804
|
-
".turbo",
|
|
2805
|
-
".vscode",
|
|
2806
|
-
".yarn",
|
|
2807
|
-
"coverage",
|
|
2808
|
-
"dist",
|
|
2809
|
-
"node_modules",
|
|
2810
|
-
"tmp"
|
|
2811
|
-
]);
|
|
2812
|
-
function resolveTargetFiles(cwd, files) {
|
|
2813
|
-
const candidates = files && files.length > 0 ? files : [...DEFAULT_CONFIG_FILENAMES];
|
|
2814
|
-
const resolved = /* @__PURE__ */ new Set();
|
|
2815
|
-
for (const file of candidates) resolved.add(pathe.default.resolve(cwd, file));
|
|
2816
|
-
return [...resolved];
|
|
2817
|
-
}
|
|
2818
|
-
async function collectWorkspaceConfigFiles(cwd, maxDepth) {
|
|
2819
|
-
const files = /* @__PURE__ */ new Set();
|
|
2820
|
-
const queue = [{
|
|
2821
|
-
dir: cwd,
|
|
2822
|
-
depth: 0
|
|
2823
|
-
}];
|
|
2824
|
-
while (queue.length > 0) {
|
|
2825
|
-
const current = queue.shift();
|
|
2826
|
-
if (!current) continue;
|
|
2827
|
-
const { dir, depth } = current;
|
|
2828
|
-
let entries;
|
|
2829
|
-
try {
|
|
2830
|
-
entries = await fs_extra.default.readdir(dir, { withFileTypes: true });
|
|
2831
|
-
} catch {
|
|
2832
|
-
continue;
|
|
2833
|
-
}
|
|
2834
|
-
for (const entry of entries) {
|
|
2835
|
-
const absolutePath = pathe.default.resolve(dir, entry.name);
|
|
2836
|
-
if (entry.isFile() && DEFAULT_CONFIG_FILENAME_SET.has(entry.name)) {
|
|
2837
|
-
files.add(absolutePath);
|
|
2838
|
-
continue;
|
|
2839
|
-
}
|
|
2840
|
-
if (!entry.isDirectory()) continue;
|
|
2841
|
-
if (DEFAULT_WORKSPACE_IGNORED_DIRS.has(entry.name)) continue;
|
|
2842
|
-
if (depth >= maxDepth) continue;
|
|
2843
|
-
queue.push({
|
|
2844
|
-
dir: absolutePath,
|
|
2845
|
-
depth: depth + 1
|
|
2846
|
-
});
|
|
2847
|
-
}
|
|
2848
|
-
}
|
|
2849
|
-
return [...files].sort((a, b) => a.localeCompare(b));
|
|
2850
|
-
}
|
|
2851
|
-
function resolveBackupRelativePath(cwd, file) {
|
|
2852
|
-
const relative = pathe.default.relative(cwd, file);
|
|
2853
|
-
if (relative.startsWith("..") || pathe.default.isAbsolute(relative)) {
|
|
2854
|
-
const sanitized = file.replace(/[:/\\]+/g, "_");
|
|
2855
|
-
return pathe.default.join("__external__", `${sanitized}.bak`);
|
|
2856
|
-
}
|
|
2857
|
-
return `${relative}.bak`;
|
|
2858
|
-
}
|
|
2859
|
-
function normalizePattern(pattern) {
|
|
2860
|
-
return pattern.replace(/\\/g, "/").replace(/^\.\/+/, "").replace(/^\/+/, "");
|
|
2861
|
-
}
|
|
2862
|
-
function globToRegExp(globPattern) {
|
|
2863
|
-
const normalized = normalizePattern(globPattern);
|
|
2864
|
-
let pattern = "";
|
|
2865
|
-
for (let i = 0; i < normalized.length; i += 1) {
|
|
2866
|
-
const char = normalized[i];
|
|
2867
|
-
if (char === "*") {
|
|
2868
|
-
if (normalized[i + 1] === "*") {
|
|
2869
|
-
pattern += ".*";
|
|
2870
|
-
i += 1;
|
|
2871
|
-
} else pattern += "[^/]*";
|
|
2872
|
-
continue;
|
|
2873
|
-
}
|
|
2874
|
-
if (char === "?") {
|
|
2875
|
-
pattern += "[^/]";
|
|
2876
|
-
continue;
|
|
2877
|
-
}
|
|
2878
|
-
if ("\\^$+?.()|{}[]".includes(char)) {
|
|
2879
|
-
pattern += `\\${char}`;
|
|
2880
|
-
continue;
|
|
2881
|
-
}
|
|
2882
|
-
pattern += char;
|
|
2883
|
-
}
|
|
2884
|
-
return new RegExp(`^${pattern}$`);
|
|
2885
|
-
}
|
|
2886
|
-
function toPatternList(patterns) {
|
|
2887
|
-
if (!patterns || patterns.length === 0) return [];
|
|
2888
|
-
return patterns.map((pattern) => pattern.trim()).filter(Boolean).map(globToRegExp);
|
|
2889
|
-
}
|
|
2890
|
-
function normalizeFileForPattern(file, cwd) {
|
|
2891
|
-
const relative = pathe.default.relative(cwd, file);
|
|
2892
|
-
if (!relative.startsWith("..") && !pathe.default.isAbsolute(relative)) return relative.replace(/\\/g, "/");
|
|
2893
|
-
return file.replace(/\\/g, "/");
|
|
2894
|
-
}
|
|
2895
|
-
function filterTargetFiles(targetFiles, cwd, include, exclude) {
|
|
2896
|
-
const includePatterns = toPatternList(include);
|
|
2897
|
-
const excludePatterns = toPatternList(exclude);
|
|
2898
|
-
if (includePatterns.length === 0 && excludePatterns.length === 0) return targetFiles;
|
|
2899
|
-
return targetFiles.filter((file) => {
|
|
2900
|
-
const normalized = normalizeFileForPattern(file, cwd);
|
|
2901
|
-
if (!(includePatterns.length === 0 || includePatterns.some((pattern) => pattern.test(normalized)))) return false;
|
|
2902
|
-
return !excludePatterns.some((pattern) => pattern.test(normalized));
|
|
2903
|
-
});
|
|
2904
|
-
}
|
|
2905
|
-
//#endregion
|
|
2906
|
-
//#region src/commands/migration-file-executor.ts
|
|
2907
|
-
async function rollbackWrittenEntries(wroteEntries) {
|
|
2908
|
-
let rollbackCount = 0;
|
|
2909
|
-
for (const written of [...wroteEntries].reverse()) try {
|
|
2910
|
-
await fs_extra.default.writeFile(written.file, written.source, "utf8");
|
|
2911
|
-
written.entry.written = false;
|
|
2912
|
-
written.entry.rolledBack = true;
|
|
2913
|
-
rollbackCount += 1;
|
|
2914
|
-
} catch {}
|
|
2915
|
-
return rollbackCount;
|
|
2916
|
-
}
|
|
2917
|
-
async function executeMigrationFile(options) {
|
|
2918
|
-
const { cwd, file, dryRun, rollbackOnError, backupDirectory, wroteEntries } = options;
|
|
2919
|
-
if (!await fs_extra.default.pathExists(file)) return {
|
|
2920
|
-
missing: true,
|
|
2921
|
-
changed: false,
|
|
2922
|
-
wrote: false,
|
|
2923
|
-
backupWritten: false
|
|
2924
|
-
};
|
|
2925
|
-
const source = await fs_extra.default.readFile(file, "utf8");
|
|
2926
|
-
const migrated = migrateConfigSource(source);
|
|
2927
|
-
const entry = {
|
|
2928
|
-
file,
|
|
2929
|
-
changed: migrated.changed,
|
|
2930
|
-
written: false,
|
|
2931
|
-
rolledBack: false,
|
|
2932
|
-
changes: migrated.changes
|
|
2933
|
-
};
|
|
2934
|
-
if (!migrated.changed || dryRun) return {
|
|
2935
|
-
missing: false,
|
|
2936
|
-
changed: migrated.changed,
|
|
2937
|
-
wrote: false,
|
|
2938
|
-
backupWritten: false,
|
|
2939
|
-
entry
|
|
2940
|
-
};
|
|
2941
|
-
let backupWritten = false;
|
|
2942
|
-
try {
|
|
2943
|
-
if (backupDirectory) {
|
|
2944
|
-
const backupRelativePath = resolveBackupRelativePath(cwd, file);
|
|
2945
|
-
const backupFile = pathe.default.resolve(backupDirectory, backupRelativePath);
|
|
2946
|
-
await fs_extra.default.ensureDir(pathe.default.dirname(backupFile));
|
|
2947
|
-
await fs_extra.default.writeFile(backupFile, source, "utf8");
|
|
2948
|
-
entry.backupFile = backupFile;
|
|
2949
|
-
backupWritten = true;
|
|
2950
|
-
}
|
|
2951
|
-
await fs_extra.default.writeFile(file, migrated.code, "utf8");
|
|
2952
|
-
entry.written = true;
|
|
2953
|
-
wroteEntries.push({
|
|
2954
|
-
file,
|
|
2955
|
-
source,
|
|
2956
|
-
entry
|
|
2957
|
-
});
|
|
2958
|
-
return {
|
|
2959
|
-
missing: false,
|
|
2960
|
-
changed: true,
|
|
2961
|
-
wrote: true,
|
|
2962
|
-
backupWritten,
|
|
2963
|
-
entry
|
|
2964
|
-
};
|
|
2965
|
-
} catch (error) {
|
|
2966
|
-
const rollbackCount = rollbackOnError && wroteEntries.length > 0 ? await rollbackWrittenEntries(wroteEntries) : 0;
|
|
2967
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
2968
|
-
const rollbackHint = rollbackOnError && rollbackCount > 0 ? ` Rolled back ${rollbackCount} previously written file(s).` : "";
|
|
2969
|
-
throw new Error(`Failed to write migrated config "${file}": ${reason}.${rollbackHint}`);
|
|
2970
|
-
}
|
|
2971
|
-
}
|
|
2972
|
-
async function restoreConfigEntries(entries, dryRun) {
|
|
2973
|
-
let scannedEntries = 0;
|
|
2974
|
-
let restorableEntries = 0;
|
|
2975
|
-
let restoredFiles = 0;
|
|
2976
|
-
let missingBackups = 0;
|
|
2977
|
-
let skippedEntries = 0;
|
|
2978
|
-
const restored = [];
|
|
2979
|
-
for (const entry of entries) {
|
|
2980
|
-
scannedEntries += 1;
|
|
2981
|
-
const targetFile = entry.file ? pathe.default.resolve(entry.file) : void 0;
|
|
2982
|
-
const backupFile = entry.backupFile ? pathe.default.resolve(entry.backupFile) : void 0;
|
|
2983
|
-
if (!targetFile || !backupFile) {
|
|
2984
|
-
skippedEntries += 1;
|
|
2985
|
-
continue;
|
|
2986
|
-
}
|
|
2987
|
-
restorableEntries += 1;
|
|
2988
|
-
if (!await fs_extra.default.pathExists(backupFile)) {
|
|
2989
|
-
missingBackups += 1;
|
|
2990
|
-
continue;
|
|
2991
|
-
}
|
|
2992
|
-
if (!dryRun) {
|
|
2993
|
-
const backupContent = await fs_extra.default.readFile(backupFile, "utf8");
|
|
2994
|
-
await fs_extra.default.ensureDir(pathe.default.dirname(targetFile));
|
|
2995
|
-
await fs_extra.default.writeFile(targetFile, backupContent, "utf8");
|
|
2996
|
-
}
|
|
2997
|
-
restoredFiles += 1;
|
|
2998
|
-
restored.push(targetFile);
|
|
2999
|
-
}
|
|
3000
|
-
return {
|
|
3001
|
-
scannedEntries,
|
|
3002
|
-
restorableEntries,
|
|
3003
|
-
restoredFiles,
|
|
3004
|
-
missingBackups,
|
|
3005
|
-
skippedEntries,
|
|
3006
|
-
restored
|
|
3007
|
-
};
|
|
3008
|
-
}
|
|
3009
|
-
//#endregion
|
|
3010
|
-
//#region src/commands/migration-report-loader.ts
|
|
3011
|
-
async function loadMigrationReportForRestore(reportFile) {
|
|
3012
|
-
const report = await fs_extra.default.readJSON(reportFile);
|
|
3013
|
-
assertMigrationReportCompatibility(report, reportFile);
|
|
3014
|
-
return {
|
|
3015
|
-
...report.reportKind === void 0 ? {} : { reportKind: report.reportKind },
|
|
3016
|
-
...report.schemaVersion === void 0 ? {} : { schemaVersion: report.schemaVersion },
|
|
3017
|
-
entries: Array.isArray(report.entries) ? report.entries : []
|
|
3018
|
-
};
|
|
3019
|
-
}
|
|
3020
|
-
//#endregion
|
|
3021
|
-
//#region src/commands/migration-target-resolver.ts
|
|
3022
|
-
async function resolveMigrationTargetFiles(options) {
|
|
3023
|
-
const { cwd, files, workspace, maxDepth, include, exclude } = options;
|
|
3024
|
-
const resolvedMaxDepth = maxDepth ?? 6;
|
|
3025
|
-
return filterTargetFiles(files && files.length > 0 ? resolveTargetFiles(cwd, files) : workspace ? await collectWorkspaceConfigFiles(cwd, resolvedMaxDepth) : resolveTargetFiles(cwd), cwd, include, exclude);
|
|
3026
|
-
}
|
|
3027
|
-
//#endregion
|
|
3028
|
-
//#region src/commands/migrate-config.ts
|
|
3029
|
-
async function migrateConfigFiles(options) {
|
|
3030
|
-
const cwd = pathe.default.resolve(options.cwd);
|
|
3031
|
-
const dryRun = options.dryRun ?? false;
|
|
3032
|
-
const rollbackOnError = options.rollbackOnError ?? true;
|
|
3033
|
-
const backupDirectory = options.backupDir ? pathe.default.resolve(cwd, options.backupDir) : void 0;
|
|
3034
|
-
const targetFiles = await resolveMigrationTargetFiles({
|
|
3035
|
-
cwd,
|
|
3036
|
-
files: options.files,
|
|
3037
|
-
workspace: options.workspace,
|
|
3038
|
-
maxDepth: options.maxDepth,
|
|
3039
|
-
include: options.include,
|
|
3040
|
-
exclude: options.exclude
|
|
3041
|
-
});
|
|
3042
|
-
const aggregation = createMigrationAggregationState();
|
|
3043
|
-
const wroteEntries = [];
|
|
3044
|
-
for (const file of targetFiles) collectMigrationExecutionResult(aggregation, await executeMigrationFile({
|
|
3045
|
-
cwd,
|
|
3046
|
-
file,
|
|
3047
|
-
dryRun,
|
|
3048
|
-
rollbackOnError,
|
|
3049
|
-
wroteEntries,
|
|
3050
|
-
...backupDirectory ? { backupDirectory } : {}
|
|
3051
|
-
}));
|
|
3052
|
-
return buildMigrationReport(aggregation, {
|
|
3053
|
-
cwd,
|
|
3054
|
-
dryRun,
|
|
3055
|
-
rollbackOnError,
|
|
3056
|
-
...backupDirectory ? { backupDirectory } : {},
|
|
3057
|
-
toolName: pkgName,
|
|
3058
|
-
toolVersion: pkgVersion
|
|
3059
|
-
});
|
|
3060
|
-
}
|
|
3061
|
-
async function restoreConfigFiles(options) {
|
|
3062
|
-
const cwd = pathe.default.resolve(options.cwd);
|
|
3063
|
-
const dryRun = options.dryRun ?? false;
|
|
3064
|
-
const strict = options.strict ?? false;
|
|
3065
|
-
const reportFile = pathe.default.resolve(cwd, options.reportFile);
|
|
3066
|
-
const report = await loadMigrationReportForRestore(reportFile);
|
|
3067
|
-
const { scannedEntries, restorableEntries, restoredFiles, missingBackups, skippedEntries, restored } = await restoreConfigEntries(report.entries, dryRun);
|
|
3068
|
-
if (strict && missingBackups > 0) throw new Error(`Restore failed: ${missingBackups} backup file(s) missing in report ${reportFile}.`);
|
|
3069
|
-
return {
|
|
3070
|
-
cwd,
|
|
3071
|
-
reportFile,
|
|
3072
|
-
...report.reportKind === void 0 ? {} : { reportKind: report.reportKind },
|
|
3073
|
-
...report.schemaVersion === void 0 ? {} : { reportSchemaVersion: report.schemaVersion },
|
|
3074
|
-
dryRun,
|
|
3075
|
-
strict,
|
|
3076
|
-
scannedEntries,
|
|
3077
|
-
restorableEntries,
|
|
3078
|
-
restoredFiles,
|
|
3079
|
-
missingBackups,
|
|
3080
|
-
skippedEntries,
|
|
3081
|
-
restored
|
|
3082
|
-
};
|
|
3083
|
-
}
|
|
3084
|
-
//#endregion
|
|
3085
|
-
//#region src/commands/types.ts
|
|
3086
|
-
const tailwindcssPatchCommands = [
|
|
3087
|
-
"install",
|
|
3088
|
-
"extract",
|
|
3089
|
-
"tokens",
|
|
3090
|
-
"init",
|
|
3091
|
-
"migrate",
|
|
3092
|
-
"restore",
|
|
3093
|
-
"validate",
|
|
3094
|
-
"status"
|
|
3095
|
-
];
|
|
3096
|
-
//#endregion
|
|
3097
|
-
//#region src/commands/validate.ts
|
|
3098
|
-
const VALIDATE_EXIT_CODES = {
|
|
3099
|
-
OK: 0,
|
|
3100
|
-
REPORT_INCOMPATIBLE: 21,
|
|
3101
|
-
MISSING_BACKUPS: 22,
|
|
3102
|
-
IO_ERROR: 23,
|
|
3103
|
-
UNKNOWN_ERROR: 24
|
|
3104
|
-
};
|
|
3105
|
-
const VALIDATE_FAILURE_REASONS = [
|
|
3106
|
-
"report-incompatible",
|
|
3107
|
-
"missing-backups",
|
|
3108
|
-
"io-error",
|
|
3109
|
-
"unknown-error"
|
|
3110
|
-
];
|
|
3111
|
-
const IO_ERROR_CODES = new Set([
|
|
3112
|
-
"ENOENT",
|
|
3113
|
-
"EACCES",
|
|
3114
|
-
"EPERM",
|
|
3115
|
-
"EISDIR",
|
|
3116
|
-
"ENOTDIR",
|
|
3117
|
-
"EMFILE",
|
|
3118
|
-
"ENFILE"
|
|
3119
|
-
]);
|
|
3120
|
-
function isNodeError(error) {
|
|
3121
|
-
return !!error && typeof error === "object" && ("code" in error || "message" in error);
|
|
3122
|
-
}
|
|
3123
|
-
function classifyValidateError(error) {
|
|
3124
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3125
|
-
if (message.startsWith("Unsupported report kind") || message.startsWith("Unsupported report schema version")) return {
|
|
3126
|
-
reason: "report-incompatible",
|
|
3127
|
-
exitCode: VALIDATE_EXIT_CODES.REPORT_INCOMPATIBLE,
|
|
3128
|
-
message
|
|
3129
|
-
};
|
|
3130
|
-
if (message.startsWith("Restore failed:")) return {
|
|
3131
|
-
reason: "missing-backups",
|
|
3132
|
-
exitCode: VALIDATE_EXIT_CODES.MISSING_BACKUPS,
|
|
3133
|
-
message
|
|
3134
|
-
};
|
|
3135
|
-
if (isNodeError(error) && typeof error.code === "string" && IO_ERROR_CODES.has(error.code)) return {
|
|
3136
|
-
reason: "io-error",
|
|
3137
|
-
exitCode: VALIDATE_EXIT_CODES.IO_ERROR,
|
|
3138
|
-
message
|
|
3139
|
-
};
|
|
3140
|
-
return {
|
|
3141
|
-
reason: "unknown-error",
|
|
3142
|
-
exitCode: VALIDATE_EXIT_CODES.UNKNOWN_ERROR,
|
|
3143
|
-
message
|
|
3144
|
-
};
|
|
3145
|
-
}
|
|
3146
|
-
var ValidateCommandError = class extends Error {
|
|
3147
|
-
reason;
|
|
3148
|
-
exitCode;
|
|
3149
|
-
constructor(summary, options) {
|
|
3150
|
-
super(summary.message, options);
|
|
3151
|
-
this.name = "ValidateCommandError";
|
|
3152
|
-
this.reason = summary.reason;
|
|
3153
|
-
this.exitCode = summary.exitCode;
|
|
3154
|
-
}
|
|
3155
|
-
};
|
|
3156
|
-
//#endregion
|
|
3157
|
-
Object.defineProperty(exports, "CacheStore", {
|
|
3158
|
-
enumerable: true,
|
|
3159
|
-
get: function() {
|
|
3160
|
-
return CacheStore;
|
|
3161
|
-
}
|
|
3162
|
-
});
|
|
3163
|
-
Object.defineProperty(exports, "MIGRATION_REPORT_KIND", {
|
|
3164
|
-
enumerable: true,
|
|
3165
|
-
get: function() {
|
|
3166
|
-
return MIGRATION_REPORT_KIND;
|
|
3167
|
-
}
|
|
3168
|
-
});
|
|
3169
|
-
Object.defineProperty(exports, "MIGRATION_REPORT_SCHEMA_VERSION", {
|
|
3170
|
-
enumerable: true,
|
|
3171
|
-
get: function() {
|
|
3172
|
-
return MIGRATION_REPORT_SCHEMA_VERSION;
|
|
3173
|
-
}
|
|
3174
|
-
});
|
|
3175
|
-
Object.defineProperty(exports, "TailwindcssPatcher", {
|
|
3176
|
-
enumerable: true,
|
|
3177
|
-
get: function() {
|
|
3178
|
-
return TailwindcssPatcher;
|
|
3179
|
-
}
|
|
3180
|
-
});
|
|
3181
|
-
Object.defineProperty(exports, "VALIDATE_EXIT_CODES", {
|
|
3182
|
-
enumerable: true,
|
|
3183
|
-
get: function() {
|
|
3184
|
-
return VALIDATE_EXIT_CODES;
|
|
3185
|
-
}
|
|
3186
|
-
});
|
|
3187
|
-
Object.defineProperty(exports, "VALIDATE_FAILURE_REASONS", {
|
|
3188
|
-
enumerable: true,
|
|
3189
|
-
get: function() {
|
|
3190
|
-
return VALIDATE_FAILURE_REASONS;
|
|
3191
|
-
}
|
|
3192
|
-
});
|
|
3193
|
-
Object.defineProperty(exports, "ValidateCommandError", {
|
|
3194
|
-
enumerable: true,
|
|
3195
|
-
get: function() {
|
|
3196
|
-
return ValidateCommandError;
|
|
3197
|
-
}
|
|
3198
|
-
});
|
|
3199
|
-
Object.defineProperty(exports, "__toESM", {
|
|
3200
|
-
enumerable: true,
|
|
3201
|
-
get: function() {
|
|
3202
|
-
return __toESM;
|
|
3203
|
-
}
|
|
3204
|
-
});
|
|
3205
|
-
Object.defineProperty(exports, "classifyValidateError", {
|
|
3206
|
-
enumerable: true,
|
|
3207
|
-
get: function() {
|
|
3208
|
-
return classifyValidateError;
|
|
3209
|
-
}
|
|
3210
|
-
});
|
|
3211
|
-
Object.defineProperty(exports, "collectClassesFromContexts", {
|
|
3212
|
-
enumerable: true,
|
|
3213
|
-
get: function() {
|
|
3214
|
-
return collectClassesFromContexts;
|
|
3215
|
-
}
|
|
3216
|
-
});
|
|
3217
|
-
Object.defineProperty(exports, "collectClassesFromTailwindV4", {
|
|
3218
|
-
enumerable: true,
|
|
3219
|
-
get: function() {
|
|
3220
|
-
return collectClassesFromTailwindV4;
|
|
3221
|
-
}
|
|
3222
|
-
});
|
|
3223
|
-
Object.defineProperty(exports, "getPatchStatusReport", {
|
|
3224
|
-
enumerable: true,
|
|
3225
|
-
get: function() {
|
|
3226
|
-
return getPatchStatusReport;
|
|
3227
|
-
}
|
|
3228
|
-
});
|
|
3229
|
-
Object.defineProperty(exports, "loadPatchOptionsForWorkspace", {
|
|
3230
|
-
enumerable: true,
|
|
3231
|
-
get: function() {
|
|
3232
|
-
return loadPatchOptionsForWorkspace;
|
|
3233
|
-
}
|
|
3234
|
-
});
|
|
3235
|
-
Object.defineProperty(exports, "loadRuntimeContexts", {
|
|
3236
|
-
enumerable: true,
|
|
3237
|
-
get: function() {
|
|
3238
|
-
return loadRuntimeContexts;
|
|
3239
|
-
}
|
|
3240
|
-
});
|
|
3241
|
-
Object.defineProperty(exports, "loadWorkspaceConfigModule", {
|
|
3242
|
-
enumerable: true,
|
|
3243
|
-
get: function() {
|
|
3244
|
-
return loadWorkspaceConfigModule;
|
|
3245
|
-
}
|
|
3246
|
-
});
|
|
3247
|
-
Object.defineProperty(exports, "logger", {
|
|
3248
|
-
enumerable: true,
|
|
3249
|
-
get: function() {
|
|
3250
|
-
return logger;
|
|
3251
|
-
}
|
|
3252
|
-
});
|
|
3253
|
-
Object.defineProperty(exports, "migrateConfigFiles", {
|
|
3254
|
-
enumerable: true,
|
|
3255
|
-
get: function() {
|
|
3256
|
-
return migrateConfigFiles;
|
|
3257
|
-
}
|
|
3258
|
-
});
|
|
3259
|
-
Object.defineProperty(exports, "normalizeOptions", {
|
|
3260
|
-
enumerable: true,
|
|
3261
|
-
get: function() {
|
|
3262
|
-
return normalizeOptions;
|
|
3263
|
-
}
|
|
3264
|
-
});
|
|
3265
|
-
Object.defineProperty(exports, "restoreConfigFiles", {
|
|
3266
|
-
enumerable: true,
|
|
3267
|
-
get: function() {
|
|
3268
|
-
return restoreConfigFiles;
|
|
3269
|
-
}
|
|
3270
|
-
});
|
|
3271
|
-
Object.defineProperty(exports, "runTailwindBuild", {
|
|
3272
|
-
enumerable: true,
|
|
3273
|
-
get: function() {
|
|
3274
|
-
return runTailwindBuild;
|
|
3275
|
-
}
|
|
3276
|
-
});
|
|
3277
|
-
Object.defineProperty(exports, "tailwindcssPatchCommands", {
|
|
3278
|
-
enumerable: true,
|
|
3279
|
-
get: function() {
|
|
3280
|
-
return tailwindcssPatchCommands;
|
|
3281
|
-
}
|
|
3282
|
-
});
|