@csszyx/cli 0.7.0 → 0.9.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.
@@ -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
- // src/index.ts
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
- var icons = {
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("\u250C" + "\u2500".repeat(width - 2) + "\u2510"));
31
- console.log(
32
- pc.cyan("\u2502") + " " + pc.bold(title) + " ".repeat(padding) + pc.cyan("\u2502")
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
- var spinner = {
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(` Mangled HTML: ${formatBytes(stats.bundleSavings.mangledHTML)} \u2193 ${htmlPercent}% (-${formatBytes(htmlSavings)})`);
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(` Mangled CSS: ${formatBytes(stats.bundleSavings.mangledCSS)} \u2193 ${cssPercent}% (-${formatBytes(cssSavings)})`);
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 = path2.join(cwd, "package.json");
178
- if (!fs2.existsSync(pkgPath)) {
177
+ const pkgPath = path.join(cwd, "package.json");
178
+ if (!fs.existsSync(pkgPath)) {
179
179
  return "unknown";
180
180
  }
181
- const pkg = fs2.readJSONSync(pkgPath);
181
+ const pkg = fs.readJSONSync(pkgPath);
182
182
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
183
183
  if (deps.next) {
184
- const hasAppDir = fs2.existsSync(path2.join(cwd, "app"));
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 (fs2.existsSync(path2.join(cwd, "pnpm-lock.yaml"))) {
213
+ if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) {
214
214
  return "pnpm";
215
215
  }
216
- if (fs2.existsSync(path2.join(cwd, "yarn.lock"))) {
216
+ if (fs.existsSync(path.join(cwd, "yarn.lock"))) {
217
217
  return "yarn";
218
218
  }
219
- if (fs2.existsSync(path2.join(cwd, "bun.lockb"))) {
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 = path2.join(cwd, "package.json");
227
- if (!fs2.existsSync(pkgPath)) {
226
+ const pkgPath = path.join(cwd, "package.json");
227
+ if (!fs.existsSync(pkgPath)) {
228
228
  return false;
229
229
  }
230
- const pkg = fs2.readJSONSync(pkgPath);
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 fs2.existsSync(path2.join(cwd, "tsconfig.json")) || fs2.existsSync(path2.join(cwd, "jsconfig.json"));
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 = fs3.existsSync(path3.join(cwd, "csszyx.config.ts")) || fs3.existsSync(path3.join(cwd, "csszyx.config.js"));
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 = path3.join(cwd, "package.json");
289
- const pkg = fs3.readJSONSync(pkgPath);
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 = path3.join(cwd, "dist");
303
- if (fs3.existsSync(distDir)) {
304
- const htmlFiles = fs3.readdirSync(distDir, { recursive: true }).filter((f) => String(f).endsWith(".html"));
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 = fs3.readFileSync(
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
- // src/commands/generate-types.ts
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(colors2) {
370
+ function flattenColors(colors) {
390
371
  const result = [];
391
- for (const [key, value] of Object.entries(colors2)) {
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
- // src/generator/type-generator.ts
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
- var STATIC_VALUE_TYPES = {
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
- "flow-row",
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 colors2 = flattenColors(theme.colors || {});
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: colors2,
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
- "0",
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 = resolve2(outputPath);
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 resolve2(outputPath);
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, scanResult;
1150
+ let configPath;
1151
+ let scanResult;
1225
1152
  if (options.config) {
1226
- configPath = resolve3(cwd, options.config);
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: resolve3(cwd, outputPath),
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
- // src/commands/init.ts
1277
- import path4 from "path";
1278
- import { execa } from "execa";
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
- projectInfo.packageManager,
1348
- ["add", "-D", "tailwindcss", twPackage],
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 = path4.join(
1276
+ const configPath = path.join(
1362
1277
  cwd,
1363
1278
  projectInfo.hasTypeScript ? "csszyx.config.ts" : "csszyx.config.js"
1364
1279
  );
1365
- await fs4.writeFile(configPath, configContent);
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 = path4.join(cwd, ".gitignore");
1286
+ const gitignorePath = path.join(cwd, ".gitignore");
1372
1287
  const ignoreEntry = "\n# csszyx generated theme types\n.csszyx\n";
1373
- if (fs4.existsSync(gitignorePath)) {
1374
- const content = await fs4.readFile(gitignorePath, "utf8");
1288
+ if (fs.existsSync(gitignorePath)) {
1289
+ const content = await fs.readFile(gitignorePath, "utf8");
1375
1290
  if (!content.includes(".csszyx")) {
1376
- await fs4.appendFile(gitignorePath, ignoreEntry);
1291
+ await fs.appendFile(gitignorePath, ignoreEntry);
1377
1292
  }
1378
1293
  } else {
1379
- await fs4.writeFile(gitignorePath, "node_modules\n.csszyx\n");
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 = path4.join(cwd, candidate);
1402
- if (fs4.existsSync(full)) {
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 = path4.join(cwd, "src/index.css");
1409
- await fs4.ensureDir(path4.dirname(cssPath));
1410
- await fs4.writeFile(cssPath, '@import "tailwindcss";\n');
1411
- printInfo(`Created ${path4.relative(cwd, cssPath)} with Tailwind v4 import`);
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 fs4.readFile(cssPath, "utf8");
1329
+ const content = await fs.readFile(cssPath, "utf8");
1415
1330
  if (!content.includes('@import "tailwindcss"') && !content.includes("@import 'tailwindcss'")) {
1416
- await fs4.writeFile(cssPath, `@import "tailwindcss";
1331
+ await fs.writeFile(cssPath, `@import "tailwindcss";
1417
1332
 
1418
1333
  ${content}`);
1419
- printInfo(`Added Tailwind v4 import to ${path4.relative(cwd, cssPath)}`);
1334
+ printInfo(`Added Tailwind v4 import to ${path.relative(cwd, cssPath)}`);
1420
1335
  }
1421
1336
  if (NEXTJS_FRAMEWORKS.has(framework)) {
1422
- const postcssMjs = path4.join(cwd, "postcss.config.mjs");
1423
- const postcssJs = path4.join(cwd, "postcss.config.js");
1424
- const postcssTs = path4.join(cwd, "postcss.config.ts");
1425
- if (!fs4.existsSync(postcssMjs) && !fs4.existsSync(postcssJs) && !fs4.existsSync(postcssTs)) {
1426
- await fs4.writeFile(postcssMjs, generatePostcssConfig());
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
- path4.join(cwd, "vite.config.ts"),
1452
- path4.join(cwd, "vite.config.js"),
1453
- path4.join(cwd, "vite.config.mts"),
1454
- path4.join(cwd, "vite.config.mjs")
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 (fs4.existsSync(c)) {
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 fs4.readFile(configPath, "utf8");
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) + "\n" + importBlock + content.slice(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 fs4.writeFile(configPath, content);
1489
- printInfo(`Injected csszyx plugin into ${path4.basename(configPath)}`);
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
- path4.join(cwd, "next.config.ts"),
1495
- path4.join(cwd, "next.config.mjs"),
1496
- path4.join(cwd, "next.config.js")
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 (fs4.existsSync(c)) {
1416
+ if (fs.existsSync(c)) {
1501
1417
  configPath = c;
1502
1418
  break;
1503
1419
  }
1504
1420
  }
1505
1421
  if (!configPath) {
1506
- configPath = path4.join(cwd, "next.config.js");
1507
- await fs4.writeFile(configPath, generateNextConfig());
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 fs4.readFile(configPath, "utf8");
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 = path4.join(cwd, "tsconfig.json");
1519
- if (!fs4.existsSync(tsconfigPath)) {
1520
- const viteTsConfig = path4.join(cwd, "tsconfig.app.json");
1521
- if (fs4.existsSync(viteTsConfig)) {
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 (!fs4.existsSync(tsconfigPath)) {
1441
+ if (!fs.existsSync(tsconfigPath)) {
1526
1442
  return;
1527
1443
  }
1528
- let content = await fs4.readFile(tsconfigPath, "utf8");
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 fs4.writeFile(tsconfigPath, content);
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(([k, v]) => `${innerSpaces}${formatKey(k)}: ${formatValue(v, indent + 2)},`);
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}}`;
@@ -1659,7 +1565,7 @@ function isGradientObj(v) {
1659
1565
  return typeof v === "object" && v !== null && "gradient" in v;
1660
1566
  }
1661
1567
  function formatKey(key) {
1662
- if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) {
1568
+ if (/^[a-z_$][\w$]*$/i.test(key)) {
1663
1569
  return key;
1664
1570
  }
1665
1571
  return `'${key}'`;
@@ -1717,14 +1623,13 @@ function escapeString(s) {
1717
1623
  return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
1718
1624
  }
1719
1625
 
1720
- // src/migrate/reverse-map.ts
1721
- var REVERSE_PROPERTY_MAP = {
1626
+ const REVERSE_PROPERTY_MAP = {
1722
1627
  // Background (ambiguous — disambiguated in class-parser)
1723
- "bg": "bg",
1628
+ bg: "bg",
1724
1629
  "bg-clip": "bgClip",
1725
1630
  "bg-origin": "bgOrigin",
1726
1631
  // Border Radius
1727
- "rounded": "rounded",
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
- "border": "border",
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
- "divide": "divideColor",
1660
+ divide: "divideColor",
1756
1661
  // Outline (ambiguous)
1757
- "outline": "outline",
1662
+ outline: "outline",
1758
1663
  "outline-offset": "outlineOffset",
1759
1664
  // Ring (v4: outset ring + inset ring)
1760
- "ring": "ring",
1665
+ ring: "ring",
1761
1666
  "ring-offset": "ringOffset",
1762
1667
  "inset-ring": "insetRing",
1763
1668
  // Spacing
1764
- "p": "p",
1765
- "pt": "pt",
1766
- "pr": "pr",
1767
- "pb": "pb",
1768
- "pl": "pl",
1769
- "px": "px",
1770
- "py": "py",
1771
- "ps": "ps",
1772
- "pe": "pe",
1773
- "m": "m",
1774
- "mt": "mt",
1775
- "mr": "mr",
1776
- "mb": "mb",
1777
- "ml": "ml",
1778
- "mx": "mx",
1779
- "my": "my",
1780
- "ms": "ms",
1781
- "me": "me",
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
- "w": "w",
1691
+ w: "w",
1787
1692
  "min-w": "minW",
1788
1693
  "max-w": "maxW",
1789
- "h": "h",
1694
+ h: "h",
1790
1695
  "min-h": "minH",
1791
1696
  "max-h": "maxH",
1792
- "size": "size",
1697
+ size: "size",
1793
1698
  // Layout
1794
- "aspect": "aspect",
1795
- "columns": "columns",
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
- "box": "box",
1801
- "float": "float",
1802
- "clear": "clear",
1803
- "object": "objectFit",
1705
+ box: "box",
1706
+ float: "float",
1707
+ clear: "clear",
1708
+ object: "objectFit",
1804
1709
  // ambiguous — objectFit vs objectPos (objectPos for position values)
1805
- "overflow": "overflow",
1710
+ overflow: "overflow",
1806
1711
  "overflow-x": "overflowX",
1807
1712
  "overflow-y": "overflowY",
1808
- "overscroll": "overscroll",
1713
+ overscroll: "overscroll",
1809
1714
  "overscroll-x": "overscrollX",
1810
1715
  "overscroll-y": "overscrollY",
1811
- "z": "z",
1716
+ z: "z",
1812
1717
  // Inset
1813
- "inset": "inset",
1718
+ inset: "inset",
1814
1719
  "inset-x": "insetX",
1815
1720
  "inset-y": "insetY",
1816
- "top": "top",
1817
- "right": "right",
1818
- "bottom": "bottom",
1819
- "left": "left",
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
- "start": "insetS",
1822
- "end": "insetE",
1726
+ start: "insetS",
1727
+ end: "insetE",
1823
1728
  // Typography (ambiguous — text-*, font-* disambiguated)
1824
- "text": "color",
1729
+ text: "color",
1825
1730
  // default for text- prefix
1826
- "font": "fontWeight",
1731
+ font: "fontWeight",
1827
1732
  // default for font- prefix
1828
- "decoration": "decoration",
1733
+ decoration: "decoration",
1829
1734
  // ambiguous
1830
1735
  "underline-offset": "underlineOffset",
1831
- "indent": "indent",
1832
- "align": "align",
1833
- "whitespace": "whitespace",
1834
- "break": "break",
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
- "hyphens": "hyphens",
1837
- "content": "content",
1838
- "leading": "leading",
1839
- "tracking": "tracking",
1840
- "list": "list",
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
- "basis": "basis",
1845
- "flex": "flex",
1749
+ basis: "basis",
1750
+ flex: "flex",
1846
1751
  // ambiguous (boolean flex, flexDirection, flexWrap)
1847
- "grow": "grow",
1848
- "shrink": "shrink",
1849
- "order": "order",
1850
- "items": "items",
1851
- "self": "self",
1852
- "justify": "justify",
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
- "gap": "gap",
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
- "col": "col",
1769
+ col: "col",
1865
1770
  "col-span": "colSpan",
1866
1771
  "col-start": "colStart",
1867
1772
  "col-end": "colEnd",
1868
- "row": "row",
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
- "shadow": "shadow",
1781
+ shadow: "shadow",
1877
1782
  // ambiguous (shadow vs shadowColor)
1878
1783
  "inset-shadow": "insetShadow",
1879
- "opacity": "opacity",
1784
+ opacity: "opacity",
1880
1785
  "mix-blend": "mixBlend",
1881
1786
  "bg-blend": "bgBlend",
1882
1787
  // Filters
1883
- "blur": "blur",
1884
- "brightness": "brightness",
1885
- "contrast": "contrast",
1788
+ blur: "blur",
1789
+ brightness: "brightness",
1790
+ contrast: "contrast",
1886
1791
  "drop-shadow": "dropShadow",
1887
- "grayscale": "grayscale",
1792
+ grayscale: "grayscale",
1888
1793
  "hue-rotate": "hueRotate",
1889
- "invert": "invert",
1890
- "saturate": "saturate",
1891
- "sepia": "sepia",
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
- "scale": "scale",
1807
+ scale: "scale",
1903
1808
  "scale-x": "scaleX",
1904
1809
  "scale-y": "scaleY",
1905
- "rotate": "rotate",
1810
+ rotate: "rotate",
1906
1811
  "translate-x": "translateX",
1907
1812
  "translate-y": "translateY",
1908
1813
  "skew-x": "skewX",
1909
1814
  "skew-y": "skewY",
1910
- "origin": "origin",
1815
+ origin: "origin",
1911
1816
  // Transitions & Animation
1912
- "transition": "transition",
1913
- "duration": "duration",
1914
- "ease": "ease",
1915
- "delay": "delay",
1916
- "animate": "animate",
1817
+ transition: "transition",
1818
+ duration: "duration",
1819
+ ease: "ease",
1820
+ delay: "delay",
1821
+ animate: "animate",
1917
1822
  // Interactivity
1918
- "cursor": "cursor",
1919
- "caret": "caret",
1823
+ cursor: "cursor",
1824
+ caret: "caret",
1920
1825
  "pointer-events": "pointerEvents",
1921
- "resize": "resize",
1922
- "scroll": "scroll",
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
- "snap": "snapType",
1846
+ snap: "snapType",
1942
1847
  // ambiguous
1943
- "touch": "touch",
1944
- "select": "select",
1848
+ touch: "touch",
1849
+ select: "select",
1945
1850
  "will-change": "willChange",
1946
- "accent": "accent",
1851
+ accent: "accent",
1947
1852
  // SVG
1948
- "fill": "fill",
1949
- "stroke": "stroke",
1853
+ fill: "fill",
1854
+ stroke: "stroke",
1950
1855
  // Tables
1951
1856
  "border-spacing": "borderSpacing",
1952
- "table": "tableLayout",
1857
+ table: "tableLayout",
1953
1858
  // ambiguous with boolean "table" display
1954
- "caption": "caption",
1859
+ caption: "caption",
1955
1860
  // Line clamp
1956
1861
  "line-clamp": "lineClamp",
1957
- "wrap": "wrap",
1862
+ wrap: "wrap",
1958
1863
  // Text shadow
1959
1864
  "text-shadow": "textShadow",
1960
1865
  // Gradient stops
1961
- "from": "from",
1962
- "via": "via",
1963
- "to": "to",
1866
+ from: "from",
1867
+ via: "via",
1868
+ to: "to",
1964
1869
  // Masks
1965
- "mask": "mask",
1870
+ mask: "mask",
1966
1871
  // Forced colors
1967
1872
  "forced-color-adjust": "forcedColorAdjust",
1968
1873
  // Perspective
1969
- "perspective": "perspective",
1874
+ perspective: "perspective",
1970
1875
  "perspective-origin": "perspectiveOrigin",
1971
- "backface": "backface"
1876
+ backface: "backface"
1972
1877
  };
1973
- var REVERSE_BOOLEAN_MAP = {
1878
+ const REVERSE_BOOLEAN_MAP = {
1974
1879
  // Display
1975
- "block": "block",
1976
- "inline": "inline",
1880
+ block: "block",
1881
+ inline: "inline",
1977
1882
  "inline-block": "inlineBlock",
1978
- "flex": "flex",
1883
+ flex: "flex",
1979
1884
  "inline-flex": "inlineFlex",
1980
- "grid": "grid",
1885
+ grid: "grid",
1981
1886
  "inline-grid": "inlineGrid",
1982
- "hidden": "hidden",
1983
- "contents": "contents",
1984
- "table": "table",
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
- "static": "static",
1991
- "fixed": "fixed",
1992
- "absolute": "absolute",
1993
- "relative": "relative",
1994
- "sticky": "sticky",
1895
+ static: "static",
1896
+ fixed: "fixed",
1897
+ absolute: "absolute",
1898
+ relative: "relative",
1899
+ sticky: "sticky",
1995
1900
  // Visibility
1996
- "visible": "visible",
1997
- "invisible": "invisible",
1998
- "collapse": "collapse",
1901
+ visible: "visible",
1902
+ invisible: "invisible",
1903
+ collapse: "collapse",
1999
1904
  // Typography
2000
- "truncate": "truncate",
2001
- "uppercase": "uppercase",
2002
- "lowercase": "lowercase",
2003
- "capitalize": "capitalize",
1905
+ truncate: "truncate",
1906
+ uppercase: "uppercase",
1907
+ lowercase: "lowercase",
1908
+ capitalize: "capitalize",
2004
1909
  "normal-case": "normalCase",
2005
- "underline": "underline",
2006
- "overline": "overline",
1910
+ underline: "underline",
1911
+ overline: "overline",
2007
1912
  "line-through": "lineThrough",
2008
1913
  "no-underline": "noUnderline",
2009
- "italic": "italic",
1914
+ italic: "italic",
2010
1915
  "not-italic": "notItalic",
2011
- "antialiased": "antialiased",
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
- "blur": "blur",
2017
- "grayscale": "grayscale",
2018
- "invert": "invert",
2019
- "sepia": "sepia",
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
- "container": "container",
2026
- "prose": "prose",
1930
+ container: "container",
1931
+ prose: "prose",
2027
1932
  "sr-only": "srOnly",
2028
1933
  "not-sr-only": "notSrOnly",
2029
- "isolate": "isolate",
2030
- "ordinal": "ordinal",
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
- "ring": "ring",
1943
+ ring: "ring",
2039
1944
  "inset-ring": "insetRing",
2040
- "outline": "outline",
2041
- "rounded": "rounded",
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
- var BOOLEAN_VALUE_MAP = {
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
- var SORTED_PREFIXES = Object.keys(REVERSE_PROPERTY_MAP).sort((a, b) => {
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
- var NEGATIVE_ALLOWED = /* @__PURE__ */ new Set([
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
- var FRACTION_SUPPORTED = /* @__PURE__ */ new Set([
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
- var SPACING_PROPS = /* @__PURE__ */ new Set([
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
- var TEXT_SIZE_KEYWORDS = /* @__PURE__ */ new Set([
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
- var TEXT_ALIGN_KEYWORDS = /* @__PURE__ */ new Set([
2266
- "left",
2267
- "center",
2268
- "right",
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
- var FONT_FAMILY_KEYWORDS = /* @__PURE__ */ new Set([
2295
- "sans",
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
- var BORDER_WIDTH_KEYWORDS = /* @__PURE__ */ new Set(["0", "2", "4", "8"]);
2310
- var BORDER_STYLE_KEYWORDS = /* @__PURE__ */ new Set([
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
- var BG_POSITION_KEYWORDS = /* @__PURE__ */ new Set([
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
- var BG_SIZE_KEYWORDS = /* @__PURE__ */ new Set(["cover", "contain", "auto"]);
2330
- var BG_REPEAT_KEYWORDS = /* @__PURE__ */ new Set([
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
- var BG_ATTACHMENT_KEYWORDS = /* @__PURE__ */ new Set(["fixed", "local", "scroll"]);
2339
- var OBJECT_FIT_KEYWORDS = /* @__PURE__ */ new Set(["contain", "cover", "fill", "none", "scale-down"]);
2340
- var OBJECT_POSITION_KEYWORDS = /* @__PURE__ */ new Set([
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
- var SHADOW_SIZE_KEYWORDS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl", "inner", "none"]);
2352
- var OUTLINE_STYLE_KEYWORDS = /* @__PURE__ */ new Set(["none", "dashed", "dotted", "double"]);
2353
- var DECORATION_STYLE_KEYWORDS = /* @__PURE__ */ new Set(["solid", "double", "dotted", "dashed", "wavy"]);
2354
- var DECORATION_THICKNESS_KEYWORDS = /* @__PURE__ */ new Set(["auto", "from-font", "0", "1", "2", "4", "8"]);
2355
- var TRANSITION_PROPERTY_KEYWORDS = /* @__PURE__ */ new Set([
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
- var REVERSE_VARIANT_MAP = {
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
- var KNOWN_SIMPLE_VARIANTS = /* @__PURE__ */ new Set([
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
- var KNOWN_VARIANTS = /* @__PURE__ */ new Set([
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({ prop: REVERSE_BOOLEAN_MAP[source], value: true }, important);
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 (["border-t", "border-r", "border-b", "border-l", "border-x", "border-y", "border-s", "border-e"].includes(prefix)) {
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
- prop: inner.slice(0, colonIdx),
2530
- value: inner.slice(colonIdx + 1)
2531
- }, important);
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(value);
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
- var 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)$/;
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 "-" + inner;
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 "-" + inner;
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 "-" + value;
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 = findTopLevelSlash2(rest);
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 findTopLevelSlash2(s) {
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
- var TODO_KEEP = "sz:keep";
3228
- var TODO_REMOVE = "sz:remove";
3229
- var TODO_PENDING = "sz:todo";
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
- // src/migrate/dynamic-patterns.ts
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, t2, customMap) {
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 (t2.isSpreadElement(arg)) {
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 (t2.isStringLiteral(arg)) {
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 (t2.isLogicalExpression(arg) && arg.operator === "&&") {
3358
- const result = handleLogicalAndInner(arg, source, t2, customMap);
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 (t2.isConditionalExpression(arg)) {
3370
- const result = handleTernaryInner(arg, source, t2, customMap);
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, t2, customMap) {
3406
- const result = handleTernaryInner(node, source, t2, customMap);
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, t2, customMap) {
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, t2, customMap);
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, t2, customMap) {
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, t2)) {
3467
- const exprSrc2 = safeSlice(source, expr.start, expr.end);
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 (t2.isStringLiteral(expr)) {
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 (t2.isConditionalExpression(expr)) {
3482
- const result = handleTernaryInner(expr, source, t2, customMap);
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 (t2.isLogicalExpression(expr) && expr.operator === "&&") {
3494
- const result = handleLogicalAndInner(expr, source, t2, customMap);
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, t2, customMap) {
3537
- if (!t2.isStringLiteral(node.consequent) || !t2.isStringLiteral(node.alternate)) {
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, t2, customMap) {
3581
- if (!t2.isStringLiteral(node.right)) {
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, t2) {
3630
- return t2.isExpression(node);
3531
+ function isExpression(node, t) {
3532
+ return t.isExpression(node);
3631
3533
  }
3632
3534
 
3633
- // src/migrate/ast-transformer.ts
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(path6) {
3680
- const src = path6.node.source.value;
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 path6.node.specifiers) {
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(path6) {
3696
- if (t.isIdentifier(path6.node.callee) && clsxImportNames.has(path6.node.callee.name)) {
3697
- const inClassName = path6.findParent(
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(path6) {
3707
- const attrName = path6.node.name;
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 = path6.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 = path6.node.value;
3730
- const attrStart = path6.node.start;
3731
- const attrEnd = path6.node.end;
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, path6.parent, options, replacements);
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({ start: attrStart, end: attrEnd, text: result.replacement });
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, path6.parent, options, replacements);
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({ start: attrStart, end: attrEnd, text: result.replacement });
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, path6.parent, options, replacements);
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({ start: attrStart, end: attrEnd, text: result.replacement });
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, path6.parent, options, replacements);
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({ start: attrStart, end: attrEnd, text: result.replacement });
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, path6.parent, options, replacements);
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({ start: attrStart, end: attrEnd, text: result.replacement });
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, path6.parent, options, replacements);
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
- var FOUC_CSS = `<style>
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}"></script>`;
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 = path5.join(cwd, ".csszyx", "logs");
3944
- fs5.mkdirSync(logDir, { recursive: true });
3945
- const filePath = path5.join(logDir, `migrate-${ts}.log`);
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: () => fs5.writeFileSync(filePath, lines.join("\n") + "\n", "utf-8")
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 = fs5.readFileSync(path5.join(cwd, ".gitignore"), "utf-8");
3876
+ const content = fs$1.readFileSync(path.join(cwd, ".gitignore"), "utf-8");
3956
3877
  return content.split("\n").some((l) => {
3957
- const t2 = l.trim();
3958
- return t2 === pattern || t2 === pattern + "/" || t2 === "/" + pattern;
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((resolve4) => {
3887
+ return new Promise((resolve) => {
3967
3888
  rl.question(question, (answer) => {
3968
3889
  rl.close();
3969
- resolve4(answer.trim().toLowerCase() === "y");
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 audit2 = options.audit || false;
3898
+ const audit = options.audit || false;
3978
3899
  const resolveTodosPath = options.resolveTodos;
3979
3900
  let customMap, files;
3980
- if (audit2) {
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 && !audit2 && !resolveTodosPath) {
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 = path5.resolve(cwd, resolveTodosPath);
3999
- const content = fs5.readFileSync(absolutePath, "utf-8");
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(`Could not load resolve map from ${resolveTodosPath}. Ensure the file exists and is valid JSON.`);
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 (audit2) {
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(`Mode: ${audit2 ? "audit" : dryRun ? "dry-run" : "migrate"}${resolveTodosPath ? ` (resolve-todos: ${resolveTodosPath})` : ""}`);
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("Tip: add .csszyx/ to your .gitignore to exclude migration logs from version control.");
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(options.pattern ? `No files found matching pattern: ${options.pattern}` : "No JSX/TSX/HTML files found");
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 = fs5.readFileSync(filePath, "utf-8");
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) {
@@ -4057,7 +3986,10 @@ async function migrate(options = {}) {
4057
3986
  }
4058
3987
  let processSource = source;
4059
3988
  if (resolveTodosPath && !isHtml) {
4060
- processSource = processSource.replace(/\{\/\*\s*@sz-todo:\s*(.*?)\s*\*\/\}\n?/g, "");
3989
+ processSource = processSource.replace(
3990
+ /\{\/\*\s*@sz-todo:\s*(\S(?:.*\S)?)\s*\*\/\}\n?/g,
3991
+ ""
3992
+ );
4061
3993
  }
4062
3994
  const result = isHtml ? transformHtmlSourceSimple(processSource, filePath, {
4063
3995
  braces: options.braces,
@@ -4073,20 +4005,22 @@ async function migrate(options = {}) {
4073
4005
  totalSkipped += result.stats.classNamesSkipped;
4074
4006
  allUnrecognized.push(...result.stats.classesUnrecognized);
4075
4007
  if (result.potentiallyUnusedImports.length > 0) {
4076
- const rel2 = path5.relative(cwd, filePath);
4008
+ const rel2 = path.relative(cwd, filePath);
4077
4009
  unusedImportFiles.push({ file: rel2, imports: result.potentiallyUnusedImports });
4078
4010
  }
4079
4011
  if (!dryRun) {
4080
4012
  try {
4081
- fs5.writeFileSync(filePath, result.code, "utf-8");
4013
+ fs$1.writeFileSync(filePath, result.code, "utf-8");
4082
4014
  } catch (err) {
4083
- const rel2 = path5.relative(cwd, filePath);
4084
- printWarn(`Could not write ${rel2}: ${err instanceof Error ? err.message : String(err)}`);
4015
+ const rel2 = path.relative(cwd, filePath);
4016
+ printWarn(
4017
+ `Could not write ${rel2}: ${err instanceof Error ? err.message : String(err)}`
4018
+ );
4085
4019
  log.writeLine(` Write error: ${rel2}`);
4086
4020
  continue;
4087
4021
  }
4088
4022
  }
4089
- const rel = path5.relative(cwd, filePath);
4023
+ const rel = path.relative(cwd, filePath);
4090
4024
  if (dryRun) {
4091
4025
  printInfo(` ${rel}: ${result.stats.classNamesTransformed} className(s) \u2192 sz`);
4092
4026
  log.writeLine(` ${rel}: ${result.stats.classNamesTransformed} className(s) \u2192 sz`);
@@ -4107,7 +4041,9 @@ async function migrate(options = {}) {
4107
4041
  }
4108
4042
  if (allUnrecognized.length > 0) {
4109
4043
  const unique = [...new Set(allUnrecognized)];
4110
- printWarn(`Unrecognized classes (${unique.length}): ${unique.slice(0, 10).join(", ")}${unique.length > 10 ? "..." : ""}`);
4044
+ printWarn(
4045
+ `Unrecognized classes (${unique.length}): ${unique.slice(0, 10).join(", ")}${unique.length > 10 ? "..." : ""}`
4046
+ );
4111
4047
  log.writeLine(`Unrecognized classes (${unique.length}): ${unique.join(", ")}`);
4112
4048
  }
4113
4049
  if (allWarnings.length > 0) {
@@ -4124,12 +4060,14 @@ async function migrate(options = {}) {
4124
4060
  log.writeLine(` ${w}`);
4125
4061
  }
4126
4062
  }
4127
- if (audit2) {
4128
- const todoPath = path5.join(cwd, ".csszyx-todo.json");
4063
+ if (audit) {
4064
+ const todoPath = path.join(cwd, ".csszyx-todo.json");
4129
4065
  const unique = [...new Set(allUnrecognized)];
4130
4066
  console.info();
4131
4067
  if (unique.length === 0) {
4132
- printSuccess("Audit complete. 100% of your classes are perfectly recognized by csszyx!");
4068
+ printSuccess(
4069
+ "Audit complete. 100% of your classes are perfectly recognized by csszyx!"
4070
+ );
4133
4071
  log.writeLine("Audit: 100% recognized.");
4134
4072
  } else {
4135
4073
  const todoObj = {};
@@ -4137,22 +4075,32 @@ async function migrate(options = {}) {
4137
4075
  todoObj[u] = "sz:todo";
4138
4076
  }
4139
4077
  try {
4140
- fs5.writeFileSync(todoPath, JSON.stringify(todoObj, null, 2));
4078
+ fs$1.writeFileSync(todoPath, JSON.stringify(todoObj, null, 2));
4141
4079
  } catch (err) {
4142
- printWarn(`Could not write ${path5.relative(cwd, todoPath)}: ${err instanceof Error ? err.message : String(err)}`);
4080
+ printWarn(
4081
+ `Could not write ${path.relative(cwd, todoPath)}: ${err instanceof Error ? err.message : String(err)}`
4082
+ );
4143
4083
  log.flush();
4144
4084
  return;
4145
4085
  }
4146
- printSuccess(`Audit complete. Exported ${unique.length} unrecognized classes to ${path5.relative(cwd, todoPath)}.`);
4147
- printInfo("Edit this file to map custom classes, then run: npx @csszyx/cli migrate --resolve-todos .csszyx-todo.json");
4148
- log.writeLine(`Audit: ${unique.length} unrecognized classes written to ${path5.relative(cwd, todoPath)}`);
4086
+ printSuccess(
4087
+ `Audit complete. Exported ${unique.length} unrecognized classes to ${path.relative(cwd, todoPath)}.`
4088
+ );
4089
+ printInfo(
4090
+ "Edit this file to map custom classes, then run: npx @csszyx/cli migrate --resolve-todos .csszyx-todo.json"
4091
+ );
4092
+ log.writeLine(
4093
+ `Audit: ${unique.length} unrecognized classes written to ${path.relative(cwd, todoPath)}`
4094
+ );
4149
4095
  }
4150
4096
  }
4151
4097
  if (resolveTodosPath) {
4152
4098
  const unique = [...new Set(allUnrecognized)];
4153
4099
  if (unique.length > 0) {
4154
4100
  console.info();
4155
- printWarn(`Still unresolved after this pass (${unique.length}): ${unique.slice(0, 10).join(", ")}${unique.length > 10 ? "..." : ""}`);
4101
+ printWarn(
4102
+ `Still unresolved after this pass (${unique.length}): ${unique.slice(0, 10).join(", ")}${unique.length > 10 ? "..." : ""}`
4103
+ );
4156
4104
  printInfo("Re-run --audit to generate a fresh snapshot when ready.");
4157
4105
  log.writeLine(`Still unresolved (${unique.length}): ${unique.join(", ")}`);
4158
4106
  }
@@ -4167,14 +4115,13 @@ async function migrate(options = {}) {
4167
4115
  }
4168
4116
  try {
4169
4117
  log.flush();
4170
- printInfo(`Migration log saved to ${path5.relative(cwd, log.filePath)}`);
4118
+ printInfo(`Migration log saved to ${path.relative(cwd, log.filePath)}`);
4171
4119
  } catch {
4172
4120
  }
4173
4121
  }
4174
4122
 
4175
- // src/index.ts
4176
- var cli = cac("csszyx");
4177
- var VERSION = "0.0.0";
4123
+ const cli = cac("csszyx");
4124
+ const VERSION = "0.0.0";
4178
4125
  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
4126
  await init({
4180
4127
  framework: options.framework,
@@ -4196,10 +4143,7 @@ cli.command("audit", "Analyze mangling performance").option("--json", "Output as
4196
4143
  cwd: options.cwd
4197
4144
  });
4198
4145
  });
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) => {
4146
+ 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
4147
  await generateTypes({
4204
4148
  config: options.config,
4205
4149
  output: options.output,
@@ -4207,7 +4151,10 @@ cli.command(
4207
4151
  silent: options.silent
4208
4152
  });
4209
4153
  });
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("--local-path <path>", "Local script path for --inject-runtime local (default: csszyx-runtime.js)").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) => {
4154
+ 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(
4155
+ "--local-path <path>",
4156
+ "Local script path for --inject-runtime local (default: csszyx-runtime.js)"
4157
+ ).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
4158
  await migrate({
4212
4159
  dryRun: options.dryRun,
4213
4160
  ignore: options.ignore ? options.ignore.split(",") : void 0,
@@ -4229,16 +4176,5 @@ cli.command("").action(() => {
4229
4176
  cli.help();
4230
4177
  cli.version(VERSION);
4231
4178
  cli.parse();
4232
- export {
4233
- classNameToSzObject,
4234
- extractScreenKeys,
4235
- extractSpacingKeys,
4236
- findConfigFile,
4237
- flattenColors,
4238
- generateAndWriteTypes,
4239
- generateTypeDeclarations,
4240
- generateTypes,
4241
- transformSource as migrateSource,
4242
- scanTailwindConfig,
4243
- writeDeclarationFile
4244
- };
4179
+
4180
+ export { classNameToSzObject, extractScreenKeys, extractSpacingKeys, findConfigFile, flattenColors, generateAndWriteTypes, generateTypeDeclarations, generateTypes, transformSource as migrateSource, scanTailwindConfig, writeDeclarationFile };