@yahoo/uds 3.114.0 → 3.115.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/automated-config/dist/mapTextVariantFixtureToValue.cjs +12 -1
- package/dist/automated-config/dist/mapTextVariantFixtureToValue.js +12 -1
- package/dist/automated-config/dist/properties.cjs +1 -1
- package/dist/automated-config/dist/properties.js +1 -1
- package/dist/cli/commands/sync.cjs +1 -3
- package/dist/cli/commands/sync.d.cts +1 -1
- package/dist/cli/commands/sync.d.ts +1 -1
- package/dist/cli/commands/sync.js +1 -3
- package/dist/cli/commands/version.cjs +0 -2
- package/dist/cli/commands/version.d.cts +1 -1
- package/dist/cli/commands/version.d.ts +1 -1
- package/dist/cli/commands/version.js +0 -2
- package/dist/cli/dist/cli.cjs +1 -1
- package/dist/cli/dist/cli.js +1 -1
- package/dist/cli/dist/commands/editor-rules.cjs +2 -2
- package/dist/cli/dist/commands/editor-rules.js +2 -2
- package/dist/cli/dist/lib/logger.cjs +66 -0
- package/dist/cli/dist/lib/logger.js +66 -0
- package/dist/cli/dist/utils/rules/config.cjs +1 -1
- package/dist/cli/dist/utils/rules/config.js +1 -1
- package/dist/cli/runner.cjs +11 -2
- package/dist/cli/runner.js +11 -2
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/styles/styler.d.cts +28 -28
- package/dist/styles/styler.d.ts +28 -28
- package/dist/styles/variants.cjs +278 -278
- package/dist/styles/variants.js +278 -278
- package/dist/tailwind/dist/commands/css.cjs +79 -0
- package/dist/tailwind/dist/commands/css.d.ts +3 -0
- package/dist/tailwind/dist/commands/css.helpers.cjs +32 -0
- package/dist/tailwind/dist/commands/css.helpers.js +28 -0
- package/dist/tailwind/dist/commands/css.js +79 -0
- package/dist/tailwind/dist/commands/generateComponentData.cjs +33 -31
- package/dist/tailwind/dist/commands/generateComponentData.d.ts +1 -1
- package/dist/tailwind/dist/commands/generateComponentData.js +33 -31
- package/dist/tailwind/dist/commands/generatePurgeCSSData.d.ts +1 -1
- package/dist/tailwind/dist/commands/purge.cjs +3 -4
- package/dist/tailwind/dist/commands/purge.d.ts +1 -1
- package/dist/tailwind/dist/commands/purge.js +3 -4
- package/dist/tailwind/dist/css/generate.cjs +120 -0
- package/dist/tailwind/dist/css/generate.d.cts +30 -0
- package/dist/tailwind/dist/css/generate.d.ts +31 -0
- package/dist/tailwind/dist/css/generate.helpers.cjs +112 -0
- package/dist/tailwind/dist/css/generate.helpers.js +100 -0
- package/dist/tailwind/dist/css/generate.js +115 -0
- package/dist/tailwind/dist/css/postcss.cjs +35 -0
- package/dist/tailwind/dist/css/postcss.helpers.cjs +27 -0
- package/dist/tailwind/dist/css/postcss.helpers.js +26 -0
- package/dist/tailwind/dist/css/postcss.js +35 -0
- package/dist/tailwind/dist/css/runner.cjs +278 -0
- package/dist/tailwind/dist/css/runner.helpers.cjs +26 -0
- package/dist/tailwind/dist/css/runner.helpers.js +23 -0
- package/dist/tailwind/dist/css/runner.js +275 -0
- package/dist/tailwind/dist/css/theme.cjs +12 -0
- package/dist/tailwind/dist/css/theme.d.cts +66 -0
- package/dist/tailwind/dist/css/theme.d.ts +66 -0
- package/dist/tailwind/dist/css/theme.js +11 -0
- package/dist/tailwind/dist/css/utils.cjs +234 -0
- package/dist/tailwind/dist/css/utils.js +223 -0
- package/dist/tailwind/dist/index.d.cts +1 -0
- package/dist/tailwind/dist/index.d.ts +5 -3
- package/dist/tailwind/dist/purger/legacy/purgeCSS.cjs +4 -3
- package/dist/tailwind/dist/purger/legacy/purgeCSS.js +4 -3
- package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +122 -125
- package/dist/tailwind/dist/purger/optimized/ast/expressions.js +122 -125
- package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +1 -8
- package/dist/tailwind/dist/purger/optimized/ast/jsx.js +1 -8
- package/dist/tailwind/dist/purger/optimized/purge.cjs +11 -10
- package/dist/tailwind/dist/purger/optimized/purge.js +10 -9
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +238 -127
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +238 -127
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +353 -261
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +352 -261
- package/dist/tailwind/dist/purger/optimized/utils/files.cjs +4 -3
- package/dist/tailwind/dist/purger/optimized/utils/files.js +4 -3
- package/dist/tailwind/dist/purger/optimized/utils/safelist.cjs +13 -21
- package/dist/tailwind/dist/purger/optimized/utils/safelist.js +13 -21
- package/dist/tailwind/dist/tailwind/plugins/typography.cjs +41 -13
- package/dist/tailwind/dist/tailwind/plugins/typography.js +41 -13
- package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.cjs +4 -2
- package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.d.cts +10 -1
- package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.d.ts +10 -1
- package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.js +4 -2
- package/dist/tailwind/dist/utils/optimizeCSS.cjs +405 -0
- package/dist/tailwind/dist/utils/optimizeCSS.js +403 -0
- package/dist/tailwind/dist/utils/postcssPreserveVars.cjs +67 -0
- package/dist/tailwind/dist/utils/postcssPreserveVars.js +65 -0
- package/dist/tailwind/dist/utils/tsMorph.cjs +1 -1
- package/dist/uds/generated/componentData.cjs +1244 -1208
- package/dist/uds/generated/componentData.js +1244 -1208
- package/dist/uds/package.cjs +10 -4
- package/dist/uds/package.js +10 -4
- package/generated/componentData.json +2683 -0
- package/generated/tailwindPurge.ts +4591 -0
- package/package.json +7 -4
|
@@ -8,20 +8,20 @@ import { Node, Project, SyntaxKind, ts } from "ts-morph";
|
|
|
8
8
|
/**
|
|
9
9
|
* Get component info with all its dependencies (using pre-generated data)
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
const getComponentWithDeps = (componentName) => {
|
|
12
12
|
const visited = /* @__PURE__ */ new Set();
|
|
13
13
|
const result = [];
|
|
14
|
-
|
|
14
|
+
const collect = (name) => {
|
|
15
15
|
if (visited.has(name)) return;
|
|
16
16
|
visited.add(name);
|
|
17
|
-
const info =
|
|
17
|
+
const info = resolveComponentInfo(name);
|
|
18
18
|
if (!info) return;
|
|
19
19
|
result.push(info);
|
|
20
|
-
|
|
21
|
-
}
|
|
20
|
+
info.internalComponents.forEach((depName) => collect(depName));
|
|
21
|
+
};
|
|
22
22
|
collect(componentName);
|
|
23
23
|
return result;
|
|
24
|
-
}
|
|
24
|
+
};
|
|
25
25
|
/**
|
|
26
26
|
* Auto-variants lookup (loaded at module init)
|
|
27
27
|
*/
|
|
@@ -30,10 +30,96 @@ let autoVariantsCache = null;
|
|
|
30
30
|
* Pre-generated component data (loaded at module init)
|
|
31
31
|
*/
|
|
32
32
|
let componentCache = null;
|
|
33
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Map of normalized component name -> actual component cache key
|
|
35
|
+
* Useful when internal components are imported without namespace separators
|
|
36
|
+
* (e.g., MenuItemBase vs Menu.ItemBase).
|
|
37
|
+
*/
|
|
38
|
+
let componentNameLookup = null;
|
|
39
|
+
const buildComponentNameLookup = (data) => {
|
|
40
|
+
const lookup = {};
|
|
41
|
+
Object.keys(data).forEach((key) => {
|
|
42
|
+
const normalized = normalizeComponentName(key);
|
|
43
|
+
if (!lookup[normalized]) lookup[normalized] = key;
|
|
44
|
+
});
|
|
45
|
+
return lookup;
|
|
46
|
+
};
|
|
47
|
+
const resolveComponentInfo = (name) => {
|
|
48
|
+
if (componentCache && componentCache[name]) return componentCache[name];
|
|
49
|
+
const normalized = normalizeComponentName(name);
|
|
50
|
+
const mappedName = componentNameLookup?.[normalized];
|
|
51
|
+
if (mappedName && componentCache) return componentCache[mappedName];
|
|
52
|
+
};
|
|
53
|
+
const getModuleSpecifierValue = (importDecl) => {
|
|
54
|
+
return importDecl.getModuleSpecifierValue() ?? importDecl.getModuleSpecifier().getText().replace(/^['"]|['"]$/g, "");
|
|
55
|
+
};
|
|
56
|
+
const isUdsComponentModule = (moduleSpecifier) => {
|
|
57
|
+
const cleaned = moduleSpecifier.replace(/^['"]|['"]$/g, "");
|
|
58
|
+
return cleaned === "@yahoo/uds" || cleaned.startsWith("@yahoo/uds/");
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Normalize component name to match autoVariants keys (lower camel, no punctuation).
|
|
62
|
+
*/
|
|
63
|
+
const normalizeComponentName = (name) => {
|
|
64
|
+
const cleaned = name.replace(/\W/g, "");
|
|
65
|
+
return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Fallback: infer prop -> variant key mapping from autoVariants when the
|
|
69
|
+
* generated component data misses it (e.g., helpers like buildAvatarRootClasses).
|
|
70
|
+
*/
|
|
71
|
+
const getAutoVariantKeysForProp = (componentName, propName) => {
|
|
72
|
+
if (!autoVariantsCache) return [];
|
|
73
|
+
const segments = componentName.match(/[A-Z][a-z0-9]*/g) ?? [];
|
|
74
|
+
const candidates = new Set([normalizeComponentName(componentName)]);
|
|
75
|
+
if (segments.length > 0) Array.from({ length: segments.length }, (_, index) => index + 1).forEach((i) => {
|
|
76
|
+
const partial = segments.slice(0, i).join("");
|
|
77
|
+
candidates.add(normalizeComponentName(partial));
|
|
78
|
+
});
|
|
79
|
+
const propLower = propName.toLowerCase();
|
|
80
|
+
return Object.keys(autoVariantsCache).filter((key) => {
|
|
81
|
+
const keyLower = key.toLowerCase();
|
|
82
|
+
return Array.from(candidates).some((candidate) => keyLower.startsWith(candidate) && keyLower.includes(propLower));
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
const getVariantKeysForProp = (componentInfo, propName) => {
|
|
86
|
+
const keys = new Set(componentInfo.propToVariantKeys?.[propName] ?? []);
|
|
87
|
+
getAutoVariantKeysForProp(componentInfo.name, propName).forEach((inferred) => keys.add(inferred));
|
|
88
|
+
return [...keys];
|
|
89
|
+
};
|
|
90
|
+
const extractClassNamePrimitives = (sourceFile) => {
|
|
91
|
+
const classes = [];
|
|
92
|
+
sourceFile.getDescendantsOfKind(SyntaxKind.JsxAttribute).forEach((attr) => {
|
|
93
|
+
if (attr.getNameNode().getText() !== "className") return;
|
|
94
|
+
const initializer = attr.getInitializer();
|
|
95
|
+
if (!initializer) return;
|
|
96
|
+
const values = [];
|
|
97
|
+
if (Node.isStringLiteral(initializer)) values.push(initializer.getLiteralText());
|
|
98
|
+
else if (Node.isJsxExpression(initializer)) {
|
|
99
|
+
const expr = initializer.getExpression();
|
|
100
|
+
if (expr) values.push(...extractStringLiterals(expr));
|
|
101
|
+
}
|
|
102
|
+
values.forEach((raw) => {
|
|
103
|
+
classes.push(...raw.split(/\s+/).filter(Boolean));
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAssignment).forEach((prop) => {
|
|
107
|
+
if (prop.getName() !== "className") return;
|
|
108
|
+
const initializer = prop.getInitializer();
|
|
109
|
+
if (!initializer) return;
|
|
110
|
+
extractStringLiterals(initializer).forEach((raw) => {
|
|
111
|
+
classes.push(...raw.split(/\s+/).filter(Boolean));
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
return classes;
|
|
115
|
+
};
|
|
116
|
+
const purgeFromCodeOptimized = async (code, options) => {
|
|
34
117
|
const { variants, autoVariants, componentData } = options;
|
|
35
118
|
if (!autoVariantsCache) autoVariantsCache = autoVariants;
|
|
36
|
-
if (!componentCache)
|
|
119
|
+
if (!componentCache) {
|
|
120
|
+
componentCache = componentData;
|
|
121
|
+
componentNameLookup = buildComponentNameLookup(componentData);
|
|
122
|
+
}
|
|
37
123
|
const startTime = performance.now();
|
|
38
124
|
const sourceFile = new Project({ useInMemoryFileSystem: true }).createSourceFile("input.tsx", code);
|
|
39
125
|
const stats = {
|
|
@@ -44,105 +130,126 @@ async function purgeFromCodeOptimized(code, options) {
|
|
|
44
130
|
expressionsResolved: 0
|
|
45
131
|
};
|
|
46
132
|
const imports = [];
|
|
47
|
-
|
|
133
|
+
sourceFile.getImportDeclarations().forEach((importDecl) => {
|
|
134
|
+
if (isUdsComponentModule(getModuleSpecifierValue(importDecl))) importDecl.getNamedImports().forEach((namedImport) => imports.push(namedImport.getName()));
|
|
135
|
+
});
|
|
48
136
|
const componentProps = /* @__PURE__ */ new Map();
|
|
137
|
+
const referencedComponents = /* @__PURE__ */ new Set();
|
|
49
138
|
const getStylesProps = extractGetStylesCalls(sourceFile, stats, variants);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
139
|
+
imports.forEach((imp) => {
|
|
140
|
+
findComponentReferences(sourceFile, imp).forEach((reference) => {
|
|
141
|
+
const componentName = reference.getTagNameNode().getText() || imp;
|
|
142
|
+
referencedComponents.add(componentName);
|
|
143
|
+
const propsMap = componentProps.get(componentName) ?? /* @__PURE__ */ new Map();
|
|
144
|
+
extractPropsFromReference(reference, stats, sourceFile).forEach(([propName, values]) => {
|
|
145
|
+
if (values.length > 0) {
|
|
146
|
+
const existing = propsMap.get(propName) ?? /* @__PURE__ */ new Set();
|
|
147
|
+
values.forEach((val) => existing.add(val));
|
|
148
|
+
propsMap.set(propName, existing);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
componentProps.set(componentName, propsMap);
|
|
152
|
+
});
|
|
153
|
+
if (!componentProps.has(imp)) componentProps.set(imp, /* @__PURE__ */ new Map());
|
|
154
|
+
});
|
|
63
155
|
const allComponents = [];
|
|
64
156
|
const seenComponents = /* @__PURE__ */ new Set();
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
157
|
+
new Set([...imports, ...referencedComponents]).forEach((componentName) => {
|
|
158
|
+
getComponentWithDeps(componentName).forEach((comp) => {
|
|
159
|
+
if (!seenComponents.has(comp.name)) {
|
|
160
|
+
seenComponents.add(comp.name);
|
|
161
|
+
allComponents.push(comp);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
});
|
|
72
165
|
const safelist = [];
|
|
73
|
-
|
|
166
|
+
[...getStylesProps.entries()].forEach(([propName, values]) => {
|
|
74
167
|
const variantGroup = variants[propName];
|
|
75
|
-
if (variantGroup)
|
|
168
|
+
if (variantGroup) values.forEach((value) => {
|
|
76
169
|
const cls = variantGroup[value];
|
|
77
170
|
if (cls) safelist.push(cls.replaceAll("\\", ""));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
allComponents.forEach((componentInfo) => {
|
|
81
174
|
const userProps = componentProps.get(componentInfo.name) ?? /* @__PURE__ */ new Map();
|
|
82
|
-
|
|
83
|
-
if (userProps.has(propName))
|
|
175
|
+
Object.entries(componentInfo.defaultProps).forEach(([propName, propValue]) => {
|
|
176
|
+
if (userProps.has(propName)) return;
|
|
84
177
|
const variantGroup = variants[propName];
|
|
85
178
|
if (variantGroup) {
|
|
86
179
|
const cls = variantGroup[propValue];
|
|
87
180
|
if (cls) safelist.push(cls.replaceAll("\\", ""));
|
|
88
181
|
}
|
|
89
|
-
const variantKeys = componentInfo
|
|
90
|
-
if (variantKeys)
|
|
91
|
-
const mappedVariantGroup = variants[variantKey];
|
|
182
|
+
const variantKeys = getVariantKeysForProp(componentInfo, propName);
|
|
183
|
+
if (variantKeys.length > 0) variantKeys.forEach((variantKey) => {
|
|
184
|
+
const mappedVariantGroup = variants[variantKey] ?? autoVariantsCache[variantKey];
|
|
92
185
|
if (mappedVariantGroup) {
|
|
93
186
|
const cls = mappedVariantGroup[propValue];
|
|
94
187
|
if (cls) safelist.push(cls.replaceAll("\\", ""));
|
|
95
188
|
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
Object.entries(componentInfo.getStylesLiterals).forEach(([propName, propValue]) => {
|
|
99
192
|
const variantGroup = variants[propName.replace(/:\d+$/, "")];
|
|
100
193
|
if (variantGroup) {
|
|
101
194
|
const cls = variantGroup[propValue];
|
|
102
195
|
if (cls) safelist.push(cls.replaceAll("\\", ""));
|
|
103
196
|
}
|
|
104
|
-
}
|
|
105
|
-
if (componentInfo.cxLiterals)
|
|
197
|
+
});
|
|
198
|
+
if (componentInfo.cxLiterals) componentInfo.cxLiterals.forEach((cls) => safelist.push(cls));
|
|
106
199
|
if (componentInfo.propToVariantKeys) {
|
|
107
200
|
const componentDefaults = options.variantDefaults?.[componentInfo.name] ?? {};
|
|
108
|
-
|
|
109
|
-
if (userProps.has(propName))
|
|
201
|
+
Object.keys(componentInfo.propToVariantKeys).forEach((propName) => {
|
|
202
|
+
if (userProps.has(propName)) return;
|
|
110
203
|
const defaultValue = componentDefaults[propName];
|
|
111
|
-
|
|
204
|
+
getVariantKeysForProp(componentInfo, propName).forEach((variantKey) => {
|
|
112
205
|
const variantGroup = autoVariantsCache[variantKey];
|
|
113
206
|
if (variantGroup) {
|
|
114
207
|
if (variantGroup["default"]) safelist.push(variantGroup["default"]);
|
|
115
208
|
if (defaultValue && variantGroup[defaultValue]) safelist.push(variantGroup[defaultValue]);
|
|
116
209
|
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
210
|
+
});
|
|
211
|
+
});
|
|
119
212
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
213
|
+
Object.entries(componentInfo.internalComponentProps).forEach(([_internalCompName, propsRecord]) => {
|
|
214
|
+
Object.entries(propsRecord).forEach(([propName, propValues]) => {
|
|
215
|
+
if (propName === "className") {
|
|
216
|
+
propValues.forEach((propValue) => {
|
|
217
|
+
propValue.split(/\s+/).filter(Boolean).forEach((cls) => safelist.push(cls));
|
|
218
|
+
});
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const variantGroup = variants[propName];
|
|
222
|
+
if (variantGroup) propValues.forEach((propValue) => {
|
|
223
|
+
const cls = variantGroup[propValue];
|
|
224
|
+
if (cls) safelist.push(cls.replaceAll("\\", ""));
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
[...userProps.entries()].forEach(([propName, usedValues]) => {
|
|
229
|
+
if (propName === "className") {
|
|
230
|
+
[...usedValues].forEach((value) => {
|
|
231
|
+
value.split(/\s+/).filter(Boolean).forEach((cls) => safelist.push(cls));
|
|
232
|
+
});
|
|
233
|
+
return;
|
|
125
234
|
}
|
|
126
|
-
}
|
|
127
|
-
for (const [propName, usedValues] of userProps) {
|
|
128
235
|
const variantGroup = variants[propName];
|
|
129
|
-
if (variantGroup)
|
|
236
|
+
if (variantGroup) [...usedValues].forEach((value) => {
|
|
130
237
|
const cls = variantGroup[value];
|
|
131
238
|
if (cls) safelist.push(cls.replaceAll("\\", ""));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (variantKeys) for (const variantKey of variantKeys) {
|
|
239
|
+
});
|
|
240
|
+
[componentInfo, ...getComponentWithDeps(componentInfo.name).slice(1)].forEach((comp) => {
|
|
241
|
+
const variantKeys = getVariantKeysForProp(comp, propName);
|
|
242
|
+
if (variantKeys.length > 0) variantKeys.forEach((variantKey) => {
|
|
137
243
|
const mappedVariantGroup = variants[variantKey];
|
|
138
|
-
if (mappedVariantGroup)
|
|
244
|
+
if (mappedVariantGroup) [...usedValues].forEach((value) => {
|
|
139
245
|
const cls = mappedVariantGroup[value];
|
|
140
246
|
if (cls) safelist.push(cls.replaceAll("\\", ""));
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
if (options.includeAllClassNamePrimitives) safelist.push(...extractClassNamePrimitives(sourceFile));
|
|
146
253
|
const finalSafelist = [...new Set(safelist)];
|
|
147
254
|
stats.timeMs = Math.round(performance.now() - startTime);
|
|
148
255
|
stats.classesGenerated = finalSafelist.length;
|
|
@@ -152,28 +259,29 @@ async function purgeFromCodeOptimized(code, options) {
|
|
|
152
259
|
components: [...seenComponents],
|
|
153
260
|
stats
|
|
154
261
|
};
|
|
155
|
-
}
|
|
262
|
+
};
|
|
156
263
|
/**
|
|
157
264
|
* Find JSX references for a component in the source file
|
|
158
265
|
*/
|
|
159
|
-
|
|
266
|
+
const findComponentReferences = (sourceFile, componentName) => {
|
|
160
267
|
const references = [];
|
|
161
|
-
|
|
162
|
-
if (!
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
268
|
+
sourceFile.getImportDeclarations().forEach((importDecl) => {
|
|
269
|
+
if (!isUdsComponentModule(getModuleSpecifierValue(importDecl))) return;
|
|
270
|
+
importDecl.getNamedImports().forEach((namedImport) => {
|
|
271
|
+
if (namedImport.getName() === componentName) {
|
|
272
|
+
const identifier = namedImport.getFirstDescendantByKindOrThrow(ts.SyntaxKind.Identifier);
|
|
273
|
+
references.push(...findJsxReferences(identifier));
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
});
|
|
168
277
|
return references;
|
|
169
|
-
}
|
|
278
|
+
};
|
|
170
279
|
/**
|
|
171
280
|
* Extract props from a JSX reference.
|
|
172
281
|
*/
|
|
173
|
-
|
|
282
|
+
const extractPropsFromReference = (reference, stats, sourceFile) => {
|
|
174
283
|
const props = [];
|
|
175
|
-
|
|
176
|
-
for (const attr of attributes) {
|
|
284
|
+
reference.getAttributes().forEach((attr) => {
|
|
177
285
|
if (attr.asKind(SyntaxKind.JsxAttribute)) {
|
|
178
286
|
const jsxAttr = attr.asKindOrThrow(SyntaxKind.JsxAttribute);
|
|
179
287
|
const propName = jsxAttr.getNameNode().getText();
|
|
@@ -194,16 +302,17 @@ function extractPropsFromReference(reference, stats, sourceFile) {
|
|
|
194
302
|
}
|
|
195
303
|
if (attr.asKind(SyntaxKind.JsxSpreadAttribute)) {
|
|
196
304
|
stats.spreadsTraced++;
|
|
197
|
-
|
|
198
|
-
|
|
305
|
+
traceSpreadInFile(attr.asKindOrThrow(SyntaxKind.JsxSpreadAttribute).getExpression().getText(), sourceFile).forEach(([propName, values]) => {
|
|
306
|
+
if (values.length > 0) props.push([propName, values]);
|
|
307
|
+
});
|
|
199
308
|
}
|
|
200
|
-
}
|
|
309
|
+
});
|
|
201
310
|
return props;
|
|
202
|
-
}
|
|
311
|
+
};
|
|
203
312
|
/**
|
|
204
313
|
* Trace spread props to their source within the same file.
|
|
205
314
|
*/
|
|
206
|
-
|
|
315
|
+
const traceSpreadInFile = (spreadName, sourceFile) => {
|
|
207
316
|
const props = [];
|
|
208
317
|
const varDecl = sourceFile.getVariableDeclaration(spreadName);
|
|
209
318
|
if (!varDecl) return props;
|
|
@@ -211,62 +320,64 @@ function traceSpreadInFile(spreadName, sourceFile) {
|
|
|
211
320
|
if (!initializer) return props;
|
|
212
321
|
const objLiteral = initializer.asKind(SyntaxKind.ObjectLiteralExpression) ? initializer.asKindOrThrow(SyntaxKind.ObjectLiteralExpression) : initializer.asKind(SyntaxKind.AsExpression) ? initializer.asKindOrThrow(SyntaxKind.AsExpression).getExpression().asKind(SyntaxKind.ObjectLiteralExpression) ? initializer.asKindOrThrow(SyntaxKind.AsExpression).getExpression().asKindOrThrow(SyntaxKind.ObjectLiteralExpression) : null : null;
|
|
213
322
|
if (!objLiteral) return props;
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
323
|
+
objLiteral.getProperties().forEach((prop) => {
|
|
324
|
+
if (prop.asKind(SyntaxKind.PropertyAssignment)) {
|
|
325
|
+
const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);
|
|
326
|
+
const propName = propAssign.getName();
|
|
327
|
+
const propInit = propAssign.getInitializer();
|
|
328
|
+
if (propInit) {
|
|
329
|
+
const values = extractStringLiterals(propInit);
|
|
330
|
+
if (values.length > 0) props.push([propName, values]);
|
|
331
|
+
}
|
|
221
332
|
}
|
|
222
|
-
}
|
|
333
|
+
});
|
|
223
334
|
return props;
|
|
224
|
-
}
|
|
335
|
+
};
|
|
225
336
|
/**
|
|
226
337
|
* Extract props from getStyles() calls in user code.
|
|
227
338
|
* This handles cases like:
|
|
228
339
|
* const styles = getStyles({ backgroundColor: 'brand', spacing: '4' });
|
|
229
340
|
*/
|
|
230
|
-
|
|
341
|
+
const extractGetStylesCalls = (sourceFile, stats, variants) => {
|
|
231
342
|
const props = /* @__PURE__ */ new Map();
|
|
232
343
|
const VALID_VARIANTS = new Set(Object.keys(variants));
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (call.getExpression().getText() !== "getStyles") continue;
|
|
344
|
+
sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).forEach((call) => {
|
|
345
|
+
if (call.getExpression().getText() !== "getStyles") return;
|
|
236
346
|
const args = call.getArguments();
|
|
237
|
-
if (args.length === 0)
|
|
347
|
+
if (args.length === 0) return;
|
|
238
348
|
const firstArg = args[0];
|
|
239
|
-
if (!firstArg.asKind(SyntaxKind.ObjectLiteralExpression))
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
349
|
+
if (!firstArg.asKind(SyntaxKind.ObjectLiteralExpression)) return;
|
|
350
|
+
firstArg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression).getProperties().forEach((prop) => {
|
|
351
|
+
if (prop.asKind(SyntaxKind.PropertyAssignment)) {
|
|
352
|
+
const propAssign = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);
|
|
353
|
+
const propName = propAssign.getName();
|
|
354
|
+
const propInit = propAssign.getInitializer();
|
|
355
|
+
if (propInit && VALID_VARIANTS.has(propName)) {
|
|
356
|
+
const values = extractStringLiterals(propInit);
|
|
357
|
+
if (values.length > 0) {
|
|
358
|
+
const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
|
|
359
|
+
values.forEach((v) => existing.add(v));
|
|
360
|
+
props.set(propName, existing);
|
|
361
|
+
stats.expressionsResolved++;
|
|
362
|
+
}
|
|
252
363
|
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
364
|
+
} else if (prop.asKind(SyntaxKind.ShorthandPropertyAssignment)) {
|
|
365
|
+
const shorthand = prop.asKindOrThrow(SyntaxKind.ShorthandPropertyAssignment);
|
|
366
|
+
const propName = shorthand.getName();
|
|
367
|
+
if (VALID_VARIANTS.has(propName)) {
|
|
368
|
+
const values = extractStringLiterals(shorthand.getNameNode());
|
|
369
|
+
if (values.length > 0) {
|
|
370
|
+
const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
|
|
371
|
+
values.forEach((v) => existing.add(v));
|
|
372
|
+
props.set(propName, existing);
|
|
373
|
+
stats.expressionsResolved++;
|
|
374
|
+
}
|
|
264
375
|
}
|
|
265
376
|
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
377
|
+
});
|
|
378
|
+
});
|
|
268
379
|
return props;
|
|
269
|
-
}
|
|
380
|
+
};
|
|
270
381
|
|
|
271
382
|
//#endregion
|
|
272
383
|
export { purgeFromCodeOptimized };
|