tailwind-unwind 0.4.0 → 0.5.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.
@@ -1530,8 +1530,10 @@ async function scanProject(options) {
1530
1530
  topLimit: options.topLimit,
1531
1531
  dedupeSubsets: options.dedupeSubsets
1532
1532
  });
1533
+ const analyzeMinOccurrences = options.minOccurrences ?? 5;
1534
+ const extractableMinOccurrences = options.extractableMinOccurrences ?? 3;
1533
1535
  const extractableSets = findRepeatedClassSets(occurrences, {
1534
- minOccurrences: options.extractableMinOccurrences ?? 3,
1536
+ minOccurrences: extractableMinOccurrences,
1535
1537
  minSize: options.minSize,
1536
1538
  maxSize: options.maxSize,
1537
1539
  topLimit: Number.POSITIVE_INFINITY
@@ -1558,7 +1560,10 @@ async function scanProject(options) {
1558
1560
  0
1559
1561
  ),
1560
1562
  topCombinations,
1561
- potentialReductionPercent
1563
+ potentialReductionPercent,
1564
+ extractablePatternCount: extractableSets.length,
1565
+ analyzeMinOccurrences,
1566
+ extractableMinOccurrences
1562
1567
  },
1563
1568
  parseWarnings: warnings
1564
1569
  };
@@ -1567,7 +1572,8 @@ async function scanProject(options) {
1567
1572
  files,
1568
1573
  occurrences,
1569
1574
  warnings,
1570
- report
1575
+ report,
1576
+ extractableCombinations: extractableSets
1571
1577
  };
1572
1578
  }
1573
1579
 
@@ -1659,16 +1665,8 @@ async function initCommand(targetPath, options = {}) {
1659
1665
  );
1660
1666
  console.log("");
1661
1667
  console.log(chalk.cyan("Next steps:"));
1662
- console.log(
1663
- chalk.white(
1664
- ` npx tailwind-unwind analyze ${targetPath} --config ${path5.basename(outputPath)}`
1665
- )
1666
- );
1667
- console.log(
1668
- chalk.white(
1669
- ` npx tailwind-unwind generate ${targetPath} --config ${path5.basename(outputPath)}`
1670
- )
1671
- );
1668
+ console.log(chalk.white(" npx tailwind-unwind check"));
1669
+ console.log(chalk.white(" npx tailwind-unwind generate"));
1672
1670
  console.log("");
1673
1671
  return {
1674
1672
  configPath: outputPath,
@@ -1753,26 +1751,35 @@ function printConsoleReport(report, options = {}) {
1753
1751
  `\u{1F4A1} Potential code reduction: ${stats.potentialReductionPercent}%`
1754
1752
  )
1755
1753
  );
1756
- const extractableCount = stats.topCombinations.filter(
1754
+ const extractableInTop = stats.topCombinations.filter(
1757
1755
  (combo) => combo.extractable
1758
1756
  ).length;
1759
- if (extractableCount > 0) {
1757
+ if (stats.analyzeMinOccurrences !== stats.extractableMinOccurrences) {
1758
+ console.log("");
1759
+ console.log(
1760
+ chalk2.yellow(
1761
+ `Note: this list uses min-occurrences ${stats.analyzeMinOccurrences}; generate/apply extract exact duplicates with \u2265${stats.extractableMinOccurrences}.`
1762
+ )
1763
+ );
1764
+ if (stats.extractablePatternCount > extractableInTop) {
1765
+ console.log(
1766
+ chalk2.yellow(
1767
+ ` ${stats.extractablePatternCount} extractable pattern(s) total in project.`
1768
+ )
1769
+ );
1770
+ }
1771
+ } else if (stats.extractablePatternCount > 0) {
1760
1772
  console.log(
1761
1773
  chalk2.magenta(
1762
- `\u{1F4A1} ${extractableCount} pattern(s) ready for generate/apply`
1774
+ `\u{1F4A1} ${stats.extractablePatternCount} extractable pattern(s) ready for generate/apply`
1763
1775
  )
1764
1776
  );
1765
1777
  }
1766
1778
  console.log(
1767
- chalk2.magenta(
1768
- "\u{1F4A1} Generate CSS: npx tailwind-unwind generate <path> --output styles.css"
1769
- )
1770
- );
1771
- console.log(
1772
- chalk2.magenta(
1773
- "\u{1F4A1} Apply classes: npx tailwind-unwind apply <path> --output styles.css"
1774
- )
1779
+ chalk2.magenta("\u{1F4A1} Quick check: npx tailwind-unwind check")
1775
1780
  );
1781
+ console.log(chalk2.magenta("\u{1F4A1} Generate CSS: npx tailwind-unwind generate"));
1782
+ console.log(chalk2.magenta("\u{1F4A1} Apply classes: npx tailwind-unwind apply"));
1776
1783
  console.log("");
1777
1784
  }
1778
1785
 
@@ -1796,7 +1803,7 @@ async function analyzeCommand(targetPath, options = {}) {
1796
1803
  include: options.include,
1797
1804
  exclude: options.exclude,
1798
1805
  changed: options.changed,
1799
- extractableMinOccurrences: 3
1806
+ extractableMinOccurrences: options.extractableMinOccurrences
1800
1807
  });
1801
1808
  } catch (error) {
1802
1809
  const message = error instanceof Error ? error.message : String(error);
@@ -1817,31 +1824,31 @@ async function analyzeCommand(targetPath, options = {}) {
1817
1824
  return report;
1818
1825
  }
1819
1826
 
1820
- // src/analyzer/savings.ts
1821
- function calculateSavings(replacements) {
1822
- if (replacements.length === 0) {
1823
- return {
1824
- replacementCount: 0,
1825
- utilityTokensBefore: 0,
1826
- utilityTokensAfter: 0,
1827
- tokensSaved: 0,
1828
- percentReduction: 0
1829
- };
1830
- }
1831
- let utilityTokensBefore = 0;
1832
- for (const replacement of replacements) {
1833
- utilityTokensBefore += replacement.from.split(/\s+/).filter(Boolean).length;
1827
+ // src/cli/defaults.ts
1828
+ var DEFAULT_TARGET_PATH = ".";
1829
+ var DEFAULT_OUTPUT_PATH = "styles.css";
1830
+ var ANALYZE_DEFAULTS = {
1831
+ minOccurrences: 5,
1832
+ minSize: 2,
1833
+ maxSize: 5,
1834
+ top: 10
1835
+ };
1836
+ var GENERATE_DEFAULTS = {
1837
+ minOccurrences: 3,
1838
+ minSize: 2,
1839
+ maxSize: 5,
1840
+ top: 10,
1841
+ prefix: "twu-",
1842
+ output: DEFAULT_OUTPUT_PATH
1843
+ };
1844
+ function resolveTargetPath(targetPath) {
1845
+ if (typeof targetPath === "string" && targetPath.trim().length > 0) {
1846
+ return targetPath;
1834
1847
  }
1835
- const utilityTokensAfter = replacements.length;
1836
- const tokensSaved = Math.max(0, utilityTokensBefore - utilityTokensAfter);
1837
- const percentReduction = utilityTokensBefore === 0 ? 0 : Math.round(tokensSaved / utilityTokensBefore * 100);
1838
- return {
1839
- replacementCount: replacements.length,
1840
- utilityTokensBefore,
1841
- utilityTokensAfter,
1842
- tokensSaved,
1843
- percentReduction
1844
- };
1848
+ return DEFAULT_TARGET_PATH;
1849
+ }
1850
+ function resolveOutputPath(cliOutput, configOutput) {
1851
+ return cliOutput ?? configOutput ?? DEFAULT_OUTPUT_PATH;
1845
1852
  }
1846
1853
 
1847
1854
  // src/codemod/formatSource.ts
@@ -2294,6 +2301,33 @@ async function loadExtractableCombinations(reportPath, options = {}) {
2294
2301
  };
2295
2302
  }
2296
2303
 
2304
+ // src/analyzer/savings.ts
2305
+ function calculateSavings(replacements) {
2306
+ if (replacements.length === 0) {
2307
+ return {
2308
+ replacementCount: 0,
2309
+ utilityTokensBefore: 0,
2310
+ utilityTokensAfter: 0,
2311
+ tokensSaved: 0,
2312
+ percentReduction: 0
2313
+ };
2314
+ }
2315
+ let utilityTokensBefore = 0;
2316
+ for (const replacement of replacements) {
2317
+ utilityTokensBefore += replacement.from.split(/\s+/).filter(Boolean).length;
2318
+ }
2319
+ const utilityTokensAfter = replacements.length;
2320
+ const tokensSaved = Math.max(0, utilityTokensBefore - utilityTokensAfter);
2321
+ const percentReduction = utilityTokensBefore === 0 ? 0 : Math.round(tokensSaved / utilityTokensBefore * 100);
2322
+ return {
2323
+ replacementCount: replacements.length,
2324
+ utilityTokensBefore,
2325
+ utilityTokensAfter,
2326
+ tokensSaved,
2327
+ percentReduction
2328
+ };
2329
+ }
2330
+
2297
2331
  // src/reporters/operationJsonReporter.ts
2298
2332
  function printGenerateJsonReport(report) {
2299
2333
  console.log(JSON.stringify(report, null, 2));
@@ -2302,10 +2336,61 @@ function printApplyJsonReport(report) {
2302
2336
  console.log(JSON.stringify(report, null, 2));
2303
2337
  }
2304
2338
 
2339
+ // src/reporters/skippedReporter.ts
2340
+ import chalk4 from "chalk";
2341
+ function groupSkippedByReason(skipped) {
2342
+ const groups = /* @__PURE__ */ new Map();
2343
+ for (const item of skipped) {
2344
+ const bucket = groups.get(item.reason) ?? [];
2345
+ bucket.push(item);
2346
+ groups.set(item.reason, bucket);
2347
+ }
2348
+ return [...groups.entries()].map(([reason, items]) => ({
2349
+ reason,
2350
+ count: items.length,
2351
+ items
2352
+ })).sort((left, right) => right.count - left.count);
2353
+ }
2354
+ function printSkippedReport(skipped, options = {}) {
2355
+ if (skipped.length === 0) {
2356
+ return;
2357
+ }
2358
+ const groups = groupSkippedByReason(skipped);
2359
+ console.log("");
2360
+ console.log(chalk4.bold.yellow(`Skipped (${skipped.length}):`));
2361
+ if (options.verbose) {
2362
+ for (const item of skipped) {
2363
+ const line = item.line ? `:${item.line}` : "";
2364
+ console.log(
2365
+ chalk4.gray(` ${item.filePath}${line}`) + chalk4.yellow(` [${item.reason}]`) + chalk4.dim(` "${item.classes.join(" ")}"`)
2366
+ );
2367
+ }
2368
+ return;
2369
+ }
2370
+ for (const group of groups) {
2371
+ console.log(
2372
+ chalk4.yellow(` ${group.reason}: `) + chalk4.white(String(group.count))
2373
+ );
2374
+ const preview = group.items.slice(0, 2);
2375
+ for (const item of preview) {
2376
+ const line = item.line ? `:${item.line}` : "";
2377
+ console.log(
2378
+ chalk4.gray(` ${item.filePath}${line}`) + chalk4.dim(` "${item.classes.join(" ")}"`)
2379
+ );
2380
+ }
2381
+ if (group.items.length > 2) {
2382
+ console.log(
2383
+ chalk4.dim(` (+${group.items.length - 2} more with same reason)`)
2384
+ );
2385
+ }
2386
+ }
2387
+ console.log(chalk4.dim(" Use --verbose-skipped to list every skipped location."));
2388
+ }
2389
+
2305
2390
  // src/commands/apply.ts
2306
2391
  import fs6 from "fs/promises";
2307
2392
  import path7 from "path";
2308
- import chalk4 from "chalk";
2393
+ import chalk5 from "chalk";
2309
2394
  async function applyCommand(targetPath, options) {
2310
2395
  let scanResult;
2311
2396
  try {
@@ -2318,12 +2403,12 @@ async function applyCommand(targetPath, options) {
2318
2403
  });
2319
2404
  } catch (error) {
2320
2405
  const message = error instanceof Error ? error.message : String(error);
2321
- console.error(chalk4.red(`Error: ${message}`));
2406
+ console.error(chalk5.red(`Error: ${message}`));
2322
2407
  process.exit(1);
2323
2408
  }
2324
2409
  for (const warning of scanResult.warnings) {
2325
- if (options.format !== "json") {
2326
- console.warn(chalk4.yellow(`\u26A0 ${warning}`));
2410
+ if (!options.quiet && options.format !== "json") {
2411
+ console.warn(chalk5.yellow(`\u26A0 ${warning}`));
2327
2412
  }
2328
2413
  }
2329
2414
  let components;
@@ -2370,16 +2455,29 @@ async function applyCommand(targetPath, options) {
2370
2455
  }
2371
2456
  } catch (error) {
2372
2457
  const message = error instanceof Error ? error.message : String(error);
2373
- console.error(chalk4.red(`Error: ${message}`));
2458
+ console.error(chalk5.red(`Error: ${message}`));
2374
2459
  process.exit(1);
2375
2460
  }
2376
2461
  if (components.length === 0) {
2377
- console.error(
2378
- chalk4.yellow(
2379
- "No repeated className sets found. Try lowering --min-occurrences."
2380
- )
2381
- );
2382
- process.exit(1);
2462
+ if (!options.quiet) {
2463
+ console.error(
2464
+ chalk5.yellow(
2465
+ "No repeated className sets found. Try lowering --min-occurrences."
2466
+ )
2467
+ );
2468
+ process.exit(1);
2469
+ }
2470
+ return {
2471
+ filesModified: 0,
2472
+ replacementsTotal: 0,
2473
+ outputPath: path7.resolve(options.output),
2474
+ componentsGenerated: 0,
2475
+ components: [],
2476
+ replacements: [],
2477
+ skipped: [],
2478
+ prettierFormatted: [],
2479
+ savings: calculateSavings([])
2480
+ };
2383
2481
  }
2384
2482
  const outputPath = path7.resolve(options.output);
2385
2483
  let filesModified = 0;
@@ -2435,7 +2533,7 @@ async function applyCommand(targetPath, options) {
2435
2533
  prettierFormatted,
2436
2534
  savings
2437
2535
  };
2438
- if (options.format === "json") {
2536
+ if (options.format === "json" && !options.quiet) {
2439
2537
  printApplyJsonReport({
2440
2538
  command: "apply",
2441
2539
  dryRun: Boolean(options.dryRun),
@@ -2450,73 +2548,250 @@ async function applyCommand(targetPath, options) {
2450
2548
  });
2451
2549
  return result;
2452
2550
  }
2551
+ if (options.quiet) {
2552
+ return result;
2553
+ }
2453
2554
  console.log("");
2454
2555
  if (options.dryRun) {
2455
- console.log(chalk4.bold.yellow("\u{1F50D} Dry run \u2014 no files were modified"));
2556
+ console.log(chalk5.bold.yellow("\u{1F50D} Dry run \u2014 no files were modified"));
2456
2557
  } else {
2457
- console.log(chalk4.bold.green("\u2705 Classes applied successfully"));
2558
+ console.log(chalk5.bold.green("\u2705 Classes applied successfully"));
2458
2559
  }
2459
- console.log(chalk4.gray(` CSS output: `) + chalk4.white(outputPath));
2560
+ console.log(chalk5.gray(` CSS output: `) + chalk5.white(outputPath));
2460
2561
  console.log(
2461
- chalk4.gray(` Component classes: `) + chalk4.white(String(components.length))
2562
+ chalk5.gray(` Component classes: `) + chalk5.white(String(components.length))
2462
2563
  );
2463
2564
  console.log(
2464
- chalk4.gray(` Files modified: `) + chalk4.white(String(filesModified))
2565
+ chalk5.gray(` Files modified: `) + chalk5.white(String(filesModified))
2465
2566
  );
2466
2567
  console.log(
2467
- chalk4.gray(` Replacements: `) + chalk4.white(String(replacementsTotal))
2568
+ chalk5.gray(` Replacements: `) + chalk5.white(String(replacementsTotal))
2468
2569
  );
2469
2570
  if (prettierFormatted.length > 0) {
2470
2571
  console.log(
2471
- chalk4.gray(` Prettier formatted: `) + chalk4.white(String(prettierFormatted.length))
2572
+ chalk5.gray(` Prettier formatted: `) + chalk5.white(String(prettierFormatted.length))
2472
2573
  );
2473
2574
  }
2474
2575
  if (savings.replacementCount > 0) {
2475
2576
  console.log("");
2476
- console.log(chalk4.bold("Savings:"));
2577
+ console.log(chalk5.bold("Savings:"));
2477
2578
  console.log(
2478
- chalk4.gray(" Utility tokens before: ") + chalk4.white(String(savings.utilityTokensBefore))
2579
+ chalk5.gray(" Utility tokens before: ") + chalk5.white(String(savings.utilityTokensBefore))
2479
2580
  );
2480
2581
  console.log(
2481
- chalk4.gray(" Utility tokens after: ") + chalk4.white(String(savings.utilityTokensAfter))
2582
+ chalk5.gray(" Utility tokens after: ") + chalk5.white(String(savings.utilityTokensAfter))
2482
2583
  );
2483
2584
  console.log(
2484
- chalk4.gray(" Tokens saved: ") + chalk4.green(String(savings.tokensSaved))
2585
+ chalk5.gray(" Tokens saved: ") + chalk5.green(String(savings.tokensSaved))
2485
2586
  );
2486
2587
  console.log(
2487
- chalk4.gray(" Reduction: ") + chalk4.green(`${savings.percentReduction}%`)
2588
+ chalk5.gray(" Reduction: ") + chalk5.green(`${savings.percentReduction}%`)
2488
2589
  );
2489
2590
  }
2490
2591
  if (allReplacements.length > 0) {
2491
2592
  console.log("");
2492
- console.log(chalk4.bold("Replacements:"));
2593
+ console.log(chalk5.bold("Replacements:"));
2493
2594
  for (const item of allReplacements) {
2494
2595
  const line = item.line ? `:${item.line}` : "";
2495
- const partialTag = item.partial ? chalk4.dim(" (partial)") : "";
2596
+ const partialTag = item.partial ? chalk5.dim(" (partial)") : "";
2496
2597
  console.log(
2497
- chalk4.gray(` ${item.filePath}${line}`) + chalk4.white(` "${item.from}" `) + chalk4.cyan("\u2192") + chalk4.green(` "${item.to}"`) + partialTag
2598
+ chalk5.gray(` ${item.filePath}${line}`) + chalk5.white(` "${item.from}" `) + chalk5.cyan("\u2192") + chalk5.green(` "${item.to}"`) + partialTag
2498
2599
  );
2499
2600
  }
2500
2601
  }
2501
- if (allSkipped.length > 0) {
2602
+ printSkippedReport(allSkipped, { verbose: options.verboseSkipped });
2603
+ console.log("");
2604
+ if (!options.dryRun) {
2605
+ console.log(
2606
+ chalk5.cyan(
2607
+ `Import ${path7.basename(outputPath)} in your global CSS if you haven't already.`
2608
+ )
2609
+ );
2502
2610
  console.log("");
2503
- console.log(chalk4.bold.yellow(`Skipped (${allSkipped.length}):`));
2504
- for (const item of allSkipped) {
2505
- const line = item.line ? `:${item.line}` : "";
2506
- const classes = item.classes.join(" ");
2611
+ }
2612
+ return result;
2613
+ }
2614
+
2615
+ // src/reporters/checkReporter.ts
2616
+ import chalk6 from "chalk";
2617
+ function printCheckJsonReport(report) {
2618
+ console.log(JSON.stringify(report, null, 2));
2619
+ }
2620
+ function printCheckConsoleReport(analysisReport, options) {
2621
+ const { stats } = analysisReport;
2622
+ const topLimit = options.topLimit ?? 5;
2623
+ const extractableInTop = stats.topCombinations.filter(
2624
+ (combo) => combo.extractable
2625
+ ).length;
2626
+ console.log("");
2627
+ console.log(chalk6.bold.cyan("\u2713 Tailwind check"));
2628
+ console.log(chalk6.cyan("\u2501".repeat(41)));
2629
+ console.log(`Files scanned: ${chalk6.white(String(stats.filesScanned))}`);
2630
+ console.log(
2631
+ `Extractable patterns: ${chalk6.white(String(stats.extractablePatternCount))}` + chalk6.gray(" (exact duplicates ready for generate/apply)")
2632
+ );
2633
+ if (stats.analyzeMinOccurrences !== stats.extractableMinOccurrences) {
2634
+ console.log("");
2635
+ console.log(
2636
+ chalk6.yellow(
2637
+ `Note: analyze lists patterns with \u2265${stats.analyzeMinOccurrences} occurrences; generate/apply extract exact duplicates with \u2265${stats.extractableMinOccurrences}.`
2638
+ )
2639
+ );
2640
+ if (stats.extractablePatternCount > extractableInTop) {
2507
2641
  console.log(
2508
- chalk4.gray(` ${item.filePath}${line}`) + chalk4.yellow(` [${item.reason}]`) + chalk4.dim(` "${classes}"`)
2642
+ chalk6.yellow(
2643
+ ` ${stats.extractablePatternCount - extractableInTop} more extractable pattern(s) exist below the analyze threshold.`
2644
+ )
2509
2645
  );
2510
2646
  }
2511
2647
  }
2512
- console.log("");
2513
- if (!options.dryRun) {
2648
+ if (stats.extractablePatternCount === 0) {
2649
+ console.log("");
2514
2650
  console.log(
2515
- chalk4.cyan(
2516
- `Import ${path7.basename(outputPath)} in your global CSS if you haven't already.`
2517
- )
2651
+ chalk6.green("No extractable duplicates found. Nothing to refactor right now.")
2518
2652
  );
2519
2653
  console.log("");
2654
+ console.log(options.passed ? chalk6.green("Check passed.") : chalk6.red("Check failed."));
2655
+ console.log("");
2656
+ return;
2657
+ }
2658
+ const previewCount = Math.min(topLimit, stats.topCombinations.length);
2659
+ if (previewCount > 0) {
2660
+ console.log("");
2661
+ console.log(chalk6.bold("Top extractable patterns:"));
2662
+ for (const combo of stats.topCombinations.filter((item) => item.extractable).slice(0, topLimit)) {
2663
+ console.log(
2664
+ chalk6.white(` \u2022 "${normalizeClasses(combo.classes)}"`) + chalk6.gray(` \u2014 ${combo.occurrences}\xD7 \u2192 `) + chalk6.green(combo.suggestion)
2665
+ );
2666
+ }
2667
+ }
2668
+ if (options.preview) {
2669
+ const preview = options.preview;
2670
+ console.log("");
2671
+ console.log(chalk6.bold("Apply preview (dry-run):"));
2672
+ console.log(
2673
+ chalk6.gray(" CSS output: ") + chalk6.white(options.outputPath)
2674
+ );
2675
+ console.log(
2676
+ chalk6.gray(" Component classes: ") + chalk6.white(String(preview.componentsGenerated))
2677
+ );
2678
+ console.log(
2679
+ chalk6.gray(" Files to modify: ") + chalk6.white(String(preview.filesModified))
2680
+ );
2681
+ console.log(
2682
+ chalk6.gray(" Replacements: ") + chalk6.white(String(preview.replacementsTotal))
2683
+ );
2684
+ if (preview.savings.replacementCount > 0) {
2685
+ console.log(
2686
+ chalk6.gray(" Token reduction: ") + chalk6.green(`${preview.savings.percentReduction}%`)
2687
+ );
2688
+ }
2689
+ printSkippedReport(preview.skipped, {
2690
+ verbose: options.verboseSkipped
2691
+ });
2692
+ }
2693
+ console.log("");
2694
+ if (options.passed) {
2695
+ console.log(chalk6.green("Check passed."));
2696
+ } else {
2697
+ console.log(chalk6.red("Check failed."));
2698
+ }
2699
+ console.log(chalk6.cyan("Next steps:"));
2700
+ console.log(chalk6.white(" npx tailwind-unwind generate"));
2701
+ console.log(chalk6.white(" npx tailwind-unwind apply --dry-run"));
2702
+ console.log("");
2703
+ }
2704
+
2705
+ // src/commands/check.ts
2706
+ import chalk7 from "chalk";
2707
+ async function checkCommand(targetPath, options) {
2708
+ let scanResult;
2709
+ try {
2710
+ scanResult = await scanProject({
2711
+ targetPath,
2712
+ minOccurrences: options.minOccurrences,
2713
+ minSize: options.minSize,
2714
+ maxSize: options.maxSize,
2715
+ topLimit: options.top,
2716
+ dedupeSubsets: options.dedupeSubsets,
2717
+ include: options.include,
2718
+ exclude: options.exclude,
2719
+ changed: options.changed,
2720
+ extractableMinOccurrences: options.extractableMinOccurrences
2721
+ });
2722
+ } catch (error) {
2723
+ const message = error instanceof Error ? error.message : String(error);
2724
+ console.error(chalk7.red(`Error: ${message}`));
2725
+ process.exit(1);
2726
+ }
2727
+ if (options.format !== "json") {
2728
+ for (const warning of scanResult.warnings) {
2729
+ console.warn(chalk7.yellow(`\u26A0 ${warning}`));
2730
+ }
2731
+ }
2732
+ const extractablePatternCount = scanResult.report.stats.extractablePatternCount;
2733
+ const failThreshold = options.failOnExtractable;
2734
+ const passed = failThreshold === void 0 ? true : extractablePatternCount <= failThreshold;
2735
+ let preview = null;
2736
+ if (extractablePatternCount > 0) {
2737
+ preview = await applyCommand(targetPath, {
2738
+ output: options.output,
2739
+ minOccurrences: options.extractableMinOccurrences ?? GENERATE_DEFAULTS.minOccurrences,
2740
+ minSize: options.minSize,
2741
+ maxSize: options.maxSize,
2742
+ top: options.top,
2743
+ prefix: options.prefix,
2744
+ include: options.include,
2745
+ exclude: options.exclude,
2746
+ changed: options.changed,
2747
+ configPath: options.configPath,
2748
+ names: options.names,
2749
+ extractableOnly: true,
2750
+ dryRun: true,
2751
+ quiet: true,
2752
+ verboseSkipped: options.verboseSkipped
2753
+ });
2754
+ }
2755
+ const result = {
2756
+ passed,
2757
+ extractablePatternCount,
2758
+ report: scanResult.report,
2759
+ preview
2760
+ };
2761
+ if (options.format === "json") {
2762
+ const jsonReport = {
2763
+ command: "check",
2764
+ passed,
2765
+ outputPath: options.output,
2766
+ extractablePatternCount,
2767
+ analyzeMinOccurrences: scanResult.report.stats.analyzeMinOccurrences,
2768
+ extractableMinOccurrences: scanResult.report.stats.extractableMinOccurrences,
2769
+ report: scanResult.report,
2770
+ preview: preview ? {
2771
+ componentsGenerated: preview.componentsGenerated,
2772
+ filesModified: preview.filesModified,
2773
+ replacementsTotal: preview.replacementsTotal,
2774
+ skippedTotal: preview.skipped.length,
2775
+ savings: preview.savings
2776
+ } : null
2777
+ };
2778
+ printCheckJsonReport(jsonReport);
2779
+ } else {
2780
+ printCheckConsoleReport(scanResult.report, {
2781
+ outputPath: options.output,
2782
+ topLimit: options.top,
2783
+ preview,
2784
+ verboseSkipped: options.verboseSkipped,
2785
+ passed
2786
+ });
2787
+ }
2788
+ if (!passed) {
2789
+ console.error(
2790
+ chalk7.red(
2791
+ `Found ${extractablePatternCount} extractable pattern(s); limit is ${failThreshold}.`
2792
+ )
2793
+ );
2794
+ process.exit(1);
2520
2795
  }
2521
2796
  return result;
2522
2797
  }
@@ -2524,7 +2799,7 @@ async function applyCommand(targetPath, options) {
2524
2799
  // src/commands/generate.ts
2525
2800
  import fs7 from "fs/promises";
2526
2801
  import path8 from "path";
2527
- import chalk5 from "chalk";
2802
+ import chalk8 from "chalk";
2528
2803
  async function generateCommand(targetPath, options) {
2529
2804
  let scanResult = null;
2530
2805
  let components;
@@ -2576,13 +2851,13 @@ async function generateCommand(targetPath, options) {
2576
2851
  }
2577
2852
  } catch (error) {
2578
2853
  const message = error instanceof Error ? error.message : String(error);
2579
- console.error(chalk5.red(`Error: ${message}`));
2854
+ console.error(chalk8.red(`Error: ${message}`));
2580
2855
  process.exit(1);
2581
2856
  }
2582
2857
  if (scanResult) {
2583
2858
  for (const warning of scanResult.warnings) {
2584
2859
  if (options.format !== "json") {
2585
- console.warn(chalk5.yellow(`\u26A0 ${warning}`));
2860
+ console.warn(chalk8.yellow(`\u26A0 ${warning}`));
2586
2861
  }
2587
2862
  }
2588
2863
  }
@@ -2606,28 +2881,28 @@ async function generateCommand(targetPath, options) {
2606
2881
  return result;
2607
2882
  }
2608
2883
  console.log("");
2609
- console.log(chalk5.bold.green("\u2705 CSS generated successfully"));
2610
- console.log(chalk5.gray(` Output: `) + chalk5.white(outputPath));
2884
+ console.log(chalk8.bold.green("\u2705 CSS generated successfully"));
2885
+ console.log(chalk8.gray(` Output: `) + chalk8.white(outputPath));
2611
2886
  console.log(
2612
- chalk5.gray(` Components: `) + chalk5.white(String(components.length))
2887
+ chalk8.gray(` Components: `) + chalk8.white(String(components.length))
2613
2888
  );
2614
2889
  if (components.length > 0) {
2615
2890
  console.log("");
2616
- console.log(chalk5.bold("Generated classes:"));
2891
+ console.log(chalk8.bold("Generated classes:"));
2617
2892
  for (const component of components) {
2618
2893
  console.log(
2619
- chalk5.green(` .${component.className}`) + chalk5.gray(` \u2014 ${component.occurrences} occurrences, `) + chalk5.dim(component.classes.join(" "))
2894
+ chalk8.green(` .${component.className}`) + chalk8.gray(` \u2014 ${component.occurrences} occurrences, `) + chalk8.dim(component.classes.join(" "))
2620
2895
  );
2621
2896
  }
2622
2897
  console.log("");
2623
2898
  console.log(
2624
- chalk5.cyan(
2625
- "Run apply to replace className strings: npx tailwind-unwind apply <path> --output styles.css"
2899
+ chalk8.cyan(
2900
+ "Run apply to replace className strings: npx tailwind-unwind apply"
2626
2901
  )
2627
2902
  );
2628
2903
  } else {
2629
2904
  console.log(
2630
- chalk5.yellow(
2905
+ chalk8.yellow(
2631
2906
  "\nNo repeated className sets matched the filters. Try lowering --min-occurrences."
2632
2907
  )
2633
2908
  );
@@ -2671,7 +2946,11 @@ export {
2671
2946
  printConsoleReport,
2672
2947
  printJsonReport,
2673
2948
  analyzeCommand,
2674
- calculateSavings,
2949
+ DEFAULT_TARGET_PATH,
2950
+ ANALYZE_DEFAULTS,
2951
+ GENERATE_DEFAULTS,
2952
+ resolveTargetPath,
2953
+ resolveOutputPath,
2675
2954
  formatSource,
2676
2955
  formatModifiedFiles,
2677
2956
  replaceClassNamesInSource,
@@ -2683,9 +2962,15 @@ export {
2683
2962
  buildComponents,
2684
2963
  buildComponentsFromCombinations,
2685
2964
  loadExtractableCombinations,
2965
+ calculateSavings,
2686
2966
  printGenerateJsonReport,
2687
2967
  printApplyJsonReport,
2968
+ groupSkippedByReason,
2969
+ printSkippedReport,
2688
2970
  applyCommand,
2971
+ printCheckJsonReport,
2972
+ printCheckConsoleReport,
2973
+ checkCommand,
2689
2974
  generateCommand
2690
2975
  };
2691
- //# sourceMappingURL=chunk-UXXIEFP4.js.map
2976
+ //# sourceMappingURL=chunk-RMTZCCPS.js.map