tailwindcss-patch 8.7.2 → 8.7.3

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,3 +1,7 @@
1
+ import {
2
+ __dirname
3
+ } from "./chunk-JHEI2MLC.mjs";
4
+
1
5
  // src/logger.ts
2
6
  import { createConsola } from "consola";
3
7
  var logger = createConsola();
@@ -16,7 +20,7 @@ import path from "pathe";
16
20
  // package.json
17
21
  var package_default = {
18
22
  name: "tailwindcss-patch",
19
- version: "8.7.2",
23
+ version: "8.7.3",
20
24
  description: "patch tailwindcss for exposing context and extract classes",
21
25
  author: "ice breaker <1324318532@qq.com>",
22
26
  license: "MIT",
@@ -37,17 +41,17 @@ var package_default = {
37
41
  ],
38
42
  exports: {
39
43
  ".": {
40
- types: "./src/index.ts",
41
- import: "./src/index.ts",
42
- require: "./src/index.ts"
44
+ types: "./dist/index.d.ts",
45
+ import: "./dist/index.mjs",
46
+ require: "./dist/index.js"
43
47
  },
44
48
  "./migration-report.schema.json": "./schema/migration-report.schema.json",
45
49
  "./restore-result.schema.json": "./schema/restore-result.schema.json",
46
50
  "./validate-result.schema.json": "./schema/validate-result.schema.json"
47
51
  },
48
- main: "./src/index.ts",
49
- module: "./src/index.ts",
50
- types: "./src/index.ts",
52
+ main: "./dist/index.js",
53
+ module: "./dist/index.mjs",
54
+ types: "./dist/index.d.ts",
51
55
  bin: {
52
56
  "tw-patch": "dev/bin.ts",
53
57
  "tailwindcss-patch": "dev/bin.ts"
@@ -1507,230 +1511,10 @@ ${Date.now()}`, { flag: "wx" });
1507
1511
  }
1508
1512
  };
1509
1513
 
1510
- // src/extraction/candidate-extractor.ts
1511
- import { promises as fs3 } from "fs";
1514
+ // src/options/normalize.ts
1512
1515
  import process3 from "process";
1516
+ import fs3 from "fs-extra";
1513
1517
  import path2 from "pathe";
1514
- async function importNode() {
1515
- return import("@tailwindcss/node");
1516
- }
1517
- async function importOxide() {
1518
- return import("@tailwindcss/oxide");
1519
- }
1520
- async function loadDesignSystem(css, bases) {
1521
- const uniqueBases = Array.from(new Set(bases.filter(Boolean)));
1522
- if (uniqueBases.length === 0) {
1523
- throw new Error("No base directories provided for Tailwind CSS design system.");
1524
- }
1525
- const { __unstable__loadDesignSystem } = await importNode();
1526
- let lastError;
1527
- for (const base of uniqueBases) {
1528
- try {
1529
- return await __unstable__loadDesignSystem(css, { base });
1530
- } catch (error) {
1531
- lastError = error;
1532
- }
1533
- }
1534
- if (lastError instanceof Error) {
1535
- throw lastError;
1536
- }
1537
- throw new Error("Failed to load Tailwind CSS design system.");
1538
- }
1539
- async function extractRawCandidatesWithPositions(content, extension = "html") {
1540
- const { Scanner } = await importOxide();
1541
- const scanner = new Scanner({});
1542
- const result = scanner.getCandidatesWithPositions({ content, extension });
1543
- return result.map(({ candidate, position }) => ({
1544
- rawCandidate: candidate,
1545
- start: position,
1546
- end: position + candidate.length
1547
- }));
1548
- }
1549
- async function extractRawCandidates(sources) {
1550
- const { Scanner } = await importOxide();
1551
- const scanner = new Scanner(sources === void 0 ? {} : { sources });
1552
- return scanner.scan();
1553
- }
1554
- async function extractValidCandidates(options) {
1555
- const providedOptions = options ?? {};
1556
- const defaultCwd = providedOptions.cwd ?? process3.cwd();
1557
- const base = providedOptions.base ?? defaultCwd;
1558
- const baseFallbacks = providedOptions.baseFallbacks ?? [];
1559
- const css = providedOptions.css ?? '@import "tailwindcss";';
1560
- const sources = (providedOptions.sources ?? [
1561
- {
1562
- base: defaultCwd,
1563
- pattern: "**/*",
1564
- negated: false
1565
- }
1566
- ]).map((source) => ({
1567
- base: source.base ?? defaultCwd,
1568
- pattern: source.pattern,
1569
- negated: source.negated
1570
- }));
1571
- const designSystem = await loadDesignSystem(css, [base, ...baseFallbacks]);
1572
- const candidates = await extractRawCandidates(sources);
1573
- const parsedCandidates = candidates.filter(
1574
- (rawCandidate) => designSystem.parseCandidate(rawCandidate).length > 0
1575
- );
1576
- if (parsedCandidates.length === 0) {
1577
- return parsedCandidates;
1578
- }
1579
- const cssByCandidate = designSystem.candidatesToCss(parsedCandidates);
1580
- const validCandidates = [];
1581
- for (let index = 0; index < parsedCandidates.length; index++) {
1582
- const candidate = parsedCandidates[index];
1583
- if (candidate === void 0) {
1584
- continue;
1585
- }
1586
- const css2 = cssByCandidate[index];
1587
- if (typeof css2 === "string" && css2.trim().length > 0) {
1588
- validCandidates.push(candidate);
1589
- }
1590
- }
1591
- return validCandidates;
1592
- }
1593
- function normalizeSources(sources, cwd) {
1594
- const baseSources = sources?.length ? sources : [
1595
- {
1596
- base: cwd,
1597
- pattern: "**/*",
1598
- negated: false
1599
- }
1600
- ];
1601
- return baseSources.map((source) => ({
1602
- base: source.base ?? cwd,
1603
- pattern: source.pattern,
1604
- negated: source.negated
1605
- }));
1606
- }
1607
- function buildLineOffsets(content) {
1608
- const offsets = [0];
1609
- for (let i = 0; i < content.length; i++) {
1610
- if (content[i] === "\n") {
1611
- offsets.push(i + 1);
1612
- }
1613
- }
1614
- if (offsets[offsets.length - 1] !== content.length) {
1615
- offsets.push(content.length);
1616
- }
1617
- return offsets;
1618
- }
1619
- function resolveLineMeta(content, offsets, index) {
1620
- let low = 0;
1621
- let high = offsets.length - 1;
1622
- while (low <= high) {
1623
- const mid = Math.floor((low + high) / 2);
1624
- const start = offsets[mid];
1625
- if (start === void 0) {
1626
- break;
1627
- }
1628
- const nextStart = offsets[mid + 1] ?? content.length;
1629
- if (index < start) {
1630
- high = mid - 1;
1631
- continue;
1632
- }
1633
- if (index >= nextStart) {
1634
- low = mid + 1;
1635
- continue;
1636
- }
1637
- const line = mid + 1;
1638
- const column = index - start + 1;
1639
- const lineEnd = content.indexOf("\n", start);
1640
- const lineText = content.slice(start, lineEnd === -1 ? content.length : lineEnd);
1641
- return { line, column, lineText };
1642
- }
1643
- const lastStart = offsets[offsets.length - 2] ?? 0;
1644
- return {
1645
- line: offsets.length - 1,
1646
- column: index - lastStart + 1,
1647
- lineText: content.slice(lastStart)
1648
- };
1649
- }
1650
- function toExtension(filename) {
1651
- const ext = path2.extname(filename).replace(/^\./, "");
1652
- return ext || "txt";
1653
- }
1654
- function toRelativeFile(cwd, filename) {
1655
- const relative = path2.relative(cwd, filename);
1656
- return relative === "" ? path2.basename(filename) : relative;
1657
- }
1658
- async function extractProjectCandidatesWithPositions(options) {
1659
- const cwd = options?.cwd ? path2.resolve(options.cwd) : process3.cwd();
1660
- const normalizedSources = normalizeSources(options?.sources, cwd);
1661
- const { Scanner } = await importOxide();
1662
- const scanner = new Scanner({
1663
- sources: normalizedSources
1664
- });
1665
- const files = scanner.files ?? [];
1666
- const entries = [];
1667
- const skipped = [];
1668
- for (const file of files) {
1669
- let content;
1670
- try {
1671
- content = await fs3.readFile(file, "utf8");
1672
- } catch (error) {
1673
- skipped.push({
1674
- file,
1675
- reason: error instanceof Error ? error.message : "Unknown error"
1676
- });
1677
- continue;
1678
- }
1679
- const extension = toExtension(file);
1680
- const matches = scanner.getCandidatesWithPositions({
1681
- file,
1682
- content,
1683
- extension
1684
- });
1685
- if (!matches.length) {
1686
- continue;
1687
- }
1688
- const offsets = buildLineOffsets(content);
1689
- const relativeFile = toRelativeFile(cwd, file);
1690
- for (const match of matches) {
1691
- const info = resolveLineMeta(content, offsets, match.position);
1692
- entries.push({
1693
- rawCandidate: match.candidate,
1694
- file,
1695
- relativeFile,
1696
- extension,
1697
- start: match.position,
1698
- end: match.position + match.candidate.length,
1699
- length: match.candidate.length,
1700
- line: info.line,
1701
- column: info.column,
1702
- lineText: info.lineText
1703
- });
1704
- }
1705
- }
1706
- return {
1707
- entries,
1708
- filesScanned: files.length,
1709
- skippedFiles: skipped,
1710
- sources: normalizedSources
1711
- };
1712
- }
1713
- function groupTokensByFile(report, options) {
1714
- const key = options?.key ?? "relative";
1715
- const stripAbsolute = options?.stripAbsolutePaths ?? key !== "absolute";
1716
- return report.entries.reduce((acc, entry) => {
1717
- const bucketKey = key === "absolute" ? entry.file : entry.relativeFile;
1718
- if (!acc[bucketKey]) {
1719
- acc[bucketKey] = [];
1720
- }
1721
- const value = stripAbsolute ? {
1722
- ...entry,
1723
- file: entry.relativeFile
1724
- } : entry;
1725
- acc[bucketKey].push(value);
1726
- return acc;
1727
- }, {});
1728
- }
1729
-
1730
- // src/options/normalize.ts
1731
- import process4 from "process";
1732
- import fs4 from "fs-extra";
1733
- import path3 from "pathe";
1734
1518
  var hasWarnedDeprecatedOptions = false;
1735
1519
  var deprecatedOptionMapping = {
1736
1520
  cwd: "projectRoot",
@@ -1740,11 +1524,11 @@ var deprecatedOptionMapping = {
1740
1524
  output: "extract"
1741
1525
  };
1742
1526
  function resolveRealpathSafe(value) {
1743
- const resolved = path3.resolve(value);
1527
+ const resolved = path2.resolve(value);
1744
1528
  try {
1745
- return path3.normalize(fs4.realpathSync(resolved));
1529
+ return path2.normalize(fs3.realpathSync(resolved));
1746
1530
  } catch {
1747
- return path3.normalize(resolved);
1531
+ return path2.normalize(resolved);
1748
1532
  }
1749
1533
  }
1750
1534
  function toPrettyValue(value) {
@@ -1765,7 +1549,7 @@ function normalizeCacheDriver(driver) {
1765
1549
  function normalizeCacheOptions(cache, projectRoot) {
1766
1550
  let enabled = false;
1767
1551
  let cwd = resolveRealpathSafe(projectRoot);
1768
- let dir = path3.resolve(cwd, "node_modules/.cache", pkgName);
1552
+ let dir = path2.resolve(cwd, "node_modules/.cache", pkgName);
1769
1553
  let file = "class-cache.json";
1770
1554
  let strategy = "merge";
1771
1555
  let driver = "file";
@@ -1774,12 +1558,12 @@ function normalizeCacheOptions(cache, projectRoot) {
1774
1558
  } else if (typeof cache === "object" && cache) {
1775
1559
  enabled = cache.enabled ?? true;
1776
1560
  cwd = cache.cwd ? resolveRealpathSafe(cache.cwd) : cwd;
1777
- dir = cache.dir ? path3.resolve(cache.dir) : path3.resolve(cwd, "node_modules/.cache", pkgName);
1561
+ dir = cache.dir ? path2.resolve(cache.dir) : path2.resolve(cwd, "node_modules/.cache", pkgName);
1778
1562
  file = cache.file ?? file;
1779
1563
  strategy = cache.strategy ?? strategy;
1780
1564
  driver = normalizeCacheDriver(cache.driver);
1781
1565
  }
1782
- const filename = path3.resolve(dir, file);
1566
+ const filename = path2.resolve(dir, file);
1783
1567
  return {
1784
1568
  enabled,
1785
1569
  cwd,
@@ -1842,9 +1626,9 @@ function normalizeExtendLengthUnitsOptions(extend) {
1842
1626
  };
1843
1627
  }
1844
1628
  function normalizeTailwindV4Options(v4, fallbackBase) {
1845
- const configuredBase = v4?.base ? path3.resolve(v4.base) : void 0;
1629
+ const configuredBase = v4?.base ? path2.resolve(v4.base) : void 0;
1846
1630
  const base = configuredBase ?? fallbackBase;
1847
- const cssEntries = Array.isArray(v4?.cssEntries) ? v4.cssEntries.filter((entry) => Boolean(entry)).map((entry) => path3.resolve(entry)) : [];
1631
+ const cssEntries = Array.isArray(v4?.cssEntries) ? v4.cssEntries.filter((entry) => Boolean(entry)).map((entry) => path2.resolve(entry)) : [];
1848
1632
  const userSources = v4?.sources;
1849
1633
  const hasUserDefinedSources = Boolean(userSources?.length);
1850
1634
  const sources = hasUserDefinedSources ? userSources : [
@@ -1936,7 +1720,7 @@ function warnDeprecatedOptionsIfNeeded(options) {
1936
1720
  function normalizeOptions(options = {}) {
1937
1721
  warnDeprecatedOptionsIfNeeded(options);
1938
1722
  const resolved = resolveOptionSlices(options);
1939
- const projectRoot = resolveRealpathSafe(resolved.projectRoot ? path3.resolve(resolved.projectRoot) : process4.cwd());
1723
+ const projectRoot = resolveRealpathSafe(resolved.projectRoot ? path2.resolve(resolved.projectRoot) : process3.cwd());
1940
1724
  const overwrite = resolved.overwrite ?? true;
1941
1725
  const output = normalizeOutputOptions(resolved.extract);
1942
1726
  const cache = normalizeCacheOptions(options.cache, projectRoot);
@@ -1966,31 +1750,629 @@ function normalizeOptions(options = {}) {
1966
1750
  };
1967
1751
  }
1968
1752
 
1969
- // src/patching/status.ts
1970
- import * as t4 from "@babel/types";
1971
- import fs6 from "fs-extra";
1972
- import path5 from "pathe";
1973
-
1974
- // src/babel/index.ts
1975
- import _babelGenerate from "@babel/generator";
1976
- import _babelTraverse from "@babel/traverse";
1977
- import { parse, parseExpression } from "@babel/parser";
1978
- function _interopDefaultCompat(e) {
1979
- return e && typeof e === "object" && "default" in e ? e.default : e;
1980
- }
1981
- var generate = _interopDefaultCompat(_babelGenerate);
1982
- var traverse = _interopDefaultCompat(_babelTraverse);
1983
-
1984
- // src/patching/operations/export-context/postcss-v2.ts
1985
- import * as t from "@babel/types";
1986
- var IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
1987
- function toIdentifierName(property) {
1988
- if (!property) {
1989
- return "contextRef";
1753
+ // src/options/legacy.ts
1754
+ function normalizeLegacyFeatures(patch) {
1755
+ const apply = patch?.applyPatches;
1756
+ const extend = apply?.extendLengthUnits;
1757
+ let extendOption = false;
1758
+ if (extend && typeof extend === "object") {
1759
+ extendOption = {
1760
+ ...extend,
1761
+ enabled: true
1762
+ };
1763
+ } else if (extend === true) {
1764
+ extendOption = {
1765
+ enabled: true,
1766
+ units: ["rpx"],
1767
+ ...patch?.overwrite === void 0 ? {} : { overwrite: patch.overwrite }
1768
+ };
1990
1769
  }
1991
- const sanitized = property.replace(/[^\w$]/gu, "_");
1992
- if (/^\d/.test(sanitized)) {
1993
- return `_${sanitized}`;
1770
+ return {
1771
+ exposeContext: apply?.exportContext ?? true,
1772
+ extendLengthUnits: extendOption
1773
+ };
1774
+ }
1775
+ function fromLegacyOptions(options) {
1776
+ if (!options) {
1777
+ return {};
1778
+ }
1779
+ const patch = options.patch;
1780
+ const features = normalizeLegacyFeatures(patch);
1781
+ const output = patch?.output;
1782
+ const tailwindConfig = patch?.tailwindcss;
1783
+ const tailwindVersion = tailwindConfig?.version;
1784
+ const tailwindV2 = tailwindConfig?.v2;
1785
+ const tailwindV3 = tailwindConfig?.v3;
1786
+ const tailwindV4 = tailwindConfig?.v4;
1787
+ const tailwindConfigPath = tailwindV3?.config ?? tailwindV2?.config;
1788
+ const tailwindCwd = tailwindV3?.cwd ?? tailwindV2?.cwd ?? patch?.cwd;
1789
+ const normalizedExtract = output ? {
1790
+ ...output.filename === void 0 ? {} : { file: output.filename },
1791
+ pretty: output.loose ? 2 : false,
1792
+ ...output.removeUniversalSelector === void 0 ? {} : { removeUniversalSelector: output.removeUniversalSelector }
1793
+ } : void 0;
1794
+ const normalizedTailwindcss = {
1795
+ ...patch?.packageName === void 0 ? {} : { packageName: patch.packageName },
1796
+ ...tailwindVersion === void 0 ? {} : { version: tailwindVersion },
1797
+ ...patch?.resolve === void 0 ? {} : { resolve: patch.resolve },
1798
+ ...tailwindConfigPath === void 0 ? {} : { config: tailwindConfigPath },
1799
+ ...tailwindCwd === void 0 ? {} : { cwd: tailwindCwd },
1800
+ ...tailwindV2 === void 0 ? {} : { v2: tailwindV2 },
1801
+ ...tailwindV3 === void 0 ? {} : { v3: tailwindV3 },
1802
+ ...tailwindV4 === void 0 ? {} : { v4: tailwindV4 }
1803
+ };
1804
+ const normalizedCache = typeof options.cache === "boolean" ? options.cache : options.cache ? {
1805
+ ...options.cache,
1806
+ enabled: options.cache.enabled ?? true
1807
+ } : void 0;
1808
+ const normalizedApply = {
1809
+ ...patch?.overwrite === void 0 ? {} : { overwrite: patch.overwrite },
1810
+ exposeContext: features.exposeContext,
1811
+ extendLengthUnits: features.extendLengthUnits
1812
+ };
1813
+ return {
1814
+ ...patch?.cwd === void 0 ? {} : { projectRoot: patch.cwd },
1815
+ ...patch?.filter === void 0 ? {} : { filter: patch.filter },
1816
+ ...normalizedCache === void 0 ? {} : { cache: normalizedCache },
1817
+ ...normalizedExtract === void 0 ? {} : { extract: normalizedExtract },
1818
+ ...Object.keys(normalizedTailwindcss).length === 0 ? {} : { tailwindcss: normalizedTailwindcss },
1819
+ apply: normalizedApply
1820
+ };
1821
+ }
1822
+ function fromUnifiedConfig(registry) {
1823
+ if (!registry) {
1824
+ return {};
1825
+ }
1826
+ const tailwind = registry.tailwindcss ?? registry.tailwind;
1827
+ const modernExtract = registry.extract;
1828
+ const legacyOutput = registry.output;
1829
+ const pretty = (() => {
1830
+ const value = modernExtract?.pretty ?? legacyOutput?.pretty;
1831
+ if (value === void 0) {
1832
+ return void 0;
1833
+ }
1834
+ if (typeof value === "boolean") {
1835
+ return value ? 2 : false;
1836
+ }
1837
+ return value;
1838
+ })();
1839
+ const removeUniversalSelector = modernExtract?.removeUniversalSelector ?? legacyOutput?.stripUniversalSelector;
1840
+ const outputFile = modernExtract?.file ?? legacyOutput?.file;
1841
+ const normalizedExtract = modernExtract || legacyOutput ? {
1842
+ ...modernExtract?.write === void 0 ? {} : { write: modernExtract.write },
1843
+ ...outputFile === void 0 ? {} : { file: outputFile },
1844
+ ...pretty === void 0 ? {} : { pretty },
1845
+ ...removeUniversalSelector === void 0 ? {} : { removeUniversalSelector },
1846
+ ...modernExtract?.format === void 0 ? {} : { format: modernExtract.format }
1847
+ } : void 0;
1848
+ const normalizedTailwindcss = tailwind ? {
1849
+ ...tailwind.version === void 0 ? {} : { version: tailwind.version },
1850
+ ...tailwind.packageName === void 0 ? tailwind.package === void 0 ? {} : { packageName: tailwind.package } : { packageName: tailwind.packageName },
1851
+ ...tailwind.resolve === void 0 ? {} : { resolve: tailwind.resolve },
1852
+ ...tailwind.config === void 0 ? {} : { config: tailwind.config },
1853
+ ...tailwind.cwd === void 0 ? {} : { cwd: tailwind.cwd },
1854
+ ...tailwind.v2 === void 0 ? tailwind.legacy === void 0 ? {} : { v2: tailwind.legacy } : { v2: tailwind.v2 },
1855
+ ...tailwind.v3 === void 0 ? tailwind.classic === void 0 ? {} : { v3: tailwind.classic } : { v3: tailwind.v3 },
1856
+ ...tailwind.v4 === void 0 ? tailwind.next === void 0 ? {} : { v4: tailwind.next } : { v4: tailwind.v4 }
1857
+ } : void 0;
1858
+ const normalizedApply = registry.apply ? {
1859
+ ...registry.apply.overwrite === void 0 ? {} : { overwrite: registry.apply.overwrite },
1860
+ ...registry.apply.exposeContext === void 0 ? {} : { exposeContext: registry.apply.exposeContext },
1861
+ ...registry.apply.extendLengthUnits === void 0 ? {} : { extendLengthUnits: registry.apply.extendLengthUnits }
1862
+ } : void 0;
1863
+ return {
1864
+ ...registry.projectRoot === void 0 ? {} : { projectRoot: registry.projectRoot },
1865
+ ...normalizedApply === void 0 ? {} : { apply: normalizedApply },
1866
+ ...registry.cache === void 0 ? {} : { cache: registry.cache },
1867
+ ...registry.filter === void 0 ? {} : { filter: registry.filter },
1868
+ ...normalizedExtract === void 0 ? {} : { extract: normalizedExtract },
1869
+ ...normalizedTailwindcss === void 0 ? {} : { tailwindcss: normalizedTailwindcss }
1870
+ };
1871
+ }
1872
+
1873
+ // src/config/workspace.ts
1874
+ import { pathToFileURL } from "url";
1875
+ import path3 from "pathe";
1876
+ var configModulePromise;
1877
+ var defuPromise;
1878
+ function isNodeError(error) {
1879
+ return !!error && typeof error === "object" && ("code" in error || "message" in error);
1880
+ }
1881
+ function isMissingConfigModuleError(error) {
1882
+ if (!isNodeError(error) || error.code !== "MODULE_NOT_FOUND") {
1883
+ return false;
1884
+ }
1885
+ const message = error.message ?? "";
1886
+ return message.includes("@tailwindcss-mangle/config");
1887
+ }
1888
+ function isMissingSharedModuleError(error) {
1889
+ if (!isNodeError(error) || error.code !== "MODULE_NOT_FOUND") {
1890
+ return false;
1891
+ }
1892
+ const message = error.message ?? "";
1893
+ return message.includes("@tailwindcss-mangle/shared");
1894
+ }
1895
+ async function loadWorkspaceConfigModule() {
1896
+ if (!configModulePromise) {
1897
+ configModulePromise = import("@tailwindcss-mangle/config").catch(async (error) => {
1898
+ if (!isMissingConfigModuleError(error)) {
1899
+ throw error;
1900
+ }
1901
+ const fallback = path3.resolve(__dirname, "../../../config/src/index.ts");
1902
+ return import(pathToFileURL(fallback).href);
1903
+ });
1904
+ }
1905
+ return configModulePromise;
1906
+ }
1907
+ async function loadWorkspaceDefu() {
1908
+ if (!defuPromise) {
1909
+ defuPromise = import("./dist-EMUBVNNO.mjs").then((mod) => mod.defu).catch(async (error) => {
1910
+ if (!isMissingSharedModuleError(error)) {
1911
+ throw error;
1912
+ }
1913
+ const fallback = path3.resolve(__dirname, "../../../shared/src/utils.ts");
1914
+ const mod = await import(pathToFileURL(fallback).href);
1915
+ return mod.defu;
1916
+ });
1917
+ }
1918
+ return defuPromise;
1919
+ }
1920
+ async function loadPatchOptionsForWorkspace(cwd, overrides) {
1921
+ const merge = await loadWorkspaceDefu();
1922
+ const configModule = await loadWorkspaceConfigModule();
1923
+ const { config } = await configModule.getConfig(cwd);
1924
+ const legacyConfig = config;
1925
+ const base = config?.registry ? fromUnifiedConfig(config.registry) : legacyConfig?.patch ? fromLegacyOptions({ patch: legacyConfig.patch }) : {};
1926
+ const merged = merge(overrides ?? {}, base);
1927
+ return merged;
1928
+ }
1929
+
1930
+ // src/extraction/candidate-extractor.ts
1931
+ import { promises as fs4 } from "fs";
1932
+ import process4 from "process";
1933
+ import path4 from "pathe";
1934
+ async function importNode() {
1935
+ return import("@tailwindcss/node");
1936
+ }
1937
+ async function importOxide() {
1938
+ return import("@tailwindcss/oxide");
1939
+ }
1940
+ async function loadDesignSystem(css, bases) {
1941
+ const uniqueBases = Array.from(new Set(bases.filter(Boolean)));
1942
+ if (uniqueBases.length === 0) {
1943
+ throw new Error("No base directories provided for Tailwind CSS design system.");
1944
+ }
1945
+ const { __unstable__loadDesignSystem } = await importNode();
1946
+ let lastError;
1947
+ for (const base of uniqueBases) {
1948
+ try {
1949
+ return await __unstable__loadDesignSystem(css, { base });
1950
+ } catch (error) {
1951
+ lastError = error;
1952
+ }
1953
+ }
1954
+ if (lastError instanceof Error) {
1955
+ throw lastError;
1956
+ }
1957
+ throw new Error("Failed to load Tailwind CSS design system.");
1958
+ }
1959
+ async function extractRawCandidatesWithPositions(content, extension = "html") {
1960
+ const { Scanner } = await importOxide();
1961
+ const scanner = new Scanner({});
1962
+ const result = scanner.getCandidatesWithPositions({ content, extension });
1963
+ return result.map(({ candidate, position }) => ({
1964
+ rawCandidate: candidate,
1965
+ start: position,
1966
+ end: position + candidate.length
1967
+ }));
1968
+ }
1969
+ async function extractRawCandidates(sources) {
1970
+ const { Scanner } = await importOxide();
1971
+ const scanner = new Scanner(sources === void 0 ? {} : { sources });
1972
+ return scanner.scan();
1973
+ }
1974
+ async function extractValidCandidates(options) {
1975
+ const providedOptions = options ?? {};
1976
+ const defaultCwd = providedOptions.cwd ?? process4.cwd();
1977
+ const base = providedOptions.base ?? defaultCwd;
1978
+ const baseFallbacks = providedOptions.baseFallbacks ?? [];
1979
+ const css = providedOptions.css ?? '@import "tailwindcss";';
1980
+ const sources = (providedOptions.sources ?? [
1981
+ {
1982
+ base: defaultCwd,
1983
+ pattern: "**/*",
1984
+ negated: false
1985
+ }
1986
+ ]).map((source) => ({
1987
+ base: source.base ?? defaultCwd,
1988
+ pattern: source.pattern,
1989
+ negated: source.negated
1990
+ }));
1991
+ const designSystem = await loadDesignSystem(css, [base, ...baseFallbacks]);
1992
+ const candidates = await extractRawCandidates(sources);
1993
+ const parsedCandidates = candidates.filter(
1994
+ (rawCandidate) => designSystem.parseCandidate(rawCandidate).length > 0
1995
+ );
1996
+ if (parsedCandidates.length === 0) {
1997
+ return parsedCandidates;
1998
+ }
1999
+ const cssByCandidate = designSystem.candidatesToCss(parsedCandidates);
2000
+ const validCandidates = [];
2001
+ for (let index = 0; index < parsedCandidates.length; index++) {
2002
+ const candidate = parsedCandidates[index];
2003
+ if (candidate === void 0) {
2004
+ continue;
2005
+ }
2006
+ const css2 = cssByCandidate[index];
2007
+ if (typeof css2 === "string" && css2.trim().length > 0) {
2008
+ validCandidates.push(candidate);
2009
+ }
2010
+ }
2011
+ return validCandidates;
2012
+ }
2013
+ function normalizeSources(sources, cwd) {
2014
+ const baseSources = sources?.length ? sources : [
2015
+ {
2016
+ base: cwd,
2017
+ pattern: "**/*",
2018
+ negated: false
2019
+ }
2020
+ ];
2021
+ return baseSources.map((source) => ({
2022
+ base: source.base ?? cwd,
2023
+ pattern: source.pattern,
2024
+ negated: source.negated
2025
+ }));
2026
+ }
2027
+ function buildLineOffsets(content) {
2028
+ const offsets = [0];
2029
+ for (let i = 0; i < content.length; i++) {
2030
+ if (content[i] === "\n") {
2031
+ offsets.push(i + 1);
2032
+ }
2033
+ }
2034
+ if (offsets[offsets.length - 1] !== content.length) {
2035
+ offsets.push(content.length);
2036
+ }
2037
+ return offsets;
2038
+ }
2039
+ function resolveLineMeta(content, offsets, index) {
2040
+ let low = 0;
2041
+ let high = offsets.length - 1;
2042
+ while (low <= high) {
2043
+ const mid = Math.floor((low + high) / 2);
2044
+ const start = offsets[mid];
2045
+ if (start === void 0) {
2046
+ break;
2047
+ }
2048
+ const nextStart = offsets[mid + 1] ?? content.length;
2049
+ if (index < start) {
2050
+ high = mid - 1;
2051
+ continue;
2052
+ }
2053
+ if (index >= nextStart) {
2054
+ low = mid + 1;
2055
+ continue;
2056
+ }
2057
+ const line = mid + 1;
2058
+ const column = index - start + 1;
2059
+ const lineEnd = content.indexOf("\n", start);
2060
+ const lineText = content.slice(start, lineEnd === -1 ? content.length : lineEnd);
2061
+ return { line, column, lineText };
2062
+ }
2063
+ const lastStart = offsets[offsets.length - 2] ?? 0;
2064
+ return {
2065
+ line: offsets.length - 1,
2066
+ column: index - lastStart + 1,
2067
+ lineText: content.slice(lastStart)
2068
+ };
2069
+ }
2070
+ function toExtension(filename) {
2071
+ const ext = path4.extname(filename).replace(/^\./, "");
2072
+ return ext || "txt";
2073
+ }
2074
+ function toRelativeFile(cwd, filename) {
2075
+ const relative = path4.relative(cwd, filename);
2076
+ return relative === "" ? path4.basename(filename) : relative;
2077
+ }
2078
+ async function extractProjectCandidatesWithPositions(options) {
2079
+ const cwd = options?.cwd ? path4.resolve(options.cwd) : process4.cwd();
2080
+ const normalizedSources = normalizeSources(options?.sources, cwd);
2081
+ const { Scanner } = await importOxide();
2082
+ const scanner = new Scanner({
2083
+ sources: normalizedSources
2084
+ });
2085
+ const files = scanner.files ?? [];
2086
+ const entries = [];
2087
+ const skipped = [];
2088
+ for (const file of files) {
2089
+ let content;
2090
+ try {
2091
+ content = await fs4.readFile(file, "utf8");
2092
+ } catch (error) {
2093
+ skipped.push({
2094
+ file,
2095
+ reason: error instanceof Error ? error.message : "Unknown error"
2096
+ });
2097
+ continue;
2098
+ }
2099
+ const extension = toExtension(file);
2100
+ const matches = scanner.getCandidatesWithPositions({
2101
+ file,
2102
+ content,
2103
+ extension
2104
+ });
2105
+ if (!matches.length) {
2106
+ continue;
2107
+ }
2108
+ const offsets = buildLineOffsets(content);
2109
+ const relativeFile = toRelativeFile(cwd, file);
2110
+ for (const match of matches) {
2111
+ const info = resolveLineMeta(content, offsets, match.position);
2112
+ entries.push({
2113
+ rawCandidate: match.candidate,
2114
+ file,
2115
+ relativeFile,
2116
+ extension,
2117
+ start: match.position,
2118
+ end: match.position + match.candidate.length,
2119
+ length: match.candidate.length,
2120
+ line: info.line,
2121
+ column: info.column,
2122
+ lineText: info.lineText
2123
+ });
2124
+ }
2125
+ }
2126
+ return {
2127
+ entries,
2128
+ filesScanned: files.length,
2129
+ skippedFiles: skipped,
2130
+ sources: normalizedSources
2131
+ };
2132
+ }
2133
+ function groupTokensByFile(report, options) {
2134
+ const key = options?.key ?? "relative";
2135
+ const stripAbsolute = options?.stripAbsolutePaths ?? key !== "absolute";
2136
+ return report.entries.reduce((acc, entry) => {
2137
+ const bucketKey = key === "absolute" ? entry.file : entry.relativeFile;
2138
+ if (!acc[bucketKey]) {
2139
+ acc[bucketKey] = [];
2140
+ }
2141
+ const value = stripAbsolute ? {
2142
+ ...entry,
2143
+ file: entry.relativeFile
2144
+ } : entry;
2145
+ acc[bucketKey].push(value);
2146
+ return acc;
2147
+ }, {});
2148
+ }
2149
+
2150
+ // src/runtime/class-collector.ts
2151
+ import process5 from "process";
2152
+ import fs5 from "fs-extra";
2153
+ import path5 from "pathe";
2154
+
2155
+ // src/utils.ts
2156
+ function isObject(val) {
2157
+ return val !== null && typeof val === "object" && Array.isArray(val) === false;
2158
+ }
2159
+ function spliceChangesIntoString(str, changes) {
2160
+ if (!changes[0]) {
2161
+ return str;
2162
+ }
2163
+ changes.sort((a, b) => {
2164
+ return a.end - b.end || a.start - b.start;
2165
+ });
2166
+ let result = "";
2167
+ let previous = changes[0];
2168
+ result += str.slice(0, previous.start);
2169
+ result += previous.replacement;
2170
+ for (let i = 1; i < changes.length; ++i) {
2171
+ const change = changes[i];
2172
+ result += str.slice(previous.end, change.start);
2173
+ result += change.replacement;
2174
+ previous = change;
2175
+ }
2176
+ result += str.slice(previous.end);
2177
+ return result;
2178
+ }
2179
+
2180
+ // src/runtime/class-collector.ts
2181
+ function collectClassesFromContexts(contexts, filter) {
2182
+ const set = /* @__PURE__ */ new Set();
2183
+ for (const context of contexts) {
2184
+ if (!isObject(context) || !context.classCache) {
2185
+ continue;
2186
+ }
2187
+ for (const key of context.classCache.keys()) {
2188
+ const className = key.toString();
2189
+ if (filter(className)) {
2190
+ set.add(className);
2191
+ }
2192
+ }
2193
+ }
2194
+ return set;
2195
+ }
2196
+ async function collectClassesFromTailwindV4(options) {
2197
+ const set = /* @__PURE__ */ new Set();
2198
+ const v4Options = options.tailwind.v4;
2199
+ if (!v4Options) {
2200
+ return set;
2201
+ }
2202
+ const toAbsolute = (value) => {
2203
+ if (!value) {
2204
+ return void 0;
2205
+ }
2206
+ return path5.isAbsolute(value) ? value : path5.resolve(options.projectRoot, value);
2207
+ };
2208
+ const resolvedConfiguredBase = toAbsolute(v4Options.configuredBase);
2209
+ const resolvedDefaultBase = toAbsolute(v4Options.base) ?? process5.cwd();
2210
+ const resolveSources = (base) => {
2211
+ if (!v4Options.sources?.length) {
2212
+ return void 0;
2213
+ }
2214
+ return v4Options.sources.map((source) => ({
2215
+ base: source.base ?? base,
2216
+ pattern: source.pattern,
2217
+ negated: source.negated
2218
+ }));
2219
+ };
2220
+ if (v4Options.cssEntries.length > 0) {
2221
+ for (const entry of v4Options.cssEntries) {
2222
+ const filePath = path5.isAbsolute(entry) ? entry : path5.resolve(options.projectRoot, entry);
2223
+ if (!await fs5.pathExists(filePath)) {
2224
+ continue;
2225
+ }
2226
+ const css = await fs5.readFile(filePath, "utf8");
2227
+ const entryDir = path5.dirname(filePath);
2228
+ const designSystemBases = resolvedConfiguredBase && resolvedConfiguredBase !== entryDir ? [entryDir, resolvedConfiguredBase] : [entryDir];
2229
+ const sourcesBase = resolvedConfiguredBase ?? entryDir;
2230
+ const sources = resolveSources(sourcesBase);
2231
+ const firstBase = designSystemBases[0] ?? entryDir;
2232
+ const extractOptions = {
2233
+ cwd: options.projectRoot,
2234
+ base: firstBase,
2235
+ baseFallbacks: designSystemBases.slice(1),
2236
+ css,
2237
+ ...sources === void 0 ? {} : { sources }
2238
+ };
2239
+ const candidates = await extractValidCandidates(extractOptions);
2240
+ for (const candidate of candidates) {
2241
+ if (options.filter(candidate)) {
2242
+ set.add(candidate);
2243
+ }
2244
+ }
2245
+ }
2246
+ } else {
2247
+ const baseForCss = resolvedConfiguredBase ?? resolvedDefaultBase;
2248
+ const sources = resolveSources(baseForCss);
2249
+ const extractOptions = {
2250
+ cwd: options.projectRoot,
2251
+ base: baseForCss,
2252
+ ...v4Options.css === void 0 ? {} : { css: v4Options.css },
2253
+ ...sources === void 0 ? {} : { sources }
2254
+ };
2255
+ const candidates = await extractValidCandidates(extractOptions);
2256
+ for (const candidate of candidates) {
2257
+ if (options.filter(candidate)) {
2258
+ set.add(candidate);
2259
+ }
2260
+ }
2261
+ }
2262
+ return set;
2263
+ }
2264
+
2265
+ // src/runtime/context-registry.ts
2266
+ import { createRequire } from "module";
2267
+ import fs6 from "fs-extra";
2268
+ import path6 from "pathe";
2269
+ var require2 = createRequire(import.meta.url);
2270
+ function resolveRuntimeEntry(packageInfo, majorVersion) {
2271
+ const root = packageInfo.rootPath;
2272
+ if (majorVersion === 2) {
2273
+ const jitIndex = path6.join(root, "lib/jit/index.js");
2274
+ if (fs6.existsSync(jitIndex)) {
2275
+ return jitIndex;
2276
+ }
2277
+ } else if (majorVersion === 3) {
2278
+ const plugin = path6.join(root, "lib/plugin.js");
2279
+ const index = path6.join(root, "lib/index.js");
2280
+ if (fs6.existsSync(plugin)) {
2281
+ return plugin;
2282
+ }
2283
+ if (fs6.existsSync(index)) {
2284
+ return index;
2285
+ }
2286
+ }
2287
+ return void 0;
2288
+ }
2289
+ function loadRuntimeContexts(packageInfo, majorVersion, refProperty) {
2290
+ if (majorVersion === 4) {
2291
+ return [];
2292
+ }
2293
+ const entry = resolveRuntimeEntry(packageInfo, majorVersion);
2294
+ if (!entry) {
2295
+ return [];
2296
+ }
2297
+ const moduleExports = require2(entry);
2298
+ if (!moduleExports) {
2299
+ return [];
2300
+ }
2301
+ const ref = moduleExports[refProperty];
2302
+ if (!ref) {
2303
+ return [];
2304
+ }
2305
+ if (Array.isArray(ref)) {
2306
+ return ref;
2307
+ }
2308
+ if (typeof ref === "object" && Array.isArray(ref.value)) {
2309
+ return ref.value;
2310
+ }
2311
+ return [];
2312
+ }
2313
+
2314
+ // src/runtime/process-tailwindcss.ts
2315
+ import { createRequire as createRequire2 } from "module";
2316
+ import path7 from "pathe";
2317
+ import postcss from "postcss";
2318
+ import { loadConfig } from "tailwindcss-config";
2319
+ var require3 = createRequire2(import.meta.url);
2320
+ async function resolveConfigPath(options) {
2321
+ if (options.config && path7.isAbsolute(options.config)) {
2322
+ return options.config;
2323
+ }
2324
+ const result = await loadConfig({ cwd: options.cwd });
2325
+ if (!result) {
2326
+ throw new Error(`Unable to locate Tailwind CSS config from ${options.cwd}`);
2327
+ }
2328
+ return result.filepath;
2329
+ }
2330
+ async function runTailwindBuild(options) {
2331
+ const configPath = await resolveConfigPath(options);
2332
+ const pluginName = options.postcssPlugin ?? (options.majorVersion === 4 ? "@tailwindcss/postcss" : "tailwindcss");
2333
+ if (options.majorVersion === 4) {
2334
+ return postcss([
2335
+ require3(pluginName)({
2336
+ config: configPath
2337
+ })
2338
+ ]).process("@import 'tailwindcss';", {
2339
+ from: void 0
2340
+ });
2341
+ }
2342
+ return postcss([
2343
+ require3(pluginName)({
2344
+ config: configPath
2345
+ })
2346
+ ]).process("@tailwind base;@tailwind components;@tailwind utilities;", {
2347
+ from: void 0
2348
+ });
2349
+ }
2350
+
2351
+ // src/patching/status.ts
2352
+ import * as t4 from "@babel/types";
2353
+ import fs8 from "fs-extra";
2354
+ import path9 from "pathe";
2355
+
2356
+ // src/babel/index.ts
2357
+ import _babelGenerate from "@babel/generator";
2358
+ import _babelTraverse from "@babel/traverse";
2359
+ import { parse, parseExpression } from "@babel/parser";
2360
+ function _interopDefaultCompat(e) {
2361
+ return e && typeof e === "object" && "default" in e ? e.default : e;
2362
+ }
2363
+ var generate = _interopDefaultCompat(_babelGenerate);
2364
+ var traverse = _interopDefaultCompat(_babelTraverse);
2365
+
2366
+ // src/patching/operations/export-context/postcss-v2.ts
2367
+ import * as t from "@babel/types";
2368
+ var IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
2369
+ function toIdentifierName(property) {
2370
+ if (!property) {
2371
+ return "contextRef";
2372
+ }
2373
+ const sanitized = property.replace(/[^\w$]/gu, "_");
2374
+ if (/^\d/.test(sanitized)) {
2375
+ return `_${sanitized}`;
1994
2376
  }
1995
2377
  return sanitized || "contextRef";
1996
2378
  }
@@ -2006,8 +2388,8 @@ function transformProcessTailwindFeaturesReturnContextV2(content) {
2006
2388
  });
2007
2389
  let hasPatched = false;
2008
2390
  traverse(ast, {
2009
- FunctionDeclaration(path13) {
2010
- const node = path13.node;
2391
+ FunctionDeclaration(path18) {
2392
+ const node = path18.node;
2011
2393
  if (node.id?.name !== "processTailwindFeatures" || node.body.body.length !== 1 || !t.isReturnStatement(node.body.body[0])) {
2012
2394
  return;
2013
2395
  }
@@ -2038,8 +2420,8 @@ function transformPostcssPluginV2(content, options) {
2038
2420
  const ast = parse(content);
2039
2421
  let hasPatched = false;
2040
2422
  traverse(ast, {
2041
- Program(path13) {
2042
- const program = path13.node;
2423
+ Program(path18) {
2424
+ const program = path18.node;
2043
2425
  const index = program.body.findIndex((statement) => {
2044
2426
  return t.isFunctionDeclaration(statement) && statement.id?.name === "_default";
2045
2427
  });
@@ -2073,11 +2455,11 @@ function transformPostcssPluginV2(content, options) {
2073
2455
  );
2074
2456
  }
2075
2457
  },
2076
- FunctionDeclaration(path13) {
2458
+ FunctionDeclaration(path18) {
2077
2459
  if (hasPatched) {
2078
2460
  return;
2079
2461
  }
2080
- const fn = path13.node;
2462
+ const fn = path18.node;
2081
2463
  if (fn.id?.name !== "_default") {
2082
2464
  return;
2083
2465
  }
@@ -2166,8 +2548,8 @@ function transformProcessTailwindFeaturesReturnContext(content) {
2166
2548
  const ast = parse(content);
2167
2549
  let hasPatched = false;
2168
2550
  traverse(ast, {
2169
- FunctionDeclaration(path13) {
2170
- const node = path13.node;
2551
+ FunctionDeclaration(path18) {
2552
+ const node = path18.node;
2171
2553
  if (node.id?.name !== "processTailwindFeatures" || node.body.body.length !== 1) {
2172
2554
  return;
2173
2555
  }
@@ -2199,8 +2581,8 @@ function transformPostcssPlugin(content, { refProperty }) {
2199
2581
  const valueMember = t2.memberExpression(refIdentifier, t2.identifier("value"));
2200
2582
  let hasPatched = false;
2201
2583
  traverse(ast, {
2202
- Program(path13) {
2203
- const program = path13.node;
2584
+ Program(path18) {
2585
+ const program = path18.node;
2204
2586
  const index = program.body.findIndex((statement) => {
2205
2587
  return t2.isExpressionStatement(statement) && t2.isAssignmentExpression(statement.expression) && t2.isMemberExpression(statement.expression.left) && t2.isFunctionExpression(statement.expression.right) && statement.expression.right.id?.name === "tailwindcss";
2206
2588
  });
@@ -2238,11 +2620,11 @@ function transformPostcssPlugin(content, { refProperty }) {
2238
2620
  );
2239
2621
  }
2240
2622
  },
2241
- FunctionExpression(path13) {
2623
+ FunctionExpression(path18) {
2242
2624
  if (hasPatched) {
2243
2625
  return;
2244
2626
  }
2245
- const fn = path13.node;
2627
+ const fn = path18.node;
2246
2628
  if (fn.id?.name !== "tailwindcss" || fn.body.body.length !== 1) {
2247
2629
  return;
2248
2630
  }
@@ -2305,64 +2687,37 @@ function transformPostcssPlugin(content, { refProperty }) {
2305
2687
  );
2306
2688
  }
2307
2689
  });
2308
- return {
2309
- code: hasPatched ? content : generate(ast).code,
2310
- hasPatched
2311
- };
2312
- }
2313
-
2314
- // src/patching/operations/extend-length-units.ts
2315
- import * as t3 from "@babel/types";
2316
- import fs5 from "fs-extra";
2317
- import path4 from "pathe";
2318
-
2319
- // src/utils.ts
2320
- function isObject(val) {
2321
- return val !== null && typeof val === "object" && Array.isArray(val) === false;
2322
- }
2323
- function spliceChangesIntoString(str, changes) {
2324
- if (!changes[0]) {
2325
- return str;
2326
- }
2327
- changes.sort((a, b) => {
2328
- return a.end - b.end || a.start - b.start;
2329
- });
2330
- let result = "";
2331
- let previous = changes[0];
2332
- result += str.slice(0, previous.start);
2333
- result += previous.replacement;
2334
- for (let i = 1; i < changes.length; ++i) {
2335
- const change = changes[i];
2336
- result += str.slice(previous.end, change.start);
2337
- result += change.replacement;
2338
- previous = change;
2339
- }
2340
- result += str.slice(previous.end);
2341
- return result;
2690
+ return {
2691
+ code: hasPatched ? content : generate(ast).code,
2692
+ hasPatched
2693
+ };
2342
2694
  }
2343
2695
 
2344
2696
  // src/patching/operations/extend-length-units.ts
2697
+ import * as t3 from "@babel/types";
2698
+ import fs7 from "fs-extra";
2699
+ import path8 from "pathe";
2345
2700
  function updateLengthUnitsArray(content, options) {
2346
2701
  const { variableName = "lengthUnits", units } = options;
2347
2702
  const ast = parse(content);
2348
2703
  let arrayRef;
2349
2704
  let changed = false;
2350
2705
  traverse(ast, {
2351
- Identifier(path13) {
2352
- if (path13.node.name === variableName && t3.isVariableDeclarator(path13.parent) && t3.isArrayExpression(path13.parent.init)) {
2353
- arrayRef = path13.parent.init;
2706
+ Identifier(path18) {
2707
+ if (path18.node.name === variableName && t3.isVariableDeclarator(path18.parent) && t3.isArrayExpression(path18.parent.init)) {
2708
+ arrayRef = path18.parent.init;
2354
2709
  const existing = new Set(
2355
- path13.parent.init.elements.map((element) => t3.isStringLiteral(element) ? element.value : void 0).filter(Boolean)
2710
+ path18.parent.init.elements.map((element) => t3.isStringLiteral(element) ? element.value : void 0).filter(Boolean)
2356
2711
  );
2357
2712
  for (const unit of units) {
2358
2713
  if (!existing.has(unit)) {
2359
- path13.parent.init.elements = path13.parent.init.elements.map((element) => {
2714
+ path18.parent.init.elements = path18.parent.init.elements.map((element) => {
2360
2715
  if (t3.isStringLiteral(element)) {
2361
2716
  return t3.stringLiteral(element.value);
2362
2717
  }
2363
2718
  return element;
2364
2719
  });
2365
- path13.parent.init.elements.push(t3.stringLiteral(unit));
2720
+ path18.parent.init.elements.push(t3.stringLiteral(unit));
2366
2721
  changed = true;
2367
2722
  }
2368
2723
  }
@@ -2383,12 +2738,12 @@ function applyExtendLengthUnitsPatchV3(rootDir, options) {
2383
2738
  lengthUnitsFilePath: options.lengthUnitsFilePath ?? "lib/util/dataTypes.js",
2384
2739
  variableName: options.variableName ?? "lengthUnits"
2385
2740
  };
2386
- const dataTypesFilePath = path4.resolve(rootDir, opts.lengthUnitsFilePath);
2387
- const exists = fs5.existsSync(dataTypesFilePath);
2741
+ const dataTypesFilePath = path8.resolve(rootDir, opts.lengthUnitsFilePath);
2742
+ const exists = fs7.existsSync(dataTypesFilePath);
2388
2743
  if (!exists) {
2389
2744
  return { changed: false, code: void 0 };
2390
2745
  }
2391
- const content = fs5.readFileSync(dataTypesFilePath, "utf8");
2746
+ const content = fs7.readFileSync(dataTypesFilePath, "utf8");
2392
2747
  const { arrayRef, changed } = updateLengthUnitsArray(content, opts);
2393
2748
  if (!arrayRef || !changed) {
2394
2749
  return { changed: false, code: void 0 };
@@ -2399,8 +2754,8 @@ function applyExtendLengthUnitsPatchV3(rootDir, options) {
2399
2754
  if (arrayRef.start != null && arrayRef.end != null) {
2400
2755
  const nextCode = `${content.slice(0, arrayRef.start)}${code}${content.slice(arrayRef.end)}`;
2401
2756
  if (opts.overwrite) {
2402
- const target = opts.destPath ? path4.resolve(opts.destPath) : dataTypesFilePath;
2403
- fs5.writeFileSync(target, nextCode, "utf8");
2757
+ const target = opts.destPath ? path8.resolve(opts.destPath) : dataTypesFilePath;
2758
+ fs7.writeFileSync(target, nextCode, "utf8");
2404
2759
  logger_default.success("Patched Tailwind CSS length unit list (v3).");
2405
2760
  }
2406
2761
  return {
@@ -2418,16 +2773,16 @@ function applyExtendLengthUnitsPatchV4(rootDir, options) {
2418
2773
  return { files: [], changed: false };
2419
2774
  }
2420
2775
  const opts = { ...options };
2421
- const distDir = path4.resolve(rootDir, "dist");
2422
- if (!fs5.existsSync(distDir)) {
2776
+ const distDir = path8.resolve(rootDir, "dist");
2777
+ if (!fs7.existsSync(distDir)) {
2423
2778
  return { files: [], changed: false };
2424
2779
  }
2425
- const entries = fs5.readdirSync(distDir);
2780
+ const entries = fs7.readdirSync(distDir);
2426
2781
  const chunkNames = entries.filter((entry) => entry.endsWith(".js") || entry.endsWith(".mjs"));
2427
2782
  const pattern = /\[\s*["']cm["'],\s*["']mm["'],[\w,"']+\]/;
2428
2783
  const candidates = chunkNames.map((chunkName) => {
2429
- const file = path4.join(distDir, chunkName);
2430
- const code = fs5.readFileSync(file, "utf8");
2784
+ const file = path8.join(distDir, chunkName);
2785
+ const code = fs7.readFileSync(file, "utf8");
2431
2786
  const match = pattern.exec(code);
2432
2787
  if (!match) {
2433
2788
  return null;
@@ -2443,13 +2798,13 @@ function applyExtendLengthUnitsPatchV4(rootDir, options) {
2443
2798
  const { code, file, match } = item;
2444
2799
  const ast = parse(match[0], { sourceType: "unambiguous" });
2445
2800
  traverse(ast, {
2446
- ArrayExpression(path13) {
2801
+ ArrayExpression(path18) {
2447
2802
  for (const unit of opts.units) {
2448
- if (path13.node.elements.some((element) => t3.isStringLiteral(element) && element.value === unit)) {
2803
+ if (path18.node.elements.some((element) => t3.isStringLiteral(element) && element.value === unit)) {
2449
2804
  item.hasPatched = true;
2450
2805
  return;
2451
2806
  }
2452
- path13.node.elements.push(t3.stringLiteral(unit));
2807
+ path18.node.elements.push(t3.stringLiteral(unit));
2453
2808
  }
2454
2809
  }
2455
2810
  });
@@ -2467,7 +2822,7 @@ function applyExtendLengthUnitsPatchV4(rootDir, options) {
2467
2822
  }
2468
2823
  ]);
2469
2824
  if (opts.overwrite) {
2470
- fs5.writeFileSync(file, item.code, "utf8");
2825
+ fs7.writeFileSync(file, item.code, "utf8");
2471
2826
  }
2472
2827
  }
2473
2828
  if (candidates.some((file) => !file.hasPatched)) {
@@ -2485,14 +2840,14 @@ function inspectLengthUnitsArray(content, variableName, units) {
2485
2840
  let found = false;
2486
2841
  let missingUnits = [];
2487
2842
  traverse(ast, {
2488
- Identifier(path13) {
2489
- if (path13.node.name === variableName && t4.isVariableDeclarator(path13.parent) && t4.isArrayExpression(path13.parent.init)) {
2843
+ Identifier(path18) {
2844
+ if (path18.node.name === variableName && t4.isVariableDeclarator(path18.parent) && t4.isArrayExpression(path18.parent.init)) {
2490
2845
  found = true;
2491
2846
  const existing = new Set(
2492
- path13.parent.init.elements.map((element) => t4.isStringLiteral(element) ? element.value : void 0).filter(Boolean)
2847
+ path18.parent.init.elements.map((element) => t4.isStringLiteral(element) ? element.value : void 0).filter(Boolean)
2493
2848
  );
2494
2849
  missingUnits = units.filter((unit) => !existing.has(unit));
2495
- path13.stop();
2850
+ path18.stop();
2496
2851
  }
2497
2852
  }
2498
2853
  });
@@ -2522,12 +2877,12 @@ function checkExposeContextPatch(context) {
2522
2877
  }
2523
2878
  const checks = [];
2524
2879
  function inspectFile(relative, transform) {
2525
- const filePath = path5.resolve(packageInfo.rootPath, relative);
2526
- if (!fs6.existsSync(filePath)) {
2880
+ const filePath = path9.resolve(packageInfo.rootPath, relative);
2881
+ if (!fs8.existsSync(filePath)) {
2527
2882
  checks.push({ relative, exists: false, patched: false });
2528
2883
  return;
2529
2884
  }
2530
- const content = fs6.readFileSync(filePath, "utf8");
2885
+ const content = fs8.readFileSync(filePath, "utf8");
2531
2886
  const { hasPatched } = transform(content);
2532
2887
  checks.push({
2533
2888
  relative,
@@ -2538,7 +2893,7 @@ function checkExposeContextPatch(context) {
2538
2893
  if (majorVersion === 3) {
2539
2894
  inspectFile("lib/processTailwindFeatures.js", transformProcessTailwindFeaturesReturnContext);
2540
2895
  const pluginCandidates = ["lib/plugin.js", "lib/index.js"];
2541
- const pluginRelative = pluginCandidates.find((candidate) => fs6.existsSync(path5.resolve(packageInfo.rootPath, candidate)));
2896
+ const pluginRelative = pluginCandidates.find((candidate) => fs8.existsSync(path9.resolve(packageInfo.rootPath, candidate)));
2542
2897
  if (pluginRelative) {
2543
2898
  inspectFile(pluginRelative, (content) => transformPostcssPlugin(content, { refProperty }));
2544
2899
  } else {
@@ -2568,9 +2923,9 @@ function checkExposeContextPatch(context) {
2568
2923
  function checkExtendLengthUnitsV3(rootDir, options) {
2569
2924
  const lengthUnitsFilePath = options.lengthUnitsFilePath ?? "lib/util/dataTypes.js";
2570
2925
  const variableName = options.variableName ?? "lengthUnits";
2571
- const target = path5.resolve(rootDir, lengthUnitsFilePath);
2572
- const files = fs6.existsSync(target) ? [path5.relative(rootDir, target)] : [];
2573
- if (!fs6.existsSync(target)) {
2926
+ const target = path9.resolve(rootDir, lengthUnitsFilePath);
2927
+ const files = fs8.existsSync(target) ? [path9.relative(rootDir, target)] : [];
2928
+ if (!fs8.existsSync(target)) {
2574
2929
  return {
2575
2930
  name: "extendLengthUnits",
2576
2931
  status: "not-applied",
@@ -2578,411 +2933,117 @@ function checkExtendLengthUnitsV3(rootDir, options) {
2578
2933
  files
2579
2934
  };
2580
2935
  }
2581
- const content = fs6.readFileSync(target, "utf8");
2582
- const { found, missingUnits } = inspectLengthUnitsArray(content, variableName, options.units);
2583
- if (!found) {
2584
- return {
2585
- name: "extendLengthUnits",
2586
- status: "not-applied",
2587
- reason: `could not locate ${variableName} array in ${lengthUnitsFilePath}`,
2588
- files
2589
- };
2590
- }
2591
- if (missingUnits.length) {
2592
- return {
2593
- name: "extendLengthUnits",
2594
- status: "not-applied",
2595
- reason: `missing units: ${missingUnits.join(", ")}`,
2596
- files
2597
- };
2598
- }
2599
- return {
2600
- name: "extendLengthUnits",
2601
- status: "applied",
2602
- files
2603
- };
2604
- }
2605
- function checkExtendLengthUnitsV4(rootDir, options) {
2606
- const distDir = path5.resolve(rootDir, "dist");
2607
- if (!fs6.existsSync(distDir)) {
2608
- return {
2609
- name: "extendLengthUnits",
2610
- status: "not-applied",
2611
- reason: "dist directory not found for Tailwind v4 package",
2612
- files: []
2613
- };
2614
- }
2615
- const result = applyExtendLengthUnitsPatchV4(rootDir, {
2616
- ...options,
2617
- enabled: true,
2618
- overwrite: false
2619
- });
2620
- if (result.files.length === 0) {
2621
- return {
2622
- name: "extendLengthUnits",
2623
- status: "not-applied",
2624
- reason: "no bundle chunks matched the length unit pattern",
2625
- files: []
2626
- };
2627
- }
2628
- const files = result.files.map((file) => path5.relative(rootDir, file.file));
2629
- const pending = result.files.filter((file) => !file.hasPatched);
2630
- if (pending.length) {
2631
- return {
2632
- name: "extendLengthUnits",
2633
- status: "not-applied",
2634
- reason: `missing units in ${pending.length} bundle${pending.length > 1 ? "s" : ""}`,
2635
- files: pending.map((file) => path5.relative(rootDir, file.file))
2636
- };
2637
- }
2638
- return {
2639
- name: "extendLengthUnits",
2640
- status: "applied",
2641
- files
2642
- };
2643
- }
2644
- function checkExtendLengthUnitsPatch(context) {
2645
- const { packageInfo, options, majorVersion } = context;
2646
- if (!options.features.extendLengthUnits) {
2647
- return {
2648
- name: "extendLengthUnits",
2649
- status: "skipped",
2650
- reason: "extendLengthUnits feature disabled",
2651
- files: []
2652
- };
2653
- }
2654
- if (majorVersion === 2) {
2655
- return {
2656
- name: "extendLengthUnits",
2657
- status: "unsupported",
2658
- reason: "length unit extension is only applied for Tailwind v3/v4",
2659
- files: []
2660
- };
2661
- }
2662
- if (majorVersion === 3) {
2663
- return checkExtendLengthUnitsV3(packageInfo.rootPath, options.features.extendLengthUnits);
2664
- }
2665
- return checkExtendLengthUnitsV4(packageInfo.rootPath, options.features.extendLengthUnits);
2666
- }
2667
- function getPatchStatusReport(context) {
2668
- return {
2669
- package: {
2670
- name: context.packageInfo.name ?? context.packageInfo.packageJson?.name,
2671
- version: context.packageInfo.version,
2672
- root: context.packageInfo.rootPath
2673
- },
2674
- majorVersion: context.majorVersion,
2675
- entries: [
2676
- checkExposeContextPatch(context),
2677
- checkExtendLengthUnitsPatch(context)
2678
- ]
2679
- };
2680
- }
2681
-
2682
- // src/runtime/class-collector.ts
2683
- import process5 from "process";
2684
- import fs7 from "fs-extra";
2685
- import path6 from "pathe";
2686
- function collectClassesFromContexts(contexts, filter) {
2687
- const set = /* @__PURE__ */ new Set();
2688
- for (const context of contexts) {
2689
- if (!isObject(context) || !context.classCache) {
2690
- continue;
2691
- }
2692
- for (const key of context.classCache.keys()) {
2693
- const className = key.toString();
2694
- if (filter(className)) {
2695
- set.add(className);
2696
- }
2697
- }
2698
- }
2699
- return set;
2700
- }
2701
- async function collectClassesFromTailwindV4(options) {
2702
- const set = /* @__PURE__ */ new Set();
2703
- const v4Options = options.tailwind.v4;
2704
- if (!v4Options) {
2705
- return set;
2706
- }
2707
- const toAbsolute = (value) => {
2708
- if (!value) {
2709
- return void 0;
2710
- }
2711
- return path6.isAbsolute(value) ? value : path6.resolve(options.projectRoot, value);
2712
- };
2713
- const resolvedConfiguredBase = toAbsolute(v4Options.configuredBase);
2714
- const resolvedDefaultBase = toAbsolute(v4Options.base) ?? process5.cwd();
2715
- const resolveSources = (base) => {
2716
- if (!v4Options.sources?.length) {
2717
- return void 0;
2718
- }
2719
- return v4Options.sources.map((source) => ({
2720
- base: source.base ?? base,
2721
- pattern: source.pattern,
2722
- negated: source.negated
2723
- }));
2724
- };
2725
- if (v4Options.cssEntries.length > 0) {
2726
- for (const entry of v4Options.cssEntries) {
2727
- const filePath = path6.isAbsolute(entry) ? entry : path6.resolve(options.projectRoot, entry);
2728
- if (!await fs7.pathExists(filePath)) {
2729
- continue;
2730
- }
2731
- const css = await fs7.readFile(filePath, "utf8");
2732
- const entryDir = path6.dirname(filePath);
2733
- const designSystemBases = resolvedConfiguredBase && resolvedConfiguredBase !== entryDir ? [entryDir, resolvedConfiguredBase] : [entryDir];
2734
- const sourcesBase = resolvedConfiguredBase ?? entryDir;
2735
- const sources = resolveSources(sourcesBase);
2736
- const firstBase = designSystemBases[0] ?? entryDir;
2737
- const extractOptions = {
2738
- cwd: options.projectRoot,
2739
- base: firstBase,
2740
- baseFallbacks: designSystemBases.slice(1),
2741
- css,
2742
- ...sources === void 0 ? {} : { sources }
2743
- };
2744
- const candidates = await extractValidCandidates(extractOptions);
2745
- for (const candidate of candidates) {
2746
- if (options.filter(candidate)) {
2747
- set.add(candidate);
2748
- }
2749
- }
2750
- }
2751
- } else {
2752
- const baseForCss = resolvedConfiguredBase ?? resolvedDefaultBase;
2753
- const sources = resolveSources(baseForCss);
2754
- const extractOptions = {
2755
- cwd: options.projectRoot,
2756
- base: baseForCss,
2757
- ...v4Options.css === void 0 ? {} : { css: v4Options.css },
2758
- ...sources === void 0 ? {} : { sources }
2759
- };
2760
- const candidates = await extractValidCandidates(extractOptions);
2761
- for (const candidate of candidates) {
2762
- if (options.filter(candidate)) {
2763
- set.add(candidate);
2764
- }
2765
- }
2766
- }
2767
- return set;
2768
- }
2769
-
2770
- // src/runtime/context-registry.ts
2771
- import { createRequire } from "module";
2772
- import fs8 from "fs-extra";
2773
- import path7 from "pathe";
2774
- var require2 = createRequire(import.meta.url);
2775
- function resolveRuntimeEntry(packageInfo, majorVersion) {
2776
- const root = packageInfo.rootPath;
2777
- if (majorVersion === 2) {
2778
- const jitIndex = path7.join(root, "lib/jit/index.js");
2779
- if (fs8.existsSync(jitIndex)) {
2780
- return jitIndex;
2781
- }
2782
- } else if (majorVersion === 3) {
2783
- const plugin = path7.join(root, "lib/plugin.js");
2784
- const index = path7.join(root, "lib/index.js");
2785
- if (fs8.existsSync(plugin)) {
2786
- return plugin;
2787
- }
2788
- if (fs8.existsSync(index)) {
2789
- return index;
2790
- }
2791
- }
2792
- return void 0;
2793
- }
2794
- function loadRuntimeContexts(packageInfo, majorVersion, refProperty) {
2795
- if (majorVersion === 4) {
2796
- return [];
2797
- }
2798
- const entry = resolveRuntimeEntry(packageInfo, majorVersion);
2799
- if (!entry) {
2800
- return [];
2801
- }
2802
- const moduleExports = require2(entry);
2803
- if (!moduleExports) {
2804
- return [];
2805
- }
2806
- const ref = moduleExports[refProperty];
2807
- if (!ref) {
2808
- return [];
2809
- }
2810
- if (Array.isArray(ref)) {
2811
- return ref;
2812
- }
2813
- if (typeof ref === "object" && Array.isArray(ref.value)) {
2814
- return ref.value;
2815
- }
2816
- return [];
2817
- }
2818
-
2819
- // src/runtime/process-tailwindcss.ts
2820
- import { createRequire as createRequire2 } from "module";
2821
- import path8 from "pathe";
2822
- import postcss from "postcss";
2823
- import { loadConfig } from "tailwindcss-config";
2824
- var require3 = createRequire2(import.meta.url);
2825
- async function resolveConfigPath(options) {
2826
- if (options.config && path8.isAbsolute(options.config)) {
2827
- return options.config;
2828
- }
2829
- const result = await loadConfig({ cwd: options.cwd });
2830
- if (!result) {
2831
- throw new Error(`Unable to locate Tailwind CSS config from ${options.cwd}`);
2832
- }
2833
- return result.filepath;
2834
- }
2835
- async function runTailwindBuild(options) {
2836
- const configPath = await resolveConfigPath(options);
2837
- const pluginName = options.postcssPlugin ?? (options.majorVersion === 4 ? "@tailwindcss/postcss" : "tailwindcss");
2838
- if (options.majorVersion === 4) {
2839
- return postcss([
2840
- require3(pluginName)({
2841
- config: configPath
2842
- })
2843
- ]).process("@import 'tailwindcss';", {
2844
- from: void 0
2845
- });
2846
- }
2847
- return postcss([
2848
- require3(pluginName)({
2849
- config: configPath
2850
- })
2851
- ]).process("@tailwind base;@tailwind components;@tailwind utilities;", {
2852
- from: void 0
2853
- });
2854
- }
2855
-
2856
- // src/api/tailwindcss-patcher.ts
2857
- import process6 from "process";
2858
- import fs10 from "fs-extra";
2859
- import { getPackageInfoSync } from "local-pkg";
2860
- import path10 from "pathe";
2861
- import { coerce } from "semver";
2862
-
2863
- // src/options/legacy.ts
2864
- function normalizeLegacyFeatures(patch) {
2865
- const apply = patch?.applyPatches;
2866
- const extend = apply?.extendLengthUnits;
2867
- let extendOption = false;
2868
- if (extend && typeof extend === "object") {
2869
- extendOption = {
2870
- ...extend,
2871
- enabled: true
2936
+ const content = fs8.readFileSync(target, "utf8");
2937
+ const { found, missingUnits } = inspectLengthUnitsArray(content, variableName, options.units);
2938
+ if (!found) {
2939
+ return {
2940
+ name: "extendLengthUnits",
2941
+ status: "not-applied",
2942
+ reason: `could not locate ${variableName} array in ${lengthUnitsFilePath}`,
2943
+ files
2872
2944
  };
2873
- } else if (extend === true) {
2874
- extendOption = {
2875
- enabled: true,
2876
- units: ["rpx"],
2877
- ...patch?.overwrite === void 0 ? {} : { overwrite: patch.overwrite }
2945
+ }
2946
+ if (missingUnits.length) {
2947
+ return {
2948
+ name: "extendLengthUnits",
2949
+ status: "not-applied",
2950
+ reason: `missing units: ${missingUnits.join(", ")}`,
2951
+ files
2878
2952
  };
2879
2953
  }
2880
2954
  return {
2881
- exposeContext: apply?.exportContext ?? true,
2882
- extendLengthUnits: extendOption
2955
+ name: "extendLengthUnits",
2956
+ status: "applied",
2957
+ files
2883
2958
  };
2884
2959
  }
2885
- function fromLegacyOptions(options) {
2886
- if (!options) {
2887
- return {};
2960
+ function checkExtendLengthUnitsV4(rootDir, options) {
2961
+ const distDir = path9.resolve(rootDir, "dist");
2962
+ if (!fs8.existsSync(distDir)) {
2963
+ return {
2964
+ name: "extendLengthUnits",
2965
+ status: "not-applied",
2966
+ reason: "dist directory not found for Tailwind v4 package",
2967
+ files: []
2968
+ };
2969
+ }
2970
+ const result = applyExtendLengthUnitsPatchV4(rootDir, {
2971
+ ...options,
2972
+ enabled: true,
2973
+ overwrite: false
2974
+ });
2975
+ if (result.files.length === 0) {
2976
+ return {
2977
+ name: "extendLengthUnits",
2978
+ status: "not-applied",
2979
+ reason: "no bundle chunks matched the length unit pattern",
2980
+ files: []
2981
+ };
2982
+ }
2983
+ const files = result.files.map((file) => path9.relative(rootDir, file.file));
2984
+ const pending = result.files.filter((file) => !file.hasPatched);
2985
+ if (pending.length) {
2986
+ return {
2987
+ name: "extendLengthUnits",
2988
+ status: "not-applied",
2989
+ reason: `missing units in ${pending.length} bundle${pending.length > 1 ? "s" : ""}`,
2990
+ files: pending.map((file) => path9.relative(rootDir, file.file))
2991
+ };
2888
2992
  }
2889
- const patch = options.patch;
2890
- const features = normalizeLegacyFeatures(patch);
2891
- const output = patch?.output;
2892
- const tailwindConfig = patch?.tailwindcss;
2893
- const tailwindVersion = tailwindConfig?.version;
2894
- const tailwindV2 = tailwindConfig?.v2;
2895
- const tailwindV3 = tailwindConfig?.v3;
2896
- const tailwindV4 = tailwindConfig?.v4;
2897
- const tailwindConfigPath = tailwindV3?.config ?? tailwindV2?.config;
2898
- const tailwindCwd = tailwindV3?.cwd ?? tailwindV2?.cwd ?? patch?.cwd;
2899
- const normalizedExtract = output ? {
2900
- ...output.filename === void 0 ? {} : { file: output.filename },
2901
- pretty: output.loose ? 2 : false,
2902
- ...output.removeUniversalSelector === void 0 ? {} : { removeUniversalSelector: output.removeUniversalSelector }
2903
- } : void 0;
2904
- const normalizedTailwindcss = {
2905
- ...patch?.packageName === void 0 ? {} : { packageName: patch.packageName },
2906
- ...tailwindVersion === void 0 ? {} : { version: tailwindVersion },
2907
- ...patch?.resolve === void 0 ? {} : { resolve: patch.resolve },
2908
- ...tailwindConfigPath === void 0 ? {} : { config: tailwindConfigPath },
2909
- ...tailwindCwd === void 0 ? {} : { cwd: tailwindCwd },
2910
- ...tailwindV2 === void 0 ? {} : { v2: tailwindV2 },
2911
- ...tailwindV3 === void 0 ? {} : { v3: tailwindV3 },
2912
- ...tailwindV4 === void 0 ? {} : { v4: tailwindV4 }
2913
- };
2914
- const normalizedCache = typeof options.cache === "boolean" ? options.cache : options.cache ? {
2915
- ...options.cache,
2916
- enabled: options.cache.enabled ?? true
2917
- } : void 0;
2918
- const normalizedApply = {
2919
- ...patch?.overwrite === void 0 ? {} : { overwrite: patch.overwrite },
2920
- exposeContext: features.exposeContext,
2921
- extendLengthUnits: features.extendLengthUnits
2922
- };
2923
2993
  return {
2924
- ...patch?.cwd === void 0 ? {} : { projectRoot: patch.cwd },
2925
- ...patch?.filter === void 0 ? {} : { filter: patch.filter },
2926
- ...normalizedCache === void 0 ? {} : { cache: normalizedCache },
2927
- ...normalizedExtract === void 0 ? {} : { extract: normalizedExtract },
2928
- ...Object.keys(normalizedTailwindcss).length === 0 ? {} : { tailwindcss: normalizedTailwindcss },
2929
- apply: normalizedApply
2994
+ name: "extendLengthUnits",
2995
+ status: "applied",
2996
+ files
2930
2997
  };
2931
2998
  }
2932
- function fromUnifiedConfig(registry) {
2933
- if (!registry) {
2934
- return {};
2999
+ function checkExtendLengthUnitsPatch(context) {
3000
+ const { packageInfo, options, majorVersion } = context;
3001
+ if (!options.features.extendLengthUnits) {
3002
+ return {
3003
+ name: "extendLengthUnits",
3004
+ status: "skipped",
3005
+ reason: "extendLengthUnits feature disabled",
3006
+ files: []
3007
+ };
2935
3008
  }
2936
- const tailwind = registry.tailwindcss ?? registry.tailwind;
2937
- const modernExtract = registry.extract;
2938
- const legacyOutput = registry.output;
2939
- const pretty = (() => {
2940
- const value = modernExtract?.pretty ?? legacyOutput?.pretty;
2941
- if (value === void 0) {
2942
- return void 0;
2943
- }
2944
- if (typeof value === "boolean") {
2945
- return value ? 2 : false;
2946
- }
2947
- return value;
2948
- })();
2949
- const removeUniversalSelector = modernExtract?.removeUniversalSelector ?? legacyOutput?.stripUniversalSelector;
2950
- const outputFile = modernExtract?.file ?? legacyOutput?.file;
2951
- const normalizedExtract = modernExtract || legacyOutput ? {
2952
- ...modernExtract?.write === void 0 ? {} : { write: modernExtract.write },
2953
- ...outputFile === void 0 ? {} : { file: outputFile },
2954
- ...pretty === void 0 ? {} : { pretty },
2955
- ...removeUniversalSelector === void 0 ? {} : { removeUniversalSelector },
2956
- ...modernExtract?.format === void 0 ? {} : { format: modernExtract.format }
2957
- } : void 0;
2958
- const normalizedTailwindcss = tailwind ? {
2959
- ...tailwind.version === void 0 ? {} : { version: tailwind.version },
2960
- ...tailwind.packageName === void 0 ? tailwind.package === void 0 ? {} : { packageName: tailwind.package } : { packageName: tailwind.packageName },
2961
- ...tailwind.resolve === void 0 ? {} : { resolve: tailwind.resolve },
2962
- ...tailwind.config === void 0 ? {} : { config: tailwind.config },
2963
- ...tailwind.cwd === void 0 ? {} : { cwd: tailwind.cwd },
2964
- ...tailwind.v2 === void 0 ? tailwind.legacy === void 0 ? {} : { v2: tailwind.legacy } : { v2: tailwind.v2 },
2965
- ...tailwind.v3 === void 0 ? tailwind.classic === void 0 ? {} : { v3: tailwind.classic } : { v3: tailwind.v3 },
2966
- ...tailwind.v4 === void 0 ? tailwind.next === void 0 ? {} : { v4: tailwind.next } : { v4: tailwind.v4 }
2967
- } : void 0;
2968
- const normalizedApply = registry.apply ? {
2969
- ...registry.apply.overwrite === void 0 ? {} : { overwrite: registry.apply.overwrite },
2970
- ...registry.apply.exposeContext === void 0 ? {} : { exposeContext: registry.apply.exposeContext },
2971
- ...registry.apply.extendLengthUnits === void 0 ? {} : { extendLengthUnits: registry.apply.extendLengthUnits }
2972
- } : void 0;
3009
+ if (majorVersion === 2) {
3010
+ return {
3011
+ name: "extendLengthUnits",
3012
+ status: "unsupported",
3013
+ reason: "length unit extension is only applied for Tailwind v3/v4",
3014
+ files: []
3015
+ };
3016
+ }
3017
+ if (majorVersion === 3) {
3018
+ return checkExtendLengthUnitsV3(packageInfo.rootPath, options.features.extendLengthUnits);
3019
+ }
3020
+ return checkExtendLengthUnitsV4(packageInfo.rootPath, options.features.extendLengthUnits);
3021
+ }
3022
+ function getPatchStatusReport(context) {
2973
3023
  return {
2974
- ...registry.projectRoot === void 0 ? {} : { projectRoot: registry.projectRoot },
2975
- ...normalizedApply === void 0 ? {} : { apply: normalizedApply },
2976
- ...registry.cache === void 0 ? {} : { cache: registry.cache },
2977
- ...registry.filter === void 0 ? {} : { filter: registry.filter },
2978
- ...normalizedExtract === void 0 ? {} : { extract: normalizedExtract },
2979
- ...normalizedTailwindcss === void 0 ? {} : { tailwindcss: normalizedTailwindcss }
3024
+ package: {
3025
+ name: context.packageInfo.name ?? context.packageInfo.packageJson?.name,
3026
+ version: context.packageInfo.version,
3027
+ root: context.packageInfo.rootPath
3028
+ },
3029
+ majorVersion: context.majorVersion,
3030
+ entries: [
3031
+ checkExposeContextPatch(context),
3032
+ checkExtendLengthUnitsPatch(context)
3033
+ ]
2980
3034
  };
2981
3035
  }
2982
3036
 
3037
+ // src/api/tailwindcss-patcher.ts
3038
+ import process6 from "process";
3039
+ import fs10 from "fs-extra";
3040
+ import { getPackageInfoSync } from "local-pkg";
3041
+ import path11 from "pathe";
3042
+ import { coerce } from "semver";
3043
+
2983
3044
  // src/patching/operations/export-context/index.ts
2984
3045
  import fs9 from "fs-extra";
2985
- import path9 from "pathe";
3046
+ import path10 from "pathe";
2986
3047
  function writeFileIfRequired(filePath, code, overwrite, successMessage) {
2987
3048
  if (!overwrite) {
2988
3049
  return;
@@ -3000,7 +3061,7 @@ function applyExposeContextPatch(params) {
3000
3061
  };
3001
3062
  if (majorVersion === 3) {
3002
3063
  const processFileRelative = "lib/processTailwindFeatures.js";
3003
- const processFilePath = path9.resolve(rootDir, processFileRelative);
3064
+ const processFilePath = path10.resolve(rootDir, processFileRelative);
3004
3065
  if (fs9.existsSync(processFilePath)) {
3005
3066
  const content = fs9.readFileSync(processFilePath, "utf8");
3006
3067
  const { code, hasPatched } = transformProcessTailwindFeaturesReturnContext(content);
@@ -3016,9 +3077,9 @@ function applyExposeContextPatch(params) {
3016
3077
  }
3017
3078
  }
3018
3079
  const pluginCandidates = ["lib/plugin.js", "lib/index.js"];
3019
- const pluginRelative = pluginCandidates.find((candidate) => fs9.existsSync(path9.resolve(rootDir, candidate)));
3080
+ const pluginRelative = pluginCandidates.find((candidate) => fs9.existsSync(path10.resolve(rootDir, candidate)));
3020
3081
  if (pluginRelative) {
3021
- const pluginPath = path9.resolve(rootDir, pluginRelative);
3082
+ const pluginPath = path10.resolve(rootDir, pluginRelative);
3022
3083
  const content = fs9.readFileSync(pluginPath, "utf8");
3023
3084
  const { code, hasPatched } = transformPostcssPlugin(content, { refProperty });
3024
3085
  result.files[pluginRelative] = code;
@@ -3034,7 +3095,7 @@ function applyExposeContextPatch(params) {
3034
3095
  }
3035
3096
  } else if (majorVersion === 2) {
3036
3097
  const processFileRelative = "lib/jit/processTailwindFeatures.js";
3037
- const processFilePath = path9.resolve(rootDir, processFileRelative);
3098
+ const processFilePath = path10.resolve(rootDir, processFileRelative);
3038
3099
  if (fs9.existsSync(processFilePath)) {
3039
3100
  const content = fs9.readFileSync(processFilePath, "utf8");
3040
3101
  const { code, hasPatched } = transformProcessTailwindFeaturesReturnContextV2(content);
@@ -3050,7 +3111,7 @@ function applyExposeContextPatch(params) {
3050
3111
  }
3051
3112
  }
3052
3113
  const pluginRelative = "lib/jit/index.js";
3053
- const pluginPath = path9.resolve(rootDir, pluginRelative);
3114
+ const pluginPath = path10.resolve(rootDir, pluginRelative);
3054
3115
  if (fs9.existsSync(pluginPath)) {
3055
3116
  const content = fs9.readFileSync(pluginPath, "utf8");
3056
3117
  const { code, hasPatched } = transformPostcssPluginV2(content, { refProperty });
@@ -3297,8 +3358,8 @@ var TailwindcssPatcher = class {
3297
3358
  if (!shouldWrite || !this.options.output.file) {
3298
3359
  return result;
3299
3360
  }
3300
- const target = path10.resolve(this.options.output.file);
3301
- await fs10.ensureDir(path10.dirname(target));
3361
+ const target = path11.resolve(this.options.output.file);
3362
+ await fs10.ensureDir(path11.dirname(target));
3302
3363
  if (this.options.output.format === "json") {
3303
3364
  const spaces = typeof this.options.output.pretty === "number" ? this.options.output.pretty : void 0;
3304
3365
  await fs10.writeJSON(target, classList, { spaces });
@@ -3341,37 +3402,94 @@ var TailwindcssPatcher = class {
3341
3402
  }
3342
3403
  };
3343
3404
 
3344
- // src/cli/migrate-config.ts
3345
- import generate2 from "@babel/generator";
3346
- import { parse as parse2 } from "@babel/parser";
3347
- import * as t5 from "@babel/types";
3348
- import fs11 from "fs-extra";
3349
- import path11 from "pathe";
3350
- var DEFAULT_CONFIG_FILENAMES = [
3351
- "tailwindcss-patch.config.ts",
3352
- "tailwindcss-patch.config.js",
3353
- "tailwindcss-patch.config.mjs",
3354
- "tailwindcss-patch.config.cjs",
3355
- "tailwindcss-mangle.config.ts",
3356
- "tailwindcss-mangle.config.js",
3357
- "tailwindcss-mangle.config.mjs",
3358
- "tailwindcss-mangle.config.cjs"
3359
- ];
3360
- var DEFAULT_CONFIG_FILENAME_SET = new Set(DEFAULT_CONFIG_FILENAMES);
3361
- var DEFAULT_WORKSPACE_IGNORED_DIRS = /* @__PURE__ */ new Set([
3362
- ".git",
3363
- ".idea",
3364
- ".turbo",
3365
- ".vscode",
3366
- ".yarn",
3367
- "coverage",
3368
- "dist",
3369
- "node_modules",
3370
- "tmp"
3371
- ]);
3372
- var DEFAULT_WORKSPACE_MAX_DEPTH = 6;
3405
+ // src/commands/migration-report.ts
3373
3406
  var MIGRATION_REPORT_KIND = "tw-patch-migrate-report";
3374
3407
  var MIGRATION_REPORT_SCHEMA_VERSION = 1;
3408
+ function assertMigrationReportCompatibility(report, reportFile) {
3409
+ if (report.reportKind !== void 0 && report.reportKind !== MIGRATION_REPORT_KIND) {
3410
+ throw new Error(`Unsupported report kind "${report.reportKind}" in ${reportFile}.`);
3411
+ }
3412
+ if (report.schemaVersion !== void 0 && (!Number.isInteger(report.schemaVersion) || report.schemaVersion > MIGRATION_REPORT_SCHEMA_VERSION)) {
3413
+ throw new Error(
3414
+ `Unsupported report schema version "${String(report.schemaVersion)}" in ${reportFile}. Current supported version is ${MIGRATION_REPORT_SCHEMA_VERSION}.`
3415
+ );
3416
+ }
3417
+ }
3418
+
3419
+ // src/commands/migrate-config.ts
3420
+ import path14 from "pathe";
3421
+
3422
+ // src/commands/migration-aggregation.ts
3423
+ function createMigrationAggregationState() {
3424
+ return {
3425
+ scannedFiles: 0,
3426
+ changedFiles: 0,
3427
+ writtenFiles: 0,
3428
+ backupsWritten: 0,
3429
+ unchangedFiles: 0,
3430
+ missingFiles: 0,
3431
+ entries: []
3432
+ };
3433
+ }
3434
+ function collectMigrationExecutionResult(state, result) {
3435
+ if (result.missing) {
3436
+ state.missingFiles += 1;
3437
+ return;
3438
+ }
3439
+ state.scannedFiles += 1;
3440
+ state.entries.push(result.entry);
3441
+ if (result.changed) {
3442
+ state.changedFiles += 1;
3443
+ if (result.wrote) {
3444
+ state.writtenFiles += 1;
3445
+ }
3446
+ if (result.backupWritten) {
3447
+ state.backupsWritten += 1;
3448
+ }
3449
+ } else {
3450
+ state.unchangedFiles += 1;
3451
+ }
3452
+ }
3453
+ function buildMigrationReport(state, context) {
3454
+ const {
3455
+ cwd,
3456
+ dryRun,
3457
+ rollbackOnError,
3458
+ backupDirectory,
3459
+ toolName,
3460
+ toolVersion,
3461
+ generatedAt = (/* @__PURE__ */ new Date()).toISOString()
3462
+ } = context;
3463
+ return {
3464
+ reportKind: MIGRATION_REPORT_KIND,
3465
+ schemaVersion: MIGRATION_REPORT_SCHEMA_VERSION,
3466
+ generatedAt,
3467
+ tool: {
3468
+ name: toolName,
3469
+ version: toolVersion
3470
+ },
3471
+ cwd,
3472
+ dryRun,
3473
+ rollbackOnError,
3474
+ ...backupDirectory ? { backupDirectory } : {},
3475
+ scannedFiles: state.scannedFiles,
3476
+ changedFiles: state.changedFiles,
3477
+ writtenFiles: state.writtenFiles,
3478
+ backupsWritten: state.backupsWritten,
3479
+ unchangedFiles: state.unchangedFiles,
3480
+ missingFiles: state.missingFiles,
3481
+ entries: state.entries
3482
+ };
3483
+ }
3484
+
3485
+ // src/commands/migration-file-executor.ts
3486
+ import fs12 from "fs-extra";
3487
+ import path13 from "pathe";
3488
+
3489
+ // src/commands/migration-source.ts
3490
+ import generate2 from "@babel/generator";
3491
+ import { parse as parse2 } from "@babel/parser";
3492
+ import * as t5 from "@babel/types";
3375
3493
  var ROOT_LEGACY_KEYS = ["cwd", "overwrite", "tailwind", "features", "output", "applyPatches"];
3376
3494
  function getPropertyKeyName(property) {
3377
3495
  if (!property.computed && t5.isIdentifier(property.key)) {
@@ -3632,11 +3750,38 @@ function migrateConfigSource(source) {
3632
3750
  changes: [...changes]
3633
3751
  };
3634
3752
  }
3753
+
3754
+ // src/commands/migration-target-files.ts
3755
+ import fs11 from "fs-extra";
3756
+ import path12 from "pathe";
3757
+ var DEFAULT_CONFIG_FILENAMES = [
3758
+ "tailwindcss-patch.config.ts",
3759
+ "tailwindcss-patch.config.js",
3760
+ "tailwindcss-patch.config.mjs",
3761
+ "tailwindcss-patch.config.cjs",
3762
+ "tailwindcss-mangle.config.ts",
3763
+ "tailwindcss-mangle.config.js",
3764
+ "tailwindcss-mangle.config.mjs",
3765
+ "tailwindcss-mangle.config.cjs"
3766
+ ];
3767
+ var DEFAULT_CONFIG_FILENAME_SET = new Set(DEFAULT_CONFIG_FILENAMES);
3768
+ var DEFAULT_WORKSPACE_IGNORED_DIRS = /* @__PURE__ */ new Set([
3769
+ ".git",
3770
+ ".idea",
3771
+ ".turbo",
3772
+ ".vscode",
3773
+ ".yarn",
3774
+ "coverage",
3775
+ "dist",
3776
+ "node_modules",
3777
+ "tmp"
3778
+ ]);
3779
+ var DEFAULT_WORKSPACE_MAX_DEPTH = 6;
3635
3780
  function resolveTargetFiles(cwd, files) {
3636
3781
  const candidates = files && files.length > 0 ? files : [...DEFAULT_CONFIG_FILENAMES];
3637
3782
  const resolved = /* @__PURE__ */ new Set();
3638
3783
  for (const file of candidates) {
3639
- resolved.add(path11.resolve(cwd, file));
3784
+ resolved.add(path12.resolve(cwd, file));
3640
3785
  }
3641
3786
  return [...resolved];
3642
3787
  }
@@ -3656,7 +3801,7 @@ async function collectWorkspaceConfigFiles(cwd, maxDepth) {
3656
3801
  continue;
3657
3802
  }
3658
3803
  for (const entry of entries) {
3659
- const absolutePath = path11.resolve(dir, entry.name);
3804
+ const absolutePath = path12.resolve(dir, entry.name);
3660
3805
  if (entry.isFile() && DEFAULT_CONFIG_FILENAME_SET.has(entry.name)) {
3661
3806
  files.add(absolutePath);
3662
3807
  continue;
@@ -3676,11 +3821,11 @@ async function collectWorkspaceConfigFiles(cwd, maxDepth) {
3676
3821
  return [...files].sort((a, b) => a.localeCompare(b));
3677
3822
  }
3678
3823
  function resolveBackupRelativePath(cwd, file) {
3679
- const relative = path11.relative(cwd, file);
3680
- const isExternal = relative.startsWith("..") || path11.isAbsolute(relative);
3824
+ const relative = path12.relative(cwd, file);
3825
+ const isExternal = relative.startsWith("..") || path12.isAbsolute(relative);
3681
3826
  if (isExternal) {
3682
3827
  const sanitized = file.replace(/[:/\\]+/g, "_");
3683
- return path11.join("__external__", `${sanitized}.bak`);
3828
+ return path12.join("__external__", `${sanitized}.bak`);
3684
3829
  }
3685
3830
  return `${relative}.bak`;
3686
3831
  }
@@ -3720,8 +3865,8 @@ function toPatternList(patterns) {
3720
3865
  return patterns.map((pattern) => pattern.trim()).filter(Boolean).map(globToRegExp);
3721
3866
  }
3722
3867
  function normalizeFileForPattern(file, cwd) {
3723
- const relative = path11.relative(cwd, file);
3724
- if (!relative.startsWith("..") && !path11.isAbsolute(relative)) {
3868
+ const relative = path12.relative(cwd, file);
3869
+ if (!relative.startsWith("..") && !path12.isAbsolute(relative)) {
3725
3870
  return relative.replace(/\\/g, "/");
3726
3871
  }
3727
3872
  return file.replace(/\\/g, "/");
@@ -3742,114 +3887,85 @@ function filterTargetFiles(targetFiles, cwd, include, exclude) {
3742
3887
  return !inExclude;
3743
3888
  });
3744
3889
  }
3745
- async function migrateConfigFiles(options) {
3746
- const cwd = path11.resolve(options.cwd);
3747
- const dryRun = options.dryRun ?? false;
3748
- const rollbackOnError = options.rollbackOnError ?? true;
3749
- const backupDirectory = options.backupDir ? path11.resolve(cwd, options.backupDir) : void 0;
3750
- const maxDepth = options.maxDepth ?? DEFAULT_WORKSPACE_MAX_DEPTH;
3751
- const discoveredTargetFiles = options.files && options.files.length > 0 ? resolveTargetFiles(cwd, options.files) : options.workspace ? await collectWorkspaceConfigFiles(cwd, maxDepth) : resolveTargetFiles(cwd);
3752
- const targetFiles = filterTargetFiles(discoveredTargetFiles, cwd, options.include, options.exclude);
3753
- const entries = [];
3754
- let scannedFiles = 0;
3755
- let changedFiles = 0;
3756
- let writtenFiles = 0;
3757
- let backupsWritten = 0;
3758
- let unchangedFiles = 0;
3759
- let missingFiles = 0;
3760
- const wroteEntries = [];
3761
- for (const file of targetFiles) {
3762
- const exists = await fs11.pathExists(file);
3763
- if (!exists) {
3764
- missingFiles += 1;
3765
- continue;
3766
- }
3767
- scannedFiles += 1;
3768
- const source = await fs11.readFile(file, "utf8");
3769
- const migrated = migrateConfigSource(source);
3770
- const entry = {
3771
- file,
3772
- changed: migrated.changed,
3773
- written: false,
3774
- rolledBack: false,
3775
- changes: migrated.changes
3776
- };
3777
- entries.push(entry);
3778
- if (migrated.changed) {
3779
- changedFiles += 1;
3780
- if (!dryRun) {
3781
- try {
3782
- if (backupDirectory) {
3783
- const backupRelativePath = resolveBackupRelativePath(cwd, file);
3784
- const backupFile = path11.resolve(backupDirectory, backupRelativePath);
3785
- await fs11.ensureDir(path11.dirname(backupFile));
3786
- await fs11.writeFile(backupFile, source, "utf8");
3787
- entry.backupFile = backupFile;
3788
- backupsWritten += 1;
3789
- }
3790
- await fs11.writeFile(file, migrated.code, "utf8");
3791
- entry.written = true;
3792
- wroteEntries.push({ file, source, entry });
3793
- writtenFiles += 1;
3794
- } catch (error) {
3795
- let rollbackCount = 0;
3796
- if (rollbackOnError && wroteEntries.length > 0) {
3797
- for (const written of [...wroteEntries].reverse()) {
3798
- try {
3799
- await fs11.writeFile(written.file, written.source, "utf8");
3800
- written.entry.written = false;
3801
- written.entry.rolledBack = true;
3802
- rollbackCount += 1;
3803
- } catch {
3804
- }
3805
- }
3806
- writtenFiles = Math.max(0, writtenFiles - rollbackCount);
3807
- }
3808
- const reason = error instanceof Error ? error.message : String(error);
3809
- const rollbackHint = rollbackOnError && rollbackCount > 0 ? ` Rolled back ${rollbackCount} previously written file(s).` : "";
3810
- throw new Error(`Failed to write migrated config "${file}": ${reason}.${rollbackHint}`);
3811
- }
3812
- }
3813
- } else {
3814
- unchangedFiles += 1;
3890
+
3891
+ // src/commands/migration-file-executor.ts
3892
+ async function rollbackWrittenEntries(wroteEntries) {
3893
+ let rollbackCount = 0;
3894
+ for (const written of [...wroteEntries].reverse()) {
3895
+ try {
3896
+ await fs12.writeFile(written.file, written.source, "utf8");
3897
+ written.entry.written = false;
3898
+ written.entry.rolledBack = true;
3899
+ rollbackCount += 1;
3900
+ } catch {
3815
3901
  }
3816
3902
  }
3817
- return {
3818
- reportKind: MIGRATION_REPORT_KIND,
3819
- schemaVersion: MIGRATION_REPORT_SCHEMA_VERSION,
3820
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
3821
- tool: {
3822
- name: pkgName,
3823
- version: pkgVersion
3824
- },
3903
+ return rollbackCount;
3904
+ }
3905
+ async function executeMigrationFile(options) {
3906
+ const {
3825
3907
  cwd,
3908
+ file,
3826
3909
  dryRun,
3827
3910
  rollbackOnError,
3828
- ...backupDirectory ? { backupDirectory } : {},
3829
- scannedFiles,
3830
- changedFiles,
3831
- writtenFiles,
3832
- backupsWritten,
3833
- unchangedFiles,
3834
- missingFiles,
3835
- entries
3911
+ backupDirectory,
3912
+ wroteEntries
3913
+ } = options;
3914
+ const exists = await fs12.pathExists(file);
3915
+ if (!exists) {
3916
+ return {
3917
+ missing: true,
3918
+ changed: false,
3919
+ wrote: false,
3920
+ backupWritten: false
3921
+ };
3922
+ }
3923
+ const source = await fs12.readFile(file, "utf8");
3924
+ const migrated = migrateConfigSource(source);
3925
+ const entry = {
3926
+ file,
3927
+ changed: migrated.changed,
3928
+ written: false,
3929
+ rolledBack: false,
3930
+ changes: migrated.changes
3836
3931
  };
3837
- }
3838
- async function restoreConfigFiles(options) {
3839
- const cwd = path11.resolve(options.cwd);
3840
- const dryRun = options.dryRun ?? false;
3841
- const strict = options.strict ?? false;
3842
- const reportFile = path11.resolve(cwd, options.reportFile);
3843
- const report = await fs11.readJSON(reportFile);
3844
- if (report.reportKind !== void 0 && report.reportKind !== MIGRATION_REPORT_KIND) {
3845
- throw new Error(`Unsupported report kind "${report.reportKind}" in ${reportFile}.`);
3932
+ if (!migrated.changed || dryRun) {
3933
+ return {
3934
+ missing: false,
3935
+ changed: migrated.changed,
3936
+ wrote: false,
3937
+ backupWritten: false,
3938
+ entry
3939
+ };
3846
3940
  }
3847
- if (report.schemaVersion !== void 0 && (!Number.isInteger(report.schemaVersion) || report.schemaVersion > MIGRATION_REPORT_SCHEMA_VERSION)) {
3848
- throw new Error(
3849
- `Unsupported report schema version "${String(report.schemaVersion)}" in ${reportFile}. Current supported version is ${MIGRATION_REPORT_SCHEMA_VERSION}.`
3850
- );
3941
+ let backupWritten = false;
3942
+ try {
3943
+ if (backupDirectory) {
3944
+ const backupRelativePath = resolveBackupRelativePath(cwd, file);
3945
+ const backupFile = path13.resolve(backupDirectory, backupRelativePath);
3946
+ await fs12.ensureDir(path13.dirname(backupFile));
3947
+ await fs12.writeFile(backupFile, source, "utf8");
3948
+ entry.backupFile = backupFile;
3949
+ backupWritten = true;
3950
+ }
3951
+ await fs12.writeFile(file, migrated.code, "utf8");
3952
+ entry.written = true;
3953
+ wroteEntries.push({ file, source, entry });
3954
+ return {
3955
+ missing: false,
3956
+ changed: true,
3957
+ wrote: true,
3958
+ backupWritten,
3959
+ entry
3960
+ };
3961
+ } catch (error) {
3962
+ const rollbackCount = rollbackOnError && wroteEntries.length > 0 ? await rollbackWrittenEntries(wroteEntries) : 0;
3963
+ const reason = error instanceof Error ? error.message : String(error);
3964
+ const rollbackHint = rollbackOnError && rollbackCount > 0 ? ` Rolled back ${rollbackCount} previously written file(s).` : "";
3965
+ throw new Error(`Failed to write migrated config "${file}": ${reason}.${rollbackHint}`);
3851
3966
  }
3852
- const entries = Array.isArray(report.entries) ? report.entries : [];
3967
+ }
3968
+ async function restoreConfigEntries(entries, dryRun) {
3853
3969
  let scannedEntries = 0;
3854
3970
  let restorableEntries = 0;
3855
3971
  let restoredFiles = 0;
@@ -3858,26 +3974,113 @@ async function restoreConfigFiles(options) {
3858
3974
  const restored = [];
3859
3975
  for (const entry of entries) {
3860
3976
  scannedEntries += 1;
3861
- const targetFile = entry.file ? path11.resolve(entry.file) : void 0;
3862
- const backupFile = entry.backupFile ? path11.resolve(entry.backupFile) : void 0;
3977
+ const targetFile = entry.file ? path13.resolve(entry.file) : void 0;
3978
+ const backupFile = entry.backupFile ? path13.resolve(entry.backupFile) : void 0;
3863
3979
  if (!targetFile || !backupFile) {
3864
3980
  skippedEntries += 1;
3865
3981
  continue;
3866
3982
  }
3867
3983
  restorableEntries += 1;
3868
- const backupExists = await fs11.pathExists(backupFile);
3984
+ const backupExists = await fs12.pathExists(backupFile);
3869
3985
  if (!backupExists) {
3870
3986
  missingBackups += 1;
3871
3987
  continue;
3872
3988
  }
3873
3989
  if (!dryRun) {
3874
- const backupContent = await fs11.readFile(backupFile, "utf8");
3875
- await fs11.ensureDir(path11.dirname(targetFile));
3876
- await fs11.writeFile(targetFile, backupContent, "utf8");
3990
+ const backupContent = await fs12.readFile(backupFile, "utf8");
3991
+ await fs12.ensureDir(path13.dirname(targetFile));
3992
+ await fs12.writeFile(targetFile, backupContent, "utf8");
3877
3993
  }
3878
3994
  restoredFiles += 1;
3879
3995
  restored.push(targetFile);
3880
3996
  }
3997
+ return {
3998
+ scannedEntries,
3999
+ restorableEntries,
4000
+ restoredFiles,
4001
+ missingBackups,
4002
+ skippedEntries,
4003
+ restored
4004
+ };
4005
+ }
4006
+
4007
+ // src/commands/migration-report-loader.ts
4008
+ import fs13 from "fs-extra";
4009
+ async function loadMigrationReportForRestore(reportFile) {
4010
+ const report = await fs13.readJSON(reportFile);
4011
+ assertMigrationReportCompatibility(report, reportFile);
4012
+ return {
4013
+ ...report.reportKind === void 0 ? {} : { reportKind: report.reportKind },
4014
+ ...report.schemaVersion === void 0 ? {} : { schemaVersion: report.schemaVersion },
4015
+ entries: Array.isArray(report.entries) ? report.entries : []
4016
+ };
4017
+ }
4018
+
4019
+ // src/commands/migration-target-resolver.ts
4020
+ async function resolveMigrationTargetFiles(options) {
4021
+ const {
4022
+ cwd,
4023
+ files,
4024
+ workspace,
4025
+ maxDepth,
4026
+ include,
4027
+ exclude
4028
+ } = options;
4029
+ const resolvedMaxDepth = maxDepth ?? DEFAULT_WORKSPACE_MAX_DEPTH;
4030
+ const discoveredTargetFiles = files && files.length > 0 ? resolveTargetFiles(cwd, files) : workspace ? await collectWorkspaceConfigFiles(cwd, resolvedMaxDepth) : resolveTargetFiles(cwd);
4031
+ return filterTargetFiles(discoveredTargetFiles, cwd, include, exclude);
4032
+ }
4033
+
4034
+ // src/commands/migrate-config.ts
4035
+ async function migrateConfigFiles(options) {
4036
+ const cwd = path14.resolve(options.cwd);
4037
+ const dryRun = options.dryRun ?? false;
4038
+ const rollbackOnError = options.rollbackOnError ?? true;
4039
+ const backupDirectory = options.backupDir ? path14.resolve(cwd, options.backupDir) : void 0;
4040
+ const targetFiles = await resolveMigrationTargetFiles({
4041
+ cwd,
4042
+ files: options.files,
4043
+ workspace: options.workspace,
4044
+ maxDepth: options.maxDepth,
4045
+ include: options.include,
4046
+ exclude: options.exclude
4047
+ });
4048
+ const aggregation = createMigrationAggregationState();
4049
+ const wroteEntries = [];
4050
+ for (const file of targetFiles) {
4051
+ const result = await executeMigrationFile({
4052
+ cwd,
4053
+ file,
4054
+ dryRun,
4055
+ rollbackOnError,
4056
+ wroteEntries,
4057
+ ...backupDirectory ? { backupDirectory } : {}
4058
+ });
4059
+ collectMigrationExecutionResult(aggregation, result);
4060
+ }
4061
+ return buildMigrationReport(aggregation, {
4062
+ cwd,
4063
+ dryRun,
4064
+ rollbackOnError,
4065
+ ...backupDirectory ? { backupDirectory } : {},
4066
+ toolName: pkgName,
4067
+ toolVersion: pkgVersion
4068
+ });
4069
+ }
4070
+ async function restoreConfigFiles(options) {
4071
+ const cwd = path14.resolve(options.cwd);
4072
+ const dryRun = options.dryRun ?? false;
4073
+ const strict = options.strict ?? false;
4074
+ const reportFile = path14.resolve(cwd, options.reportFile);
4075
+ const report = await loadMigrationReportForRestore(reportFile);
4076
+ const {
4077
+ scannedEntries,
4078
+ restorableEntries,
4079
+ restoredFiles,
4080
+ missingBackups,
4081
+ skippedEntries,
4082
+ restored
4083
+ } = await restoreConfigEntries(report.entries, dryRun);
3881
4084
  if (strict && missingBackups > 0) {
3882
4085
  throw new Error(`Restore failed: ${missingBackups} backup file(s) missing in report ${reportFile}.`);
3883
4086
  }
@@ -3897,105 +4100,7 @@ async function restoreConfigFiles(options) {
3897
4100
  };
3898
4101
  }
3899
4102
 
3900
- // src/cli/commands.ts
3901
- import process7 from "process";
3902
- import { CONFIG_NAME, getConfig, initConfig } from "@tailwindcss-mangle/config";
3903
-
3904
- // ../../node_modules/.pnpm/defu@6.1.4/node_modules/defu/dist/defu.mjs
3905
- function isPlainObject(value) {
3906
- if (value === null || typeof value !== "object") {
3907
- return false;
3908
- }
3909
- const prototype = Object.getPrototypeOf(value);
3910
- if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
3911
- return false;
3912
- }
3913
- if (Symbol.iterator in value) {
3914
- return false;
3915
- }
3916
- if (Symbol.toStringTag in value) {
3917
- return Object.prototype.toString.call(value) === "[object Module]";
3918
- }
3919
- return true;
3920
- }
3921
- function _defu(baseObject, defaults, namespace = ".", merger) {
3922
- if (!isPlainObject(defaults)) {
3923
- return _defu(baseObject, {}, namespace, merger);
3924
- }
3925
- const object = Object.assign({}, defaults);
3926
- for (const key in baseObject) {
3927
- if (key === "__proto__" || key === "constructor") {
3928
- continue;
3929
- }
3930
- const value = baseObject[key];
3931
- if (value === null || value === void 0) {
3932
- continue;
3933
- }
3934
- if (merger && merger(object, key, value, namespace)) {
3935
- continue;
3936
- }
3937
- if (Array.isArray(value) && Array.isArray(object[key])) {
3938
- object[key] = [...value, ...object[key]];
3939
- } else if (isPlainObject(value) && isPlainObject(object[key])) {
3940
- object[key] = _defu(
3941
- value,
3942
- object[key],
3943
- (namespace ? `${namespace}.` : "") + key.toString(),
3944
- merger
3945
- );
3946
- } else {
3947
- object[key] = value;
3948
- }
3949
- }
3950
- return object;
3951
- }
3952
- function createDefu(merger) {
3953
- return (...arguments_) => (
3954
- // eslint-disable-next-line unicorn/no-array-reduce
3955
- arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
3956
- );
3957
- }
3958
- var defu = createDefu();
3959
- var defuFn = createDefu((object, key, currentValue) => {
3960
- if (object[key] !== void 0 && typeof currentValue === "function") {
3961
- object[key] = currentValue(object[key]);
3962
- return true;
3963
- }
3964
- });
3965
- var defuArrayFn = createDefu((object, key, currentValue) => {
3966
- if (Array.isArray(object[key]) && typeof currentValue === "function") {
3967
- object[key] = currentValue(object[key]);
3968
- return true;
3969
- }
3970
- });
3971
-
3972
- // ../shared/src/utils.ts
3973
- var defuOverrideArray = createDefu((obj, key, value) => {
3974
- if (Array.isArray(obj[key]) && Array.isArray(value)) {
3975
- obj[key] = value;
3976
- return true;
3977
- }
3978
- });
3979
- var preserveClassNames = [
3980
- // https://tailwindcss.com/docs/transition-timing-function start
3981
- // https://github.com/sonofmagic/tailwindcss-mangle/issues/21
3982
- "ease-out",
3983
- "ease-linear",
3984
- "ease-in",
3985
- "ease-in-out"
3986
- // https://tailwindcss.com/docs/transition-timing-function end
3987
- ];
3988
- var preserveClassNamesMap = preserveClassNames.reduce((acc, cur) => {
3989
- acc[cur] = true;
3990
- return acc;
3991
- }, {});
3992
- var acceptChars = [..."abcdefghijklmnopqrstuvwxyz"];
3993
-
3994
- // src/cli/commands.ts
3995
- import cac from "cac";
3996
- import fs12 from "fs-extra";
3997
- import path12 from "pathe";
3998
- var tailwindcssPatchCommands = ["install", "extract", "tokens", "init", "migrate", "restore", "validate", "status"];
4103
+ // src/commands/validate.ts
3999
4104
  var VALIDATE_EXIT_CODES = {
4000
4105
  OK: 0,
4001
4106
  REPORT_INCOMPATIBLE: 21,
@@ -4010,7 +4115,7 @@ var VALIDATE_FAILURE_REASONS = [
4010
4115
  "unknown-error"
4011
4116
  ];
4012
4117
  var IO_ERROR_CODES = /* @__PURE__ */ new Set(["ENOENT", "EACCES", "EPERM", "EISDIR", "ENOTDIR", "EMFILE", "ENFILE"]);
4013
- function isNodeError(error) {
4118
+ function isNodeError2(error) {
4014
4119
  return !!error && typeof error === "object" && ("code" in error || "message" in error);
4015
4120
  }
4016
4121
  function classifyValidateError(error) {
@@ -4029,7 +4134,7 @@ function classifyValidateError(error) {
4029
4134
  message
4030
4135
  };
4031
4136
  }
4032
- if (isNodeError(error) && typeof error.code === "string" && IO_ERROR_CODES.has(error.code)) {
4137
+ if (isNodeError2(error) && typeof error.code === "string" && IO_ERROR_CODES.has(error.code)) {
4033
4138
  return {
4034
4139
  reason: "io-error",
4035
4140
  exitCode: VALIDATE_EXIT_CODES.IO_ERROR,
@@ -4052,6 +4157,17 @@ var ValidateCommandError = class extends Error {
4052
4157
  this.exitCode = summary.exitCode;
4053
4158
  }
4054
4159
  };
4160
+
4161
+ // src/commands/types.ts
4162
+ var tailwindcssPatchCommands = ["install", "extract", "tokens", "init", "migrate", "restore", "validate", "status"];
4163
+
4164
+ // src/commands/cli.ts
4165
+ import cac from "cac";
4166
+
4167
+ // src/commands/command-definitions.ts
4168
+ import process7 from "process";
4169
+
4170
+ // src/commands/token-output.ts
4055
4171
  var TOKEN_FORMATS = ["json", "lines", "grouped-json"];
4056
4172
  var DEFAULT_TOKEN_REPORT = ".tw-patch/tw-token-report.json";
4057
4173
  function formatTokenLine(entry) {
@@ -4073,68 +4189,8 @@ function formatGroupedPreview(map, limit = 3) {
4073
4189
  moreFiles: Math.max(0, files.length - limit)
4074
4190
  };
4075
4191
  }
4076
- function resolveCwd(rawCwd) {
4077
- if (!rawCwd) {
4078
- return process7.cwd();
4079
- }
4080
- return path12.resolve(rawCwd);
4081
- }
4082
- function createDefaultRunner(factory) {
4083
- let promise;
4084
- return () => {
4085
- if (!promise) {
4086
- promise = factory();
4087
- }
4088
- return promise;
4089
- };
4090
- }
4091
- async function loadPatchOptionsForCwd(cwd, overrides) {
4092
- const { config } = await getConfig(cwd);
4093
- const legacyConfig = config;
4094
- const base = config?.registry ? fromUnifiedConfig(config.registry) : legacyConfig?.patch ? fromLegacyOptions({ patch: legacyConfig.patch }) : {};
4095
- const merged = defu(overrides ?? {}, base);
4096
- return merged;
4097
- }
4098
- function createCommandContext(cli, command, commandName, args, cwd) {
4099
- let cachedOptions;
4100
- let cachedPatcher;
4101
- let cachedConfig;
4102
- const loadPatchOptionsForContext = (overrides) => {
4103
- if (overrides) {
4104
- return loadPatchOptionsForCwd(cwd, overrides);
4105
- }
4106
- if (!cachedOptions) {
4107
- cachedOptions = loadPatchOptionsForCwd(cwd);
4108
- }
4109
- return cachedOptions;
4110
- };
4111
- const createPatcherForContext = async (overrides) => {
4112
- if (overrides) {
4113
- const patchOptions = await loadPatchOptionsForCwd(cwd, overrides);
4114
- return new TailwindcssPatcher(patchOptions);
4115
- }
4116
- if (!cachedPatcher) {
4117
- cachedPatcher = loadPatchOptionsForContext().then((options) => new TailwindcssPatcher(options));
4118
- }
4119
- return cachedPatcher;
4120
- };
4121
- return {
4122
- cli,
4123
- command,
4124
- commandName,
4125
- args,
4126
- cwd,
4127
- logger: logger_default,
4128
- loadConfig: () => {
4129
- if (!cachedConfig) {
4130
- cachedConfig = getConfig(cwd);
4131
- }
4132
- return cachedConfig;
4133
- },
4134
- loadPatchOptions: loadPatchOptionsForContext,
4135
- createPatcher: createPatcherForContext
4136
- };
4137
- }
4192
+
4193
+ // src/commands/command-definitions.ts
4138
4194
  function createCwdOptionDefinition(description = "Working directory") {
4139
4195
  return {
4140
4196
  flags: "--cwd <dir>",
@@ -4224,6 +4280,8 @@ function buildDefaultCommandDefinitions() {
4224
4280
  }
4225
4281
  };
4226
4282
  }
4283
+
4284
+ // src/commands/command-metadata.ts
4227
4285
  function addPrefixIfMissing(value, prefix) {
4228
4286
  if (!prefix || value.startsWith(prefix)) {
4229
4287
  return value;
@@ -4251,30 +4309,93 @@ function resolveOptionDefinitions(defaults, override) {
4251
4309
  }
4252
4310
  return [...defaults, ...customDefs];
4253
4311
  }
4254
- function applyCommandOptions(command, optionDefs) {
4255
- for (const option of optionDefs) {
4256
- command.option(option.flags, option.description ?? "", option.config);
4257
- }
4312
+ function resolveCommandMetadata(command, mountOptions, prefix, defaults) {
4313
+ const names = resolveCommandNames(command, mountOptions, prefix);
4314
+ const definition = defaults[command];
4315
+ const override = mountOptions.commandOptions?.[command];
4316
+ const description = override?.description ?? definition.description;
4317
+ const optionDefs = resolveOptionDefinitions(definition.optionDefs, override);
4318
+ return { ...names, description, optionDefs };
4319
+ }
4320
+ function applyCommandOptions(command, optionDefs) {
4321
+ for (const option of optionDefs) {
4322
+ command.option(option.flags, option.description ?? "", option.config);
4323
+ }
4324
+ }
4325
+
4326
+ // src/commands/command-context.ts
4327
+ import process8 from "process";
4328
+ import path15 from "pathe";
4329
+ function resolveCommandCwd(rawCwd) {
4330
+ if (!rawCwd) {
4331
+ return process8.cwd();
4332
+ }
4333
+ return path15.resolve(rawCwd);
4334
+ }
4335
+ function createMemoizedPromiseRunner(factory) {
4336
+ let promise;
4337
+ return () => {
4338
+ if (!promise) {
4339
+ promise = factory();
4340
+ }
4341
+ return promise;
4342
+ };
4343
+ }
4344
+ function createTailwindcssPatchCommandContext(cli, command, commandName, args, cwd) {
4345
+ const loadCachedConfig = createMemoizedPromiseRunner(
4346
+ () => loadWorkspaceConfigModule().then((mod) => mod.getConfig(cwd))
4347
+ );
4348
+ const loadCachedPatchOptions = createMemoizedPromiseRunner(
4349
+ () => loadPatchOptionsForWorkspace(cwd)
4350
+ );
4351
+ const createCachedPatcher = createMemoizedPromiseRunner(async () => {
4352
+ const patchOptions = await loadCachedPatchOptions();
4353
+ return new TailwindcssPatcher(patchOptions);
4354
+ });
4355
+ const loadPatchOptionsForContext = (overrides) => {
4356
+ if (overrides) {
4357
+ return loadPatchOptionsForWorkspace(cwd, overrides);
4358
+ }
4359
+ return loadCachedPatchOptions();
4360
+ };
4361
+ const createPatcherForContext = async (overrides) => {
4362
+ if (overrides) {
4363
+ const patchOptions = await loadPatchOptionsForWorkspace(cwd, overrides);
4364
+ return new TailwindcssPatcher(patchOptions);
4365
+ }
4366
+ return createCachedPatcher();
4367
+ };
4368
+ return {
4369
+ cli,
4370
+ command,
4371
+ commandName,
4372
+ args,
4373
+ cwd,
4374
+ logger: logger_default,
4375
+ loadConfig: loadCachedConfig,
4376
+ loadPatchOptions: loadPatchOptionsForContext,
4377
+ createPatcher: createPatcherForContext
4378
+ };
4258
4379
  }
4380
+
4381
+ // src/commands/command-runtime.ts
4259
4382
  function runWithCommandHandler(cli, command, commandName, args, handler, defaultHandler) {
4260
- const cwd = resolveCwd(args.cwd);
4261
- const context = createCommandContext(cli, command, commandName, args, cwd);
4262
- const runDefault = createDefaultRunner(() => defaultHandler(context));
4383
+ const cwd = resolveCommandCwd(args.cwd);
4384
+ const context = createTailwindcssPatchCommandContext(cli, command, commandName, args, cwd);
4385
+ const runDefault = createMemoizedPromiseRunner(() => defaultHandler(context));
4263
4386
  if (!handler) {
4264
4387
  return runDefault();
4265
4388
  }
4266
4389
  return handler(context, runDefault);
4267
4390
  }
4268
- function resolveCommandMetadata(command, mountOptions, prefix, defaults) {
4269
- const names = resolveCommandNames(command, mountOptions, prefix);
4270
- const definition = defaults[command];
4271
- const override = mountOptions.commandOptions?.[command];
4272
- const description = override?.description ?? definition.description;
4273
- const optionDefs = resolveOptionDefinitions(definition.optionDefs, override);
4274
- return { ...names, description, optionDefs };
4275
- }
4276
- async function installCommandDefaultHandler(ctx) {
4277
- const patcher = await ctx.createPatcher();
4391
+
4392
+ // src/commands/basic-handlers.ts
4393
+ import process9 from "process";
4394
+ import fs14 from "fs-extra";
4395
+ import path16 from "pathe";
4396
+ var DEFAULT_CONFIG_NAME = "tailwindcss-mangle";
4397
+ async function installCommandDefaultHandler(_ctx) {
4398
+ const patcher = new TailwindcssPatcher();
4278
4399
  await patcher.patch();
4279
4400
  logger_default.success("Tailwind CSS runtime patched successfully.");
4280
4401
  }
@@ -4325,18 +4446,18 @@ async function tokensCommandDefaultHandler(ctx) {
4325
4446
  const grouped = format === "grouped-json" ? buildGrouped() : null;
4326
4447
  const resolveGrouped = () => grouped ?? buildGrouped();
4327
4448
  if (shouldWrite) {
4328
- const target = path12.resolve(targetFile);
4329
- await fs12.ensureDir(path12.dirname(target));
4449
+ const target = path16.resolve(targetFile);
4450
+ await fs14.ensureDir(path16.dirname(target));
4330
4451
  if (format === "json") {
4331
- await fs12.writeJSON(target, report, { spaces: 2 });
4452
+ await fs14.writeJSON(target, report, { spaces: 2 });
4332
4453
  } else if (format === "grouped-json") {
4333
- await fs12.writeJSON(target, resolveGrouped(), { spaces: 2 });
4454
+ await fs14.writeJSON(target, resolveGrouped(), { spaces: 2 });
4334
4455
  } else {
4335
4456
  const lines = report.entries.map(formatTokenLine);
4336
- await fs12.writeFile(target, `${lines.join("\n")}
4457
+ await fs14.writeFile(target, `${lines.join("\n")}
4337
4458
  `, "utf8");
4338
4459
  }
4339
- logger_default.success(`Collected ${report.entries.length} tokens (${format}) \u2192 ${target.replace(process7.cwd(), ".")}`);
4460
+ logger_default.success(`Collected ${report.entries.length} tokens (${format}) \u2192 ${target.replace(process9.cwd(), ".")}`);
4340
4461
  } else {
4341
4462
  logger_default.success(`Collected ${report.entries.length} tokens from ${report.filesScanned} files.`);
4342
4463
  if (format === "lines") {
@@ -4375,60 +4496,94 @@ async function tokensCommandDefaultHandler(ctx) {
4375
4496
  return report;
4376
4497
  }
4377
4498
  async function initCommandDefaultHandler(ctx) {
4378
- await initConfig(ctx.cwd);
4379
- logger_default.success(`\u2728 ${CONFIG_NAME}.config.ts initialized!`);
4499
+ const configModule = await loadWorkspaceConfigModule();
4500
+ await configModule.initConfig(ctx.cwd);
4501
+ const configName = configModule.CONFIG_NAME || DEFAULT_CONFIG_NAME;
4502
+ logger_default.success(`\u2728 ${configName}.config.ts initialized!`);
4380
4503
  }
4381
- async function migrateCommandDefaultHandler(ctx) {
4382
- const { args } = ctx;
4383
- const normalizePatternArgs = (value) => {
4384
- if (!value) {
4385
- return void 0;
4386
- }
4387
- const raw = Array.isArray(value) ? value : [value];
4388
- const values = raw.flatMap((item) => item.split(",")).map((item) => item.trim()).filter(Boolean);
4389
- return values.length > 0 ? values : void 0;
4504
+
4505
+ // src/commands/migration-args.ts
4506
+ function normalizePatternArgs(value) {
4507
+ if (!value) {
4508
+ return void 0;
4509
+ }
4510
+ const raw = Array.isArray(value) ? value : [value];
4511
+ const values = raw.flatMap((item) => item.split(",")).map((item) => item.trim()).filter(Boolean);
4512
+ return values.length > 0 ? values : void 0;
4513
+ }
4514
+ function parseMaxDepth(value) {
4515
+ if (value === void 0) {
4516
+ return {
4517
+ maxDepth: void 0,
4518
+ hasInvalidMaxDepth: false
4519
+ };
4520
+ }
4521
+ const parsed = Number(value);
4522
+ if (!Number.isFinite(parsed) || parsed < 0) {
4523
+ return {
4524
+ maxDepth: void 0,
4525
+ hasInvalidMaxDepth: true
4526
+ };
4527
+ }
4528
+ return {
4529
+ maxDepth: Math.floor(parsed),
4530
+ hasInvalidMaxDepth: false
4390
4531
  };
4532
+ }
4533
+ function resolveMigrateCommandArgs(args) {
4391
4534
  const include = normalizePatternArgs(args.include);
4392
4535
  const exclude = normalizePatternArgs(args.exclude);
4393
- const parsedMaxDepth = args.maxDepth === void 0 ? void 0 : Number(args.maxDepth);
4394
- const maxDepth = parsedMaxDepth !== void 0 && Number.isFinite(parsedMaxDepth) && parsedMaxDepth >= 0 ? Math.floor(parsedMaxDepth) : void 0;
4536
+ const { maxDepth, hasInvalidMaxDepth } = parseMaxDepth(args.maxDepth);
4395
4537
  const checkMode = args.check ?? false;
4396
4538
  const dryRun = args.dryRun ?? checkMode;
4397
- if (args.workspace && args.maxDepth !== void 0 && maxDepth === void 0) {
4398
- logger_default.warn(`Invalid --max-depth value "${String(args.maxDepth)}", fallback to default depth.`);
4399
- }
4400
- const report = await migrateConfigFiles({
4401
- cwd: ctx.cwd,
4539
+ return {
4540
+ include,
4541
+ exclude,
4542
+ maxDepth,
4543
+ checkMode,
4402
4544
  dryRun,
4403
- ...args.config ? { files: [args.config] } : {},
4404
- ...args.workspace ? { workspace: true } : {},
4405
- ...args.workspace && maxDepth !== void 0 ? { maxDepth } : {},
4406
- ...args.backupDir ? { backupDir: args.backupDir } : {},
4407
- ...include ? { include } : {},
4408
- ...exclude ? { exclude } : {}
4409
- });
4410
- if (args.reportFile) {
4411
- const reportPath = path12.resolve(ctx.cwd, args.reportFile);
4412
- await fs12.ensureDir(path12.dirname(reportPath));
4413
- await fs12.writeJSON(reportPath, report, { spaces: 2 });
4414
- logger_default.info(`Migration report written: ${reportPath.replace(process7.cwd(), ".")}`);
4415
- }
4416
- if (args.json) {
4417
- logger_default.log(JSON.stringify(report, null, 2));
4418
- if (checkMode && report.changedFiles > 0) {
4419
- throw new Error(`Migration check failed: ${report.changedFiles} file(s) still need migration.`);
4420
- }
4421
- if (report.scannedFiles === 0) {
4422
- logger_default.warn("No config files found for migration.");
4423
- }
4424
- return report;
4425
- }
4426
- if (report.scannedFiles === 0) {
4427
- logger_default.warn("No config files found for migration.");
4428
- return report;
4429
- }
4545
+ hasInvalidMaxDepth
4546
+ };
4547
+ }
4548
+ function resolveRestoreCommandArgs(args) {
4549
+ return {
4550
+ reportFile: args.reportFile ?? ".tw-patch/migrate-report.json",
4551
+ dryRun: args.dryRun ?? false,
4552
+ strict: args.strict ?? false
4553
+ };
4554
+ }
4555
+ function resolveValidateCommandArgs(args) {
4556
+ return {
4557
+ reportFile: args.reportFile ?? ".tw-patch/migrate-report.json",
4558
+ strict: args.strict ?? false
4559
+ };
4560
+ }
4561
+
4562
+ // src/commands/migration-output.ts
4563
+ import process10 from "process";
4564
+ import fs15 from "fs-extra";
4565
+ import path17 from "pathe";
4566
+ function formatPathForLog(file) {
4567
+ return file.replace(process10.cwd(), ".");
4568
+ }
4569
+ function createMigrationCheckFailureError(changedFiles) {
4570
+ return new Error(`Migration check failed: ${changedFiles} file(s) still need migration.`);
4571
+ }
4572
+ async function writeMigrationReportFile(cwd, reportFile, report) {
4573
+ const reportPath = path17.resolve(cwd, reportFile);
4574
+ await fs15.ensureDir(path17.dirname(reportPath));
4575
+ await fs15.writeJSON(reportPath, report, { spaces: 2 });
4576
+ logger_default.info(`Migration report written: ${formatPathForLog(reportPath)}`);
4577
+ }
4578
+ function logMigrationReportAsJson(report) {
4579
+ logger_default.log(JSON.stringify(report, null, 2));
4580
+ }
4581
+ function logNoMigrationConfigFilesWarning() {
4582
+ logger_default.warn("No config files found for migration.");
4583
+ }
4584
+ function logMigrationEntries(report, dryRun) {
4430
4585
  for (const entry of report.entries) {
4431
- const fileLabel = entry.file.replace(process7.cwd(), ".");
4586
+ const fileLabel = formatPathForLog(entry.file);
4432
4587
  if (!entry.changed) {
4433
4588
  logger_default.info(`No changes: ${fileLabel}`);
4434
4589
  continue;
@@ -4442,105 +4597,156 @@ async function migrateCommandDefaultHandler(ctx) {
4442
4597
  logger_default.info(` - ${change}`);
4443
4598
  }
4444
4599
  if (entry.backupFile) {
4445
- logger_default.info(` - backup: ${entry.backupFile.replace(process7.cwd(), ".")}`);
4600
+ logger_default.info(` - backup: ${formatPathForLog(entry.backupFile)}`);
4446
4601
  }
4447
4602
  }
4603
+ }
4604
+ function logMigrationSummary(report) {
4448
4605
  logger_default.info(
4449
4606
  `Migration summary: scanned=${report.scannedFiles}, changed=${report.changedFiles}, written=${report.writtenFiles}, backups=${report.backupsWritten}, missing=${report.missingFiles}, unchanged=${report.unchangedFiles}`
4450
4607
  );
4451
- if (checkMode && report.changedFiles > 0) {
4452
- throw new Error(`Migration check failed: ${report.changedFiles} file(s) still need migration.`);
4453
- }
4454
- return report;
4455
4608
  }
4456
- async function restoreCommandDefaultHandler(ctx) {
4457
- const { args } = ctx;
4458
- const reportFile = args.reportFile ?? ".tw-patch/migrate-report.json";
4459
- const result = await restoreConfigFiles({
4460
- cwd: ctx.cwd,
4461
- reportFile,
4462
- dryRun: args.dryRun ?? false,
4463
- strict: args.strict ?? false
4464
- });
4465
- if (args.json) {
4466
- logger_default.log(JSON.stringify(result, null, 2));
4467
- return result;
4468
- }
4609
+ function logRestoreResultAsJson(result) {
4610
+ logger_default.log(JSON.stringify(result, null, 2));
4611
+ }
4612
+ function logRestoreSummary(result) {
4469
4613
  logger_default.info(
4470
4614
  `Restore summary: scanned=${result.scannedEntries}, restorable=${result.restorableEntries}, restored=${result.restoredFiles}, missingBackups=${result.missingBackups}, skipped=${result.skippedEntries}`
4471
4615
  );
4472
4616
  if (result.restored.length > 0) {
4473
4617
  const preview = result.restored.slice(0, 5);
4474
4618
  for (const file of preview) {
4475
- logger_default.info(` - ${file.replace(process7.cwd(), ".")}`);
4619
+ logger_default.info(` - ${formatPathForLog(file)}`);
4476
4620
  }
4477
4621
  if (result.restored.length > preview.length) {
4478
4622
  logger_default.info(` ...and ${result.restored.length - preview.length} more`);
4479
4623
  }
4480
4624
  }
4481
- return result;
4482
4625
  }
4483
- async function validateCommandDefaultHandler(ctx) {
4626
+ function logValidateSuccessAsJson(result) {
4627
+ const payload = {
4628
+ ok: true,
4629
+ ...result
4630
+ };
4631
+ logger_default.log(JSON.stringify(payload, null, 2));
4632
+ }
4633
+ function logValidateSuccessSummary(result) {
4634
+ logger_default.success(
4635
+ `Migration report validated: scanned=${result.scannedEntries}, restorable=${result.restorableEntries}, missingBackups=${result.missingBackups}, skipped=${result.skippedEntries}`
4636
+ );
4637
+ if (result.reportKind || result.reportSchemaVersion !== void 0) {
4638
+ const kind = result.reportKind ?? "unknown";
4639
+ const schema = result.reportSchemaVersion === void 0 ? "unknown" : String(result.reportSchemaVersion);
4640
+ logger_default.info(` metadata: kind=${kind}, schema=${schema}`);
4641
+ }
4642
+ }
4643
+ function logValidateFailureAsJson(summary) {
4644
+ const payload = {
4645
+ ok: false,
4646
+ reason: summary.reason,
4647
+ exitCode: summary.exitCode,
4648
+ message: summary.message
4649
+ };
4650
+ logger_default.log(JSON.stringify(payload, null, 2));
4651
+ }
4652
+ function logValidateFailureSummary(summary) {
4653
+ logger_default.error(`Validation failed [${summary.reason}] (exit ${summary.exitCode}): ${summary.message}`);
4654
+ }
4655
+
4656
+ // src/commands/migrate-handler.ts
4657
+ async function migrateCommandDefaultHandler(ctx) {
4484
4658
  const { args } = ctx;
4485
- const reportFile = args.reportFile ?? ".tw-patch/migrate-report.json";
4486
- try {
4487
- const result = await restoreConfigFiles({
4488
- cwd: ctx.cwd,
4489
- reportFile,
4490
- dryRun: true,
4491
- strict: args.strict ?? false
4492
- });
4493
- if (args.json) {
4494
- const payload = {
4495
- ok: true,
4496
- ...result
4497
- };
4498
- logger_default.log(JSON.stringify(payload, null, 2));
4499
- return result;
4659
+ const {
4660
+ include,
4661
+ exclude,
4662
+ maxDepth,
4663
+ checkMode,
4664
+ dryRun,
4665
+ hasInvalidMaxDepth
4666
+ } = resolveMigrateCommandArgs(args);
4667
+ if (args.workspace && hasInvalidMaxDepth) {
4668
+ logger_default.warn(`Invalid --max-depth value "${String(args.maxDepth)}", fallback to default depth.`);
4669
+ }
4670
+ const report = await migrateConfigFiles({
4671
+ cwd: ctx.cwd,
4672
+ dryRun,
4673
+ ...args.config ? { files: [args.config] } : {},
4674
+ ...args.workspace ? { workspace: true } : {},
4675
+ ...args.workspace && maxDepth !== void 0 ? { maxDepth } : {},
4676
+ ...args.backupDir ? { backupDir: args.backupDir } : {},
4677
+ ...include ? { include } : {},
4678
+ ...exclude ? { exclude } : {}
4679
+ });
4680
+ if (args.reportFile) {
4681
+ await writeMigrationReportFile(ctx.cwd, args.reportFile, report);
4682
+ }
4683
+ if (args.json) {
4684
+ logMigrationReportAsJson(report);
4685
+ if (checkMode && report.changedFiles > 0) {
4686
+ throw createMigrationCheckFailureError(report.changedFiles);
4500
4687
  }
4501
- logger_default.success(
4502
- `Migration report validated: scanned=${result.scannedEntries}, restorable=${result.restorableEntries}, missingBackups=${result.missingBackups}, skipped=${result.skippedEntries}`
4503
- );
4504
- if (result.reportKind || result.reportSchemaVersion !== void 0) {
4505
- const kind = result.reportKind ?? "unknown";
4506
- const schema = result.reportSchemaVersion === void 0 ? "unknown" : String(result.reportSchemaVersion);
4507
- logger_default.info(` metadata: kind=${kind}, schema=${schema}`);
4688
+ if (report.scannedFiles === 0) {
4689
+ logNoMigrationConfigFilesWarning();
4508
4690
  }
4691
+ return report;
4692
+ }
4693
+ if (report.scannedFiles === 0) {
4694
+ logNoMigrationConfigFilesWarning();
4695
+ return report;
4696
+ }
4697
+ logMigrationEntries(report, dryRun);
4698
+ logMigrationSummary(report);
4699
+ if (checkMode && report.changedFiles > 0) {
4700
+ throw createMigrationCheckFailureError(report.changedFiles);
4701
+ }
4702
+ return report;
4703
+ }
4704
+
4705
+ // src/commands/restore-handler.ts
4706
+ async function restoreCommandDefaultHandler(ctx) {
4707
+ const { args } = ctx;
4708
+ const restoreArgs = resolveRestoreCommandArgs(args);
4709
+ const result = await restoreConfigFiles({
4710
+ cwd: ctx.cwd,
4711
+ reportFile: restoreArgs.reportFile,
4712
+ dryRun: restoreArgs.dryRun,
4713
+ strict: restoreArgs.strict
4714
+ });
4715
+ if (args.json) {
4716
+ logRestoreResultAsJson(result);
4509
4717
  return result;
4510
- } catch (error) {
4511
- const summary = classifyValidateError(error);
4512
- if (args.json) {
4513
- const payload = {
4514
- ok: false,
4515
- reason: summary.reason,
4516
- exitCode: summary.exitCode,
4517
- message: summary.message
4518
- };
4519
- logger_default.log(JSON.stringify(payload, null, 2));
4520
- } else {
4521
- logger_default.error(`Validation failed [${summary.reason}] (exit ${summary.exitCode}): ${summary.message}`);
4522
- }
4523
- throw new ValidateCommandError(summary, { cause: error });
4524
4718
  }
4719
+ logRestoreSummary(result);
4720
+ return result;
4525
4721
  }
4722
+
4723
+ // src/commands/status-output.ts
4526
4724
  function formatFilesHint(entry) {
4527
4725
  if (!entry.files.length) {
4528
4726
  return "";
4529
4727
  }
4530
4728
  return ` (${entry.files.join(", ")})`;
4531
4729
  }
4532
- async function statusCommandDefaultHandler(ctx) {
4533
- const patcher = await ctx.createPatcher();
4534
- const report = await patcher.getPatchStatus();
4535
- if (ctx.args.json) {
4536
- logger_default.log(JSON.stringify(report, null, 2));
4537
- return report;
4538
- }
4539
- const applied = report.entries.filter((entry) => entry.status === "applied");
4540
- const pending = report.entries.filter((entry) => entry.status === "not-applied");
4541
- const skipped = report.entries.filter((entry) => entry.status === "skipped" || entry.status === "unsupported");
4542
- const packageLabel = `${report.package.name ?? "tailwindcss"}@${report.package.version ?? "unknown"}`;
4543
- logger_default.info(`Patch status for ${packageLabel} (v${report.majorVersion})`);
4730
+ function formatPackageLabel(report) {
4731
+ return `${report.package.name ?? "tailwindcss"}@${report.package.version ?? "unknown"}`;
4732
+ }
4733
+ function partitionStatusEntries(report) {
4734
+ return {
4735
+ applied: report.entries.filter((entry) => entry.status === "applied"),
4736
+ pending: report.entries.filter((entry) => entry.status === "not-applied"),
4737
+ skipped: report.entries.filter((entry) => entry.status === "skipped" || entry.status === "unsupported")
4738
+ };
4739
+ }
4740
+ function logStatusReportAsJson(report) {
4741
+ logger_default.log(JSON.stringify(report, null, 2));
4742
+ }
4743
+ function logStatusReportSummary(report) {
4744
+ const {
4745
+ applied,
4746
+ pending,
4747
+ skipped
4748
+ } = partitionStatusEntries(report);
4749
+ logger_default.info(`Patch status for ${formatPackageLabel(report)} (v${report.majorVersion})`);
4544
4750
  if (applied.length) {
4545
4751
  logger_default.success("Applied:");
4546
4752
  applied.forEach((entry) => logger_default.success(` \u2022 ${entry.name}${formatFilesHint(entry)}`));
@@ -4548,7 +4754,7 @@ async function statusCommandDefaultHandler(ctx) {
4548
4754
  if (pending.length) {
4549
4755
  logger_default.warn("Needs attention:");
4550
4756
  pending.forEach((entry) => {
4551
- const details = entry.reason ? ` \u2013 ${entry.reason}` : "";
4757
+ const details = entry.reason ? ` - ${entry.reason}` : "";
4552
4758
  logger_default.warn(` \u2022 ${entry.name}${formatFilesHint(entry)}${details}`);
4553
4759
  });
4554
4760
  } else {
@@ -4557,151 +4763,89 @@ async function statusCommandDefaultHandler(ctx) {
4557
4763
  if (skipped.length) {
4558
4764
  logger_default.info("Skipped:");
4559
4765
  skipped.forEach((entry) => {
4560
- const details = entry.reason ? ` \u2013 ${entry.reason}` : "";
4766
+ const details = entry.reason ? ` - ${entry.reason}` : "";
4561
4767
  logger_default.info(` \u2022 ${entry.name}${details}`);
4562
4768
  });
4563
4769
  }
4770
+ }
4771
+
4772
+ // src/commands/status-handler.ts
4773
+ async function statusCommandDefaultHandler(ctx) {
4774
+ const patcher = await ctx.createPatcher();
4775
+ const report = await patcher.getPatchStatus();
4776
+ if (ctx.args.json) {
4777
+ logStatusReportAsJson(report);
4778
+ return report;
4779
+ }
4780
+ logStatusReportSummary(report);
4564
4781
  return report;
4565
4782
  }
4783
+
4784
+ // src/commands/validate-handler.ts
4785
+ async function validateCommandDefaultHandler(ctx) {
4786
+ const { args } = ctx;
4787
+ const validateArgs = resolveValidateCommandArgs(args);
4788
+ try {
4789
+ const result = await restoreConfigFiles({
4790
+ cwd: ctx.cwd,
4791
+ reportFile: validateArgs.reportFile,
4792
+ dryRun: true,
4793
+ strict: validateArgs.strict
4794
+ });
4795
+ if (args.json) {
4796
+ logValidateSuccessAsJson(result);
4797
+ return result;
4798
+ }
4799
+ logValidateSuccessSummary(result);
4800
+ return result;
4801
+ } catch (error) {
4802
+ const summary = classifyValidateError(error);
4803
+ if (args.json) {
4804
+ logValidateFailureAsJson(summary);
4805
+ } else {
4806
+ logValidateFailureSummary(summary);
4807
+ }
4808
+ throw new ValidateCommandError(summary, { cause: error });
4809
+ }
4810
+ }
4811
+
4812
+ // src/commands/default-handler-map.ts
4813
+ var defaultCommandHandlers = {
4814
+ install: installCommandDefaultHandler,
4815
+ extract: extractCommandDefaultHandler,
4816
+ tokens: tokensCommandDefaultHandler,
4817
+ init: initCommandDefaultHandler,
4818
+ migrate: migrateCommandDefaultHandler,
4819
+ restore: restoreCommandDefaultHandler,
4820
+ validate: validateCommandDefaultHandler,
4821
+ status: statusCommandDefaultHandler
4822
+ };
4823
+
4824
+ // src/commands/command-registrar.ts
4825
+ function registerTailwindcssPatchCommand(cli, commandName, options, prefix, defaultDefinitions) {
4826
+ const metadata = resolveCommandMetadata(commandName, options, prefix, defaultDefinitions);
4827
+ const command = cli.command(metadata.name, metadata.description);
4828
+ applyCommandOptions(command, metadata.optionDefs);
4829
+ command.action(async (args) => {
4830
+ return runWithCommandHandler(
4831
+ cli,
4832
+ command,
4833
+ commandName,
4834
+ args,
4835
+ options.commandHandlers?.[commandName],
4836
+ defaultCommandHandlers[commandName]
4837
+ );
4838
+ });
4839
+ metadata.aliases.forEach((alias) => command.alias(alias));
4840
+ }
4841
+
4842
+ // src/commands/cli.ts
4566
4843
  function mountTailwindcssPatchCommands(cli, options = {}) {
4567
4844
  const prefix = options.commandPrefix ?? "";
4568
4845
  const selectedCommands = options.commands ?? tailwindcssPatchCommands;
4569
4846
  const defaultDefinitions = buildDefaultCommandDefinitions();
4570
- const registrars = {
4571
- install: () => {
4572
- const metadata = resolveCommandMetadata("install", options, prefix, defaultDefinitions);
4573
- const command = cli.command(metadata.name, metadata.description);
4574
- applyCommandOptions(command, metadata.optionDefs);
4575
- command.action(async (args) => {
4576
- return runWithCommandHandler(
4577
- cli,
4578
- command,
4579
- "install",
4580
- args,
4581
- options.commandHandlers?.install,
4582
- installCommandDefaultHandler
4583
- );
4584
- });
4585
- metadata.aliases.forEach((alias) => command.alias(alias));
4586
- },
4587
- extract: () => {
4588
- const metadata = resolveCommandMetadata("extract", options, prefix, defaultDefinitions);
4589
- const command = cli.command(metadata.name, metadata.description);
4590
- applyCommandOptions(command, metadata.optionDefs);
4591
- command.action(async (args) => {
4592
- return runWithCommandHandler(
4593
- cli,
4594
- command,
4595
- "extract",
4596
- args,
4597
- options.commandHandlers?.extract,
4598
- extractCommandDefaultHandler
4599
- );
4600
- });
4601
- metadata.aliases.forEach((alias) => command.alias(alias));
4602
- },
4603
- tokens: () => {
4604
- const metadata = resolveCommandMetadata("tokens", options, prefix, defaultDefinitions);
4605
- const command = cli.command(metadata.name, metadata.description);
4606
- applyCommandOptions(command, metadata.optionDefs);
4607
- command.action(async (args) => {
4608
- return runWithCommandHandler(
4609
- cli,
4610
- command,
4611
- "tokens",
4612
- args,
4613
- options.commandHandlers?.tokens,
4614
- tokensCommandDefaultHandler
4615
- );
4616
- });
4617
- metadata.aliases.forEach((alias) => command.alias(alias));
4618
- },
4619
- init: () => {
4620
- const metadata = resolveCommandMetadata("init", options, prefix, defaultDefinitions);
4621
- const command = cli.command(metadata.name, metadata.description);
4622
- applyCommandOptions(command, metadata.optionDefs);
4623
- command.action(async (args) => {
4624
- return runWithCommandHandler(
4625
- cli,
4626
- command,
4627
- "init",
4628
- args,
4629
- options.commandHandlers?.init,
4630
- initCommandDefaultHandler
4631
- );
4632
- });
4633
- metadata.aliases.forEach((alias) => command.alias(alias));
4634
- },
4635
- migrate: () => {
4636
- const metadata = resolveCommandMetadata("migrate", options, prefix, defaultDefinitions);
4637
- const command = cli.command(metadata.name, metadata.description);
4638
- applyCommandOptions(command, metadata.optionDefs);
4639
- command.action(async (args) => {
4640
- return runWithCommandHandler(
4641
- cli,
4642
- command,
4643
- "migrate",
4644
- args,
4645
- options.commandHandlers?.migrate,
4646
- migrateCommandDefaultHandler
4647
- );
4648
- });
4649
- metadata.aliases.forEach((alias) => command.alias(alias));
4650
- },
4651
- restore: () => {
4652
- const metadata = resolveCommandMetadata("restore", options, prefix, defaultDefinitions);
4653
- const command = cli.command(metadata.name, metadata.description);
4654
- applyCommandOptions(command, metadata.optionDefs);
4655
- command.action(async (args) => {
4656
- return runWithCommandHandler(
4657
- cli,
4658
- command,
4659
- "restore",
4660
- args,
4661
- options.commandHandlers?.restore,
4662
- restoreCommandDefaultHandler
4663
- );
4664
- });
4665
- metadata.aliases.forEach((alias) => command.alias(alias));
4666
- },
4667
- validate: () => {
4668
- const metadata = resolveCommandMetadata("validate", options, prefix, defaultDefinitions);
4669
- const command = cli.command(metadata.name, metadata.description);
4670
- applyCommandOptions(command, metadata.optionDefs);
4671
- command.action(async (args) => {
4672
- return runWithCommandHandler(
4673
- cli,
4674
- command,
4675
- "validate",
4676
- args,
4677
- options.commandHandlers?.validate,
4678
- validateCommandDefaultHandler
4679
- );
4680
- });
4681
- metadata.aliases.forEach((alias) => command.alias(alias));
4682
- },
4683
- status: () => {
4684
- const metadata = resolveCommandMetadata("status", options, prefix, defaultDefinitions);
4685
- const command = cli.command(metadata.name, metadata.description);
4686
- applyCommandOptions(command, metadata.optionDefs);
4687
- command.action(async (args) => {
4688
- return runWithCommandHandler(
4689
- cli,
4690
- command,
4691
- "status",
4692
- args,
4693
- options.commandHandlers?.status,
4694
- statusCommandDefaultHandler
4695
- );
4696
- });
4697
- metadata.aliases.forEach((alias) => command.alias(alias));
4698
- }
4699
- };
4700
4847
  for (const name of selectedCommands) {
4701
- const register = registrars[name];
4702
- if (register) {
4703
- register();
4704
- }
4848
+ registerTailwindcssPatchCommand(cli, name, options, prefix, defaultDefinitions);
4705
4849
  }
4706
4850
  return cli;
4707
4851
  }
@@ -4714,26 +4858,26 @@ function createTailwindcssPatchCli(options = {}) {
4714
4858
  export {
4715
4859
  logger_default,
4716
4860
  CacheStore,
4861
+ normalizeOptions,
4717
4862
  extractRawCandidatesWithPositions,
4718
4863
  extractRawCandidates,
4719
4864
  extractValidCandidates,
4720
4865
  extractProjectCandidatesWithPositions,
4721
4866
  groupTokensByFile,
4722
- normalizeOptions,
4723
- getPatchStatusReport,
4724
4867
  collectClassesFromContexts,
4725
4868
  collectClassesFromTailwindV4,
4726
4869
  loadRuntimeContexts,
4727
4870
  runTailwindBuild,
4871
+ getPatchStatusReport,
4728
4872
  TailwindcssPatcher,
4729
4873
  MIGRATION_REPORT_KIND,
4730
4874
  MIGRATION_REPORT_SCHEMA_VERSION,
4731
4875
  migrateConfigFiles,
4732
4876
  restoreConfigFiles,
4733
- tailwindcssPatchCommands,
4734
4877
  VALIDATE_EXIT_CODES,
4735
4878
  VALIDATE_FAILURE_REASONS,
4736
4879
  ValidateCommandError,
4880
+ tailwindcssPatchCommands,
4737
4881
  mountTailwindcssPatchCommands,
4738
4882
  createTailwindcssPatchCli
4739
4883
  };