@yahoo/uds 3.120.0 → 3.122.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 (69) hide show
  1. package/dist/components/client/Popover/Popover.cjs +1 -1
  2. package/dist/components/client/Popover/Popover.js +1 -1
  3. package/dist/components/client/Popover/PopoverContent.cjs +12 -17
  4. package/dist/components/client/Popover/PopoverContent.js +12 -17
  5. package/dist/components/client/Popover/UDSPopoverConfigProvider.cjs +13 -3
  6. package/dist/components/client/Popover/UDSPopoverConfigProvider.d.cts +13 -5
  7. package/dist/components/client/Popover/UDSPopoverConfigProvider.d.ts +13 -5
  8. package/dist/components/client/Popover/UDSPopoverConfigProvider.js +13 -3
  9. package/dist/components/client/Toast/UDSToastConfigProvider.d.cts +1 -1
  10. package/dist/components/client/Toast/UDSToastConfigProvider.d.ts +1 -1
  11. package/dist/fixtures/dist/index.cjs +1 -2
  12. package/dist/fixtures/dist/index.js +1 -2
  13. package/dist/index.d.cts +2 -2
  14. package/dist/index.d.ts +2 -2
  15. package/dist/runtime/popoverConfig.cjs +2 -0
  16. package/dist/runtime/popoverConfig.d.cts +3 -1
  17. package/dist/runtime/popoverConfig.d.ts +3 -1
  18. package/dist/runtime/popoverConfig.js +2 -0
  19. package/dist/styles/styler.d.cts +43 -43
  20. package/dist/styles/styler.d.ts +43 -43
  21. package/dist/tailwind/dist/commands/generateComponentData.cjs +5 -1
  22. package/dist/tailwind/dist/commands/generateComponentData.d.cts +3 -0
  23. package/dist/tailwind/dist/commands/generateComponentData.d.cts.map +1 -1
  24. package/dist/tailwind/dist/commands/generateComponentData.d.ts +3 -0
  25. package/dist/tailwind/dist/commands/generateComponentData.d.ts.map +1 -1
  26. package/dist/tailwind/dist/commands/generateComponentData.js +5 -1
  27. package/dist/tailwind/dist/commands/generateComponentData.js.map +1 -1
  28. package/dist/tailwind/dist/css/generate.cjs +2 -1
  29. package/dist/tailwind/dist/css/generate.d.cts.map +1 -1
  30. package/dist/tailwind/dist/css/generate.d.ts.map +1 -1
  31. package/dist/tailwind/dist/css/generate.js +3 -2
  32. package/dist/tailwind/dist/css/generate.js.map +1 -1
  33. package/dist/tailwind/dist/css/nodeUtils.cjs +7 -5
  34. package/dist/tailwind/dist/css/nodeUtils.js +7 -5
  35. package/dist/tailwind/dist/css/nodeUtils.js.map +1 -1
  36. package/dist/tailwind/dist/css/runner.cjs +4 -3
  37. package/dist/tailwind/dist/css/runner.js +5 -4
  38. package/dist/tailwind/dist/css/runner.js.map +1 -1
  39. package/dist/tailwind/dist/css/utils.cjs +62 -0
  40. package/dist/tailwind/dist/css/utils.js +62 -1
  41. package/dist/tailwind/dist/css/utils.js.map +1 -1
  42. package/dist/tailwind/dist/fixtures/dist/index.js.map +1 -1
  43. package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +104 -19
  44. package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.cts +5 -0
  45. package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.cts.map +1 -1
  46. package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.ts +5 -0
  47. package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.ts.map +1 -1
  48. package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +104 -19
  49. package/dist/tailwind/dist/purger/optimized/purgeFromCode.js.map +1 -1
  50. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +99 -10
  51. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +99 -10
  52. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js.map +1 -1
  53. package/dist/tailwind/dist/runtimeConfig/hookMetadata.cjs +364 -0
  54. package/dist/tailwind/dist/runtimeConfig/hookMetadata.js +358 -0
  55. package/dist/tailwind/dist/runtimeConfig/hookMetadata.js.map +1 -0
  56. package/dist/tailwind/dist/types/dist/index.d.cts.map +1 -1
  57. package/dist/tailwind/dist/types/dist/index.d.ts.map +1 -1
  58. package/dist/tokens/index.d.cts +2 -2
  59. package/dist/tokens/index.d.ts +2 -2
  60. package/dist/tokens/types.d.cts +2 -2
  61. package/dist/tokens/types.d.ts +2 -2
  62. package/dist/types/dist/index.d.cts +2 -1
  63. package/dist/types/dist/index.d.ts +2 -1
  64. package/dist/uds/generated/componentData.cjs +915 -628
  65. package/dist/uds/generated/componentData.js +915 -628
  66. package/dist/uds/package.cjs +3 -3
  67. package/dist/uds/package.js +3 -3
  68. package/generated/componentData.json +1131 -782
  69. package/package.json +4 -4
@@ -90,6 +90,38 @@ const getVariantKeysForProp = (componentInfo, propName) => {
90
90
  getAutoVariantKeysForProp(componentInfo.name, propName).forEach((inferred) => keys.add(inferred));
91
91
  return [...keys];
92
92
  };
93
+ const addVariantGroupClasses = (variantGroup, safelist) => {
94
+ if (!variantGroup) return;
95
+ Object.values(variantGroup).forEach((cls) => {
96
+ safelist.push(cls.replaceAll("\\", ""));
97
+ });
98
+ };
99
+ const getRuntimeDefaultPropValues = (componentInfo, propName, runtimeConfigValues) => {
100
+ const selector = componentInfo.runtimeConfigDefaultProps?.[propName];
101
+ if (!selector || !runtimeConfigValues) return [];
102
+ const value = runtimeConfigValues[selector];
103
+ return value === void 0 ? [] : [String(value)];
104
+ };
105
+ const getPropCandidateValues = (componentInfo, propName, userProps, options) => {
106
+ const explicitValues = userProps.get(propName);
107
+ if (explicitValues && explicitValues.size > 0) return [...explicitValues];
108
+ const configuredDefault = options.variantDefaults?.[componentInfo.name]?.[propName];
109
+ if (configuredDefault) return [configuredDefault];
110
+ if (componentInfo.defaultProps[propName]) return [componentInfo.defaultProps[propName]];
111
+ return getRuntimeDefaultPropValues(componentInfo, propName, options.runtimeConfigValues);
112
+ };
113
+ const resolveRuntimeSelectorValues = (selectorTemplate, componentInfo, userProps, options) => {
114
+ const runtimeConfigValues = options.runtimeConfigValues;
115
+ if (!runtimeConfigValues) return [];
116
+ return [...selectorTemplate.matchAll(/\$\{(\w+)\}/g)].map((match) => match[1]).reduce((acc, propName) => {
117
+ const propValues = getPropCandidateValues(componentInfo, propName, userProps, options);
118
+ if (propValues.length === 0) return [];
119
+ return acc.flatMap((selector) => propValues.map((value) => selector.replaceAll("${" + propName + "}", value)));
120
+ }, [selectorTemplate]).flatMap((selector) => {
121
+ const value = runtimeConfigValues[selector];
122
+ return value === void 0 ? [] : [String(value)];
123
+ });
124
+ };
93
125
  const extractClassNamePrimitives = (sourceFile) => {
94
126
  const classes = [];
95
127
  sourceFile.getDescendantsOfKind(SyntaxKind.JsxAttribute).forEach((attr) => {
@@ -139,6 +171,7 @@ const purgeFromCodeOptimized = async (code, options) => {
139
171
  });
140
172
  });
141
173
  const componentProps = /* @__PURE__ */ new Map();
174
+ const componentUnresolvedSpreadProps = /* @__PURE__ */ new Map();
142
175
  const referencedComponents = /* @__PURE__ */ new Set();
143
176
  const getStylesProps = extractGetStylesCalls(sourceFile, stats, variants);
144
177
  imports.forEach((imp) => {
@@ -146,16 +179,21 @@ const purgeFromCodeOptimized = async (code, options) => {
146
179
  const componentName = reference.getTagNameNode().getText() || imp;
147
180
  referencedComponents.add(componentName);
148
181
  const propsMap = componentProps.get(componentName) ?? /* @__PURE__ */ new Map();
149
- extractPropsFromReference(reference, stats, sourceFile).forEach(([propName, values]) => {
182
+ const unresolvedSpreadProps = componentUnresolvedSpreadProps.get(componentName) ?? /* @__PURE__ */ new Set();
183
+ extractPropsFromReference(reference, stats, sourceFile).forEach(({ propName, values, fromSpread }) => {
150
184
  if (values.length > 0) {
151
185
  const existing = propsMap.get(propName) ?? /* @__PURE__ */ new Set();
152
186
  values.forEach((val) => existing.add(val));
153
187
  propsMap.set(propName, existing);
188
+ return;
154
189
  }
190
+ if (fromSpread) unresolvedSpreadProps.add(propName);
155
191
  });
156
192
  componentProps.set(componentName, propsMap);
193
+ componentUnresolvedSpreadProps.set(componentName, unresolvedSpreadProps);
157
194
  });
158
195
  if (!componentProps.has(imp)) componentProps.set(imp, /* @__PURE__ */ new Map());
196
+ if (!componentUnresolvedSpreadProps.has(imp)) componentUnresolvedSpreadProps.set(imp, /* @__PURE__ */ new Set());
159
197
  });
160
198
  const allComponents = [];
161
199
  const seenComponents = /* @__PURE__ */ new Set();
@@ -177,6 +215,7 @@ const purgeFromCodeOptimized = async (code, options) => {
177
215
  });
178
216
  allComponents.forEach((componentInfo) => {
179
217
  const userProps = componentProps.get(componentInfo.name) ?? /* @__PURE__ */ new Map();
218
+ const unresolvedSpreadProps = componentUnresolvedSpreadProps.get(componentInfo.name) ?? /* @__PURE__ */ new Set();
180
219
  Object.entries(componentInfo.defaultProps).forEach(([propName, propValue]) => {
181
220
  if (userProps.has(propName)) return;
182
221
  const variantGroup = variants[propName];
@@ -200,17 +239,29 @@ const purgeFromCodeOptimized = async (code, options) => {
200
239
  if (cls) safelist.push(cls.replaceAll("\\", ""));
201
240
  }
202
241
  });
242
+ Object.entries(componentInfo.runtimeConfigGetStyles ?? {}).forEach(([propName, selectors]) => {
243
+ const variantGroup = variants[propName] ?? autoVariantsCache[propName];
244
+ if (!variantGroup) return;
245
+ selectors.forEach((selector) => {
246
+ resolveRuntimeSelectorValues(selector, componentInfo, userProps, options).forEach((value) => {
247
+ const cls = variantGroup[value];
248
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
249
+ });
250
+ });
251
+ });
203
252
  if (componentInfo.cxLiterals) componentInfo.cxLiterals.forEach((cls) => safelist.push(cls));
204
253
  if (componentInfo.propToVariantKeys) {
205
254
  const componentDefaults = options.variantDefaults?.[componentInfo.name] ?? {};
206
255
  Object.keys(componentInfo.propToVariantKeys).forEach((propName) => {
207
256
  if (userProps.has(propName)) return;
208
- const defaultValue = componentDefaults[propName];
257
+ const defaultValues = componentDefaults[propName] ? [componentDefaults[propName]] : getRuntimeDefaultPropValues(componentInfo, propName, options.runtimeConfigValues);
209
258
  getVariantKeysForProp(componentInfo, propName).forEach((variantKey) => {
210
259
  const variantGroup = autoVariantsCache[variantKey];
211
260
  if (variantGroup) {
212
261
  if (variantGroup["default"]) safelist.push(variantGroup["default"]);
213
- if (defaultValue && variantGroup[defaultValue]) safelist.push(variantGroup[defaultValue]);
262
+ defaultValues.forEach((defaultValue) => {
263
+ if (variantGroup[defaultValue]) safelist.push(variantGroup[defaultValue]);
264
+ });
214
265
  }
215
266
  });
216
267
  });
@@ -230,6 +281,18 @@ const purgeFromCodeOptimized = async (code, options) => {
230
281
  });
231
282
  });
232
283
  });
284
+ Object.entries(componentInfo.runtimeConfigInternalComponentProps ?? {}).forEach(([_internalCompName, propsRecord]) => {
285
+ Object.entries(propsRecord).forEach(([propName, selectors]) => {
286
+ const variantGroup = variants[propName];
287
+ if (!variantGroup) return;
288
+ selectors.forEach((selector) => {
289
+ resolveRuntimeSelectorValues(selector, componentInfo, userProps, options).forEach((value) => {
290
+ const cls = variantGroup[value];
291
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
292
+ });
293
+ });
294
+ });
295
+ });
233
296
  [...userProps.entries()].forEach(([propName, usedValues]) => {
234
297
  if (propName === "className") {
235
298
  [...usedValues].forEach((value) => {
@@ -253,6 +316,14 @@ const purgeFromCodeOptimized = async (code, options) => {
253
316
  });
254
317
  });
255
318
  });
319
+ unresolvedSpreadProps.forEach((propName) => {
320
+ addVariantGroupClasses(variants[propName] ?? autoVariantsCache[propName], safelist);
321
+ [componentInfo, ...getComponentWithDeps(componentInfo.name).slice(1)].forEach((comp) => {
322
+ getVariantKeysForProp(comp, propName).forEach((variantKey) => {
323
+ addVariantGroupClasses(variants[variantKey] ?? autoVariantsCache[variantKey], safelist);
324
+ });
325
+ });
326
+ });
256
327
  });
257
328
  if (options.includeAllClassNamePrimitives) safelist.push(...extractClassNamePrimitives(sourceFile));
258
329
  const finalSafelist = [...new Set(safelist)];
@@ -322,12 +393,20 @@ const extractPropsFromReference = (reference, stats, sourceFile) => {
322
393
  if (resolved.length > 0) stats.expressionsResolved++;
323
394
  }
324
395
  }
325
- props.push([propName, values]);
396
+ props.push({
397
+ propName,
398
+ values,
399
+ fromSpread: false
400
+ });
326
401
  }
327
402
  if (attr.asKind(SyntaxKind.JsxSpreadAttribute)) {
328
403
  stats.spreadsTraced++;
329
404
  traceSpreadInFile(attr.asKindOrThrow(SyntaxKind.JsxSpreadAttribute).getExpression().getText(), sourceFile).forEach(([propName, values]) => {
330
- if (values.length > 0) props.push([propName, values]);
405
+ props.push({
406
+ propName,
407
+ values,
408
+ fromSpread: true
409
+ });
331
410
  });
332
411
  }
333
412
  });
@@ -337,25 +416,31 @@ const extractPropsFromReference = (reference, stats, sourceFile) => {
337
416
  * Trace spread props to their source within the same file.
338
417
  */
339
418
  const traceSpreadInFile = (spreadName, sourceFile) => {
340
- const props = [];
341
- const varDecl = sourceFile.getVariableDeclaration(spreadName);
342
- if (!varDecl) return props;
419
+ const props = /* @__PURE__ */ new Map();
420
+ const varDecl = sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration).find((declaration) => declaration.getName() === spreadName);
421
+ if (!varDecl) return [];
343
422
  const initializer = varDecl.getInitializer();
344
- if (!initializer) return props;
345
- 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;
346
- if (!objLiteral) return props;
347
- objLiteral.getProperties().forEach((prop) => {
348
- if (prop.asKind(SyntaxKind.PropertyAssignment)) {
423
+ if (!initializer) return [];
424
+ getSpreadObjectLiteralCandidates(initializer).forEach((objLiteral) => {
425
+ objLiteral.getProperties().forEach((prop) => {
426
+ if (!prop.asKind(SyntaxKind.PropertyAssignment)) return;
349
427
  const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);
350
428
  const propName = propAssign.getName();
351
429
  const propInit = propAssign.getInitializer();
352
- if (propInit) {
353
- const values = extractStringLiterals(propInit);
354
- if (values.length > 0) props.push([propName, values]);
355
- }
356
- }
430
+ const values = propInit ? extractStringLiterals(propInit) : [];
431
+ const existingValues = props.get(propName) ?? /* @__PURE__ */ new Set();
432
+ values.forEach((value) => existingValues.add(value));
433
+ props.set(propName, existingValues);
434
+ });
357
435
  });
358
- return props;
436
+ return [...props.entries()].map(([propName, values]) => [propName, [...values]]);
437
+ };
438
+ const getSpreadObjectLiteralCandidates = (node) => {
439
+ if (Node.isObjectLiteralExpression(node)) return [node];
440
+ if (Node.isParenthesizedExpression(node)) return getSpreadObjectLiteralCandidates(node.getExpression());
441
+ if (Node.isAsExpression(node) || Node.isTypeAssertion(node) || Node.isSatisfiesExpression(node)) return getSpreadObjectLiteralCandidates(node.getExpression());
442
+ if (Node.isConditionalExpression(node)) return [...getSpreadObjectLiteralCandidates(node.getWhenTrue()), ...getSpreadObjectLiteralCandidates(node.getWhenFalse())];
443
+ return [];
359
444
  };
360
445
  /**
361
446
  * Extract props from getStyles() calls in user code.
@@ -1 +1 @@
1
- {"version":3,"file":"purgeFromCode.js","names":[],"sources":["../../../src/purger/optimized/purgeFromCode.ts"],"sourcesContent":["import type { ImportDeclaration } from 'ts-morph';\nimport { Node, Project, SyntaxKind, ts } from 'ts-morph';\n\nimport { extractStringLiterals, findJsxReferences } from './ast';\nimport type { JsxElementWithAttributes, PurgeStats } from './types';\n\ninterface PurgeFromCodeResult {\n safelist: string[];\n imports: string[];\n components: string[];\n stats: PurgeStats;\n}\n\n/**\n * Serialized component info from pre-generated data\n */\ninterface SerializedComponentInfo {\n name: string;\n defaultProps: Record<string, string>;\n getStylesLiterals: Record<string, string>;\n cxLiterals?: string[];\n internalComponents: string[];\n internalComponentProps: Record<string, Record<string, string[]>>;\n propToVariantKeys: Record<string, string[]>;\n}\n\n/**\n * Get component info with all its dependencies (using pre-generated data)\n */\nconst getComponentWithDeps = (componentName: string): SerializedComponentInfo[] => {\n const visited = new Set<string>();\n const result: SerializedComponentInfo[] = [];\n\n const collect = (name: string): void => {\n if (visited.has(name)) {\n return;\n }\n visited.add(name);\n\n const info = resolveComponentInfo(name);\n if (!info) {\n return;\n }\n\n result.push(info);\n\n // Recursively collect internal component dependencies\n info.internalComponents.forEach((depName) => collect(depName));\n };\n\n collect(componentName);\n return result;\n};\n\n/**\n * Optimized purge from code string.\n *\n * This is a standalone implementation that:\n * - Analyzes UDS component source files to get accurate default props\n * - Includes defaults from internally used components\n * - Only depends on variants from src/styles/variants.ts (source of truth)\n * - Uses ts-morph for AST analysis\n *\n * Key behaviors:\n * - Includes classes for component default props (analyzed from source)\n * - Includes defaults for internal component dependencies\n * - Includes classes for explicitly used prop values\n * - Resolves ternary/logical expressions to extract all possible values\n * - Traces spreads to const objects in the same file\n * - Does NOT fall back to type properties for unresolved spreads\n */\n/**\n * Variant defaults per component from consumer's config\n * e.g., { Button: { size: 'md', variant: 'primary' }, Avatar: { size: 'md' } }\n */\ntype VariantDefaults = Record<string, Record<string, string>>;\n\ninterface PurgeFromCodeOptions {\n colorModes?: ('dark' | 'light')[];\n /** Variant defaults from consumer's config - used to include default CSS when prop not specified */\n variantDefaults?: VariantDefaults;\n variants: Record<string, Record<string, string>>;\n autoVariants: Record<string, Record<string, string>>;\n componentData: Record<string, SerializedComponentInfo>;\n includeAllClassNamePrimitives?: boolean;\n filePath?: string;\n}\n\n/**\n * Auto-variants lookup (loaded at module init)\n */\nlet autoVariantsCache = null as unknown as Record<string, Record<string, string>>;\n\n/**\n * Pre-generated component data (loaded at module init)\n */\nlet componentCache = null as unknown as Record<string, SerializedComponentInfo>;\n\n/**\n * Map of normalized component name -> actual component cache key\n * Useful when internal components are imported without namespace separators\n * (e.g., MenuItemBase vs Menu.ItemBase).\n */\nlet componentNameLookup: Record<string, string> | null = null;\n\nconst buildComponentNameLookup = (\n data: Record<string, SerializedComponentInfo>,\n): Record<string, string> => {\n const lookup: Record<string, string> = {};\n\n Object.keys(data).forEach((key) => {\n const normalized = normalizeComponentName(key);\n // Keep the first match to avoid arbitrary overwrites on collisions\n if (!lookup[normalized]) {\n lookup[normalized] = key;\n }\n });\n\n return lookup;\n};\n\nconst resolveComponentInfo = (name: string): SerializedComponentInfo | undefined => {\n if (componentCache && componentCache[name]) {\n return componentCache[name];\n }\n\n const normalized = normalizeComponentName(name);\n const mappedName = componentNameLookup?.[normalized];\n if (mappedName && componentCache) {\n return componentCache[mappedName];\n }\n\n return undefined;\n};\n\nconst getModuleSpecifierValue = (importDecl: ImportDeclaration): string => {\n return (\n importDecl.getModuleSpecifierValue() ??\n importDecl\n .getModuleSpecifier()\n .getText()\n .replace(/^['\"]|['\"]$/g, '')\n );\n};\n\nconst isTypeOnlyNamedImport = (importDecl: ImportDeclaration, importName: string): boolean => {\n if (importDecl.isTypeOnly()) {\n return true;\n }\n\n return (\n importDecl\n .getNamedImports()\n .find((namedImport) => namedImport.getName() === importName)\n ?.isTypeOnly() ?? false\n );\n};\n\nconst isUdsComponentModule = (moduleSpecifier: string): boolean => {\n const cleaned = moduleSpecifier.replace(/^['\"]|['\"]$/g, '');\n return cleaned === '@yahoo/uds' || cleaned.startsWith('@yahoo/uds/');\n};\n\n/**\n * Normalize component name to match autoVariants keys (lower camel, no punctuation).\n */\nconst normalizeComponentName = (name: string): string => {\n const cleaned = name.replace(/\\W/g, '');\n return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);\n};\n\n/**\n * Fallback: infer prop -> variant key mapping from autoVariants when the\n * generated component data misses it (e.g., helpers like buildAvatarRootClasses).\n */\nconst getAutoVariantKeysForProp = (componentName: string, propName: string): string[] => {\n if (!autoVariantsCache) {\n return [];\n }\n\n const segments = componentName.match(/[A-Z][a-z0-9]*/g) ?? [];\n const candidates = new Set<string>([normalizeComponentName(componentName)]);\n\n // Add progressively shorter prefixes (e.g., AvatarImage -> avatar, avatarimage)\n if (segments.length > 0) {\n Array.from({ length: segments.length }, (_, index) => index + 1).forEach((i) => {\n const partial = segments.slice(0, i).join('');\n candidates.add(normalizeComponentName(partial));\n });\n }\n\n const propLower = propName.toLowerCase();\n\n return Object.keys(autoVariantsCache).filter((key) => {\n const keyLower = key.toLowerCase();\n return Array.from(candidates).some(\n (candidate) => keyLower.startsWith(candidate) && keyLower.includes(propLower),\n );\n });\n};\n\nconst getVariantKeysForProp = (\n componentInfo: SerializedComponentInfo,\n propName: string,\n): string[] => {\n const keys = new Set(componentInfo.propToVariantKeys?.[propName] ?? []);\n\n getAutoVariantKeysForProp(componentInfo.name, propName).forEach((inferred) => keys.add(inferred));\n\n return [...keys];\n};\n\nconst extractClassNamePrimitives = (\n sourceFile: ReturnType<Project['createSourceFile']>,\n): string[] => {\n const classes: string[] = [];\n\n // JSX className attributes\n sourceFile.getDescendantsOfKind(SyntaxKind.JsxAttribute).forEach((attr) => {\n if (attr.getNameNode().getText() !== 'className') {\n return;\n }\n\n const initializer = attr.getInitializer();\n if (!initializer) {\n return;\n }\n\n const values: string[] = [];\n\n if (Node.isStringLiteral(initializer)) {\n values.push(initializer.getLiteralText());\n } else if (Node.isJsxExpression(initializer)) {\n const expr = initializer.getExpression();\n if (expr) {\n values.push(...extractStringLiterals(expr));\n }\n }\n\n values.forEach((raw) => {\n classes.push(...raw.split(/\\s+/).filter(Boolean));\n });\n });\n\n // Plain object property assignments like const props = { className: '...' }\n sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAssignment).forEach((prop) => {\n if (prop.getName() !== 'className') {\n return;\n }\n\n const initializer = prop.getInitializer();\n if (!initializer) {\n return;\n }\n\n const rawValues = extractStringLiterals(initializer);\n rawValues.forEach((raw) => {\n classes.push(...raw.split(/\\s+/).filter(Boolean));\n });\n });\n\n return classes;\n};\n\nconst purgeFromCodeOptimized = async (\n code: string,\n options: PurgeFromCodeOptions,\n): Promise<PurgeFromCodeResult> => {\n const { variants, autoVariants, componentData } = options;\n\n if (!autoVariantsCache) {\n autoVariantsCache = autoVariants;\n }\n\n if (!componentCache) {\n componentCache = componentData;\n componentNameLookup = buildComponentNameLookup(componentData);\n }\n\n const startTime = performance.now();\n\n const project = new Project({ useInMemoryFileSystem: true });\n const sourceFile = project.createSourceFile(options.filePath ?? 'input.tsx', code, {\n overwrite: true,\n });\n\n const stats: PurgeStats = {\n filesScanned: 1,\n timeMs: 0,\n classesGenerated: 0,\n spreadsTraced: 0,\n expressionsResolved: 0,\n };\n\n // Parse UDS imports\n const imports: string[] = [];\n sourceFile.getImportDeclarations().forEach((importDecl) => {\n const moduleSpec = getModuleSpecifierValue(importDecl);\n if (isUdsComponentModule(moduleSpec)) {\n importDecl.getNamedImports().forEach((namedImport) => {\n if (!namedImport.isTypeOnly() && !importDecl.isTypeOnly()) {\n imports.push(namedImport.getName());\n }\n });\n }\n });\n\n // Track all resolved prop values per component\n const componentProps = new Map<string, Map<string, Set<string>>>();\n const referencedComponents = new Set<string>();\n\n // Extract props from getStyles() calls in user code\n const getStylesProps = extractGetStylesCalls(sourceFile, stats, variants);\n\n // Find all JSX elements that use UDS components\n imports.forEach((imp) => {\n const references = findComponentReferences(sourceFile, imp);\n\n references.forEach((reference) => {\n const tagName = reference.getTagNameNode().getText();\n const componentName = tagName || imp;\n\n referencedComponents.add(componentName);\n\n const propsMap = componentProps.get(componentName) ?? new Map<string, Set<string>>();\n const props = extractPropsFromReference(reference, stats, sourceFile);\n\n props.forEach(([propName, values]) => {\n if (values.length > 0) {\n const existing = propsMap.get(propName) ?? new Set();\n values.forEach((val) => existing.add(val));\n propsMap.set(propName, existing);\n }\n });\n\n componentProps.set(componentName, propsMap);\n });\n\n if (!componentProps.has(imp)) {\n componentProps.set(imp, new Map());\n }\n });\n\n // Collect all components (including dependencies)\n const allComponents: SerializedComponentInfo[] = [];\n const seenComponents = new Set<string>();\n\n const componentsToProcess = new Set<string>([...imports, ...referencedComponents]);\n\n componentsToProcess.forEach((componentName) => {\n const componentsWithDeps = getComponentWithDeps(componentName);\n componentsWithDeps.forEach((comp) => {\n if (!seenComponents.has(comp.name)) {\n seenComponents.add(comp.name);\n allComponents.push(comp);\n }\n });\n });\n\n // Generate safelist\n const safelist: string[] = [];\n\n // Add classes from getStyles() calls in user code\n [...getStylesProps.entries()].forEach(([propName, values]) => {\n const variantGroup = variants[propName as keyof typeof variants];\n if (variantGroup) {\n values.forEach((value) => {\n const cls = (variantGroup as Record<string, string>)[value];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n });\n }\n });\n\n // Add defaults from all components (including internal dependencies)\n allComponents.forEach((componentInfo) => {\n const userProps = componentProps.get(componentInfo.name) ?? new Map();\n\n // Add default classes (only for props not explicitly set by user)\n Object.entries(componentInfo.defaultProps).forEach(([propName, propValue]) => {\n // Skip if user set this prop explicitly\n if (userProps.has(propName)) {\n return;\n }\n\n // Try direct lookup first\n const variantGroup = variants[propName as keyof typeof variants];\n if (variantGroup) {\n const cls = (variantGroup as Record<string, string>)[propValue];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n }\n\n // Also check propToVariantKeys mapping (e.g., Text's variant -> fontFamily, fontSize, etc.)\n const variantKeys = getVariantKeysForProp(componentInfo, propName);\n if (variantKeys.length > 0) {\n variantKeys.forEach((variantKey) => {\n const mappedVariantGroup =\n variants[variantKey as keyof typeof variants] ?? autoVariantsCache[variantKey];\n if (mappedVariantGroup) {\n const cls = (mappedVariantGroup as Record<string, string>)[propValue];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n }\n });\n }\n });\n\n // Add hardcoded literals from getStyles() calls in component source\n Object.entries(componentInfo.getStylesLiterals).forEach(([propName, propValue]) => {\n // Strip indexed suffix (e.g., \"variantKey:1\" -> \"variantKey\")\n // This handles ternary expressions that generate multiple values per key\n const basePropName = propName.replace(/:\\d+$/, '');\n const variantGroup = variants[basePropName as keyof typeof variants];\n if (variantGroup) {\n const cls = (variantGroup as Record<string, string>)[propValue];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n }\n });\n\n // Add raw Tailwind classes from cx() calls in component source\n if (componentInfo.cxLiterals) {\n componentInfo.cxLiterals.forEach((cls) => safelist.push(cls));\n }\n\n // Add default-variant classes for props not explicitly set\n // The component uses \"uds-button-size-default-root\" at runtime when no size prop is specified\n // The CSS generator creates rules like: .uds-button-size-md-root, .uds-button-size-default-root { ... }\n // We need BOTH classes: the default (runtime) and the actual value (triggers CSS generation)\n if (componentInfo.propToVariantKeys) {\n // Get defaults from consumer config if provided\n const componentDefaults = options.variantDefaults?.[componentInfo.name] ?? {};\n\n Object.keys(componentInfo.propToVariantKeys).forEach((propName) => {\n // Skip if user set this prop explicitly\n if (userProps.has(propName)) {\n return;\n }\n\n // Get the default value from consumer's config\n const defaultValue = componentDefaults[propName];\n const variantKeys = getVariantKeysForProp(componentInfo, propName);\n\n variantKeys.forEach((variantKey) => {\n const variantGroup = autoVariantsCache[variantKey];\n if (variantGroup) {\n // Add the \"default\" class (used by component at runtime)\n if (variantGroup['default']) {\n safelist.push(variantGroup['default']);\n }\n // Add the actual value class (triggers CSS generation with the alias)\n if (defaultValue && variantGroup[defaultValue]) {\n safelist.push(variantGroup[defaultValue]);\n }\n }\n });\n });\n }\n\n // Add classes for props passed to internal components with literal values\n Object.entries(componentInfo.internalComponentProps).forEach(\n ([_internalCompName, propsRecord]) => {\n Object.entries(propsRecord).forEach(([propName, propValues]) => {\n if (propName === 'className') {\n propValues.forEach((propValue) => {\n propValue\n .split(/\\s+/)\n .filter(Boolean)\n .forEach((cls) => safelist.push(cls));\n });\n return;\n }\n\n const variantGroup = variants[propName as keyof typeof variants];\n if (variantGroup) {\n propValues.forEach((propValue) => {\n const cls = (variantGroup as Record<string, string>)[propValue];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n });\n }\n });\n },\n );\n\n // Add classes for explicitly used props\n [...userProps.entries()].forEach(([propName, usedValues]) => {\n if (propName === 'className') {\n [...usedValues].forEach((value) => {\n value\n .split(/\\s+/)\n .filter(Boolean)\n .forEach((cls: string) => safelist.push(cls));\n });\n return;\n }\n\n // First try direct lookup (for Box-style props like backgroundColor)\n const variantGroup = variants[propName as keyof typeof variants];\n if (variantGroup) {\n [...usedValues].forEach((value) => {\n const cls = (variantGroup as Record<string, string>)[value];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n });\n }\n\n // Check if this prop maps to variant keys in this component or its internal components\n // This handles cases like Avatar where size prop mapping is in internal AvatarIcon,\n // and Text where variant -> fontFamily, fontSize, fontWeight, lineHeight, etc.\n const componentsToCheck = [\n componentInfo,\n ...getComponentWithDeps(componentInfo.name).slice(1),\n ];\n componentsToCheck.forEach((comp) => {\n const variantKeys = getVariantKeysForProp(comp, propName);\n if (variantKeys.length > 0) {\n variantKeys.forEach((variantKey) => {\n const mappedVariantGroup = variants[variantKey as keyof typeof variants];\n if (mappedVariantGroup) {\n [...usedValues].forEach((value) => {\n const cls = (mappedVariantGroup as Record<string, string>)[value];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n });\n }\n });\n }\n });\n });\n });\n\n if (options.includeAllClassNamePrimitives) {\n safelist.push(...extractClassNamePrimitives(sourceFile));\n }\n\n // Deduplicate\n const finalSafelist = [...new Set(safelist)];\n\n stats.timeMs = Math.round(performance.now() - startTime);\n stats.classesGenerated = finalSafelist.length;\n\n return {\n safelist: finalSafelist,\n imports,\n components: [...seenComponents],\n stats,\n };\n};\n\n/**\n * Find JSX references for a component in the source file\n */\nconst findComponentReferences = (\n sourceFile: ReturnType<Project['createSourceFile']>,\n componentName: string,\n): JsxElementWithAttributes[] => {\n const references: JsxElementWithAttributes[] = [];\n const seenTags = new Set<string>();\n\n const collectMatchingTags = (localName: string): void => {\n sourceFile\n .getDescendants()\n .filter(\n (node): node is JsxElementWithAttributes =>\n Node.isJsxOpeningElement(node) || Node.isJsxSelfClosingElement(node),\n )\n .forEach((node) => {\n const tagName = node.getTagNameNode().getText();\n if (tagName === localName || tagName.startsWith(`${localName}.`)) {\n const key = `${tagName}:${node.getStart()}`;\n if (!seenTags.has(key)) {\n seenTags.add(key);\n references.push(node);\n }\n }\n });\n };\n\n sourceFile.getImportDeclarations().forEach((importDecl) => {\n const moduleSpec = getModuleSpecifierValue(importDecl);\n if (!isUdsComponentModule(moduleSpec)) {\n return;\n }\n\n importDecl.getNamedImports().forEach((namedImport) => {\n if (\n namedImport.getName() !== componentName ||\n isTypeOnlyNamedImport(importDecl, componentName)\n ) {\n return;\n }\n\n const localName = namedImport.getAliasNode()?.getText() ?? componentName;\n const identifier = namedImport.getFirstDescendantByKindOrThrow(ts.SyntaxKind.Identifier);\n\n findJsxReferences(identifier).forEach((reference) => {\n const key = `${reference.getTagNameNode().getText()}:${reference.getStart()}`;\n if (!seenTags.has(key)) {\n seenTags.add(key);\n references.push(reference);\n }\n });\n\n collectMatchingTags(localName);\n });\n });\n\n return references;\n};\n\n/**\n * Extract props from a JSX reference.\n */\nconst extractPropsFromReference = (\n reference: JsxElementWithAttributes,\n stats: PurgeStats,\n sourceFile: ReturnType<Project['createSourceFile']>,\n): Array<[string, string[]]> => {\n const props: Array<[string, string[]]> = [];\n const attributes = reference.getAttributes();\n\n attributes.forEach((attr) => {\n if (attr.asKind(SyntaxKind.JsxAttribute)) {\n const jsxAttr = attr.asKindOrThrow(SyntaxKind.JsxAttribute);\n const propName = jsxAttr.getNameNode().getText();\n const values: string[] = [];\n\n const initializer = jsxAttr.getInitializer();\n\n // Direct string literal: prop=\"value\"\n if (initializer && Node.isStringLiteral(initializer)) {\n values.push(initializer.getLiteralText());\n stats.expressionsResolved++;\n } else if (initializer && initializer.asKind(SyntaxKind.JsxExpression)) {\n // JSX expression: prop={expression}\n // Use extractStringLiterals to handle ternaries, nullish, OR, etc.\n const jsxExpr = initializer.asKindOrThrow(SyntaxKind.JsxExpression);\n const expression = jsxExpr.getExpression();\n if (expression) {\n const resolved = extractStringLiterals(expression);\n values.push(...resolved);\n if (resolved.length > 0) {\n stats.expressionsResolved++;\n }\n }\n }\n\n props.push([propName, values]);\n }\n\n if (attr.asKind(SyntaxKind.JsxSpreadAttribute)) {\n stats.spreadsTraced++;\n\n const spreadAttr = attr.asKindOrThrow(SyntaxKind.JsxSpreadAttribute);\n const expression = spreadAttr.getExpression();\n const spreadName = expression.getText();\n\n const resolvedSpreadProps = traceSpreadInFile(spreadName, sourceFile);\n\n resolvedSpreadProps.forEach(([propName, values]) => {\n if (values.length > 0) {\n props.push([propName, values]);\n }\n });\n }\n });\n\n return props;\n};\n\n/**\n * Trace spread props to their source within the same file.\n */\nconst traceSpreadInFile = (\n spreadName: string,\n sourceFile: ReturnType<Project['createSourceFile']>,\n): Array<[string, string[]]> => {\n const props: Array<[string, string[]]> = [];\n\n const varDecl = sourceFile.getVariableDeclaration(spreadName);\n if (!varDecl) {\n return props;\n }\n\n const initializer = varDecl.getInitializer();\n if (!initializer) {\n return props;\n }\n\n const objLiteral = initializer.asKind(SyntaxKind.ObjectLiteralExpression)\n ? initializer.asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n : initializer.asKind(SyntaxKind.AsExpression)\n ? initializer\n .asKindOrThrow(SyntaxKind.AsExpression)\n .getExpression()\n .asKind(SyntaxKind.ObjectLiteralExpression)\n ? initializer\n .asKindOrThrow(SyntaxKind.AsExpression)\n .getExpression()\n .asKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n : null\n : null;\n\n if (!objLiteral) {\n return props;\n }\n\n objLiteral.getProperties().forEach((prop) => {\n if (prop.asKind(SyntaxKind.PropertyAssignment)) {\n const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);\n const propName = propAssign.getName();\n const propInit = propAssign.getInitializer();\n\n if (propInit) {\n const values = extractStringLiterals(propInit);\n if (values.length > 0) {\n props.push([propName, values]);\n }\n }\n }\n });\n\n return props;\n};\n\n/**\n * Extract props from getStyles() calls in user code.\n * This handles cases like:\n * const styles = getStyles({ backgroundColor: 'brand', spacing: '4' });\n */\nconst extractGetStylesCalls = (\n sourceFile: ReturnType<Project['createSourceFile']>,\n stats: PurgeStats,\n\n variants: Record<string, Record<string, string>>,\n): Map<string, Set<string>> => {\n const props = new Map<string, Set<string>>();\n\n const VALID_VARIANTS = new Set(Object.keys(variants));\n\n // Find all getStyles() call expressions\n const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n\n callExpressions.forEach((call) => {\n const expression = call.getExpression();\n if (expression.getText() !== 'getStyles') {\n return;\n }\n\n const args = call.getArguments();\n if (args.length === 0) {\n return;\n }\n\n const firstArg = args[0];\n if (!firstArg.asKind(SyntaxKind.ObjectLiteralExpression)) {\n return;\n }\n\n const objLiteral = firstArg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);\n\n objLiteral.getProperties().forEach((prop) => {\n if (prop.asKind(SyntaxKind.PropertyAssignment)) {\n const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);\n const propName = propAssign.getName();\n const propInit = propAssign.getInitializer();\n\n if (propInit && VALID_VARIANTS.has(propName)) {\n const values = extractStringLiterals(propInit);\n if (values.length > 0) {\n const existing = props.get(propName) ?? new Set();\n values.forEach((v) => existing.add(v));\n props.set(propName, existing);\n stats.expressionsResolved++;\n }\n }\n } else if (prop.asKind(SyntaxKind.ShorthandPropertyAssignment)) {\n // Handle shorthand like { backgroundColor } where backgroundColor is a variable\n const shorthand = prop.asKindOrThrow(SyntaxKind.ShorthandPropertyAssignment);\n const propName = shorthand.getName();\n\n if (VALID_VARIANTS.has(propName)) {\n // Try to trace the variable\n const nameNode = shorthand.getNameNode();\n const values = extractStringLiterals(nameNode);\n if (values.length > 0) {\n const existing = props.get(propName) ?? new Set();\n values.forEach((v) => existing.add(v));\n props.set(propName, existing);\n stats.expressionsResolved++;\n }\n }\n }\n });\n });\n\n return props;\n};\n\nexport type { PurgeFromCodeOptions, PurgeFromCodeResult, VariantDefaults };\nexport { purgeFromCodeOptimized };\n"],"mappings":";;;;;;;;;AA6BA,MAAM,wBAAwB,kBAAqD;CACjF,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAM,SAAoC,EAAE;CAE5C,MAAM,WAAW,SAAuB;AACtC,MAAI,QAAQ,IAAI,KAAK,CACnB;AAEF,UAAQ,IAAI,KAAK;EAEjB,MAAM,OAAO,qBAAqB,KAAK;AACvC,MAAI,CAAC,KACH;AAGF,SAAO,KAAK,KAAK;AAGjB,OAAK,mBAAmB,SAAS,YAAY,QAAQ,QAAQ,CAAC;;AAGhE,SAAQ,cAAc;AACtB,QAAO;;;;;AAwCT,IAAI,oBAAoB;;;;AAKxB,IAAI,iBAAiB;;;;;;AAOrB,IAAI,sBAAqD;AAEzD,MAAM,4BACJ,SAC2B;CAC3B,MAAM,SAAiC,EAAE;AAEzC,QAAO,KAAK,KAAK,CAAC,SAAS,QAAQ;EACjC,MAAM,aAAa,uBAAuB,IAAI;AAE9C,MAAI,CAAC,OAAO,YACV,QAAO,cAAc;GAEvB;AAEF,QAAO;;AAGT,MAAM,wBAAwB,SAAsD;AAClF,KAAI,kBAAkB,eAAe,MACnC,QAAO,eAAe;CAGxB,MAAM,aAAa,uBAAuB,KAAK;CAC/C,MAAM,aAAa,sBAAsB;AACzC,KAAI,cAAc,eAChB,QAAO,eAAe;;AAM1B,MAAM,2BAA2B,eAA0C;AACzE,QACE,WAAW,yBAAyB,IACpC,WACG,oBAAoB,CACpB,SAAS,CACT,QAAQ,gBAAgB,GAAG;;AAIlC,MAAM,yBAAyB,YAA+B,eAAgC;AAC5F,KAAI,WAAW,YAAY,CACzB,QAAO;AAGT,QACE,WACG,iBAAiB,CACjB,MAAM,gBAAgB,YAAY,SAAS,KAAK,WAAW,EAC1D,YAAY,IAAI;;AAIxB,MAAM,wBAAwB,oBAAqC;CACjE,MAAM,UAAU,gBAAgB,QAAQ,gBAAgB,GAAG;AAC3D,QAAO,YAAY,gBAAgB,QAAQ,WAAW,cAAc;;;;;AAMtE,MAAM,0BAA0B,SAAyB;CACvD,MAAM,UAAU,KAAK,QAAQ,OAAO,GAAG;AACvC,QAAO,QAAQ,OAAO,EAAE,CAAC,aAAa,GAAG,QAAQ,MAAM,EAAE;;;;;;AAO3D,MAAM,6BAA6B,eAAuB,aAA+B;AACvF,KAAI,CAAC,kBACH,QAAO,EAAE;CAGX,MAAM,WAAW,cAAc,MAAM,kBAAkB,IAAI,EAAE;CAC7D,MAAM,aAAa,IAAI,IAAY,CAAC,uBAAuB,cAAc,CAAC,CAAC;AAG3E,KAAI,SAAS,SAAS,EACpB,OAAM,KAAK,EAAE,QAAQ,SAAS,QAAQ,GAAG,GAAG,UAAU,QAAQ,EAAE,CAAC,SAAS,MAAM;EAC9E,MAAM,UAAU,SAAS,MAAM,GAAG,EAAE,CAAC,KAAK,GAAG;AAC7C,aAAW,IAAI,uBAAuB,QAAQ,CAAC;GAC/C;CAGJ,MAAM,YAAY,SAAS,aAAa;AAExC,QAAO,OAAO,KAAK,kBAAkB,CAAC,QAAQ,QAAQ;EACpD,MAAM,WAAW,IAAI,aAAa;AAClC,SAAO,MAAM,KAAK,WAAW,CAAC,MAC3B,cAAc,SAAS,WAAW,UAAU,IAAI,SAAS,SAAS,UAAU,CAC9E;GACD;;AAGJ,MAAM,yBACJ,eACA,aACa;CACb,MAAM,OAAO,IAAI,IAAI,cAAc,oBAAoB,aAAa,EAAE,CAAC;AAEvE,2BAA0B,cAAc,MAAM,SAAS,CAAC,SAAS,aAAa,KAAK,IAAI,SAAS,CAAC;AAEjG,QAAO,CAAC,GAAG,KAAK;;AAGlB,MAAM,8BACJ,eACa;CACb,MAAM,UAAoB,EAAE;AAG5B,YAAW,qBAAqB,WAAW,aAAa,CAAC,SAAS,SAAS;AACzE,MAAI,KAAK,aAAa,CAAC,SAAS,KAAK,YACnC;EAGF,MAAM,cAAc,KAAK,gBAAgB;AACzC,MAAI,CAAC,YACH;EAGF,MAAM,SAAmB,EAAE;AAE3B,MAAI,KAAK,gBAAgB,YAAY,CACnC,QAAO,KAAK,YAAY,gBAAgB,CAAC;WAChC,KAAK,gBAAgB,YAAY,EAAE;GAC5C,MAAM,OAAO,YAAY,eAAe;AACxC,OAAI,KACF,QAAO,KAAK,GAAG,sBAAsB,KAAK,CAAC;;AAI/C,SAAO,SAAS,QAAQ;AACtB,WAAQ,KAAK,GAAG,IAAI,MAAM,MAAM,CAAC,OAAO,QAAQ,CAAC;IACjD;GACF;AAGF,YAAW,qBAAqB,WAAW,mBAAmB,CAAC,SAAS,SAAS;AAC/E,MAAI,KAAK,SAAS,KAAK,YACrB;EAGF,MAAM,cAAc,KAAK,gBAAgB;AACzC,MAAI,CAAC,YACH;AAIF,EADkB,sBAAsB,YAAY,CAC1C,SAAS,QAAQ;AACzB,WAAQ,KAAK,GAAG,IAAI,MAAM,MAAM,CAAC,OAAO,QAAQ,CAAC;IACjD;GACF;AAEF,QAAO;;AAGT,MAAM,yBAAyB,OAC7B,MACA,YACiC;CACjC,MAAM,EAAE,UAAU,cAAc,kBAAkB;AAElD,KAAI,CAAC,kBACH,qBAAoB;AAGtB,KAAI,CAAC,gBAAgB;AACnB,mBAAiB;AACjB,wBAAsB,yBAAyB,cAAc;;CAG/D,MAAM,YAAY,YAAY,KAAK;CAGnC,MAAM,aADU,IAAI,QAAQ,EAAE,uBAAuB,MAAM,CAAC,CACjC,iBAAiB,QAAQ,YAAY,aAAa,MAAM,EACjF,WAAW,MACZ,CAAC;CAEF,MAAM,QAAoB;EACxB,cAAc;EACd,QAAQ;EACR,kBAAkB;EAClB,eAAe;EACf,qBAAqB;EACtB;CAGD,MAAM,UAAoB,EAAE;AAC5B,YAAW,uBAAuB,CAAC,SAAS,eAAe;AAEzD,MAAI,qBADe,wBAAwB,WAAW,CAClB,CAClC,YAAW,iBAAiB,CAAC,SAAS,gBAAgB;AACpD,OAAI,CAAC,YAAY,YAAY,IAAI,CAAC,WAAW,YAAY,CACvD,SAAQ,KAAK,YAAY,SAAS,CAAC;IAErC;GAEJ;CAGF,MAAM,iCAAiB,IAAI,KAAuC;CAClE,MAAM,uCAAuB,IAAI,KAAa;CAG9C,MAAM,iBAAiB,sBAAsB,YAAY,OAAO,SAAS;AAGzE,SAAQ,SAAS,QAAQ;AAGvB,EAFmB,wBAAwB,YAAY,IAAI,CAEhD,SAAS,cAAc;GAEhC,MAAM,gBADU,UAAU,gBAAgB,CAAC,SAAS,IACnB;AAEjC,wBAAqB,IAAI,cAAc;GAEvC,MAAM,WAAW,eAAe,IAAI,cAAc,oBAAI,IAAI,KAA0B;AAGpF,GAFc,0BAA0B,WAAW,OAAO,WAAW,CAE/D,SAAS,CAAC,UAAU,YAAY;AACpC,QAAI,OAAO,SAAS,GAAG;KACrB,MAAM,WAAW,SAAS,IAAI,SAAS,oBAAI,IAAI,KAAK;AACpD,YAAO,SAAS,QAAQ,SAAS,IAAI,IAAI,CAAC;AAC1C,cAAS,IAAI,UAAU,SAAS;;KAElC;AAEF,kBAAe,IAAI,eAAe,SAAS;IAC3C;AAEF,MAAI,CAAC,eAAe,IAAI,IAAI,CAC1B,gBAAe,IAAI,qBAAK,IAAI,KAAK,CAAC;GAEpC;CAGF,MAAM,gBAA2C,EAAE;CACnD,MAAM,iCAAiB,IAAI,KAAa;AAIxC,CAF4B,IAAI,IAAY,CAAC,GAAG,SAAS,GAAG,qBAAqB,CAAC,CAE9D,SAAS,kBAAkB;AAE7C,EAD2B,qBAAqB,cAAc,CAC3C,SAAS,SAAS;AACnC,OAAI,CAAC,eAAe,IAAI,KAAK,KAAK,EAAE;AAClC,mBAAe,IAAI,KAAK,KAAK;AAC7B,kBAAc,KAAK,KAAK;;IAE1B;GACF;CAGF,MAAM,WAAqB,EAAE;AAG7B,EAAC,GAAG,eAAe,SAAS,CAAC,CAAC,SAAS,CAAC,UAAU,YAAY;EAC5D,MAAM,eAAe,SAAS;AAC9B,MAAI,aACF,QAAO,SAAS,UAAU;GACxB,MAAM,MAAO,aAAwC;AACrD,OAAI,IACF,UAAS,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC;IAEzC;GAEJ;AAGF,eAAc,SAAS,kBAAkB;EACvC,MAAM,YAAY,eAAe,IAAI,cAAc,KAAK,oBAAI,IAAI,KAAK;AAGrE,SAAO,QAAQ,cAAc,aAAa,CAAC,SAAS,CAAC,UAAU,eAAe;AAE5E,OAAI,UAAU,IAAI,SAAS,CACzB;GAIF,MAAM,eAAe,SAAS;AAC9B,OAAI,cAAc;IAChB,MAAM,MAAO,aAAwC;AACrD,QAAI,IACF,UAAS,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC;;GAK3C,MAAM,cAAc,sBAAsB,eAAe,SAAS;AAClE,OAAI,YAAY,SAAS,EACvB,aAAY,SAAS,eAAe;IAClC,MAAM,qBACJ,SAAS,eAAwC,kBAAkB;AACrE,QAAI,oBAAoB;KACtB,MAAM,MAAO,mBAA8C;AAC3D,SAAI,IACF,UAAS,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC;;KAG3C;IAEJ;AAGF,SAAO,QAAQ,cAAc,kBAAkB,CAAC,SAAS,CAAC,UAAU,eAAe;GAIjF,MAAM,eAAe,SADA,SAAS,QAAQ,SAAS,GAAG;AAElD,OAAI,cAAc;IAChB,MAAM,MAAO,aAAwC;AACrD,QAAI,IACF,UAAS,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC;;IAG3C;AAGF,MAAI,cAAc,WAChB,eAAc,WAAW,SAAS,QAAQ,SAAS,KAAK,IAAI,CAAC;AAO/D,MAAI,cAAc,mBAAmB;GAEnC,MAAM,oBAAoB,QAAQ,kBAAkB,cAAc,SAAS,EAAE;AAE7E,UAAO,KAAK,cAAc,kBAAkB,CAAC,SAAS,aAAa;AAEjE,QAAI,UAAU,IAAI,SAAS,CACzB;IAIF,MAAM,eAAe,kBAAkB;AAGvC,IAFoB,sBAAsB,eAAe,SAAS,CAEtD,SAAS,eAAe;KAClC,MAAM,eAAe,kBAAkB;AACvC,SAAI,cAAc;AAEhB,UAAI,aAAa,WACf,UAAS,KAAK,aAAa,WAAW;AAGxC,UAAI,gBAAgB,aAAa,cAC/B,UAAS,KAAK,aAAa,cAAc;;MAG7C;KACF;;AAIJ,SAAO,QAAQ,cAAc,uBAAuB,CAAC,SAClD,CAAC,mBAAmB,iBAAiB;AACpC,UAAO,QAAQ,YAAY,CAAC,SAAS,CAAC,UAAU,gBAAgB;AAC9D,QAAI,aAAa,aAAa;AAC5B,gBAAW,SAAS,cAAc;AAChC,gBACG,MAAM,MAAM,CACZ,OAAO,QAAQ,CACf,SAAS,QAAQ,SAAS,KAAK,IAAI,CAAC;OACvC;AACF;;IAGF,MAAM,eAAe,SAAS;AAC9B,QAAI,aACF,YAAW,SAAS,cAAc;KAChC,MAAM,MAAO,aAAwC;AACrD,SAAI,IACF,UAAS,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC;MAEzC;KAEJ;IAEL;AAGD,GAAC,GAAG,UAAU,SAAS,CAAC,CAAC,SAAS,CAAC,UAAU,gBAAgB;AAC3D,OAAI,aAAa,aAAa;AAC5B,KAAC,GAAG,WAAW,CAAC,SAAS,UAAU;AACjC,WACG,MAAM,MAAM,CACZ,OAAO,QAAQ,CACf,SAAS,QAAgB,SAAS,KAAK,IAAI,CAAC;MAC/C;AACF;;GAIF,MAAM,eAAe,SAAS;AAC9B,OAAI,aACF,EAAC,GAAG,WAAW,CAAC,SAAS,UAAU;IACjC,MAAM,MAAO,aAAwC;AACrD,QAAI,IACF,UAAS,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC;KAEzC;AAUJ,GAJ0B,CACxB,eACA,GAAG,qBAAqB,cAAc,KAAK,CAAC,MAAM,EAAE,CACrD,CACiB,SAAS,SAAS;IAClC,MAAM,cAAc,sBAAsB,MAAM,SAAS;AACzD,QAAI,YAAY,SAAS,EACvB,aAAY,SAAS,eAAe;KAClC,MAAM,qBAAqB,SAAS;AACpC,SAAI,mBACF,EAAC,GAAG,WAAW,CAAC,SAAS,UAAU;MACjC,MAAM,MAAO,mBAA8C;AAC3D,UAAI,IACF,UAAS,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC;OAEzC;MAEJ;KAEJ;IACF;GACF;AAEF,KAAI,QAAQ,8BACV,UAAS,KAAK,GAAG,2BAA2B,WAAW,CAAC;CAI1D,MAAM,gBAAgB,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;AAE5C,OAAM,SAAS,KAAK,MAAM,YAAY,KAAK,GAAG,UAAU;AACxD,OAAM,mBAAmB,cAAc;AAEvC,QAAO;EACL,UAAU;EACV;EACA,YAAY,CAAC,GAAG,eAAe;EAC/B;EACD;;;;;AAMH,MAAM,2BACJ,YACA,kBAC+B;CAC/B,MAAM,aAAyC,EAAE;CACjD,MAAM,2BAAW,IAAI,KAAa;CAElC,MAAM,uBAAuB,cAA4B;AACvD,aACG,gBAAgB,CAChB,QACE,SACC,KAAK,oBAAoB,KAAK,IAAI,KAAK,wBAAwB,KAAK,CACvE,CACA,SAAS,SAAS;GACjB,MAAM,UAAU,KAAK,gBAAgB,CAAC,SAAS;AAC/C,OAAI,YAAY,aAAa,QAAQ,WAAW,GAAG,UAAU,GAAG,EAAE;IAChE,MAAM,MAAM,GAAG,QAAQ,GAAG,KAAK,UAAU;AACzC,QAAI,CAAC,SAAS,IAAI,IAAI,EAAE;AACtB,cAAS,IAAI,IAAI;AACjB,gBAAW,KAAK,KAAK;;;IAGzB;;AAGN,YAAW,uBAAuB,CAAC,SAAS,eAAe;AAEzD,MAAI,CAAC,qBADc,wBAAwB,WAAW,CACjB,CACnC;AAGF,aAAW,iBAAiB,CAAC,SAAS,gBAAgB;AACpD,OACE,YAAY,SAAS,KAAK,iBAC1B,sBAAsB,YAAY,cAAc,CAEhD;GAGF,MAAM,YAAY,YAAY,cAAc,EAAE,SAAS,IAAI;AAG3D,qBAFmB,YAAY,gCAAgC,GAAG,WAAW,WAAW,CAE3D,CAAC,SAAS,cAAc;IACnD,MAAM,MAAM,GAAG,UAAU,gBAAgB,CAAC,SAAS,CAAC,GAAG,UAAU,UAAU;AAC3E,QAAI,CAAC,SAAS,IAAI,IAAI,EAAE;AACtB,cAAS,IAAI,IAAI;AACjB,gBAAW,KAAK,UAAU;;KAE5B;AAEF,uBAAoB,UAAU;IAC9B;GACF;AAEF,QAAO;;;;;AAMT,MAAM,6BACJ,WACA,OACA,eAC8B;CAC9B,MAAM,QAAmC,EAAE;AAG3C,CAFmB,UAAU,eAAe,CAEjC,SAAS,SAAS;AAC3B,MAAI,KAAK,OAAO,WAAW,aAAa,EAAE;GACxC,MAAM,UAAU,KAAK,cAAc,WAAW,aAAa;GAC3D,MAAM,WAAW,QAAQ,aAAa,CAAC,SAAS;GAChD,MAAM,SAAmB,EAAE;GAE3B,MAAM,cAAc,QAAQ,gBAAgB;AAG5C,OAAI,eAAe,KAAK,gBAAgB,YAAY,EAAE;AACpD,WAAO,KAAK,YAAY,gBAAgB,CAAC;AACzC,UAAM;cACG,eAAe,YAAY,OAAO,WAAW,cAAc,EAAE;IAItE,MAAM,aADU,YAAY,cAAc,WAAW,cAAc,CACxC,eAAe;AAC1C,QAAI,YAAY;KACd,MAAM,WAAW,sBAAsB,WAAW;AAClD,YAAO,KAAK,GAAG,SAAS;AACxB,SAAI,SAAS,SAAS,EACpB,OAAM;;;AAKZ,SAAM,KAAK,CAAC,UAAU,OAAO,CAAC;;AAGhC,MAAI,KAAK,OAAO,WAAW,mBAAmB,EAAE;AAC9C,SAAM;AAQN,GAF4B,kBAJT,KAAK,cAAc,WAAW,mBAAmB,CACtC,eAAe,CACf,SAAS,EAEmB,WAAW,CAEjD,SAAS,CAAC,UAAU,YAAY;AAClD,QAAI,OAAO,SAAS,EAClB,OAAM,KAAK,CAAC,UAAU,OAAO,CAAC;KAEhC;;GAEJ;AAEF,QAAO;;;;;AAMT,MAAM,qBACJ,YACA,eAC8B;CAC9B,MAAM,QAAmC,EAAE;CAE3C,MAAM,UAAU,WAAW,uBAAuB,WAAW;AAC7D,KAAI,CAAC,QACH,QAAO;CAGT,MAAM,cAAc,QAAQ,gBAAgB;AAC5C,KAAI,CAAC,YACH,QAAO;CAGT,MAAM,aAAa,YAAY,OAAO,WAAW,wBAAwB,GACrE,YAAY,cAAc,WAAW,wBAAwB,GAC7D,YAAY,OAAO,WAAW,aAAa,GACzC,YACG,cAAc,WAAW,aAAa,CACtC,eAAe,CACf,OAAO,WAAW,wBAAwB,GAC3C,YACG,cAAc,WAAW,aAAa,CACtC,eAAe,CACf,cAAc,WAAW,wBAAwB,GACpD,OACF;AAEN,KAAI,CAAC,WACH,QAAO;AAGT,YAAW,eAAe,CAAC,SAAS,SAAS;AAC3C,MAAI,KAAK,OAAO,WAAW,mBAAmB,EAAE;GAC9C,MAAM,aAAa,KAAK,cAAc,WAAW,mBAAmB;GACpE,MAAM,WAAW,WAAW,SAAS;GACrC,MAAM,WAAW,WAAW,gBAAgB;AAE5C,OAAI,UAAU;IACZ,MAAM,SAAS,sBAAsB,SAAS;AAC9C,QAAI,OAAO,SAAS,EAClB,OAAM,KAAK,CAAC,UAAU,OAAO,CAAC;;;GAIpC;AAEF,QAAO;;;;;;;AAQT,MAAM,yBACJ,YACA,OAEA,aAC6B;CAC7B,MAAM,wBAAQ,IAAI,KAA0B;CAE5C,MAAM,iBAAiB,IAAI,IAAI,OAAO,KAAK,SAAS,CAAC;AAKrD,CAFwB,WAAW,qBAAqB,WAAW,eAAe,CAElE,SAAS,SAAS;AAEhC,MADmB,KAAK,eAAe,CACxB,SAAS,KAAK,YAC3B;EAGF,MAAM,OAAO,KAAK,cAAc;AAChC,MAAI,KAAK,WAAW,EAClB;EAGF,MAAM,WAAW,KAAK;AACtB,MAAI,CAAC,SAAS,OAAO,WAAW,wBAAwB,CACtD;AAKF,EAFmB,SAAS,cAAc,WAAW,wBAAwB,CAElE,eAAe,CAAC,SAAS,SAAS;AAC3C,OAAI,KAAK,OAAO,WAAW,mBAAmB,EAAE;IAC9C,MAAM,aAAa,KAAK,cAAc,WAAW,mBAAmB;IACpE,MAAM,WAAW,WAAW,SAAS;IACrC,MAAM,WAAW,WAAW,gBAAgB;AAE5C,QAAI,YAAY,eAAe,IAAI,SAAS,EAAE;KAC5C,MAAM,SAAS,sBAAsB,SAAS;AAC9C,SAAI,OAAO,SAAS,GAAG;MACrB,MAAM,WAAW,MAAM,IAAI,SAAS,oBAAI,IAAI,KAAK;AACjD,aAAO,SAAS,MAAM,SAAS,IAAI,EAAE,CAAC;AACtC,YAAM,IAAI,UAAU,SAAS;AAC7B,YAAM;;;cAGD,KAAK,OAAO,WAAW,4BAA4B,EAAE;IAE9D,MAAM,YAAY,KAAK,cAAc,WAAW,4BAA4B;IAC5E,MAAM,WAAW,UAAU,SAAS;AAEpC,QAAI,eAAe,IAAI,SAAS,EAAE;KAGhC,MAAM,SAAS,sBADE,UAAU,aAAa,CACM;AAC9C,SAAI,OAAO,SAAS,GAAG;MACrB,MAAM,WAAW,MAAM,IAAI,SAAS,oBAAI,IAAI,KAAK;AACjD,aAAO,SAAS,MAAM,SAAS,IAAI,EAAE,CAAC;AACtC,YAAM,IAAI,UAAU,SAAS;AAC7B,YAAM;;;;IAIZ;GACF;AAEF,QAAO"}
1
+ {"version":3,"file":"purgeFromCode.js","names":[],"sources":["../../../src/purger/optimized/purgeFromCode.ts"],"sourcesContent":["import type { ImportDeclaration, ObjectLiteralExpression } from 'ts-morph';\nimport { Node, Project, SyntaxKind, ts } from 'ts-morph';\n\nimport { extractStringLiterals, findJsxReferences } from './ast';\nimport type { JsxElementWithAttributes, PurgeStats } from './types';\n\ninterface PurgeFromCodeResult {\n safelist: string[];\n imports: string[];\n components: string[];\n stats: PurgeStats;\n}\n\ntype RuntimeConfigValues = Record<string, string | number | boolean>;\n\n/**\n * Serialized component info from pre-generated data\n */\ninterface SerializedComponentInfo {\n name: string;\n defaultProps: Record<string, string>;\n getStylesLiterals: Record<string, string>;\n cxLiterals?: string[];\n internalComponents: string[];\n internalComponentProps: Record<string, Record<string, string[]>>;\n propToVariantKeys: Record<string, string[]>;\n runtimeConfigDefaultProps?: Record<string, string>;\n runtimeConfigGetStyles?: Record<string, string[]>;\n runtimeConfigInternalComponentProps?: Record<string, Record<string, string[]>>;\n}\n\n/**\n * Get component info with all its dependencies (using pre-generated data)\n */\nconst getComponentWithDeps = (componentName: string): SerializedComponentInfo[] => {\n const visited = new Set<string>();\n const result: SerializedComponentInfo[] = [];\n\n const collect = (name: string): void => {\n if (visited.has(name)) {\n return;\n }\n visited.add(name);\n\n const info = resolveComponentInfo(name);\n if (!info) {\n return;\n }\n\n result.push(info);\n\n // Recursively collect internal component dependencies\n info.internalComponents.forEach((depName) => collect(depName));\n };\n\n collect(componentName);\n return result;\n};\n\n/**\n * Optimized purge from code string.\n *\n * This is a standalone implementation that:\n * - Analyzes UDS component source files to get accurate default props\n * - Includes defaults from internally used components\n * - Only depends on variants from src/styles/variants.ts (source of truth)\n * - Uses ts-morph for AST analysis\n *\n * Key behaviors:\n * - Includes classes for component default props (analyzed from source)\n * - Includes defaults for internal component dependencies\n * - Includes classes for explicitly used prop values\n * - Resolves ternary/logical expressions to extract all possible values\n * - Traces spreads to const objects in the same file\n * - Does NOT fall back to type properties for unresolved spreads\n */\n/**\n * Variant defaults per component from consumer's config\n * e.g., { Button: { size: 'md', variant: 'primary' }, Avatar: { size: 'md' } }\n */\ntype VariantDefaults = Record<string, Record<string, string>>;\n\ninterface PurgeFromCodeOptions {\n colorModes?: ('dark' | 'light')[];\n /** Variant defaults from consumer's config - used to include default CSS when prop not specified */\n variantDefaults?: VariantDefaults;\n runtimeConfigValues?: RuntimeConfigValues;\n variants: Record<string, Record<string, string>>;\n autoVariants: Record<string, Record<string, string>>;\n componentData: Record<string, SerializedComponentInfo>;\n includeAllClassNamePrimitives?: boolean;\n filePath?: string;\n}\n\n/**\n * Auto-variants lookup (loaded at module init)\n */\nlet autoVariantsCache = null as unknown as Record<string, Record<string, string>>;\n\n/**\n * Pre-generated component data (loaded at module init)\n */\nlet componentCache = null as unknown as Record<string, SerializedComponentInfo>;\n\n/**\n * Map of normalized component name -> actual component cache key\n * Useful when internal components are imported without namespace separators\n * (e.g., MenuItemBase vs Menu.ItemBase).\n */\nlet componentNameLookup: Record<string, string> | null = null;\n\nconst buildComponentNameLookup = (\n data: Record<string, SerializedComponentInfo>,\n): Record<string, string> => {\n const lookup: Record<string, string> = {};\n\n Object.keys(data).forEach((key) => {\n const normalized = normalizeComponentName(key);\n // Keep the first match to avoid arbitrary overwrites on collisions\n if (!lookup[normalized]) {\n lookup[normalized] = key;\n }\n });\n\n return lookup;\n};\n\nconst resolveComponentInfo = (name: string): SerializedComponentInfo | undefined => {\n if (componentCache && componentCache[name]) {\n return componentCache[name];\n }\n\n const normalized = normalizeComponentName(name);\n const mappedName = componentNameLookup?.[normalized];\n if (mappedName && componentCache) {\n return componentCache[mappedName];\n }\n\n return undefined;\n};\n\nconst getModuleSpecifierValue = (importDecl: ImportDeclaration): string => {\n return (\n importDecl.getModuleSpecifierValue() ??\n importDecl\n .getModuleSpecifier()\n .getText()\n .replace(/^['\"]|['\"]$/g, '')\n );\n};\n\nconst isTypeOnlyNamedImport = (importDecl: ImportDeclaration, importName: string): boolean => {\n if (importDecl.isTypeOnly()) {\n return true;\n }\n\n return (\n importDecl\n .getNamedImports()\n .find((namedImport) => namedImport.getName() === importName)\n ?.isTypeOnly() ?? false\n );\n};\n\nconst isUdsComponentModule = (moduleSpecifier: string): boolean => {\n const cleaned = moduleSpecifier.replace(/^['\"]|['\"]$/g, '');\n return cleaned === '@yahoo/uds' || cleaned.startsWith('@yahoo/uds/');\n};\n\n/**\n * Normalize component name to match autoVariants keys (lower camel, no punctuation).\n */\nconst normalizeComponentName = (name: string): string => {\n const cleaned = name.replace(/\\W/g, '');\n return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);\n};\n\n/**\n * Fallback: infer prop -> variant key mapping from autoVariants when the\n * generated component data misses it (e.g., helpers like buildAvatarRootClasses).\n */\nconst getAutoVariantKeysForProp = (componentName: string, propName: string): string[] => {\n if (!autoVariantsCache) {\n return [];\n }\n\n const segments = componentName.match(/[A-Z][a-z0-9]*/g) ?? [];\n const candidates = new Set<string>([normalizeComponentName(componentName)]);\n\n // Add progressively shorter prefixes (e.g., AvatarImage -> avatar, avatarimage)\n if (segments.length > 0) {\n Array.from({ length: segments.length }, (_, index) => index + 1).forEach((i) => {\n const partial = segments.slice(0, i).join('');\n candidates.add(normalizeComponentName(partial));\n });\n }\n\n const propLower = propName.toLowerCase();\n\n return Object.keys(autoVariantsCache).filter((key) => {\n const keyLower = key.toLowerCase();\n return Array.from(candidates).some(\n (candidate) => keyLower.startsWith(candidate) && keyLower.includes(propLower),\n );\n });\n};\n\nconst getVariantKeysForProp = (\n componentInfo: SerializedComponentInfo,\n propName: string,\n): string[] => {\n const keys = new Set(componentInfo.propToVariantKeys?.[propName] ?? []);\n\n getAutoVariantKeysForProp(componentInfo.name, propName).forEach((inferred) => keys.add(inferred));\n\n return [...keys];\n};\n\nconst addVariantGroupClasses = (\n variantGroup: Record<string, string> | undefined,\n safelist: string[],\n): void => {\n if (!variantGroup) {\n return;\n }\n\n Object.values(variantGroup).forEach((cls) => {\n safelist.push(cls.replaceAll('\\\\', ''));\n });\n};\n\nconst getRuntimeDefaultPropValues = (\n componentInfo: SerializedComponentInfo,\n propName: string,\n runtimeConfigValues?: RuntimeConfigValues,\n): string[] => {\n const selector = componentInfo.runtimeConfigDefaultProps?.[propName];\n if (!selector || !runtimeConfigValues) {\n return [];\n }\n\n const value = runtimeConfigValues[selector];\n return value === undefined ? [] : [String(value)];\n};\n\nconst getPropCandidateValues = (\n componentInfo: SerializedComponentInfo,\n propName: string,\n userProps: Map<string, Set<string>>,\n options: PurgeFromCodeOptions,\n): string[] => {\n const explicitValues = userProps.get(propName);\n if (explicitValues && explicitValues.size > 0) {\n return [...explicitValues];\n }\n\n const configuredDefault = options.variantDefaults?.[componentInfo.name]?.[propName];\n if (configuredDefault) {\n return [configuredDefault];\n }\n\n if (componentInfo.defaultProps[propName]) {\n return [componentInfo.defaultProps[propName]];\n }\n\n return getRuntimeDefaultPropValues(componentInfo, propName, options.runtimeConfigValues);\n};\n\nconst resolveRuntimeSelectorValues = (\n selectorTemplate: string,\n componentInfo: SerializedComponentInfo,\n userProps: Map<string, Set<string>>,\n options: PurgeFromCodeOptions,\n): string[] => {\n const runtimeConfigValues = options.runtimeConfigValues;\n if (!runtimeConfigValues) {\n return [];\n }\n\n const placeholders = [...selectorTemplate.matchAll(/\\$\\{(\\w+)\\}/g)].map((match) => match[1]);\n const selectors = placeholders.reduce<string[]>(\n (acc, propName) => {\n const propValues = getPropCandidateValues(componentInfo, propName, userProps, options);\n if (propValues.length === 0) {\n return [];\n }\n\n return acc.flatMap((selector) =>\n propValues.map((value) => selector.replaceAll('$' + '{' + propName + '}', value)),\n );\n },\n [selectorTemplate],\n );\n\n return selectors.flatMap((selector) => {\n const value = runtimeConfigValues[selector];\n return value === undefined ? [] : [String(value)];\n });\n};\n\nconst extractClassNamePrimitives = (\n sourceFile: ReturnType<Project['createSourceFile']>,\n): string[] => {\n const classes: string[] = [];\n\n // JSX className attributes\n sourceFile.getDescendantsOfKind(SyntaxKind.JsxAttribute).forEach((attr) => {\n if (attr.getNameNode().getText() !== 'className') {\n return;\n }\n\n const initializer = attr.getInitializer();\n if (!initializer) {\n return;\n }\n\n const values: string[] = [];\n\n if (Node.isStringLiteral(initializer)) {\n values.push(initializer.getLiteralText());\n } else if (Node.isJsxExpression(initializer)) {\n const expr = initializer.getExpression();\n if (expr) {\n values.push(...extractStringLiterals(expr));\n }\n }\n\n values.forEach((raw) => {\n classes.push(...raw.split(/\\s+/).filter(Boolean));\n });\n });\n\n // Plain object property assignments like const props = { className: '...' }\n sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAssignment).forEach((prop) => {\n if (prop.getName() !== 'className') {\n return;\n }\n\n const initializer = prop.getInitializer();\n if (!initializer) {\n return;\n }\n\n const rawValues = extractStringLiterals(initializer);\n rawValues.forEach((raw) => {\n classes.push(...raw.split(/\\s+/).filter(Boolean));\n });\n });\n\n return classes;\n};\n\nconst purgeFromCodeOptimized = async (\n code: string,\n options: PurgeFromCodeOptions,\n): Promise<PurgeFromCodeResult> => {\n const { variants, autoVariants, componentData } = options;\n\n if (!autoVariantsCache) {\n autoVariantsCache = autoVariants;\n }\n\n if (!componentCache) {\n componentCache = componentData;\n componentNameLookup = buildComponentNameLookup(componentData);\n }\n\n const startTime = performance.now();\n\n const project = new Project({ useInMemoryFileSystem: true });\n const sourceFile = project.createSourceFile(options.filePath ?? 'input.tsx', code, {\n overwrite: true,\n });\n\n const stats: PurgeStats = {\n filesScanned: 1,\n timeMs: 0,\n classesGenerated: 0,\n spreadsTraced: 0,\n expressionsResolved: 0,\n };\n\n // Parse UDS imports\n const imports: string[] = [];\n sourceFile.getImportDeclarations().forEach((importDecl) => {\n const moduleSpec = getModuleSpecifierValue(importDecl);\n if (isUdsComponentModule(moduleSpec)) {\n importDecl.getNamedImports().forEach((namedImport) => {\n if (!namedImport.isTypeOnly() && !importDecl.isTypeOnly()) {\n imports.push(namedImport.getName());\n }\n });\n }\n });\n\n // Track all resolved prop values per component\n const componentProps = new Map<string, Map<string, Set<string>>>();\n const componentUnresolvedSpreadProps = new Map<string, Set<string>>();\n const referencedComponents = new Set<string>();\n\n // Extract props from getStyles() calls in user code\n const getStylesProps = extractGetStylesCalls(sourceFile, stats, variants);\n\n // Find all JSX elements that use UDS components\n imports.forEach((imp) => {\n const references = findComponentReferences(sourceFile, imp);\n\n references.forEach((reference) => {\n const tagName = reference.getTagNameNode().getText();\n const componentName = tagName || imp;\n\n referencedComponents.add(componentName);\n\n const propsMap = componentProps.get(componentName) ?? new Map<string, Set<string>>();\n const unresolvedSpreadProps = componentUnresolvedSpreadProps.get(componentName) ?? new Set();\n const props = extractPropsFromReference(reference, stats, sourceFile);\n\n props.forEach(({ propName, values, fromSpread }) => {\n if (values.length > 0) {\n const existing = propsMap.get(propName) ?? new Set();\n values.forEach((val) => existing.add(val));\n propsMap.set(propName, existing);\n return;\n }\n\n if (fromSpread) {\n unresolvedSpreadProps.add(propName);\n }\n });\n\n componentProps.set(componentName, propsMap);\n componentUnresolvedSpreadProps.set(componentName, unresolvedSpreadProps);\n });\n\n if (!componentProps.has(imp)) {\n componentProps.set(imp, new Map());\n }\n\n if (!componentUnresolvedSpreadProps.has(imp)) {\n componentUnresolvedSpreadProps.set(imp, new Set());\n }\n });\n\n // Collect all components (including dependencies)\n const allComponents: SerializedComponentInfo[] = [];\n const seenComponents = new Set<string>();\n\n const componentsToProcess = new Set<string>([...imports, ...referencedComponents]);\n\n componentsToProcess.forEach((componentName) => {\n const componentsWithDeps = getComponentWithDeps(componentName);\n componentsWithDeps.forEach((comp) => {\n if (!seenComponents.has(comp.name)) {\n seenComponents.add(comp.name);\n allComponents.push(comp);\n }\n });\n });\n\n // Generate safelist\n const safelist: string[] = [];\n\n // Add classes from getStyles() calls in user code\n [...getStylesProps.entries()].forEach(([propName, values]) => {\n const variantGroup = variants[propName as keyof typeof variants];\n if (variantGroup) {\n values.forEach((value) => {\n const cls = (variantGroup as Record<string, string>)[value];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n });\n }\n });\n\n // Add defaults from all components (including internal dependencies)\n allComponents.forEach((componentInfo) => {\n const userProps = componentProps.get(componentInfo.name) ?? new Map();\n const unresolvedSpreadProps =\n componentUnresolvedSpreadProps.get(componentInfo.name) ?? new Set();\n\n // Add default classes (only for props not explicitly set by user)\n Object.entries(componentInfo.defaultProps).forEach(([propName, propValue]) => {\n // Skip if user set this prop explicitly\n if (userProps.has(propName)) {\n return;\n }\n\n // Try direct lookup first\n const variantGroup = variants[propName as keyof typeof variants];\n if (variantGroup) {\n const cls = (variantGroup as Record<string, string>)[propValue];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n }\n\n // Also check propToVariantKeys mapping (e.g., Text's variant -> fontFamily, fontSize, etc.)\n const variantKeys = getVariantKeysForProp(componentInfo, propName);\n if (variantKeys.length > 0) {\n variantKeys.forEach((variantKey) => {\n const mappedVariantGroup =\n variants[variantKey as keyof typeof variants] ?? autoVariantsCache[variantKey];\n if (mappedVariantGroup) {\n const cls = (mappedVariantGroup as Record<string, string>)[propValue];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n }\n });\n }\n });\n\n // Add hardcoded literals from getStyles() calls in component source\n Object.entries(componentInfo.getStylesLiterals).forEach(([propName, propValue]) => {\n // Strip indexed suffix (e.g., \"variantKey:1\" -> \"variantKey\")\n // This handles ternary expressions that generate multiple values per key\n const basePropName = propName.replace(/:\\d+$/, '');\n const variantGroup = variants[basePropName as keyof typeof variants];\n if (variantGroup) {\n const cls = (variantGroup as Record<string, string>)[propValue];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n }\n });\n\n Object.entries(componentInfo.runtimeConfigGetStyles ?? {}).forEach(([propName, selectors]) => {\n const variantGroup =\n variants[propName as keyof typeof variants] ?? autoVariantsCache[propName];\n if (!variantGroup) {\n return;\n }\n\n selectors.forEach((selector) => {\n resolveRuntimeSelectorValues(selector, componentInfo, userProps, options).forEach(\n (value) => {\n const cls = (variantGroup as Record<string, string>)[value];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n },\n );\n });\n });\n\n // Add raw Tailwind classes from cx() calls in component source\n if (componentInfo.cxLiterals) {\n componentInfo.cxLiterals.forEach((cls) => safelist.push(cls));\n }\n\n // Add default-variant classes for props not explicitly set\n // The component uses \"uds-button-size-default-root\" at runtime when no size prop is specified\n // The CSS generator creates rules like: .uds-button-size-md-root, .uds-button-size-default-root { ... }\n // We need BOTH classes: the default (runtime) and the actual value (triggers CSS generation)\n if (componentInfo.propToVariantKeys) {\n // Get defaults from consumer config if provided\n const componentDefaults = options.variantDefaults?.[componentInfo.name] ?? {};\n\n Object.keys(componentInfo.propToVariantKeys).forEach((propName) => {\n // Skip if user set this prop explicitly\n if (userProps.has(propName)) {\n return;\n }\n\n // Get the default value from consumer's config\n const defaultValues = componentDefaults[propName]\n ? [componentDefaults[propName]]\n : getRuntimeDefaultPropValues(componentInfo, propName, options.runtimeConfigValues);\n const variantKeys = getVariantKeysForProp(componentInfo, propName);\n\n variantKeys.forEach((variantKey) => {\n const variantGroup = autoVariantsCache[variantKey];\n if (variantGroup) {\n // Add the \"default\" class (used by component at runtime)\n if (variantGroup['default']) {\n safelist.push(variantGroup['default']);\n }\n // Add the actual value class (triggers CSS generation with the alias)\n defaultValues.forEach((defaultValue) => {\n if (variantGroup[defaultValue]) {\n safelist.push(variantGroup[defaultValue]);\n }\n });\n }\n });\n });\n }\n\n // Add classes for props passed to internal components with literal values\n Object.entries(componentInfo.internalComponentProps).forEach(\n ([_internalCompName, propsRecord]) => {\n Object.entries(propsRecord).forEach(([propName, propValues]) => {\n if (propName === 'className') {\n propValues.forEach((propValue) => {\n propValue\n .split(/\\s+/)\n .filter(Boolean)\n .forEach((cls) => safelist.push(cls));\n });\n return;\n }\n\n const variantGroup = variants[propName as keyof typeof variants];\n if (variantGroup) {\n propValues.forEach((propValue) => {\n const cls = (variantGroup as Record<string, string>)[propValue];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n });\n }\n });\n },\n );\n\n Object.entries(componentInfo.runtimeConfigInternalComponentProps ?? {}).forEach(\n ([_internalCompName, propsRecord]) => {\n Object.entries(propsRecord).forEach(([propName, selectors]) => {\n const variantGroup = variants[propName as keyof typeof variants];\n if (!variantGroup) {\n return;\n }\n\n selectors.forEach((selector) => {\n resolveRuntimeSelectorValues(selector, componentInfo, userProps, options).forEach(\n (value) => {\n const cls = (variantGroup as Record<string, string>)[value];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n },\n );\n });\n });\n },\n );\n\n // Add classes for explicitly used props\n [...userProps.entries()].forEach(([propName, usedValues]) => {\n if (propName === 'className') {\n [...usedValues].forEach((value) => {\n value\n .split(/\\s+/)\n .filter(Boolean)\n .forEach((cls: string) => safelist.push(cls));\n });\n return;\n }\n\n // First try direct lookup (for Box-style props like backgroundColor)\n const variantGroup = variants[propName as keyof typeof variants];\n if (variantGroup) {\n [...usedValues].forEach((value) => {\n const cls = (variantGroup as Record<string, string>)[value];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n });\n }\n\n // Check if this prop maps to variant keys in this component or its internal components\n // This handles cases like Avatar where size prop mapping is in internal AvatarIcon,\n // and Text where variant -> fontFamily, fontSize, fontWeight, lineHeight, etc.\n const componentsToCheck = [\n componentInfo,\n ...getComponentWithDeps(componentInfo.name).slice(1),\n ];\n componentsToCheck.forEach((comp) => {\n const variantKeys = getVariantKeysForProp(comp, propName);\n if (variantKeys.length > 0) {\n variantKeys.forEach((variantKey) => {\n const mappedVariantGroup = variants[variantKey as keyof typeof variants];\n if (mappedVariantGroup) {\n [...usedValues].forEach((value) => {\n const cls = (mappedVariantGroup as Record<string, string>)[value];\n if (cls) {\n safelist.push(cls.replaceAll('\\\\', ''));\n }\n });\n }\n });\n }\n });\n });\n\n unresolvedSpreadProps.forEach((propName) => {\n addVariantGroupClasses(\n variants[propName as keyof typeof variants] ?? autoVariantsCache[propName],\n safelist,\n );\n\n const componentsToCheck = [\n componentInfo,\n ...getComponentWithDeps(componentInfo.name).slice(1),\n ];\n componentsToCheck.forEach((comp) => {\n const variantKeys = getVariantKeysForProp(comp, propName);\n variantKeys.forEach((variantKey) => {\n addVariantGroupClasses(\n variants[variantKey as keyof typeof variants] ?? autoVariantsCache[variantKey],\n safelist,\n );\n });\n });\n });\n });\n\n if (options.includeAllClassNamePrimitives) {\n safelist.push(...extractClassNamePrimitives(sourceFile));\n }\n\n // Deduplicate\n const finalSafelist = [...new Set(safelist)];\n\n stats.timeMs = Math.round(performance.now() - startTime);\n stats.classesGenerated = finalSafelist.length;\n\n return {\n safelist: finalSafelist,\n imports,\n components: [...seenComponents],\n stats,\n };\n};\n\n/**\n * Find JSX references for a component in the source file\n */\nconst findComponentReferences = (\n sourceFile: ReturnType<Project['createSourceFile']>,\n componentName: string,\n): JsxElementWithAttributes[] => {\n const references: JsxElementWithAttributes[] = [];\n const seenTags = new Set<string>();\n\n const collectMatchingTags = (localName: string): void => {\n sourceFile\n .getDescendants()\n .filter(\n (node): node is JsxElementWithAttributes =>\n Node.isJsxOpeningElement(node) || Node.isJsxSelfClosingElement(node),\n )\n .forEach((node) => {\n const tagName = node.getTagNameNode().getText();\n if (tagName === localName || tagName.startsWith(`${localName}.`)) {\n const key = `${tagName}:${node.getStart()}`;\n if (!seenTags.has(key)) {\n seenTags.add(key);\n references.push(node);\n }\n }\n });\n };\n\n sourceFile.getImportDeclarations().forEach((importDecl) => {\n const moduleSpec = getModuleSpecifierValue(importDecl);\n if (!isUdsComponentModule(moduleSpec)) {\n return;\n }\n\n importDecl.getNamedImports().forEach((namedImport) => {\n if (\n namedImport.getName() !== componentName ||\n isTypeOnlyNamedImport(importDecl, componentName)\n ) {\n return;\n }\n\n const localName = namedImport.getAliasNode()?.getText() ?? componentName;\n const identifier = namedImport.getFirstDescendantByKindOrThrow(ts.SyntaxKind.Identifier);\n\n findJsxReferences(identifier).forEach((reference) => {\n const key = `${reference.getTagNameNode().getText()}:${reference.getStart()}`;\n if (!seenTags.has(key)) {\n seenTags.add(key);\n references.push(reference);\n }\n });\n\n collectMatchingTags(localName);\n });\n });\n\n return references;\n};\n\n/**\n * Extract props from a JSX reference.\n */\nconst extractPropsFromReference = (\n reference: JsxElementWithAttributes,\n stats: PurgeStats,\n sourceFile: ReturnType<Project['createSourceFile']>,\n): Array<{ propName: string; values: string[]; fromSpread: boolean }> => {\n const props: Array<{ propName: string; values: string[]; fromSpread: boolean }> = [];\n const attributes = reference.getAttributes();\n\n attributes.forEach((attr) => {\n if (attr.asKind(SyntaxKind.JsxAttribute)) {\n const jsxAttr = attr.asKindOrThrow(SyntaxKind.JsxAttribute);\n const propName = jsxAttr.getNameNode().getText();\n const values: string[] = [];\n\n const initializer = jsxAttr.getInitializer();\n\n // Direct string literal: prop=\"value\"\n if (initializer && Node.isStringLiteral(initializer)) {\n values.push(initializer.getLiteralText());\n stats.expressionsResolved++;\n } else if (initializer && initializer.asKind(SyntaxKind.JsxExpression)) {\n // JSX expression: prop={expression}\n // Use extractStringLiterals to handle ternaries, nullish, OR, etc.\n const jsxExpr = initializer.asKindOrThrow(SyntaxKind.JsxExpression);\n const expression = jsxExpr.getExpression();\n if (expression) {\n const resolved = extractStringLiterals(expression);\n values.push(...resolved);\n if (resolved.length > 0) {\n stats.expressionsResolved++;\n }\n }\n }\n\n props.push({ propName, values, fromSpread: false });\n }\n\n if (attr.asKind(SyntaxKind.JsxSpreadAttribute)) {\n stats.spreadsTraced++;\n\n const spreadAttr = attr.asKindOrThrow(SyntaxKind.JsxSpreadAttribute);\n const expression = spreadAttr.getExpression();\n const spreadName = expression.getText();\n\n const resolvedSpreadProps = traceSpreadInFile(spreadName, sourceFile);\n\n resolvedSpreadProps.forEach(([propName, values]) => {\n props.push({ propName, values, fromSpread: true });\n });\n }\n });\n\n return props;\n};\n\n/**\n * Trace spread props to their source within the same file.\n */\nconst traceSpreadInFile = (\n spreadName: string,\n sourceFile: ReturnType<Project['createSourceFile']>,\n): Array<[string, string[]]> => {\n const props = new Map<string, Set<string>>();\n\n const varDecl = sourceFile\n .getDescendantsOfKind(SyntaxKind.VariableDeclaration)\n .find((declaration) => declaration.getName() === spreadName);\n if (!varDecl) {\n return [];\n }\n\n const initializer = varDecl.getInitializer();\n if (!initializer) {\n return [];\n }\n\n getSpreadObjectLiteralCandidates(initializer).forEach((objLiteral) => {\n objLiteral.getProperties().forEach((prop) => {\n if (!prop.asKind(SyntaxKind.PropertyAssignment)) {\n return;\n }\n\n const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);\n const propName = propAssign.getName();\n const propInit = propAssign.getInitializer();\n const values = propInit ? extractStringLiterals(propInit) : [];\n const existingValues = props.get(propName) ?? new Set<string>();\n\n values.forEach((value) => existingValues.add(value));\n props.set(propName, existingValues);\n });\n });\n\n return [...props.entries()].map(([propName, values]) => [propName, [...values]]);\n};\n\nconst getSpreadObjectLiteralCandidates = (node: Node): ObjectLiteralExpression[] => {\n if (Node.isObjectLiteralExpression(node)) {\n return [node];\n }\n\n if (Node.isParenthesizedExpression(node)) {\n return getSpreadObjectLiteralCandidates(node.getExpression());\n }\n\n if (Node.isAsExpression(node) || Node.isTypeAssertion(node) || Node.isSatisfiesExpression(node)) {\n return getSpreadObjectLiteralCandidates(node.getExpression());\n }\n\n if (Node.isConditionalExpression(node)) {\n return [\n ...getSpreadObjectLiteralCandidates(node.getWhenTrue()),\n ...getSpreadObjectLiteralCandidates(node.getWhenFalse()),\n ];\n }\n\n return [];\n};\n\n/**\n * Extract props from getStyles() calls in user code.\n * This handles cases like:\n * const styles = getStyles({ backgroundColor: 'brand', spacing: '4' });\n */\nconst extractGetStylesCalls = (\n sourceFile: ReturnType<Project['createSourceFile']>,\n stats: PurgeStats,\n\n variants: Record<string, Record<string, string>>,\n): Map<string, Set<string>> => {\n const props = new Map<string, Set<string>>();\n\n const VALID_VARIANTS = new Set(Object.keys(variants));\n\n // Find all getStyles() call expressions\n const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n\n callExpressions.forEach((call) => {\n const expression = call.getExpression();\n if (expression.getText() !== 'getStyles') {\n return;\n }\n\n const args = call.getArguments();\n if (args.length === 0) {\n return;\n }\n\n const firstArg = args[0];\n if (!firstArg.asKind(SyntaxKind.ObjectLiteralExpression)) {\n return;\n }\n\n const objLiteral = firstArg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);\n\n objLiteral.getProperties().forEach((prop) => {\n if (prop.asKind(SyntaxKind.PropertyAssignment)) {\n const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);\n const propName = propAssign.getName();\n const propInit = propAssign.getInitializer();\n\n if (propInit && VALID_VARIANTS.has(propName)) {\n const values = extractStringLiterals(propInit);\n if (values.length > 0) {\n const existing = props.get(propName) ?? new Set();\n values.forEach((v) => existing.add(v));\n props.set(propName, existing);\n stats.expressionsResolved++;\n }\n }\n } else if (prop.asKind(SyntaxKind.ShorthandPropertyAssignment)) {\n // Handle shorthand like { backgroundColor } where backgroundColor is a variable\n const shorthand = prop.asKindOrThrow(SyntaxKind.ShorthandPropertyAssignment);\n const propName = shorthand.getName();\n\n if (VALID_VARIANTS.has(propName)) {\n // Try to trace the variable\n const nameNode = shorthand.getNameNode();\n const values = extractStringLiterals(nameNode);\n if (values.length > 0) {\n const existing = props.get(propName) ?? new Set();\n values.forEach((v) => existing.add(v));\n props.set(propName, existing);\n stats.expressionsResolved++;\n }\n }\n }\n });\n });\n\n return props;\n};\n\nexport type { PurgeFromCodeOptions, PurgeFromCodeResult, RuntimeConfigValues, VariantDefaults };\nexport { purgeFromCodeOptimized };\n"],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
3
  const require_entryPoints = require('../../../utils/entryPoints.cjs');
4
4
  const require_index = require('../../../motion-tokens/dist/index.cjs');
5
+ const require_hookMetadata = require('../../../runtimeConfig/hookMetadata.cjs');
5
6
  let node_fs = require("node:fs");
6
7
  let node_path = require("node:path");
7
8
  node_path = require_runtime.__toESM(node_path);
@@ -67,6 +68,72 @@ const addPropToVariantKeyMapping = (propToVariantKeys, propName, variantKey) =>
67
68
  const existing = propToVariantKeys.get(propName) ?? [];
68
69
  if (!existing.includes(variantKey)) propToVariantKeys.set(propName, [...existing, variantKey]);
69
70
  };
71
+ const addRuntimeSelector = (target, key, selector) => {
72
+ const existing = target.get(key) ?? [];
73
+ if (!existing.includes(selector)) target.set(key, [...existing, selector]);
74
+ };
75
+ const getExpressionWithoutWrappers = (node) => {
76
+ if (ts_morph.Node.isParenthesizedExpression(node)) return getExpressionWithoutWrappers(node.getExpression());
77
+ if (ts_morph.Node.isAsExpression(node) || ts_morph.Node.isTypeAssertion(node) || ts_morph.Node.isSatisfiesExpression(node)) return getExpressionWithoutWrappers(node.getExpression());
78
+ return node;
79
+ };
80
+ const applyRuntimeSelectorIndex = (selector, indexKey, isIdentifierIndex = false) => {
81
+ if (selector.includes("${")) return selector;
82
+ return isIdentifierIndex ? selector + ".${" + indexKey + "}" : `${selector}.${indexKey}`;
83
+ };
84
+ const resolveRuntimeBindingFromExpression = (expr, runtimeBindings) => {
85
+ const normalized = getExpressionWithoutWrappers(expr);
86
+ if (ts_morph.Node.isIdentifier(normalized)) return runtimeBindings.get(normalized.getText()) ?? null;
87
+ if (ts_morph.Node.isElementAccessExpression(normalized)) {
88
+ const target = resolveRuntimeBindingFromExpression(normalized.getExpression(), runtimeBindings);
89
+ if (!target) return null;
90
+ const argumentExpression = normalized.getArgumentExpression();
91
+ if (!argumentExpression) return null;
92
+ const argument = getExpressionWithoutWrappers(argumentExpression);
93
+ if (ts_morph.Node.isStringLiteral(argument)) return { selector: applyRuntimeSelectorIndex(target.selector, argument.getLiteralValue()) };
94
+ if (ts_morph.Node.isIdentifier(argument)) return { selector: applyRuntimeSelectorIndex(target.selector, argument.getText(), true) };
95
+ }
96
+ if (ts_morph.Node.isPropertyAccessExpression(normalized)) {
97
+ const target = resolveRuntimeBindingFromExpression(normalized.getExpression(), runtimeBindings);
98
+ if (!target) return null;
99
+ return { selector: applyRuntimeSelectorIndex(target.selector, normalized.getName()) };
100
+ }
101
+ return null;
102
+ };
103
+ const collectRuntimeSelectorsFromExpression = (expr, runtimeBindings) => {
104
+ const normalized = getExpressionWithoutWrappers(expr);
105
+ const resolvedBinding = resolveRuntimeBindingFromExpression(normalized, runtimeBindings);
106
+ if (resolvedBinding) return [resolvedBinding.selector];
107
+ if (ts_morph.Node.isConditionalExpression(normalized)) return [...collectRuntimeSelectorsFromExpression(normalized.getWhenTrue(), runtimeBindings), ...collectRuntimeSelectorsFromExpression(normalized.getWhenFalse(), runtimeBindings)];
108
+ if (ts_morph.Node.isBinaryExpression(normalized)) return [...collectRuntimeSelectorsFromExpression(normalized.getLeft(), runtimeBindings), ...collectRuntimeSelectorsFromExpression(normalized.getRight(), runtimeBindings)];
109
+ return [];
110
+ };
111
+ const collectRuntimeConfigBindings = (sourceFile, runtimeBindings, runtimeConfigDefaultProps) => {
112
+ sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.VariableDeclaration).forEach((declaration) => {
113
+ const initializer = declaration.getInitializer();
114
+ if (!initializer) return;
115
+ const normalizedInitializer = getExpressionWithoutWrappers(initializer);
116
+ const nameNode = declaration.getNameNode();
117
+ if (ts_morph.Node.isObjectBindingPattern(nameNode) && ts_morph.Node.isCallExpression(normalizedInitializer)) {
118
+ const hookConfig = require_hookMetadata.getRuntimeHookConfig(normalizedInitializer.getExpression().getText());
119
+ if (!hookConfig) return;
120
+ Object.entries(hookConfig.defaultProps).forEach(([propName, selector]) => {
121
+ runtimeConfigDefaultProps.set(propName, selector);
122
+ });
123
+ nameNode.getElements().forEach((element) => {
124
+ const fieldName = element.getPropertyNameNode()?.getText() ?? element.getName();
125
+ const localName = element.getName();
126
+ const fieldConfig = hookConfig.fields[fieldName];
127
+ if (!fieldConfig) return;
128
+ runtimeBindings.set(localName, { selector: fieldConfig.bindingSelector });
129
+ });
130
+ return;
131
+ }
132
+ if (!ts_morph.Node.isIdentifier(nameNode)) return;
133
+ const resolvedBinding = resolveRuntimeBindingFromExpression(normalizedInitializer, runtimeBindings);
134
+ if (resolvedBinding) runtimeBindings.set(nameNode.getText(), resolvedBinding);
135
+ });
136
+ };
70
137
  const extractFallbackIdentifier = (initializer) => {
71
138
  if (!ts_morph.Node.isBinaryExpression(initializer)) return null;
72
139
  const operatorKind = initializer.getOperatorToken().getKind();
@@ -120,11 +187,16 @@ const analyzeComponent = (project, componentPath) => {
120
187
  const internalComponents = [];
121
188
  const internalComponentProps = /* @__PURE__ */ new Map();
122
189
  const propToVariantKeys = /* @__PURE__ */ new Map();
190
+ const runtimeConfigDefaultProps = /* @__PURE__ */ new Map();
191
+ const runtimeConfigGetStyles = /* @__PURE__ */ new Map();
192
+ const runtimeConfigInternalComponentProps = /* @__PURE__ */ new Map();
193
+ const runtimeBindings = /* @__PURE__ */ new Map();
123
194
  collectComponentDefaultsAndProps(sourceFile, defaultProps, componentPropNames);
124
- collectGetStylesMetadata(sourceFile, styleProps, getStylesLiterals, propToVariantKeys);
195
+ collectRuntimeConfigBindings(sourceFile, runtimeBindings, runtimeConfigDefaultProps);
196
+ collectGetStylesMetadata(sourceFile, styleProps, getStylesLiterals, propToVariantKeys, runtimeBindings, runtimeConfigGetStyles);
125
197
  collectCxLiterals(sourceFile, cxLiterals);
126
198
  collectIntrinsicClassNameLiterals(sourceFile, cxLiterals);
127
- extractInternalComponents(sourceFile, internalComponents, internalComponentProps, propToVariantKeys, componentPropNames);
199
+ extractInternalComponents(sourceFile, internalComponents, internalComponentProps, runtimeConfigInternalComponentProps, propToVariantKeys, componentPropNames, runtimeBindings);
128
200
  return {
129
201
  name: componentName,
130
202
  filePath: componentPath,
@@ -135,6 +207,9 @@ const analyzeComponent = (project, componentPath) => {
135
207
  internalComponents,
136
208
  internalComponentProps,
137
209
  propToVariantKeys,
210
+ runtimeConfigDefaultProps,
211
+ runtimeConfigGetStyles,
212
+ runtimeConfigInternalComponentProps,
138
213
  motionVarPrefixes: extractMotionVarPrefixes(sourceFile)
139
214
  };
140
215
  };
@@ -175,20 +250,23 @@ const storeVariantLiteralValues = (variantKey, literalValues, getStylesLiterals)
175
250
  getStylesLiterals.set(literalKey, value);
176
251
  });
177
252
  };
178
- const handleGetStylesPropertyAssignment = (prop, styleProps, getStylesLiterals, propToVariantKeys) => {
253
+ const handleGetStylesPropertyAssignment = (prop, styleProps, getStylesLiterals, propToVariantKeys, runtimeBindings, runtimeConfigGetStyles) => {
179
254
  const variantKey = prop.getName();
180
255
  addStyleProp(styleProps, variantKey);
181
256
  const initializer = prop.getInitializer();
182
257
  if (!initializer) return;
183
258
  if (ts_morph.Node.isStringLiteral(initializer)) getStylesLiterals.set(variantKey, initializer.getLiteralValue());
184
259
  if (ts_morph.Node.isIdentifier(initializer)) addPropToVariantKeyMapping(propToVariantKeys, initializer.getText(), variantKey);
260
+ collectRuntimeSelectorsFromExpression(initializer, runtimeBindings).forEach((selector) => {
261
+ addRuntimeSelector(runtimeConfigGetStyles, variantKey, selector);
262
+ });
185
263
  const fallbackIdentifier = extractFallbackIdentifier(initializer);
186
264
  if (fallbackIdentifier) addPropToVariantKeyMapping(propToVariantKeys, fallbackIdentifier, variantKey);
187
265
  if (ts_morph.Node.isConditionalExpression(initializer)) storeVariantLiteralValues(variantKey, [...extractConditionalStringLiterals(initializer.getWhenTrue()), ...extractConditionalStringLiterals(initializer.getWhenFalse())], getStylesLiterals);
188
266
  };
189
- const handleGetStylesObjectProperty = (prop, styleProps, getStylesLiterals, propToVariantKeys, sourceFile) => {
267
+ const handleGetStylesObjectProperty = (prop, styleProps, getStylesLiterals, propToVariantKeys, sourceFile, runtimeBindings, runtimeConfigGetStyles) => {
190
268
  if (ts_morph.Node.isPropertyAssignment(prop)) {
191
- handleGetStylesPropertyAssignment(prop, styleProps, getStylesLiterals, propToVariantKeys);
269
+ handleGetStylesPropertyAssignment(prop, styleProps, getStylesLiterals, propToVariantKeys, runtimeBindings, runtimeConfigGetStyles);
192
270
  return;
193
271
  }
194
272
  if (ts_morph.Node.isShorthandPropertyAssignment(prop)) {
@@ -200,12 +278,12 @@ const handleGetStylesObjectProperty = (prop, styleProps, getStylesLiterals, prop
200
278
  if (objectLiteral) analyzeObjectForVariantMappings(objectLiteral, styleProps, getStylesLiterals, propToVariantKeys, sourceFile);
201
279
  }
202
280
  };
203
- const collectGetStylesMetadata = (sourceFile, styleProps, getStylesLiterals, propToVariantKeys) => {
281
+ const collectGetStylesMetadata = (sourceFile, styleProps, getStylesLiterals, propToVariantKeys, runtimeBindings, runtimeConfigGetStyles) => {
204
282
  sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.CallExpression).filter((call) => call.getExpression().getText() === "getStyles").forEach((call) => {
205
283
  const args = call.getArguments();
206
284
  if (args.length === 0 || !ts_morph.Node.isObjectLiteralExpression(args[0])) return;
207
285
  args[0].getProperties().forEach((prop) => {
208
- handleGetStylesObjectProperty(prop, styleProps, getStylesLiterals, propToVariantKeys, sourceFile);
286
+ handleGetStylesObjectProperty(prop, styleProps, getStylesLiterals, propToVariantKeys, sourceFile, runtimeBindings, runtimeConfigGetStyles);
209
287
  });
210
288
  });
211
289
  };
@@ -241,9 +319,9 @@ const collectIntrinsicClassNameLiterals = (sourceFile, cxLiterals) => {
241
319
  * Extract UDS components used internally in the file and their prop values.
242
320
  * Also detects prop aliasing (e.g., columnGap={gap} means gap -> columnGap).
243
321
  */
244
- const extractInternalComponents = (sourceFile, internalComponents, internalComponentProps, propToVariantKeys, componentProps) => {
322
+ const extractInternalComponents = (sourceFile, internalComponents, internalComponentProps, runtimeConfigInternalComponentProps, propToVariantKeys, componentProps, runtimeBindings) => {
245
323
  collectImportedInternalComponents(sourceFile, internalComponents);
246
- collectInternalComponentUsages(sourceFile, internalComponents, internalComponentProps, propToVariantKeys, componentProps);
324
+ collectInternalComponentUsages(sourceFile, internalComponents, internalComponentProps, runtimeConfigInternalComponentProps, propToVariantKeys, componentProps, runtimeBindings);
247
325
  };
248
326
  const isInternalUdsModule = (moduleSpec) => {
249
327
  return (moduleSpec.startsWith("@yahoo/uds") || moduleSpec.startsWith("../") || moduleSpec.startsWith("./")) && (moduleSpec.includes("/components/") || moduleSpec === "@yahoo/uds");
@@ -294,12 +372,23 @@ const extractJsxAttributeLiteralValues = (attr, componentProps, propToVariantKey
294
372
  values: []
295
373
  };
296
374
  };
297
- const collectInternalComponentUsages = (sourceFile, internalComponents, internalComponentProps, propToVariantKeys, componentProps) => {
375
+ const collectInternalComponentUsages = (sourceFile, internalComponents, internalComponentProps, runtimeConfigInternalComponentProps, propToVariantKeys, componentProps, runtimeBindings) => {
298
376
  [...sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.JsxSelfClosingElement), ...sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.JsxOpeningElement)].forEach((element) => {
299
377
  const tagName = element.getTagNameNode().getText();
300
378
  if (!/^[A-Z]/.test(tagName)) return;
301
379
  pushUniqueComponentName(internalComponents, tagName);
302
380
  element.getAttributes().forEach((attr) => {
381
+ if (ts_morph.Node.isJsxAttribute(attr)) {
382
+ const initializer = attr.getInitializer();
383
+ const expression = initializer && ts_morph.Node.isJsxExpression(initializer) ? initializer.getExpression() : void 0;
384
+ const runtimeSelectors = expression ? collectRuntimeSelectorsFromExpression(expression, runtimeBindings) : [];
385
+ if (runtimeSelectors.length > 0) {
386
+ const runtimePropsMap = getOrCreateComponentPropsMap(runtimeConfigInternalComponentProps, tagName);
387
+ const runtimePropName = attr.getNameNode().getText();
388
+ const existingRuntimeSelectors = runtimePropsMap.get(runtimePropName) ?? [];
389
+ runtimePropsMap.set(runtimePropName, [...new Set([...existingRuntimeSelectors, ...runtimeSelectors])]);
390
+ }
391
+ }
303
392
  const extracted = extractJsxAttributeLiteralValues(attr, componentProps, propToVariantKeys);
304
393
  if (!extracted || extracted.values.length === 0) return;
305
394
  const componentPropsMap = getOrCreateComponentPropsMap(internalComponentProps, tagName);