@yahoo/uds 3.104.0 → 3.105.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.
Files changed (78) hide show
  1. package/dist/automated-config/dist/generated/autoVariants.cjs +57 -0
  2. package/dist/automated-config/dist/generated/autoVariants.d.cts +57 -57
  3. package/dist/automated-config/dist/generated/autoVariants.d.ts +57 -57
  4. package/dist/automated-config/dist/generated/autoVariants.js +57 -0
  5. package/dist/automated-config/dist/utils/generateDefaultClassName.cjs +18 -0
  6. package/dist/automated-config/dist/utils/generateDefaultClassName.d.cts +14 -0
  7. package/dist/automated-config/dist/utils/generateDefaultClassName.d.ts +14 -0
  8. package/dist/automated-config/dist/utils/generateDefaultClassName.js +17 -0
  9. package/dist/automated-config/dist/utils/index.cjs +3 -6
  10. package/dist/automated-config/dist/utils/index.d.cts +2 -2
  11. package/dist/automated-config/dist/utils/index.d.ts +2 -2
  12. package/dist/automated-config/dist/utils/index.js +3 -5
  13. package/dist/cli/runner.cjs +21 -5
  14. package/dist/cli/runner.js +21 -5
  15. package/dist/components/client/Button.cjs +9 -9
  16. package/dist/components/client/Button.js +2 -2
  17. package/dist/components/client/IconButton.cjs +8 -8
  18. package/dist/components/client/IconButton.js +2 -2
  19. package/dist/components/client/SpringMotionConfig.cjs +4 -4
  20. package/dist/components/client/SpringMotionConfig.js +5 -5
  21. package/dist/components/client/buttonConstants.cjs +10 -0
  22. package/dist/components/client/buttonConstants.d.cts +9 -0
  23. package/dist/components/client/buttonConstants.d.ts +9 -0
  24. package/dist/components/client/buttonConstants.js +8 -0
  25. package/dist/index.cjs +2 -1
  26. package/dist/index.d.cts +2 -1
  27. package/dist/index.d.ts +2 -1
  28. package/dist/index.js +2 -1
  29. package/dist/motion-tokens/dist/index.cjs +11 -0
  30. package/dist/motion-tokens/dist/index.d.cts +5 -1
  31. package/dist/motion-tokens/dist/index.d.ts +5 -1
  32. package/dist/motion-tokens/dist/index.js +11 -1
  33. package/dist/styles/styler.d.cts +67 -67
  34. package/dist/styles/styler.d.ts +67 -67
  35. package/dist/styles/variants.d.cts +57 -0
  36. package/dist/styles/variants.d.ts +57 -0
  37. package/dist/tailwind/dist/commands/generateComponentData.cjs +65 -0
  38. package/dist/tailwind/dist/commands/generateComponentData.d.ts +3 -0
  39. package/dist/tailwind/dist/commands/generateComponentData.js +64 -0
  40. package/dist/tailwind/dist/commands/generatePurgeCSSData.cjs +1 -1
  41. package/dist/tailwind/dist/commands/generatePurgeCSSData.js +1 -1
  42. package/dist/tailwind/dist/commands/purge.cjs +41 -11
  43. package/dist/tailwind/dist/commands/purge.d.ts +2 -1
  44. package/dist/tailwind/dist/commands/purge.js +41 -11
  45. package/dist/tailwind/dist/index.d.ts +1 -0
  46. package/dist/tailwind/dist/{utils → purger/legacy}/purgeCSS.cjs +7 -7
  47. package/dist/tailwind/dist/{utils → purger/legacy}/purgeCSS.js +6 -6
  48. package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +193 -0
  49. package/dist/tailwind/dist/purger/optimized/ast/expressions.js +192 -0
  50. package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +20 -0
  51. package/dist/tailwind/dist/purger/optimized/ast/jsx.js +19 -0
  52. package/dist/tailwind/dist/purger/optimized/purge.cjs +69 -0
  53. package/dist/tailwind/dist/purger/optimized/purge.js +66 -0
  54. package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +273 -0
  55. package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +272 -0
  56. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +408 -0
  57. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +405 -0
  58. package/dist/tailwind/dist/purger/optimized/utils/files.cjs +27 -0
  59. package/dist/tailwind/dist/purger/optimized/utils/files.js +24 -0
  60. package/dist/tailwind/dist/purger/optimized/utils/safelist.cjs +64 -0
  61. package/dist/tailwind/dist/purger/optimized/utils/safelist.js +60 -0
  62. package/dist/tailwind/dist/tailwind/utils/getColorModeStyles.cjs +1 -0
  63. package/dist/tailwind/dist/tailwind/utils/getColorModeStyles.js +1 -0
  64. package/dist/tailwind/dist/utils/tsMorph.cjs +1 -1
  65. package/dist/tokens/automation/index.cjs +2 -1
  66. package/dist/tokens/automation/index.d.cts +2 -1
  67. package/dist/tokens/automation/index.d.ts +2 -1
  68. package/dist/tokens/automation/index.js +2 -1
  69. package/dist/tokens/index.cjs +2 -1
  70. package/dist/tokens/index.d.cts +2 -1
  71. package/dist/tokens/index.d.ts +2 -1
  72. package/dist/tokens/index.js +2 -1
  73. package/dist/uds/generated/componentData.cjs +2110 -0
  74. package/dist/uds/generated/componentData.js +1720 -0
  75. package/dist/uds/generated/tailwindPurge.cjs +24 -24
  76. package/dist/uds/generated/tailwindPurge.js +24 -24
  77. package/package.json +1 -1
  78. /package/dist/tailwind/dist/{utils → purger/legacy}/purgeCSS.d.ts +0 -0
@@ -1,7 +1,9 @@
1
1
  /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
2
  import { trackEvent } from "../../../cli/dist/utils/analytics.js";
3
+ import { print } from "../../../cli/dist/lib/print.js";
3
4
  import { spinStart, spinStop } from "../../../cli/dist/lib/spinner.js";
4
- import { purge } from "../utils/purgeCSS.js";
5
+ import { purge } from "../purger/legacy/purgeCSS.js";
6
+ import { purgeOptimized } from "../purger/optimized/purge.js";
5
7
 
6
8
  //#region ../tailwind/dist/commands/purge.js
7
9
  /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
@@ -9,16 +11,44 @@ const makePurgeCommand = (getContext) => ({
9
11
  name: "purge",
10
12
  description: `Purge unused CSS`,
11
13
  run: async (props) => {
12
- spinStart("Purging css started...");
13
- try {
14
- const { variants, packageJson, generatedPurgeCssData } = await getContext();
15
- await purge(variants, packageJson, generatedPurgeCssData, props.options);
16
- spinStop("✅", "Purging css done!");
17
- return await trackEvent("purge");
18
- } catch (error) {
19
- if (error instanceof Error) spinStop("", error.message);
20
- else spinStop("❌", "Purging css failed! Please reach out to #uds-ask channel for support.");
21
- process.exitCode = 1;
14
+ const { entry, output, optimized, config } = props.options;
15
+ const useOptimized = optimized === "true" || optimized === true;
16
+ const { variants, autoVariants, packageJson, generatedPurgeCssData, componentData } = await getContext();
17
+ if (useOptimized) {
18
+ spinStart("Purging CSS with optimized purger...");
19
+ try {
20
+ const result = await purgeOptimized({
21
+ entry: typeof entry === "string" ? entry : void 0,
22
+ output: typeof output === "string" ? output : void 0,
23
+ variants,
24
+ autoVariants,
25
+ componentData
26
+ });
27
+ spinStop("✅", `Purging done (optimized)! Generated ${result.stats.classesGenerated} classes in ${result.stats.timeMs}ms`);
28
+ print(` Files scanned: ${result.stats.filesScanned}`);
29
+ print(` Spreads traced: ${result.stats.spreadsTraced}`);
30
+ print(` Expressions resolved: ${result.stats.expressionsResolved}`);
31
+ return await trackEvent("purge", { optimized: true });
32
+ } catch (error) {
33
+ if (error instanceof Error) spinStop("❌", error.message);
34
+ else spinStop("❌", "Purging css failed! Please reach out to #uds-ask channel for support.");
35
+ process.exitCode = 1;
36
+ }
37
+ } else {
38
+ spinStart("Purging css started...");
39
+ try {
40
+ await purge(variants, packageJson, generatedPurgeCssData, {
41
+ config: typeof config === "string" ? config : void 0,
42
+ entry: typeof entry === "string" ? entry : void 0,
43
+ output: typeof output === "string" ? output : void 0
44
+ });
45
+ spinStop("✅", "Purging css done!");
46
+ return await trackEvent("purge");
47
+ } catch (error) {
48
+ if (error instanceof Error) spinStop("❌", error.message);
49
+ else spinStop("❌", "Purging css failed! Please reach out to #uds-ask channel for support.");
50
+ process.exitCode = 1;
51
+ }
22
52
  }
23
53
  }
24
54
  });
@@ -1,5 +1,6 @@
1
1
 
2
2
  import "./tailwind/components/getResponsiveTextStyles.js";
3
3
  import { WebTokens, parseTokens } from "./utils/parseTokens.js";
4
+ import "./commands/generateComponentData.js";
4
5
  import "./commands/generatePurgeCSSData.js";
5
6
  import "./commands/purge.js";
@@ -1,9 +1,9 @@
1
1
  /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
- const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
- const require_index = require('../../../css-tokens/dist/index.cjs');
4
- const require_print = require('../../../cli/dist/lib/print.cjs');
5
- const require_spinner = require('../../../cli/dist/lib/spinner.cjs');
6
- const require_tsMorph = require('./tsMorph.cjs');
2
+ const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
3
+ const require_index = require('../../../../css-tokens/dist/index.cjs');
4
+ const require_print = require('../../../../cli/dist/lib/print.cjs');
5
+ const require_spinner = require('../../../../cli/dist/lib/spinner.cjs');
6
+ const require_tsMorph = require('../../utils/tsMorph.cjs');
7
7
  let node_path = require("node:path");
8
8
  node_path = require_runtime.__toESM(node_path);
9
9
  let node_fs = require("node:fs");
@@ -11,7 +11,7 @@ let ts_morph = require("ts-morph");
11
11
  let fast_glob = require("fast-glob");
12
12
  fast_glob = require_runtime.__toESM(fast_glob);
13
13
 
14
- //#region ../tailwind/dist/utils/purgeCSS.js
14
+ //#region ../tailwind/dist/purger/legacy/purgeCSS.js
15
15
  /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
16
16
  const scaleModeToClass = {
17
17
  large: require_index.LARGE_SCALE_MODE_CLASSNAME,
@@ -128,7 +128,7 @@ const isUDSComponent = (component, { componentToVariants }) => {
128
128
  };
129
129
  const saveToFile = (safeList, outputPath) => {
130
130
  const fileContent = `
131
- //! This file is generated by purgeCSS.ts from @yahoo/uds
131
+ //! This file is generated by \`uds purge\` from @yahoo/uds
132
132
  //! Do not edit directly
133
133
  //! If there is issue with this file please report to #ask-uds
134
134
  export const safelist = ${JSON.stringify(safeList)};
@@ -1,14 +1,14 @@
1
1
  /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
- import { DARK_COLOR_MODE_CLASSNAME, LARGE_SCALE_MODE_CLASSNAME, LIGHT_COLOR_MODE_CLASSNAME, MEDIUM_SCALE_MODE_CLASSNAME, SMALL_SCALE_MODE_CLASSNAME, XLARGE_SCALE_MODE_CLASSNAME, XSMALL_SCALE_MODE_CLASSNAME, XXLARGE_SCALE_MODE_CLASSNAME, XXXLARGE_SCALE_MODE_CLASSNAME } from "../../../css-tokens/dist/index.js";
3
- import { print } from "../../../cli/dist/lib/print.js";
4
- import { spinStart, spinStop } from "../../../cli/dist/lib/spinner.js";
5
- import { findReferencesAsJsxElements, getUsedPropsInReference } from "./tsMorph.js";
2
+ import { DARK_COLOR_MODE_CLASSNAME, LARGE_SCALE_MODE_CLASSNAME, LIGHT_COLOR_MODE_CLASSNAME, MEDIUM_SCALE_MODE_CLASSNAME, SMALL_SCALE_MODE_CLASSNAME, XLARGE_SCALE_MODE_CLASSNAME, XSMALL_SCALE_MODE_CLASSNAME, XXLARGE_SCALE_MODE_CLASSNAME, XXXLARGE_SCALE_MODE_CLASSNAME } from "../../../../css-tokens/dist/index.js";
3
+ import { print } from "../../../../cli/dist/lib/print.js";
4
+ import { spinStart, spinStop } from "../../../../cli/dist/lib/spinner.js";
5
+ import { findReferencesAsJsxElements, getUsedPropsInReference } from "../../utils/tsMorph.js";
6
6
  import path from "node:path";
7
7
  import { mkdirSync, writeFileSync } from "node:fs";
8
8
  import { Node, Project, SyntaxKind, ts } from "ts-morph";
9
9
  import fg from "fast-glob";
10
10
 
11
- //#region ../tailwind/dist/utils/purgeCSS.js
11
+ //#region ../tailwind/dist/purger/legacy/purgeCSS.js
12
12
  /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
13
13
  const scaleModeToClass = {
14
14
  large: LARGE_SCALE_MODE_CLASSNAME,
@@ -125,7 +125,7 @@ const isUDSComponent = (component, { componentToVariants }) => {
125
125
  };
126
126
  const saveToFile = (safeList, outputPath) => {
127
127
  const fileContent = `
128
- //! This file is generated by purgeCSS.ts from @yahoo/uds
128
+ //! This file is generated by \`uds purge\` from @yahoo/uds
129
129
  //! Do not edit directly
130
130
  //! If there is issue with this file please report to #ask-uds
131
131
  export const safelist = ${JSON.stringify(safeList)};
@@ -0,0 +1,193 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_runtime = require('../../../../../_virtual/_rolldown/runtime.cjs');
3
+ let ts_morph = require("ts-morph");
4
+
5
+ //#region ../tailwind/dist/purger/optimized/ast/expressions.js
6
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
7
+ /**
8
+ * Extracts string literal values from an expression.
9
+ *
10
+ * Handles:
11
+ * - Direct string literals: 'value'
12
+ * - Ternary expressions: condition ? 'a' : 'b' -> ['a', 'b']
13
+ * - Variable references: traces back to initializer
14
+ * - Logical expressions: a || 'fallback', a ?? 'default'
15
+ * - Function calls: traces to return statements
16
+ * - Template literals: `value`
17
+ * - As expressions: value as Type
18
+ *
19
+ * @param node The expression node to extract values from
20
+ * @param visited Set of visited nodes to prevent infinite recursion
21
+ * @returns Array of extracted string literal values
22
+ */
23
+ function extractStringLiterals(node, visited = /* @__PURE__ */ new Set()) {
24
+ if (visited.has(node)) return [];
25
+ visited.add(node);
26
+ const values = [];
27
+ if (ts_morph.Node.isStringLiteral(node)) {
28
+ values.push(node.getLiteralValue());
29
+ return values;
30
+ }
31
+ if (ts_morph.Node.isNoSubstitutionTemplateLiteral(node)) {
32
+ values.push(node.getLiteralValue());
33
+ return values;
34
+ }
35
+ if (ts_morph.Node.isConditionalExpression(node)) {
36
+ values.push(...extractStringLiterals(node.getWhenTrue(), visited));
37
+ values.push(...extractStringLiterals(node.getWhenFalse(), visited));
38
+ return values;
39
+ }
40
+ if (ts_morph.Node.isBinaryExpression(node)) {
41
+ const op = node.getOperatorToken().getText();
42
+ if (op === "||" || op === "??") {
43
+ values.push(...extractStringLiterals(node.getLeft(), visited));
44
+ values.push(...extractStringLiterals(node.getRight(), visited));
45
+ return values;
46
+ }
47
+ }
48
+ if (ts_morph.Node.isParenthesizedExpression(node)) {
49
+ values.push(...extractStringLiterals(node.getExpression(), visited));
50
+ return values;
51
+ }
52
+ if (ts_morph.Node.isAsExpression(node)) {
53
+ values.push(...extractStringLiterals(node.getExpression(), visited));
54
+ return values;
55
+ }
56
+ if (ts_morph.Node.isPropertyAccessExpression(node)) {
57
+ const typeValues = extractLiteralValuesFromType(node);
58
+ if (typeValues.length > 0) {
59
+ values.push(...typeValues);
60
+ return values;
61
+ }
62
+ const expression = node.getExpression();
63
+ const propertyName = node.getName();
64
+ const baseValues = extractObjectValues(expression, visited);
65
+ for (const objValue of baseValues) if (typeof objValue === "object" && objValue !== null && propertyName in objValue) {
66
+ const propValue = objValue[propertyName];
67
+ if (typeof propValue === "string") values.push(propValue);
68
+ }
69
+ return values;
70
+ }
71
+ if (ts_morph.Node.isElementAccessExpression(node)) {
72
+ const typeValues = extractLiteralValuesFromType(node);
73
+ if (typeValues.length > 0) {
74
+ values.push(...typeValues);
75
+ return values;
76
+ }
77
+ return values;
78
+ }
79
+ if (ts_morph.Node.isCallExpression(node)) {
80
+ const expression = node.getExpression();
81
+ if (ts_morph.Node.isIdentifier(expression)) for (const definition of expression.getDefinitionNodes()) {
82
+ if (ts_morph.Node.isFunctionDeclaration(definition)) for (const returnStmt of definition.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement)) {
83
+ const returnExpr = returnStmt.getExpression();
84
+ if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
85
+ }
86
+ if (ts_morph.Node.isVariableDeclaration(definition)) {
87
+ const initializer = definition.getInitializer();
88
+ if (initializer) values.push(...extractFromFunctionLike(initializer, visited));
89
+ }
90
+ }
91
+ return values;
92
+ }
93
+ if (ts_morph.Node.isIdentifier(node)) {
94
+ let foundInitializer = false;
95
+ for (const definition of node.getDefinitionNodes()) {
96
+ if (ts_morph.Node.isVariableDeclaration(definition)) {
97
+ const initializer = definition.getInitializer();
98
+ if (initializer) {
99
+ foundInitializer = true;
100
+ values.push(...extractStringLiterals(initializer, visited));
101
+ }
102
+ }
103
+ if (ts_morph.Node.isParameterDeclaration(definition)) {
104
+ const initializer = definition.getInitializer();
105
+ if (initializer) {
106
+ foundInitializer = true;
107
+ values.push(...extractStringLiterals(initializer, visited));
108
+ }
109
+ }
110
+ if (ts_morph.Node.isBindingElement(definition)) {
111
+ const initializer = definition.getInitializer();
112
+ if (initializer) {
113
+ foundInitializer = true;
114
+ values.push(...extractStringLiterals(initializer, visited));
115
+ }
116
+ }
117
+ }
118
+ if (!foundInitializer && values.length === 0) values.push(...extractLiteralValuesFromType(node));
119
+ return values;
120
+ }
121
+ return values;
122
+ }
123
+ /**
124
+ * Extract string literals from arrow functions or function expressions
125
+ */
126
+ function extractFromFunctionLike(node, visited) {
127
+ const values = [];
128
+ if (ts_morph.Node.isArrowFunction(node)) {
129
+ const body = node.getBody();
130
+ if (ts_morph.Node.isBlock(body)) for (const returnStmt of body.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement)) {
131
+ const returnExpr = returnStmt.getExpression();
132
+ if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
133
+ }
134
+ else values.push(...extractStringLiterals(body, visited));
135
+ } else if (ts_morph.Node.isFunctionExpression(node)) for (const returnStmt of node.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement)) {
136
+ const returnExpr = returnStmt.getExpression();
137
+ if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
138
+ }
139
+ return values;
140
+ }
141
+ /**
142
+ * Extract object literal values from an expression.
143
+ * Returns an array of all possible object values (for union types or indexed access).
144
+ */
145
+ function extractObjectValues(node, visited) {
146
+ if (visited.has(node)) return [];
147
+ visited.add(node);
148
+ const values = [];
149
+ if (ts_morph.Node.isObjectLiteralExpression(node)) {
150
+ const obj = {};
151
+ for (const prop of node.getProperties()) if (ts_morph.Node.isPropertyAssignment(prop)) {
152
+ const name = prop.getName();
153
+ const init = prop.getInitializer();
154
+ if (init && ts_morph.Node.isStringLiteral(init)) obj[name] = init.getLiteralValue();
155
+ else if (init && ts_morph.Node.isObjectLiteralExpression(init)) {
156
+ const nestedValues = extractObjectValues(init, visited);
157
+ if (nestedValues.length > 0) obj[name] = nestedValues[0];
158
+ }
159
+ }
160
+ values.push(obj);
161
+ return values;
162
+ }
163
+ if (ts_morph.Node.isIdentifier(node)) {
164
+ for (const definition of node.getDefinitionNodes()) if (ts_morph.Node.isVariableDeclaration(definition)) {
165
+ const initializer = definition.getInitializer();
166
+ if (initializer) if (ts_morph.Node.isAsExpression(initializer)) {
167
+ const inner = initializer.getExpression();
168
+ values.push(...extractObjectValues(inner, visited));
169
+ } else values.push(...extractObjectValues(initializer, visited));
170
+ }
171
+ return values;
172
+ }
173
+ if (ts_morph.Node.isElementAccessExpression(node)) {
174
+ const baseObjects = extractObjectValues(node.getExpression(), visited);
175
+ for (const obj of baseObjects) if (typeof obj === "object" && obj !== null) for (const value of Object.values(obj)) values.push(value);
176
+ return values;
177
+ }
178
+ return values;
179
+ }
180
+ /**
181
+ * Extract literal values from a TypeScript type (for union types like 'brand' | 'secondary')
182
+ */
183
+ function extractLiteralValuesFromType(node) {
184
+ const values = [];
185
+ const nodeType = node.getType();
186
+ if (nodeType.isUnion()) {
187
+ for (const unionMember of nodeType.getUnionTypes()) if (unionMember.isStringLiteral()) values.push(unionMember.getLiteralValue());
188
+ } else if (nodeType.isStringLiteral()) values.push(nodeType.getLiteralValue());
189
+ return values;
190
+ }
191
+
192
+ //#endregion
193
+ exports.extractStringLiterals = extractStringLiterals;
@@ -0,0 +1,192 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { Node, SyntaxKind } from "ts-morph";
3
+
4
+ //#region ../tailwind/dist/purger/optimized/ast/expressions.js
5
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
6
+ /**
7
+ * Extracts string literal values from an expression.
8
+ *
9
+ * Handles:
10
+ * - Direct string literals: 'value'
11
+ * - Ternary expressions: condition ? 'a' : 'b' -> ['a', 'b']
12
+ * - Variable references: traces back to initializer
13
+ * - Logical expressions: a || 'fallback', a ?? 'default'
14
+ * - Function calls: traces to return statements
15
+ * - Template literals: `value`
16
+ * - As expressions: value as Type
17
+ *
18
+ * @param node The expression node to extract values from
19
+ * @param visited Set of visited nodes to prevent infinite recursion
20
+ * @returns Array of extracted string literal values
21
+ */
22
+ function extractStringLiterals(node, visited = /* @__PURE__ */ new Set()) {
23
+ if (visited.has(node)) return [];
24
+ visited.add(node);
25
+ const values = [];
26
+ if (Node.isStringLiteral(node)) {
27
+ values.push(node.getLiteralValue());
28
+ return values;
29
+ }
30
+ if (Node.isNoSubstitutionTemplateLiteral(node)) {
31
+ values.push(node.getLiteralValue());
32
+ return values;
33
+ }
34
+ if (Node.isConditionalExpression(node)) {
35
+ values.push(...extractStringLiterals(node.getWhenTrue(), visited));
36
+ values.push(...extractStringLiterals(node.getWhenFalse(), visited));
37
+ return values;
38
+ }
39
+ if (Node.isBinaryExpression(node)) {
40
+ const op = node.getOperatorToken().getText();
41
+ if (op === "||" || op === "??") {
42
+ values.push(...extractStringLiterals(node.getLeft(), visited));
43
+ values.push(...extractStringLiterals(node.getRight(), visited));
44
+ return values;
45
+ }
46
+ }
47
+ if (Node.isParenthesizedExpression(node)) {
48
+ values.push(...extractStringLiterals(node.getExpression(), visited));
49
+ return values;
50
+ }
51
+ if (Node.isAsExpression(node)) {
52
+ values.push(...extractStringLiterals(node.getExpression(), visited));
53
+ return values;
54
+ }
55
+ if (Node.isPropertyAccessExpression(node)) {
56
+ const typeValues = extractLiteralValuesFromType(node);
57
+ if (typeValues.length > 0) {
58
+ values.push(...typeValues);
59
+ return values;
60
+ }
61
+ const expression = node.getExpression();
62
+ const propertyName = node.getName();
63
+ const baseValues = extractObjectValues(expression, visited);
64
+ for (const objValue of baseValues) if (typeof objValue === "object" && objValue !== null && propertyName in objValue) {
65
+ const propValue = objValue[propertyName];
66
+ if (typeof propValue === "string") values.push(propValue);
67
+ }
68
+ return values;
69
+ }
70
+ if (Node.isElementAccessExpression(node)) {
71
+ const typeValues = extractLiteralValuesFromType(node);
72
+ if (typeValues.length > 0) {
73
+ values.push(...typeValues);
74
+ return values;
75
+ }
76
+ return values;
77
+ }
78
+ if (Node.isCallExpression(node)) {
79
+ const expression = node.getExpression();
80
+ if (Node.isIdentifier(expression)) for (const definition of expression.getDefinitionNodes()) {
81
+ if (Node.isFunctionDeclaration(definition)) for (const returnStmt of definition.getDescendantsOfKind(SyntaxKind.ReturnStatement)) {
82
+ const returnExpr = returnStmt.getExpression();
83
+ if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
84
+ }
85
+ if (Node.isVariableDeclaration(definition)) {
86
+ const initializer = definition.getInitializer();
87
+ if (initializer) values.push(...extractFromFunctionLike(initializer, visited));
88
+ }
89
+ }
90
+ return values;
91
+ }
92
+ if (Node.isIdentifier(node)) {
93
+ let foundInitializer = false;
94
+ for (const definition of node.getDefinitionNodes()) {
95
+ if (Node.isVariableDeclaration(definition)) {
96
+ const initializer = definition.getInitializer();
97
+ if (initializer) {
98
+ foundInitializer = true;
99
+ values.push(...extractStringLiterals(initializer, visited));
100
+ }
101
+ }
102
+ if (Node.isParameterDeclaration(definition)) {
103
+ const initializer = definition.getInitializer();
104
+ if (initializer) {
105
+ foundInitializer = true;
106
+ values.push(...extractStringLiterals(initializer, visited));
107
+ }
108
+ }
109
+ if (Node.isBindingElement(definition)) {
110
+ const initializer = definition.getInitializer();
111
+ if (initializer) {
112
+ foundInitializer = true;
113
+ values.push(...extractStringLiterals(initializer, visited));
114
+ }
115
+ }
116
+ }
117
+ if (!foundInitializer && values.length === 0) values.push(...extractLiteralValuesFromType(node));
118
+ return values;
119
+ }
120
+ return values;
121
+ }
122
+ /**
123
+ * Extract string literals from arrow functions or function expressions
124
+ */
125
+ function extractFromFunctionLike(node, visited) {
126
+ const values = [];
127
+ if (Node.isArrowFunction(node)) {
128
+ const body = node.getBody();
129
+ if (Node.isBlock(body)) for (const returnStmt of body.getDescendantsOfKind(SyntaxKind.ReturnStatement)) {
130
+ const returnExpr = returnStmt.getExpression();
131
+ if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
132
+ }
133
+ else values.push(...extractStringLiterals(body, visited));
134
+ } else if (Node.isFunctionExpression(node)) for (const returnStmt of node.getDescendantsOfKind(SyntaxKind.ReturnStatement)) {
135
+ const returnExpr = returnStmt.getExpression();
136
+ if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
137
+ }
138
+ return values;
139
+ }
140
+ /**
141
+ * Extract object literal values from an expression.
142
+ * Returns an array of all possible object values (for union types or indexed access).
143
+ */
144
+ function extractObjectValues(node, visited) {
145
+ if (visited.has(node)) return [];
146
+ visited.add(node);
147
+ const values = [];
148
+ if (Node.isObjectLiteralExpression(node)) {
149
+ const obj = {};
150
+ for (const prop of node.getProperties()) if (Node.isPropertyAssignment(prop)) {
151
+ const name = prop.getName();
152
+ const init = prop.getInitializer();
153
+ if (init && Node.isStringLiteral(init)) obj[name] = init.getLiteralValue();
154
+ else if (init && Node.isObjectLiteralExpression(init)) {
155
+ const nestedValues = extractObjectValues(init, visited);
156
+ if (nestedValues.length > 0) obj[name] = nestedValues[0];
157
+ }
158
+ }
159
+ values.push(obj);
160
+ return values;
161
+ }
162
+ if (Node.isIdentifier(node)) {
163
+ for (const definition of node.getDefinitionNodes()) if (Node.isVariableDeclaration(definition)) {
164
+ const initializer = definition.getInitializer();
165
+ if (initializer) if (Node.isAsExpression(initializer)) {
166
+ const inner = initializer.getExpression();
167
+ values.push(...extractObjectValues(inner, visited));
168
+ } else values.push(...extractObjectValues(initializer, visited));
169
+ }
170
+ return values;
171
+ }
172
+ if (Node.isElementAccessExpression(node)) {
173
+ const baseObjects = extractObjectValues(node.getExpression(), visited);
174
+ for (const obj of baseObjects) if (typeof obj === "object" && obj !== null) for (const value of Object.values(obj)) values.push(value);
175
+ return values;
176
+ }
177
+ return values;
178
+ }
179
+ /**
180
+ * Extract literal values from a TypeScript type (for union types like 'brand' | 'secondary')
181
+ */
182
+ function extractLiteralValuesFromType(node) {
183
+ const values = [];
184
+ const nodeType = node.getType();
185
+ if (nodeType.isUnion()) {
186
+ for (const unionMember of nodeType.getUnionTypes()) if (unionMember.isStringLiteral()) values.push(unionMember.getLiteralValue());
187
+ } else if (nodeType.isStringLiteral()) values.push(nodeType.getLiteralValue());
188
+ return values;
189
+ }
190
+
191
+ //#endregion
192
+ export { extractStringLiterals };
@@ -0,0 +1,20 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_runtime = require('../../../../../_virtual/_rolldown/runtime.cjs');
3
+ let ts_morph = require("ts-morph");
4
+
5
+ //#region ../tailwind/dist/purger/optimized/ast/jsx.js
6
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
7
+ /**
8
+ * Find all JSX usages of a component from its identifier
9
+ */
10
+ function findJsxReferences(identifier) {
11
+ const elements = [];
12
+ for (const reference of identifier.findReferencesAsNodes()) {
13
+ const node = reference.getFirstAncestor((n) => ts_morph.Node.isJsxOpeningElement(n) || ts_morph.Node.isJsxSelfClosingElement(n));
14
+ if (node && (ts_morph.Node.isJsxOpeningElement(node) || ts_morph.Node.isJsxSelfClosingElement(node))) elements.push(node);
15
+ }
16
+ return elements;
17
+ }
18
+
19
+ //#endregion
20
+ exports.findJsxReferences = findJsxReferences;
@@ -0,0 +1,19 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { Node, SyntaxKind } from "ts-morph";
3
+
4
+ //#region ../tailwind/dist/purger/optimized/ast/jsx.js
5
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
6
+ /**
7
+ * Find all JSX usages of a component from its identifier
8
+ */
9
+ function findJsxReferences(identifier) {
10
+ const elements = [];
11
+ for (const reference of identifier.findReferencesAsNodes()) {
12
+ const node = reference.getFirstAncestor((n) => Node.isJsxOpeningElement(n) || Node.isJsxSelfClosingElement(n));
13
+ if (node && (Node.isJsxOpeningElement(node) || Node.isJsxSelfClosingElement(node))) elements.push(node);
14
+ }
15
+ return elements;
16
+ }
17
+
18
+ //#endregion
19
+ export { findJsxReferences };
@@ -0,0 +1,69 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
3
+ const require_purgeFromCode = require('./purgeFromCode.cjs');
4
+ const require_files = require('./utils/files.cjs');
5
+ const require_safelist = require('./utils/safelist.cjs');
6
+ let node_path = require("node:path");
7
+ node_path = require_runtime.__toESM(node_path);
8
+ let node_fs = require("node:fs");
9
+ node_fs = require_runtime.__toESM(node_fs);
10
+
11
+ //#region ../tailwind/dist/purger/optimized/purge.js
12
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
13
+ const warnedLocations = /* @__PURE__ */ new Set();
14
+ /**
15
+ * Clear warned locations (call at start of new purge run)
16
+ */
17
+ function clearWarnings() {
18
+ warnedLocations.clear();
19
+ }
20
+ /**
21
+ * Main purge function - optimized version
22
+ *
23
+ * Uses purgeFromCodeOptimized internally to ensure consistent behavior
24
+ * between CLI and playground.
25
+ */
26
+ async function purgeOptimized(options) {
27
+ const { entry = "/src/", output = "dist/safelist.ts", colorModes = ["dark"], variants, autoVariants, componentData } = options;
28
+ const startTime = performance.now();
29
+ clearWarnings();
30
+ const workspaceDir = process.env.PWD ?? process.cwd();
31
+ const files = await require_files.scanForFiles(entry);
32
+ const allClasses = [];
33
+ const allImports = /* @__PURE__ */ new Set();
34
+ const allComponents = /* @__PURE__ */ new Set();
35
+ const stats = {
36
+ filesScanned: files.length,
37
+ timeMs: 0,
38
+ classesGenerated: 0,
39
+ spreadsTraced: 0,
40
+ expressionsResolved: 0
41
+ };
42
+ for (const filePath of files) {
43
+ const result = await require_purgeFromCode.purgeFromCodeOptimized(node_fs.default.readFileSync(filePath, "utf-8"), {
44
+ colorModes,
45
+ variants,
46
+ autoVariants,
47
+ componentData
48
+ });
49
+ allClasses.push(...result.safelist);
50
+ result.imports.forEach((imp) => allImports.add(imp));
51
+ result.components.forEach((comp) => allComponents.add(comp));
52
+ stats.spreadsTraced += result.stats.spreadsTraced;
53
+ stats.expressionsResolved += result.stats.expressionsResolved;
54
+ }
55
+ allClasses.push(...require_safelist.getThemeAndScaleClasses(colorModes));
56
+ const finalSafelist = require_safelist.deduplicateSafelist(allClasses);
57
+ await require_safelist.saveSafelistToFile(finalSafelist, node_path.default.join(workspaceDir, output));
58
+ stats.timeMs = Math.round(performance.now() - startTime);
59
+ stats.classesGenerated = finalSafelist.length;
60
+ return {
61
+ safelist: finalSafelist,
62
+ imports: [...allImports],
63
+ components: [...allComponents],
64
+ stats
65
+ };
66
+ }
67
+
68
+ //#endregion
69
+ exports.purgeOptimized = purgeOptimized;