tailwindcss-patch 8.7.4-alpha.0 → 9.0.0-alpha.2

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.
Files changed (70) hide show
  1. package/README.md +65 -5
  2. package/dist/{chunk-ZXW4S356.js → chunk-TOAZIPHJ.js} +295 -285
  3. package/dist/{chunk-6ZDYMYHE.mjs → chunk-VDWTCQ74.mjs} +259 -249
  4. package/dist/cli.js +4 -4
  5. package/dist/cli.mjs +1 -1
  6. package/dist/index.d.mts +46 -134
  7. package/dist/index.d.ts +46 -134
  8. package/dist/index.js +5 -3
  9. package/dist/index.mjs +4 -2
  10. package/package.json +8 -3
  11. package/src/api/tailwindcss-patcher.ts +424 -0
  12. package/src/babel/index.ts +12 -0
  13. package/src/cache/context.ts +212 -0
  14. package/src/cache/store.ts +1440 -0
  15. package/src/cache/types.ts +71 -0
  16. package/src/cli.ts +20 -0
  17. package/src/commands/basic-handlers.ts +145 -0
  18. package/src/commands/cli.ts +56 -0
  19. package/src/commands/command-context.ts +77 -0
  20. package/src/commands/command-definitions.ts +102 -0
  21. package/src/commands/command-metadata.ts +68 -0
  22. package/src/commands/command-registrar.ts +39 -0
  23. package/src/commands/command-runtime.ts +33 -0
  24. package/src/commands/default-handler-map.ts +25 -0
  25. package/src/commands/migrate-config.ts +104 -0
  26. package/src/commands/migrate-handler.ts +67 -0
  27. package/src/commands/migration-aggregation.ts +100 -0
  28. package/src/commands/migration-args.ts +85 -0
  29. package/src/commands/migration-file-executor.ts +189 -0
  30. package/src/commands/migration-output.ts +115 -0
  31. package/src/commands/migration-report-loader.ts +26 -0
  32. package/src/commands/migration-report.ts +21 -0
  33. package/src/commands/migration-source.ts +318 -0
  34. package/src/commands/migration-target-files.ts +161 -0
  35. package/src/commands/migration-target-resolver.ts +34 -0
  36. package/src/commands/migration-types.ts +65 -0
  37. package/src/commands/restore-handler.ts +24 -0
  38. package/src/commands/status-handler.ts +17 -0
  39. package/src/commands/status-output.ts +60 -0
  40. package/src/commands/token-output.ts +30 -0
  41. package/src/commands/types.ts +137 -0
  42. package/src/commands/validate-handler.ts +42 -0
  43. package/src/commands/validate.ts +83 -0
  44. package/src/config/index.ts +25 -0
  45. package/src/config/workspace.ts +87 -0
  46. package/src/constants.ts +4 -0
  47. package/src/extraction/candidate-extractor.ts +354 -0
  48. package/src/index.ts +57 -0
  49. package/src/install/class-collector.ts +1 -0
  50. package/src/install/context-registry.ts +1 -0
  51. package/src/install/index.ts +5 -0
  52. package/src/install/patch-runner.ts +1 -0
  53. package/src/install/process-tailwindcss.ts +1 -0
  54. package/src/install/status.ts +1 -0
  55. package/src/logger.ts +5 -0
  56. package/src/options/legacy.ts +93 -0
  57. package/src/options/normalize.ts +262 -0
  58. package/src/options/types.ts +217 -0
  59. package/src/patching/operations/export-context/index.ts +110 -0
  60. package/src/patching/operations/export-context/postcss-v2.ts +235 -0
  61. package/src/patching/operations/export-context/postcss-v3.ts +249 -0
  62. package/src/patching/operations/extend-length-units.ts +197 -0
  63. package/src/patching/patch-runner.ts +46 -0
  64. package/src/patching/status.ts +262 -0
  65. package/src/runtime/class-collector.ts +105 -0
  66. package/src/runtime/collector.ts +148 -0
  67. package/src/runtime/context-registry.ts +65 -0
  68. package/src/runtime/process-tailwindcss.ts +115 -0
  69. package/src/types.ts +159 -0
  70. package/src/utils.ts +52 -0
@@ -20,7 +20,7 @@ import path from "pathe";
20
20
  // package.json
21
21
  var package_default = {
22
22
  name: "tailwindcss-patch",
23
- version: "8.7.4-alpha.0",
23
+ version: "9.0.0-alpha.2",
24
24
  description: "patch tailwindcss for exposing context and extract classes",
25
25
  author: "ice breaker <1324318532@qq.com>",
26
26
  license: "MIT",
@@ -41,17 +41,17 @@ var package_default = {
41
41
  ],
42
42
  exports: {
43
43
  ".": {
44
- types: "./dist/index.d.ts",
45
- import: "./dist/index.mjs",
46
- require: "./dist/index.js"
44
+ types: "./src/index.ts",
45
+ import: "./src/index.ts",
46
+ require: "./src/index.ts"
47
47
  },
48
48
  "./migration-report.schema.json": "./schema/migration-report.schema.json",
49
49
  "./restore-result.schema.json": "./schema/restore-result.schema.json",
50
50
  "./validate-result.schema.json": "./schema/validate-result.schema.json"
51
51
  },
52
- main: "./dist/index.js",
53
- module: "./dist/index.mjs",
54
- types: "./dist/index.d.ts",
52
+ main: "./src/index.ts",
53
+ module: "./src/index.ts",
54
+ types: "./src/index.ts",
55
55
  bin: {
56
56
  "tw-patch": "dev/bin.ts",
57
57
  "tailwindcss-patch": "dev/bin.ts"
@@ -59,18 +59,23 @@ var package_default = {
59
59
  files: [
60
60
  "bin",
61
61
  "dist",
62
- "schema"
62
+ "schema",
63
+ "src"
63
64
  ],
64
65
  scripts: {
65
66
  dev: "tsup --watch --sourcemap",
66
67
  build: "tsup",
67
68
  test: "vitest run",
69
+ "test:types": "pnpm build && tsd --typings dist/index.d.mts --files test-d/**/*.test-d.ts",
68
70
  "test:dev": "vitest",
69
71
  "bench:cold-start": "node --import tsx bench/cold-start.ts",
70
72
  patch: "tsx dev/bin.ts install",
71
73
  r0: "tsx dev/bin.ts extract",
72
74
  r1: "tsx dev/bin.ts extract --css index.css"
73
75
  },
76
+ tsd: {
77
+ directory: "test-d"
78
+ },
74
79
  publishConfig: {
75
80
  access: "public",
76
81
  registry: "https://registry.npmjs.org/",
@@ -1516,14 +1521,6 @@ ${Date.now()}`, { flag: "wx" });
1516
1521
  import process3 from "process";
1517
1522
  import fs3 from "fs-extra";
1518
1523
  import path2 from "pathe";
1519
- var hasWarnedDeprecatedOptions = false;
1520
- var deprecatedOptionMapping = {
1521
- cwd: "projectRoot",
1522
- overwrite: "apply.overwrite",
1523
- tailwind: "tailwindcss",
1524
- features: "apply",
1525
- output: "extract"
1526
- };
1527
1524
  function resolveRealpathSafe(value) {
1528
1525
  const resolved = path2.resolve(value);
1529
1526
  try {
@@ -1668,66 +1665,32 @@ function normalizeTailwindOptions(tailwind, projectRoot) {
1668
1665
  v4
1669
1666
  };
1670
1667
  }
1671
- function resolveOptionSlices(options) {
1672
- const projectRoot = options.projectRoot ?? options.cwd;
1673
- const overwrite = options.apply?.overwrite ?? options.overwrite;
1674
- const tailwind = options.tailwindcss ?? options.tailwind;
1675
- const exposeContext = options.apply?.exposeContext !== void 0 ? options.apply.exposeContext : options.features?.exposeContext;
1676
- const extendLengthUnits = options.apply?.extendLengthUnits !== void 0 ? options.apply.extendLengthUnits : options.features?.extendLengthUnits;
1677
- const write = options.extract?.write ?? options.output?.enabled;
1678
- const file = options.extract?.file ?? options.output?.file;
1679
- const format = options.extract?.format ?? options.output?.format;
1680
- const pretty = options.extract?.pretty ?? options.output?.pretty;
1681
- const removeUniversalSelector = options.extract?.removeUniversalSelector ?? options.output?.removeUniversalSelector;
1682
- const extract = {
1683
- ...write === void 0 ? {} : { write },
1684
- ...file === void 0 ? {} : { file },
1685
- ...format === void 0 ? {} : { format },
1686
- ...pretty === void 0 ? {} : { pretty },
1687
- ...removeUniversalSelector === void 0 ? {} : { removeUniversalSelector }
1688
- };
1689
- return {
1690
- ...projectRoot === void 0 ? {} : { projectRoot },
1691
- ...overwrite === void 0 ? {} : { overwrite },
1692
- ...tailwind === void 0 ? {} : { tailwind },
1693
- ...Object.keys(extract).length === 0 ? {} : { extract },
1694
- ...exposeContext === void 0 ? {} : { exposeContext },
1695
- ...extendLengthUnits === void 0 ? {} : { extendLengthUnits }
1696
- };
1697
- }
1698
- function findUsedDeprecatedOptions(options) {
1699
- const result = [];
1700
- for (const key of Object.keys(deprecatedOptionMapping)) {
1701
- if (options[key] !== void 0) {
1702
- result.push(key);
1703
- }
1704
- }
1705
- return result;
1706
- }
1707
- function warnDeprecatedOptionsIfNeeded(options) {
1708
- if (hasWarnedDeprecatedOptions) {
1709
- return;
1710
- }
1711
- const used = findUsedDeprecatedOptions(options);
1668
+ var deprecatedOptionMapping = {
1669
+ cwd: "projectRoot",
1670
+ overwrite: "apply.overwrite",
1671
+ tailwind: "tailwindcss",
1672
+ features: "apply",
1673
+ output: "extract"
1674
+ };
1675
+ function assertNoDeprecatedOptions(options) {
1676
+ const used = Object.keys(deprecatedOptionMapping).filter((key) => Object.prototype.hasOwnProperty.call(options, key));
1712
1677
  if (used.length === 0) {
1713
1678
  return;
1714
1679
  }
1715
- hasWarnedDeprecatedOptions = true;
1716
1680
  const mapping = used.map((key) => `${key} -> ${deprecatedOptionMapping[key]}`).join(", ");
1717
- logger_default.warn(
1718
- `[deprecated] TailwindcssPatcher options (${used.join(", ")}) are deprecated and will be removed in the next major version. Please migrate to: ${mapping}.`
1681
+ throw new Error(
1682
+ `Legacy TailwindcssPatcher options are no longer supported: ${used.join(", ")}. Use the modern fields instead: ${mapping}.`
1719
1683
  );
1720
1684
  }
1721
1685
  function normalizeOptions(options = {}) {
1722
- warnDeprecatedOptionsIfNeeded(options);
1723
- const resolved = resolveOptionSlices(options);
1724
- const projectRoot = resolveRealpathSafe(resolved.projectRoot ? path2.resolve(resolved.projectRoot) : process3.cwd());
1725
- const overwrite = resolved.overwrite ?? true;
1726
- const output = normalizeOutputOptions(resolved.extract);
1686
+ assertNoDeprecatedOptions(options);
1687
+ const projectRoot = resolveRealpathSafe(options.projectRoot ? path2.resolve(options.projectRoot) : process3.cwd());
1688
+ const overwrite = options.apply?.overwrite ?? true;
1689
+ const output = normalizeOutputOptions(options.extract);
1727
1690
  const cache = normalizeCacheOptions(options.cache, projectRoot);
1728
- const tailwind = normalizeTailwindOptions(resolved.tailwind, projectRoot);
1729
- const exposeContext = normalizeExposeContextOptions(resolved.exposeContext);
1730
- const extendLengthUnits = normalizeExtendLengthUnitsOptions(resolved.extendLengthUnits);
1691
+ const tailwind = normalizeTailwindOptions(options.tailwindcss, projectRoot);
1692
+ const exposeContext = normalizeExposeContextOptions(options.apply?.exposeContext);
1693
+ const extendLengthUnits = normalizeExtendLengthUnitsOptions(options.apply?.extendLengthUnits);
1731
1694
  const filter = (className) => {
1732
1695
  if (output.removeUniversalSelector && className === "*") {
1733
1696
  return false;
@@ -1752,122 +1715,70 @@ function normalizeOptions(options = {}) {
1752
1715
  }
1753
1716
 
1754
1717
  // src/options/legacy.ts
1755
- function normalizeLegacyFeatures(patch) {
1756
- const apply = patch?.applyPatches;
1757
- const extend = apply?.extendLengthUnits;
1758
- let extendOption = false;
1759
- if (extend && typeof extend === "object") {
1760
- extendOption = {
1761
- ...extend,
1762
- enabled: true
1763
- };
1764
- } else if (extend === true) {
1765
- extendOption = {
1766
- enabled: true,
1767
- units: ["rpx"],
1768
- ...patch?.overwrite === void 0 ? {} : { overwrite: patch.overwrite }
1769
- };
1718
+ var deprecatedRegistryMapping = {
1719
+ output: "extract",
1720
+ tailwind: "tailwindcss"
1721
+ };
1722
+ var deprecatedTailwindMapping = {
1723
+ package: "packageName",
1724
+ legacy: "v2",
1725
+ classic: "v3",
1726
+ next: "v4"
1727
+ };
1728
+ function assertNoDeprecatedRegistryOptions(registry) {
1729
+ const usedRegistryKeys = Object.keys(deprecatedRegistryMapping).filter((key) => Object.prototype.hasOwnProperty.call(registry, key));
1730
+ if (usedRegistryKeys.length > 0) {
1731
+ const mapping = usedRegistryKeys.map((key) => `${key} -> ${deprecatedRegistryMapping[key]}`).join(", ");
1732
+ throw new Error(
1733
+ `Legacy registry fields are no longer supported: ${usedRegistryKeys.join(", ")}. Use the modern fields instead: ${mapping}.`
1734
+ );
1770
1735
  }
1771
- return {
1772
- exposeContext: apply?.exportContext ?? true,
1773
- extendLengthUnits: extendOption
1774
- };
1775
- }
1776
- function fromLegacyOptions(options) {
1777
- if (!options) {
1778
- return {};
1736
+ const tailwind = registry.tailwindcss;
1737
+ if (!tailwind) {
1738
+ return;
1739
+ }
1740
+ const usedTailwindKeys = Object.keys(deprecatedTailwindMapping).filter((key) => Object.prototype.hasOwnProperty.call(tailwind, key));
1741
+ if (usedTailwindKeys.length > 0) {
1742
+ const mapping = usedTailwindKeys.map((key) => `${key} -> tailwindcss.${deprecatedTailwindMapping[key]}`).join(", ");
1743
+ throw new Error(
1744
+ `Legacy "registry.tailwindcss" fields are no longer supported: ${usedTailwindKeys.join(", ")}. Use the modern fields instead: ${mapping}.`
1745
+ );
1779
1746
  }
1780
- const patch = options.patch;
1781
- const features = normalizeLegacyFeatures(patch);
1782
- const output = patch?.output;
1783
- const tailwindConfig = patch?.tailwindcss;
1784
- const tailwindVersion = tailwindConfig?.version;
1785
- const tailwindV2 = tailwindConfig?.v2;
1786
- const tailwindV3 = tailwindConfig?.v3;
1787
- const tailwindV4 = tailwindConfig?.v4;
1788
- const tailwindConfigPath = tailwindV3?.config ?? tailwindV2?.config;
1789
- const tailwindCwd = tailwindV3?.cwd ?? tailwindV2?.cwd ?? patch?.cwd;
1790
- const normalizedExtract = output ? {
1791
- ...output.filename === void 0 ? {} : { file: output.filename },
1792
- pretty: output.loose ? 2 : false,
1793
- ...output.removeUniversalSelector === void 0 ? {} : { removeUniversalSelector: output.removeUniversalSelector }
1794
- } : void 0;
1795
- const normalizedTailwindcss = {
1796
- ...patch?.packageName === void 0 ? {} : { packageName: patch.packageName },
1797
- ...tailwindVersion === void 0 ? {} : { version: tailwindVersion },
1798
- ...patch?.resolve === void 0 ? {} : { resolve: patch.resolve },
1799
- ...tailwindConfigPath === void 0 ? {} : { config: tailwindConfigPath },
1800
- ...tailwindCwd === void 0 ? {} : { cwd: tailwindCwd },
1801
- ...tailwindV2 === void 0 ? {} : { v2: tailwindV2 },
1802
- ...tailwindV3 === void 0 ? {} : { v3: tailwindV3 },
1803
- ...tailwindV4 === void 0 ? {} : { v4: tailwindV4 }
1804
- };
1805
- const normalizedCache = typeof options.cache === "boolean" ? options.cache : options.cache ? {
1806
- ...options.cache,
1807
- enabled: options.cache.enabled ?? true
1808
- } : void 0;
1809
- const normalizedApply = {
1810
- ...patch?.overwrite === void 0 ? {} : { overwrite: patch.overwrite },
1811
- exposeContext: features.exposeContext,
1812
- extendLengthUnits: features.extendLengthUnits
1813
- };
1814
- return {
1815
- ...patch?.cwd === void 0 ? {} : { projectRoot: patch.cwd },
1816
- ...patch?.filter === void 0 ? {} : { filter: patch.filter },
1817
- ...normalizedCache === void 0 ? {} : { cache: normalizedCache },
1818
- ...normalizedExtract === void 0 ? {} : { extract: normalizedExtract },
1819
- ...Object.keys(normalizedTailwindcss).length === 0 ? {} : { tailwindcss: normalizedTailwindcss },
1820
- apply: normalizedApply
1821
- };
1822
1747
  }
1823
1748
  function fromUnifiedConfig(registry) {
1824
1749
  if (!registry) {
1825
1750
  return {};
1826
1751
  }
1827
- const tailwind = registry.tailwindcss ?? registry.tailwind;
1828
- const modernExtract = registry.extract;
1829
- const legacyOutput = registry.output;
1830
- const pretty = (() => {
1831
- const value = modernExtract?.pretty ?? legacyOutput?.pretty;
1832
- if (value === void 0) {
1833
- return void 0;
1834
- }
1835
- if (typeof value === "boolean") {
1836
- return value ? 2 : false;
1837
- }
1838
- return value;
1839
- })();
1840
- const removeUniversalSelector = modernExtract?.removeUniversalSelector ?? legacyOutput?.stripUniversalSelector;
1841
- const outputFile = modernExtract?.file ?? legacyOutput?.file;
1842
- const normalizedExtract = modernExtract || legacyOutput ? {
1843
- ...modernExtract?.write === void 0 ? {} : { write: modernExtract.write },
1844
- ...outputFile === void 0 ? {} : { file: outputFile },
1845
- ...pretty === void 0 ? {} : { pretty },
1846
- ...removeUniversalSelector === void 0 ? {} : { removeUniversalSelector },
1847
- ...modernExtract?.format === void 0 ? {} : { format: modernExtract.format }
1752
+ assertNoDeprecatedRegistryOptions(registry);
1753
+ const extract = registry.extract ? {
1754
+ ...registry.extract.write === void 0 ? {} : { write: registry.extract.write },
1755
+ ...registry.extract.file === void 0 ? {} : { file: registry.extract.file },
1756
+ ...registry.extract.format === void 0 ? {} : { format: registry.extract.format },
1757
+ ...registry.extract.pretty === void 0 ? {} : { pretty: registry.extract.pretty },
1758
+ ...registry.extract.removeUniversalSelector === void 0 ? {} : { removeUniversalSelector: registry.extract.removeUniversalSelector }
1848
1759
  } : void 0;
1849
- const normalizedTailwindcss = tailwind ? {
1850
- ...tailwind.version === void 0 ? {} : { version: tailwind.version },
1851
- ...tailwind.packageName === void 0 ? tailwind.package === void 0 ? {} : { packageName: tailwind.package } : { packageName: tailwind.packageName },
1852
- ...tailwind.resolve === void 0 ? {} : { resolve: tailwind.resolve },
1853
- ...tailwind.config === void 0 ? {} : { config: tailwind.config },
1854
- ...tailwind.cwd === void 0 ? {} : { cwd: tailwind.cwd },
1855
- ...tailwind.v2 === void 0 ? tailwind.legacy === void 0 ? {} : { v2: tailwind.legacy } : { v2: tailwind.v2 },
1856
- ...tailwind.v3 === void 0 ? tailwind.classic === void 0 ? {} : { v3: tailwind.classic } : { v3: tailwind.v3 },
1857
- ...tailwind.v4 === void 0 ? tailwind.next === void 0 ? {} : { v4: tailwind.next } : { v4: tailwind.v4 }
1760
+ const tailwindcss = registry.tailwindcss ? {
1761
+ ...registry.tailwindcss.version === void 0 ? {} : { version: registry.tailwindcss.version },
1762
+ ...registry.tailwindcss.packageName === void 0 ? {} : { packageName: registry.tailwindcss.packageName },
1763
+ ...registry.tailwindcss.resolve === void 0 ? {} : { resolve: registry.tailwindcss.resolve },
1764
+ ...registry.tailwindcss.config === void 0 ? {} : { config: registry.tailwindcss.config },
1765
+ ...registry.tailwindcss.cwd === void 0 ? {} : { cwd: registry.tailwindcss.cwd },
1766
+ ...registry.tailwindcss.v2 === void 0 ? {} : { v2: registry.tailwindcss.v2 },
1767
+ ...registry.tailwindcss.v3 === void 0 ? {} : { v3: registry.tailwindcss.v3 },
1768
+ ...registry.tailwindcss.v4 === void 0 ? {} : { v4: registry.tailwindcss.v4 }
1858
1769
  } : void 0;
1859
- const normalizedApply = registry.apply ? {
1770
+ const apply = registry.apply ? {
1860
1771
  ...registry.apply.overwrite === void 0 ? {} : { overwrite: registry.apply.overwrite },
1861
1772
  ...registry.apply.exposeContext === void 0 ? {} : { exposeContext: registry.apply.exposeContext },
1862
1773
  ...registry.apply.extendLengthUnits === void 0 ? {} : { extendLengthUnits: registry.apply.extendLengthUnits }
1863
1774
  } : void 0;
1864
1775
  return {
1865
1776
  ...registry.projectRoot === void 0 ? {} : { projectRoot: registry.projectRoot },
1866
- ...normalizedApply === void 0 ? {} : { apply: normalizedApply },
1777
+ ...apply === void 0 ? {} : { apply },
1867
1778
  ...registry.cache === void 0 ? {} : { cache: registry.cache },
1868
1779
  ...registry.filter === void 0 ? {} : { filter: registry.filter },
1869
- ...normalizedExtract === void 0 ? {} : { extract: normalizedExtract },
1870
- ...normalizedTailwindcss === void 0 ? {} : { tailwindcss: normalizedTailwindcss }
1780
+ ...extract === void 0 ? {} : { extract },
1781
+ ...tailwindcss === void 0 ? {} : { tailwindcss }
1871
1782
  };
1872
1783
  }
1873
1784
 
@@ -1879,19 +1790,22 @@ var defuPromise;
1879
1790
  function isNodeError(error) {
1880
1791
  return !!error && typeof error === "object" && ("code" in error || "message" in error);
1881
1792
  }
1882
- function isMissingConfigModuleError(error) {
1883
- if (!isNodeError(error) || error.code !== "MODULE_NOT_FOUND") {
1793
+ function isMissingModuleError(error, pkgName2) {
1794
+ if (!isNodeError(error)) {
1884
1795
  return false;
1885
1796
  }
1886
- const message = error.message ?? "";
1887
- return message.includes("@tailwindcss-mangle/config");
1888
- }
1889
- function isMissingSharedModuleError(error) {
1890
- if (!isNodeError(error) || error.code !== "MODULE_NOT_FOUND") {
1797
+ const code = error.code;
1798
+ if (code !== "MODULE_NOT_FOUND" && code !== "ERR_MODULE_NOT_FOUND") {
1891
1799
  return false;
1892
1800
  }
1893
1801
  const message = error.message ?? "";
1894
- return message.includes("@tailwindcss-mangle/shared");
1802
+ return message.includes(pkgName2) || message.includes(`${pkgName2}/dist/`);
1803
+ }
1804
+ function isMissingConfigModuleError(error) {
1805
+ return isMissingModuleError(error, "@tailwindcss-mangle/config");
1806
+ }
1807
+ function isMissingSharedModuleError(error) {
1808
+ return isMissingModuleError(error, "@tailwindcss-mangle/shared");
1895
1809
  }
1896
1810
  async function loadWorkspaceConfigModule() {
1897
1811
  if (!configModulePromise) {
@@ -1922,8 +1836,10 @@ async function loadPatchOptionsForWorkspace(cwd, overrides) {
1922
1836
  const merge = await loadWorkspaceDefu();
1923
1837
  const configModule = await loadWorkspaceConfigModule();
1924
1838
  const { config } = await configModule.getConfig(cwd);
1925
- const legacyConfig = config;
1926
- const base = config?.registry ? fromUnifiedConfig(config.registry) : legacyConfig?.patch ? fromLegacyOptions({ patch: legacyConfig.patch }) : {};
1839
+ if (config && typeof config === "object" && "patch" in config && config.patch !== void 0) {
1840
+ throw new Error('Legacy workspace config field "patch" is no longer supported. Move patcher options under "registry".');
1841
+ }
1842
+ const base = config?.registry ? fromUnifiedConfig(config.registry) : {};
1927
1843
  const merged = merge(overrides ?? {}, base);
1928
1844
  return merged;
1929
1845
  }
@@ -2188,14 +2104,12 @@ function groupTokensByFile(report, options) {
2188
2104
  const stripAbsolute = options?.stripAbsolutePaths ?? key !== "absolute";
2189
2105
  return report.entries.reduce((acc, entry) => {
2190
2106
  const bucketKey = key === "absolute" ? entry.file : entry.relativeFile;
2191
- if (!acc[bucketKey]) {
2192
- acc[bucketKey] = [];
2193
- }
2107
+ const bucket = acc[bucketKey] ?? (acc[bucketKey] = []);
2194
2108
  const value = stripAbsolute ? {
2195
2109
  ...entry,
2196
2110
  file: entry.relativeFile
2197
2111
  } : entry;
2198
- acc[bucketKey].push(value);
2112
+ bucket.push(value);
2199
2113
  return acc;
2200
2114
  }, {});
2201
2115
  }
@@ -2210,18 +2124,22 @@ function isObject(val) {
2210
2124
  return val !== null && typeof val === "object" && Array.isArray(val) === false;
2211
2125
  }
2212
2126
  function spliceChangesIntoString(str, changes) {
2213
- if (!changes[0]) {
2127
+ const firstChange = changes[0];
2128
+ if (!firstChange) {
2214
2129
  return str;
2215
2130
  }
2216
2131
  changes.sort((a, b) => {
2217
2132
  return a.end - b.end || a.start - b.start;
2218
2133
  });
2219
2134
  let result = "";
2220
- let previous = changes[0];
2135
+ let previous = firstChange;
2221
2136
  result += str.slice(0, previous.start);
2222
2137
  result += previous.replacement;
2223
2138
  for (let i = 1; i < changes.length; ++i) {
2224
2139
  const change = changes[i];
2140
+ if (!change) {
2141
+ continue;
2142
+ }
2225
2143
  result += str.slice(previous.end, change.start);
2226
2144
  result += change.replacement;
2227
2145
  previous = change;
@@ -2530,7 +2448,12 @@ function transformPostcssPluginV2(content, options) {
2530
2448
  const previous = program.body[index - 1];
2531
2449
  const beforePrevious = program.body[index - 2];
2532
2450
  const alreadyHasVariable = Boolean(
2533
- previous && t.isVariableDeclaration(previous) && previous.declarations.length === 1 && t.isIdentifier(previous.declarations[0].id) && previous.declarations[0].id.name === refIdentifier.name
2451
+ previous && t.isVariableDeclaration(previous) && previous.declarations.length === 1 && (() => {
2452
+ const declaration = previous.declarations[0];
2453
+ return Boolean(
2454
+ declaration && t.isIdentifier(declaration.id) && declaration.id.name === refIdentifier.name
2455
+ );
2456
+ })()
2534
2457
  );
2535
2458
  const alreadyAssignsExports = Boolean(
2536
2459
  beforePrevious && t.isExpressionStatement(beforePrevious) && t.isAssignmentExpression(beforePrevious.expression) && t.isMemberExpression(beforePrevious.expression.left) && t.isIdentifier(beforePrevious.expression.right) && beforePrevious.expression.right.name === refIdentifier.name && generate(beforePrevious.expression.left).code === generate(exportMember).code
@@ -2691,7 +2614,12 @@ function transformPostcssPlugin(content, { refProperty }) {
2691
2614
  const previousStatement = program.body[index - 1];
2692
2615
  const lastStatement = program.body[program.body.length - 1];
2693
2616
  const alreadyHasVariable = Boolean(
2694
- previousStatement && t2.isVariableDeclaration(previousStatement) && previousStatement.declarations.length === 1 && t2.isIdentifier(previousStatement.declarations[0].id) && previousStatement.declarations[0].id.name === refIdentifier.name
2617
+ previousStatement && t2.isVariableDeclaration(previousStatement) && previousStatement.declarations.length === 1 && (() => {
2618
+ const declaration = previousStatement.declarations[0];
2619
+ return Boolean(
2620
+ declaration && t2.isIdentifier(declaration.id) && declaration.id.name === refIdentifier.name
2621
+ );
2622
+ })()
2695
2623
  );
2696
2624
  const alreadyAssignsModuleExports = Boolean(
2697
2625
  t2.isExpressionStatement(lastStatement) && t2.isAssignmentExpression(lastStatement.expression) && t2.isMemberExpression(lastStatement.expression.left) && t2.isIdentifier(lastStatement.expression.right) && lastStatement.expression.right.name === refIdentifier.name && generate(lastStatement.expression.left).code === generate(moduleExportsMember).code
@@ -3257,25 +3185,7 @@ function applyTailwindPatches(context) {
3257
3185
  return results;
3258
3186
  }
3259
3187
 
3260
- // src/api/tailwindcss-patcher.ts
3261
- function resolveMajorVersion(version, hint) {
3262
- if (hint && [2, 3, 4].includes(hint)) {
3263
- return hint;
3264
- }
3265
- if (version) {
3266
- const coerced = coerce(version);
3267
- if (coerced) {
3268
- const major = coerced.major;
3269
- if (major === 2 || major === 3 || major === 4) {
3270
- return major;
3271
- }
3272
- if (major >= 4) {
3273
- return 4;
3274
- }
3275
- }
3276
- }
3277
- return 3;
3278
- }
3188
+ // src/runtime/collector.ts
3279
3189
  function resolveTailwindExecutionOptions(normalized, majorVersion) {
3280
3190
  const base = normalized.tailwind;
3281
3191
  if (majorVersion === 2 && base.v2) {
@@ -3298,17 +3208,138 @@ function resolveTailwindExecutionOptions(normalized, majorVersion) {
3298
3208
  postcssPlugin: base.postcssPlugin
3299
3209
  };
3300
3210
  }
3211
+ var BaseCollector = class {
3212
+ constructor(packageInfo, options, majorVersion) {
3213
+ this.packageInfo = packageInfo;
3214
+ this.options = options;
3215
+ this.majorVersion = majorVersion;
3216
+ }
3217
+ async patch() {
3218
+ return applyTailwindPatches({
3219
+ packageInfo: this.packageInfo,
3220
+ options: this.options,
3221
+ majorVersion: this.majorVersion
3222
+ });
3223
+ }
3224
+ async getPatchStatus() {
3225
+ return getPatchStatusReport({
3226
+ packageInfo: this.packageInfo,
3227
+ options: this.options,
3228
+ majorVersion: this.majorVersion
3229
+ });
3230
+ }
3231
+ getContexts() {
3232
+ return loadRuntimeContexts(
3233
+ this.packageInfo,
3234
+ this.majorVersion,
3235
+ this.options.features.exposeContext.refProperty
3236
+ );
3237
+ }
3238
+ };
3239
+ var RuntimeCollector = class extends BaseCollector {
3240
+ constructor(packageInfo, options, majorVersion, snapshotFactory) {
3241
+ super(packageInfo, options, majorVersion);
3242
+ this.snapshotFactory = snapshotFactory;
3243
+ }
3244
+ inFlightBuild;
3245
+ async collectClassSet() {
3246
+ const contexts = this.getContexts();
3247
+ return collectClassesFromContexts(contexts, this.options.filter);
3248
+ }
3249
+ getPatchSnapshot() {
3250
+ return this.snapshotFactory();
3251
+ }
3252
+ async runTailwindBuildIfNeeded() {
3253
+ if (this.inFlightBuild) {
3254
+ return this.inFlightBuild;
3255
+ }
3256
+ const executionOptions = resolveTailwindExecutionOptions(this.options, this.majorVersion);
3257
+ const buildOptions = {
3258
+ cwd: executionOptions.cwd,
3259
+ majorVersion: this.majorVersion,
3260
+ ...executionOptions.config === void 0 ? {} : { config: executionOptions.config },
3261
+ ...executionOptions.postcssPlugin === void 0 ? {} : { postcssPlugin: executionOptions.postcssPlugin }
3262
+ };
3263
+ this.inFlightBuild = runTailwindBuild(buildOptions).then(() => void 0);
3264
+ try {
3265
+ await this.inFlightBuild;
3266
+ } finally {
3267
+ this.inFlightBuild = void 0;
3268
+ }
3269
+ }
3270
+ };
3271
+ var TailwindV4Collector = class extends BaseCollector {
3272
+ constructor(packageInfo, options, snapshotFactory) {
3273
+ super(packageInfo, options, 4);
3274
+ this.snapshotFactory = snapshotFactory;
3275
+ }
3276
+ snapshotFactory;
3277
+ async collectClassSet() {
3278
+ return collectClassesFromTailwindV4(this.options);
3279
+ }
3280
+ getPatchSnapshot() {
3281
+ return this.snapshotFactory();
3282
+ }
3283
+ };
3284
+
3285
+ // src/api/tailwindcss-patcher.ts
3286
+ function resolveInstalledMajorVersion(version) {
3287
+ if (!version) {
3288
+ return void 0;
3289
+ }
3290
+ const coerced = coerce(version);
3291
+ if (!coerced) {
3292
+ return void 0;
3293
+ }
3294
+ const major = coerced.major;
3295
+ if (major === 2 || major === 3 || major === 4) {
3296
+ return major;
3297
+ }
3298
+ if (major >= 4) {
3299
+ return 4;
3300
+ }
3301
+ return void 0;
3302
+ }
3303
+ function validateInstalledVersion(packageVersion, expectedMajor, packageName) {
3304
+ const installedMajor = resolveInstalledMajorVersion(packageVersion);
3305
+ if (installedMajor === void 0) {
3306
+ return;
3307
+ }
3308
+ if (installedMajor !== expectedMajor) {
3309
+ throw new Error(
3310
+ `Configured tailwindcss.version=${expectedMajor}, but resolved package "${packageName}" is version ${packageVersion}. Update the configuration or resolve the correct package.`
3311
+ );
3312
+ }
3313
+ }
3314
+ function resolveMajorVersionOrThrow(configuredMajor, packageVersion, packageName) {
3315
+ if (configuredMajor !== void 0) {
3316
+ validateInstalledVersion(packageVersion, configuredMajor, packageName);
3317
+ return configuredMajor;
3318
+ }
3319
+ const installedMajor = resolveInstalledMajorVersion(packageVersion);
3320
+ if (installedMajor !== void 0) {
3321
+ return installedMajor;
3322
+ }
3323
+ throw new Error(
3324
+ `Unable to infer Tailwind CSS major version from resolved package "${packageName}" (${packageVersion ?? "unknown"}). Set "tailwindcss.version" to 2, 3, or 4 explicitly.`
3325
+ );
3326
+ }
3327
+ function createCollector(packageInfo, options, majorVersion, snapshotFactory) {
3328
+ if (majorVersion === 4) {
3329
+ return new TailwindV4Collector(packageInfo, options, snapshotFactory);
3330
+ }
3331
+ return new RuntimeCollector(packageInfo, options, majorVersion, snapshotFactory);
3332
+ }
3301
3333
  var TailwindcssPatcher = class {
3302
3334
  options;
3303
3335
  packageInfo;
3304
3336
  majorVersion;
3305
3337
  cacheContext;
3306
3338
  cacheStore;
3339
+ collector;
3307
3340
  patchMemo;
3308
- inFlightBuild;
3309
3341
  constructor(options = {}) {
3310
- const resolvedOptions = options && typeof options === "object" && "patch" in options ? fromLegacyOptions(options) : options;
3311
- this.options = normalizeOptions(resolvedOptions);
3342
+ this.options = normalizeOptions(options);
3312
3343
  const packageInfo = getPackageInfoSync(
3313
3344
  this.options.tailwind.packageName,
3314
3345
  this.options.tailwind.resolve
@@ -3317,9 +3348,10 @@ var TailwindcssPatcher = class {
3317
3348
  throw new Error(`Unable to locate Tailwind CSS package "${this.options.tailwind.packageName}".`);
3318
3349
  }
3319
3350
  this.packageInfo = packageInfo;
3320
- this.majorVersion = resolveMajorVersion(
3351
+ this.majorVersion = resolveMajorVersionOrThrow(
3352
+ this.options.tailwind.versionHint,
3321
3353
  this.packageInfo.version,
3322
- this.options.tailwind.versionHint
3354
+ this.options.tailwind.packageName
3323
3355
  );
3324
3356
  this.cacheContext = createCacheContextDescriptor(
3325
3357
  this.options,
@@ -3327,56 +3359,30 @@ var TailwindcssPatcher = class {
3327
3359
  this.majorVersion
3328
3360
  );
3329
3361
  this.cacheStore = new CacheStore(this.options.cache, this.cacheContext);
3362
+ this.collector = createCollector(
3363
+ this.packageInfo,
3364
+ this.options,
3365
+ this.majorVersion,
3366
+ () => this.createPatchSnapshot()
3367
+ );
3330
3368
  }
3331
3369
  async patch() {
3332
- const snapshot = this.createPatchSnapshot();
3370
+ const snapshot = this.collector.getPatchSnapshot();
3333
3371
  if (this.patchMemo && this.patchMemo.snapshot === snapshot) {
3334
3372
  return this.patchMemo.result;
3335
3373
  }
3336
- const result = applyTailwindPatches({
3337
- packageInfo: this.packageInfo,
3338
- options: this.options,
3339
- majorVersion: this.majorVersion
3340
- });
3374
+ const result = await this.collector.patch();
3341
3375
  this.patchMemo = {
3342
3376
  result,
3343
- snapshot: this.createPatchSnapshot()
3377
+ snapshot: this.collector.getPatchSnapshot()
3344
3378
  };
3345
3379
  return result;
3346
3380
  }
3347
3381
  async getPatchStatus() {
3348
- return getPatchStatusReport({
3349
- packageInfo: this.packageInfo,
3350
- options: this.options,
3351
- majorVersion: this.majorVersion
3352
- });
3382
+ return this.collector.getPatchStatus();
3353
3383
  }
3354
3384
  getContexts() {
3355
- return loadRuntimeContexts(
3356
- this.packageInfo,
3357
- this.majorVersion,
3358
- this.options.features.exposeContext.refProperty
3359
- );
3360
- }
3361
- async runTailwindBuildIfNeeded() {
3362
- if (this.majorVersion === 2 || this.majorVersion === 3) {
3363
- if (this.inFlightBuild) {
3364
- return this.inFlightBuild;
3365
- }
3366
- const executionOptions = resolveTailwindExecutionOptions(this.options, this.majorVersion);
3367
- const buildOptions = {
3368
- cwd: executionOptions.cwd,
3369
- majorVersion: this.majorVersion,
3370
- ...executionOptions.config === void 0 ? {} : { config: executionOptions.config },
3371
- ...executionOptions.postcssPlugin === void 0 ? {} : { postcssPlugin: executionOptions.postcssPlugin }
3372
- };
3373
- this.inFlightBuild = runTailwindBuild(buildOptions).then(() => void 0);
3374
- try {
3375
- await this.inFlightBuild;
3376
- } finally {
3377
- this.inFlightBuild = void 0;
3378
- }
3379
- }
3385
+ return this.collector.getContexts();
3380
3386
  }
3381
3387
  createPatchSnapshot() {
3382
3388
  const entries = [];
@@ -3420,11 +3426,14 @@ var TailwindcssPatcher = class {
3420
3426
  }
3421
3427
  async collectClassSet() {
3422
3428
  if (this.majorVersion === 4) {
3423
- return collectClassesFromTailwindV4(this.options);
3429
+ return this.collector.collectClassSet();
3424
3430
  }
3425
3431
  const contexts = this.getContexts();
3426
3432
  return collectClassesFromContexts(contexts, this.options.filter);
3427
3433
  }
3434
+ async runTailwindBuildIfNeeded() {
3435
+ await this.collector.runTailwindBuildIfNeeded?.();
3436
+ }
3428
3437
  debugCacheRead(meta) {
3429
3438
  if (meta.hit) {
3430
3439
  logger_default.debug(
@@ -4564,7 +4573,7 @@ import fs15 from "fs-extra";
4564
4573
  import path16 from "pathe";
4565
4574
  var DEFAULT_CONFIG_NAME = "tailwindcss-mangle";
4566
4575
  async function installCommandDefaultHandler(_ctx) {
4567
- const patcher = new TailwindcssPatcher();
4576
+ const patcher = await _ctx.createPatcher();
4568
4577
  await patcher.patch();
4569
4578
  logger_default.success("Tailwind CSS runtime patched successfully.");
4570
4579
  }
@@ -4996,13 +5005,14 @@ function registerTailwindcssPatchCommand(cli, commandName, options, prefix, defa
4996
5005
  const command = cli.command(metadata.name, metadata.description);
4997
5006
  applyCommandOptions(command, metadata.optionDefs);
4998
5007
  command.action(async (args) => {
5008
+ const defaultHandler = defaultCommandHandlers[commandName];
4999
5009
  return runWithCommandHandler(
5000
5010
  cli,
5001
5011
  command,
5002
5012
  commandName,
5003
5013
  args,
5004
5014
  options.commandHandlers?.[commandName],
5005
- defaultCommandHandlers[commandName]
5015
+ defaultHandler
5006
5016
  );
5007
5017
  });
5008
5018
  metadata.aliases.forEach((alias) => command.alias(alias));