@csszyx/cli 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index.d.ts → index.d.mts} +3 -2
- package/dist/{index.js → index.mjs} +496 -563
- package/package.json +17 -13
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import cac from 'cac';
|
|
3
|
+
import path, { resolve, dirname } from 'node:path';
|
|
4
|
+
import fs from 'fs-extra';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import pc from 'picocolors';
|
|
7
|
+
import fs$1, { existsSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { mkdir } from 'node:fs/promises';
|
|
9
|
+
import { pathToFileURL } from 'node:url';
|
|
10
|
+
import resolveConfig from 'tailwindcss/resolveConfig.js';
|
|
11
|
+
import { execa } from 'execa';
|
|
12
|
+
import prompts from 'prompts';
|
|
13
|
+
import readline from 'node:readline';
|
|
14
|
+
import fg from 'fast-glob';
|
|
15
|
+
import { parse } from '@babel/parser';
|
|
16
|
+
import _traverse from '@babel/traverse';
|
|
17
|
+
import * as t from '@babel/types';
|
|
2
18
|
|
|
3
|
-
|
|
4
|
-
import cac from "cac";
|
|
5
|
-
|
|
6
|
-
// src/commands/audit.ts
|
|
7
|
-
import path from "path";
|
|
8
|
-
import fs from "fs-extra";
|
|
9
|
-
|
|
10
|
-
// src/utils/terminal-ui.ts
|
|
11
|
-
import ora from "ora";
|
|
12
|
-
import pc from "picocolors";
|
|
13
|
-
var colors = {
|
|
19
|
+
const colors = {
|
|
14
20
|
success: pc.green,
|
|
15
21
|
error: pc.red,
|
|
16
22
|
warn: pc.yellow,
|
|
@@ -18,7 +24,7 @@ var colors = {
|
|
|
18
24
|
dim: pc.dim,
|
|
19
25
|
bold: pc.bold
|
|
20
26
|
};
|
|
21
|
-
|
|
27
|
+
const icons = {
|
|
22
28
|
success: "\u2713",
|
|
23
29
|
error: "\u2717",
|
|
24
30
|
warn: "\u26A0",
|
|
@@ -27,11 +33,9 @@ var icons = {
|
|
|
27
33
|
function printHeader(title) {
|
|
28
34
|
const width = 48;
|
|
29
35
|
const padding = Math.max(0, width - title.length - 4);
|
|
30
|
-
console.log(pc.cyan(
|
|
31
|
-
console.log(
|
|
32
|
-
|
|
33
|
-
);
|
|
34
|
-
console.log(pc.cyan("\u2514" + "\u2500".repeat(width - 2) + "\u2518"));
|
|
36
|
+
console.log(pc.cyan(`\u250C${"\u2500".repeat(width - 2)}\u2510`));
|
|
37
|
+
console.log(`${pc.cyan("\u2502")} ${pc.bold(title)}${" ".repeat(padding)}${pc.cyan("\u2502")}`);
|
|
38
|
+
console.log(pc.cyan(`\u2514${"\u2500".repeat(width - 2)}\u2518`));
|
|
35
39
|
console.log();
|
|
36
40
|
}
|
|
37
41
|
function printSection(title) {
|
|
@@ -51,7 +55,7 @@ function printWarn(message) {
|
|
|
51
55
|
function printInfo(message) {
|
|
52
56
|
console.log(colors.info(`${icons.info} ${message}`));
|
|
53
57
|
}
|
|
54
|
-
|
|
58
|
+
const spinner = {
|
|
55
59
|
start(text) {
|
|
56
60
|
return ora(text).start();
|
|
57
61
|
},
|
|
@@ -70,7 +74,6 @@ function printBar(values, max, width = 20) {
|
|
|
70
74
|
return "\u25A0".repeat(filled) + "\u25A1".repeat(width - filled);
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
// src/commands/audit.ts
|
|
74
77
|
async function audit(options = {}) {
|
|
75
78
|
const cwd = options.cwd || process.cwd();
|
|
76
79
|
const stats = await collectStats(cwd);
|
|
@@ -110,14 +113,18 @@ async function audit(options = {}) {
|
|
|
110
113
|
const htmlSavings = stats.bundleSavings.originalHTML - stats.bundleSavings.mangledHTML;
|
|
111
114
|
const htmlPercent = Math.round(htmlSavings / stats.bundleSavings.originalHTML * 100);
|
|
112
115
|
console.log(` Original HTML: ${formatBytes(stats.bundleSavings.originalHTML)}`);
|
|
113
|
-
console.log(
|
|
116
|
+
console.log(
|
|
117
|
+
` Mangled HTML: ${formatBytes(stats.bundleSavings.mangledHTML)} \u2193 ${htmlPercent}% (-${formatBytes(htmlSavings)})`
|
|
118
|
+
);
|
|
114
119
|
console.log();
|
|
115
120
|
}
|
|
116
121
|
if (stats.bundleSavings.originalCSS > 0) {
|
|
117
122
|
const cssSavings = stats.bundleSavings.originalCSS - stats.bundleSavings.mangledCSS;
|
|
118
123
|
const cssPercent = Math.round(cssSavings / stats.bundleSavings.originalCSS * 100);
|
|
119
124
|
console.log(` Original CSS: ${formatBytes(stats.bundleSavings.originalCSS)}`);
|
|
120
|
-
console.log(
|
|
125
|
+
console.log(
|
|
126
|
+
` Mangled CSS: ${formatBytes(stats.bundleSavings.mangledCSS)} \u2193 ${cssPercent}% (-${formatBytes(cssSavings)})`
|
|
127
|
+
);
|
|
121
128
|
}
|
|
122
129
|
console.log();
|
|
123
130
|
printInfo("\u{1F4A1} Tip: Enable runtime lite bundle for -1.1KB");
|
|
@@ -165,23 +172,16 @@ function formatBytes(bytes) {
|
|
|
165
172
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
166
173
|
}
|
|
167
174
|
|
|
168
|
-
// src/commands/doctor.ts
|
|
169
|
-
import path3 from "path";
|
|
170
|
-
import fs3 from "fs-extra";
|
|
171
|
-
|
|
172
|
-
// src/utils/framework-detector.ts
|
|
173
|
-
import path2 from "path";
|
|
174
|
-
import fs2 from "fs-extra";
|
|
175
175
|
function detectFramework(cwd) {
|
|
176
176
|
try {
|
|
177
|
-
const pkgPath =
|
|
178
|
-
if (!
|
|
177
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
178
|
+
if (!fs.existsSync(pkgPath)) {
|
|
179
179
|
return "unknown";
|
|
180
180
|
}
|
|
181
|
-
const pkg =
|
|
181
|
+
const pkg = fs.readJSONSync(pkgPath);
|
|
182
182
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
183
183
|
if (deps.next) {
|
|
184
|
-
const hasAppDir =
|
|
184
|
+
const hasAppDir = fs.existsSync(path.join(cwd, "app"));
|
|
185
185
|
return hasAppDir ? "nextjs-app" : "nextjs-pages";
|
|
186
186
|
}
|
|
187
187
|
if (deps.nuxt) {
|
|
@@ -210,24 +210,24 @@ function detectFramework(cwd) {
|
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
function detectPackageManager(cwd) {
|
|
213
|
-
if (
|
|
213
|
+
if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) {
|
|
214
214
|
return "pnpm";
|
|
215
215
|
}
|
|
216
|
-
if (
|
|
216
|
+
if (fs.existsSync(path.join(cwd, "yarn.lock"))) {
|
|
217
217
|
return "yarn";
|
|
218
218
|
}
|
|
219
|
-
if (
|
|
219
|
+
if (fs.existsSync(path.join(cwd, "bun.lockb"))) {
|
|
220
220
|
return "bun";
|
|
221
221
|
}
|
|
222
222
|
return "npm";
|
|
223
223
|
}
|
|
224
224
|
function hasTailwindInstalled(cwd) {
|
|
225
225
|
try {
|
|
226
|
-
const pkgPath =
|
|
227
|
-
if (!
|
|
226
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
227
|
+
if (!fs.existsSync(pkgPath)) {
|
|
228
228
|
return false;
|
|
229
229
|
}
|
|
230
|
-
const pkg =
|
|
230
|
+
const pkg = fs.readJSONSync(pkgPath);
|
|
231
231
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
232
232
|
return !!deps.tailwindcss;
|
|
233
233
|
} catch {
|
|
@@ -235,7 +235,7 @@ function hasTailwindInstalled(cwd) {
|
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
function hasTypeScript(cwd) {
|
|
238
|
-
return
|
|
238
|
+
return fs.existsSync(path.join(cwd, "tsconfig.json")) || fs.existsSync(path.join(cwd, "jsconfig.json"));
|
|
239
239
|
}
|
|
240
240
|
function getProjectInfo(cwd = process.cwd()) {
|
|
241
241
|
return {
|
|
@@ -261,14 +261,13 @@ function getFrameworkName(framework) {
|
|
|
261
261
|
return names[framework];
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
-
// src/commands/doctor.ts
|
|
265
264
|
async function doctor(options = {}) {
|
|
266
265
|
const cwd = options.cwd || process.cwd();
|
|
267
266
|
const projectInfo = getProjectInfo(cwd);
|
|
268
267
|
printHeader("csszyx Doctor");
|
|
269
268
|
let issueCount = 0;
|
|
270
269
|
printSection("\u{1F4CB} Configuration Health");
|
|
271
|
-
const hasConfig =
|
|
270
|
+
const hasConfig = fs.existsSync(path.join(cwd, "csszyx.config.ts")) || fs.existsSync(path.join(cwd, "csszyx.config.js"));
|
|
272
271
|
if (hasConfig) {
|
|
273
272
|
printSuccess("csszyx configuration found");
|
|
274
273
|
} else {
|
|
@@ -285,8 +284,8 @@ async function doctor(options = {}) {
|
|
|
285
284
|
}
|
|
286
285
|
printSection("\u{1F4E6} Package Versions");
|
|
287
286
|
try {
|
|
288
|
-
const pkgPath =
|
|
289
|
-
const pkg =
|
|
287
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
288
|
+
const pkg = fs.readJSONSync(pkgPath);
|
|
290
289
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
291
290
|
if (deps.csszyx) {
|
|
292
291
|
printSuccess(`csszyx: ${deps.csszyx}`);
|
|
@@ -299,15 +298,12 @@ async function doctor(options = {}) {
|
|
|
299
298
|
issueCount++;
|
|
300
299
|
}
|
|
301
300
|
printSection("\u{1F528} Build Output");
|
|
302
|
-
const distDir =
|
|
303
|
-
if (
|
|
304
|
-
const htmlFiles =
|
|
301
|
+
const distDir = path.join(cwd, "dist");
|
|
302
|
+
if (fs.existsSync(distDir)) {
|
|
303
|
+
const htmlFiles = fs.readdirSync(distDir, { recursive: true }).filter((f) => String(f).endsWith(".html"));
|
|
305
304
|
if (htmlFiles.length > 0) {
|
|
306
305
|
printSuccess(`Found ${htmlFiles.length} HTML file(s)`);
|
|
307
|
-
const htmlContent =
|
|
308
|
-
path3.join(distDir, String(htmlFiles[0])),
|
|
309
|
-
"utf-8"
|
|
310
|
-
);
|
|
306
|
+
const htmlContent = fs.readFileSync(path.join(distDir, String(htmlFiles[0])), "utf-8");
|
|
311
307
|
if (htmlContent.includes("data-sz-checksum")) {
|
|
312
308
|
printSuccess("Checksum injection working");
|
|
313
309
|
} else {
|
|
@@ -328,20 +324,7 @@ async function doctor(options = {}) {
|
|
|
328
324
|
}
|
|
329
325
|
}
|
|
330
326
|
|
|
331
|
-
|
|
332
|
-
import { resolve as resolve3 } from "path";
|
|
333
|
-
|
|
334
|
-
// src/generator/type-generator.ts
|
|
335
|
-
import { writeFileSync } from "fs";
|
|
336
|
-
import { mkdir } from "fs/promises";
|
|
337
|
-
import { dirname, resolve as resolve2 } from "path";
|
|
338
|
-
|
|
339
|
-
// src/scanner/tailwind-scanner.ts
|
|
340
|
-
import { existsSync } from "fs";
|
|
341
|
-
import { resolve } from "path";
|
|
342
|
-
import { pathToFileURL } from "url";
|
|
343
|
-
import resolveConfig from "tailwindcss/resolveConfig.js";
|
|
344
|
-
var CONFIG_FILES = [
|
|
327
|
+
const CONFIG_FILES = [
|
|
345
328
|
"tailwind.config.ts",
|
|
346
329
|
"tailwind.config.js",
|
|
347
330
|
"tailwind.config.cjs",
|
|
@@ -373,9 +356,7 @@ async function scanTailwindConfig(configPath) {
|
|
|
373
356
|
}
|
|
374
357
|
const resolvedConfig = resolveConfig(userConfig);
|
|
375
358
|
const theme = resolvedConfig.theme;
|
|
376
|
-
const hasCustomColors = Boolean(
|
|
377
|
-
userConfig.theme?.colors || userConfig.theme?.extend?.colors
|
|
378
|
-
);
|
|
359
|
+
const hasCustomColors = Boolean(userConfig.theme?.colors || userConfig.theme?.extend?.colors);
|
|
379
360
|
const hasCustomSpacing = Boolean(
|
|
380
361
|
userConfig.theme?.spacing || userConfig.theme?.extend?.spacing
|
|
381
362
|
);
|
|
@@ -386,9 +367,9 @@ async function scanTailwindConfig(configPath) {
|
|
|
386
367
|
hasCustomSpacing
|
|
387
368
|
};
|
|
388
369
|
}
|
|
389
|
-
function flattenColors(
|
|
370
|
+
function flattenColors(colors) {
|
|
390
371
|
const result = [];
|
|
391
|
-
for (const [key, value] of Object.entries(
|
|
372
|
+
for (const [key, value] of Object.entries(colors)) {
|
|
392
373
|
if (key === "inherit" || key === "current" || key === "transparent") {
|
|
393
374
|
result.push(key);
|
|
394
375
|
continue;
|
|
@@ -411,13 +392,13 @@ function extractSpacingKeys(spacing) {
|
|
|
411
392
|
return Object.keys(spacing).sort((a, b) => {
|
|
412
393
|
const aNum = parseFloat(a);
|
|
413
394
|
const bNum = parseFloat(b);
|
|
414
|
-
if (!isNaN(aNum) && !isNaN(bNum)) {
|
|
395
|
+
if (!Number.isNaN(aNum) && !Number.isNaN(bNum)) {
|
|
415
396
|
return aNum - bNum;
|
|
416
397
|
}
|
|
417
|
-
if (!isNaN(aNum)) {
|
|
398
|
+
if (!Number.isNaN(aNum)) {
|
|
418
399
|
return -1;
|
|
419
400
|
}
|
|
420
|
-
if (!isNaN(bNum)) {
|
|
401
|
+
if (!Number.isNaN(bNum)) {
|
|
421
402
|
return 1;
|
|
422
403
|
}
|
|
423
404
|
return a.localeCompare(b);
|
|
@@ -427,8 +408,7 @@ function extractScreenKeys(screens) {
|
|
|
427
408
|
return Object.keys(screens);
|
|
428
409
|
}
|
|
429
410
|
|
|
430
|
-
|
|
431
|
-
var PROPERTY_MAPPINGS = [
|
|
411
|
+
const PROPERTY_MAPPINGS = [
|
|
432
412
|
// Layout
|
|
433
413
|
{
|
|
434
414
|
prop: "display",
|
|
@@ -796,7 +776,7 @@ var PROPERTY_MAPPINGS = [
|
|
|
796
776
|
description: "Transition timing function"
|
|
797
777
|
}
|
|
798
778
|
];
|
|
799
|
-
|
|
779
|
+
const STATIC_VALUE_TYPES = {
|
|
800
780
|
display: [
|
|
801
781
|
"block",
|
|
802
782
|
"inline-block",
|
|
@@ -828,41 +808,11 @@ var STATIC_VALUE_TYPES = {
|
|
|
828
808
|
"y-scroll"
|
|
829
809
|
],
|
|
830
810
|
flexDirection: ["row", "row-reverse", "col", "col-reverse"],
|
|
831
|
-
justify: [
|
|
832
|
-
"normal",
|
|
833
|
-
"start",
|
|
834
|
-
"end",
|
|
835
|
-
"center",
|
|
836
|
-
"between",
|
|
837
|
-
"around",
|
|
838
|
-
"evenly",
|
|
839
|
-
"stretch"
|
|
840
|
-
],
|
|
811
|
+
justify: ["normal", "start", "end", "center", "between", "around", "evenly", "stretch"],
|
|
841
812
|
items: ["start", "end", "center", "baseline", "stretch"],
|
|
842
813
|
flex: ["1", "auto", "initial", "none"],
|
|
843
|
-
grid: [
|
|
844
|
-
|
|
845
|
-
"flow-col",
|
|
846
|
-
"flow-dense",
|
|
847
|
-
"flow-row-dense",
|
|
848
|
-
"flow-col-dense"
|
|
849
|
-
],
|
|
850
|
-
gridCols: [
|
|
851
|
-
"1",
|
|
852
|
-
"2",
|
|
853
|
-
"3",
|
|
854
|
-
"4",
|
|
855
|
-
"5",
|
|
856
|
-
"6",
|
|
857
|
-
"7",
|
|
858
|
-
"8",
|
|
859
|
-
"9",
|
|
860
|
-
"10",
|
|
861
|
-
"11",
|
|
862
|
-
"12",
|
|
863
|
-
"none",
|
|
864
|
-
"subgrid"
|
|
865
|
-
],
|
|
814
|
+
grid: ["flow-row", "flow-col", "flow-dense", "flow-row-dense", "flow-col-dense"],
|
|
815
|
+
gridCols: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "none", "subgrid"],
|
|
866
816
|
gridRows: ["1", "2", "3", "4", "5", "6", "none", "subgrid"],
|
|
867
817
|
col: [
|
|
868
818
|
"auto",
|
|
@@ -957,7 +907,7 @@ function generateUnionType(values) {
|
|
|
957
907
|
}
|
|
958
908
|
function generateTypeDeclarations(theme, options = {}) {
|
|
959
909
|
const { includeComments = true } = options;
|
|
960
|
-
const
|
|
910
|
+
const colors = flattenColors(theme.colors || {});
|
|
961
911
|
const spacing = extractSpacingKeys(theme.spacing || {});
|
|
962
912
|
const screens = extractScreenKeys(theme.screens || {});
|
|
963
913
|
const sizing = [
|
|
@@ -985,7 +935,7 @@ function generateTypeDeclarations(theme, options = {}) {
|
|
|
985
935
|
"5/6"
|
|
986
936
|
];
|
|
987
937
|
const valueTypeMap = {
|
|
988
|
-
colors
|
|
938
|
+
colors,
|
|
989
939
|
spacing,
|
|
990
940
|
sizing,
|
|
991
941
|
screens,
|
|
@@ -1071,29 +1021,8 @@ function generateTypeDeclarations(theme, options = {}) {
|
|
|
1071
1021
|
"screen-xl",
|
|
1072
1022
|
"screen-2xl"
|
|
1073
1023
|
],
|
|
1074
|
-
minHeight: [
|
|
1075
|
-
|
|
1076
|
-
"full",
|
|
1077
|
-
"screen",
|
|
1078
|
-
"svh",
|
|
1079
|
-
"lvh",
|
|
1080
|
-
"dvh",
|
|
1081
|
-
"min",
|
|
1082
|
-
"max",
|
|
1083
|
-
"fit"
|
|
1084
|
-
],
|
|
1085
|
-
maxHeight: [
|
|
1086
|
-
"0",
|
|
1087
|
-
"none",
|
|
1088
|
-
"full",
|
|
1089
|
-
"screen",
|
|
1090
|
-
"svh",
|
|
1091
|
-
"lvh",
|
|
1092
|
-
"dvh",
|
|
1093
|
-
"min",
|
|
1094
|
-
"max",
|
|
1095
|
-
"fit"
|
|
1096
|
-
],
|
|
1024
|
+
minHeight: ["0", "full", "screen", "svh", "lvh", "dvh", "min", "max", "fit"],
|
|
1025
|
+
maxHeight: ["0", "none", "full", "screen", "svh", "lvh", "dvh", "min", "max", "fit"],
|
|
1097
1026
|
scale: ["0", "50", "75", "90", "95", "100", "105", "110", "125", "150"],
|
|
1098
1027
|
rotate: ["0", "1", "2", "3", "6", "12", "45", "90", "180"],
|
|
1099
1028
|
translate: spacing,
|
|
@@ -1134,9 +1063,7 @@ function generateTypeDeclarations(theme, options = {}) {
|
|
|
1134
1063
|
const responsiveProps = [];
|
|
1135
1064
|
for (const screen of screens) {
|
|
1136
1065
|
if (includeComments) {
|
|
1137
|
-
responsiveProps.push(
|
|
1138
|
-
` /** Styles applied at ${screen} breakpoint and above */`
|
|
1139
|
-
);
|
|
1066
|
+
responsiveProps.push(` /** Styles applied at ${screen} breakpoint and above */`);
|
|
1140
1067
|
}
|
|
1141
1068
|
responsiveProps.push(` ${screen}?: SzVariantObject;`);
|
|
1142
1069
|
}
|
|
@@ -1202,7 +1129,7 @@ export {};
|
|
|
1202
1129
|
return output;
|
|
1203
1130
|
}
|
|
1204
1131
|
async function writeDeclarationFile(content, outputPath) {
|
|
1205
|
-
const absolutePath =
|
|
1132
|
+
const absolutePath = resolve(outputPath);
|
|
1206
1133
|
const dir = dirname(absolutePath);
|
|
1207
1134
|
await mkdir(dir, { recursive: true });
|
|
1208
1135
|
writeFileSync(absolutePath, content, "utf-8");
|
|
@@ -1211,19 +1138,19 @@ async function generateAndWriteTypes(theme, options = {}) {
|
|
|
1211
1138
|
const outputPath = options.output || "./csszyx.d.ts";
|
|
1212
1139
|
const content = generateTypeDeclarations(theme, options);
|
|
1213
1140
|
await writeDeclarationFile(content, outputPath);
|
|
1214
|
-
return
|
|
1141
|
+
return resolve(outputPath);
|
|
1215
1142
|
}
|
|
1216
1143
|
|
|
1217
|
-
// src/commands/generate-types.ts
|
|
1218
1144
|
async function generateTypes(options = {}) {
|
|
1219
1145
|
const cwd = options.cwd || process.cwd();
|
|
1220
1146
|
const log = options.silent ? () => {
|
|
1221
1147
|
} : console.log;
|
|
1222
1148
|
const error = options.silent ? () => {
|
|
1223
1149
|
} : console.error;
|
|
1224
|
-
let configPath
|
|
1150
|
+
let configPath;
|
|
1151
|
+
let scanResult;
|
|
1225
1152
|
if (options.config) {
|
|
1226
|
-
configPath =
|
|
1153
|
+
configPath = resolve(cwd, options.config);
|
|
1227
1154
|
} else {
|
|
1228
1155
|
log("\u{1F50D} Searching for tailwind.config...");
|
|
1229
1156
|
const foundConfig = findConfigFile(cwd);
|
|
@@ -1252,35 +1179,25 @@ async function generateTypes(options = {}) {
|
|
|
1252
1179
|
}
|
|
1253
1180
|
const outputPath = options.output || "./csszyx.d.ts";
|
|
1254
1181
|
const generatorOptions = {
|
|
1255
|
-
output:
|
|
1182
|
+
output: resolve(cwd, outputPath),
|
|
1256
1183
|
includeComments: true
|
|
1257
1184
|
};
|
|
1258
1185
|
log("\n\u{1F4DD} Generating TypeScript declarations...");
|
|
1259
1186
|
try {
|
|
1260
|
-
const writtenPath = await generateAndWriteTypes(
|
|
1261
|
-
scanResult.theme,
|
|
1262
|
-
generatorOptions
|
|
1263
|
-
);
|
|
1187
|
+
const writtenPath = await generateAndWriteTypes(scanResult.theme, generatorOptions);
|
|
1264
1188
|
log("\n\u2728 Types generated successfully!");
|
|
1265
1189
|
log(` Output: ${writtenPath}`);
|
|
1266
1190
|
log('\n\u{1F4A1} Add this to your tsconfig.json "include" array:');
|
|
1267
1191
|
log(' "include": ["src", "csszyx.d.ts"]');
|
|
1268
1192
|
} catch (err) {
|
|
1269
|
-
error(
|
|
1270
|
-
`\u274C Failed to generate types: ${err instanceof Error ? err.message : String(err)}`
|
|
1271
|
-
);
|
|
1193
|
+
error(`\u274C Failed to generate types: ${err instanceof Error ? err.message : String(err)}`);
|
|
1272
1194
|
process.exit(1);
|
|
1273
1195
|
}
|
|
1274
1196
|
}
|
|
1275
1197
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
import fs4 from "fs-extra";
|
|
1280
|
-
import prompts from "prompts";
|
|
1281
|
-
var VITE_FRAMEWORKS = /* @__PURE__ */ new Set(["vite-react", "vite-vue", "vite-svelte"]);
|
|
1282
|
-
var NEXTJS_FRAMEWORKS = /* @__PURE__ */ new Set(["nextjs-app", "nextjs-pages"]);
|
|
1283
|
-
var CSS_ENTRY_CANDIDATES = [
|
|
1198
|
+
const VITE_FRAMEWORKS = /* @__PURE__ */ new Set(["vite-react", "vite-vue", "vite-svelte"]);
|
|
1199
|
+
const NEXTJS_FRAMEWORKS = /* @__PURE__ */ new Set(["nextjs-app", "nextjs-pages"]);
|
|
1200
|
+
const CSS_ENTRY_CANDIDATES = [
|
|
1284
1201
|
"src/index.css",
|
|
1285
1202
|
"src/app.css",
|
|
1286
1203
|
"src/globals.css",
|
|
@@ -1343,11 +1260,9 @@ async function init(options = {}) {
|
|
|
1343
1260
|
await execa(projectInfo.packageManager, ["add", "csszyx"], { cwd });
|
|
1344
1261
|
if (config.installTailwind) {
|
|
1345
1262
|
const twPackage = VITE_FRAMEWORKS.has(projectInfo.framework) ? "@tailwindcss/vite" : "@tailwindcss/postcss";
|
|
1346
|
-
await execa(
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
{ cwd }
|
|
1350
|
-
);
|
|
1263
|
+
await execa(projectInfo.packageManager, ["add", "-D", "tailwindcss", twPackage], {
|
|
1264
|
+
cwd
|
|
1265
|
+
});
|
|
1351
1266
|
}
|
|
1352
1267
|
spinner.succeed(spin, "Installed csszyx");
|
|
1353
1268
|
} catch (error) {
|
|
@@ -1358,25 +1273,25 @@ async function init(options = {}) {
|
|
|
1358
1273
|
const spin2 = spinner.start("Creating config files...");
|
|
1359
1274
|
try {
|
|
1360
1275
|
const configContent = generateConfigFile(config);
|
|
1361
|
-
const configPath =
|
|
1276
|
+
const configPath = path.join(
|
|
1362
1277
|
cwd,
|
|
1363
1278
|
projectInfo.hasTypeScript ? "csszyx.config.ts" : "csszyx.config.js"
|
|
1364
1279
|
);
|
|
1365
|
-
await
|
|
1280
|
+
await fs.writeFile(configPath, configContent);
|
|
1366
1281
|
if (config.installTailwind) {
|
|
1367
1282
|
await setupTailwindCss(cwd, projectInfo.framework);
|
|
1368
1283
|
}
|
|
1369
1284
|
await injectPlugin(cwd, projectInfo.framework);
|
|
1370
1285
|
if (config.setupGitignore) {
|
|
1371
|
-
const gitignorePath =
|
|
1286
|
+
const gitignorePath = path.join(cwd, ".gitignore");
|
|
1372
1287
|
const ignoreEntry = "\n# csszyx generated theme types\n.csszyx\n";
|
|
1373
|
-
if (
|
|
1374
|
-
const content = await
|
|
1288
|
+
if (fs.existsSync(gitignorePath)) {
|
|
1289
|
+
const content = await fs.readFile(gitignorePath, "utf8");
|
|
1375
1290
|
if (!content.includes(".csszyx")) {
|
|
1376
|
-
await
|
|
1291
|
+
await fs.appendFile(gitignorePath, ignoreEntry);
|
|
1377
1292
|
}
|
|
1378
1293
|
} else {
|
|
1379
|
-
await
|
|
1294
|
+
await fs.writeFile(gitignorePath, "node_modules\n.csszyx\n");
|
|
1380
1295
|
}
|
|
1381
1296
|
}
|
|
1382
1297
|
if (config.setupTsconfig) {
|
|
@@ -1398,32 +1313,32 @@ async function init(options = {}) {
|
|
|
1398
1313
|
async function setupTailwindCss(cwd, framework) {
|
|
1399
1314
|
let cssPath;
|
|
1400
1315
|
for (const candidate of CSS_ENTRY_CANDIDATES) {
|
|
1401
|
-
const full =
|
|
1402
|
-
if (
|
|
1316
|
+
const full = path.join(cwd, candidate);
|
|
1317
|
+
if (fs.existsSync(full)) {
|
|
1403
1318
|
cssPath = full;
|
|
1404
1319
|
break;
|
|
1405
1320
|
}
|
|
1406
1321
|
}
|
|
1407
1322
|
if (!cssPath) {
|
|
1408
|
-
cssPath =
|
|
1409
|
-
await
|
|
1410
|
-
await
|
|
1411
|
-
printInfo(`Created ${
|
|
1323
|
+
cssPath = path.join(cwd, "src/index.css");
|
|
1324
|
+
await fs.ensureDir(path.dirname(cssPath));
|
|
1325
|
+
await fs.writeFile(cssPath, '@import "tailwindcss";\n');
|
|
1326
|
+
printInfo(`Created ${path.relative(cwd, cssPath)} with Tailwind v4 import`);
|
|
1412
1327
|
return;
|
|
1413
1328
|
}
|
|
1414
|
-
const content = await
|
|
1329
|
+
const content = await fs.readFile(cssPath, "utf8");
|
|
1415
1330
|
if (!content.includes('@import "tailwindcss"') && !content.includes("@import 'tailwindcss'")) {
|
|
1416
|
-
await
|
|
1331
|
+
await fs.writeFile(cssPath, `@import "tailwindcss";
|
|
1417
1332
|
|
|
1418
1333
|
${content}`);
|
|
1419
|
-
printInfo(`Added Tailwind v4 import to ${
|
|
1334
|
+
printInfo(`Added Tailwind v4 import to ${path.relative(cwd, cssPath)}`);
|
|
1420
1335
|
}
|
|
1421
1336
|
if (NEXTJS_FRAMEWORKS.has(framework)) {
|
|
1422
|
-
const postcssMjs =
|
|
1423
|
-
const postcssJs =
|
|
1424
|
-
const postcssTs =
|
|
1425
|
-
if (!
|
|
1426
|
-
await
|
|
1337
|
+
const postcssMjs = path.join(cwd, "postcss.config.mjs");
|
|
1338
|
+
const postcssJs = path.join(cwd, "postcss.config.js");
|
|
1339
|
+
const postcssTs = path.join(cwd, "postcss.config.ts");
|
|
1340
|
+
if (!fs.existsSync(postcssMjs) && !fs.existsSync(postcssJs) && !fs.existsSync(postcssTs)) {
|
|
1341
|
+
await fs.writeFile(postcssMjs, generatePostcssConfig());
|
|
1427
1342
|
printInfo("Created postcss.config.mjs for Tailwind v4");
|
|
1428
1343
|
}
|
|
1429
1344
|
}
|
|
@@ -1448,14 +1363,14 @@ async function injectPlugin(cwd, framework) {
|
|
|
1448
1363
|
}
|
|
1449
1364
|
async function injectVitePlugin(cwd) {
|
|
1450
1365
|
const candidates = [
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1366
|
+
path.join(cwd, "vite.config.ts"),
|
|
1367
|
+
path.join(cwd, "vite.config.js"),
|
|
1368
|
+
path.join(cwd, "vite.config.mts"),
|
|
1369
|
+
path.join(cwd, "vite.config.mjs")
|
|
1455
1370
|
];
|
|
1456
1371
|
let configPath;
|
|
1457
1372
|
for (const c of candidates) {
|
|
1458
|
-
if (
|
|
1373
|
+
if (fs.existsSync(c)) {
|
|
1459
1374
|
configPath = c;
|
|
1460
1375
|
break;
|
|
1461
1376
|
}
|
|
@@ -1463,7 +1378,7 @@ async function injectVitePlugin(cwd) {
|
|
|
1463
1378
|
if (!configPath) {
|
|
1464
1379
|
return false;
|
|
1465
1380
|
}
|
|
1466
|
-
let content = await
|
|
1381
|
+
let content = await fs.readFile(configPath, "utf8");
|
|
1467
1382
|
if (content.includes("csszyx")) {
|
|
1468
1383
|
return true;
|
|
1469
1384
|
}
|
|
@@ -1476,7 +1391,8 @@ async function injectVitePlugin(cwd) {
|
|
|
1476
1391
|
return false;
|
|
1477
1392
|
}
|
|
1478
1393
|
const insertAt = lastImportMatch.index + lastImportMatch[0].length;
|
|
1479
|
-
content = content.slice(0, insertAt)
|
|
1394
|
+
content = `${content.slice(0, insertAt)}
|
|
1395
|
+
${importBlock}${content.slice(insertAt)}`;
|
|
1480
1396
|
const pluginsMatch = content.match(/plugins\s*:\s*\[/);
|
|
1481
1397
|
if (!pluginsMatch || pluginsMatch.index === void 0) {
|
|
1482
1398
|
return false;
|
|
@@ -1485,47 +1401,47 @@ async function injectVitePlugin(cwd) {
|
|
|
1485
1401
|
const twEntry = content.includes("tailwindcss()") ? "" : "\n tailwindcss(),";
|
|
1486
1402
|
content = content.slice(0, pluginsInsertAt) + `
|
|
1487
1403
|
...csszyx(), // csszyx MUST come before tailwindcss${twEntry}` + content.slice(pluginsInsertAt);
|
|
1488
|
-
await
|
|
1489
|
-
printInfo(`Injected csszyx plugin into ${
|
|
1404
|
+
await fs.writeFile(configPath, content);
|
|
1405
|
+
printInfo(`Injected csszyx plugin into ${path.basename(configPath)}`);
|
|
1490
1406
|
return true;
|
|
1491
1407
|
}
|
|
1492
1408
|
async function injectNextPlugin(cwd) {
|
|
1493
1409
|
const candidates = [
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1410
|
+
path.join(cwd, "next.config.ts"),
|
|
1411
|
+
path.join(cwd, "next.config.mjs"),
|
|
1412
|
+
path.join(cwd, "next.config.js")
|
|
1497
1413
|
];
|
|
1498
1414
|
let configPath;
|
|
1499
1415
|
for (const c of candidates) {
|
|
1500
|
-
if (
|
|
1416
|
+
if (fs.existsSync(c)) {
|
|
1501
1417
|
configPath = c;
|
|
1502
1418
|
break;
|
|
1503
1419
|
}
|
|
1504
1420
|
}
|
|
1505
1421
|
if (!configPath) {
|
|
1506
|
-
configPath =
|
|
1507
|
-
await
|
|
1422
|
+
configPath = path.join(cwd, "next.config.js");
|
|
1423
|
+
await fs.writeFile(configPath, generateNextConfig());
|
|
1508
1424
|
printInfo("Created next.config.js with csszyx plugin");
|
|
1509
1425
|
return true;
|
|
1510
1426
|
}
|
|
1511
|
-
const content = await
|
|
1427
|
+
const content = await fs.readFile(configPath, "utf8");
|
|
1512
1428
|
if (content.includes("csszyx")) {
|
|
1513
1429
|
return true;
|
|
1514
1430
|
}
|
|
1515
1431
|
return false;
|
|
1516
1432
|
}
|
|
1517
1433
|
async function setupTsconfig(cwd) {
|
|
1518
|
-
let tsconfigPath =
|
|
1519
|
-
if (!
|
|
1520
|
-
const viteTsConfig =
|
|
1521
|
-
if (
|
|
1434
|
+
let tsconfigPath = path.join(cwd, "tsconfig.json");
|
|
1435
|
+
if (!fs.existsSync(tsconfigPath)) {
|
|
1436
|
+
const viteTsConfig = path.join(cwd, "tsconfig.app.json");
|
|
1437
|
+
if (fs.existsSync(viteTsConfig)) {
|
|
1522
1438
|
tsconfigPath = viteTsConfig;
|
|
1523
1439
|
}
|
|
1524
1440
|
}
|
|
1525
|
-
if (!
|
|
1441
|
+
if (!fs.existsSync(tsconfigPath)) {
|
|
1526
1442
|
return;
|
|
1527
1443
|
}
|
|
1528
|
-
let content = await
|
|
1444
|
+
let content = await fs.readFile(tsconfigPath, "utf8");
|
|
1529
1445
|
if (content.includes(".csszyx")) {
|
|
1530
1446
|
return;
|
|
1531
1447
|
}
|
|
@@ -1533,7 +1449,7 @@ async function setupTsconfig(cwd) {
|
|
|
1533
1449
|
if (includeMatch && includeMatch.index !== void 0) {
|
|
1534
1450
|
const insertPos = includeMatch.index + includeMatch[0].length;
|
|
1535
1451
|
content = content.slice(0, insertPos) + '\n "./.csszyx/theme.d.ts",\n "./.csszyx",' + content.slice(insertPos);
|
|
1536
|
-
await
|
|
1452
|
+
await fs.writeFile(tsconfigPath, content);
|
|
1537
1453
|
}
|
|
1538
1454
|
}
|
|
1539
1455
|
function generateConfigFile(config) {
|
|
@@ -1600,18 +1516,6 @@ function generateNextPluginInstructions() {
|
|
|
1600
1516
|
`;
|
|
1601
1517
|
}
|
|
1602
1518
|
|
|
1603
|
-
// src/commands/migrate.ts
|
|
1604
|
-
import fs5 from "fs";
|
|
1605
|
-
import path5 from "path";
|
|
1606
|
-
import readline from "readline";
|
|
1607
|
-
import fg from "fast-glob";
|
|
1608
|
-
|
|
1609
|
-
// src/migrate/ast-transformer.ts
|
|
1610
|
-
import { parse } from "@babel/parser";
|
|
1611
|
-
import _traverse from "@babel/traverse";
|
|
1612
|
-
import * as t from "@babel/types";
|
|
1613
|
-
|
|
1614
|
-
// src/migrate/sz-codegen.ts
|
|
1615
1519
|
function generateSzExpression(obj) {
|
|
1616
1520
|
return `{${objectToString(obj)}}`;
|
|
1617
1521
|
}
|
|
@@ -1642,7 +1546,9 @@ function objectToString(obj, indent = 0) {
|
|
|
1642
1546
|
const parts = entries.map(([k, v]) => `${formatKey(k)}: ${formatValue(v, indent)}`);
|
|
1643
1547
|
return `{ ${parts.join(", ")} }`;
|
|
1644
1548
|
}
|
|
1645
|
-
const lines = entries.map(
|
|
1549
|
+
const lines = entries.map(
|
|
1550
|
+
([k, v]) => `${innerSpaces}${formatKey(k)}: ${formatValue(v, indent + 2)},`
|
|
1551
|
+
);
|
|
1646
1552
|
return `{
|
|
1647
1553
|
${lines.join("\n")}
|
|
1648
1554
|
${spaces}}`;
|
|
@@ -1717,14 +1623,13 @@ function escapeString(s) {
|
|
|
1717
1623
|
return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
1718
1624
|
}
|
|
1719
1625
|
|
|
1720
|
-
|
|
1721
|
-
var REVERSE_PROPERTY_MAP = {
|
|
1626
|
+
const REVERSE_PROPERTY_MAP = {
|
|
1722
1627
|
// Background (ambiguous — disambiguated in class-parser)
|
|
1723
|
-
|
|
1628
|
+
bg: "bg",
|
|
1724
1629
|
"bg-clip": "bgClip",
|
|
1725
1630
|
"bg-origin": "bgOrigin",
|
|
1726
1631
|
// Border Radius
|
|
1727
|
-
|
|
1632
|
+
rounded: "rounded",
|
|
1728
1633
|
"rounded-t": "roundedT",
|
|
1729
1634
|
"rounded-r": "roundedR",
|
|
1730
1635
|
"rounded-b": "roundedB",
|
|
@@ -1740,7 +1645,7 @@ var REVERSE_PROPERTY_MAP = {
|
|
|
1740
1645
|
"rounded-es": "roundedEs",
|
|
1741
1646
|
"rounded-ee": "roundedEe",
|
|
1742
1647
|
// Border (ambiguous — disambiguated)
|
|
1743
|
-
|
|
1648
|
+
border: "border",
|
|
1744
1649
|
"border-t": "borderT",
|
|
1745
1650
|
"border-r": "borderR",
|
|
1746
1651
|
"border-b": "borderB",
|
|
@@ -1752,120 +1657,120 @@ var REVERSE_PROPERTY_MAP = {
|
|
|
1752
1657
|
// Divide
|
|
1753
1658
|
"divide-x": "divideX",
|
|
1754
1659
|
"divide-y": "divideY",
|
|
1755
|
-
|
|
1660
|
+
divide: "divideColor",
|
|
1756
1661
|
// Outline (ambiguous)
|
|
1757
|
-
|
|
1662
|
+
outline: "outline",
|
|
1758
1663
|
"outline-offset": "outlineOffset",
|
|
1759
1664
|
// Ring (v4: outset ring + inset ring)
|
|
1760
|
-
|
|
1665
|
+
ring: "ring",
|
|
1761
1666
|
"ring-offset": "ringOffset",
|
|
1762
1667
|
"inset-ring": "insetRing",
|
|
1763
1668
|
// Spacing
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1669
|
+
p: "p",
|
|
1670
|
+
pt: "pt",
|
|
1671
|
+
pr: "pr",
|
|
1672
|
+
pb: "pb",
|
|
1673
|
+
pl: "pl",
|
|
1674
|
+
px: "px",
|
|
1675
|
+
py: "py",
|
|
1676
|
+
ps: "ps",
|
|
1677
|
+
pe: "pe",
|
|
1678
|
+
m: "m",
|
|
1679
|
+
mt: "mt",
|
|
1680
|
+
mr: "mr",
|
|
1681
|
+
mb: "mb",
|
|
1682
|
+
ml: "ml",
|
|
1683
|
+
mx: "mx",
|
|
1684
|
+
my: "my",
|
|
1685
|
+
ms: "ms",
|
|
1686
|
+
me: "me",
|
|
1782
1687
|
// Space between
|
|
1783
1688
|
"space-x": "spaceX",
|
|
1784
1689
|
"space-y": "spaceY",
|
|
1785
1690
|
// Sizing
|
|
1786
|
-
|
|
1691
|
+
w: "w",
|
|
1787
1692
|
"min-w": "minW",
|
|
1788
1693
|
"max-w": "maxW",
|
|
1789
|
-
|
|
1694
|
+
h: "h",
|
|
1790
1695
|
"min-h": "minH",
|
|
1791
1696
|
"max-h": "maxH",
|
|
1792
|
-
|
|
1697
|
+
size: "size",
|
|
1793
1698
|
// Layout
|
|
1794
|
-
|
|
1795
|
-
|
|
1699
|
+
aspect: "aspect",
|
|
1700
|
+
columns: "columns",
|
|
1796
1701
|
"break-after": "breakAfter",
|
|
1797
1702
|
"break-before": "breakBefore",
|
|
1798
1703
|
"break-inside": "breakInside",
|
|
1799
1704
|
"box-decoration": "boxDecoration",
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1705
|
+
box: "box",
|
|
1706
|
+
float: "float",
|
|
1707
|
+
clear: "clear",
|
|
1708
|
+
object: "objectFit",
|
|
1804
1709
|
// ambiguous — objectFit vs objectPos (objectPos for position values)
|
|
1805
|
-
|
|
1710
|
+
overflow: "overflow",
|
|
1806
1711
|
"overflow-x": "overflowX",
|
|
1807
1712
|
"overflow-y": "overflowY",
|
|
1808
|
-
|
|
1713
|
+
overscroll: "overscroll",
|
|
1809
1714
|
"overscroll-x": "overscrollX",
|
|
1810
1715
|
"overscroll-y": "overscrollY",
|
|
1811
|
-
|
|
1716
|
+
z: "z",
|
|
1812
1717
|
// Inset
|
|
1813
|
-
|
|
1718
|
+
inset: "inset",
|
|
1814
1719
|
"inset-x": "insetX",
|
|
1815
1720
|
"inset-y": "insetY",
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1721
|
+
top: "top",
|
|
1722
|
+
right: "right",
|
|
1723
|
+
bottom: "bottom",
|
|
1724
|
+
left: "left",
|
|
1820
1725
|
// TW v4.2: start/end are deprecated — migrate to inset-s/inset-e
|
|
1821
|
-
|
|
1822
|
-
|
|
1726
|
+
start: "insetS",
|
|
1727
|
+
end: "insetE",
|
|
1823
1728
|
// Typography (ambiguous — text-*, font-* disambiguated)
|
|
1824
|
-
|
|
1729
|
+
text: "color",
|
|
1825
1730
|
// default for text- prefix
|
|
1826
|
-
|
|
1731
|
+
font: "fontWeight",
|
|
1827
1732
|
// default for font- prefix
|
|
1828
|
-
|
|
1733
|
+
decoration: "decoration",
|
|
1829
1734
|
// ambiguous
|
|
1830
1735
|
"underline-offset": "underlineOffset",
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1736
|
+
indent: "indent",
|
|
1737
|
+
align: "align",
|
|
1738
|
+
whitespace: "whitespace",
|
|
1739
|
+
break: "break",
|
|
1835
1740
|
// ambiguous with break-after/before/inside (handled by prefix matching)
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1741
|
+
hyphens: "hyphens",
|
|
1742
|
+
content: "content",
|
|
1743
|
+
leading: "leading",
|
|
1744
|
+
tracking: "tracking",
|
|
1745
|
+
list: "list",
|
|
1841
1746
|
// ambiguous
|
|
1842
1747
|
"list-image": "listImg",
|
|
1843
1748
|
// Flex & Grid
|
|
1844
|
-
|
|
1845
|
-
|
|
1749
|
+
basis: "basis",
|
|
1750
|
+
flex: "flex",
|
|
1846
1751
|
// ambiguous (boolean flex, flexDirection, flexWrap)
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1752
|
+
grow: "grow",
|
|
1753
|
+
shrink: "shrink",
|
|
1754
|
+
order: "order",
|
|
1755
|
+
items: "items",
|
|
1756
|
+
self: "self",
|
|
1757
|
+
justify: "justify",
|
|
1853
1758
|
"justify-items": "justifyItems",
|
|
1854
1759
|
"justify-self": "justifySelf",
|
|
1855
1760
|
"place-content": "placeContent",
|
|
1856
1761
|
"place-items": "placeItems",
|
|
1857
1762
|
"place-self": "placeSelf",
|
|
1858
|
-
|
|
1763
|
+
gap: "gap",
|
|
1859
1764
|
"gap-x": "gapX",
|
|
1860
1765
|
"gap-y": "gapY",
|
|
1861
1766
|
// Grid
|
|
1862
1767
|
"grid-cols": "gridCols",
|
|
1863
1768
|
"grid-rows": "gridRows",
|
|
1864
|
-
|
|
1769
|
+
col: "col",
|
|
1865
1770
|
"col-span": "colSpan",
|
|
1866
1771
|
"col-start": "colStart",
|
|
1867
1772
|
"col-end": "colEnd",
|
|
1868
|
-
|
|
1773
|
+
row: "row",
|
|
1869
1774
|
"row-span": "rowSpan",
|
|
1870
1775
|
"row-start": "rowStart",
|
|
1871
1776
|
"row-end": "rowEnd",
|
|
@@ -1873,22 +1778,22 @@ var REVERSE_PROPERTY_MAP = {
|
|
|
1873
1778
|
"auto-cols": "autoCols",
|
|
1874
1779
|
"auto-rows": "autoRows",
|
|
1875
1780
|
// Effects
|
|
1876
|
-
|
|
1781
|
+
shadow: "shadow",
|
|
1877
1782
|
// ambiguous (shadow vs shadowColor)
|
|
1878
1783
|
"inset-shadow": "insetShadow",
|
|
1879
|
-
|
|
1784
|
+
opacity: "opacity",
|
|
1880
1785
|
"mix-blend": "mixBlend",
|
|
1881
1786
|
"bg-blend": "bgBlend",
|
|
1882
1787
|
// Filters
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1788
|
+
blur: "blur",
|
|
1789
|
+
brightness: "brightness",
|
|
1790
|
+
contrast: "contrast",
|
|
1886
1791
|
"drop-shadow": "dropShadow",
|
|
1887
|
-
|
|
1792
|
+
grayscale: "grayscale",
|
|
1888
1793
|
"hue-rotate": "hueRotate",
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1794
|
+
invert: "invert",
|
|
1795
|
+
saturate: "saturate",
|
|
1796
|
+
sepia: "sepia",
|
|
1892
1797
|
"backdrop-blur": "backdropBlur",
|
|
1893
1798
|
"backdrop-brightness": "backdropBrightness",
|
|
1894
1799
|
"backdrop-contrast": "backdropContrast",
|
|
@@ -1899,27 +1804,27 @@ var REVERSE_PROPERTY_MAP = {
|
|
|
1899
1804
|
"backdrop-saturate": "backdropSaturate",
|
|
1900
1805
|
"backdrop-sepia": "backdropSepia",
|
|
1901
1806
|
// Transforms
|
|
1902
|
-
|
|
1807
|
+
scale: "scale",
|
|
1903
1808
|
"scale-x": "scaleX",
|
|
1904
1809
|
"scale-y": "scaleY",
|
|
1905
|
-
|
|
1810
|
+
rotate: "rotate",
|
|
1906
1811
|
"translate-x": "translateX",
|
|
1907
1812
|
"translate-y": "translateY",
|
|
1908
1813
|
"skew-x": "skewX",
|
|
1909
1814
|
"skew-y": "skewY",
|
|
1910
|
-
|
|
1815
|
+
origin: "origin",
|
|
1911
1816
|
// Transitions & Animation
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1817
|
+
transition: "transition",
|
|
1818
|
+
duration: "duration",
|
|
1819
|
+
ease: "ease",
|
|
1820
|
+
delay: "delay",
|
|
1821
|
+
animate: "animate",
|
|
1917
1822
|
// Interactivity
|
|
1918
|
-
|
|
1919
|
-
|
|
1823
|
+
cursor: "cursor",
|
|
1824
|
+
caret: "caret",
|
|
1920
1825
|
"pointer-events": "pointerEvents",
|
|
1921
|
-
|
|
1922
|
-
|
|
1826
|
+
resize: "resize",
|
|
1827
|
+
scroll: "scroll",
|
|
1923
1828
|
"scroll-m": "scrollM",
|
|
1924
1829
|
"scroll-mt": "scrollMt",
|
|
1925
1830
|
"scroll-mr": "scrollMr",
|
|
@@ -1938,96 +1843,96 @@ var REVERSE_PROPERTY_MAP = {
|
|
|
1938
1843
|
"scroll-pe": "scrollPe",
|
|
1939
1844
|
"scroll-px": "scrollPx",
|
|
1940
1845
|
"scroll-py": "scrollPy",
|
|
1941
|
-
|
|
1846
|
+
snap: "snapType",
|
|
1942
1847
|
// ambiguous
|
|
1943
|
-
|
|
1944
|
-
|
|
1848
|
+
touch: "touch",
|
|
1849
|
+
select: "select",
|
|
1945
1850
|
"will-change": "willChange",
|
|
1946
|
-
|
|
1851
|
+
accent: "accent",
|
|
1947
1852
|
// SVG
|
|
1948
|
-
|
|
1949
|
-
|
|
1853
|
+
fill: "fill",
|
|
1854
|
+
stroke: "stroke",
|
|
1950
1855
|
// Tables
|
|
1951
1856
|
"border-spacing": "borderSpacing",
|
|
1952
|
-
|
|
1857
|
+
table: "tableLayout",
|
|
1953
1858
|
// ambiguous with boolean "table" display
|
|
1954
|
-
|
|
1859
|
+
caption: "caption",
|
|
1955
1860
|
// Line clamp
|
|
1956
1861
|
"line-clamp": "lineClamp",
|
|
1957
|
-
|
|
1862
|
+
wrap: "wrap",
|
|
1958
1863
|
// Text shadow
|
|
1959
1864
|
"text-shadow": "textShadow",
|
|
1960
1865
|
// Gradient stops
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1866
|
+
from: "from",
|
|
1867
|
+
via: "via",
|
|
1868
|
+
to: "to",
|
|
1964
1869
|
// Masks
|
|
1965
|
-
|
|
1870
|
+
mask: "mask",
|
|
1966
1871
|
// Forced colors
|
|
1967
1872
|
"forced-color-adjust": "forcedColorAdjust",
|
|
1968
1873
|
// Perspective
|
|
1969
|
-
|
|
1874
|
+
perspective: "perspective",
|
|
1970
1875
|
"perspective-origin": "perspectiveOrigin",
|
|
1971
|
-
|
|
1876
|
+
backface: "backface"
|
|
1972
1877
|
};
|
|
1973
|
-
|
|
1878
|
+
const REVERSE_BOOLEAN_MAP = {
|
|
1974
1879
|
// Display
|
|
1975
|
-
|
|
1976
|
-
|
|
1880
|
+
block: "block",
|
|
1881
|
+
inline: "inline",
|
|
1977
1882
|
"inline-block": "inlineBlock",
|
|
1978
|
-
|
|
1883
|
+
flex: "flex",
|
|
1979
1884
|
"inline-flex": "inlineFlex",
|
|
1980
|
-
|
|
1885
|
+
grid: "grid",
|
|
1981
1886
|
"inline-grid": "inlineGrid",
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1887
|
+
hidden: "hidden",
|
|
1888
|
+
contents: "contents",
|
|
1889
|
+
table: "table",
|
|
1985
1890
|
"table-row": "tableRow",
|
|
1986
1891
|
"table-cell": "tableCell",
|
|
1987
1892
|
"flow-root": "flowRoot",
|
|
1988
1893
|
"list-item": "listItem",
|
|
1989
1894
|
// Position
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1895
|
+
static: "static",
|
|
1896
|
+
fixed: "fixed",
|
|
1897
|
+
absolute: "absolute",
|
|
1898
|
+
relative: "relative",
|
|
1899
|
+
sticky: "sticky",
|
|
1995
1900
|
// Visibility
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1901
|
+
visible: "visible",
|
|
1902
|
+
invisible: "invisible",
|
|
1903
|
+
collapse: "collapse",
|
|
1999
1904
|
// Typography
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
1905
|
+
truncate: "truncate",
|
|
1906
|
+
uppercase: "uppercase",
|
|
1907
|
+
lowercase: "lowercase",
|
|
1908
|
+
capitalize: "capitalize",
|
|
2004
1909
|
"normal-case": "normalCase",
|
|
2005
|
-
|
|
2006
|
-
|
|
1910
|
+
underline: "underline",
|
|
1911
|
+
overline: "overline",
|
|
2007
1912
|
"line-through": "lineThrough",
|
|
2008
1913
|
"no-underline": "noUnderline",
|
|
2009
|
-
|
|
1914
|
+
italic: "italic",
|
|
2010
1915
|
"not-italic": "notItalic",
|
|
2011
|
-
|
|
1916
|
+
antialiased: "antialiased",
|
|
2012
1917
|
"subpixel-antialiased": "subpixelAntialiased",
|
|
2013
1918
|
// Flexbox
|
|
2014
1919
|
// flexWrap is string-based, not boolean — removed from boolean map
|
|
2015
1920
|
// Filters (defaults)
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
1921
|
+
blur: "blur",
|
|
1922
|
+
grayscale: "grayscale",
|
|
1923
|
+
invert: "invert",
|
|
1924
|
+
sepia: "sepia",
|
|
2020
1925
|
"backdrop-blur": "backdropBlur",
|
|
2021
1926
|
"backdrop-grayscale": "backdropGrayscale",
|
|
2022
1927
|
"backdrop-invert": "backdropInvert",
|
|
2023
1928
|
"backdrop-sepia": "backdropSepia",
|
|
2024
1929
|
// Misc
|
|
2025
|
-
|
|
2026
|
-
|
|
1930
|
+
container: "container",
|
|
1931
|
+
prose: "prose",
|
|
2027
1932
|
"sr-only": "srOnly",
|
|
2028
1933
|
"not-sr-only": "notSrOnly",
|
|
2029
|
-
|
|
2030
|
-
|
|
1934
|
+
isolate: "isolate",
|
|
1935
|
+
ordinal: "ordinal",
|
|
2031
1936
|
"slashed-zero": "slashedZero",
|
|
2032
1937
|
// Divide/Space reverse
|
|
2033
1938
|
"divide-x-reverse": "divideXReverse",
|
|
@@ -2035,10 +1940,10 @@ var REVERSE_BOOLEAN_MAP = {
|
|
|
2035
1940
|
"space-x-reverse": "spaceXReverse",
|
|
2036
1941
|
"space-y-reverse": "spaceYReverse",
|
|
2037
1942
|
// Ring/Outline/Border-radius (boolean defaults)
|
|
2038
|
-
|
|
1943
|
+
ring: "ring",
|
|
2039
1944
|
"inset-ring": "insetRing",
|
|
2040
|
-
|
|
2041
|
-
|
|
1945
|
+
outline: "outline",
|
|
1946
|
+
rounded: "rounded",
|
|
2042
1947
|
// Transforms
|
|
2043
1948
|
"scale-3d": "scale",
|
|
2044
1949
|
"translate-3d": "translate",
|
|
@@ -2074,7 +1979,7 @@ var REVERSE_BOOLEAN_MAP = {
|
|
|
2074
1979
|
"appearance-none": "appearance",
|
|
2075
1980
|
"appearance-auto": "appearance"
|
|
2076
1981
|
};
|
|
2077
|
-
|
|
1982
|
+
const BOOLEAN_VALUE_MAP = {
|
|
2078
1983
|
// Snap types
|
|
2079
1984
|
"snap-none": { prop: "snapType", value: "none" },
|
|
2080
1985
|
"snap-x": { prop: "snapType", value: "x" },
|
|
@@ -2110,13 +2015,13 @@ var BOOLEAN_VALUE_MAP = {
|
|
|
2110
2015
|
"transform-gpu": { prop: "transform", value: "gpu" },
|
|
2111
2016
|
"transform-cpu": { prop: "transform", value: "cpu" }
|
|
2112
2017
|
};
|
|
2113
|
-
|
|
2018
|
+
const SORTED_PREFIXES = Object.keys(REVERSE_PROPERTY_MAP).sort((a, b) => {
|
|
2114
2019
|
if (b.length !== a.length) {
|
|
2115
2020
|
return b.length - a.length;
|
|
2116
2021
|
}
|
|
2117
2022
|
return a.localeCompare(b);
|
|
2118
2023
|
});
|
|
2119
|
-
|
|
2024
|
+
const NEGATIVE_ALLOWED = /* @__PURE__ */ new Set([
|
|
2120
2025
|
"m",
|
|
2121
2026
|
"mt",
|
|
2122
2027
|
"mr",
|
|
@@ -2162,7 +2067,7 @@ var NEGATIVE_ALLOWED = /* @__PURE__ */ new Set([
|
|
|
2162
2067
|
"hue-rotate",
|
|
2163
2068
|
"backdrop-hue-rotate"
|
|
2164
2069
|
]);
|
|
2165
|
-
|
|
2070
|
+
const FRACTION_SUPPORTED = /* @__PURE__ */ new Set([
|
|
2166
2071
|
"w",
|
|
2167
2072
|
"min-w",
|
|
2168
2073
|
"max-w",
|
|
@@ -2183,7 +2088,7 @@ var FRACTION_SUPPORTED = /* @__PURE__ */ new Set([
|
|
|
2183
2088
|
"translate-x",
|
|
2184
2089
|
"translate-y"
|
|
2185
2090
|
]);
|
|
2186
|
-
|
|
2091
|
+
const SPACING_PROPS = /* @__PURE__ */ new Set([
|
|
2187
2092
|
"p",
|
|
2188
2093
|
"pt",
|
|
2189
2094
|
"pr",
|
|
@@ -2247,7 +2152,7 @@ var SPACING_PROPS = /* @__PURE__ */ new Set([
|
|
|
2247
2152
|
"translate-x",
|
|
2248
2153
|
"translate-y"
|
|
2249
2154
|
]);
|
|
2250
|
-
|
|
2155
|
+
const TEXT_SIZE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2251
2156
|
"xs",
|
|
2252
2157
|
"sm",
|
|
2253
2158
|
"base",
|
|
@@ -2262,25 +2167,10 @@ var TEXT_SIZE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
2262
2167
|
"8xl",
|
|
2263
2168
|
"9xl"
|
|
2264
2169
|
]);
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
"justify",
|
|
2270
|
-
"start",
|
|
2271
|
-
"end"
|
|
2272
|
-
]);
|
|
2273
|
-
var TEXT_WRAP_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2274
|
-
"wrap",
|
|
2275
|
-
"nowrap",
|
|
2276
|
-
"balance",
|
|
2277
|
-
"pretty"
|
|
2278
|
-
]);
|
|
2279
|
-
var TEXT_OVERFLOW_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2280
|
-
"ellipsis",
|
|
2281
|
-
"clip"
|
|
2282
|
-
]);
|
|
2283
|
-
var FONT_WEIGHT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2170
|
+
const TEXT_ALIGN_KEYWORDS = /* @__PURE__ */ new Set(["left", "center", "right", "justify", "start", "end"]);
|
|
2171
|
+
const TEXT_WRAP_KEYWORDS = /* @__PURE__ */ new Set(["wrap", "nowrap", "balance", "pretty"]);
|
|
2172
|
+
const TEXT_OVERFLOW_KEYWORDS = /* @__PURE__ */ new Set(["ellipsis", "clip"]);
|
|
2173
|
+
const FONT_WEIGHT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2284
2174
|
"thin",
|
|
2285
2175
|
"extralight",
|
|
2286
2176
|
"light",
|
|
@@ -2291,12 +2181,8 @@ var FONT_WEIGHT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
2291
2181
|
"extrabold",
|
|
2292
2182
|
"black"
|
|
2293
2183
|
]);
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
"serif",
|
|
2297
|
-
"mono"
|
|
2298
|
-
]);
|
|
2299
|
-
var FONT_STRETCH_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2184
|
+
const FONT_FAMILY_KEYWORDS = /* @__PURE__ */ new Set(["sans", "serif", "mono"]);
|
|
2185
|
+
const FONT_STRETCH_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2300
2186
|
"ultra-condensed",
|
|
2301
2187
|
"extra-condensed",
|
|
2302
2188
|
"condensed",
|
|
@@ -2306,8 +2192,8 @@ var FONT_STRETCH_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
2306
2192
|
"extra-expanded",
|
|
2307
2193
|
"ultra-expanded"
|
|
2308
2194
|
]);
|
|
2309
|
-
|
|
2310
|
-
|
|
2195
|
+
const BORDER_WIDTH_KEYWORDS = /* @__PURE__ */ new Set(["0", "2", "4", "8"]);
|
|
2196
|
+
const BORDER_STYLE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2311
2197
|
"solid",
|
|
2312
2198
|
"dashed",
|
|
2313
2199
|
"dotted",
|
|
@@ -2315,7 +2201,7 @@ var BORDER_STYLE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
2315
2201
|
"none",
|
|
2316
2202
|
"hidden"
|
|
2317
2203
|
]);
|
|
2318
|
-
|
|
2204
|
+
const BG_POSITION_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2319
2205
|
"center",
|
|
2320
2206
|
"top",
|
|
2321
2207
|
"bottom",
|
|
@@ -2326,8 +2212,8 @@ var BG_POSITION_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
2326
2212
|
"right-top",
|
|
2327
2213
|
"right-bottom"
|
|
2328
2214
|
]);
|
|
2329
|
-
|
|
2330
|
-
|
|
2215
|
+
const BG_SIZE_KEYWORDS = /* @__PURE__ */ new Set(["cover", "contain", "auto"]);
|
|
2216
|
+
const BG_REPEAT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2331
2217
|
"repeat",
|
|
2332
2218
|
"no-repeat",
|
|
2333
2219
|
"repeat-x",
|
|
@@ -2335,9 +2221,9 @@ var BG_REPEAT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
2335
2221
|
"round",
|
|
2336
2222
|
"space"
|
|
2337
2223
|
]);
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2224
|
+
const BG_ATTACHMENT_KEYWORDS = /* @__PURE__ */ new Set(["fixed", "local", "scroll"]);
|
|
2225
|
+
const OBJECT_FIT_KEYWORDS = /* @__PURE__ */ new Set(["contain", "cover", "fill", "none", "scale-down"]);
|
|
2226
|
+
const OBJECT_POSITION_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2341
2227
|
"center",
|
|
2342
2228
|
"top",
|
|
2343
2229
|
"bottom",
|
|
@@ -2348,11 +2234,19 @@ var OBJECT_POSITION_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
2348
2234
|
"right-top",
|
|
2349
2235
|
"right-bottom"
|
|
2350
2236
|
]);
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2237
|
+
const SHADOW_SIZE_KEYWORDS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl", "inner", "none"]);
|
|
2238
|
+
const OUTLINE_STYLE_KEYWORDS = /* @__PURE__ */ new Set(["none", "dashed", "dotted", "double"]);
|
|
2239
|
+
const DECORATION_STYLE_KEYWORDS = /* @__PURE__ */ new Set(["solid", "double", "dotted", "dashed", "wavy"]);
|
|
2240
|
+
const DECORATION_THICKNESS_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2241
|
+
"auto",
|
|
2242
|
+
"from-font",
|
|
2243
|
+
"0",
|
|
2244
|
+
"1",
|
|
2245
|
+
"2",
|
|
2246
|
+
"4",
|
|
2247
|
+
"8"
|
|
2248
|
+
]);
|
|
2249
|
+
const TRANSITION_PROPERTY_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2356
2250
|
"none",
|
|
2357
2251
|
"all",
|
|
2358
2252
|
"colors",
|
|
@@ -2360,7 +2254,7 @@ var TRANSITION_PROPERTY_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
2360
2254
|
"shadow",
|
|
2361
2255
|
"transform"
|
|
2362
2256
|
]);
|
|
2363
|
-
|
|
2257
|
+
const REVERSE_VARIANT_MAP = {
|
|
2364
2258
|
"focus-within": "focusWithin",
|
|
2365
2259
|
"focus-visible": "focusVisible",
|
|
2366
2260
|
"first-of-type": "firstOfType",
|
|
@@ -2385,7 +2279,7 @@ var REVERSE_VARIANT_MAP = {
|
|
|
2385
2279
|
"@max-xl": "@maxXl",
|
|
2386
2280
|
"@max-2xl": "@max2xl"
|
|
2387
2281
|
};
|
|
2388
|
-
|
|
2282
|
+
const KNOWN_SIMPLE_VARIANTS = /* @__PURE__ */ new Set([
|
|
2389
2283
|
"sm",
|
|
2390
2284
|
"md",
|
|
2391
2285
|
"lg",
|
|
@@ -2432,7 +2326,7 @@ var KNOWN_SIMPLE_VARIANTS = /* @__PURE__ */ new Set([
|
|
|
2432
2326
|
"ltr",
|
|
2433
2327
|
"rtl"
|
|
2434
2328
|
]);
|
|
2435
|
-
|
|
2329
|
+
/* @__PURE__ */ new Set([
|
|
2436
2330
|
...KNOWN_SIMPLE_VARIANTS,
|
|
2437
2331
|
"focus-within",
|
|
2438
2332
|
"focus-visible",
|
|
@@ -2457,7 +2351,6 @@ var KNOWN_VARIANTS = /* @__PURE__ */ new Set([
|
|
|
2457
2351
|
"pointer-none"
|
|
2458
2352
|
]);
|
|
2459
2353
|
|
|
2460
|
-
// src/migrate/class-parser.ts
|
|
2461
2354
|
function parseClass(cls) {
|
|
2462
2355
|
let important = false;
|
|
2463
2356
|
let input = cls;
|
|
@@ -2487,7 +2380,10 @@ function parseClass(cls) {
|
|
|
2487
2380
|
continue;
|
|
2488
2381
|
}
|
|
2489
2382
|
if (REVERSE_BOOLEAN_MAP[source]) {
|
|
2490
|
-
return applyImportant(
|
|
2383
|
+
return applyImportant(
|
|
2384
|
+
{ prop: REVERSE_BOOLEAN_MAP[source], value: true },
|
|
2385
|
+
important
|
|
2386
|
+
);
|
|
2491
2387
|
}
|
|
2492
2388
|
if (prefix === "divide-x" || prefix === "divide-y") {
|
|
2493
2389
|
return applyImportant({ prop, value: true }, important);
|
|
@@ -2495,12 +2391,21 @@ function parseClass(cls) {
|
|
|
2495
2391
|
if (prefix === "border") {
|
|
2496
2392
|
return applyImportant({ prop: "border", value: true }, important);
|
|
2497
2393
|
}
|
|
2498
|
-
if ([
|
|
2394
|
+
if ([
|
|
2395
|
+
"border-t",
|
|
2396
|
+
"border-r",
|
|
2397
|
+
"border-b",
|
|
2398
|
+
"border-l",
|
|
2399
|
+
"border-x",
|
|
2400
|
+
"border-y",
|
|
2401
|
+
"border-s",
|
|
2402
|
+
"border-e"
|
|
2403
|
+
].includes(prefix)) {
|
|
2499
2404
|
return applyImportant({ prop, value: true }, important);
|
|
2500
2405
|
}
|
|
2501
2406
|
continue;
|
|
2502
2407
|
}
|
|
2503
|
-
if (source.startsWith(prefix
|
|
2408
|
+
if (source.startsWith(`${prefix}-`)) {
|
|
2504
2409
|
const rawValue = source.slice(prefix.length + 1);
|
|
2505
2410
|
if (!rawValue) {
|
|
2506
2411
|
continue;
|
|
@@ -2525,10 +2430,13 @@ function parseClass(cls) {
|
|
|
2525
2430
|
const inner = input.slice(1, -1);
|
|
2526
2431
|
if (inner.startsWith("--")) {
|
|
2527
2432
|
const colonIdx = inner.indexOf(":");
|
|
2528
|
-
return applyImportant(
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2433
|
+
return applyImportant(
|
|
2434
|
+
{
|
|
2435
|
+
prop: inner.slice(0, colonIdx),
|
|
2436
|
+
value: inner.slice(colonIdx + 1)
|
|
2437
|
+
},
|
|
2438
|
+
important
|
|
2439
|
+
);
|
|
2532
2440
|
}
|
|
2533
2441
|
}
|
|
2534
2442
|
return null;
|
|
@@ -2538,13 +2446,13 @@ function applyImportant(result, important) {
|
|
|
2538
2446
|
return result;
|
|
2539
2447
|
}
|
|
2540
2448
|
if (typeof result.value === "string") {
|
|
2541
|
-
return { prop: result.prop, value: result.value
|
|
2449
|
+
return { prop: result.prop, value: `${result.value}!` };
|
|
2542
2450
|
}
|
|
2543
2451
|
if (typeof result.value === "boolean") {
|
|
2544
2452
|
return { prop: result.prop, value: "!" };
|
|
2545
2453
|
}
|
|
2546
2454
|
if (typeof result.value === "number") {
|
|
2547
|
-
return { prop: result.prop, value: String(result.value)
|
|
2455
|
+
return { prop: result.prop, value: `${String(result.value)}!` };
|
|
2548
2456
|
}
|
|
2549
2457
|
return result;
|
|
2550
2458
|
}
|
|
@@ -2597,14 +2505,13 @@ function tryGradient(cls, negative) {
|
|
|
2597
2505
|
return null;
|
|
2598
2506
|
}
|
|
2599
2507
|
let colorInterp;
|
|
2600
|
-
const slashIdx = findTopLevelSlash(input);
|
|
2508
|
+
const slashIdx = findTopLevelSlash$1(input);
|
|
2601
2509
|
if (slashIdx !== -1) {
|
|
2602
2510
|
colorInterp = input.slice(slashIdx + 1);
|
|
2603
2511
|
input = input.slice(0, slashIdx);
|
|
2604
2512
|
}
|
|
2605
2513
|
const grad = { gradient: type };
|
|
2606
|
-
if (input === "" || input === void 0) {
|
|
2607
|
-
} else if (input.startsWith("-")) {
|
|
2514
|
+
if (input === "" || input === void 0) ; else if (input.startsWith("-")) {
|
|
2608
2515
|
const dir = input.slice(1);
|
|
2609
2516
|
if (dir.startsWith("[") && dir.endsWith("]")) {
|
|
2610
2517
|
grad.dir = dir.slice(1, -1).replace(/_/g, " ");
|
|
@@ -2621,7 +2528,7 @@ function tryGradient(cls, negative) {
|
|
|
2621
2528
|
}
|
|
2622
2529
|
return { prop: "bgImg", value: grad };
|
|
2623
2530
|
}
|
|
2624
|
-
function findTopLevelSlash(s) {
|
|
2531
|
+
function findTopLevelSlash$1(s) {
|
|
2625
2532
|
let depth = 0;
|
|
2626
2533
|
for (let i = 0; i < s.length; i++) {
|
|
2627
2534
|
if (s[i] === "[" || s[i] === "(") {
|
|
@@ -2635,7 +2542,7 @@ function findTopLevelSlash(s) {
|
|
|
2635
2542
|
return -1;
|
|
2636
2543
|
}
|
|
2637
2544
|
function disambiguateAndParse(prefix, rawValue, negative) {
|
|
2638
|
-
const slashIdx = findTopLevelSlash(rawValue);
|
|
2545
|
+
const slashIdx = findTopLevelSlash$1(rawValue);
|
|
2639
2546
|
let opacity;
|
|
2640
2547
|
let value = rawValue;
|
|
2641
2548
|
if (slashIdx !== -1 && !isGradientPrefix(prefix)) {
|
|
@@ -2647,7 +2554,7 @@ function disambiguateAndParse(prefix, rawValue, negative) {
|
|
|
2647
2554
|
opacity = opacity.slice(1, -1);
|
|
2648
2555
|
if (!String(opacity).includes("%")) {
|
|
2649
2556
|
const opNum = Number(opacity);
|
|
2650
|
-
if (!isNaN(opNum)) {
|
|
2557
|
+
if (!Number.isNaN(opNum)) {
|
|
2651
2558
|
opacity = opNum;
|
|
2652
2559
|
}
|
|
2653
2560
|
}
|
|
@@ -2655,7 +2562,7 @@ function disambiguateAndParse(prefix, rawValue, negative) {
|
|
|
2655
2562
|
opacity = opacity.slice(1, -1);
|
|
2656
2563
|
} else {
|
|
2657
2564
|
const opNum = Number(opacity);
|
|
2658
|
-
if (!isNaN(opNum)) {
|
|
2565
|
+
if (!Number.isNaN(opNum)) {
|
|
2659
2566
|
opacity = opNum;
|
|
2660
2567
|
}
|
|
2661
2568
|
}
|
|
@@ -2711,7 +2618,7 @@ function disambiguate(prefix, value, negative) {
|
|
|
2711
2618
|
case "ease":
|
|
2712
2619
|
return { prop: "ease", value: parseValue("ease", value, negative) };
|
|
2713
2620
|
case "snap":
|
|
2714
|
-
return disambiguateSnap(
|
|
2621
|
+
return disambiguateSnap();
|
|
2715
2622
|
case "flex":
|
|
2716
2623
|
return disambiguateFlex(value);
|
|
2717
2624
|
case "table":
|
|
@@ -2819,7 +2726,7 @@ function disambiguateOutline(value) {
|
|
|
2819
2726
|
return { prop: "outlineStyle", value };
|
|
2820
2727
|
}
|
|
2821
2728
|
const num = Number(value);
|
|
2822
|
-
if (!isNaN(num) && Number.isInteger(num)) {
|
|
2729
|
+
if (!Number.isNaN(num) && Number.isInteger(num)) {
|
|
2823
2730
|
return { prop: "outline", value: num };
|
|
2824
2731
|
}
|
|
2825
2732
|
if (isArbitraryDimension(value)) {
|
|
@@ -2833,7 +2740,7 @@ function disambiguateDecoration(value) {
|
|
|
2833
2740
|
}
|
|
2834
2741
|
if (DECORATION_THICKNESS_KEYWORDS.has(value)) {
|
|
2835
2742
|
const num = Number(value);
|
|
2836
|
-
if (!isNaN(num)) {
|
|
2743
|
+
if (!Number.isNaN(num)) {
|
|
2837
2744
|
return { prop: "decorationThickness", value };
|
|
2838
2745
|
}
|
|
2839
2746
|
return { prop: "decorationThickness", value };
|
|
@@ -2842,7 +2749,7 @@ function disambiguateDecoration(value) {
|
|
|
2842
2749
|
}
|
|
2843
2750
|
function disambiguateRing(value, negative) {
|
|
2844
2751
|
const num = Number(value);
|
|
2845
|
-
if (!isNaN(num) && Number.isInteger(num)) {
|
|
2752
|
+
if (!Number.isNaN(num) && Number.isInteger(num)) {
|
|
2846
2753
|
return { prop: "ring", value: negative ? -num : num };
|
|
2847
2754
|
}
|
|
2848
2755
|
if (isArbitraryDimension(value)) {
|
|
@@ -2852,14 +2759,14 @@ function disambiguateRing(value, negative) {
|
|
|
2852
2759
|
}
|
|
2853
2760
|
function disambiguateRingOffset(value) {
|
|
2854
2761
|
const num = Number(value);
|
|
2855
|
-
if (!isNaN(num) && Number.isInteger(num)) {
|
|
2762
|
+
if (!Number.isNaN(num) && Number.isInteger(num)) {
|
|
2856
2763
|
return { prop: "ringOffset", value: num };
|
|
2857
2764
|
}
|
|
2858
2765
|
return { prop: "ringOffsetColor", value: parseStringValue(value) };
|
|
2859
2766
|
}
|
|
2860
2767
|
function disambiguateInsetRing(value, negative) {
|
|
2861
2768
|
const num = Number(value);
|
|
2862
|
-
if (!isNaN(num) && Number.isInteger(num)) {
|
|
2769
|
+
if (!Number.isNaN(num) && Number.isInteger(num)) {
|
|
2863
2770
|
return { prop: "insetRing", value: negative ? -num : num };
|
|
2864
2771
|
}
|
|
2865
2772
|
if (isArbitraryDimension(value)) {
|
|
@@ -2879,7 +2786,7 @@ function disambiguateInsetShadow(value) {
|
|
|
2879
2786
|
}
|
|
2880
2787
|
function disambiguateStroke(value) {
|
|
2881
2788
|
const num = Number(value);
|
|
2882
|
-
if (!isNaN(num) && Number.isInteger(num)) {
|
|
2789
|
+
if (!Number.isNaN(num) && Number.isInteger(num)) {
|
|
2883
2790
|
return { prop: "strokeWidth", value: num };
|
|
2884
2791
|
}
|
|
2885
2792
|
return { prop: "stroke", value: parseStringValue(value) };
|
|
@@ -2922,7 +2829,7 @@ function disambiguateTable(value) {
|
|
|
2922
2829
|
function disambiguateDivide(value) {
|
|
2923
2830
|
return { prop: "divideColor", value: parseStringValue(value) };
|
|
2924
2831
|
}
|
|
2925
|
-
|
|
2832
|
+
const CSS_DIMENSION_RE = /^-?[\d.]+(?:px|r?em|ex|ch|vw|vh|vmin|vmax|svh|svw|dvh|dvw|lvh|lvw|cqw|cqh|cqi|cqb|%|fr|deg|rad|turn|grad|ms|s|pt|pc|cm|mm|in)$/;
|
|
2926
2833
|
function isArbitraryDimension(value) {
|
|
2927
2834
|
if (!value.startsWith("[") || !value.endsWith("]")) {
|
|
2928
2835
|
return false;
|
|
@@ -2936,7 +2843,7 @@ function isValidSpacingValue(value) {
|
|
|
2936
2843
|
if (value.startsWith("(") && value.endsWith(")")) {
|
|
2937
2844
|
return true;
|
|
2938
2845
|
}
|
|
2939
|
-
if (!isNaN(Number(value))) {
|
|
2846
|
+
if (!Number.isNaN(Number(value))) {
|
|
2940
2847
|
return true;
|
|
2941
2848
|
}
|
|
2942
2849
|
if (/^\d+\/\d+$/.test(value)) {
|
|
@@ -2989,7 +2896,7 @@ function parseValue(prefix, value, negative) {
|
|
|
2989
2896
|
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2990
2897
|
const inner = value.slice(1, -1).replace(/_/g, " ");
|
|
2991
2898
|
if (negative) {
|
|
2992
|
-
return
|
|
2899
|
+
return `-${inner}`;
|
|
2993
2900
|
}
|
|
2994
2901
|
if (prefix === "content") {
|
|
2995
2902
|
const isQuoted = inner.startsWith("'") && inner.endsWith("'") || inner.startsWith('"') && inner.endsWith('"');
|
|
@@ -3002,7 +2909,7 @@ function parseValue(prefix, value, negative) {
|
|
|
3002
2909
|
if (value.startsWith("(") && value.endsWith(")")) {
|
|
3003
2910
|
const inner = value.slice(1, -1);
|
|
3004
2911
|
if (negative) {
|
|
3005
|
-
return
|
|
2912
|
+
return `-${inner}`;
|
|
3006
2913
|
}
|
|
3007
2914
|
return inner;
|
|
3008
2915
|
}
|
|
@@ -3022,14 +2929,14 @@ function parseValue(prefix, value, negative) {
|
|
|
3022
2929
|
return "screen";
|
|
3023
2930
|
}
|
|
3024
2931
|
const num = Number(value);
|
|
3025
|
-
if (!isNaN(num)) {
|
|
2932
|
+
if (!Number.isNaN(num)) {
|
|
3026
2933
|
if (negative) {
|
|
3027
2934
|
return -num;
|
|
3028
2935
|
}
|
|
3029
2936
|
return num;
|
|
3030
2937
|
}
|
|
3031
2938
|
if (negative) {
|
|
3032
|
-
return
|
|
2939
|
+
return `-${value}`;
|
|
3033
2940
|
}
|
|
3034
2941
|
return value;
|
|
3035
2942
|
}
|
|
@@ -3038,7 +2945,7 @@ function parseNumericOrString(prefix, value, negative) {
|
|
|
3038
2945
|
return "px";
|
|
3039
2946
|
}
|
|
3040
2947
|
const num = Number(value);
|
|
3041
|
-
if (!isNaN(num)) {
|
|
2948
|
+
if (!Number.isNaN(num)) {
|
|
3042
2949
|
return negative ? -num : num;
|
|
3043
2950
|
}
|
|
3044
2951
|
return value;
|
|
@@ -3053,7 +2960,6 @@ function parseStringValue(value) {
|
|
|
3053
2960
|
return value;
|
|
3054
2961
|
}
|
|
3055
2962
|
|
|
3056
|
-
// src/migrate/variant-parser.ts
|
|
3057
2963
|
function tokenize(className) {
|
|
3058
2964
|
return className.trim().split(/\s+/).filter(Boolean);
|
|
3059
2965
|
}
|
|
@@ -3159,7 +3065,7 @@ function parseGroupPeerVariant(variant) {
|
|
|
3159
3065
|
const type = isGroup ? "group" : "peer";
|
|
3160
3066
|
let rest = variant.slice(type.length + 1);
|
|
3161
3067
|
let name;
|
|
3162
|
-
const slashIdx =
|
|
3068
|
+
const slashIdx = findTopLevelSlash(rest);
|
|
3163
3069
|
if (slashIdx !== -1) {
|
|
3164
3070
|
name = rest.slice(slashIdx + 1);
|
|
3165
3071
|
rest = rest.slice(0, slashIdx);
|
|
@@ -3202,7 +3108,7 @@ function parseGroupPeerVariant(variant) {
|
|
|
3202
3108
|
}
|
|
3203
3109
|
return keys;
|
|
3204
3110
|
}
|
|
3205
|
-
function
|
|
3111
|
+
function findTopLevelSlash(s) {
|
|
3206
3112
|
let depth = 0;
|
|
3207
3113
|
for (let i = 0; i < s.length; i++) {
|
|
3208
3114
|
if (s[i] === "[" || s[i] === "(") {
|
|
@@ -3224,9 +3130,9 @@ function normalizeVariantKey(variant) {
|
|
|
3224
3130
|
}
|
|
3225
3131
|
return variant;
|
|
3226
3132
|
}
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3133
|
+
const TODO_KEEP = "sz:keep";
|
|
3134
|
+
const TODO_REMOVE = "sz:remove";
|
|
3135
|
+
const TODO_PENDING = "sz:todo";
|
|
3230
3136
|
function resolveCustomMapEntry(token, customMap, resolveString) {
|
|
3231
3137
|
if (!(token in customMap)) {
|
|
3232
3138
|
return null;
|
|
@@ -3321,30 +3227,22 @@ function setNestedValue(obj, keyPath, prop, value) {
|
|
|
3321
3227
|
current[prop] = value;
|
|
3322
3228
|
}
|
|
3323
3229
|
|
|
3324
|
-
|
|
3325
|
-
var CLSX_LIKE_NAMES = /* @__PURE__ */ new Set([
|
|
3326
|
-
"clsx",
|
|
3327
|
-
"cn",
|
|
3328
|
-
"cx",
|
|
3329
|
-
"twMerge",
|
|
3330
|
-
"classNames",
|
|
3331
|
-
"classnames"
|
|
3332
|
-
]);
|
|
3230
|
+
const CLSX_LIKE_NAMES = /* @__PURE__ */ new Set(["clsx", "cn", "cx", "twMerge", "classNames", "classnames"]);
|
|
3333
3231
|
function isClsxLikeName(name) {
|
|
3334
3232
|
return CLSX_LIKE_NAMES.has(name);
|
|
3335
3233
|
}
|
|
3336
|
-
function handleClsxCall(node, source,
|
|
3234
|
+
function handleClsxCall(node, source, t, customMap) {
|
|
3337
3235
|
const warnings = [];
|
|
3338
3236
|
const allUnrecognized = [];
|
|
3339
3237
|
const elements = [];
|
|
3340
3238
|
let converted = 0;
|
|
3341
3239
|
for (const arg of node.arguments) {
|
|
3342
|
-
if (
|
|
3240
|
+
if (t.isSpreadElement(arg)) {
|
|
3343
3241
|
const argSrc2 = safeSlice(source, arg.start, arg.end);
|
|
3344
3242
|
warnings.push(`Cannot migrate spread argument: ${argSrc2}`);
|
|
3345
3243
|
return skip(allUnrecognized, warnings);
|
|
3346
3244
|
}
|
|
3347
|
-
if (
|
|
3245
|
+
if (t.isStringLiteral(arg)) {
|
|
3348
3246
|
const result = migrateString(arg.value, customMap);
|
|
3349
3247
|
if (!result) {
|
|
3350
3248
|
return skip(allUnrecognized, warnings);
|
|
@@ -3354,8 +3252,8 @@ function handleClsxCall(node, source, t2, customMap) {
|
|
|
3354
3252
|
converted++;
|
|
3355
3253
|
continue;
|
|
3356
3254
|
}
|
|
3357
|
-
if (
|
|
3358
|
-
const result = handleLogicalAndInner(arg, source,
|
|
3255
|
+
if (t.isLogicalExpression(arg) && arg.operator === "&&") {
|
|
3256
|
+
const result = handleLogicalAndInner(arg, source, t, customMap);
|
|
3359
3257
|
if (!result) {
|
|
3360
3258
|
const argSrc2 = safeSlice(source, arg.start, arg.end);
|
|
3361
3259
|
warnings.push(`Cannot migrate logical expression: ${argSrc2}`);
|
|
@@ -3366,8 +3264,8 @@ function handleClsxCall(node, source, t2, customMap) {
|
|
|
3366
3264
|
converted++;
|
|
3367
3265
|
continue;
|
|
3368
3266
|
}
|
|
3369
|
-
if (
|
|
3370
|
-
const result = handleTernaryInner(arg, source,
|
|
3267
|
+
if (t.isConditionalExpression(arg)) {
|
|
3268
|
+
const result = handleTernaryInner(arg, source, t, customMap);
|
|
3371
3269
|
if (!result) {
|
|
3372
3270
|
const argSrc2 = safeSlice(source, arg.start, arg.end);
|
|
3373
3271
|
warnings.push(`Cannot migrate ternary: ${argSrc2}`);
|
|
@@ -3402,8 +3300,8 @@ function handleClsxCall(node, source, t2, customMap) {
|
|
|
3402
3300
|
migrated: true
|
|
3403
3301
|
};
|
|
3404
3302
|
}
|
|
3405
|
-
function handleTernary(node, source,
|
|
3406
|
-
const result = handleTernaryInner(node, source,
|
|
3303
|
+
function handleTernary(node, source, t, customMap) {
|
|
3304
|
+
const result = handleTernaryInner(node, source, t, customMap);
|
|
3407
3305
|
if (!result) {
|
|
3408
3306
|
return {
|
|
3409
3307
|
replacement: "",
|
|
@@ -3421,7 +3319,7 @@ function handleTernary(node, source, t2, customMap) {
|
|
|
3421
3319
|
migrated: true
|
|
3422
3320
|
};
|
|
3423
3321
|
}
|
|
3424
|
-
function handleLogicalAnd(node, source,
|
|
3322
|
+
function handleLogicalAnd(node, source, t, customMap) {
|
|
3425
3323
|
if (node.operator !== "&&") {
|
|
3426
3324
|
return {
|
|
3427
3325
|
replacement: "",
|
|
@@ -3431,7 +3329,7 @@ function handleLogicalAnd(node, source, t2, customMap) {
|
|
|
3431
3329
|
migrated: false
|
|
3432
3330
|
};
|
|
3433
3331
|
}
|
|
3434
|
-
const result = handleLogicalAndInner(node, source,
|
|
3332
|
+
const result = handleLogicalAndInner(node, source, t, customMap);
|
|
3435
3333
|
if (!result) {
|
|
3436
3334
|
return {
|
|
3437
3335
|
replacement: "",
|
|
@@ -3449,7 +3347,7 @@ function handleLogicalAnd(node, source, t2, customMap) {
|
|
|
3449
3347
|
migrated: true
|
|
3450
3348
|
};
|
|
3451
3349
|
}
|
|
3452
|
-
function handleTemplateLiteral(node, source,
|
|
3350
|
+
function handleTemplateLiteral(node, source, t, customMap) {
|
|
3453
3351
|
const warnings = [];
|
|
3454
3352
|
const allUnrecognized = [];
|
|
3455
3353
|
const staticText = node.quasis.map((q) => q.value.cooked ?? q.value.raw).join(" ");
|
|
@@ -3463,12 +3361,16 @@ function handleTemplateLiteral(node, source, t2, customMap) {
|
|
|
3463
3361
|
const dynamicElements = [];
|
|
3464
3362
|
let converted = 0;
|
|
3465
3363
|
for (const expr of node.expressions) {
|
|
3466
|
-
if (!isExpression(expr,
|
|
3467
|
-
const exprSrc2 = safeSlice(
|
|
3364
|
+
if (!isExpression(expr, t)) {
|
|
3365
|
+
const exprSrc2 = safeSlice(
|
|
3366
|
+
source,
|
|
3367
|
+
expr.start,
|
|
3368
|
+
expr.end
|
|
3369
|
+
);
|
|
3468
3370
|
warnings.push(`Cannot migrate template expression: ${exprSrc2}`);
|
|
3469
3371
|
return skip(allUnrecognized, warnings);
|
|
3470
3372
|
}
|
|
3471
|
-
if (
|
|
3373
|
+
if (t.isStringLiteral(expr)) {
|
|
3472
3374
|
const result = migrateString(expr.value, customMap);
|
|
3473
3375
|
if (result) {
|
|
3474
3376
|
const { szObject } = classNameToSzObject(expr.value, customMap);
|
|
@@ -3478,8 +3380,8 @@ function handleTemplateLiteral(node, source, t2, customMap) {
|
|
|
3478
3380
|
}
|
|
3479
3381
|
continue;
|
|
3480
3382
|
}
|
|
3481
|
-
if (
|
|
3482
|
-
const result = handleTernaryInner(expr, source,
|
|
3383
|
+
if (t.isConditionalExpression(expr)) {
|
|
3384
|
+
const result = handleTernaryInner(expr, source, t, customMap);
|
|
3483
3385
|
if (!result) {
|
|
3484
3386
|
const exprSrc2 = safeSlice(source, expr.start, expr.end);
|
|
3485
3387
|
warnings.push(`Cannot migrate template ternary: ${exprSrc2}`);
|
|
@@ -3490,8 +3392,8 @@ function handleTemplateLiteral(node, source, t2, customMap) {
|
|
|
3490
3392
|
converted++;
|
|
3491
3393
|
continue;
|
|
3492
3394
|
}
|
|
3493
|
-
if (
|
|
3494
|
-
const result = handleLogicalAndInner(expr, source,
|
|
3395
|
+
if (t.isLogicalExpression(expr) && expr.operator === "&&") {
|
|
3396
|
+
const result = handleLogicalAndInner(expr, source, t, customMap);
|
|
3495
3397
|
if (!result) {
|
|
3496
3398
|
const exprSrc2 = safeSlice(source, expr.start, expr.end);
|
|
3497
3399
|
warnings.push(`Cannot migrate template logical expr: ${exprSrc2}`);
|
|
@@ -3533,8 +3435,8 @@ function handleTemplateLiteral(node, source, t2, customMap) {
|
|
|
3533
3435
|
migrated: true
|
|
3534
3436
|
};
|
|
3535
3437
|
}
|
|
3536
|
-
function handleTernaryInner(node, source,
|
|
3537
|
-
if (!
|
|
3438
|
+
function handleTernaryInner(node, source, t, customMap) {
|
|
3439
|
+
if (!t.isStringLiteral(node.consequent) || !t.isStringLiteral(node.alternate)) {
|
|
3538
3440
|
return null;
|
|
3539
3441
|
}
|
|
3540
3442
|
const condSource = safeSlice(source, node.test.start, node.test.end);
|
|
@@ -3577,8 +3479,8 @@ function handleTernaryInner(node, source, t2, customMap) {
|
|
|
3577
3479
|
unrecognized: []
|
|
3578
3480
|
};
|
|
3579
3481
|
}
|
|
3580
|
-
function handleLogicalAndInner(node, source,
|
|
3581
|
-
if (!
|
|
3482
|
+
function handleLogicalAndInner(node, source, t, customMap) {
|
|
3483
|
+
if (!t.isStringLiteral(node.right)) {
|
|
3582
3484
|
return null;
|
|
3583
3485
|
}
|
|
3584
3486
|
const result = migrateString(node.right.value, customMap);
|
|
@@ -3626,12 +3528,11 @@ function wrapCondition(cond) {
|
|
|
3626
3528
|
}
|
|
3627
3529
|
return cond;
|
|
3628
3530
|
}
|
|
3629
|
-
function isExpression(node,
|
|
3630
|
-
return
|
|
3531
|
+
function isExpression(node, t) {
|
|
3532
|
+
return t.isExpression(node);
|
|
3631
3533
|
}
|
|
3632
3534
|
|
|
3633
|
-
|
|
3634
|
-
var traverse = typeof _traverse === "function" ? _traverse : _traverse.default;
|
|
3535
|
+
const traverse = typeof _traverse === "function" ? _traverse : _traverse.default;
|
|
3635
3536
|
function injectTodoComment(unrecognized, parent, options, replacements) {
|
|
3636
3537
|
if (!options.injectTodos || unrecognized.length === 0) {
|
|
3637
3538
|
return;
|
|
@@ -3676,15 +3577,15 @@ function transformSource(source, filePath, options = {}) {
|
|
|
3676
3577
|
}
|
|
3677
3578
|
traverse(ast, {
|
|
3678
3579
|
// Track clsx-like and CVA imports
|
|
3679
|
-
ImportDeclaration(
|
|
3680
|
-
const src =
|
|
3580
|
+
ImportDeclaration(path) {
|
|
3581
|
+
const src = path.node.source.value;
|
|
3681
3582
|
const clsxPackages = ["clsx", "clsx/lite", "classnames", "tailwind-merge"];
|
|
3682
|
-
const isClsxPkg = clsxPackages.some((p) => src === p || src.startsWith(p
|
|
3583
|
+
const isClsxPkg = clsxPackages.some((p) => src === p || src.startsWith(`${p}/`));
|
|
3683
3584
|
const cvaPkgs = ["cva", "class-variance-authority"];
|
|
3684
|
-
if (cvaPkgs.some((p) => src === p || src.startsWith(p
|
|
3585
|
+
if (cvaPkgs.some((p) => src === p || src.startsWith(`${p}/`))) {
|
|
3685
3586
|
hasCvaImport = true;
|
|
3686
3587
|
}
|
|
3687
|
-
for (const spec of
|
|
3588
|
+
for (const spec of path.node.specifiers) {
|
|
3688
3589
|
const localName = spec.local.name;
|
|
3689
3590
|
if (isClsxPkg || isClsxLikeName(localName)) {
|
|
3690
3591
|
clsxImportNames.add(localName);
|
|
@@ -3692,9 +3593,9 @@ function transformSource(source, filePath, options = {}) {
|
|
|
3692
3593
|
}
|
|
3693
3594
|
},
|
|
3694
3595
|
// Track clsx usage outside className
|
|
3695
|
-
CallExpression(
|
|
3696
|
-
if (t.isIdentifier(
|
|
3697
|
-
const inClassName =
|
|
3596
|
+
CallExpression(path) {
|
|
3597
|
+
if (t.isIdentifier(path.node.callee) && clsxImportNames.has(path.node.callee.name)) {
|
|
3598
|
+
const inClassName = path.findParent(
|
|
3698
3599
|
(p) => t.isJSXAttribute(p.node) && t.isJSXIdentifier(p.node.name) && p.node.name.name === "className"
|
|
3699
3600
|
);
|
|
3700
3601
|
if (!inClassName) {
|
|
@@ -3703,12 +3604,12 @@ function transformSource(source, filePath, options = {}) {
|
|
|
3703
3604
|
}
|
|
3704
3605
|
},
|
|
3705
3606
|
// Main transformation: className → sz
|
|
3706
|
-
JSXAttribute(
|
|
3707
|
-
const attrName =
|
|
3607
|
+
JSXAttribute(path) {
|
|
3608
|
+
const attrName = path.node.name;
|
|
3708
3609
|
if (!t.isJSXIdentifier(attrName) || attrName.name !== "className") {
|
|
3709
3610
|
return;
|
|
3710
3611
|
}
|
|
3711
|
-
const parent =
|
|
3612
|
+
const parent = path.parent;
|
|
3712
3613
|
if (t.isJSXOpeningElement(parent)) {
|
|
3713
3614
|
const elementName = parent.name;
|
|
3714
3615
|
const isCapitalized = t.isJSXIdentifier(elementName) && /^[A-Z]/.test(elementName.name) || t.isJSXMemberExpression(elementName);
|
|
@@ -3726,9 +3627,9 @@ function transformSource(source, filePath, options = {}) {
|
|
|
3726
3627
|
return;
|
|
3727
3628
|
}
|
|
3728
3629
|
}
|
|
3729
|
-
const value =
|
|
3730
|
-
const attrStart =
|
|
3731
|
-
const attrEnd =
|
|
3630
|
+
const value = path.node.value;
|
|
3631
|
+
const attrStart = path.node.start;
|
|
3632
|
+
const attrEnd = path.node.end;
|
|
3732
3633
|
if (attrStart === null || attrStart === void 0 || attrEnd === null || attrEnd === void 0) {
|
|
3733
3634
|
return;
|
|
3734
3635
|
}
|
|
@@ -3738,7 +3639,7 @@ function transformSource(source, filePath, options = {}) {
|
|
|
3738
3639
|
replacements.push({ start: attrStart, end: attrEnd, text: result.replacement });
|
|
3739
3640
|
classNamesTransformed++;
|
|
3740
3641
|
classesUnrecognized.push(...result.unrecognized);
|
|
3741
|
-
injectTodoComment(result.unrecognized,
|
|
3642
|
+
injectTodoComment(result.unrecognized, path.parent, options, replacements);
|
|
3742
3643
|
} else {
|
|
3743
3644
|
classNamesSkipped++;
|
|
3744
3645
|
}
|
|
@@ -3749,10 +3650,14 @@ function transformSource(source, filePath, options = {}) {
|
|
|
3749
3650
|
if (t.isStringLiteral(expr)) {
|
|
3750
3651
|
const result = processStaticString(expr.value, options.customMap);
|
|
3751
3652
|
if (result) {
|
|
3752
|
-
replacements.push({
|
|
3653
|
+
replacements.push({
|
|
3654
|
+
start: attrStart,
|
|
3655
|
+
end: attrEnd,
|
|
3656
|
+
text: result.replacement
|
|
3657
|
+
});
|
|
3753
3658
|
classNamesTransformed++;
|
|
3754
3659
|
classesUnrecognized.push(...result.unrecognized);
|
|
3755
|
-
injectTodoComment(result.unrecognized,
|
|
3660
|
+
injectTodoComment(result.unrecognized, path.parent, options, replacements);
|
|
3756
3661
|
} else {
|
|
3757
3662
|
classNamesSkipped++;
|
|
3758
3663
|
}
|
|
@@ -3761,20 +3666,28 @@ function transformSource(source, filePath, options = {}) {
|
|
|
3761
3666
|
if (t.isTemplateLiteral(expr)) {
|
|
3762
3667
|
const result = handleTemplateLiteral(expr, source, t, options.customMap);
|
|
3763
3668
|
if (result.migrated) {
|
|
3764
|
-
replacements.push({
|
|
3669
|
+
replacements.push({
|
|
3670
|
+
start: attrStart,
|
|
3671
|
+
end: attrEnd,
|
|
3672
|
+
text: result.replacement
|
|
3673
|
+
});
|
|
3765
3674
|
classNamesTransformed += result.converted;
|
|
3766
3675
|
classesUnrecognized.push(...result.unrecognized);
|
|
3767
3676
|
} else {
|
|
3768
3677
|
classNamesSkipped++;
|
|
3769
3678
|
warnings.push(...result.warnings.map((w) => `[${filePath}] ${w}`));
|
|
3770
3679
|
}
|
|
3771
|
-
injectTodoComment(result.unrecognized,
|
|
3680
|
+
injectTodoComment(result.unrecognized, path.parent, options, replacements);
|
|
3772
3681
|
return;
|
|
3773
3682
|
}
|
|
3774
3683
|
if (t.isCallExpression(expr) && t.isIdentifier(expr.callee) && isClsxLikeName(expr.callee.name)) {
|
|
3775
3684
|
const result = handleClsxCall(expr, source, t, options.customMap);
|
|
3776
3685
|
if (result.migrated) {
|
|
3777
|
-
replacements.push({
|
|
3686
|
+
replacements.push({
|
|
3687
|
+
start: attrStart,
|
|
3688
|
+
end: attrEnd,
|
|
3689
|
+
text: result.replacement
|
|
3690
|
+
});
|
|
3778
3691
|
classNamesTransformed += result.converted;
|
|
3779
3692
|
classesUnrecognized.push(...result.unrecognized);
|
|
3780
3693
|
if (expr.start !== null && expr.start !== void 0) {
|
|
@@ -3784,33 +3697,41 @@ function transformSource(source, filePath, options = {}) {
|
|
|
3784
3697
|
classNamesSkipped++;
|
|
3785
3698
|
warnings.push(...result.warnings.map((w) => `[${filePath}] ${w}`));
|
|
3786
3699
|
}
|
|
3787
|
-
injectTodoComment(result.unrecognized,
|
|
3700
|
+
injectTodoComment(result.unrecognized, path.parent, options, replacements);
|
|
3788
3701
|
return;
|
|
3789
3702
|
}
|
|
3790
3703
|
if (t.isConditionalExpression(expr)) {
|
|
3791
3704
|
const result = handleTernary(expr, source, t, options.customMap);
|
|
3792
3705
|
if (result.migrated) {
|
|
3793
|
-
replacements.push({
|
|
3706
|
+
replacements.push({
|
|
3707
|
+
start: attrStart,
|
|
3708
|
+
end: attrEnd,
|
|
3709
|
+
text: result.replacement
|
|
3710
|
+
});
|
|
3794
3711
|
classNamesTransformed += result.converted;
|
|
3795
3712
|
classesUnrecognized.push(...result.unrecognized);
|
|
3796
3713
|
} else {
|
|
3797
3714
|
classNamesSkipped++;
|
|
3798
3715
|
warnings.push(...result.warnings.map((w) => `[${filePath}] ${w}`));
|
|
3799
3716
|
}
|
|
3800
|
-
injectTodoComment(result.unrecognized,
|
|
3717
|
+
injectTodoComment(result.unrecognized, path.parent, options, replacements);
|
|
3801
3718
|
return;
|
|
3802
3719
|
}
|
|
3803
3720
|
if (t.isLogicalExpression(expr) && expr.operator === "&&") {
|
|
3804
3721
|
const result = handleLogicalAnd(expr, source, t, options.customMap);
|
|
3805
3722
|
if (result.migrated) {
|
|
3806
|
-
replacements.push({
|
|
3723
|
+
replacements.push({
|
|
3724
|
+
start: attrStart,
|
|
3725
|
+
end: attrEnd,
|
|
3726
|
+
text: result.replacement
|
|
3727
|
+
});
|
|
3807
3728
|
classNamesTransformed += result.converted;
|
|
3808
3729
|
classesUnrecognized.push(...result.unrecognized);
|
|
3809
3730
|
} else {
|
|
3810
3731
|
classNamesSkipped++;
|
|
3811
3732
|
warnings.push(...result.warnings.map((w) => `[${filePath}] ${w}`));
|
|
3812
3733
|
}
|
|
3813
|
-
injectTodoComment(result.unrecognized,
|
|
3734
|
+
injectTodoComment(result.unrecognized, path.parent, options, replacements);
|
|
3814
3735
|
return;
|
|
3815
3736
|
}
|
|
3816
3737
|
classNamesSkipped++;
|
|
@@ -3868,7 +3789,7 @@ function processStaticString(classNameStr, customMap) {
|
|
|
3868
3789
|
unrecognized: []
|
|
3869
3790
|
};
|
|
3870
3791
|
}
|
|
3871
|
-
|
|
3792
|
+
const FOUC_CSS = `<style>
|
|
3872
3793
|
/* csszyx: hide [sz] elements until runtime processes them */
|
|
3873
3794
|
[sz] { visibility: hidden; }
|
|
3874
3795
|
body.sz-ready [sz] { visibility: visible; }
|
|
@@ -3899,7 +3820,7 @@ function transformHtmlSourceSimple(source, filePath, options = {}) {
|
|
|
3899
3820
|
}
|
|
3900
3821
|
if (injectRuntime && output.includes("</body>")) {
|
|
3901
3822
|
const scriptSrc = injectRuntime === "cdn" ? cdnUrl : localPath;
|
|
3902
|
-
const scriptTag = `<script src="${scriptSrc}"
|
|
3823
|
+
const scriptTag = `<script src="${scriptSrc}"><\/script>`;
|
|
3903
3824
|
if (!output.includes(scriptSrc)) {
|
|
3904
3825
|
output = output.replace("</body>", `${scriptTag}
|
|
3905
3826
|
</body>`);
|
|
@@ -3936,26 +3857,26 @@ function transformHtmlSourceSimple(source, filePath, options = {}) {
|
|
|
3936
3857
|
};
|
|
3937
3858
|
}
|
|
3938
3859
|
|
|
3939
|
-
// src/commands/migrate.ts
|
|
3940
3860
|
function createLogFile(cwd) {
|
|
3941
3861
|
const now = /* @__PURE__ */ new Date();
|
|
3942
3862
|
const ts = now.toISOString().slice(0, 19).replace("T", "_").replace(/:/g, "-");
|
|
3943
|
-
const logDir =
|
|
3944
|
-
|
|
3945
|
-
const filePath =
|
|
3863
|
+
const logDir = path.join(cwd, ".csszyx", "logs");
|
|
3864
|
+
fs$1.mkdirSync(logDir, { recursive: true });
|
|
3865
|
+
const filePath = path.join(logDir, `migrate-${ts}.log`);
|
|
3946
3866
|
const lines = [`csszyx migrate \u2014 ${now.toISOString()}`, ""];
|
|
3947
3867
|
return {
|
|
3948
3868
|
filePath,
|
|
3949
3869
|
writeLine: (line) => lines.push(line),
|
|
3950
|
-
flush: () =>
|
|
3870
|
+
flush: () => fs$1.writeFileSync(filePath, `${lines.join("\n")}
|
|
3871
|
+
`, "utf-8")
|
|
3951
3872
|
};
|
|
3952
3873
|
}
|
|
3953
3874
|
function isGitignored(cwd, pattern) {
|
|
3954
3875
|
try {
|
|
3955
|
-
const content =
|
|
3876
|
+
const content = fs$1.readFileSync(path.join(cwd, ".gitignore"), "utf-8");
|
|
3956
3877
|
return content.split("\n").some((l) => {
|
|
3957
|
-
const
|
|
3958
|
-
return
|
|
3878
|
+
const t = l.trim();
|
|
3879
|
+
return t === pattern || t === `${pattern}/` || t === `/${pattern}`;
|
|
3959
3880
|
});
|
|
3960
3881
|
} catch {
|
|
3961
3882
|
return false;
|
|
@@ -3963,10 +3884,10 @@ function isGitignored(cwd, pattern) {
|
|
|
3963
3884
|
}
|
|
3964
3885
|
async function askYesNo(question) {
|
|
3965
3886
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
3966
|
-
return new Promise((
|
|
3887
|
+
return new Promise((resolve) => {
|
|
3967
3888
|
rl.question(question, (answer) => {
|
|
3968
3889
|
rl.close();
|
|
3969
|
-
|
|
3890
|
+
resolve(answer.trim().toLowerCase() === "y");
|
|
3970
3891
|
});
|
|
3971
3892
|
});
|
|
3972
3893
|
}
|
|
@@ -3974,10 +3895,10 @@ async function migrate(options = {}) {
|
|
|
3974
3895
|
const cwd = options.cwd || process.cwd();
|
|
3975
3896
|
let dryRun = options.dryRun || false;
|
|
3976
3897
|
const ignorePatterns = options.ignore || [];
|
|
3977
|
-
const
|
|
3898
|
+
const audit = options.audit || false;
|
|
3978
3899
|
const resolveTodosPath = options.resolveTodos;
|
|
3979
3900
|
let customMap, files;
|
|
3980
|
-
if (
|
|
3901
|
+
if (audit) {
|
|
3981
3902
|
dryRun = true;
|
|
3982
3903
|
}
|
|
3983
3904
|
let injectTodos = options.injectTodos || false;
|
|
@@ -3985,7 +3906,7 @@ async function migrate(options = {}) {
|
|
|
3985
3906
|
injectTodos = true;
|
|
3986
3907
|
}
|
|
3987
3908
|
printHeader("csszyx Migration Tool");
|
|
3988
|
-
if (process.stdout.isTTY && !injectTodos && !
|
|
3909
|
+
if (process.stdout.isTTY && !injectTodos && !audit && !resolveTodosPath) {
|
|
3989
3910
|
const answer = await askYesNo(
|
|
3990
3911
|
"Add {/* @sz-todo */} comments above elements with unrecognized classes? [y/N] "
|
|
3991
3912
|
);
|
|
@@ -3995,26 +3916,32 @@ async function migrate(options = {}) {
|
|
|
3995
3916
|
}
|
|
3996
3917
|
if (resolveTodosPath) {
|
|
3997
3918
|
try {
|
|
3998
|
-
const absolutePath =
|
|
3999
|
-
const content =
|
|
3919
|
+
const absolutePath = path.resolve(cwd, resolveTodosPath);
|
|
3920
|
+
const content = fs$1.readFileSync(absolutePath, "utf-8");
|
|
4000
3921
|
customMap = JSON.parse(content);
|
|
4001
3922
|
printInfo(`Loaded resolution map from ${resolveTodosPath}`);
|
|
4002
3923
|
} catch {
|
|
4003
|
-
printWarn(
|
|
3924
|
+
printWarn(
|
|
3925
|
+
`Could not load resolve map from ${resolveTodosPath}. Ensure the file exists and is valid JSON.`
|
|
3926
|
+
);
|
|
4004
3927
|
return;
|
|
4005
3928
|
}
|
|
4006
3929
|
}
|
|
4007
|
-
if (
|
|
3930
|
+
if (audit) {
|
|
4008
3931
|
printInfo("Audit mode \u2014 scanning for unrecognized classes to generate a mapping file...");
|
|
4009
3932
|
} else if (dryRun) {
|
|
4010
3933
|
printInfo("Dry run mode \u2014 no files will be modified");
|
|
4011
3934
|
}
|
|
4012
3935
|
const log = createLogFile(cwd);
|
|
4013
|
-
log.writeLine(
|
|
3936
|
+
log.writeLine(
|
|
3937
|
+
`Mode: ${audit ? "audit" : dryRun ? "dry-run" : "migrate"}${resolveTodosPath ? ` (resolve-todos: ${resolveTodosPath})` : ""}`
|
|
3938
|
+
);
|
|
4014
3939
|
log.writeLine(`injectTodos: ${injectTodos}`);
|
|
4015
3940
|
log.writeLine("");
|
|
4016
3941
|
if (!isGitignored(cwd, ".csszyx")) {
|
|
4017
|
-
printWarn(
|
|
3942
|
+
printWarn(
|
|
3943
|
+
"Tip: add .csszyx/ to your .gitignore to exclude migration logs from version control."
|
|
3944
|
+
);
|
|
4018
3945
|
}
|
|
4019
3946
|
const patterns = options.pattern ? [options.pattern] : ["**/*.{jsx,tsx,html}"];
|
|
4020
3947
|
const ignore = [
|
|
@@ -4036,7 +3963,9 @@ async function migrate(options = {}) {
|
|
|
4036
3963
|
}
|
|
4037
3964
|
s.succeed(`Found ${files.length} files`);
|
|
4038
3965
|
if (files.length === 0) {
|
|
4039
|
-
printWarn(
|
|
3966
|
+
printWarn(
|
|
3967
|
+
options.pattern ? `No files found matching pattern: ${options.pattern}` : "No JSX/TSX/HTML files found"
|
|
3968
|
+
);
|
|
4040
3969
|
log.writeLine("No files found.");
|
|
4041
3970
|
log.flush();
|
|
4042
3971
|
return;
|
|
@@ -4049,7 +3978,7 @@ async function migrate(options = {}) {
|
|
|
4049
3978
|
const unusedImportFiles = [];
|
|
4050
3979
|
const s2 = spinner.start("Migrating...");
|
|
4051
3980
|
for (const filePath of files) {
|
|
4052
|
-
const source =
|
|
3981
|
+
const source = fs$1.readFileSync(filePath, "utf-8");
|
|
4053
3982
|
const isHtml = filePath.endsWith(".html");
|
|
4054
3983
|
const hasRelevantAttr = isHtml ? source.includes("class=") : source.includes("className=");
|
|
4055
3984
|
if (!hasRelevantAttr) {
|
|
@@ -4073,20 +4002,22 @@ async function migrate(options = {}) {
|
|
|
4073
4002
|
totalSkipped += result.stats.classNamesSkipped;
|
|
4074
4003
|
allUnrecognized.push(...result.stats.classesUnrecognized);
|
|
4075
4004
|
if (result.potentiallyUnusedImports.length > 0) {
|
|
4076
|
-
const rel2 =
|
|
4005
|
+
const rel2 = path.relative(cwd, filePath);
|
|
4077
4006
|
unusedImportFiles.push({ file: rel2, imports: result.potentiallyUnusedImports });
|
|
4078
4007
|
}
|
|
4079
4008
|
if (!dryRun) {
|
|
4080
4009
|
try {
|
|
4081
|
-
|
|
4010
|
+
fs$1.writeFileSync(filePath, result.code, "utf-8");
|
|
4082
4011
|
} catch (err) {
|
|
4083
|
-
const rel2 =
|
|
4084
|
-
printWarn(
|
|
4012
|
+
const rel2 = path.relative(cwd, filePath);
|
|
4013
|
+
printWarn(
|
|
4014
|
+
`Could not write ${rel2}: ${err instanceof Error ? err.message : String(err)}`
|
|
4015
|
+
);
|
|
4085
4016
|
log.writeLine(` Write error: ${rel2}`);
|
|
4086
4017
|
continue;
|
|
4087
4018
|
}
|
|
4088
4019
|
}
|
|
4089
|
-
const rel =
|
|
4020
|
+
const rel = path.relative(cwd, filePath);
|
|
4090
4021
|
if (dryRun) {
|
|
4091
4022
|
printInfo(` ${rel}: ${result.stats.classNamesTransformed} className(s) \u2192 sz`);
|
|
4092
4023
|
log.writeLine(` ${rel}: ${result.stats.classNamesTransformed} className(s) \u2192 sz`);
|
|
@@ -4107,7 +4038,9 @@ async function migrate(options = {}) {
|
|
|
4107
4038
|
}
|
|
4108
4039
|
if (allUnrecognized.length > 0) {
|
|
4109
4040
|
const unique = [...new Set(allUnrecognized)];
|
|
4110
|
-
printWarn(
|
|
4041
|
+
printWarn(
|
|
4042
|
+
`Unrecognized classes (${unique.length}): ${unique.slice(0, 10).join(", ")}${unique.length > 10 ? "..." : ""}`
|
|
4043
|
+
);
|
|
4111
4044
|
log.writeLine(`Unrecognized classes (${unique.length}): ${unique.join(", ")}`);
|
|
4112
4045
|
}
|
|
4113
4046
|
if (allWarnings.length > 0) {
|
|
@@ -4124,12 +4057,14 @@ async function migrate(options = {}) {
|
|
|
4124
4057
|
log.writeLine(` ${w}`);
|
|
4125
4058
|
}
|
|
4126
4059
|
}
|
|
4127
|
-
if (
|
|
4128
|
-
const todoPath =
|
|
4060
|
+
if (audit) {
|
|
4061
|
+
const todoPath = path.join(cwd, ".csszyx-todo.json");
|
|
4129
4062
|
const unique = [...new Set(allUnrecognized)];
|
|
4130
4063
|
console.info();
|
|
4131
4064
|
if (unique.length === 0) {
|
|
4132
|
-
printSuccess(
|
|
4065
|
+
printSuccess(
|
|
4066
|
+
"Audit complete. 100% of your classes are perfectly recognized by csszyx!"
|
|
4067
|
+
);
|
|
4133
4068
|
log.writeLine("Audit: 100% recognized.");
|
|
4134
4069
|
} else {
|
|
4135
4070
|
const todoObj = {};
|
|
@@ -4137,22 +4072,32 @@ async function migrate(options = {}) {
|
|
|
4137
4072
|
todoObj[u] = "sz:todo";
|
|
4138
4073
|
}
|
|
4139
4074
|
try {
|
|
4140
|
-
|
|
4075
|
+
fs$1.writeFileSync(todoPath, JSON.stringify(todoObj, null, 2));
|
|
4141
4076
|
} catch (err) {
|
|
4142
|
-
printWarn(
|
|
4077
|
+
printWarn(
|
|
4078
|
+
`Could not write ${path.relative(cwd, todoPath)}: ${err instanceof Error ? err.message : String(err)}`
|
|
4079
|
+
);
|
|
4143
4080
|
log.flush();
|
|
4144
4081
|
return;
|
|
4145
4082
|
}
|
|
4146
|
-
printSuccess(
|
|
4147
|
-
|
|
4148
|
-
|
|
4083
|
+
printSuccess(
|
|
4084
|
+
`Audit complete. Exported ${unique.length} unrecognized classes to ${path.relative(cwd, todoPath)}.`
|
|
4085
|
+
);
|
|
4086
|
+
printInfo(
|
|
4087
|
+
"Edit this file to map custom classes, then run: npx @csszyx/cli migrate --resolve-todos .csszyx-todo.json"
|
|
4088
|
+
);
|
|
4089
|
+
log.writeLine(
|
|
4090
|
+
`Audit: ${unique.length} unrecognized classes written to ${path.relative(cwd, todoPath)}`
|
|
4091
|
+
);
|
|
4149
4092
|
}
|
|
4150
4093
|
}
|
|
4151
4094
|
if (resolveTodosPath) {
|
|
4152
4095
|
const unique = [...new Set(allUnrecognized)];
|
|
4153
4096
|
if (unique.length > 0) {
|
|
4154
4097
|
console.info();
|
|
4155
|
-
printWarn(
|
|
4098
|
+
printWarn(
|
|
4099
|
+
`Still unresolved after this pass (${unique.length}): ${unique.slice(0, 10).join(", ")}${unique.length > 10 ? "..." : ""}`
|
|
4100
|
+
);
|
|
4156
4101
|
printInfo("Re-run --audit to generate a fresh snapshot when ready.");
|
|
4157
4102
|
log.writeLine(`Still unresolved (${unique.length}): ${unique.join(", ")}`);
|
|
4158
4103
|
}
|
|
@@ -4167,14 +4112,13 @@ async function migrate(options = {}) {
|
|
|
4167
4112
|
}
|
|
4168
4113
|
try {
|
|
4169
4114
|
log.flush();
|
|
4170
|
-
printInfo(`Migration log saved to ${
|
|
4115
|
+
printInfo(`Migration log saved to ${path.relative(cwd, log.filePath)}`);
|
|
4171
4116
|
} catch {
|
|
4172
4117
|
}
|
|
4173
4118
|
}
|
|
4174
4119
|
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
var VERSION = "0.0.0";
|
|
4120
|
+
const cli = cac("csszyx");
|
|
4121
|
+
const VERSION = "0.0.0";
|
|
4178
4122
|
cli.command("init", "Setup csszyx in your project").option("--framework <name>", "Specify framework").option("--yes", "Skip prompts (use defaults)").option("--cwd <dir>", "Current working directory").action(async (options) => {
|
|
4179
4123
|
await init({
|
|
4180
4124
|
framework: options.framework,
|
|
@@ -4196,10 +4140,7 @@ cli.command("audit", "Analyze mangling performance").option("--json", "Output as
|
|
|
4196
4140
|
cwd: options.cwd
|
|
4197
4141
|
});
|
|
4198
4142
|
});
|
|
4199
|
-
cli.command(
|
|
4200
|
-
"generate-types",
|
|
4201
|
-
"Generate TypeScript declarations from tailwind.config.js"
|
|
4202
|
-
).option("-c, --config <path>", "Path to tailwind.config.js").option("-o, --output <path>", "Output file path (default: ./csszyx.d.ts)").option("--cwd <dir>", "Current working directory").option("--silent", "Silent mode (no output)").action(async (options) => {
|
|
4143
|
+
cli.command("generate-types", "Generate TypeScript declarations from tailwind.config.js").option("-c, --config <path>", "Path to tailwind.config.js").option("-o, --output <path>", "Output file path (default: ./csszyx.d.ts)").option("--cwd <dir>", "Current working directory").option("--silent", "Silent mode (no output)").action(async (options) => {
|
|
4203
4144
|
await generateTypes({
|
|
4204
4145
|
config: options.config,
|
|
4205
4146
|
output: options.output,
|
|
@@ -4207,7 +4148,10 @@ cli.command(
|
|
|
4207
4148
|
silent: options.silent
|
|
4208
4149
|
});
|
|
4209
4150
|
});
|
|
4210
|
-
cli.command("migrate [dir]", "Convert Tailwind className to sz prop").option("--dry-run", "Show changes without modifying files").option("--ignore <patterns>", "Glob patterns to ignore (comma-separated)").option("--pattern <glob>", "Custom glob pattern for file discovery").option("--cwd <dir>", "Current working directory").option("--braces", "Wrap HTML sz values in outer { } braces (default: bare)").option("--no-fouc", "Skip FOUC-prevention CSS injection into HTML files").option("--inject-runtime <mode>", "Inject runtime script into HTML: local | cdn").option("--cdn-url <url>", "Custom CDN URL for --inject-runtime cdn").option(
|
|
4151
|
+
cli.command("migrate [dir]", "Convert Tailwind className to sz prop").option("--dry-run", "Show changes without modifying files").option("--ignore <patterns>", "Glob patterns to ignore (comma-separated)").option("--pattern <glob>", "Custom glob pattern for file discovery").option("--cwd <dir>", "Current working directory").option("--braces", "Wrap HTML sz values in outer { } braces (default: bare)").option("--no-fouc", "Skip FOUC-prevention CSS injection into HTML files").option("--inject-runtime <mode>", "Inject runtime script into HTML: local | cdn").option("--cdn-url <url>", "Custom CDN URL for --inject-runtime cdn").option(
|
|
4152
|
+
"--local-path <path>",
|
|
4153
|
+
"Local script path for --inject-runtime local (default: csszyx-runtime.js)"
|
|
4154
|
+
).option("--audit", "Scan without modifying files and output .csszyx-todo.json").option("--inject-todos", "Inject {/* @sz-todo */} comments above unrecognized classes").option("--resolve-todos <file>", "Path to a JSON file mapping custom classes to sz properties").action(async (dir, options) => {
|
|
4211
4155
|
await migrate({
|
|
4212
4156
|
dryRun: options.dryRun,
|
|
4213
4157
|
ignore: options.ignore ? options.ignore.split(",") : void 0,
|
|
@@ -4229,16 +4173,5 @@ cli.command("").action(() => {
|
|
|
4229
4173
|
cli.help();
|
|
4230
4174
|
cli.version(VERSION);
|
|
4231
4175
|
cli.parse();
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
extractScreenKeys,
|
|
4235
|
-
extractSpacingKeys,
|
|
4236
|
-
findConfigFile,
|
|
4237
|
-
flattenColors,
|
|
4238
|
-
generateAndWriteTypes,
|
|
4239
|
-
generateTypeDeclarations,
|
|
4240
|
-
generateTypes,
|
|
4241
|
-
transformSource as migrateSource,
|
|
4242
|
-
scanTailwindConfig,
|
|
4243
|
-
writeDeclarationFile
|
|
4244
|
-
};
|
|
4176
|
+
|
|
4177
|
+
export { classNameToSzObject, extractScreenKeys, extractSpacingKeys, findConfigFile, flattenColors, generateAndWriteTypes, generateTypeDeclarations, generateTypes, transformSource as migrateSource, scanTailwindConfig, writeDeclarationFile };
|