@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
@@ -0,0 +1,66 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { purgeFromCodeOptimized } from "./purgeFromCode.js";
3
+ import { scanForFiles } from "./utils/files.js";
4
+ import { deduplicateSafelist, getThemeAndScaleClasses, saveSafelistToFile } from "./utils/safelist.js";
5
+ import path from "node:path";
6
+ import fs from "node:fs";
7
+
8
+ //#region ../tailwind/dist/purger/optimized/purge.js
9
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
10
+ const warnedLocations = /* @__PURE__ */ new Set();
11
+ /**
12
+ * Clear warned locations (call at start of new purge run)
13
+ */
14
+ function clearWarnings() {
15
+ warnedLocations.clear();
16
+ }
17
+ /**
18
+ * Main purge function - optimized version
19
+ *
20
+ * Uses purgeFromCodeOptimized internally to ensure consistent behavior
21
+ * between CLI and playground.
22
+ */
23
+ async function purgeOptimized(options) {
24
+ const { entry = "/src/", output = "dist/safelist.ts", colorModes = ["dark"], variants, autoVariants, componentData } = options;
25
+ const startTime = performance.now();
26
+ clearWarnings();
27
+ const workspaceDir = process.env.PWD ?? process.cwd();
28
+ const files = await scanForFiles(entry);
29
+ const allClasses = [];
30
+ const allImports = /* @__PURE__ */ new Set();
31
+ const allComponents = /* @__PURE__ */ new Set();
32
+ const stats = {
33
+ filesScanned: files.length,
34
+ timeMs: 0,
35
+ classesGenerated: 0,
36
+ spreadsTraced: 0,
37
+ expressionsResolved: 0
38
+ };
39
+ for (const filePath of files) {
40
+ const result = await purgeFromCodeOptimized(fs.readFileSync(filePath, "utf-8"), {
41
+ colorModes,
42
+ variants,
43
+ autoVariants,
44
+ componentData
45
+ });
46
+ allClasses.push(...result.safelist);
47
+ result.imports.forEach((imp) => allImports.add(imp));
48
+ result.components.forEach((comp) => allComponents.add(comp));
49
+ stats.spreadsTraced += result.stats.spreadsTraced;
50
+ stats.expressionsResolved += result.stats.expressionsResolved;
51
+ }
52
+ allClasses.push(...getThemeAndScaleClasses(colorModes));
53
+ const finalSafelist = deduplicateSafelist(allClasses);
54
+ await saveSafelistToFile(finalSafelist, path.join(workspaceDir, output));
55
+ stats.timeMs = Math.round(performance.now() - startTime);
56
+ stats.classesGenerated = finalSafelist.length;
57
+ return {
58
+ safelist: finalSafelist,
59
+ imports: [...allImports],
60
+ components: [...allComponents],
61
+ stats
62
+ };
63
+ }
64
+
65
+ //#endregion
66
+ export { purgeOptimized };
@@ -0,0 +1,273 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
3
+ const require_expressions = require('./ast/expressions.cjs');
4
+ const require_jsx = require('./ast/jsx.cjs');
5
+ let ts_morph = require("ts-morph");
6
+
7
+ //#region ../tailwind/dist/purger/optimized/purgeFromCode.js
8
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
9
+ /**
10
+ * Get component info with all its dependencies (using pre-generated data)
11
+ */
12
+ function getComponentWithDeps(componentName) {
13
+ const visited = /* @__PURE__ */ new Set();
14
+ const result = [];
15
+ function collect(name) {
16
+ if (visited.has(name)) return;
17
+ visited.add(name);
18
+ const info = componentCache[name];
19
+ if (!info) return;
20
+ result.push(info);
21
+ for (const depName of info.internalComponents) collect(depName);
22
+ }
23
+ collect(componentName);
24
+ return result;
25
+ }
26
+ /**
27
+ * Auto-variants lookup (loaded at module init)
28
+ */
29
+ let autoVariantsCache = null;
30
+ /**
31
+ * Pre-generated component data (loaded at module init)
32
+ */
33
+ let componentCache = null;
34
+ async function purgeFromCodeOptimized(code, options) {
35
+ const { variants, autoVariants, componentData } = options;
36
+ if (!autoVariantsCache) autoVariantsCache = autoVariants;
37
+ if (!componentCache) componentCache = componentData;
38
+ const startTime = performance.now();
39
+ const sourceFile = new ts_morph.Project({ useInMemoryFileSystem: true }).createSourceFile("input.tsx", code);
40
+ const stats = {
41
+ filesScanned: 1,
42
+ timeMs: 0,
43
+ classesGenerated: 0,
44
+ spreadsTraced: 0,
45
+ expressionsResolved: 0
46
+ };
47
+ const imports = [];
48
+ for (const importDecl of sourceFile.getImportDeclarations()) if (importDecl.getModuleSpecifier().getText().includes("@yahoo/uds")) for (const namedImport of importDecl.getNamedImports()) imports.push(namedImport.getName());
49
+ const componentProps = /* @__PURE__ */ new Map();
50
+ const getStylesProps = extractGetStylesCalls(sourceFile, stats, variants);
51
+ for (const imp of imports) {
52
+ const references = findComponentReferences(sourceFile, imp);
53
+ const propsMap = componentProps.get(imp) ?? /* @__PURE__ */ new Map();
54
+ for (const reference of references) {
55
+ const props = extractPropsFromReference(reference, stats, sourceFile);
56
+ for (const [propName, values] of props) if (values.length > 0) {
57
+ const existing = propsMap.get(propName) ?? /* @__PURE__ */ new Set();
58
+ for (const val of values) existing.add(val);
59
+ propsMap.set(propName, existing);
60
+ }
61
+ }
62
+ componentProps.set(imp, propsMap);
63
+ }
64
+ const allComponents = [];
65
+ const seenComponents = /* @__PURE__ */ new Set();
66
+ for (const componentName of imports) {
67
+ const componentsWithDeps = getComponentWithDeps(componentName);
68
+ for (const comp of componentsWithDeps) if (!seenComponents.has(comp.name)) {
69
+ seenComponents.add(comp.name);
70
+ allComponents.push(comp);
71
+ }
72
+ }
73
+ const safelist = [];
74
+ for (const [propName, values] of getStylesProps) {
75
+ const variantGroup = variants[propName];
76
+ if (variantGroup) for (const value of values) {
77
+ const cls = variantGroup[value];
78
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
79
+ }
80
+ }
81
+ for (const componentInfo of allComponents) {
82
+ const userProps = componentProps.get(componentInfo.name) ?? /* @__PURE__ */ new Map();
83
+ for (const [propName, propValue] of Object.entries(componentInfo.defaultProps)) {
84
+ if (userProps.has(propName)) continue;
85
+ const variantGroup = variants[propName];
86
+ if (variantGroup) {
87
+ const cls = variantGroup[propValue];
88
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
89
+ }
90
+ const variantKeys = componentInfo.propToVariantKeys?.[propName];
91
+ if (variantKeys) for (const variantKey of variantKeys) {
92
+ const mappedVariantGroup = variants[variantKey];
93
+ if (mappedVariantGroup) {
94
+ const cls = mappedVariantGroup[propValue];
95
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
96
+ }
97
+ }
98
+ }
99
+ for (const [propName, propValue] of Object.entries(componentInfo.getStylesLiterals)) {
100
+ const variantGroup = variants[propName.replace(/:\d+$/, "")];
101
+ if (variantGroup) {
102
+ const cls = variantGroup[propValue];
103
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
104
+ }
105
+ }
106
+ if (componentInfo.cxLiterals) for (const cls of componentInfo.cxLiterals) safelist.push(cls);
107
+ if (componentInfo.propToVariantKeys) {
108
+ const componentDefaults = options.variantDefaults?.[componentInfo.name] ?? {};
109
+ for (const [propName, variantKeys] of Object.entries(componentInfo.propToVariantKeys)) {
110
+ if (userProps.has(propName)) continue;
111
+ const defaultValue = componentDefaults[propName];
112
+ for (const variantKey of variantKeys) {
113
+ const variantGroup = autoVariantsCache[variantKey];
114
+ if (variantGroup) {
115
+ if (variantGroup["default"]) safelist.push(variantGroup["default"]);
116
+ if (defaultValue && variantGroup[defaultValue]) safelist.push(variantGroup[defaultValue]);
117
+ }
118
+ }
119
+ }
120
+ }
121
+ for (const [_internalCompName, propsRecord] of Object.entries(componentInfo.internalComponentProps)) for (const [propName, propValues] of Object.entries(propsRecord)) {
122
+ const variantGroup = variants[propName];
123
+ if (variantGroup) for (const propValue of propValues) {
124
+ const cls = variantGroup[propValue];
125
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
126
+ }
127
+ }
128
+ for (const [propName, usedValues] of userProps) {
129
+ const variantGroup = variants[propName];
130
+ if (variantGroup) for (const value of usedValues) {
131
+ const cls = variantGroup[value];
132
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
133
+ }
134
+ const componentsToCheck = [componentInfo, ...getComponentWithDeps(componentInfo.name).slice(1)];
135
+ for (const comp of componentsToCheck) {
136
+ const variantKeys = comp.propToVariantKeys?.[propName];
137
+ if (variantKeys) for (const variantKey of variantKeys) {
138
+ const mappedVariantGroup = variants[variantKey];
139
+ if (mappedVariantGroup) for (const value of usedValues) {
140
+ const cls = mappedVariantGroup[value];
141
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
147
+ const finalSafelist = [...new Set(safelist)];
148
+ stats.timeMs = Math.round(performance.now() - startTime);
149
+ stats.classesGenerated = finalSafelist.length;
150
+ return {
151
+ safelist: finalSafelist,
152
+ imports,
153
+ components: [...seenComponents],
154
+ stats
155
+ };
156
+ }
157
+ /**
158
+ * Find JSX references for a component in the source file
159
+ */
160
+ function findComponentReferences(sourceFile, componentName) {
161
+ const references = [];
162
+ for (const importDecl of sourceFile.getImportDeclarations()) {
163
+ if (!importDecl.getModuleSpecifier().getText().includes("@yahoo/uds")) continue;
164
+ for (const namedImport of importDecl.getNamedImports()) if (namedImport.getName() === componentName) {
165
+ const identifier = namedImport.getFirstDescendantByKindOrThrow(ts_morph.ts.SyntaxKind.Identifier);
166
+ references.push(...require_jsx.findJsxReferences(identifier));
167
+ }
168
+ }
169
+ return references;
170
+ }
171
+ /**
172
+ * Extract props from a JSX reference.
173
+ */
174
+ function extractPropsFromReference(reference, stats, sourceFile) {
175
+ const props = [];
176
+ const attributes = reference.getAttributes();
177
+ for (const attr of attributes) {
178
+ if (attr.asKind(ts_morph.SyntaxKind.JsxAttribute)) {
179
+ const jsxAttr = attr.asKindOrThrow(ts_morph.SyntaxKind.JsxAttribute);
180
+ const propName = jsxAttr.getNameNode().getText();
181
+ const values = [];
182
+ const initializer = jsxAttr.getInitializer();
183
+ if (initializer && ts_morph.Node.isStringLiteral(initializer)) {
184
+ values.push(initializer.getLiteralText());
185
+ stats.expressionsResolved++;
186
+ } else if (initializer && initializer.asKind(ts_morph.SyntaxKind.JsxExpression)) {
187
+ const expression = initializer.asKindOrThrow(ts_morph.SyntaxKind.JsxExpression).getExpression();
188
+ if (expression) {
189
+ const resolved = require_expressions.extractStringLiterals(expression);
190
+ values.push(...resolved);
191
+ if (resolved.length > 0) stats.expressionsResolved++;
192
+ }
193
+ }
194
+ props.push([propName, values]);
195
+ }
196
+ if (attr.asKind(ts_morph.SyntaxKind.JsxSpreadAttribute)) {
197
+ stats.spreadsTraced++;
198
+ const resolvedSpreadProps = traceSpreadInFile(attr.asKindOrThrow(ts_morph.SyntaxKind.JsxSpreadAttribute).getExpression().getText(), sourceFile);
199
+ for (const [propName, values] of resolvedSpreadProps) if (values.length > 0) props.push([propName, values]);
200
+ }
201
+ }
202
+ return props;
203
+ }
204
+ /**
205
+ * Trace spread props to their source within the same file.
206
+ */
207
+ function traceSpreadInFile(spreadName, sourceFile) {
208
+ const props = [];
209
+ const varDecl = sourceFile.getVariableDeclaration(spreadName);
210
+ if (!varDecl) return props;
211
+ const initializer = varDecl.getInitializer();
212
+ if (!initializer) return props;
213
+ const objLiteral = initializer.asKind(ts_morph.SyntaxKind.ObjectLiteralExpression) ? initializer.asKindOrThrow(ts_morph.SyntaxKind.ObjectLiteralExpression) : initializer.asKind(ts_morph.SyntaxKind.AsExpression) ? initializer.asKindOrThrow(ts_morph.SyntaxKind.AsExpression).getExpression().asKind(ts_morph.SyntaxKind.ObjectLiteralExpression) ? initializer.asKindOrThrow(ts_morph.SyntaxKind.AsExpression).getExpression().asKindOrThrow(ts_morph.SyntaxKind.ObjectLiteralExpression) : null : null;
214
+ if (!objLiteral) return props;
215
+ for (const prop of objLiteral.getProperties()) if (prop.asKind(ts_morph.SyntaxKind.PropertyAssignment)) {
216
+ const propAssign = prop.asKindOrThrow(ts_morph.SyntaxKind.PropertyAssignment);
217
+ const propName = propAssign.getName();
218
+ const propInit = propAssign.getInitializer();
219
+ if (propInit) {
220
+ const values = require_expressions.extractStringLiterals(propInit);
221
+ if (values.length > 0) props.push([propName, values]);
222
+ }
223
+ }
224
+ return props;
225
+ }
226
+ /**
227
+ * Extract props from getStyles() calls in user code.
228
+ * This handles cases like:
229
+ * const styles = getStyles({ backgroundColor: 'brand', spacing: '4' });
230
+ */
231
+ function extractGetStylesCalls(sourceFile, stats, variants) {
232
+ const props = /* @__PURE__ */ new Map();
233
+ const VALID_VARIANTS = new Set(Object.keys(variants));
234
+ const callExpressions = sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.CallExpression);
235
+ for (const call of callExpressions) {
236
+ if (call.getExpression().getText() !== "getStyles") continue;
237
+ const args = call.getArguments();
238
+ if (args.length === 0) continue;
239
+ const firstArg = args[0];
240
+ if (!firstArg.asKind(ts_morph.SyntaxKind.ObjectLiteralExpression)) continue;
241
+ const objLiteral = firstArg.asKindOrThrow(ts_morph.SyntaxKind.ObjectLiteralExpression);
242
+ for (const prop of objLiteral.getProperties()) if (prop.asKind(ts_morph.SyntaxKind.PropertyAssignment)) {
243
+ const propAssign = prop.asKindOrThrow(ts_morph.SyntaxKind.PropertyAssignment);
244
+ const propName = propAssign.getName();
245
+ const propInit = propAssign.getInitializer();
246
+ if (propInit && VALID_VARIANTS.has(propName)) {
247
+ const values = require_expressions.extractStringLiterals(propInit);
248
+ if (values.length > 0) {
249
+ const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
250
+ for (const v of values) existing.add(v);
251
+ props.set(propName, existing);
252
+ stats.expressionsResolved++;
253
+ }
254
+ }
255
+ } else if (prop.asKind(ts_morph.SyntaxKind.ShorthandPropertyAssignment)) {
256
+ const shorthand = prop.asKindOrThrow(ts_morph.SyntaxKind.ShorthandPropertyAssignment);
257
+ const propName = shorthand.getName();
258
+ if (VALID_VARIANTS.has(propName)) {
259
+ const values = require_expressions.extractStringLiterals(shorthand.getNameNode());
260
+ if (values.length > 0) {
261
+ const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
262
+ for (const v of values) existing.add(v);
263
+ props.set(propName, existing);
264
+ stats.expressionsResolved++;
265
+ }
266
+ }
267
+ }
268
+ }
269
+ return props;
270
+ }
271
+
272
+ //#endregion
273
+ exports.purgeFromCodeOptimized = purgeFromCodeOptimized;
@@ -0,0 +1,272 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { extractStringLiterals } from "./ast/expressions.js";
3
+ import { findJsxReferences } from "./ast/jsx.js";
4
+ import { Node, Project, SyntaxKind, ts } from "ts-morph";
5
+
6
+ //#region ../tailwind/dist/purger/optimized/purgeFromCode.js
7
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
8
+ /**
9
+ * Get component info with all its dependencies (using pre-generated data)
10
+ */
11
+ function getComponentWithDeps(componentName) {
12
+ const visited = /* @__PURE__ */ new Set();
13
+ const result = [];
14
+ function collect(name) {
15
+ if (visited.has(name)) return;
16
+ visited.add(name);
17
+ const info = componentCache[name];
18
+ if (!info) return;
19
+ result.push(info);
20
+ for (const depName of info.internalComponents) collect(depName);
21
+ }
22
+ collect(componentName);
23
+ return result;
24
+ }
25
+ /**
26
+ * Auto-variants lookup (loaded at module init)
27
+ */
28
+ let autoVariantsCache = null;
29
+ /**
30
+ * Pre-generated component data (loaded at module init)
31
+ */
32
+ let componentCache = null;
33
+ async function purgeFromCodeOptimized(code, options) {
34
+ const { variants, autoVariants, componentData } = options;
35
+ if (!autoVariantsCache) autoVariantsCache = autoVariants;
36
+ if (!componentCache) componentCache = componentData;
37
+ const startTime = performance.now();
38
+ const sourceFile = new Project({ useInMemoryFileSystem: true }).createSourceFile("input.tsx", code);
39
+ const stats = {
40
+ filesScanned: 1,
41
+ timeMs: 0,
42
+ classesGenerated: 0,
43
+ spreadsTraced: 0,
44
+ expressionsResolved: 0
45
+ };
46
+ const imports = [];
47
+ for (const importDecl of sourceFile.getImportDeclarations()) if (importDecl.getModuleSpecifier().getText().includes("@yahoo/uds")) for (const namedImport of importDecl.getNamedImports()) imports.push(namedImport.getName());
48
+ const componentProps = /* @__PURE__ */ new Map();
49
+ const getStylesProps = extractGetStylesCalls(sourceFile, stats, variants);
50
+ for (const imp of imports) {
51
+ const references = findComponentReferences(sourceFile, imp);
52
+ const propsMap = componentProps.get(imp) ?? /* @__PURE__ */ new Map();
53
+ for (const reference of references) {
54
+ const props = extractPropsFromReference(reference, stats, sourceFile);
55
+ for (const [propName, values] of props) if (values.length > 0) {
56
+ const existing = propsMap.get(propName) ?? /* @__PURE__ */ new Set();
57
+ for (const val of values) existing.add(val);
58
+ propsMap.set(propName, existing);
59
+ }
60
+ }
61
+ componentProps.set(imp, propsMap);
62
+ }
63
+ const allComponents = [];
64
+ const seenComponents = /* @__PURE__ */ new Set();
65
+ for (const componentName of imports) {
66
+ const componentsWithDeps = getComponentWithDeps(componentName);
67
+ for (const comp of componentsWithDeps) if (!seenComponents.has(comp.name)) {
68
+ seenComponents.add(comp.name);
69
+ allComponents.push(comp);
70
+ }
71
+ }
72
+ const safelist = [];
73
+ for (const [propName, values] of getStylesProps) {
74
+ const variantGroup = variants[propName];
75
+ if (variantGroup) for (const value of values) {
76
+ const cls = variantGroup[value];
77
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
78
+ }
79
+ }
80
+ for (const componentInfo of allComponents) {
81
+ const userProps = componentProps.get(componentInfo.name) ?? /* @__PURE__ */ new Map();
82
+ for (const [propName, propValue] of Object.entries(componentInfo.defaultProps)) {
83
+ if (userProps.has(propName)) continue;
84
+ const variantGroup = variants[propName];
85
+ if (variantGroup) {
86
+ const cls = variantGroup[propValue];
87
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
88
+ }
89
+ const variantKeys = componentInfo.propToVariantKeys?.[propName];
90
+ if (variantKeys) for (const variantKey of variantKeys) {
91
+ const mappedVariantGroup = variants[variantKey];
92
+ if (mappedVariantGroup) {
93
+ const cls = mappedVariantGroup[propValue];
94
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
95
+ }
96
+ }
97
+ }
98
+ for (const [propName, propValue] of Object.entries(componentInfo.getStylesLiterals)) {
99
+ const variantGroup = variants[propName.replace(/:\d+$/, "")];
100
+ if (variantGroup) {
101
+ const cls = variantGroup[propValue];
102
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
103
+ }
104
+ }
105
+ if (componentInfo.cxLiterals) for (const cls of componentInfo.cxLiterals) safelist.push(cls);
106
+ if (componentInfo.propToVariantKeys) {
107
+ const componentDefaults = options.variantDefaults?.[componentInfo.name] ?? {};
108
+ for (const [propName, variantKeys] of Object.entries(componentInfo.propToVariantKeys)) {
109
+ if (userProps.has(propName)) continue;
110
+ const defaultValue = componentDefaults[propName];
111
+ for (const variantKey of variantKeys) {
112
+ const variantGroup = autoVariantsCache[variantKey];
113
+ if (variantGroup) {
114
+ if (variantGroup["default"]) safelist.push(variantGroup["default"]);
115
+ if (defaultValue && variantGroup[defaultValue]) safelist.push(variantGroup[defaultValue]);
116
+ }
117
+ }
118
+ }
119
+ }
120
+ for (const [_internalCompName, propsRecord] of Object.entries(componentInfo.internalComponentProps)) for (const [propName, propValues] of Object.entries(propsRecord)) {
121
+ const variantGroup = variants[propName];
122
+ if (variantGroup) for (const propValue of propValues) {
123
+ const cls = variantGroup[propValue];
124
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
125
+ }
126
+ }
127
+ for (const [propName, usedValues] of userProps) {
128
+ const variantGroup = variants[propName];
129
+ if (variantGroup) for (const value of usedValues) {
130
+ const cls = variantGroup[value];
131
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
132
+ }
133
+ const componentsToCheck = [componentInfo, ...getComponentWithDeps(componentInfo.name).slice(1)];
134
+ for (const comp of componentsToCheck) {
135
+ const variantKeys = comp.propToVariantKeys?.[propName];
136
+ if (variantKeys) for (const variantKey of variantKeys) {
137
+ const mappedVariantGroup = variants[variantKey];
138
+ if (mappedVariantGroup) for (const value of usedValues) {
139
+ const cls = mappedVariantGroup[value];
140
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ const finalSafelist = [...new Set(safelist)];
147
+ stats.timeMs = Math.round(performance.now() - startTime);
148
+ stats.classesGenerated = finalSafelist.length;
149
+ return {
150
+ safelist: finalSafelist,
151
+ imports,
152
+ components: [...seenComponents],
153
+ stats
154
+ };
155
+ }
156
+ /**
157
+ * Find JSX references for a component in the source file
158
+ */
159
+ function findComponentReferences(sourceFile, componentName) {
160
+ const references = [];
161
+ for (const importDecl of sourceFile.getImportDeclarations()) {
162
+ if (!importDecl.getModuleSpecifier().getText().includes("@yahoo/uds")) continue;
163
+ for (const namedImport of importDecl.getNamedImports()) if (namedImport.getName() === componentName) {
164
+ const identifier = namedImport.getFirstDescendantByKindOrThrow(ts.SyntaxKind.Identifier);
165
+ references.push(...findJsxReferences(identifier));
166
+ }
167
+ }
168
+ return references;
169
+ }
170
+ /**
171
+ * Extract props from a JSX reference.
172
+ */
173
+ function extractPropsFromReference(reference, stats, sourceFile) {
174
+ const props = [];
175
+ const attributes = reference.getAttributes();
176
+ for (const attr of attributes) {
177
+ if (attr.asKind(SyntaxKind.JsxAttribute)) {
178
+ const jsxAttr = attr.asKindOrThrow(SyntaxKind.JsxAttribute);
179
+ const propName = jsxAttr.getNameNode().getText();
180
+ const values = [];
181
+ const initializer = jsxAttr.getInitializer();
182
+ if (initializer && Node.isStringLiteral(initializer)) {
183
+ values.push(initializer.getLiteralText());
184
+ stats.expressionsResolved++;
185
+ } else if (initializer && initializer.asKind(SyntaxKind.JsxExpression)) {
186
+ const expression = initializer.asKindOrThrow(SyntaxKind.JsxExpression).getExpression();
187
+ if (expression) {
188
+ const resolved = extractStringLiterals(expression);
189
+ values.push(...resolved);
190
+ if (resolved.length > 0) stats.expressionsResolved++;
191
+ }
192
+ }
193
+ props.push([propName, values]);
194
+ }
195
+ if (attr.asKind(SyntaxKind.JsxSpreadAttribute)) {
196
+ stats.spreadsTraced++;
197
+ const resolvedSpreadProps = traceSpreadInFile(attr.asKindOrThrow(SyntaxKind.JsxSpreadAttribute).getExpression().getText(), sourceFile);
198
+ for (const [propName, values] of resolvedSpreadProps) if (values.length > 0) props.push([propName, values]);
199
+ }
200
+ }
201
+ return props;
202
+ }
203
+ /**
204
+ * Trace spread props to their source within the same file.
205
+ */
206
+ function traceSpreadInFile(spreadName, sourceFile) {
207
+ const props = [];
208
+ const varDecl = sourceFile.getVariableDeclaration(spreadName);
209
+ if (!varDecl) return props;
210
+ const initializer = varDecl.getInitializer();
211
+ if (!initializer) return props;
212
+ const objLiteral = initializer.asKind(SyntaxKind.ObjectLiteralExpression) ? initializer.asKindOrThrow(SyntaxKind.ObjectLiteralExpression) : initializer.asKind(SyntaxKind.AsExpression) ? initializer.asKindOrThrow(SyntaxKind.AsExpression).getExpression().asKind(SyntaxKind.ObjectLiteralExpression) ? initializer.asKindOrThrow(SyntaxKind.AsExpression).getExpression().asKindOrThrow(SyntaxKind.ObjectLiteralExpression) : null : null;
213
+ if (!objLiteral) return props;
214
+ for (const prop of objLiteral.getProperties()) if (prop.asKind(SyntaxKind.PropertyAssignment)) {
215
+ const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);
216
+ const propName = propAssign.getName();
217
+ const propInit = propAssign.getInitializer();
218
+ if (propInit) {
219
+ const values = extractStringLiterals(propInit);
220
+ if (values.length > 0) props.push([propName, values]);
221
+ }
222
+ }
223
+ return props;
224
+ }
225
+ /**
226
+ * Extract props from getStyles() calls in user code.
227
+ * This handles cases like:
228
+ * const styles = getStyles({ backgroundColor: 'brand', spacing: '4' });
229
+ */
230
+ function extractGetStylesCalls(sourceFile, stats, variants) {
231
+ const props = /* @__PURE__ */ new Map();
232
+ const VALID_VARIANTS = new Set(Object.keys(variants));
233
+ const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);
234
+ for (const call of callExpressions) {
235
+ if (call.getExpression().getText() !== "getStyles") continue;
236
+ const args = call.getArguments();
237
+ if (args.length === 0) continue;
238
+ const firstArg = args[0];
239
+ if (!firstArg.asKind(SyntaxKind.ObjectLiteralExpression)) continue;
240
+ const objLiteral = firstArg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
241
+ for (const prop of objLiteral.getProperties()) if (prop.asKind(SyntaxKind.PropertyAssignment)) {
242
+ const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);
243
+ const propName = propAssign.getName();
244
+ const propInit = propAssign.getInitializer();
245
+ if (propInit && VALID_VARIANTS.has(propName)) {
246
+ const values = extractStringLiterals(propInit);
247
+ if (values.length > 0) {
248
+ const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
249
+ for (const v of values) existing.add(v);
250
+ props.set(propName, existing);
251
+ stats.expressionsResolved++;
252
+ }
253
+ }
254
+ } else if (prop.asKind(SyntaxKind.ShorthandPropertyAssignment)) {
255
+ const shorthand = prop.asKindOrThrow(SyntaxKind.ShorthandPropertyAssignment);
256
+ const propName = shorthand.getName();
257
+ if (VALID_VARIANTS.has(propName)) {
258
+ const values = extractStringLiterals(shorthand.getNameNode());
259
+ if (values.length > 0) {
260
+ const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
261
+ for (const v of values) existing.add(v);
262
+ props.set(propName, existing);
263
+ stats.expressionsResolved++;
264
+ }
265
+ }
266
+ }
267
+ }
268
+ return props;
269
+ }
270
+
271
+ //#endregion
272
+ export { purgeFromCodeOptimized };