tailwindcss-patch 7.1.6 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -73
- package/dist/chunk-F3S7POWF.js +1389 -0
- package/dist/chunk-IQ26TKX2.mjs +1385 -0
- package/dist/cli.js +131 -38
- package/dist/cli.mjs +132 -38
- package/dist/index.d.mts +243 -87
- package/dist/index.d.ts +243 -87
- package/dist/index.js +6 -2
- package/dist/index.mjs +19 -15
- package/package.json +19 -19
- package/dist/chunk-NS2I2YPX.mjs +0 -1102
- package/dist/chunk-ZKCG5Q25.js +0 -1107
|
@@ -0,0 +1,1385 @@
|
|
|
1
|
+
// src/logger.ts
|
|
2
|
+
import { createConsola } from "consola";
|
|
3
|
+
var logger = createConsola();
|
|
4
|
+
var logger_default = logger;
|
|
5
|
+
|
|
6
|
+
// src/cache/store.ts
|
|
7
|
+
import fs from "fs-extra";
|
|
8
|
+
var CacheStore = class {
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
async ensureDir() {
|
|
13
|
+
await fs.ensureDir(this.options.dir);
|
|
14
|
+
}
|
|
15
|
+
ensureDirSync() {
|
|
16
|
+
fs.ensureDirSync(this.options.dir);
|
|
17
|
+
}
|
|
18
|
+
async write(data) {
|
|
19
|
+
if (!this.options.enabled) {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
await this.ensureDir();
|
|
24
|
+
await fs.writeJSON(this.options.path, Array.from(data));
|
|
25
|
+
return this.options.path;
|
|
26
|
+
} catch (error) {
|
|
27
|
+
logger_default.error("Unable to persist Tailwind class cache", error);
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
writeSync(data) {
|
|
32
|
+
if (!this.options.enabled) {
|
|
33
|
+
return void 0;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
this.ensureDirSync();
|
|
37
|
+
fs.writeJSONSync(this.options.path, Array.from(data));
|
|
38
|
+
return this.options.path;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
logger_default.error("Unable to persist Tailwind class cache", error);
|
|
41
|
+
return void 0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async read() {
|
|
45
|
+
if (!this.options.enabled) {
|
|
46
|
+
return /* @__PURE__ */ new Set();
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const exists = await fs.pathExists(this.options.path);
|
|
50
|
+
if (!exists) {
|
|
51
|
+
return /* @__PURE__ */ new Set();
|
|
52
|
+
}
|
|
53
|
+
const data = await fs.readJSON(this.options.path);
|
|
54
|
+
if (Array.isArray(data)) {
|
|
55
|
+
return new Set(data.filter((item) => typeof item === "string"));
|
|
56
|
+
}
|
|
57
|
+
} catch (error) {
|
|
58
|
+
logger_default.warn("Unable to read Tailwind class cache, removing invalid file.", error);
|
|
59
|
+
try {
|
|
60
|
+
await fs.remove(this.options.path);
|
|
61
|
+
} catch (cleanupError) {
|
|
62
|
+
logger_default.error("Failed to clean up invalid cache file", cleanupError);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return /* @__PURE__ */ new Set();
|
|
66
|
+
}
|
|
67
|
+
readSync() {
|
|
68
|
+
if (!this.options.enabled) {
|
|
69
|
+
return /* @__PURE__ */ new Set();
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const exists = fs.pathExistsSync(this.options.path);
|
|
73
|
+
if (!exists) {
|
|
74
|
+
return /* @__PURE__ */ new Set();
|
|
75
|
+
}
|
|
76
|
+
const data = fs.readJSONSync(this.options.path);
|
|
77
|
+
if (Array.isArray(data)) {
|
|
78
|
+
return new Set(data.filter((item) => typeof item === "string"));
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
logger_default.warn("Unable to read Tailwind class cache, removing invalid file.", error);
|
|
82
|
+
try {
|
|
83
|
+
fs.removeSync(this.options.path);
|
|
84
|
+
} catch (cleanupError) {
|
|
85
|
+
logger_default.error("Failed to clean up invalid cache file", cleanupError);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return /* @__PURE__ */ new Set();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// src/extraction/candidate-extractor.ts
|
|
93
|
+
import process from "process";
|
|
94
|
+
async function importNode() {
|
|
95
|
+
return import("@tailwindcss/node");
|
|
96
|
+
}
|
|
97
|
+
async function importOxide() {
|
|
98
|
+
return import("@tailwindcss/oxide");
|
|
99
|
+
}
|
|
100
|
+
async function extractRawCandidatesWithPositions(content, extension = "html") {
|
|
101
|
+
const { Scanner } = await importOxide();
|
|
102
|
+
const scanner = new Scanner({});
|
|
103
|
+
const result = scanner.getCandidatesWithPositions({ content, extension });
|
|
104
|
+
return result.map(({ candidate, position }) => ({
|
|
105
|
+
rawCandidate: candidate,
|
|
106
|
+
start: position,
|
|
107
|
+
end: position + candidate.length
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
async function extractRawCandidates(sources) {
|
|
111
|
+
const { Scanner } = await importOxide();
|
|
112
|
+
const scanner = new Scanner({
|
|
113
|
+
sources
|
|
114
|
+
});
|
|
115
|
+
return scanner.scan();
|
|
116
|
+
}
|
|
117
|
+
async function extractValidCandidates(options) {
|
|
118
|
+
const providedOptions = options ?? {};
|
|
119
|
+
const defaultCwd = providedOptions.cwd ?? process.cwd();
|
|
120
|
+
const base = providedOptions.base ?? defaultCwd;
|
|
121
|
+
const css = providedOptions.css ?? '@import "tailwindcss";';
|
|
122
|
+
const sources = (providedOptions.sources ?? [
|
|
123
|
+
{
|
|
124
|
+
base: defaultCwd,
|
|
125
|
+
pattern: "**/*",
|
|
126
|
+
negated: false
|
|
127
|
+
}
|
|
128
|
+
]).map((source) => ({
|
|
129
|
+
base: source.base ?? defaultCwd,
|
|
130
|
+
pattern: source.pattern,
|
|
131
|
+
negated: source.negated
|
|
132
|
+
}));
|
|
133
|
+
const { __unstable__loadDesignSystem } = await importNode();
|
|
134
|
+
const designSystem = await __unstable__loadDesignSystem(css, { base });
|
|
135
|
+
const candidates = await extractRawCandidates(sources);
|
|
136
|
+
const validCandidates = candidates.filter(
|
|
137
|
+
(rawCandidate) => designSystem.parseCandidate(rawCandidate).length > 0
|
|
138
|
+
);
|
|
139
|
+
return validCandidates;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/options/legacy.ts
|
|
143
|
+
function normalizeLegacyFeatures(patch) {
|
|
144
|
+
const apply = patch?.applyPatches;
|
|
145
|
+
const extend = apply?.extendLengthUnits;
|
|
146
|
+
let extendOption = false;
|
|
147
|
+
if (extend && typeof extend === "object") {
|
|
148
|
+
extendOption = {
|
|
149
|
+
...extend,
|
|
150
|
+
enabled: true
|
|
151
|
+
};
|
|
152
|
+
} else if (extend === true) {
|
|
153
|
+
extendOption = {
|
|
154
|
+
enabled: true,
|
|
155
|
+
units: ["rpx"],
|
|
156
|
+
overwrite: patch?.overwrite
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
exposeContext: apply?.exportContext ?? true,
|
|
161
|
+
extendLengthUnits: extendOption
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function fromLegacyOptions(options) {
|
|
165
|
+
if (!options) {
|
|
166
|
+
return {};
|
|
167
|
+
}
|
|
168
|
+
const patch = options.patch;
|
|
169
|
+
const features = normalizeLegacyFeatures(patch);
|
|
170
|
+
const output = patch?.output;
|
|
171
|
+
const tailwindConfig = patch?.tailwindcss;
|
|
172
|
+
const tailwindVersion = tailwindConfig?.version;
|
|
173
|
+
const tailwindV2 = tailwindConfig?.v2;
|
|
174
|
+
const tailwindV3 = tailwindConfig?.v3;
|
|
175
|
+
const tailwindV4 = tailwindConfig?.v4;
|
|
176
|
+
const tailwindConfigPath = tailwindV3?.config ?? tailwindV2?.config;
|
|
177
|
+
const tailwindCwd = tailwindV3?.cwd ?? tailwindV2?.cwd ?? patch?.cwd;
|
|
178
|
+
return {
|
|
179
|
+
cwd: patch?.cwd,
|
|
180
|
+
overwrite: patch?.overwrite,
|
|
181
|
+
filter: patch?.filter,
|
|
182
|
+
cache: typeof options.cache === "boolean" ? options.cache : options.cache ? {
|
|
183
|
+
...options.cache,
|
|
184
|
+
enabled: options.cache.enabled ?? true
|
|
185
|
+
} : void 0,
|
|
186
|
+
output: output ? {
|
|
187
|
+
file: output.filename,
|
|
188
|
+
pretty: output.loose ? 2 : false,
|
|
189
|
+
removeUniversalSelector: output.removeUniversalSelector
|
|
190
|
+
} : void 0,
|
|
191
|
+
tailwind: {
|
|
192
|
+
packageName: patch?.packageName,
|
|
193
|
+
version: tailwindVersion,
|
|
194
|
+
resolve: patch?.resolve,
|
|
195
|
+
config: tailwindConfigPath,
|
|
196
|
+
cwd: tailwindCwd,
|
|
197
|
+
v2: tailwindV2,
|
|
198
|
+
v3: tailwindV3,
|
|
199
|
+
v4: tailwindV4
|
|
200
|
+
},
|
|
201
|
+
features: {
|
|
202
|
+
exposeContext: features.exposeContext,
|
|
203
|
+
extendLengthUnits: features.extendLengthUnits
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function fromUnifiedConfig(registry) {
|
|
208
|
+
if (!registry) {
|
|
209
|
+
return {};
|
|
210
|
+
}
|
|
211
|
+
const tailwind = registry.tailwind;
|
|
212
|
+
const output = registry.output;
|
|
213
|
+
const pretty = (() => {
|
|
214
|
+
if (output?.pretty === void 0) {
|
|
215
|
+
return void 0;
|
|
216
|
+
}
|
|
217
|
+
if (typeof output.pretty === "boolean") {
|
|
218
|
+
return output.pretty ? 2 : false;
|
|
219
|
+
}
|
|
220
|
+
return output.pretty;
|
|
221
|
+
})();
|
|
222
|
+
return {
|
|
223
|
+
output: output ? {
|
|
224
|
+
file: output.file,
|
|
225
|
+
pretty,
|
|
226
|
+
removeUniversalSelector: output.stripUniversalSelector
|
|
227
|
+
} : void 0,
|
|
228
|
+
tailwind: tailwind ? {
|
|
229
|
+
version: tailwind.version,
|
|
230
|
+
packageName: tailwind.package,
|
|
231
|
+
resolve: tailwind.resolve,
|
|
232
|
+
config: tailwind.config,
|
|
233
|
+
cwd: tailwind.cwd,
|
|
234
|
+
v2: tailwind.legacy,
|
|
235
|
+
v3: tailwind.classic,
|
|
236
|
+
v4: tailwind.next
|
|
237
|
+
} : void 0
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/options/normalize.ts
|
|
242
|
+
import process2 from "process";
|
|
243
|
+
import path from "pathe";
|
|
244
|
+
|
|
245
|
+
// src/constants.ts
|
|
246
|
+
var pkgName = "tailwindcss-patch";
|
|
247
|
+
|
|
248
|
+
// src/options/normalize.ts
|
|
249
|
+
function toPrettyValue(value) {
|
|
250
|
+
if (typeof value === "number") {
|
|
251
|
+
return value > 0 ? value : false;
|
|
252
|
+
}
|
|
253
|
+
if (value === true) {
|
|
254
|
+
return 2;
|
|
255
|
+
}
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
function normalizeCacheOptions(cache, projectRoot) {
|
|
259
|
+
let enabled = false;
|
|
260
|
+
let cwd = projectRoot;
|
|
261
|
+
let dir = path.resolve(cwd, "node_modules/.cache", pkgName);
|
|
262
|
+
let file = "class-cache.json";
|
|
263
|
+
let strategy = "merge";
|
|
264
|
+
if (typeof cache === "boolean") {
|
|
265
|
+
enabled = cache;
|
|
266
|
+
} else if (typeof cache === "object" && cache) {
|
|
267
|
+
enabled = cache.enabled ?? true;
|
|
268
|
+
cwd = cache.cwd ?? cwd;
|
|
269
|
+
dir = cache.dir ? path.resolve(cache.dir) : path.resolve(cwd, "node_modules/.cache", pkgName);
|
|
270
|
+
file = cache.file ?? file;
|
|
271
|
+
strategy = cache.strategy ?? strategy;
|
|
272
|
+
}
|
|
273
|
+
const filename = path.resolve(dir, file);
|
|
274
|
+
return {
|
|
275
|
+
enabled,
|
|
276
|
+
cwd,
|
|
277
|
+
dir,
|
|
278
|
+
file,
|
|
279
|
+
path: filename,
|
|
280
|
+
strategy
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function normalizeOutputOptions(output) {
|
|
284
|
+
const enabled = output?.enabled ?? true;
|
|
285
|
+
const file = output?.file ?? ".tw-patch/tw-class-list.json";
|
|
286
|
+
const format = output?.format ?? "json";
|
|
287
|
+
const pretty = toPrettyValue(output?.pretty ?? true);
|
|
288
|
+
const removeUniversalSelector = output?.removeUniversalSelector ?? true;
|
|
289
|
+
return {
|
|
290
|
+
enabled,
|
|
291
|
+
file,
|
|
292
|
+
format,
|
|
293
|
+
pretty,
|
|
294
|
+
removeUniversalSelector
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
function normalizeExposeContextOptions(features) {
|
|
298
|
+
if (features?.exposeContext === false) {
|
|
299
|
+
return {
|
|
300
|
+
enabled: false,
|
|
301
|
+
refProperty: "contextRef"
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
if (typeof features?.exposeContext === "object" && features.exposeContext) {
|
|
305
|
+
return {
|
|
306
|
+
enabled: true,
|
|
307
|
+
refProperty: features.exposeContext.refProperty ?? "contextRef"
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
enabled: true,
|
|
312
|
+
refProperty: "contextRef"
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
function normalizeExtendLengthUnitsOptions(features) {
|
|
316
|
+
const extend = features?.extendLengthUnits;
|
|
317
|
+
if (extend === false || extend === void 0) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
if (extend.enabled === false) {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
const base = {
|
|
324
|
+
units: ["rpx"],
|
|
325
|
+
overwrite: true
|
|
326
|
+
};
|
|
327
|
+
return {
|
|
328
|
+
...base,
|
|
329
|
+
...extend,
|
|
330
|
+
enabled: extend.enabled ?? true,
|
|
331
|
+
units: extend.units ?? base.units,
|
|
332
|
+
overwrite: extend.overwrite ?? base.overwrite
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function normalizeTailwindV4Options(v4, fallbackBase) {
|
|
336
|
+
const base = v4?.base ? path.resolve(v4.base) : fallbackBase;
|
|
337
|
+
const cssEntries = Array.isArray(v4?.cssEntries) ? v4.cssEntries.filter((entry) => Boolean(entry)).map((entry) => path.resolve(entry)) : [];
|
|
338
|
+
const sources = v4?.sources?.length ? v4.sources : [
|
|
339
|
+
{
|
|
340
|
+
base,
|
|
341
|
+
pattern: "**/*",
|
|
342
|
+
negated: false
|
|
343
|
+
}
|
|
344
|
+
];
|
|
345
|
+
return {
|
|
346
|
+
base,
|
|
347
|
+
css: v4?.css,
|
|
348
|
+
cssEntries,
|
|
349
|
+
sources
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function normalizeTailwindOptions(tailwind, projectRoot) {
|
|
353
|
+
const packageName = tailwind?.packageName ?? "tailwindcss";
|
|
354
|
+
const versionHint = tailwind?.version;
|
|
355
|
+
const resolve = tailwind?.resolve;
|
|
356
|
+
const cwd = tailwind?.cwd ?? projectRoot;
|
|
357
|
+
const config = tailwind?.config;
|
|
358
|
+
const postcssPlugin = tailwind?.postcssPlugin;
|
|
359
|
+
const v4 = normalizeTailwindV4Options(tailwind?.v4, cwd);
|
|
360
|
+
return {
|
|
361
|
+
packageName,
|
|
362
|
+
versionHint,
|
|
363
|
+
resolve,
|
|
364
|
+
cwd,
|
|
365
|
+
config,
|
|
366
|
+
postcssPlugin,
|
|
367
|
+
v2: tailwind?.v2,
|
|
368
|
+
v3: tailwind?.v3,
|
|
369
|
+
v4
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
function normalizeOptions(options = {}) {
|
|
373
|
+
const projectRoot = options.cwd ? path.resolve(options.cwd) : process2.cwd();
|
|
374
|
+
const overwrite = options.overwrite ?? true;
|
|
375
|
+
const output = normalizeOutputOptions(options.output);
|
|
376
|
+
const cache = normalizeCacheOptions(options.cache, projectRoot);
|
|
377
|
+
const tailwind = normalizeTailwindOptions(options.tailwind, projectRoot);
|
|
378
|
+
const exposeContext = normalizeExposeContextOptions(options.features);
|
|
379
|
+
const extendLengthUnits = normalizeExtendLengthUnitsOptions(options.features);
|
|
380
|
+
const filter = (className) => {
|
|
381
|
+
if (output.removeUniversalSelector && className === "*") {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
if (typeof options.filter === "function") {
|
|
385
|
+
return options.filter(className) !== false;
|
|
386
|
+
}
|
|
387
|
+
return true;
|
|
388
|
+
};
|
|
389
|
+
return {
|
|
390
|
+
projectRoot,
|
|
391
|
+
overwrite,
|
|
392
|
+
tailwind,
|
|
393
|
+
features: {
|
|
394
|
+
exposeContext,
|
|
395
|
+
extendLengthUnits
|
|
396
|
+
},
|
|
397
|
+
output,
|
|
398
|
+
cache,
|
|
399
|
+
filter
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// src/runtime/class-collector.ts
|
|
404
|
+
import process3 from "process";
|
|
405
|
+
import fs2 from "fs-extra";
|
|
406
|
+
import path2 from "pathe";
|
|
407
|
+
|
|
408
|
+
// src/utils.ts
|
|
409
|
+
function isObject(val) {
|
|
410
|
+
return val !== null && typeof val === "object" && Array.isArray(val) === false;
|
|
411
|
+
}
|
|
412
|
+
function spliceChangesIntoString(str, changes) {
|
|
413
|
+
if (!changes[0]) {
|
|
414
|
+
return str;
|
|
415
|
+
}
|
|
416
|
+
changes.sort((a, b) => {
|
|
417
|
+
return a.end - b.end || a.start - b.start;
|
|
418
|
+
});
|
|
419
|
+
let result = "";
|
|
420
|
+
let previous = changes[0];
|
|
421
|
+
result += str.slice(0, previous.start);
|
|
422
|
+
result += previous.replacement;
|
|
423
|
+
for (let i = 1; i < changes.length; ++i) {
|
|
424
|
+
const change = changes[i];
|
|
425
|
+
result += str.slice(previous.end, change.start);
|
|
426
|
+
result += change.replacement;
|
|
427
|
+
previous = change;
|
|
428
|
+
}
|
|
429
|
+
result += str.slice(previous.end);
|
|
430
|
+
return result;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// src/runtime/class-collector.ts
|
|
434
|
+
function collectClassesFromContexts(contexts, filter) {
|
|
435
|
+
const set = /* @__PURE__ */ new Set();
|
|
436
|
+
for (const context of contexts) {
|
|
437
|
+
if (!isObject(context) || !context.classCache) {
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
for (const key of context.classCache.keys()) {
|
|
441
|
+
const className = key.toString();
|
|
442
|
+
if (filter(className)) {
|
|
443
|
+
set.add(className);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return set;
|
|
448
|
+
}
|
|
449
|
+
async function collectClassesFromTailwindV4(options) {
|
|
450
|
+
const set = /* @__PURE__ */ new Set();
|
|
451
|
+
const v4Options = options.tailwind.v4;
|
|
452
|
+
if (!v4Options) {
|
|
453
|
+
return set;
|
|
454
|
+
}
|
|
455
|
+
const sources = v4Options.sources?.map((source) => {
|
|
456
|
+
return {
|
|
457
|
+
base: source.base ?? v4Options.base ?? process3.cwd(),
|
|
458
|
+
pattern: source.pattern,
|
|
459
|
+
negated: source.negated
|
|
460
|
+
};
|
|
461
|
+
});
|
|
462
|
+
if (v4Options.cssEntries.length > 0) {
|
|
463
|
+
for (const entry of v4Options.cssEntries) {
|
|
464
|
+
const filePath = path2.isAbsolute(entry) ? entry : path2.resolve(options.projectRoot, entry);
|
|
465
|
+
if (!await fs2.pathExists(filePath)) {
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
const css = await fs2.readFile(filePath, "utf8");
|
|
469
|
+
const candidates = await extractValidCandidates({
|
|
470
|
+
cwd: options.projectRoot,
|
|
471
|
+
base: v4Options.base,
|
|
472
|
+
css,
|
|
473
|
+
sources
|
|
474
|
+
});
|
|
475
|
+
for (const candidate of candidates) {
|
|
476
|
+
if (options.filter(candidate)) {
|
|
477
|
+
set.add(candidate);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
} else {
|
|
482
|
+
const candidates = await extractValidCandidates({
|
|
483
|
+
cwd: options.projectRoot,
|
|
484
|
+
base: v4Options.base,
|
|
485
|
+
css: v4Options.css,
|
|
486
|
+
sources
|
|
487
|
+
});
|
|
488
|
+
for (const candidate of candidates) {
|
|
489
|
+
if (options.filter(candidate)) {
|
|
490
|
+
set.add(candidate);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return set;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// src/runtime/context-registry.ts
|
|
498
|
+
import { createRequire } from "module";
|
|
499
|
+
import fs3 from "fs-extra";
|
|
500
|
+
import path3 from "pathe";
|
|
501
|
+
var require2 = createRequire(import.meta.url);
|
|
502
|
+
function resolveRuntimeEntry(packageInfo, majorVersion) {
|
|
503
|
+
const root = packageInfo.rootPath;
|
|
504
|
+
if (majorVersion === 2) {
|
|
505
|
+
const jitIndex = path3.join(root, "lib/jit/index.js");
|
|
506
|
+
if (fs3.existsSync(jitIndex)) {
|
|
507
|
+
return jitIndex;
|
|
508
|
+
}
|
|
509
|
+
} else if (majorVersion === 3) {
|
|
510
|
+
const plugin = path3.join(root, "lib/plugin.js");
|
|
511
|
+
const index = path3.join(root, "lib/index.js");
|
|
512
|
+
if (fs3.existsSync(plugin)) {
|
|
513
|
+
return plugin;
|
|
514
|
+
}
|
|
515
|
+
if (fs3.existsSync(index)) {
|
|
516
|
+
return index;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return void 0;
|
|
520
|
+
}
|
|
521
|
+
function loadRuntimeContexts(packageInfo, majorVersion, refProperty) {
|
|
522
|
+
if (majorVersion === 4) {
|
|
523
|
+
return [];
|
|
524
|
+
}
|
|
525
|
+
const entry = resolveRuntimeEntry(packageInfo, majorVersion);
|
|
526
|
+
if (!entry) {
|
|
527
|
+
return [];
|
|
528
|
+
}
|
|
529
|
+
const moduleExports = require2(entry);
|
|
530
|
+
if (!moduleExports) {
|
|
531
|
+
return [];
|
|
532
|
+
}
|
|
533
|
+
const ref = moduleExports[refProperty];
|
|
534
|
+
if (!ref) {
|
|
535
|
+
return [];
|
|
536
|
+
}
|
|
537
|
+
if (Array.isArray(ref)) {
|
|
538
|
+
return ref;
|
|
539
|
+
}
|
|
540
|
+
if (typeof ref === "object" && Array.isArray(ref.value)) {
|
|
541
|
+
return ref.value;
|
|
542
|
+
}
|
|
543
|
+
return [];
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// src/runtime/process-tailwindcss.ts
|
|
547
|
+
import { createRequire as createRequire2 } from "module";
|
|
548
|
+
import path4 from "pathe";
|
|
549
|
+
import postcss from "postcss";
|
|
550
|
+
import { loadConfig } from "tailwindcss-config";
|
|
551
|
+
var require3 = createRequire2(import.meta.url);
|
|
552
|
+
async function resolveConfigPath(options) {
|
|
553
|
+
if (options.config && path4.isAbsolute(options.config)) {
|
|
554
|
+
return options.config;
|
|
555
|
+
}
|
|
556
|
+
const result = await loadConfig({ cwd: options.cwd });
|
|
557
|
+
if (!result) {
|
|
558
|
+
throw new Error(`Unable to locate Tailwind CSS config from ${options.cwd}`);
|
|
559
|
+
}
|
|
560
|
+
return result.filepath;
|
|
561
|
+
}
|
|
562
|
+
async function runTailwindBuild(options) {
|
|
563
|
+
const configPath = await resolveConfigPath(options);
|
|
564
|
+
const pluginName = options.postcssPlugin ?? (options.majorVersion === 4 ? "@tailwindcss/postcss" : "tailwindcss");
|
|
565
|
+
if (options.majorVersion === 4) {
|
|
566
|
+
return postcss([
|
|
567
|
+
require3(pluginName)({
|
|
568
|
+
config: configPath
|
|
569
|
+
})
|
|
570
|
+
]).process("@import 'tailwindcss';", {
|
|
571
|
+
from: void 0
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
return postcss([
|
|
575
|
+
require3(pluginName)({
|
|
576
|
+
config: configPath
|
|
577
|
+
})
|
|
578
|
+
]).process("@tailwind base;@tailwind components;@tailwind utilities;", {
|
|
579
|
+
from: void 0
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// src/api/tailwindcss-patcher.ts
|
|
584
|
+
import process4 from "process";
|
|
585
|
+
import fs6 from "fs-extra";
|
|
586
|
+
import { getPackageInfoSync } from "local-pkg";
|
|
587
|
+
import path7 from "pathe";
|
|
588
|
+
import { coerce } from "semver";
|
|
589
|
+
|
|
590
|
+
// src/patching/operations/export-context/index.ts
|
|
591
|
+
import fs4 from "fs-extra";
|
|
592
|
+
import path5 from "pathe";
|
|
593
|
+
|
|
594
|
+
// src/patching/operations/export-context/postcss-v2.ts
|
|
595
|
+
import * as t from "@babel/types";
|
|
596
|
+
|
|
597
|
+
// src/babel/index.ts
|
|
598
|
+
import _babelGenerate from "@babel/generator";
|
|
599
|
+
import _babelTraverse from "@babel/traverse";
|
|
600
|
+
import { parse, parseExpression } from "@babel/parser";
|
|
601
|
+
function _interopDefaultCompat(e) {
|
|
602
|
+
return e && typeof e === "object" && "default" in e ? e.default : e;
|
|
603
|
+
}
|
|
604
|
+
var generate = _interopDefaultCompat(_babelGenerate);
|
|
605
|
+
var traverse = _interopDefaultCompat(_babelTraverse);
|
|
606
|
+
|
|
607
|
+
// src/patching/operations/export-context/postcss-v2.ts
|
|
608
|
+
var IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
|
|
609
|
+
function toIdentifierName(property) {
|
|
610
|
+
if (!property) {
|
|
611
|
+
return "contextRef";
|
|
612
|
+
}
|
|
613
|
+
const sanitized = property.replace(/[^\w$]/gu, "_");
|
|
614
|
+
if (/^\d/.test(sanitized)) {
|
|
615
|
+
return `_${sanitized}`;
|
|
616
|
+
}
|
|
617
|
+
return sanitized || "contextRef";
|
|
618
|
+
}
|
|
619
|
+
function createExportsMember(property) {
|
|
620
|
+
if (IDENTIFIER_RE.test(property)) {
|
|
621
|
+
return t.memberExpression(t.identifier("exports"), t.identifier(property));
|
|
622
|
+
}
|
|
623
|
+
return t.memberExpression(t.identifier("exports"), t.stringLiteral(property), true);
|
|
624
|
+
}
|
|
625
|
+
function transformProcessTailwindFeaturesReturnContextV2(content) {
|
|
626
|
+
const ast = parse(content, {
|
|
627
|
+
sourceType: "unambiguous"
|
|
628
|
+
});
|
|
629
|
+
let hasPatched = false;
|
|
630
|
+
traverse(ast, {
|
|
631
|
+
FunctionDeclaration(path8) {
|
|
632
|
+
const node = path8.node;
|
|
633
|
+
if (node.id?.name !== "processTailwindFeatures" || node.body.body.length !== 1 || !t.isReturnStatement(node.body.body[0])) {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
const returnStatement3 = node.body.body[0];
|
|
637
|
+
if (!t.isFunctionExpression(returnStatement3.argument)) {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
const body = returnStatement3.argument.body.body;
|
|
641
|
+
const lastStatement = body[body.length - 1];
|
|
642
|
+
const alreadyReturnsContext = Boolean(
|
|
643
|
+
t.isReturnStatement(lastStatement) && t.isIdentifier(lastStatement.argument) && lastStatement.argument.name === "context"
|
|
644
|
+
);
|
|
645
|
+
hasPatched = alreadyReturnsContext;
|
|
646
|
+
if (!alreadyReturnsContext) {
|
|
647
|
+
body.push(t.returnStatement(t.identifier("context")));
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
return {
|
|
652
|
+
code: hasPatched ? content : generate(ast).code,
|
|
653
|
+
hasPatched
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
function transformPostcssPluginV2(content, options) {
|
|
657
|
+
const refIdentifier = t.identifier(toIdentifierName(options.refProperty));
|
|
658
|
+
const exportMember = createExportsMember(options.refProperty);
|
|
659
|
+
const valueMember = t.memberExpression(refIdentifier, t.identifier("value"));
|
|
660
|
+
const ast = parse(content);
|
|
661
|
+
let hasPatched = false;
|
|
662
|
+
traverse(ast, {
|
|
663
|
+
Program(path8) {
|
|
664
|
+
const program = path8.node;
|
|
665
|
+
const index = program.body.findIndex((statement) => {
|
|
666
|
+
return t.isFunctionDeclaration(statement) && statement.id?.name === "_default";
|
|
667
|
+
});
|
|
668
|
+
if (index === -1) {
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
const previous = program.body[index - 1];
|
|
672
|
+
const beforePrevious = program.body[index - 2];
|
|
673
|
+
const alreadyHasVariable = Boolean(
|
|
674
|
+
previous && t.isVariableDeclaration(previous) && previous.declarations.length === 1 && t.isIdentifier(previous.declarations[0].id) && previous.declarations[0].id.name === refIdentifier.name
|
|
675
|
+
);
|
|
676
|
+
const alreadyAssignsExports = Boolean(
|
|
677
|
+
beforePrevious && t.isExpressionStatement(beforePrevious) && t.isAssignmentExpression(beforePrevious.expression) && t.isMemberExpression(beforePrevious.expression.left) && t.isIdentifier(beforePrevious.expression.right) && beforePrevious.expression.right.name === refIdentifier.name && generate(beforePrevious.expression.left).code === generate(exportMember).code
|
|
678
|
+
);
|
|
679
|
+
hasPatched = alreadyHasVariable && alreadyAssignsExports;
|
|
680
|
+
if (!alreadyHasVariable) {
|
|
681
|
+
program.body.splice(
|
|
682
|
+
index,
|
|
683
|
+
0,
|
|
684
|
+
t.variableDeclaration("var", [
|
|
685
|
+
t.variableDeclarator(
|
|
686
|
+
refIdentifier,
|
|
687
|
+
t.objectExpression([
|
|
688
|
+
t.objectProperty(t.identifier("value"), t.arrayExpression())
|
|
689
|
+
])
|
|
690
|
+
)
|
|
691
|
+
]),
|
|
692
|
+
t.expressionStatement(
|
|
693
|
+
t.assignmentExpression("=", exportMember, refIdentifier)
|
|
694
|
+
)
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
},
|
|
698
|
+
FunctionDeclaration(path8) {
|
|
699
|
+
if (hasPatched) {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
const fn = path8.node;
|
|
703
|
+
if (fn.id?.name !== "_default") {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
if (fn.body.body.length !== 1 || !t.isReturnStatement(fn.body.body[0])) {
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
const returnStatement3 = fn.body.body[0];
|
|
710
|
+
if (!t.isCallExpression(returnStatement3.argument) || !t.isMemberExpression(returnStatement3.argument.callee) || !t.isArrayExpression(returnStatement3.argument.callee.object)) {
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
const fnExpression = returnStatement3.argument.callee.object.elements[1];
|
|
714
|
+
if (!fnExpression || !t.isFunctionExpression(fnExpression)) {
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
const block = fnExpression.body;
|
|
718
|
+
const statements = block.body;
|
|
719
|
+
if (t.isExpressionStatement(statements[0]) && t.isAssignmentExpression(statements[0].expression) && t.isNumericLiteral(statements[0].expression.right)) {
|
|
720
|
+
hasPatched = true;
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
const lastStatement = statements[statements.length - 1];
|
|
724
|
+
if (lastStatement && t.isExpressionStatement(lastStatement)) {
|
|
725
|
+
statements[statements.length - 1] = t.expressionStatement(
|
|
726
|
+
t.callExpression(
|
|
727
|
+
t.memberExpression(valueMember, t.identifier("push")),
|
|
728
|
+
[lastStatement.expression]
|
|
729
|
+
)
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
const index = statements.findIndex((statement) => t.isIfStatement(statement));
|
|
733
|
+
if (index > -1) {
|
|
734
|
+
const ifStatement = statements[index];
|
|
735
|
+
if (t.isBlockStatement(ifStatement.consequent) && ifStatement.consequent.body[1] && t.isForOfStatement(ifStatement.consequent.body[1])) {
|
|
736
|
+
const forOf = ifStatement.consequent.body[1];
|
|
737
|
+
if (t.isBlockStatement(forOf.body) && forOf.body.body.length === 1) {
|
|
738
|
+
const nestedIf = forOf.body.body[0];
|
|
739
|
+
if (nestedIf && t.isIfStatement(nestedIf) && t.isBlockStatement(nestedIf.consequent) && nestedIf.consequent.body.length === 1 && t.isExpressionStatement(nestedIf.consequent.body[0])) {
|
|
740
|
+
nestedIf.consequent.body[0] = t.expressionStatement(
|
|
741
|
+
t.callExpression(
|
|
742
|
+
t.memberExpression(valueMember, t.identifier("push")),
|
|
743
|
+
[nestedIf.consequent.body[0].expression]
|
|
744
|
+
)
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
statements.unshift(
|
|
751
|
+
t.expressionStatement(
|
|
752
|
+
t.assignmentExpression(
|
|
753
|
+
"=",
|
|
754
|
+
t.memberExpression(valueMember, t.identifier("length")),
|
|
755
|
+
t.numericLiteral(0)
|
|
756
|
+
)
|
|
757
|
+
)
|
|
758
|
+
);
|
|
759
|
+
}
|
|
760
|
+
});
|
|
761
|
+
return {
|
|
762
|
+
code: hasPatched ? content : generate(ast).code,
|
|
763
|
+
hasPatched
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// src/patching/operations/export-context/postcss-v3.ts
|
|
768
|
+
import * as t2 from "@babel/types";
|
|
769
|
+
var IDENTIFIER_RE2 = /^[A-Z_$][\w$]*$/i;
|
|
770
|
+
function toIdentifierName2(property) {
|
|
771
|
+
if (!property) {
|
|
772
|
+
return "contextRef";
|
|
773
|
+
}
|
|
774
|
+
const sanitized = property.replace(/[^\w$]/gu, "_");
|
|
775
|
+
if (/^\d/.test(sanitized)) {
|
|
776
|
+
return `_${sanitized}`;
|
|
777
|
+
}
|
|
778
|
+
return sanitized || "contextRef";
|
|
779
|
+
}
|
|
780
|
+
function createModuleExportsMember(property) {
|
|
781
|
+
const object = t2.memberExpression(t2.identifier("module"), t2.identifier("exports"));
|
|
782
|
+
if (IDENTIFIER_RE2.test(property)) {
|
|
783
|
+
return t2.memberExpression(object, t2.identifier(property));
|
|
784
|
+
}
|
|
785
|
+
return t2.memberExpression(object, t2.stringLiteral(property), true);
|
|
786
|
+
}
|
|
787
|
+
function transformProcessTailwindFeaturesReturnContext(content) {
|
|
788
|
+
const ast = parse(content);
|
|
789
|
+
let hasPatched = false;
|
|
790
|
+
traverse(ast, {
|
|
791
|
+
FunctionDeclaration(path8) {
|
|
792
|
+
const node = path8.node;
|
|
793
|
+
if (node.id?.name !== "processTailwindFeatures" || node.body.body.length !== 1) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
const [returnStatement3] = node.body.body;
|
|
797
|
+
if (!t2.isReturnStatement(returnStatement3) || !t2.isFunctionExpression(returnStatement3.argument)) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
const expression = returnStatement3.argument;
|
|
801
|
+
const body = expression.body.body;
|
|
802
|
+
const lastStatement = body[body.length - 1];
|
|
803
|
+
const alreadyReturnsContext = Boolean(
|
|
804
|
+
t2.isReturnStatement(lastStatement) && t2.isIdentifier(lastStatement.argument) && lastStatement.argument.name === "context"
|
|
805
|
+
);
|
|
806
|
+
hasPatched = alreadyReturnsContext;
|
|
807
|
+
if (!alreadyReturnsContext) {
|
|
808
|
+
body.push(t2.returnStatement(t2.identifier("context")));
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
return {
|
|
813
|
+
code: hasPatched ? content : generate(ast).code,
|
|
814
|
+
hasPatched
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
function transformPostcssPlugin(content, { refProperty }) {
|
|
818
|
+
const ast = parse(content);
|
|
819
|
+
const refIdentifier = t2.identifier(toIdentifierName2(refProperty));
|
|
820
|
+
const moduleExportsMember = createModuleExportsMember(refProperty);
|
|
821
|
+
const valueMember = t2.memberExpression(refIdentifier, t2.identifier("value"));
|
|
822
|
+
let hasPatched = false;
|
|
823
|
+
traverse(ast, {
|
|
824
|
+
Program(path8) {
|
|
825
|
+
const program = path8.node;
|
|
826
|
+
const index = program.body.findIndex((statement) => {
|
|
827
|
+
return t2.isExpressionStatement(statement) && t2.isAssignmentExpression(statement.expression) && t2.isMemberExpression(statement.expression.left) && t2.isFunctionExpression(statement.expression.right) && statement.expression.right.id?.name === "tailwindcss";
|
|
828
|
+
});
|
|
829
|
+
if (index === -1) {
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
const previousStatement = program.body[index - 1];
|
|
833
|
+
const lastStatement = program.body[program.body.length - 1];
|
|
834
|
+
const alreadyHasVariable = Boolean(
|
|
835
|
+
previousStatement && t2.isVariableDeclaration(previousStatement) && previousStatement.declarations.length === 1 && t2.isIdentifier(previousStatement.declarations[0].id) && previousStatement.declarations[0].id.name === refIdentifier.name
|
|
836
|
+
);
|
|
837
|
+
const alreadyAssignsModuleExports = Boolean(
|
|
838
|
+
t2.isExpressionStatement(lastStatement) && t2.isAssignmentExpression(lastStatement.expression) && t2.isMemberExpression(lastStatement.expression.left) && t2.isIdentifier(lastStatement.expression.right) && lastStatement.expression.right.name === refIdentifier.name && generate(lastStatement.expression.left).code === generate(moduleExportsMember).code
|
|
839
|
+
);
|
|
840
|
+
hasPatched = alreadyHasVariable && alreadyAssignsModuleExports;
|
|
841
|
+
if (!alreadyHasVariable) {
|
|
842
|
+
program.body.splice(
|
|
843
|
+
index,
|
|
844
|
+
0,
|
|
845
|
+
t2.variableDeclaration("const", [
|
|
846
|
+
t2.variableDeclarator(
|
|
847
|
+
refIdentifier,
|
|
848
|
+
t2.objectExpression([
|
|
849
|
+
t2.objectProperty(t2.identifier("value"), t2.arrayExpression())
|
|
850
|
+
])
|
|
851
|
+
)
|
|
852
|
+
])
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
if (!alreadyAssignsModuleExports) {
|
|
856
|
+
program.body.push(
|
|
857
|
+
t2.expressionStatement(
|
|
858
|
+
t2.assignmentExpression("=", moduleExportsMember, refIdentifier)
|
|
859
|
+
)
|
|
860
|
+
);
|
|
861
|
+
}
|
|
862
|
+
},
|
|
863
|
+
FunctionExpression(path8) {
|
|
864
|
+
if (hasPatched) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const fn = path8.node;
|
|
868
|
+
if (fn.id?.name !== "tailwindcss" || fn.body.body.length !== 1) {
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
const [returnStatement3] = fn.body.body;
|
|
872
|
+
if (!returnStatement3 || !t2.isReturnStatement(returnStatement3) || !t2.isObjectExpression(returnStatement3.argument)) {
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
const properties = returnStatement3.argument.properties;
|
|
876
|
+
if (properties.length !== 2) {
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
const pluginsProperty = properties.find(
|
|
880
|
+
(prop) => t2.isObjectProperty(prop) && t2.isIdentifier(prop.key) && prop.key.name === "plugins"
|
|
881
|
+
);
|
|
882
|
+
if (!pluginsProperty || !t2.isObjectProperty(pluginsProperty) || !t2.isCallExpression(pluginsProperty.value) || !t2.isMemberExpression(pluginsProperty.value.callee) || !t2.isArrayExpression(pluginsProperty.value.callee.object)) {
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
const pluginsArray = pluginsProperty.value.callee.object.elements;
|
|
886
|
+
const targetPlugin = pluginsArray[1];
|
|
887
|
+
if (!targetPlugin || !t2.isFunctionExpression(targetPlugin)) {
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
const block = targetPlugin.body;
|
|
891
|
+
const statements = block.body;
|
|
892
|
+
const last = statements[statements.length - 1];
|
|
893
|
+
if (last && t2.isExpressionStatement(last)) {
|
|
894
|
+
statements[statements.length - 1] = t2.expressionStatement(
|
|
895
|
+
t2.callExpression(
|
|
896
|
+
t2.memberExpression(valueMember, t2.identifier("push")),
|
|
897
|
+
[last.expression]
|
|
898
|
+
)
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
const index = statements.findIndex((s) => t2.isIfStatement(s));
|
|
902
|
+
if (index > -1) {
|
|
903
|
+
const ifStatement = statements[index];
|
|
904
|
+
if (t2.isBlockStatement(ifStatement.consequent)) {
|
|
905
|
+
const [, second] = ifStatement.consequent.body;
|
|
906
|
+
if (second && t2.isForOfStatement(second) && t2.isBlockStatement(second.body)) {
|
|
907
|
+
const bodyStatement = second.body.body[0];
|
|
908
|
+
if (bodyStatement && t2.isIfStatement(bodyStatement) && t2.isBlockStatement(bodyStatement.consequent) && bodyStatement.consequent.body.length === 1 && t2.isExpressionStatement(bodyStatement.consequent.body[0])) {
|
|
909
|
+
bodyStatement.consequent.body[0] = t2.expressionStatement(
|
|
910
|
+
t2.callExpression(
|
|
911
|
+
t2.memberExpression(valueMember, t2.identifier("push")),
|
|
912
|
+
[bodyStatement.consequent.body[0].expression]
|
|
913
|
+
)
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
statements.unshift(
|
|
920
|
+
t2.expressionStatement(
|
|
921
|
+
t2.assignmentExpression(
|
|
922
|
+
"=",
|
|
923
|
+
t2.memberExpression(valueMember, t2.identifier("length")),
|
|
924
|
+
t2.numericLiteral(0)
|
|
925
|
+
)
|
|
926
|
+
)
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
return {
|
|
931
|
+
code: hasPatched ? content : generate(ast).code,
|
|
932
|
+
hasPatched
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// src/patching/operations/export-context/index.ts
|
|
937
|
+
function writeFileIfRequired(filePath, code, overwrite, successMessage) {
|
|
938
|
+
if (!overwrite) {
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
fs4.writeFileSync(filePath, code, {
|
|
942
|
+
encoding: "utf8"
|
|
943
|
+
});
|
|
944
|
+
logger_default.success(successMessage);
|
|
945
|
+
}
|
|
946
|
+
function applyExposeContextPatch(params) {
|
|
947
|
+
const { rootDir, refProperty, overwrite, majorVersion } = params;
|
|
948
|
+
const result = {
|
|
949
|
+
applied: false,
|
|
950
|
+
files: {}
|
|
951
|
+
};
|
|
952
|
+
if (majorVersion === 3) {
|
|
953
|
+
const processFileRelative = "lib/processTailwindFeatures.js";
|
|
954
|
+
const processFilePath = path5.resolve(rootDir, processFileRelative);
|
|
955
|
+
if (fs4.existsSync(processFilePath)) {
|
|
956
|
+
const content = fs4.readFileSync(processFilePath, "utf8");
|
|
957
|
+
const { code, hasPatched } = transformProcessTailwindFeaturesReturnContext(content);
|
|
958
|
+
result.files[processFileRelative] = code;
|
|
959
|
+
if (!hasPatched) {
|
|
960
|
+
writeFileIfRequired(
|
|
961
|
+
processFilePath,
|
|
962
|
+
code,
|
|
963
|
+
overwrite,
|
|
964
|
+
"Patched Tailwind CSS processTailwindFeatures to expose runtime context."
|
|
965
|
+
);
|
|
966
|
+
result.applied = true;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
const pluginCandidates = ["lib/plugin.js", "lib/index.js"];
|
|
970
|
+
const pluginRelative = pluginCandidates.find((candidate) => fs4.existsSync(path5.resolve(rootDir, candidate)));
|
|
971
|
+
if (pluginRelative) {
|
|
972
|
+
const pluginPath = path5.resolve(rootDir, pluginRelative);
|
|
973
|
+
const content = fs4.readFileSync(pluginPath, "utf8");
|
|
974
|
+
const { code, hasPatched } = transformPostcssPlugin(content, { refProperty });
|
|
975
|
+
result.files[pluginRelative] = code;
|
|
976
|
+
if (!hasPatched) {
|
|
977
|
+
writeFileIfRequired(
|
|
978
|
+
pluginPath,
|
|
979
|
+
code,
|
|
980
|
+
overwrite,
|
|
981
|
+
"Patched Tailwind CSS plugin entry to collect runtime contexts."
|
|
982
|
+
);
|
|
983
|
+
result.applied = true;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
} else if (majorVersion === 2) {
|
|
987
|
+
const processFileRelative = "lib/jit/processTailwindFeatures.js";
|
|
988
|
+
const processFilePath = path5.resolve(rootDir, processFileRelative);
|
|
989
|
+
if (fs4.existsSync(processFilePath)) {
|
|
990
|
+
const content = fs4.readFileSync(processFilePath, "utf8");
|
|
991
|
+
const { code, hasPatched } = transformProcessTailwindFeaturesReturnContextV2(content);
|
|
992
|
+
result.files[processFileRelative] = code;
|
|
993
|
+
if (!hasPatched) {
|
|
994
|
+
writeFileIfRequired(
|
|
995
|
+
processFilePath,
|
|
996
|
+
code,
|
|
997
|
+
overwrite,
|
|
998
|
+
"Patched Tailwind CSS JIT processTailwindFeatures to expose runtime context."
|
|
999
|
+
);
|
|
1000
|
+
result.applied = true;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
const pluginRelative = "lib/jit/index.js";
|
|
1004
|
+
const pluginPath = path5.resolve(rootDir, pluginRelative);
|
|
1005
|
+
if (fs4.existsSync(pluginPath)) {
|
|
1006
|
+
const content = fs4.readFileSync(pluginPath, "utf8");
|
|
1007
|
+
const { code, hasPatched } = transformPostcssPluginV2(content, { refProperty });
|
|
1008
|
+
result.files[pluginRelative] = code;
|
|
1009
|
+
if (!hasPatched) {
|
|
1010
|
+
writeFileIfRequired(
|
|
1011
|
+
pluginPath,
|
|
1012
|
+
code,
|
|
1013
|
+
overwrite,
|
|
1014
|
+
"Patched Tailwind CSS JIT entry to collect runtime contexts."
|
|
1015
|
+
);
|
|
1016
|
+
result.applied = true;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
return result;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
// src/patching/operations/extend-length-units.ts
|
|
1024
|
+
import * as t3 from "@babel/types";
|
|
1025
|
+
import fs5 from "fs-extra";
|
|
1026
|
+
import path6 from "pathe";
|
|
1027
|
+
function updateLengthUnitsArray(content, options) {
|
|
1028
|
+
const { variableName = "lengthUnits", units } = options;
|
|
1029
|
+
const ast = parse(content);
|
|
1030
|
+
let arrayRef;
|
|
1031
|
+
let changed = false;
|
|
1032
|
+
traverse(ast, {
|
|
1033
|
+
Identifier(path8) {
|
|
1034
|
+
if (path8.node.name === variableName && t3.isVariableDeclarator(path8.parent) && t3.isArrayExpression(path8.parent.init)) {
|
|
1035
|
+
arrayRef = path8.parent.init;
|
|
1036
|
+
const existing = new Set(
|
|
1037
|
+
path8.parent.init.elements.map((element) => t3.isStringLiteral(element) ? element.value : void 0).filter(Boolean)
|
|
1038
|
+
);
|
|
1039
|
+
for (const unit of units) {
|
|
1040
|
+
if (!existing.has(unit)) {
|
|
1041
|
+
path8.parent.init.elements = path8.parent.init.elements.map((element) => {
|
|
1042
|
+
if (t3.isStringLiteral(element)) {
|
|
1043
|
+
return t3.stringLiteral(element.value);
|
|
1044
|
+
}
|
|
1045
|
+
return element;
|
|
1046
|
+
});
|
|
1047
|
+
path8.parent.init.elements.push(t3.stringLiteral(unit));
|
|
1048
|
+
changed = true;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
});
|
|
1054
|
+
return {
|
|
1055
|
+
arrayRef,
|
|
1056
|
+
changed
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
function applyExtendLengthUnitsPatchV3(rootDir, options) {
|
|
1060
|
+
if (!options.enabled) {
|
|
1061
|
+
return { changed: false, code: void 0 };
|
|
1062
|
+
}
|
|
1063
|
+
const opts = {
|
|
1064
|
+
...options,
|
|
1065
|
+
lengthUnitsFilePath: options.lengthUnitsFilePath ?? "lib/util/dataTypes.js",
|
|
1066
|
+
variableName: options.variableName ?? "lengthUnits"
|
|
1067
|
+
};
|
|
1068
|
+
const dataTypesFilePath = path6.resolve(rootDir, opts.lengthUnitsFilePath);
|
|
1069
|
+
const exists = fs5.existsSync(dataTypesFilePath);
|
|
1070
|
+
if (!exists) {
|
|
1071
|
+
return { changed: false, code: void 0 };
|
|
1072
|
+
}
|
|
1073
|
+
const content = fs5.readFileSync(dataTypesFilePath, "utf8");
|
|
1074
|
+
const { arrayRef, changed } = updateLengthUnitsArray(content, opts);
|
|
1075
|
+
if (!arrayRef || !changed) {
|
|
1076
|
+
return { changed: false, code: void 0 };
|
|
1077
|
+
}
|
|
1078
|
+
const { code } = generate(arrayRef, {
|
|
1079
|
+
jsescOption: { quotes: "single" }
|
|
1080
|
+
});
|
|
1081
|
+
if (arrayRef.start != null && arrayRef.end != null) {
|
|
1082
|
+
const nextCode = `${content.slice(0, arrayRef.start)}${code}${content.slice(arrayRef.end)}`;
|
|
1083
|
+
if (opts.overwrite) {
|
|
1084
|
+
const target = opts.destPath ? path6.resolve(opts.destPath) : dataTypesFilePath;
|
|
1085
|
+
fs5.writeFileSync(target, nextCode, "utf8");
|
|
1086
|
+
logger_default.success("Patched Tailwind CSS length unit list (v3).");
|
|
1087
|
+
}
|
|
1088
|
+
return {
|
|
1089
|
+
changed: true,
|
|
1090
|
+
code: nextCode
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
return {
|
|
1094
|
+
changed: false,
|
|
1095
|
+
code: void 0
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
function applyExtendLengthUnitsPatchV4(rootDir, options) {
|
|
1099
|
+
if (!options.enabled) {
|
|
1100
|
+
return { files: [], changed: false };
|
|
1101
|
+
}
|
|
1102
|
+
const opts = { ...options };
|
|
1103
|
+
const distDir = path6.resolve(rootDir, "dist");
|
|
1104
|
+
if (!fs5.existsSync(distDir)) {
|
|
1105
|
+
return { files: [], changed: false };
|
|
1106
|
+
}
|
|
1107
|
+
const entries = fs5.readdirSync(distDir);
|
|
1108
|
+
const chunkNames = entries.filter((entry) => entry.endsWith(".js") || entry.endsWith(".mjs"));
|
|
1109
|
+
const pattern = /\[\s*["']cm["'],\s*["']mm["'],[\w,"']+\]/;
|
|
1110
|
+
const candidates = chunkNames.map((chunkName) => {
|
|
1111
|
+
const file = path6.join(distDir, chunkName);
|
|
1112
|
+
const code = fs5.readFileSync(file, "utf8");
|
|
1113
|
+
const match = pattern.exec(code);
|
|
1114
|
+
if (!match) {
|
|
1115
|
+
return null;
|
|
1116
|
+
}
|
|
1117
|
+
return {
|
|
1118
|
+
file,
|
|
1119
|
+
code,
|
|
1120
|
+
match,
|
|
1121
|
+
hasPatched: false
|
|
1122
|
+
};
|
|
1123
|
+
}).filter((candidate) => candidate !== null);
|
|
1124
|
+
for (const item of candidates) {
|
|
1125
|
+
const { code, file, match } = item;
|
|
1126
|
+
const ast = parse(match[0], { sourceType: "unambiguous" });
|
|
1127
|
+
traverse(ast, {
|
|
1128
|
+
ArrayExpression(path8) {
|
|
1129
|
+
for (const unit of opts.units) {
|
|
1130
|
+
if (path8.node.elements.some((element) => t3.isStringLiteral(element) && element.value === unit)) {
|
|
1131
|
+
item.hasPatched = true;
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
path8.node.elements.push(t3.stringLiteral(unit));
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
});
|
|
1138
|
+
if (item.hasPatched) {
|
|
1139
|
+
continue;
|
|
1140
|
+
}
|
|
1141
|
+
const { code: replacement } = generate(ast, { minified: true });
|
|
1142
|
+
const start = match.index ?? 0;
|
|
1143
|
+
const end = start + match[0].length;
|
|
1144
|
+
item.code = spliceChangesIntoString(code, [
|
|
1145
|
+
{
|
|
1146
|
+
start,
|
|
1147
|
+
end,
|
|
1148
|
+
replacement: replacement.endsWith(";") ? replacement.slice(0, -1) : replacement
|
|
1149
|
+
}
|
|
1150
|
+
]);
|
|
1151
|
+
if (opts.overwrite) {
|
|
1152
|
+
fs5.writeFileSync(file, item.code, "utf8");
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
if (candidates.some((file) => !file.hasPatched)) {
|
|
1156
|
+
logger_default.success("Patched Tailwind CSS length unit list (v4).");
|
|
1157
|
+
}
|
|
1158
|
+
return {
|
|
1159
|
+
changed: candidates.some((file) => !file.hasPatched),
|
|
1160
|
+
files: candidates
|
|
1161
|
+
};
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
// src/patching/patch-runner.ts
|
|
1165
|
+
function applyTailwindPatches(context) {
|
|
1166
|
+
const { packageInfo, options, majorVersion } = context;
|
|
1167
|
+
const results = {};
|
|
1168
|
+
if (options.features.exposeContext.enabled && (majorVersion === 2 || majorVersion === 3)) {
|
|
1169
|
+
results.exposeContext = applyExposeContextPatch({
|
|
1170
|
+
rootDir: packageInfo.rootPath,
|
|
1171
|
+
refProperty: options.features.exposeContext.refProperty,
|
|
1172
|
+
overwrite: options.overwrite,
|
|
1173
|
+
majorVersion
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
if (options.features.extendLengthUnits?.enabled) {
|
|
1177
|
+
if (majorVersion === 3) {
|
|
1178
|
+
results.extendLengthUnits = applyExtendLengthUnitsPatchV3(
|
|
1179
|
+
packageInfo.rootPath,
|
|
1180
|
+
options.features.extendLengthUnits
|
|
1181
|
+
);
|
|
1182
|
+
} else if (majorVersion === 4) {
|
|
1183
|
+
results.extendLengthUnits = applyExtendLengthUnitsPatchV4(
|
|
1184
|
+
packageInfo.rootPath,
|
|
1185
|
+
options.features.extendLengthUnits
|
|
1186
|
+
);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
return results;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
// src/api/tailwindcss-patcher.ts
|
|
1193
|
+
function resolveMajorVersion(version, hint) {
|
|
1194
|
+
if (hint && [2, 3, 4].includes(hint)) {
|
|
1195
|
+
return hint;
|
|
1196
|
+
}
|
|
1197
|
+
if (version) {
|
|
1198
|
+
const coerced = coerce(version);
|
|
1199
|
+
if (coerced) {
|
|
1200
|
+
const major = coerced.major;
|
|
1201
|
+
if (major === 2 || major === 3 || major === 4) {
|
|
1202
|
+
return major;
|
|
1203
|
+
}
|
|
1204
|
+
if (major >= 4) {
|
|
1205
|
+
return 4;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
return 3;
|
|
1210
|
+
}
|
|
1211
|
+
function resolveTailwindExecutionOptions(normalized, majorVersion) {
|
|
1212
|
+
const base = normalized.tailwind;
|
|
1213
|
+
if (majorVersion === 2 && base.v2) {
|
|
1214
|
+
return {
|
|
1215
|
+
cwd: base.v2.cwd ?? base.cwd ?? normalized.projectRoot,
|
|
1216
|
+
config: base.v2.config ?? base.config,
|
|
1217
|
+
postcssPlugin: base.v2.postcssPlugin ?? base.postcssPlugin
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
if (majorVersion === 3 && base.v3) {
|
|
1221
|
+
return {
|
|
1222
|
+
cwd: base.v3.cwd ?? base.cwd ?? normalized.projectRoot,
|
|
1223
|
+
config: base.v3.config ?? base.config,
|
|
1224
|
+
postcssPlugin: base.v3.postcssPlugin ?? base.postcssPlugin
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
return {
|
|
1228
|
+
cwd: base.cwd ?? normalized.projectRoot,
|
|
1229
|
+
config: base.config,
|
|
1230
|
+
postcssPlugin: base.postcssPlugin
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
var TailwindcssPatcher = class {
|
|
1234
|
+
options;
|
|
1235
|
+
packageInfo;
|
|
1236
|
+
majorVersion;
|
|
1237
|
+
cacheStore;
|
|
1238
|
+
constructor(options = {}) {
|
|
1239
|
+
const resolvedOptions = options && typeof options === "object" && "patch" in options ? fromLegacyOptions(options) : options;
|
|
1240
|
+
this.options = normalizeOptions(resolvedOptions);
|
|
1241
|
+
const packageInfo = getPackageInfoSync(
|
|
1242
|
+
this.options.tailwind.packageName,
|
|
1243
|
+
this.options.tailwind.resolve
|
|
1244
|
+
);
|
|
1245
|
+
if (!packageInfo) {
|
|
1246
|
+
throw new Error(`Unable to locate Tailwind CSS package "${this.options.tailwind.packageName}".`);
|
|
1247
|
+
}
|
|
1248
|
+
this.packageInfo = packageInfo;
|
|
1249
|
+
this.majorVersion = resolveMajorVersion(
|
|
1250
|
+
this.packageInfo.version,
|
|
1251
|
+
this.options.tailwind.versionHint
|
|
1252
|
+
);
|
|
1253
|
+
this.cacheStore = new CacheStore(this.options.cache);
|
|
1254
|
+
}
|
|
1255
|
+
async patch() {
|
|
1256
|
+
return applyTailwindPatches({
|
|
1257
|
+
packageInfo: this.packageInfo,
|
|
1258
|
+
options: this.options,
|
|
1259
|
+
majorVersion: this.majorVersion
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
getContexts() {
|
|
1263
|
+
return loadRuntimeContexts(
|
|
1264
|
+
this.packageInfo,
|
|
1265
|
+
this.majorVersion,
|
|
1266
|
+
this.options.features.exposeContext.refProperty
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
async runTailwindBuildIfNeeded() {
|
|
1270
|
+
if (this.majorVersion === 2 || this.majorVersion === 3) {
|
|
1271
|
+
const executionOptions = resolveTailwindExecutionOptions(this.options, this.majorVersion);
|
|
1272
|
+
await runTailwindBuild({
|
|
1273
|
+
cwd: executionOptions.cwd,
|
|
1274
|
+
config: executionOptions.config,
|
|
1275
|
+
majorVersion: this.majorVersion,
|
|
1276
|
+
postcssPlugin: executionOptions.postcssPlugin
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
async collectClassSet() {
|
|
1281
|
+
if (this.majorVersion === 4) {
|
|
1282
|
+
return collectClassesFromTailwindV4(this.options);
|
|
1283
|
+
}
|
|
1284
|
+
const contexts = this.getContexts();
|
|
1285
|
+
return collectClassesFromContexts(contexts, this.options.filter);
|
|
1286
|
+
}
|
|
1287
|
+
collectClassSetSync() {
|
|
1288
|
+
if (this.majorVersion === 4) {
|
|
1289
|
+
throw new Error("getClassSetSync is not supported for Tailwind CSS v4 projects. Use getClassSet instead.");
|
|
1290
|
+
}
|
|
1291
|
+
const contexts = this.getContexts();
|
|
1292
|
+
return collectClassesFromContexts(contexts, this.options.filter);
|
|
1293
|
+
}
|
|
1294
|
+
async mergeWithCache(set) {
|
|
1295
|
+
if (!this.options.cache.enabled) {
|
|
1296
|
+
return set;
|
|
1297
|
+
}
|
|
1298
|
+
const existing = await this.cacheStore.read();
|
|
1299
|
+
if (this.options.cache.strategy === "merge") {
|
|
1300
|
+
for (const value of existing) {
|
|
1301
|
+
set.add(value);
|
|
1302
|
+
}
|
|
1303
|
+
await this.cacheStore.write(set);
|
|
1304
|
+
} else {
|
|
1305
|
+
if (set.size > 0) {
|
|
1306
|
+
await this.cacheStore.write(set);
|
|
1307
|
+
} else {
|
|
1308
|
+
return existing;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
return set;
|
|
1312
|
+
}
|
|
1313
|
+
mergeWithCacheSync(set) {
|
|
1314
|
+
if (!this.options.cache.enabled) {
|
|
1315
|
+
return set;
|
|
1316
|
+
}
|
|
1317
|
+
const existing = this.cacheStore.readSync();
|
|
1318
|
+
if (this.options.cache.strategy === "merge") {
|
|
1319
|
+
for (const value of existing) {
|
|
1320
|
+
set.add(value);
|
|
1321
|
+
}
|
|
1322
|
+
this.cacheStore.writeSync(set);
|
|
1323
|
+
} else {
|
|
1324
|
+
if (set.size > 0) {
|
|
1325
|
+
this.cacheStore.writeSync(set);
|
|
1326
|
+
} else {
|
|
1327
|
+
return existing;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
return set;
|
|
1331
|
+
}
|
|
1332
|
+
async getClassSet() {
|
|
1333
|
+
await this.runTailwindBuildIfNeeded();
|
|
1334
|
+
const set = await this.collectClassSet();
|
|
1335
|
+
return this.mergeWithCache(set);
|
|
1336
|
+
}
|
|
1337
|
+
getClassSetSync() {
|
|
1338
|
+
const set = this.collectClassSetSync();
|
|
1339
|
+
return this.mergeWithCacheSync(set);
|
|
1340
|
+
}
|
|
1341
|
+
async extract(options) {
|
|
1342
|
+
const shouldWrite = options?.write ?? this.options.output.enabled;
|
|
1343
|
+
const classSet = await this.getClassSet();
|
|
1344
|
+
const classList = Array.from(classSet);
|
|
1345
|
+
const result = {
|
|
1346
|
+
classList,
|
|
1347
|
+
classSet
|
|
1348
|
+
};
|
|
1349
|
+
if (!shouldWrite || !this.options.output.file) {
|
|
1350
|
+
return result;
|
|
1351
|
+
}
|
|
1352
|
+
const target = path7.resolve(this.options.output.file);
|
|
1353
|
+
await fs6.ensureDir(path7.dirname(target));
|
|
1354
|
+
if (this.options.output.format === "json") {
|
|
1355
|
+
const spaces = typeof this.options.output.pretty === "number" ? this.options.output.pretty : void 0;
|
|
1356
|
+
await fs6.writeJSON(target, classList, { spaces });
|
|
1357
|
+
} else {
|
|
1358
|
+
await fs6.writeFile(target, `${classList.join("\n")}
|
|
1359
|
+
`, "utf8");
|
|
1360
|
+
}
|
|
1361
|
+
logger_default.success(`Tailwind CSS class list saved to ${target.replace(process4.cwd(), ".")}`);
|
|
1362
|
+
return {
|
|
1363
|
+
...result,
|
|
1364
|
+
filename: target
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
// Backwards compatibility helper used by tests and API consumers.
|
|
1368
|
+
extractValidCandidates = extractValidCandidates;
|
|
1369
|
+
};
|
|
1370
|
+
|
|
1371
|
+
export {
|
|
1372
|
+
logger_default,
|
|
1373
|
+
CacheStore,
|
|
1374
|
+
extractRawCandidatesWithPositions,
|
|
1375
|
+
extractRawCandidates,
|
|
1376
|
+
extractValidCandidates,
|
|
1377
|
+
fromLegacyOptions,
|
|
1378
|
+
fromUnifiedConfig,
|
|
1379
|
+
normalizeOptions,
|
|
1380
|
+
collectClassesFromContexts,
|
|
1381
|
+
collectClassesFromTailwindV4,
|
|
1382
|
+
loadRuntimeContexts,
|
|
1383
|
+
runTailwindBuild,
|
|
1384
|
+
TailwindcssPatcher
|
|
1385
|
+
};
|