@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.
- package/dist/components/client/Popover/Popover.cjs +1 -1
- package/dist/components/client/Popover/Popover.js +1 -1
- package/dist/components/client/Popover/PopoverContent.cjs +12 -17
- package/dist/components/client/Popover/PopoverContent.js +12 -17
- package/dist/components/client/Popover/UDSPopoverConfigProvider.cjs +13 -3
- package/dist/components/client/Popover/UDSPopoverConfigProvider.d.cts +13 -5
- package/dist/components/client/Popover/UDSPopoverConfigProvider.d.ts +13 -5
- package/dist/components/client/Popover/UDSPopoverConfigProvider.js +13 -3
- package/dist/components/client/Toast/UDSToastConfigProvider.d.cts +1 -1
- package/dist/components/client/Toast/UDSToastConfigProvider.d.ts +1 -1
- package/dist/fixtures/dist/index.cjs +1 -2
- package/dist/fixtures/dist/index.js +1 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/runtime/popoverConfig.cjs +2 -0
- package/dist/runtime/popoverConfig.d.cts +3 -1
- package/dist/runtime/popoverConfig.d.ts +3 -1
- package/dist/runtime/popoverConfig.js +2 -0
- package/dist/styles/styler.d.cts +43 -43
- package/dist/styles/styler.d.ts +43 -43
- package/dist/tailwind/dist/commands/generateComponentData.cjs +5 -1
- package/dist/tailwind/dist/commands/generateComponentData.d.cts +3 -0
- package/dist/tailwind/dist/commands/generateComponentData.d.cts.map +1 -1
- package/dist/tailwind/dist/commands/generateComponentData.d.ts +3 -0
- package/dist/tailwind/dist/commands/generateComponentData.d.ts.map +1 -1
- package/dist/tailwind/dist/commands/generateComponentData.js +5 -1
- package/dist/tailwind/dist/commands/generateComponentData.js.map +1 -1
- package/dist/tailwind/dist/css/generate.cjs +2 -1
- package/dist/tailwind/dist/css/generate.d.cts.map +1 -1
- package/dist/tailwind/dist/css/generate.d.ts.map +1 -1
- package/dist/tailwind/dist/css/generate.js +3 -2
- package/dist/tailwind/dist/css/generate.js.map +1 -1
- package/dist/tailwind/dist/css/nodeUtils.cjs +7 -5
- package/dist/tailwind/dist/css/nodeUtils.js +7 -5
- package/dist/tailwind/dist/css/nodeUtils.js.map +1 -1
- package/dist/tailwind/dist/css/runner.cjs +4 -3
- package/dist/tailwind/dist/css/runner.js +5 -4
- package/dist/tailwind/dist/css/runner.js.map +1 -1
- package/dist/tailwind/dist/css/utils.cjs +62 -0
- package/dist/tailwind/dist/css/utils.js +62 -1
- package/dist/tailwind/dist/css/utils.js.map +1 -1
- package/dist/tailwind/dist/fixtures/dist/index.js.map +1 -1
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +104 -19
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.cts +5 -0
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.cts.map +1 -1
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.ts +5 -0
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.ts.map +1 -1
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +104 -19
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.js.map +1 -1
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +99 -10
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +99 -10
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js.map +1 -1
- package/dist/tailwind/dist/runtimeConfig/hookMetadata.cjs +364 -0
- package/dist/tailwind/dist/runtimeConfig/hookMetadata.js +358 -0
- package/dist/tailwind/dist/runtimeConfig/hookMetadata.js.map +1 -0
- package/dist/tailwind/dist/types/dist/index.d.cts.map +1 -1
- package/dist/tailwind/dist/types/dist/index.d.ts.map +1 -1
- package/dist/tokens/index.d.cts +2 -2
- package/dist/tokens/index.d.ts +2 -2
- package/dist/tokens/types.d.cts +2 -2
- package/dist/tokens/types.d.ts +2 -2
- package/dist/types/dist/index.d.cts +2 -1
- package/dist/types/dist/index.d.ts +2 -1
- package/dist/uds/generated/componentData.cjs +915 -628
- package/dist/uds/generated/componentData.js +915 -628
- package/dist/uds/package.cjs +3 -3
- package/dist/uds/package.js +3 -3
- package/generated/componentData.json +1131 -782
- 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
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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.
|
|
342
|
-
if (!varDecl) return
|
|
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
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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":"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"}
|
|
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
|
-
|
|
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);
|