tailwindcss-patch 9.4.4 → 9.5.1

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 (36) hide show
  1. package/dist/{cli-CLvyx3xl.mjs → cli-Bv15iTiT.mjs} +1 -1
  2. package/dist/{cli-srv0kRlt.js → cli-Db2YAbkN.js} +3 -2
  3. package/dist/cli.js +2 -2
  4. package/dist/cli.mjs +2 -2
  5. package/dist/commands/cli-runtime.d.mts +1 -1
  6. package/dist/commands/cli-runtime.d.ts +1 -1
  7. package/dist/commands/cli-runtime.js +2 -2
  8. package/dist/commands/cli-runtime.mjs +2 -2
  9. package/dist/{dist-Dn7cMVhi.js → dist-wp0o36Ns.js} +1 -1
  10. package/dist/index.d.mts +7 -149
  11. package/dist/index.d.ts +8 -150
  12. package/dist/index.js +294 -521
  13. package/dist/index.mjs +6 -471
  14. package/dist/{validate-oAkURzUC.d.mts → validate-B5-08lrU.d.ts} +8 -252
  15. package/dist/{validate-RpdgpjgT.js → validate-C8oLv32F.js} +79 -1705
  16. package/dist/{validate-BuqRodYI.d.ts → validate-CgrG4aAY.d.mts} +8 -252
  17. package/dist/{validate-CUNJFfHh.mjs → validate-Cu1G06lO.mjs} +5 -1402
  18. package/package.json +5 -7
  19. package/src/api/tailwindcss-patcher.ts +3 -2
  20. package/src/extraction/candidate-extractor.ts +17 -701
  21. package/src/extraction/split-candidate-tokens.ts +5 -101
  22. package/src/options/types.ts +1 -2
  23. package/src/style-candidates.ts +5 -35
  24. package/src/style-generator.ts +11 -80
  25. package/src/types.ts +21 -95
  26. package/src/v3/index.ts +2 -2
  27. package/src/v4/index.ts +104 -28
  28. package/src/v3/style-generator.ts +0 -384
  29. package/src/v4/bare-arbitrary-values.ts +0 -545
  30. package/src/v4/candidates.ts +0 -316
  31. package/src/v4/engine.ts +0 -112
  32. package/src/v4/node-adapter.ts +0 -207
  33. package/src/v4/source-scan.ts +0 -432
  34. package/src/v4/source.ts +0 -235
  35. package/src/v4/style-generator.ts +0 -44
  36. package/src/v4/types.ts +0 -103
@@ -32,12 +32,7 @@ let semver = require("semver");
32
32
  let node_crypto = require("node:crypto");
33
33
  let consola = require("consola");
34
34
  let node_url = require("node:url");
35
- let node_fs = require("node:fs");
36
- let postcss = require("postcss");
37
- postcss = __toESM(postcss);
38
- let node_fs_promises = require("node:fs/promises");
39
- let micromatch = require("micromatch");
40
- micromatch = __toESM(micromatch);
35
+ let _tailwindcss_mangle_engine = require("@tailwindcss-mangle/engine");
41
36
  let _babel_types = require("@babel/types");
42
37
  _babel_types = __toESM(_babel_types);
43
38
  let _babel_generator = require("@babel/generator");
@@ -45,9 +40,11 @@ _babel_generator = __toESM(_babel_generator);
45
40
  let _babel_traverse = require("@babel/traverse");
46
41
  _babel_traverse = __toESM(_babel_traverse);
47
42
  let _babel_parser = require("@babel/parser");
43
+ let postcss = require("postcss");
44
+ postcss = __toESM(postcss);
48
45
  let tailwindcss_config = require("tailwindcss-config");
49
46
  //#region package.json
50
- var version = "9.4.4";
47
+ var version = "9.5.1";
51
48
  //#endregion
52
49
  //#region src/constants.ts
53
50
  const pkgName = "tailwindcss-patch";
@@ -1400,1481 +1397,86 @@ function normalizeTailwindOptions(tailwind, projectRoot, shouldDefaultResolveFro
1400
1397
  v4
1401
1398
  };
1402
1399
  }
1403
- const deprecatedOptionMapping = {
1404
- cwd: "projectRoot",
1405
- overwrite: "apply.overwrite",
1406
- tailwind: "tailwindcss",
1407
- features: "apply",
1408
- output: "extract"
1409
- };
1410
- function assertNoDeprecatedOptions(options) {
1411
- const used = Object.keys(deprecatedOptionMapping).filter((key) => Object.hasOwn(options, key));
1412
- if (used.length === 0) return;
1413
- const mapping = used.map((key) => `${key} -> ${deprecatedOptionMapping[key]}`).join(", ");
1414
- throw new Error(`Legacy TailwindcssPatcher options are no longer supported: ${used.join(", ")}. Use the modern fields instead: ${mapping}.`);
1415
- }
1416
- function normalizeOptions(options = {}) {
1417
- assertNoDeprecatedOptions(options);
1418
- const projectRoot = resolveRealpathSafe(options.projectRoot ? pathe.default.resolve(options.projectRoot) : node_process.default.cwd());
1419
- const overwrite = options.apply?.overwrite ?? true;
1420
- const output = normalizeOutputOptions(options.extract);
1421
- const cache = normalizeCacheOptions(options.cache, projectRoot);
1422
- const tailwind = normalizeTailwindOptions(options.tailwindcss, projectRoot, options.projectRoot !== void 0 || options.tailwindcss?.cwd !== void 0);
1423
- const exposeContext = normalizeExposeContextOptions(options.apply?.exposeContext);
1424
- const extendLengthUnits = normalizeExtendLengthUnitsOptions(options.apply?.extendLengthUnits);
1425
- const filter = (className) => {
1426
- if (output.removeUniversalSelector && className === "*") return false;
1427
- if (typeof options.filter === "function") return options.filter(className) !== false;
1428
- return true;
1429
- };
1430
- return {
1431
- projectRoot,
1432
- overwrite,
1433
- tailwind,
1434
- features: {
1435
- exposeContext,
1436
- extendLengthUnits
1437
- },
1438
- output,
1439
- cache,
1440
- filter
1441
- };
1442
- }
1443
- //#endregion
1444
- //#region src/config/workspace.ts
1445
- let configModulePromise;
1446
- let defuPromise;
1447
- function isNodeError$1(error) {
1448
- return !!error && typeof error === "object" && ("code" in error || "message" in error);
1449
- }
1450
- function isMissingModuleError(error, pkgName) {
1451
- if (!isNodeError$1(error)) return false;
1452
- const code = error.code;
1453
- if (code !== "MODULE_NOT_FOUND" && code !== "ERR_MODULE_NOT_FOUND") return false;
1454
- const message = error.message ?? "";
1455
- return message.includes(pkgName) || message.includes(`${pkgName}/dist/`);
1456
- }
1457
- function isMissingConfigModuleError(error) {
1458
- return isMissingModuleError(error, "@tailwindcss-mangle/config");
1459
- }
1460
- function isMissingSharedModuleError(error) {
1461
- return isMissingModuleError(error, "@tailwindcss-mangle/shared");
1462
- }
1463
- async function loadWorkspaceConfigModule() {
1464
- if (!configModulePromise) configModulePromise = import("@tailwindcss-mangle/config").catch(async (error) => {
1465
- if (!isMissingConfigModuleError(error)) throw error;
1466
- return import((0, node_url.pathToFileURL)(pathe.default.resolve(__dirname, "../../../config/src/index.ts")).href);
1467
- });
1468
- return configModulePromise;
1469
- }
1470
- async function loadWorkspaceDefu() {
1471
- if (!defuPromise) defuPromise = Promise.resolve().then(() => require("./dist-Dn7cMVhi.js")).then((mod) => mod.defu).catch(async (error) => {
1472
- if (!isMissingSharedModuleError(error)) throw error;
1473
- return (await import((0, node_url.pathToFileURL)(pathe.default.resolve(__dirname, "../../../shared/src/utils.ts")).href)).defu;
1474
- });
1475
- return defuPromise;
1476
- }
1477
- async function loadPatchOptionsForWorkspace(cwd, overrides) {
1478
- const merge = await loadWorkspaceDefu();
1479
- const { config } = await (await loadWorkspaceConfigModule()).getConfig(cwd);
1480
- if (config && typeof config === "object" && "patch" in config && config.patch !== void 0) throw new Error("Legacy workspace config field \"patch\" is no longer supported. Move patcher options under \"registry\".");
1481
- const base = config?.registry ? fromUnifiedConfig(config.registry) : {};
1482
- return merge(overrides ?? {}, base, { projectRoot: cwd });
1483
- }
1484
- //#endregion
1485
- //#region src/v4/bare-arbitrary-values.ts
1486
- const DEFAULT_BARE_ARBITRARY_VALUE_UNITS = [
1487
- "%",
1488
- "px",
1489
- "rpx",
1490
- "rem",
1491
- "em",
1492
- "vw",
1493
- "vh",
1494
- "vmin",
1495
- "vmax",
1496
- "dvw",
1497
- "dvh",
1498
- "svw",
1499
- "svh",
1500
- "lvw",
1501
- "lvh",
1502
- "ch",
1503
- "ex",
1504
- "lh",
1505
- "rlh",
1506
- "fr",
1507
- "deg",
1508
- "rad",
1509
- "turn",
1510
- "s",
1511
- "ms"
1512
- ];
1513
- const NUMBER_RE = /^-?(?:\d+|\d*\.\d+)$/;
1514
- const FUNCTION_VALUE_RE = /^[a-z_-][\w-]*\(/i;
1515
- const HEX_ESCAPE_RE = /^[\da-f]$/i;
1516
- const ASPECT_RATIO_RE = /^\d+\/\d+$/;
1517
- const ESCAPED_WHITESPACE_RE = /\\[nrt]/g;
1518
- function splitVariantPrefix(candidate) {
1519
- let depth = 0;
1520
- let quote;
1521
- let lastSeparator = -1;
1522
- for (let index = 0; index < candidate.length; index++) {
1523
- const character = candidate[index];
1524
- if (character === "\\") {
1525
- index++;
1526
- continue;
1527
- }
1528
- if (quote) {
1529
- if (character === quote) quote = void 0;
1530
- continue;
1531
- }
1532
- if (character === "\"" || character === "'") {
1533
- quote = character;
1534
- continue;
1535
- }
1536
- if (character === "[" || character === "(" || character === "{") {
1537
- depth++;
1538
- continue;
1539
- }
1540
- if (character === "]" || character === ")" || character === "}") {
1541
- depth = Math.max(0, depth - 1);
1542
- continue;
1543
- }
1544
- if (depth === 0 && character === ":") lastSeparator = index;
1545
- }
1546
- if (lastSeparator === -1) return {
1547
- prefix: "",
1548
- body: candidate
1549
- };
1550
- return {
1551
- prefix: candidate.slice(0, lastSeparator + 1),
1552
- body: candidate.slice(lastSeparator + 1)
1553
- };
1554
- }
1555
- function isBalancedFunctionValue(value) {
1556
- let depth = 0;
1557
- let quote;
1558
- for (let index = 0; index < value.length; index++) {
1559
- const character = value[index];
1560
- if (character === "\\") {
1561
- index++;
1562
- continue;
1563
- }
1564
- if (quote) {
1565
- if (character === quote) quote = void 0;
1566
- continue;
1567
- }
1568
- if (character === "\"" || character === "'") {
1569
- quote = character;
1570
- continue;
1571
- }
1572
- if (character === "(") {
1573
- depth++;
1574
- continue;
1575
- }
1576
- if (character === ")") {
1577
- depth--;
1578
- if (depth < 0) return false;
1579
- }
1580
- }
1581
- return depth === 0 && quote === void 0;
1582
- }
1583
- function isEscapedAt(value, index) {
1584
- let slashCount = 0;
1585
- for (let slashIndex = index - 1; slashIndex >= 0 && value[slashIndex] === "\\"; slashIndex--) slashCount++;
1586
- return slashCount % 2 === 1;
1587
- }
1588
- function isBalancedBareArbitraryBody(value) {
1589
- let depth = 0;
1590
- let quote;
1591
- for (let index = 0; index < value.length; index++) {
1592
- const character = value[index];
1593
- if (isEscapedAt(value, index)) continue;
1594
- if (quote) {
1595
- if (character === quote) quote = void 0;
1596
- continue;
1597
- }
1598
- if (character === "\"" || character === "'") {
1599
- quote = character;
1600
- continue;
1601
- }
1602
- if (character === "(" || character === "{") {
1603
- depth++;
1604
- continue;
1605
- }
1606
- if (character === ")" || character === "}") {
1607
- depth--;
1608
- if (depth < 0) return false;
1609
- }
1610
- }
1611
- return depth === 0 && quote === void 0;
1612
- }
1613
- function isHexColorValue(value) {
1614
- return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6,8})$/i.test(value);
1615
- }
1616
- function isQuotedValue(value) {
1617
- const quote = value[0];
1618
- if (quote !== "\"" && quote !== "'" || value[value.length - 1] !== quote) return false;
1619
- let escaped = false;
1620
- for (let index = 1; index < value.length - 1; index++) {
1621
- const character = value[index];
1622
- if (escaped) {
1623
- escaped = false;
1624
- continue;
1625
- }
1626
- if (character === "\\") escaped = true;
1627
- }
1628
- return !escaped;
1629
- }
1630
- function normalizeBareArbitraryValueOptions(options) {
1631
- if (options === false || options === void 0 || options === null) return;
1632
- const units = options === true ? DEFAULT_BARE_ARBITRARY_VALUE_UNITS : options.units ?? DEFAULT_BARE_ARBITRARY_VALUE_UNITS;
1633
- const normalizedUnits = [...new Set(units.filter((unit) => typeof unit === "string" && unit.length > 0))];
1634
- if (normalizedUnits.length === 0) return;
1635
- return { units: normalizedUnits.sort((a, b) => b.length - a.length) };
1636
- }
1637
- function isBareArbitraryValuesEnabled(options) {
1638
- return normalizeBareArbitraryValueOptions(options) !== void 0;
1639
- }
1640
- function normalizeEscapedValue(value) {
1641
- let result = "";
1642
- for (let index = 0; index < value.length; index++) {
1643
- const character = value[index];
1644
- if (character !== "\\") {
1645
- result += character;
1646
- continue;
1647
- }
1648
- const nextCharacter = value[index + 1];
1649
- if (nextCharacter === void 0) {
1650
- result += character;
1651
- continue;
1652
- }
1653
- if (HEX_ESCAPE_RE.test(nextCharacter)) {
1654
- let hex = "";
1655
- let nextIndex = index + 1;
1656
- while (nextIndex < value.length && hex.length < 6) {
1657
- const hexCharacter = value[nextIndex];
1658
- if (hexCharacter === void 0 || !HEX_ESCAPE_RE.test(hexCharacter)) break;
1659
- hex += hexCharacter;
1660
- nextIndex++;
1661
- }
1662
- if (/[\t\n\f\r ]/.test(value[nextIndex] ?? "")) nextIndex++;
1663
- const decoded = String.fromCodePoint(Number.parseInt(hex, 16));
1664
- result += decoded === "_" ? "\\_" : decoded;
1665
- index = nextIndex - 1;
1666
- continue;
1667
- }
1668
- result += nextCharacter === "_" ? "\\_" : nextCharacter;
1669
- index++;
1670
- }
1671
- return result;
1672
- }
1673
- function resolveValueWithUnit(body, units) {
1674
- const value = normalizeEscapedValue(body);
1675
- for (const unit of units) {
1676
- if (!value.endsWith(unit)) continue;
1677
- const numberPart = value.slice(0, -unit.length);
1678
- if (NUMBER_RE.test(numberPart)) return `${numberPart}${unit}`;
1679
- }
1680
- }
1681
- function resolveArbitraryValue(utility, body, units) {
1682
- const value = normalizeEscapedValue(body);
1683
- const withUnit = resolveValueWithUnit(value, units);
1684
- if (withUnit) return withUnit;
1685
- if (utility === "aspect" && ASPECT_RATIO_RE.test(value)) return value;
1686
- if (isHexColorValue(value)) return value;
1687
- if (isQuotedValue(value)) return value;
1688
- if (FUNCTION_VALUE_RE.test(value) && value.endsWith(")") && isBalancedFunctionValue(value)) {
1689
- if (utility === "text" && /^var\(/i.test(value)) return `color:${value}`;
1690
- return value;
1691
- }
1692
- }
1693
- function resolveUtilityAndValue(body, units) {
1694
- let depth = 0;
1695
- let quote;
1696
- for (let index = body.length - 1; index > 0; index--) {
1697
- const character = body[index];
1698
- if (isEscapedAt(body, index)) continue;
1699
- if (quote) {
1700
- if (character === quote) quote = void 0;
1701
- continue;
1702
- }
1703
- if (character === "\"" || character === "'") {
1704
- quote = character;
1705
- continue;
1706
- }
1707
- if (character === ")" || character === "}") {
1708
- depth++;
1709
- continue;
1710
- }
1711
- if (character === "(" || character === "{") {
1712
- depth = Math.max(0, depth - 1);
1713
- continue;
1714
- }
1715
- if (depth > 0 || character !== "-") continue;
1716
- const utility = body.slice(0, index);
1717
- const rawValue = body.slice(index + 1);
1718
- if (!utility || !rawValue) continue;
1719
- const value = resolveArbitraryValue(utility, rawValue, units);
1720
- if (value) return {
1721
- utility,
1722
- value
1723
- };
1724
- }
1725
- }
1726
- function resolveBareArbitraryValueCandidate(candidate, options) {
1727
- const normalizedOptions = normalizeBareArbitraryValueOptions(options);
1728
- if (!normalizedOptions || !candidate || candidate.includes("[") || candidate.includes("]")) return;
1729
- const { prefix, body } = splitVariantPrefix(candidate);
1730
- const important = body.startsWith("!") ? "!" : "";
1731
- let normalizedBody = important ? body.slice(1) : body;
1732
- const negative = normalizedBody.startsWith("-") ? "-" : "";
1733
- if (negative) normalizedBody = normalizedBody.slice(1);
1734
- if (!isBalancedBareArbitraryBody(normalizedBody)) return;
1735
- const resolved = resolveUtilityAndValue(normalizedBody, normalizedOptions.units);
1736
- if (!resolved) return;
1737
- return {
1738
- candidate,
1739
- canonicalCandidate: `${prefix}${important}${negative}${resolved.utility}-[${resolved.value}]`
1740
- };
1741
- }
1742
- function isBareArbitrarySourceSplitter(char) {
1743
- return /\s/.test(char);
1744
- }
1745
- function isQuoteBoundary(content, start, index) {
1746
- const tokenPrefix = content.slice(start, index);
1747
- return tokenPrefix.length === 0 || !tokenPrefix.endsWith("-");
1748
- }
1749
- function trimBareArbitrarySourceToken(token, start) {
1750
- let nextToken = token;
1751
- let nextStart = start;
1752
- while (nextToken.length > 0 && /^[<{([]$/.test(nextToken[0])) {
1753
- nextToken = nextToken.slice(1);
1754
- nextStart++;
1755
- }
1756
- while (nextToken.length > 0 && /^[>\],;]$/.test(nextToken[nextToken.length - 1])) nextToken = nextToken.slice(0, -1);
1757
- return {
1758
- token: nextToken,
1759
- start: nextStart
1760
- };
1761
- }
1762
- function pushBareArbitrarySourceCandidate(result, token, start, options) {
1763
- const trimmed = trimBareArbitrarySourceToken(token, start);
1764
- if (!trimmed.token || trimmed.token.includes("=") || trimmed.token.includes("[") || trimmed.token.includes("]")) return;
1765
- if (!resolveBareArbitraryValueCandidate(trimmed.token, options)) return;
1766
- result.push({
1767
- rawCandidate: trimmed.token,
1768
- start: trimmed.start,
1769
- end: trimmed.start + trimmed.token.length
1770
- });
1771
- }
1772
- function extractBareArbitraryValueSourceCandidatesWithPositions(content, options) {
1773
- if (!isBareArbitraryValuesEnabled(options)) return [];
1774
- const normalized = content.includes("\\") ? content.replace(ESCAPED_WHITESPACE_RE, " ") : content;
1775
- const result = [];
1776
- let depth = 0;
1777
- let quote;
1778
- let start = 0;
1779
- for (let index = 0; index < normalized.length; index++) {
1780
- const char = normalized[index];
1781
- if (char === void 0) continue;
1782
- if (char === "\\") {
1783
- index++;
1784
- continue;
1785
- }
1786
- if (quote) {
1787
- if (char === quote) quote = void 0;
1788
- } else if ((char === "\"" || char === "'" || char === "`") && !isQuoteBoundary(normalized, start, index)) quote = char;
1789
- else if (char === "(" || char === "{" || char === "[") depth++;
1790
- else if (char === ")" || char === "}" || char === "]") depth = Math.max(0, depth - 1);
1791
- if (!isBareArbitrarySourceSplitter(char) && !((char === "\"" || char === "'" || char === "`") && depth === 0 && isQuoteBoundary(normalized, start, index))) continue;
1792
- pushBareArbitrarySourceCandidate(result, normalized.slice(start, index), start, options);
1793
- start = index + 1;
1794
- }
1795
- pushBareArbitrarySourceCandidate(result, normalized.slice(start), start, options);
1796
- return result;
1797
- }
1798
- function extractBareArbitraryValueSourceCandidates(content, options) {
1799
- return [...new Set(extractBareArbitraryValueSourceCandidatesWithPositions(content, options).map((candidate) => candidate.rawCandidate))];
1800
- }
1801
- function escapeCssClassName(value) {
1802
- let result = "";
1803
- for (let index = 0; index < value.length; index++) {
1804
- const codeUnit = value.charCodeAt(index);
1805
- const character = value.charAt(index);
1806
- if (codeUnit === 0) {
1807
- result += "�";
1808
- continue;
1809
- }
1810
- if (codeUnit >= 1 && codeUnit <= 31 || codeUnit === 127 || index === 0 && codeUnit >= 48 && codeUnit <= 57 || index === 1 && codeUnit >= 48 && codeUnit <= 57 && value.charCodeAt(0) === 45) {
1811
- result += `\\${codeUnit.toString(16)} `;
1812
- continue;
1813
- }
1814
- if (codeUnit >= 128 || codeUnit === 45 || codeUnit === 95 || codeUnit >= 48 && codeUnit <= 57 || codeUnit >= 65 && codeUnit <= 90 || codeUnit >= 97 && codeUnit <= 122) {
1815
- result += character;
1816
- continue;
1817
- }
1818
- result += `\\${character}`;
1819
- }
1820
- return result;
1821
- }
1822
- //#endregion
1823
- //#region src/v4/candidates.ts
1824
- function resolveValidTailwindV4Candidates(designSystem, candidates, options) {
1825
- const validCandidates = /* @__PURE__ */ new Set();
1826
- const parsedCandidates = [];
1827
- const originalCandidatesByCanonical = /* @__PURE__ */ new Map();
1828
- for (const candidate of candidates) {
1829
- if (!candidate) continue;
1830
- const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options?.bareArbitraryValues);
1831
- const candidateToCheck = bareArbitrary?.canonicalCandidate ?? candidate;
1832
- if (bareArbitrary) {
1833
- const originalCandidates = originalCandidatesByCanonical.get(candidateToCheck) ?? /* @__PURE__ */ new Set();
1834
- originalCandidates.add(candidate);
1835
- originalCandidatesByCanonical.set(candidateToCheck, originalCandidates);
1836
- }
1837
- if (parsedCandidates.includes(candidateToCheck)) continue;
1838
- if (designSystem.parseCandidate(candidateToCheck).length > 0) parsedCandidates.push(candidateToCheck);
1839
- }
1840
- if (parsedCandidates.length === 0) return validCandidates;
1841
- const cssByCandidate = designSystem.candidatesToCss(parsedCandidates);
1842
- for (let index = 0; index < parsedCandidates.length; index++) {
1843
- const candidate = parsedCandidates[index];
1844
- const candidateCss = cssByCandidate[index];
1845
- if (candidate && typeof candidateCss === "string" && candidateCss.trim().length > 0) {
1846
- const originalCandidates = originalCandidatesByCanonical.get(candidate);
1847
- if (originalCandidates) {
1848
- for (const originalCandidate of originalCandidates) validCandidates.add(originalCandidate);
1849
- continue;
1850
- }
1851
- validCandidates.add(candidate);
1852
- }
1853
- }
1854
- return validCandidates;
1855
- }
1856
- function createSelectorAliasMap(candidates, options) {
1857
- const aliases = /* @__PURE__ */ new Map();
1858
- for (const candidate of candidates) {
1859
- const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options);
1860
- if (!bareArbitrary) continue;
1861
- const canonicalSelector = escapeCssClassName(bareArbitrary.canonicalCandidate);
1862
- const bareSelectors = aliases.get(canonicalSelector) ?? /* @__PURE__ */ new Set();
1863
- bareSelectors.add(escapeCssClassName(bareArbitrary.candidate));
1864
- aliases.set(canonicalSelector, bareSelectors);
1865
- }
1866
- return aliases;
1867
- }
1868
- function replaceBareArbitraryValueSelectors(css, candidates, options) {
1869
- const aliases = createSelectorAliasMap(candidates, options);
1870
- if (aliases.size === 0) return css;
1871
- if (Array.from(aliases.values()).every((bareSelectors) => bareSelectors.size === 1)) {
1872
- let result = css;
1873
- for (const [canonicalSelector, bareSelectors] of aliases) {
1874
- const bareSelector = Array.from(bareSelectors)[0];
1875
- if (bareSelector !== void 0) result = result.replaceAll(canonicalSelector, bareSelector);
1876
- }
1877
- return result;
1878
- }
1879
- const root = postcss.default.parse(css);
1880
- root.walkRules((rule) => {
1881
- let selectors = rule.selectors;
1882
- for (const [canonicalSelector, bareSelectors] of aliases) selectors = selectors.flatMap((selector) => {
1883
- if (!selector.includes(canonicalSelector)) return selector;
1884
- return Array.from(bareSelectors, (bareSelector) => selector.replaceAll(canonicalSelector, bareSelector));
1885
- });
1886
- rule.selectors = selectors;
1887
- });
1888
- return root.toString();
1889
- }
1890
- function canonicalizeBareArbitraryValueCandidates(candidates, options) {
1891
- return Array.from(candidates, (candidate) => {
1892
- return resolveBareArbitraryValueCandidate(candidate, options)?.canonicalCandidate ?? candidate;
1893
- });
1894
- }
1895
- function splitTopLevel(value, separator, options) {
1896
- const result = [];
1897
- let start = 0;
1898
- let depth = 0;
1899
- let quote;
1900
- for (let index = 0; index < value.length; index++) {
1901
- const character = value[index];
1902
- if (character === "\\") {
1903
- index++;
1904
- continue;
1905
- }
1906
- if (quote) {
1907
- if (character === quote) quote = void 0;
1908
- continue;
1909
- }
1910
- if (character === "\"" || character === "'") {
1911
- quote = character;
1912
- continue;
1913
- }
1914
- if (character === "(" || character === "[" || character === "{") {
1915
- depth++;
1916
- continue;
1917
- }
1918
- if (character === ")" || character === "]" || character === "}") {
1919
- depth = Math.max(0, depth - 1);
1920
- continue;
1921
- }
1922
- if (depth === 0 && character === separator) {
1923
- const item = value.slice(start, index).trim();
1924
- if (item || options?.keepEmpty) result.push(item);
1925
- start = index + 1;
1926
- }
1927
- }
1928
- const item = value.slice(start).trim();
1929
- if (item || options?.keepEmpty) result.push(item);
1930
- return result;
1931
- }
1932
- const sequencePattern = /^(-?\d+)\.\.(-?\d+)(?:\.\.(-?\d+))?$/;
1933
- function expandSequence(value) {
1934
- const match = value.match(sequencePattern);
1935
- if (!match) return [value];
1936
- const [, startValue, endValue, stepValue] = match;
1937
- if (startValue === void 0 || endValue === void 0) return [value];
1938
- const start = Number.parseInt(startValue, 10);
1939
- const end = Number.parseInt(endValue, 10);
1940
- let step = stepValue === void 0 ? start <= end ? 1 : -1 : Number.parseInt(stepValue, 10);
1941
- if (step === 0) throw new Error("Step cannot be zero in Tailwind CSS v4 inline source sequence.");
1942
- const ascending = start < end;
1943
- if (ascending && step < 0) step = -step;
1944
- if (!ascending && step > 0) step = -step;
1945
- const result = [];
1946
- for (let current = start; ascending ? current <= end : current >= end; current += step) result.push(current.toString());
1947
- return result;
1948
- }
1949
- function expandInlinePattern(pattern) {
1950
- const openIndex = pattern.indexOf("{");
1951
- if (openIndex === -1) return [pattern];
1952
- const prefix = pattern.slice(0, openIndex);
1953
- const rest = pattern.slice(openIndex);
1954
- let depth = 0;
1955
- let closeIndex = -1;
1956
- for (let index = 0; index < rest.length; index++) {
1957
- const character = rest[index];
1958
- if (character === "{") depth++;
1959
- else if (character === "}") {
1960
- depth--;
1961
- if (depth === 0) {
1962
- closeIndex = index;
1963
- break;
1964
- }
1965
- }
1966
- }
1967
- if (closeIndex === -1) throw new Error(`The Tailwind CSS v4 inline source pattern "${pattern}" is not balanced.`);
1968
- const body = rest.slice(1, closeIndex);
1969
- const suffix = rest.slice(closeIndex + 1);
1970
- const parts = sequencePattern.test(body) ? expandSequence(body) : splitTopLevel(body, ",", { keepEmpty: true }).flatMap((part) => expandInlinePattern(part));
1971
- const suffixes = expandInlinePattern(suffix);
1972
- const result = [];
1973
- for (const part of parts) for (const expandedSuffix of suffixes) result.push(`${prefix}${part}${expandedSuffix}`);
1974
- return result;
1975
- }
1976
- function unquoteCssString(value) {
1977
- const quote = value[0];
1978
- if (quote !== "\"" && quote !== "'" || value[value.length - 1] !== quote) return;
1979
- let result = "";
1980
- for (let index = 1; index < value.length - 1; index++) {
1981
- const character = value[index];
1982
- if (character === "\\") {
1983
- index++;
1984
- result += value[index] ?? "";
1985
- continue;
1986
- }
1987
- result += character;
1988
- }
1989
- return result;
1990
- }
1991
- function extractTailwindV4InlineSourceCandidates(css) {
1992
- const included = /* @__PURE__ */ new Set();
1993
- const excluded = /* @__PURE__ */ new Set();
1994
- postcss.default.parse(css).walkAtRules("source", (rule) => {
1995
- let params = rule.params.trim();
1996
- if (!params) return;
1997
- let negated = false;
1998
- if (params.startsWith("not ")) {
1999
- negated = true;
2000
- params = params.slice(4).trim();
2001
- }
2002
- if (!params.startsWith("inline(") || !params.endsWith(")")) return;
2003
- const inlineValue = unquoteCssString(params.slice(7, -1).trim());
2004
- if (inlineValue === void 0) return;
2005
- const target = negated ? excluded : included;
2006
- for (const part of splitTopLevel(inlineValue, " ")) for (const candidate of expandInlinePattern(part)) target.add(candidate);
2007
- });
2008
- return {
2009
- included,
2010
- excluded
2011
- };
2012
- }
2013
- //#endregion
2014
- //#region src/v4/node-adapter.ts
2015
- const nodeModulePromiseCache = /* @__PURE__ */ new Map();
2016
- const designSystemPromiseCache = /* @__PURE__ */ new Map();
2017
- function unique(values) {
2018
- return Array.from(new Set(Array.from(values).filter(Boolean).map((value) => pathe.default.resolve(value))));
2019
- }
2020
- function createRequireBase(base) {
2021
- return pathe.default.join(base, "package.json");
2022
- }
2023
- function isRelativeSpecifier(id) {
2024
- return id.startsWith("./") || id.startsWith("../") || id === "." || id === "..";
2025
- }
2026
- function isAbsoluteSpecifier(id) {
2027
- return pathe.default.isAbsolute(id);
2028
- }
2029
- function isCssSpecifier(id) {
2030
- return pathe.default.extname(id) === ".css";
2031
- }
2032
- function createCssResolutionCandidates(id) {
2033
- if (isCssSpecifier(id)) return [id];
2034
- return [`${id}/index.css`, id];
2035
- }
2036
- function createFallbackCssResolver(baseCandidates) {
2037
- const bases = unique(baseCandidates);
2038
- return async (id) => {
2039
- if (isRelativeSpecifier(id) || isAbsoluteSpecifier(id)) return;
2040
- for (const base of bases) {
2041
- const requireFromBase = (0, node_module.createRequire)(createRequireBase(base));
2042
- for (const candidate of createCssResolutionCandidates(id)) try {
2043
- return requireFromBase.resolve(candidate);
2044
- } catch {}
2045
- }
2046
- };
2047
- }
2048
- async function importResolvedModule(resolved) {
2049
- return import((0, node_url.pathToFileURL)(resolved).href);
2050
- }
2051
- async function importTailwindNodeFromBase(base) {
2052
- try {
2053
- return await importResolvedModule((0, node_module.createRequire)(createRequireBase(base)).resolve("@tailwindcss/node"));
2054
- } catch {
2055
- return;
2056
- }
2057
- }
2058
- async function importFallbackTailwindNode() {
2059
- return import("@tailwindcss/node");
2060
- }
2061
- async function loadTailwindV4NodeModule(baseCandidates) {
2062
- const bases = unique(baseCandidates);
2063
- const cacheKey = JSON.stringify(bases);
2064
- const cached = nodeModulePromiseCache.get(cacheKey);
2065
- if (cached) return cached;
2066
- const promise = (async () => {
2067
- for (const base of bases) {
2068
- const loaded = await importTailwindNodeFromBase(base);
2069
- if (loaded) return loaded;
2070
- }
2071
- return importFallbackTailwindNode();
2072
- })();
2073
- nodeModulePromiseCache.set(cacheKey, promise);
2074
- promise.catch(() => {
2075
- if (nodeModulePromiseCache.get(cacheKey) === promise) nodeModulePromiseCache.delete(cacheKey);
2076
- });
2077
- return promise;
2078
- }
2079
- function createDesignSystemCacheKey(css, bases) {
2080
- return JSON.stringify({
2081
- css,
2082
- bases: unique(bases)
2083
- });
2084
- }
2085
- function getTailwindV4DesignSystemCacheKey(source) {
2086
- return createDesignSystemCacheKey(source.css, [source.base, ...source.baseFallbacks]);
2087
- }
2088
- async function loadTailwindV4DesignSystem(source) {
2089
- const bases = unique([source.base, ...source.baseFallbacks]);
2090
- if (bases.length === 0) throw new Error("No base directories provided for Tailwind CSS v4 design system.");
2091
- const cacheKey = createDesignSystemCacheKey(source.css, bases);
2092
- const cached = designSystemPromiseCache.get(cacheKey);
2093
- if (cached) return cached;
2094
- const promise = (async () => {
2095
- const node = await loadTailwindV4NodeModule([source.projectRoot, ...bases]);
2096
- let lastError;
2097
- for (const base of bases) try {
2098
- return await node.__unstable__loadDesignSystem(source.css, { base });
2099
- } catch (error) {
2100
- lastError = error;
2101
- }
2102
- if (lastError instanceof Error) throw lastError;
2103
- throw new Error("Failed to load Tailwind CSS v4 design system.");
2104
- })();
2105
- designSystemPromiseCache.set(cacheKey, promise);
2106
- promise.catch(() => {
2107
- if (designSystemPromiseCache.get(cacheKey) === promise) designSystemPromiseCache.delete(cacheKey);
2108
- });
2109
- return promise;
2110
- }
2111
- async function compileTailwindV4Source(source) {
2112
- const bases = unique([source.base, ...source.baseFallbacks]);
2113
- if (bases.length === 0) throw new Error("No base directories provided for Tailwind CSS v4 compiler.");
2114
- const node = await loadTailwindV4NodeModule([source.projectRoot, ...bases]);
2115
- let lastError;
2116
- for (const base of bases) {
2117
- const dependencies = new Set(source.dependencies);
2118
- try {
2119
- return {
2120
- compiled: await node.compile(source.css, {
2121
- base,
2122
- customCssResolver: createFallbackCssResolver([source.projectRoot, ...bases]),
2123
- onDependency(dependency) {
2124
- dependencies.add(pathe.default.resolve(dependency));
2125
- }
2126
- }),
2127
- dependencies
2128
- };
2129
- } catch (error) {
2130
- lastError = error;
2131
- }
2132
- }
2133
- if (lastError instanceof Error) throw lastError;
2134
- throw new Error("Failed to compile Tailwind CSS v4 source.");
2135
- }
2136
- //#endregion
2137
- //#region src/v4/source-scan.ts
2138
- const TAILWIND_V4_IGNORED_CONTENT_DIRS = [
2139
- ".git",
2140
- ".hg",
2141
- ".jj",
2142
- ".next",
2143
- ".parcel-cache",
2144
- ".pnpm-store",
2145
- ".svelte-kit",
2146
- ".svn",
2147
- ".turbo",
2148
- ".venv",
2149
- ".vercel",
2150
- ".yarn",
2151
- "__pycache__",
2152
- "node_modules",
2153
- "venv"
2154
- ];
2155
- const TAILWIND_V4_IGNORED_EXTENSIONS = [
2156
- "less",
2157
- "lock",
2158
- "sass",
2159
- "scss",
2160
- "styl",
2161
- "log"
2162
- ];
2163
- const TAILWIND_V4_IGNORED_FILES = [
2164
- "package-lock.json",
2165
- "pnpm-lock.yaml",
2166
- "bun.lockb",
2167
- ".gitignore",
2168
- ".env",
2169
- ".env.*"
2170
- ];
2171
- const TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN = "**/*";
2172
- function uniqueResolvedPaths(values) {
2173
- const result = [];
2174
- for (const value of values) {
2175
- if (!value) continue;
2176
- const resolved = pathe.default.resolve(value);
2177
- if (!result.includes(resolved)) result.push(resolved);
2178
- }
2179
- return result;
2180
- }
2181
- function toPosixPath(value) {
2182
- return value.replaceAll(pathe.default.sep, "/");
2183
- }
2184
- function resolveSourceScanPath(value) {
2185
- const resolved = pathe.default.resolve(value);
2186
- try {
2187
- return node_fs.realpathSync.native(resolved);
2188
- } catch {
2189
- return resolved;
2190
- }
2191
- }
2192
- function normalizeGlobPattern(pattern) {
2193
- return pattern.startsWith("./") ? pattern.slice(2) : pattern;
2194
- }
2195
- function hasGlobMagic(value) {
2196
- return /[*?[\]{}()!+@]/.test(value);
2197
- }
2198
- function splitStaticGlobPrefix(pattern) {
2199
- const segments = normalizeGlobPattern(pattern).split(/[\\/]+/);
2200
- const prefix = [];
2201
- const rest = [];
2202
- let reachedGlob = false;
2203
- for (const segment of segments) {
2204
- if (!reachedGlob && segment && !hasGlobMagic(segment)) {
2205
- prefix.push(segment);
2206
- continue;
2207
- }
2208
- reachedGlob = true;
2209
- rest.push(segment);
2210
- }
2211
- return {
2212
- prefix,
2213
- rest
2214
- };
2215
- }
2216
- async function pathExistsAsDirectory(file) {
2217
- try {
2218
- return (await (0, node_fs_promises.stat)(file)).isDirectory();
2219
- } catch {
2220
- return false;
2221
- }
2222
- }
2223
- function createTailwindV4DefaultIgnoreSources(base) {
2224
- return [
2225
- ...TAILWIND_V4_IGNORED_CONTENT_DIRS.map((pattern) => ({
2226
- base,
2227
- pattern: `**/${pattern}/**`,
2228
- negated: true
2229
- })),
2230
- ...TAILWIND_V4_IGNORED_EXTENSIONS.map((extension) => ({
2231
- base,
2232
- pattern: `**/*.${extension}`,
2233
- negated: true
2234
- })),
2235
- ...TAILWIND_V4_IGNORED_FILES.map((pattern) => ({
2236
- base,
2237
- pattern: `**/${pattern}`,
2238
- negated: true
2239
- }))
2240
- ];
2241
- }
2242
- function createTailwindV4RootSources(root, fallbackBase) {
2243
- if (root === "none") return [];
2244
- if (root === null) return [{
2245
- base: fallbackBase,
2246
- pattern: TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN,
2247
- negated: false
2248
- }];
2249
- return [{
2250
- ...root,
2251
- negated: false
2252
- }];
2253
- }
2254
- function createTailwindV4CompiledSourceEntries(root, sources, fallbackBase) {
2255
- return [...createTailwindV4RootSources(root, fallbackBase), ...sources];
2256
- }
2257
- async function resolveTailwindV4SourceEntry(sourcePath, base, negated, defaultPattern = TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN) {
2258
- const absoluteSource = pathe.default.isAbsolute(sourcePath) ? pathe.default.resolve(sourcePath) : pathe.default.resolve(base, sourcePath);
2259
- if (await pathExistsAsDirectory(absoluteSource)) return {
2260
- base: absoluteSource,
2261
- negated,
2262
- pattern: normalizeGlobPattern(defaultPattern)
2263
- };
2264
- if (pathe.default.isAbsolute(sourcePath)) return {
2265
- base: pathe.default.dirname(absoluteSource),
2266
- negated,
2267
- pattern: normalizeGlobPattern(pathe.default.basename(absoluteSource))
2268
- };
2269
- const { prefix, rest } = splitStaticGlobPrefix(sourcePath);
2270
- if (prefix.length > 0 && rest.length > 0) return {
2271
- base: pathe.default.resolve(base, ...prefix),
2272
- negated,
2273
- pattern: normalizeGlobPattern(rest.join("/"))
2274
- };
2275
- return {
2276
- base,
2277
- negated,
2278
- pattern: normalizeGlobPattern(sourcePath)
2279
- };
2280
- }
2281
- async function normalizeTailwindV4SourceEntries(sources, options = {}) {
2282
- const cwd = options.cwd ? pathe.default.resolve(options.cwd) : node_process.default.cwd();
2283
- return Promise.all(sources.map((source) => resolveTailwindV4SourceEntry(source.pattern, source.base ? pathe.default.resolve(source.base) : cwd, source.negated, options.defaultPattern)));
2284
- }
2285
- function expandBracePattern(pattern) {
2286
- const index = pattern.indexOf("{");
2287
- if (index === -1) return [pattern];
2288
- const rest = pattern.slice(index);
2289
- let depth = 0;
2290
- let endIndex = -1;
2291
- for (let i = 0; i < rest.length; i++) {
2292
- const char = rest[i];
2293
- if (char === "\\") {
2294
- i += 1;
2295
- continue;
2296
- }
2297
- if (char === "{") {
2298
- depth += 1;
2299
- continue;
2300
- }
2301
- if (char === "}") {
2302
- depth -= 1;
2303
- if (depth === 0) {
2304
- endIndex = i;
2305
- break;
2306
- }
2307
- }
2308
- }
2309
- if (endIndex === -1) return [pattern];
2310
- const prefix = pattern.slice(0, index);
2311
- const inner = rest.slice(1, endIndex);
2312
- const suffix = rest.slice(endIndex + 1);
2313
- const parts = [];
2314
- const stack = [];
2315
- let lastPos = 0;
2316
- for (let i = 0; i < inner.length; i++) {
2317
- const char = inner[i];
2318
- if (char === "\\") {
2319
- i += 1;
2320
- continue;
2321
- }
2322
- if (char === "{") {
2323
- stack.push("}");
2324
- continue;
2325
- }
2326
- if (char === "}" && stack[stack.length - 1] === "}") {
2327
- stack.pop();
2328
- continue;
2329
- }
2330
- if (char === "," && stack.length === 0) {
2331
- parts.push(inner.slice(lastPos, i));
2332
- lastPos = i + 1;
2333
- }
2334
- }
2335
- parts.push(inner.slice(lastPos));
2336
- return parts.flatMap((part) => expandBracePattern(`${prefix}${part}${suffix}`));
2337
- }
2338
- function expandTailwindV4SourceEntryBraces(sources) {
2339
- return sources.flatMap((source) => {
2340
- const base = pathe.default.resolve(source.base);
2341
- return expandBracePattern(source.pattern).map((pattern) => ({
2342
- base,
2343
- pattern,
2344
- negated: source.negated
2345
- }));
2346
- });
2347
- }
2348
- function normalizeTailwindV4ScannerSources(sources, cwd, ignoredSources = []) {
2349
- return expandTailwindV4SourceEntryBraces([...sources?.length ? sources : [{
2350
- base: cwd,
2351
- pattern: TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN,
2352
- negated: false
2353
- }], ...ignoredSources]);
2354
- }
2355
- function normalizeEntryPattern(entry) {
2356
- return pathe.default.isAbsolute(entry.pattern) ? toPosixPath(pathe.default.relative(resolveSourceScanPath(entry.base), entry.pattern)) : normalizeGlobPattern(entry.pattern);
2357
- }
2358
- function isFileMatchedByTailwindV4SourceEntry(file, entry) {
2359
- const relative = toPosixPath(pathe.default.relative(resolveSourceScanPath(entry.base), file));
2360
- return Boolean(relative) && !relative.startsWith("../") && !pathe.default.isAbsolute(relative) && micromatch.default.isMatch(relative, normalizeEntryPattern(entry));
2361
- }
2362
- function isFileExcludedByTailwindV4SourceEntries(file, entries) {
2363
- if (!entries?.length) return false;
2364
- const resolvedFile = resolveSourceScanPath(file);
2365
- return entries.some((entry) => entry.negated && isFileMatchedByTailwindV4SourceEntry(resolvedFile, entry));
2366
- }
2367
- function isFileMatchedByTailwindV4SourceEntries(file, entries) {
2368
- if (!entries?.length) return true;
2369
- const positiveEntries = entries.filter((entry) => !entry.negated);
2370
- const negativeEntries = entries.filter((entry) => entry.negated);
2371
- if (positiveEntries.length === 0) return false;
2372
- const resolvedFile = resolveSourceScanPath(file);
2373
- if (!positiveEntries.some((entry) => isFileMatchedByTailwindV4SourceEntry(resolvedFile, entry))) return false;
2374
- return !negativeEntries.some((entry) => isFileMatchedByTailwindV4SourceEntry(resolvedFile, entry));
2375
- }
2376
- function createTailwindV4SourceEntryMatcher(entries) {
2377
- if (!entries?.length) return;
2378
- return (file) => isFileMatchedByTailwindV4SourceEntries(file, entries);
2379
- }
2380
- function createTailwindV4SourceExclusionMatcher(entries) {
2381
- if (!entries?.length) return;
2382
- return (file) => isFileExcludedByTailwindV4SourceEntries(file, entries);
2383
- }
2384
- function groupTailwindV4SourceEntriesByBase(entries) {
2385
- const entriesByBase = /* @__PURE__ */ new Map();
2386
- for (const entry of entries) {
2387
- const base = pathe.default.resolve(entry.base);
2388
- const group = entriesByBase.get(base) ?? [];
2389
- group.push({
2390
- ...entry,
2391
- base,
2392
- pattern: normalizeGlobPattern(entry.pattern)
2393
- });
2394
- entriesByBase.set(base, group);
2395
- }
2396
- return entriesByBase;
2397
- }
2398
- async function expandTailwindV4SourceEntries(entries, resolveFiles) {
2399
- if (entries.length === 0) return [];
2400
- const files = /* @__PURE__ */ new Set();
2401
- await Promise.all([...groupTailwindV4SourceEntriesByBase(entries).entries()].map(async ([base, group]) => {
2402
- const matched = await resolveFiles({
2403
- cwd: base,
2404
- sources: group
2405
- });
2406
- for (const file of matched) files.add(pathe.default.resolve(file));
2407
- }));
2408
- return [...files].filter((file) => !isFileExcludedByTailwindV4SourceEntries(file, entries));
2409
- }
2410
- function mergeTailwindV4SourceEntries(...entries) {
2411
- const result = [];
2412
- const seen = /* @__PURE__ */ new Set();
2413
- for (const group of entries) for (const entry of group ?? []) {
2414
- const normalized = {
2415
- base: pathe.default.resolve(entry.base),
2416
- pattern: normalizeGlobPattern(entry.pattern),
2417
- negated: entry.negated
2418
- };
2419
- const key = JSON.stringify(normalized);
2420
- if (seen.has(key)) continue;
2421
- seen.add(key);
2422
- result.push(normalized);
2423
- }
2424
- return result;
2425
- }
2426
- function resolveTailwindV4SourceBaseCandidates(projectRoot, base, baseFallbacks) {
2427
- return uniqueResolvedPaths([
2428
- base,
2429
- projectRoot,
2430
- ...baseFallbacks
2431
- ]);
2432
- }
2433
- //#endregion
2434
- //#region src/extraction/candidate-extractor.ts
2435
- let oxideImportPromise;
2436
- const designSystemCandidateCache = /* @__PURE__ */ new Map();
2437
- function createOxideRuntimeDependencyError(cause) {
2438
- return new Error([
2439
- "tailwindcss-patch could not load @tailwindcss/oxide, which is required for source candidate scanning.",
2440
- "This dependency should be installed automatically by tailwindcss-patch.",
2441
- "Reinstall dependencies without disabling optional dependencies, or install @tailwindcss/oxide@^4.2.4 manually if your package manager omitted it."
2442
- ].join(" "), { cause });
2443
- }
2444
- async function importOxide() {
2445
- try {
2446
- return await import("@tailwindcss/oxide");
2447
- } catch (error) {
2448
- throw createOxideRuntimeDependencyError(error);
2449
- }
2450
- }
2451
- function getOxideModule() {
2452
- oxideImportPromise ??= importOxide();
2453
- oxideImportPromise.catch(() => {
2454
- oxideImportPromise = void 0;
2455
- });
2456
- return oxideImportPromise;
2457
- }
2458
- const HTML_ATTRIBUTE_NAME_CANDIDATE_RE = /^(?:class|className|hover-class|hoverClass)$/;
2459
- const CSS_DIRECTIVE_CANDIDATE_RE = /^@(?:apply|tailwind|source|config|plugin|theme|utility|custom-variant|variant)$/;
2460
- const CSS_APPLY_IMPORTANT = "!important";
2461
- const CSS_APPLY_RE = /@apply\s+([^;{}]+)/g;
2462
- const JS_LIKE_SOURCE_EXTENSION_RE = /^[cm]?[jt]sx?$/;
2463
- const MIXED_TEMPLATE_SOURCE_EXTENSION_RE = /^(?:vue|uvue|nvue|svelte|mpx)$/;
2464
- const CSS_LIKE_SOURCE_EXTENSION_RE = /^(?:css|wxss|acss|jxss|ttss|qss|tyss|scss|sass|less|styl|stylus)$/;
2465
- const SFC_SCRIPT_BLOCK_RE = /<script\b[^>]*>([\s\S]*?)<\/script>/gi;
2466
- function isWhitespace(value) {
2467
- return value === " " || value === "\n" || value === "\r" || value === " " || value === "\f";
2468
- }
2469
- function isHtmlAttributeNameCandidate(content, candidate) {
2470
- if (!HTML_ATTRIBUTE_NAME_CANDIDATE_RE.test(candidate.rawCandidate)) return false;
2471
- let index = candidate.end;
2472
- while (isWhitespace(content[index])) index++;
2473
- return content[index] === "=";
2474
- }
2475
- function isInsideHtmlTagText(content, candidate) {
2476
- if (content.lastIndexOf("<", candidate.start) > content.lastIndexOf(">", candidate.start)) return false;
2477
- const nextOpen = content.indexOf("<", candidate.end);
2478
- return nextOpen !== -1 && (nextOpen < content.indexOf(">", candidate.end) || !content.includes(">", candidate.end));
2479
- }
2480
- function isCssDirectiveCandidate(candidate) {
2481
- return candidate === CSS_APPLY_IMPORTANT || CSS_DIRECTIVE_CANDIDATE_RE.test(candidate);
2482
- }
2483
- function isCandidateInCssApplyParams(content, candidate) {
2484
- const apply = content.lastIndexOf("@apply", candidate.start);
2485
- if (apply === -1) return false;
2486
- const boundary = content.slice(apply + 6, candidate.start);
2487
- return !/[;{}]/.test(boundary);
2488
- }
2489
- function isCandidateInsideJsStringStaticContent(content, start) {
2490
- let quote;
2491
- let templateExpressionDepth = 0;
2492
- for (let index = 0; index < start; index++) {
2493
- const char = content[index];
2494
- const next = content[index + 1];
2495
- if (quote && char === "\\") {
2496
- index++;
2497
- continue;
2498
- }
2499
- if (quote === "`" && templateExpressionDepth > 0) {
2500
- if (char === "\"" || char === "'") {
2501
- const nestedQuote = char;
2502
- index++;
2503
- while (index < start) {
2504
- const nestedChar = content[index];
2505
- if (nestedChar === "\\") {
2506
- index += 2;
2507
- continue;
2508
- }
2509
- if (nestedChar === nestedQuote) break;
2510
- index++;
2511
- }
2512
- continue;
2513
- }
2514
- if (char === "`") {
2515
- index++;
2516
- while (index < start) {
2517
- const nestedChar = content[index];
2518
- if (nestedChar === "\\") {
2519
- index += 2;
2520
- continue;
2521
- }
2522
- if (nestedChar === "`") break;
2523
- index++;
2524
- }
2525
- continue;
2526
- }
2527
- if (char === "{") {
2528
- templateExpressionDepth++;
2529
- continue;
2530
- }
2531
- if (char === "}") {
2532
- templateExpressionDepth--;
2533
- continue;
2534
- }
2535
- continue;
2536
- }
2537
- if (quote) {
2538
- if (quote === "`" && char === "$" && next === "{") {
2539
- templateExpressionDepth = 1;
2540
- index++;
2541
- continue;
2542
- }
2543
- if (char === quote) quote = void 0;
2544
- continue;
2545
- }
2546
- if (char === "\"" || char === "'" || char === "`") quote = char;
2547
- }
2548
- return quote !== void 0 && templateExpressionDepth === 0;
2549
- }
2550
- function shouldKeepSourceCandidate(content, extension, candidate) {
2551
- if (!candidate.rawCandidate || isCssDirectiveCandidate(candidate.rawCandidate)) return false;
2552
- if (CSS_LIKE_SOURCE_EXTENSION_RE.test(extension) && !isCandidateInCssApplyParams(content, candidate)) return false;
2553
- if (isHtmlAttributeNameCandidate(content, candidate)) return false;
2554
- if (isInsideHtmlTagText(content, candidate)) return false;
2555
- if (JS_LIKE_SOURCE_EXTENSION_RE.test(extension) && !isCandidateInsideJsStringStaticContent(content, candidate.start)) return false;
2556
- return true;
2557
- }
2558
- function createLocalCandidate(candidate) {
2559
- return {
2560
- rawCandidate: candidate.rawCandidate,
2561
- start: candidate.localStart,
2562
- end: candidate.localStart + candidate.rawCandidate.length
2563
- };
2564
- }
2565
- function dedupeCandidatesWithPositions(candidates) {
2566
- const seen = /* @__PURE__ */ new Set();
2567
- return candidates.filter((candidate) => {
2568
- const key = `${candidate.start}:${candidate.end}:${candidate.rawCandidate}`;
2569
- if (seen.has(key)) return false;
2570
- seen.add(key);
2571
- return true;
2572
- });
2573
- }
2574
- function createBareArbitraryValueCandidateContexts(content, extension, offset, options) {
2575
- return extractBareArbitraryValueSourceCandidatesWithPositions(content, options?.bareArbitraryValues).map((candidate) => ({
2576
- content,
2577
- extension,
2578
- localStart: candidate.start,
2579
- rawCandidate: candidate.rawCandidate,
2580
- start: candidate.start + offset,
2581
- end: candidate.end + offset
2582
- }));
2583
- }
2584
- async function extractCssApplyCandidates(content, extension, options) {
2585
- const candidates = [];
2586
- CSS_APPLY_RE.lastIndex = 0;
2587
- let match = CSS_APPLY_RE.exec(content);
2588
- while (match !== null) {
2589
- const applyParams = match[1] ?? "";
2590
- const applyParamsStart = match.index + match[0].indexOf(applyParams);
2591
- const applyCandidates = await extractRawCandidatesWithPositions(applyParams, extension);
2592
- candidates.push(...applyCandidates.map((candidate) => ({
2593
- content: applyParams,
2594
- extension: "html",
2595
- localStart: candidate.start,
2596
- rawCandidate: candidate.rawCandidate,
2597
- start: candidate.start + applyParamsStart,
2598
- end: candidate.end + applyParamsStart
2599
- })));
2600
- candidates.push(...createBareArbitraryValueCandidateContexts(applyParams, "html", applyParamsStart, options));
2601
- match = CSS_APPLY_RE.exec(content);
2602
- }
2603
- return candidates;
2604
- }
2605
- async function extractMixedSourceScriptCandidates(content, options) {
2606
- const candidates = [];
2607
- SFC_SCRIPT_BLOCK_RE.lastIndex = 0;
2608
- let match = SFC_SCRIPT_BLOCK_RE.exec(content);
2609
- while (match !== null) {
2610
- const scriptContent = match[1] ?? "";
2611
- const scriptStart = match.index + match[0].indexOf(scriptContent);
2612
- const scriptCandidates = await extractRawCandidatesWithPositions(scriptContent, "js");
2613
- candidates.push(...scriptCandidates.map((candidate) => ({
2614
- content: scriptContent,
2615
- extension: "js",
2616
- localStart: candidate.start,
2617
- rawCandidate: candidate.rawCandidate,
2618
- start: candidate.start + scriptStart,
2619
- end: candidate.end + scriptStart
2620
- })));
2621
- candidates.push(...createBareArbitraryValueCandidateContexts(scriptContent, "js", scriptStart, options));
2622
- match = SFC_SCRIPT_BLOCK_RE.exec(content);
2623
- }
2624
- return candidates;
2625
- }
2626
- function createCandidateCacheKey(designSystemKey, options) {
2627
- if (options.bareArbitraryValues == null || options.bareArbitraryValues === false) return designSystemKey;
2628
- return `${designSystemKey}:bare-arbitrary:${JSON.stringify(options.bareArbitraryValues)}`;
2629
- }
2630
- async function extractRawCandidatesWithPositions(content, extension = "html", options) {
2631
- const { Scanner } = await getOxideModule();
2632
- const candidates = new Scanner({}).getCandidatesWithPositions({
2633
- content,
2634
- extension
2635
- }).map(({ candidate, position }) => ({
2636
- rawCandidate: candidate,
2637
- start: position,
2638
- end: position + candidate.length
2639
- }));
2640
- candidates.push(...extractBareArbitraryValueSourceCandidatesWithPositions(content, options?.bareArbitraryValues));
2641
- return dedupeCandidatesWithPositions(candidates);
2642
- }
2643
- async function extractSourceCandidatesWithPositions(content, extension = "html", options) {
2644
- const normalizedExtension = extension.replace(/^\./, "");
2645
- const candidates = CSS_LIKE_SOURCE_EXTENSION_RE.test(normalizedExtension) ? await extractCssApplyCandidates(content, normalizedExtension, options) : (await extractRawCandidatesWithPositions(content, normalizedExtension, options)).map((candidate) => ({
2646
- ...candidate,
2647
- content,
2648
- extension: normalizedExtension,
2649
- localStart: candidate.start
2650
- }));
2651
- if (MIXED_TEMPLATE_SOURCE_EXTENSION_RE.test(normalizedExtension)) candidates.push(...await extractMixedSourceScriptCandidates(content, options));
2652
- const seen = /* @__PURE__ */ new Set();
2653
- return candidates.filter((candidate) => {
2654
- if (!shouldKeepSourceCandidate(candidate.content, candidate.extension, createLocalCandidate(candidate))) return false;
2655
- const key = `${candidate.start}:${candidate.end}:${candidate.rawCandidate}`;
2656
- if (seen.has(key)) return false;
2657
- seen.add(key);
2658
- return true;
2659
- }).map(({ rawCandidate, start, end }) => ({
2660
- rawCandidate,
2661
- start,
2662
- end
2663
- }));
2664
- }
2665
- async function extractSourceCandidates(content, extension = "html", options) {
2666
- const candidates = await extractSourceCandidatesWithPositions(content, extension, options);
2667
- return [...new Set(candidates.map((candidate) => candidate.rawCandidate))];
2668
- }
2669
- async function extractRawCandidates(sources, options) {
2670
- const { Scanner } = await getOxideModule();
2671
- const scanner = new Scanner(sources === void 0 ? {} : { sources });
2672
- const candidates = new Set(scanner.scan());
2673
- if (options?.bareArbitraryValues !== void 0 && options.bareArbitraryValues !== false) await Promise.all((scanner.files ?? []).map(async (file) => {
2674
- try {
2675
- const content = await node_fs.promises.readFile(file, "utf8");
2676
- const extension = toExtension(file);
2677
- for (const candidate of extractBareArbitraryValueSourceCandidatesWithPositions(content, options.bareArbitraryValues)) if (shouldKeepSourceCandidate(content, extension, candidate)) candidates.add(candidate.rawCandidate);
2678
- } catch {}
2679
- }));
2680
- return [...candidates];
2681
- }
2682
- async function extractValidCandidates(options) {
2683
- const providedOptions = options ?? {};
2684
- const defaultCwd = providedOptions.cwd ?? node_process.default.cwd();
2685
- const base = providedOptions.base ?? defaultCwd;
2686
- const baseFallbacks = providedOptions.baseFallbacks ?? [];
2687
- const css = providedOptions.css ?? "@import \"tailwindcss\";";
2688
- const sources = (providedOptions.sources ?? [{
2689
- base: defaultCwd,
2690
- pattern: "**/*",
2691
- negated: false
2692
- }]).map((source) => ({
2693
- base: source.base ?? defaultCwd,
2694
- pattern: source.pattern,
2695
- negated: source.negated
2696
- }));
2697
- const source = {
2698
- projectRoot: defaultCwd,
2699
- base,
2700
- baseFallbacks,
2701
- css,
2702
- dependencies: []
2703
- };
2704
- const designSystemKey = getTailwindV4DesignSystemCacheKey(source);
2705
- const designSystem = await loadTailwindV4DesignSystem(source);
2706
- const candidateCacheKey = createCandidateCacheKey(designSystemKey, providedOptions);
2707
- const candidateCache = designSystemCandidateCache.get(candidateCacheKey) ?? /* @__PURE__ */ new Map();
2708
- designSystemCandidateCache.set(candidateCacheKey, candidateCache);
2709
- const candidates = await extractRawCandidates(sources, providedOptions.bareArbitraryValues === void 0 ? void 0 : { bareArbitraryValues: providedOptions.bareArbitraryValues });
2710
- const inlineSources = extractTailwindV4InlineSourceCandidates(css);
2711
- for (const candidate of inlineSources.included) candidates.push(candidate);
2712
- for (const candidate of inlineSources.excluded) {
2713
- let index = candidates.indexOf(candidate);
2714
- while (index !== -1) {
2715
- candidates.splice(index, 1);
2716
- index = candidates.indexOf(candidate);
2717
- }
2718
- }
2719
- const validCandidates = [];
2720
- const uncachedCandidates = [];
2721
- for (const rawCandidate of candidates) {
2722
- const cached = candidateCache.get(rawCandidate);
2723
- if (cached === true) {
2724
- validCandidates.push(rawCandidate);
2725
- continue;
2726
- }
2727
- if (cached === false) continue;
2728
- const bareArbitrary = resolveBareArbitraryValueCandidate(rawCandidate, providedOptions.bareArbitraryValues);
2729
- if (designSystem.parseCandidate(rawCandidate).length > 0 || bareArbitrary && designSystem.parseCandidate(bareArbitrary.canonicalCandidate).length > 0) {
2730
- uncachedCandidates.push(rawCandidate);
2731
- continue;
2732
- }
2733
- candidateCache.set(rawCandidate, false);
2734
- }
2735
- if (uncachedCandidates.length === 0) return validCandidates;
2736
- const validUncachedCandidates = resolveValidTailwindV4Candidates(designSystem, uncachedCandidates, providedOptions.bareArbitraryValues === void 0 ? void 0 : { bareArbitraryValues: providedOptions.bareArbitraryValues });
2737
- for (const candidate of uncachedCandidates) {
2738
- const isValid = validUncachedCandidates.has(candidate);
2739
- candidateCache.set(candidate, isValid);
2740
- if (!isValid) continue;
2741
- validCandidates.push(candidate);
2742
- }
2743
- return validCandidates;
2744
- }
2745
- function buildLineOffsets(content) {
2746
- const offsets = [0];
2747
- for (let i = 0; i < content.length; i++) if (content[i] === "\n") offsets.push(i + 1);
2748
- if (offsets[offsets.length - 1] !== content.length) offsets.push(content.length);
2749
- return offsets;
1400
+ const deprecatedOptionMapping = {
1401
+ cwd: "projectRoot",
1402
+ overwrite: "apply.overwrite",
1403
+ tailwind: "tailwindcss",
1404
+ features: "apply",
1405
+ output: "extract"
1406
+ };
1407
+ function assertNoDeprecatedOptions(options) {
1408
+ const used = Object.keys(deprecatedOptionMapping).filter((key) => Object.hasOwn(options, key));
1409
+ if (used.length === 0) return;
1410
+ const mapping = used.map((key) => `${key} -> ${deprecatedOptionMapping[key]}`).join(", ");
1411
+ throw new Error(`Legacy TailwindcssPatcher options are no longer supported: ${used.join(", ")}. Use the modern fields instead: ${mapping}.`);
2750
1412
  }
2751
- function resolveLineMeta(content, offsets, index) {
2752
- let low = 0;
2753
- let high = offsets.length - 1;
2754
- while (low <= high) {
2755
- const mid = Math.floor((low + high) / 2);
2756
- const start = offsets[mid];
2757
- if (start === void 0) break;
2758
- const nextStart = offsets[mid + 1] ?? content.length;
2759
- if (index < start) {
2760
- high = mid - 1;
2761
- continue;
2762
- }
2763
- if (index >= nextStart) {
2764
- low = mid + 1;
2765
- continue;
2766
- }
2767
- const line = mid + 1;
2768
- const column = index - start + 1;
2769
- const lineEnd = content.indexOf("\n", start);
2770
- return {
2771
- line,
2772
- column,
2773
- lineText: content.slice(start, lineEnd === -1 ? content.length : lineEnd)
2774
- };
2775
- }
2776
- const lastStart = offsets[offsets.length - 2] ?? 0;
1413
+ function normalizeOptions(options = {}) {
1414
+ assertNoDeprecatedOptions(options);
1415
+ const projectRoot = resolveRealpathSafe(options.projectRoot ? pathe.default.resolve(options.projectRoot) : node_process.default.cwd());
1416
+ const overwrite = options.apply?.overwrite ?? true;
1417
+ const output = normalizeOutputOptions(options.extract);
1418
+ const cache = normalizeCacheOptions(options.cache, projectRoot);
1419
+ const tailwind = normalizeTailwindOptions(options.tailwindcss, projectRoot, options.projectRoot !== void 0 || options.tailwindcss?.cwd !== void 0);
1420
+ const exposeContext = normalizeExposeContextOptions(options.apply?.exposeContext);
1421
+ const extendLengthUnits = normalizeExtendLengthUnitsOptions(options.apply?.extendLengthUnits);
1422
+ const filter = (className) => {
1423
+ if (output.removeUniversalSelector && className === "*") return false;
1424
+ if (typeof options.filter === "function") return options.filter(className) !== false;
1425
+ return true;
1426
+ };
2777
1427
  return {
2778
- line: offsets.length - 1,
2779
- column: index - lastStart + 1,
2780
- lineText: content.slice(lastStart)
1428
+ projectRoot,
1429
+ overwrite,
1430
+ tailwind,
1431
+ features: {
1432
+ exposeContext,
1433
+ extendLengthUnits
1434
+ },
1435
+ output,
1436
+ cache,
1437
+ filter
2781
1438
  };
2782
1439
  }
2783
- function toExtension(filename) {
2784
- return pathe.default.extname(filename).replace(/^\./, "") || "txt";
1440
+ //#endregion
1441
+ //#region src/config/workspace.ts
1442
+ let configModulePromise;
1443
+ let defuPromise;
1444
+ function isNodeError$1(error) {
1445
+ return !!error && typeof error === "object" && ("code" in error || "message" in error);
2785
1446
  }
2786
- function toRelativeFile(cwd, filename) {
2787
- const relative = pathe.default.relative(cwd, filename);
2788
- return relative === "" ? pathe.default.basename(filename) : relative;
1447
+ function isMissingModuleError(error, pkgName) {
1448
+ if (!isNodeError$1(error)) return false;
1449
+ const code = error.code;
1450
+ if (code !== "MODULE_NOT_FOUND" && code !== "ERR_MODULE_NOT_FOUND") return false;
1451
+ const message = error.message ?? "";
1452
+ return message.includes(pkgName) || message.includes(`${pkgName}/dist/`);
2789
1453
  }
2790
- async function resolveScannerSources(options) {
2791
- const cwd = options?.cwd ? pathe.default.resolve(options.cwd) : node_process.default.cwd();
2792
- if (options?.sources?.length || options?.css === void 0) return {
2793
- cwd,
2794
- sources: normalizeTailwindV4ScannerSources(options?.sources, cwd, options?.ignoredSources)
2795
- };
2796
- const base = options.base ? pathe.default.resolve(options.base) : cwd;
2797
- const { compiled } = await compileTailwindV4Source({
2798
- projectRoot: cwd,
2799
- base,
2800
- baseFallbacks: options.baseFallbacks?.map((baseFallback) => pathe.default.resolve(baseFallback)) ?? [],
2801
- css: options.css,
2802
- dependencies: []
2803
- });
2804
- return {
2805
- cwd,
2806
- sources: normalizeTailwindV4ScannerSources(createTailwindV4CompiledSourceEntries(compiled.root, compiled.sources, base), cwd, options.ignoredSources)
2807
- };
1454
+ function isMissingConfigModuleError(error) {
1455
+ return isMissingModuleError(error, "@tailwindcss-mangle/config");
2808
1456
  }
2809
- async function resolveProjectSourceFiles(options) {
2810
- const { sources } = await resolveScannerSources(options);
2811
- const { Scanner } = await getOxideModule();
2812
- const files = new Scanner({ sources }).files ?? [];
2813
- return options?.filter ? files.filter(options.filter) : files;
1457
+ function isMissingSharedModuleError(error) {
1458
+ return isMissingModuleError(error, "@tailwindcss-mangle/shared");
2814
1459
  }
2815
- async function extractProjectCandidatesWithPositions(options) {
2816
- const { cwd, sources } = await resolveScannerSources(options);
2817
- const { Scanner } = await getOxideModule();
2818
- const scanner = new Scanner({ sources });
2819
- const files = scanner.files ?? [];
2820
- const entries = [];
2821
- const skipped = [];
2822
- for (const file of files) {
2823
- let content;
2824
- try {
2825
- content = await node_fs.promises.readFile(file, "utf8");
2826
- } catch (error) {
2827
- skipped.push({
2828
- file,
2829
- reason: error instanceof Error ? error.message : "Unknown error"
2830
- });
2831
- continue;
2832
- }
2833
- const extension = toExtension(file);
2834
- const matches = scanner.getCandidatesWithPositions({
2835
- file,
2836
- content,
2837
- extension
2838
- });
2839
- if (!matches.length) continue;
2840
- const offsets = buildLineOffsets(content);
2841
- const relativeFile = toRelativeFile(cwd, file);
2842
- for (const match of matches) {
2843
- const info = resolveLineMeta(content, offsets, match.position);
2844
- entries.push({
2845
- rawCandidate: match.candidate,
2846
- file,
2847
- relativeFile,
2848
- extension,
2849
- start: match.position,
2850
- end: match.position + match.candidate.length,
2851
- length: match.candidate.length,
2852
- line: info.line,
2853
- column: info.column,
2854
- lineText: info.lineText
2855
- });
2856
- }
2857
- }
2858
- return {
2859
- entries,
2860
- filesScanned: files.length,
2861
- skippedFiles: skipped,
2862
- sources
2863
- };
1460
+ async function loadWorkspaceConfigModule() {
1461
+ if (!configModulePromise) configModulePromise = import("@tailwindcss-mangle/config").catch(async (error) => {
1462
+ if (!isMissingConfigModuleError(error)) throw error;
1463
+ return import((0, node_url.pathToFileURL)(pathe.default.resolve(__dirname, "../../../config/src/index.ts")).href);
1464
+ });
1465
+ return configModulePromise;
1466
+ }
1467
+ async function loadWorkspaceDefu() {
1468
+ if (!defuPromise) defuPromise = Promise.resolve().then(() => require("./dist-wp0o36Ns.js")).then((mod) => mod.defu).catch(async (error) => {
1469
+ if (!isMissingSharedModuleError(error)) throw error;
1470
+ return (await import((0, node_url.pathToFileURL)(pathe.default.resolve(__dirname, "../../../shared/src/utils.ts")).href)).defu;
1471
+ });
1472
+ return defuPromise;
2864
1473
  }
2865
- function groupTokensByFile(report, options) {
2866
- const key = options?.key ?? "relative";
2867
- const stripAbsolute = options?.stripAbsolutePaths ?? key !== "absolute";
2868
- return report.entries.reduce((acc, entry) => {
2869
- const bucketKey = key === "absolute" ? entry.file : entry.relativeFile;
2870
- const bucket = acc[bucketKey] ?? (acc[bucketKey] = []);
2871
- const value = stripAbsolute ? {
2872
- ...entry,
2873
- file: entry.relativeFile
2874
- } : entry;
2875
- bucket.push(value);
2876
- return acc;
2877
- }, {});
1474
+ async function loadPatchOptionsForWorkspace(cwd, overrides) {
1475
+ const merge = await loadWorkspaceDefu();
1476
+ const { config } = await (await loadWorkspaceConfigModule()).getConfig(cwd);
1477
+ if (config && typeof config === "object" && "patch" in config && config.patch !== void 0) throw new Error("Legacy workspace config field \"patch\" is no longer supported. Move patcher options under \"registry\".");
1478
+ const base = config?.registry ? fromUnifiedConfig(config.registry) : {};
1479
+ return merge(overrides ?? {}, base, { projectRoot: cwd });
2878
1480
  }
2879
1481
  //#endregion
2880
1482
  //#region src/utils.ts
@@ -2942,7 +1544,7 @@ async function collectClassesFromTailwindV4(options) {
2942
1544
  }));
2943
1545
  };
2944
1546
  const addCandidates = async (extractOptions) => {
2945
- const candidates = await extractValidCandidates(extractOptions);
1547
+ const candidates = await (0, _tailwindcss_mangle_engine.extractValidCandidates)(extractOptions);
2946
1548
  for (const candidate of candidates) if (options.filter(candidate)) set.add(candidate);
2947
1549
  };
2948
1550
  if (v4Options.cssSources.length > 0) for (const source of v4Options.cssSources) {
@@ -3915,9 +2517,9 @@ var TailwindcssPatcher = class {
3915
2517
  logger.debug(`[cache] clear scope=${result.scope} contexts=${result.contextsRemoved} entries=${result.entriesRemoved} files=${result.filesRemoved}`);
3916
2518
  return result;
3917
2519
  }
3918
- extractValidCandidates = extractValidCandidates;
2520
+ extractValidCandidates = _tailwindcss_mangle_engine.extractValidCandidates;
3919
2521
  async collectContentTokens(options) {
3920
- return extractProjectCandidatesWithPositions({
2522
+ return (0, _tailwindcss_mangle_engine.extractProjectCandidatesWithPositions)({
3921
2523
  cwd: options?.cwd ?? this.options.projectRoot,
3922
2524
  sources: options?.sources ?? this.options.tailwind.v4?.sources ?? []
3923
2525
  });
@@ -3927,7 +2529,7 @@ var TailwindcssPatcher = class {
3927
2529
  ...options?.cwd === void 0 ? {} : { cwd: options.cwd },
3928
2530
  ...options?.sources === void 0 ? {} : { sources: options.sources }
3929
2531
  };
3930
- return groupTokensByFile(await this.collectContentTokens(collectContentOptions), {
2532
+ return (0, _tailwindcss_mangle_engine.groupTokensByFile)(await this.collectContentTokens(collectContentOptions), {
3931
2533
  ...options?.key === void 0 ? {} : { key: options.key },
3932
2534
  ...options?.stripAbsolutePaths === void 0 ? {} : { stripAbsolutePaths: options.stripAbsolutePaths }
3933
2535
  });
@@ -4570,30 +3172,6 @@ Object.defineProperty(exports, "MIGRATION_REPORT_SCHEMA_VERSION", {
4570
3172
  return MIGRATION_REPORT_SCHEMA_VERSION;
4571
3173
  }
4572
3174
  });
4573
- Object.defineProperty(exports, "TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN", {
4574
- enumerable: true,
4575
- get: function() {
4576
- return TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN;
4577
- }
4578
- });
4579
- Object.defineProperty(exports, "TAILWIND_V4_IGNORED_CONTENT_DIRS", {
4580
- enumerable: true,
4581
- get: function() {
4582
- return TAILWIND_V4_IGNORED_CONTENT_DIRS;
4583
- }
4584
- });
4585
- Object.defineProperty(exports, "TAILWIND_V4_IGNORED_EXTENSIONS", {
4586
- enumerable: true,
4587
- get: function() {
4588
- return TAILWIND_V4_IGNORED_EXTENSIONS;
4589
- }
4590
- });
4591
- Object.defineProperty(exports, "TAILWIND_V4_IGNORED_FILES", {
4592
- enumerable: true,
4593
- get: function() {
4594
- return TAILWIND_V4_IGNORED_FILES;
4595
- }
4596
- });
4597
3175
  Object.defineProperty(exports, "TailwindcssPatcher", {
4598
3176
  enumerable: true,
4599
3177
  get: function() {
@@ -4624,12 +3202,6 @@ Object.defineProperty(exports, "__toESM", {
4624
3202
  return __toESM;
4625
3203
  }
4626
3204
  });
4627
- Object.defineProperty(exports, "canonicalizeBareArbitraryValueCandidates", {
4628
- enumerable: true,
4629
- get: function() {
4630
- return canonicalizeBareArbitraryValueCandidates;
4631
- }
4632
- });
4633
3205
  Object.defineProperty(exports, "classifyValidateError", {
4634
3206
  enumerable: true,
4635
3207
  get: function() {
@@ -4648,144 +3220,12 @@ Object.defineProperty(exports, "collectClassesFromTailwindV4", {
4648
3220
  return collectClassesFromTailwindV4;
4649
3221
  }
4650
3222
  });
4651
- Object.defineProperty(exports, "compileTailwindV4Source", {
4652
- enumerable: true,
4653
- get: function() {
4654
- return compileTailwindV4Source;
4655
- }
4656
- });
4657
- Object.defineProperty(exports, "createTailwindV4CompiledSourceEntries", {
4658
- enumerable: true,
4659
- get: function() {
4660
- return createTailwindV4CompiledSourceEntries;
4661
- }
4662
- });
4663
- Object.defineProperty(exports, "createTailwindV4DefaultIgnoreSources", {
4664
- enumerable: true,
4665
- get: function() {
4666
- return createTailwindV4DefaultIgnoreSources;
4667
- }
4668
- });
4669
- Object.defineProperty(exports, "createTailwindV4RootSources", {
4670
- enumerable: true,
4671
- get: function() {
4672
- return createTailwindV4RootSources;
4673
- }
4674
- });
4675
- Object.defineProperty(exports, "createTailwindV4SourceEntryMatcher", {
4676
- enumerable: true,
4677
- get: function() {
4678
- return createTailwindV4SourceEntryMatcher;
4679
- }
4680
- });
4681
- Object.defineProperty(exports, "createTailwindV4SourceExclusionMatcher", {
4682
- enumerable: true,
4683
- get: function() {
4684
- return createTailwindV4SourceExclusionMatcher;
4685
- }
4686
- });
4687
- Object.defineProperty(exports, "escapeCssClassName", {
4688
- enumerable: true,
4689
- get: function() {
4690
- return escapeCssClassName;
4691
- }
4692
- });
4693
- Object.defineProperty(exports, "expandTailwindV4SourceEntries", {
4694
- enumerable: true,
4695
- get: function() {
4696
- return expandTailwindV4SourceEntries;
4697
- }
4698
- });
4699
- Object.defineProperty(exports, "expandTailwindV4SourceEntryBraces", {
4700
- enumerable: true,
4701
- get: function() {
4702
- return expandTailwindV4SourceEntryBraces;
4703
- }
4704
- });
4705
- Object.defineProperty(exports, "extractBareArbitraryValueSourceCandidates", {
4706
- enumerable: true,
4707
- get: function() {
4708
- return extractBareArbitraryValueSourceCandidates;
4709
- }
4710
- });
4711
- Object.defineProperty(exports, "extractBareArbitraryValueSourceCandidatesWithPositions", {
4712
- enumerable: true,
4713
- get: function() {
4714
- return extractBareArbitraryValueSourceCandidatesWithPositions;
4715
- }
4716
- });
4717
- Object.defineProperty(exports, "extractProjectCandidatesWithPositions", {
4718
- enumerable: true,
4719
- get: function() {
4720
- return extractProjectCandidatesWithPositions;
4721
- }
4722
- });
4723
- Object.defineProperty(exports, "extractRawCandidates", {
4724
- enumerable: true,
4725
- get: function() {
4726
- return extractRawCandidates;
4727
- }
4728
- });
4729
- Object.defineProperty(exports, "extractRawCandidatesWithPositions", {
4730
- enumerable: true,
4731
- get: function() {
4732
- return extractRawCandidatesWithPositions;
4733
- }
4734
- });
4735
- Object.defineProperty(exports, "extractSourceCandidates", {
4736
- enumerable: true,
4737
- get: function() {
4738
- return extractSourceCandidates;
4739
- }
4740
- });
4741
- Object.defineProperty(exports, "extractSourceCandidatesWithPositions", {
4742
- enumerable: true,
4743
- get: function() {
4744
- return extractSourceCandidatesWithPositions;
4745
- }
4746
- });
4747
- Object.defineProperty(exports, "extractTailwindV4InlineSourceCandidates", {
4748
- enumerable: true,
4749
- get: function() {
4750
- return extractTailwindV4InlineSourceCandidates;
4751
- }
4752
- });
4753
- Object.defineProperty(exports, "extractValidCandidates", {
4754
- enumerable: true,
4755
- get: function() {
4756
- return extractValidCandidates;
4757
- }
4758
- });
4759
3223
  Object.defineProperty(exports, "getPatchStatusReport", {
4760
3224
  enumerable: true,
4761
3225
  get: function() {
4762
3226
  return getPatchStatusReport;
4763
3227
  }
4764
3228
  });
4765
- Object.defineProperty(exports, "groupTokensByFile", {
4766
- enumerable: true,
4767
- get: function() {
4768
- return groupTokensByFile;
4769
- }
4770
- });
4771
- Object.defineProperty(exports, "isBareArbitraryValuesEnabled", {
4772
- enumerable: true,
4773
- get: function() {
4774
- return isBareArbitraryValuesEnabled;
4775
- }
4776
- });
4777
- Object.defineProperty(exports, "isFileExcludedByTailwindV4SourceEntries", {
4778
- enumerable: true,
4779
- get: function() {
4780
- return isFileExcludedByTailwindV4SourceEntries;
4781
- }
4782
- });
4783
- Object.defineProperty(exports, "isFileMatchedByTailwindV4SourceEntries", {
4784
- enumerable: true,
4785
- get: function() {
4786
- return isFileMatchedByTailwindV4SourceEntries;
4787
- }
4788
- });
4789
3229
  Object.defineProperty(exports, "loadPatchOptionsForWorkspace", {
4790
3230
  enumerable: true,
4791
3231
  get: function() {
@@ -4798,12 +3238,6 @@ Object.defineProperty(exports, "loadRuntimeContexts", {
4798
3238
  return loadRuntimeContexts;
4799
3239
  }
4800
3240
  });
4801
- Object.defineProperty(exports, "loadTailwindV4DesignSystem", {
4802
- enumerable: true,
4803
- get: function() {
4804
- return loadTailwindV4DesignSystem;
4805
- }
4806
- });
4807
3241
  Object.defineProperty(exports, "loadWorkspaceConfigModule", {
4808
3242
  enumerable: true,
4809
3243
  get: function() {
@@ -4816,12 +3250,6 @@ Object.defineProperty(exports, "logger", {
4816
3250
  return logger;
4817
3251
  }
4818
3252
  });
4819
- Object.defineProperty(exports, "mergeTailwindV4SourceEntries", {
4820
- enumerable: true,
4821
- get: function() {
4822
- return mergeTailwindV4SourceEntries;
4823
- }
4824
- });
4825
3253
  Object.defineProperty(exports, "migrateConfigFiles", {
4826
3254
  enumerable: true,
4827
3255
  get: function() {
@@ -4834,60 +3262,6 @@ Object.defineProperty(exports, "normalizeOptions", {
4834
3262
  return normalizeOptions;
4835
3263
  }
4836
3264
  });
4837
- Object.defineProperty(exports, "normalizeTailwindV4ScannerSources", {
4838
- enumerable: true,
4839
- get: function() {
4840
- return normalizeTailwindV4ScannerSources;
4841
- }
4842
- });
4843
- Object.defineProperty(exports, "normalizeTailwindV4SourceEntries", {
4844
- enumerable: true,
4845
- get: function() {
4846
- return normalizeTailwindV4SourceEntries;
4847
- }
4848
- });
4849
- Object.defineProperty(exports, "replaceBareArbitraryValueSelectors", {
4850
- enumerable: true,
4851
- get: function() {
4852
- return replaceBareArbitraryValueSelectors;
4853
- }
4854
- });
4855
- Object.defineProperty(exports, "resolveBareArbitraryValueCandidate", {
4856
- enumerable: true,
4857
- get: function() {
4858
- return resolveBareArbitraryValueCandidate;
4859
- }
4860
- });
4861
- Object.defineProperty(exports, "resolveProjectSourceFiles", {
4862
- enumerable: true,
4863
- get: function() {
4864
- return resolveProjectSourceFiles;
4865
- }
4866
- });
4867
- Object.defineProperty(exports, "resolveSourceScanPath", {
4868
- enumerable: true,
4869
- get: function() {
4870
- return resolveSourceScanPath;
4871
- }
4872
- });
4873
- Object.defineProperty(exports, "resolveTailwindV4SourceBaseCandidates", {
4874
- enumerable: true,
4875
- get: function() {
4876
- return resolveTailwindV4SourceBaseCandidates;
4877
- }
4878
- });
4879
- Object.defineProperty(exports, "resolveTailwindV4SourceEntry", {
4880
- enumerable: true,
4881
- get: function() {
4882
- return resolveTailwindV4SourceEntry;
4883
- }
4884
- });
4885
- Object.defineProperty(exports, "resolveValidTailwindV4Candidates", {
4886
- enumerable: true,
4887
- get: function() {
4888
- return resolveValidTailwindV4Candidates;
4889
- }
4890
- });
4891
3265
  Object.defineProperty(exports, "restoreConfigFiles", {
4892
3266
  enumerable: true,
4893
3267
  get: function() {