tailwindcss-patch 8.2.4 → 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -285,105 +285,6 @@ function groupTokensByFile(report, options) {
285
285
  }, {});
286
286
  }
287
287
 
288
- // src/options/legacy.ts
289
- function normalizeLegacyFeatures(patch) {
290
- const apply = patch?.applyPatches;
291
- const extend = apply?.extendLengthUnits;
292
- let extendOption = false;
293
- if (extend && typeof extend === "object") {
294
- extendOption = {
295
- ...extend,
296
- enabled: true
297
- };
298
- } else if (extend === true) {
299
- extendOption = {
300
- enabled: true,
301
- units: ["rpx"],
302
- overwrite: patch?.overwrite
303
- };
304
- }
305
- return {
306
- exposeContext: apply?.exportContext ?? true,
307
- extendLengthUnits: extendOption
308
- };
309
- }
310
- function fromLegacyOptions(options) {
311
- if (!options) {
312
- return {};
313
- }
314
- const patch = options.patch;
315
- const features = normalizeLegacyFeatures(patch);
316
- const output = patch?.output;
317
- const tailwindConfig = patch?.tailwindcss;
318
- const tailwindVersion = tailwindConfig?.version;
319
- const tailwindV2 = tailwindConfig?.v2;
320
- const tailwindV3 = tailwindConfig?.v3;
321
- const tailwindV4 = tailwindConfig?.v4;
322
- const tailwindConfigPath = tailwindV3?.config ?? tailwindV2?.config;
323
- const tailwindCwd = tailwindV3?.cwd ?? tailwindV2?.cwd ?? patch?.cwd;
324
- return {
325
- cwd: patch?.cwd,
326
- overwrite: patch?.overwrite,
327
- filter: patch?.filter,
328
- cache: typeof options.cache === "boolean" ? options.cache : options.cache ? {
329
- ...options.cache,
330
- enabled: options.cache.enabled ?? true
331
- } : void 0,
332
- output: output ? {
333
- file: output.filename,
334
- pretty: output.loose ? 2 : false,
335
- removeUniversalSelector: output.removeUniversalSelector
336
- } : void 0,
337
- tailwind: {
338
- packageName: patch?.packageName,
339
- version: tailwindVersion,
340
- resolve: patch?.resolve,
341
- config: tailwindConfigPath,
342
- cwd: tailwindCwd,
343
- v2: tailwindV2,
344
- v3: tailwindV3,
345
- v4: tailwindV4
346
- },
347
- features: {
348
- exposeContext: features.exposeContext,
349
- extendLengthUnits: features.extendLengthUnits
350
- }
351
- };
352
- }
353
- function fromUnifiedConfig(registry) {
354
- if (!registry) {
355
- return {};
356
- }
357
- const tailwind = registry.tailwind;
358
- const output = registry.output;
359
- const pretty = (() => {
360
- if (output?.pretty === void 0) {
361
- return void 0;
362
- }
363
- if (typeof output.pretty === "boolean") {
364
- return output.pretty ? 2 : false;
365
- }
366
- return output.pretty;
367
- })();
368
- return {
369
- output: output ? {
370
- file: output.file,
371
- pretty,
372
- removeUniversalSelector: output.stripUniversalSelector
373
- } : void 0,
374
- tailwind: tailwind ? {
375
- version: tailwind.version,
376
- packageName: tailwind.package,
377
- resolve: tailwind.resolve,
378
- config: tailwind.config,
379
- cwd: tailwind.cwd,
380
- v2: tailwind.legacy,
381
- v3: tailwind.classic,
382
- v4: tailwind.next
383
- } : void 0
384
- };
385
- }
386
-
387
288
  // src/options/normalize.ts
388
289
  import process2 from "process";
389
290
  import path2 from "pathe";
@@ -761,6 +662,105 @@ import { getPackageInfoSync } from "local-pkg";
761
662
  import path8 from "pathe";
762
663
  import { coerce } from "semver";
763
664
 
665
+ // src/options/legacy.ts
666
+ function normalizeLegacyFeatures(patch) {
667
+ const apply = patch?.applyPatches;
668
+ const extend = apply?.extendLengthUnits;
669
+ let extendOption = false;
670
+ if (extend && typeof extend === "object") {
671
+ extendOption = {
672
+ ...extend,
673
+ enabled: true
674
+ };
675
+ } else if (extend === true) {
676
+ extendOption = {
677
+ enabled: true,
678
+ units: ["rpx"],
679
+ overwrite: patch?.overwrite
680
+ };
681
+ }
682
+ return {
683
+ exposeContext: apply?.exportContext ?? true,
684
+ extendLengthUnits: extendOption
685
+ };
686
+ }
687
+ function fromLegacyOptions(options) {
688
+ if (!options) {
689
+ return {};
690
+ }
691
+ const patch = options.patch;
692
+ const features = normalizeLegacyFeatures(patch);
693
+ const output = patch?.output;
694
+ const tailwindConfig = patch?.tailwindcss;
695
+ const tailwindVersion = tailwindConfig?.version;
696
+ const tailwindV2 = tailwindConfig?.v2;
697
+ const tailwindV3 = tailwindConfig?.v3;
698
+ const tailwindV4 = tailwindConfig?.v4;
699
+ const tailwindConfigPath = tailwindV3?.config ?? tailwindV2?.config;
700
+ const tailwindCwd = tailwindV3?.cwd ?? tailwindV2?.cwd ?? patch?.cwd;
701
+ return {
702
+ cwd: patch?.cwd,
703
+ overwrite: patch?.overwrite,
704
+ filter: patch?.filter,
705
+ cache: typeof options.cache === "boolean" ? options.cache : options.cache ? {
706
+ ...options.cache,
707
+ enabled: options.cache.enabled ?? true
708
+ } : void 0,
709
+ output: output ? {
710
+ file: output.filename,
711
+ pretty: output.loose ? 2 : false,
712
+ removeUniversalSelector: output.removeUniversalSelector
713
+ } : void 0,
714
+ tailwind: {
715
+ packageName: patch?.packageName,
716
+ version: tailwindVersion,
717
+ resolve: patch?.resolve,
718
+ config: tailwindConfigPath,
719
+ cwd: tailwindCwd,
720
+ v2: tailwindV2,
721
+ v3: tailwindV3,
722
+ v4: tailwindV4
723
+ },
724
+ features: {
725
+ exposeContext: features.exposeContext,
726
+ extendLengthUnits: features.extendLengthUnits
727
+ }
728
+ };
729
+ }
730
+ function fromUnifiedConfig(registry) {
731
+ if (!registry) {
732
+ return {};
733
+ }
734
+ const tailwind = registry.tailwind;
735
+ const output = registry.output;
736
+ const pretty = (() => {
737
+ if (output?.pretty === void 0) {
738
+ return void 0;
739
+ }
740
+ if (typeof output.pretty === "boolean") {
741
+ return output.pretty ? 2 : false;
742
+ }
743
+ return output.pretty;
744
+ })();
745
+ return {
746
+ output: output ? {
747
+ file: output.file,
748
+ pretty,
749
+ removeUniversalSelector: output.stripUniversalSelector
750
+ } : void 0,
751
+ tailwind: tailwind ? {
752
+ version: tailwind.version,
753
+ packageName: tailwind.package,
754
+ resolve: tailwind.resolve,
755
+ config: tailwind.config,
756
+ cwd: tailwind.cwd,
757
+ v2: tailwind.legacy,
758
+ v3: tailwind.classic,
759
+ v4: tailwind.next
760
+ } : void 0
761
+ };
762
+ }
763
+
764
764
  // src/patching/operations/export-context/index.ts
765
765
  import fs5 from "fs-extra";
766
766
  import path6 from "pathe";
@@ -802,8 +802,8 @@ function transformProcessTailwindFeaturesReturnContextV2(content) {
802
802
  });
803
803
  let hasPatched = false;
804
804
  traverse(ast, {
805
- FunctionDeclaration(path9) {
806
- const node = path9.node;
805
+ FunctionDeclaration(path10) {
806
+ const node = path10.node;
807
807
  if (node.id?.name !== "processTailwindFeatures" || node.body.body.length !== 1 || !t.isReturnStatement(node.body.body[0])) {
808
808
  return;
809
809
  }
@@ -834,8 +834,8 @@ function transformPostcssPluginV2(content, options) {
834
834
  const ast = parse(content);
835
835
  let hasPatched = false;
836
836
  traverse(ast, {
837
- Program(path9) {
838
- const program = path9.node;
837
+ Program(path10) {
838
+ const program = path10.node;
839
839
  const index = program.body.findIndex((statement) => {
840
840
  return t.isFunctionDeclaration(statement) && statement.id?.name === "_default";
841
841
  });
@@ -869,11 +869,11 @@ function transformPostcssPluginV2(content, options) {
869
869
  );
870
870
  }
871
871
  },
872
- FunctionDeclaration(path9) {
872
+ FunctionDeclaration(path10) {
873
873
  if (hasPatched) {
874
874
  return;
875
875
  }
876
- const fn = path9.node;
876
+ const fn = path10.node;
877
877
  if (fn.id?.name !== "_default") {
878
878
  return;
879
879
  }
@@ -962,8 +962,8 @@ function transformProcessTailwindFeaturesReturnContext(content) {
962
962
  const ast = parse(content);
963
963
  let hasPatched = false;
964
964
  traverse(ast, {
965
- FunctionDeclaration(path9) {
966
- const node = path9.node;
965
+ FunctionDeclaration(path10) {
966
+ const node = path10.node;
967
967
  if (node.id?.name !== "processTailwindFeatures" || node.body.body.length !== 1) {
968
968
  return;
969
969
  }
@@ -995,8 +995,8 @@ function transformPostcssPlugin(content, { refProperty }) {
995
995
  const valueMember = t2.memberExpression(refIdentifier, t2.identifier("value"));
996
996
  let hasPatched = false;
997
997
  traverse(ast, {
998
- Program(path9) {
999
- const program = path9.node;
998
+ Program(path10) {
999
+ const program = path10.node;
1000
1000
  const index = program.body.findIndex((statement) => {
1001
1001
  return t2.isExpressionStatement(statement) && t2.isAssignmentExpression(statement.expression) && t2.isMemberExpression(statement.expression.left) && t2.isFunctionExpression(statement.expression.right) && statement.expression.right.id?.name === "tailwindcss";
1002
1002
  });
@@ -1034,11 +1034,11 @@ function transformPostcssPlugin(content, { refProperty }) {
1034
1034
  );
1035
1035
  }
1036
1036
  },
1037
- FunctionExpression(path9) {
1037
+ FunctionExpression(path10) {
1038
1038
  if (hasPatched) {
1039
1039
  return;
1040
1040
  }
1041
- const fn = path9.node;
1041
+ const fn = path10.node;
1042
1042
  if (fn.id?.name !== "tailwindcss" || fn.body.body.length !== 1) {
1043
1043
  return;
1044
1044
  }
@@ -1204,21 +1204,21 @@ function updateLengthUnitsArray(content, options) {
1204
1204
  let arrayRef;
1205
1205
  let changed = false;
1206
1206
  traverse(ast, {
1207
- Identifier(path9) {
1208
- if (path9.node.name === variableName && t3.isVariableDeclarator(path9.parent) && t3.isArrayExpression(path9.parent.init)) {
1209
- arrayRef = path9.parent.init;
1207
+ Identifier(path10) {
1208
+ if (path10.node.name === variableName && t3.isVariableDeclarator(path10.parent) && t3.isArrayExpression(path10.parent.init)) {
1209
+ arrayRef = path10.parent.init;
1210
1210
  const existing = new Set(
1211
- path9.parent.init.elements.map((element) => t3.isStringLiteral(element) ? element.value : void 0).filter(Boolean)
1211
+ path10.parent.init.elements.map((element) => t3.isStringLiteral(element) ? element.value : void 0).filter(Boolean)
1212
1212
  );
1213
1213
  for (const unit of units) {
1214
1214
  if (!existing.has(unit)) {
1215
- path9.parent.init.elements = path9.parent.init.elements.map((element) => {
1215
+ path10.parent.init.elements = path10.parent.init.elements.map((element) => {
1216
1216
  if (t3.isStringLiteral(element)) {
1217
1217
  return t3.stringLiteral(element.value);
1218
1218
  }
1219
1219
  return element;
1220
1220
  });
1221
- path9.parent.init.elements.push(t3.stringLiteral(unit));
1221
+ path10.parent.init.elements.push(t3.stringLiteral(unit));
1222
1222
  changed = true;
1223
1223
  }
1224
1224
  }
@@ -1299,13 +1299,13 @@ function applyExtendLengthUnitsPatchV4(rootDir, options) {
1299
1299
  const { code, file, match } = item;
1300
1300
  const ast = parse(match[0], { sourceType: "unambiguous" });
1301
1301
  traverse(ast, {
1302
- ArrayExpression(path9) {
1302
+ ArrayExpression(path10) {
1303
1303
  for (const unit of opts.units) {
1304
- if (path9.node.elements.some((element) => t3.isStringLiteral(element) && element.value === unit)) {
1304
+ if (path10.node.elements.some((element) => t3.isStringLiteral(element) && element.value === unit)) {
1305
1305
  item.hasPatched = true;
1306
1306
  return;
1307
1307
  }
1308
- path9.node.elements.push(t3.stringLiteral(unit));
1308
+ path10.node.elements.push(t3.stringLiteral(unit));
1309
1309
  }
1310
1310
  }
1311
1311
  });
@@ -1558,6 +1558,287 @@ var TailwindcssPatcher = class {
1558
1558
  }
1559
1559
  };
1560
1560
 
1561
+ // src/cli/commands.ts
1562
+ import process5 from "process";
1563
+ import { CONFIG_NAME, getConfig, initConfig } from "@tailwindcss-mangle/config";
1564
+
1565
+ // ../../node_modules/.pnpm/defu@6.1.4/node_modules/defu/dist/defu.mjs
1566
+ function isPlainObject(value) {
1567
+ if (value === null || typeof value !== "object") {
1568
+ return false;
1569
+ }
1570
+ const prototype = Object.getPrototypeOf(value);
1571
+ if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
1572
+ return false;
1573
+ }
1574
+ if (Symbol.iterator in value) {
1575
+ return false;
1576
+ }
1577
+ if (Symbol.toStringTag in value) {
1578
+ return Object.prototype.toString.call(value) === "[object Module]";
1579
+ }
1580
+ return true;
1581
+ }
1582
+ function _defu(baseObject, defaults, namespace = ".", merger) {
1583
+ if (!isPlainObject(defaults)) {
1584
+ return _defu(baseObject, {}, namespace, merger);
1585
+ }
1586
+ const object = Object.assign({}, defaults);
1587
+ for (const key in baseObject) {
1588
+ if (key === "__proto__" || key === "constructor") {
1589
+ continue;
1590
+ }
1591
+ const value = baseObject[key];
1592
+ if (value === null || value === void 0) {
1593
+ continue;
1594
+ }
1595
+ if (merger && merger(object, key, value, namespace)) {
1596
+ continue;
1597
+ }
1598
+ if (Array.isArray(value) && Array.isArray(object[key])) {
1599
+ object[key] = [...value, ...object[key]];
1600
+ } else if (isPlainObject(value) && isPlainObject(object[key])) {
1601
+ object[key] = _defu(
1602
+ value,
1603
+ object[key],
1604
+ (namespace ? `${namespace}.` : "") + key.toString(),
1605
+ merger
1606
+ );
1607
+ } else {
1608
+ object[key] = value;
1609
+ }
1610
+ }
1611
+ return object;
1612
+ }
1613
+ function createDefu(merger) {
1614
+ return (...arguments_) => (
1615
+ // eslint-disable-next-line unicorn/no-array-reduce
1616
+ arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
1617
+ );
1618
+ }
1619
+ var defu = createDefu();
1620
+ var defuFn = createDefu((object, key, currentValue) => {
1621
+ if (object[key] !== void 0 && typeof currentValue === "function") {
1622
+ object[key] = currentValue(object[key]);
1623
+ return true;
1624
+ }
1625
+ });
1626
+ var defuArrayFn = createDefu((object, key, currentValue) => {
1627
+ if (Array.isArray(object[key]) && typeof currentValue === "function") {
1628
+ object[key] = currentValue(object[key]);
1629
+ return true;
1630
+ }
1631
+ });
1632
+
1633
+ // ../shared/src/utils.ts
1634
+ var defuOverrideArray = createDefu((obj, key, value) => {
1635
+ if (Array.isArray(obj[key]) && Array.isArray(value)) {
1636
+ obj[key] = value;
1637
+ return true;
1638
+ }
1639
+ });
1640
+ var preserveClassNames = [
1641
+ // https://tailwindcss.com/docs/transition-timing-function start
1642
+ // https://github.com/sonofmagic/tailwindcss-mangle/issues/21
1643
+ "ease-out",
1644
+ "ease-linear",
1645
+ "ease-in",
1646
+ "ease-in-out"
1647
+ // https://tailwindcss.com/docs/transition-timing-function end
1648
+ ];
1649
+ var preserveClassNamesMap = preserveClassNames.reduce((acc, cur) => {
1650
+ acc[cur] = true;
1651
+ return acc;
1652
+ }, {});
1653
+ var acceptChars = [..."abcdefghijklmnopqrstuvwxyz"];
1654
+
1655
+ // src/cli/commands.ts
1656
+ import cac from "cac";
1657
+ import fs8 from "fs-extra";
1658
+ import path9 from "pathe";
1659
+ var tailwindcssPatchCommands = [
1660
+ "install",
1661
+ "extract",
1662
+ "tokens",
1663
+ "init"
1664
+ ];
1665
+ function createTailwindcssPatchCli(options = {}) {
1666
+ const cli = cac(options.name ?? "tw-patch");
1667
+ mountTailwindcssPatchCommands(cli, options.mountOptions);
1668
+ return cli;
1669
+ }
1670
+ function mountTailwindcssPatchCommands(cli, options = {}) {
1671
+ const prefix = options.commandPrefix ?? "";
1672
+ const selectedCommands = options.commands ?? tailwindcssPatchCommands;
1673
+ const TOKEN_FORMATS = ["json", "lines", "grouped-json"];
1674
+ const registrars = {
1675
+ install() {
1676
+ const { name, aliases } = resolveCommandNames("install", options, prefix);
1677
+ const command = cli.command(name, "Apply Tailwind CSS runtime patches").option("--cwd <dir>", "Working directory", { default: process5.cwd() }).action(async (args) => {
1678
+ const patchOptions = await loadPatchOptions(args.cwd);
1679
+ const patcher = new TailwindcssPatcher(patchOptions);
1680
+ await patcher.patch();
1681
+ logger_default.success("Tailwind CSS runtime patched successfully.");
1682
+ });
1683
+ aliases.forEach((alias) => command.alias(alias));
1684
+ },
1685
+ extract() {
1686
+ const { name, aliases } = resolveCommandNames("extract", options, prefix);
1687
+ const command = cli.command(name, "Collect generated class names into a cache file").option("--cwd <dir>", "Working directory", { default: process5.cwd() }).option("--output <file>", "Override output file path").option("--format <format>", "Output format (json|lines)").option("--css <file>", "Tailwind CSS entry CSS when using v4").option("--no-write", "Skip writing to disk").action(async (args) => {
1688
+ const overrides = {};
1689
+ if (args.output || args.format) {
1690
+ overrides.output = {
1691
+ file: args.output,
1692
+ format: args.format
1693
+ };
1694
+ }
1695
+ if (args.css) {
1696
+ overrides.tailwind = {
1697
+ v4: {
1698
+ cssEntries: [args.css]
1699
+ }
1700
+ };
1701
+ }
1702
+ const patchOptions = await loadPatchOptions(args.cwd, overrides);
1703
+ const patcher = new TailwindcssPatcher(patchOptions);
1704
+ const result = await patcher.extract({ write: args.write });
1705
+ if (result.filename) {
1706
+ logger_default.success(`Collected ${result.classList.length} classes \u2192 ${result.filename}`);
1707
+ } else {
1708
+ logger_default.success(`Collected ${result.classList.length} classes.`);
1709
+ }
1710
+ });
1711
+ aliases.forEach((alias) => command.alias(alias));
1712
+ },
1713
+ tokens() {
1714
+ const { name, aliases } = resolveCommandNames("tokens", options, prefix);
1715
+ const command = cli.command(name, "Extract Tailwind tokens with file/position metadata").option("--cwd <dir>", "Working directory", { default: process5.cwd() }).option("--output <file>", "Override output file path", { default: ".tw-patch/tw-token-report.json" }).option("--format <format>", "Output format (json|lines|grouped-json)", { default: "json" }).option("--group-key <key>", "Grouping key for grouped-json output (relative|absolute)", { default: "relative" }).option("--no-write", "Skip writing to disk").action(async (args) => {
1716
+ const patchOptions = await loadPatchOptions(args.cwd);
1717
+ const patcher = new TailwindcssPatcher(patchOptions);
1718
+ const report = await patcher.collectContentTokens();
1719
+ const shouldWrite = args.write ?? true;
1720
+ let format = args.format ?? "json";
1721
+ if (!TOKEN_FORMATS.includes(format)) {
1722
+ format = "json";
1723
+ }
1724
+ const targetFile = args.output ?? ".tw-patch/tw-token-report.json";
1725
+ const groupKey = args.groupKey === "absolute" ? "absolute" : "relative";
1726
+ const buildGrouped = () => groupTokensByFile(report, {
1727
+ key: groupKey,
1728
+ stripAbsolutePaths: groupKey !== "absolute"
1729
+ });
1730
+ const grouped = format === "grouped-json" ? buildGrouped() : null;
1731
+ const resolveGrouped = () => grouped ?? buildGrouped();
1732
+ if (shouldWrite) {
1733
+ const target = path9.resolve(targetFile);
1734
+ await fs8.ensureDir(path9.dirname(target));
1735
+ if (format === "json") {
1736
+ await fs8.writeJSON(target, report, { spaces: 2 });
1737
+ } else if (format === "grouped-json") {
1738
+ await fs8.writeJSON(target, resolveGrouped(), { spaces: 2 });
1739
+ } else {
1740
+ const lines = report.entries.map(formatTokenLine);
1741
+ await fs8.writeFile(target, `${lines.join("\n")}
1742
+ `, "utf8");
1743
+ }
1744
+ logger_default.success(
1745
+ `Collected ${report.entries.length} tokens (${format}) \u2192 ${target.replace(process5.cwd(), ".")}`
1746
+ );
1747
+ } else {
1748
+ logger_default.success(`Collected ${report.entries.length} tokens from ${report.filesScanned} files.`);
1749
+ if (format === "lines") {
1750
+ const preview = report.entries.slice(0, 5).map(formatTokenLine).join("\n");
1751
+ if (preview) {
1752
+ logger_default.log("");
1753
+ logger_default.info(preview);
1754
+ if (report.entries.length > 5) {
1755
+ logger_default.info(`\u2026and ${report.entries.length - 5} more.`);
1756
+ }
1757
+ }
1758
+ } else if (format === "grouped-json") {
1759
+ const map = resolveGrouped();
1760
+ const { preview, moreFiles } = formatGroupedPreview(map);
1761
+ if (preview) {
1762
+ logger_default.log("");
1763
+ logger_default.info(preview);
1764
+ if (moreFiles > 0) {
1765
+ logger_default.info(`\u2026and ${moreFiles} more files.`);
1766
+ }
1767
+ }
1768
+ } else {
1769
+ const previewEntries = report.entries.slice(0, 3);
1770
+ if (previewEntries.length) {
1771
+ logger_default.log("");
1772
+ logger_default.info(JSON.stringify(previewEntries, null, 2));
1773
+ }
1774
+ }
1775
+ }
1776
+ if (report.skippedFiles.length) {
1777
+ logger_default.warn("Skipped files:");
1778
+ for (const skipped of report.skippedFiles) {
1779
+ logger_default.warn(` \u2022 ${skipped.file} (${skipped.reason})`);
1780
+ }
1781
+ }
1782
+ });
1783
+ aliases.forEach((alias) => command.alias(alias));
1784
+ },
1785
+ init() {
1786
+ const { name, aliases } = resolveCommandNames("init", options, prefix);
1787
+ const command = cli.command(name, "Generate a tailwindcss-patch config file").option("--cwd <dir>", "Working directory", { default: process5.cwd() }).action(async (args) => {
1788
+ await initConfig(args.cwd);
1789
+ logger_default.success(`\u2728 ${CONFIG_NAME}.config.ts initialized!`);
1790
+ });
1791
+ aliases.forEach((alias) => command.alias(alias));
1792
+ }
1793
+ };
1794
+ for (const name of selectedCommands) {
1795
+ const register = registrars[name];
1796
+ if (register) {
1797
+ register();
1798
+ }
1799
+ }
1800
+ return cli;
1801
+ }
1802
+ async function loadPatchOptions(cwd, overrides) {
1803
+ const { config } = await getConfig(cwd);
1804
+ const legacyConfig = config;
1805
+ const base = config?.registry ? fromUnifiedConfig(config.registry) : legacyConfig?.patch ? fromLegacyOptions({ patch: legacyConfig.patch }) : {};
1806
+ const merged = defu(overrides ?? {}, base);
1807
+ return merged;
1808
+ }
1809
+ function resolveCommandNames(command, mountOptions, prefix) {
1810
+ const override = mountOptions.commandOptions?.[command];
1811
+ const baseName = override?.name ?? command;
1812
+ const name = addPrefixIfMissing(baseName, prefix);
1813
+ const aliases = (override?.aliases ?? []).map((alias) => addPrefixIfMissing(alias, prefix));
1814
+ return { name, aliases };
1815
+ }
1816
+ function addPrefixIfMissing(value, prefix) {
1817
+ if (!prefix || value.startsWith(prefix)) {
1818
+ return value;
1819
+ }
1820
+ return `${prefix}${value}`;
1821
+ }
1822
+ function formatTokenLine(entry) {
1823
+ return `${entry.relativeFile}:${entry.line}:${entry.column} ${entry.rawCandidate} (${entry.start}-${entry.end})`;
1824
+ }
1825
+ function formatGroupedPreview(map, limit = 3) {
1826
+ const files = Object.keys(map);
1827
+ if (!files.length) {
1828
+ return { preview: "", moreFiles: 0 };
1829
+ }
1830
+ const lines = files.slice(0, limit).map((file) => {
1831
+ const tokens = map[file];
1832
+ const sample = tokens.slice(0, 3).map((token) => token.rawCandidate).join(", ");
1833
+ const suffix = tokens.length > 3 ? ", \u2026" : "";
1834
+ return `${file}: ${tokens.length} tokens (${sample}${suffix})`;
1835
+ });
1836
+ return {
1837
+ preview: lines.join("\n"),
1838
+ moreFiles: Math.max(0, files.length - limit)
1839
+ };
1840
+ }
1841
+
1561
1842
  export {
1562
1843
  logger_default,
1563
1844
  CacheStore,
@@ -1566,12 +1847,13 @@ export {
1566
1847
  extractValidCandidates,
1567
1848
  extractProjectCandidatesWithPositions,
1568
1849
  groupTokensByFile,
1569
- fromLegacyOptions,
1570
- fromUnifiedConfig,
1571
1850
  normalizeOptions,
1572
1851
  collectClassesFromContexts,
1573
1852
  collectClassesFromTailwindV4,
1574
1853
  loadRuntimeContexts,
1575
1854
  runTailwindBuild,
1576
- TailwindcssPatcher
1855
+ TailwindcssPatcher,
1856
+ tailwindcssPatchCommands,
1857
+ createTailwindcssPatchCli,
1858
+ mountTailwindcssPatchCommands
1577
1859
  };