@yahoo/uds 3.171.1 → 3.172.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/automated-config/dist/utils/getConfigVariantProperties.d.cts +2 -2
- package/dist/automated-config/dist/utils/getConfigVariantProperties.d.ts +2 -2
- package/dist/components/client/Popover/UDSPopoverConfigProvider.d.cts +1 -1
- package/dist/components/client/Popover/UDSPopoverConfigProvider.d.ts +1 -1
- package/dist/css/dist/purger/optimized/ast/expressions.cjs +278 -278
- package/dist/css/dist/purger/optimized/ast/expressions.js +278 -278
- package/dist/css/dist/purger/optimized/ast/jsx.cjs +67 -36
- package/dist/css/dist/purger/optimized/ast/jsx.js +67 -35
- package/dist/css/dist/purger/optimized/ast/oxc.cjs +265 -0
- package/dist/css/dist/purger/optimized/ast/oxc.js +253 -0
- package/dist/css/dist/purger/optimized/ast/props.cjs +21 -15
- package/dist/css/dist/purger/optimized/ast/props.js +21 -14
- package/dist/css/dist/purger/optimized/ast/spread.cjs +19 -19
- package/dist/css/dist/purger/optimized/ast/spread.js +19 -18
- package/dist/css/dist/purger/optimized/purgeFromCode.cjs +86 -101
- package/dist/css/dist/purger/optimized/purgeFromCode.js +86 -100
- package/dist/tailwind-internal/dist/utils/getShadowStyles.d.cts +2 -2
- package/dist/tailwind-internal/dist/utils/getShadowStyles.d.ts +2 -2
- package/dist/tailwind-v3/dist/purger/legacy/purgeCSS.cjs +1 -1
- package/dist/tailwind-v3/dist/purger/legacy/purgeCSS.js +1 -1
- package/dist/uds/generated/componentData.cjs +450 -450
- package/dist/uds/generated/componentData.js +450 -450
- package/dist/uds/package.cjs +2 -0
- package/dist/uds/package.js +2 -0
- package/generated/componentData.json +1049 -1049
- package/package.json +3 -1
|
@@ -1,32 +1,17 @@
|
|
|
1
1
|
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
2
|
const require_runtime = require("../../../../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_oxc = require("./oxc.cjs");
|
|
3
4
|
let node_fs = require("node:fs");
|
|
4
5
|
node_fs = require_runtime.__toESM(node_fs, 1);
|
|
5
6
|
let node_path = require("node:path");
|
|
6
7
|
node_path = require_runtime.__toESM(node_path, 1);
|
|
7
|
-
let
|
|
8
|
+
let oxc_resolver = require("oxc-resolver");
|
|
8
9
|
//#region ../css/dist/purger/optimized/ast/expressions.mjs
|
|
9
10
|
/*! © 2026 Yahoo, Inc. UDS CSS v0.0.0-development */
|
|
10
|
-
const
|
|
11
|
-
const importedSourceFileCache = /* @__PURE__ */ new Map();
|
|
11
|
+
const importedSourceCache = /* @__PURE__ */ new Map();
|
|
12
12
|
const tsConfigPathCache = /* @__PURE__ */ new Map();
|
|
13
|
-
const
|
|
13
|
+
const resolverCache = /* @__PURE__ */ new Map();
|
|
14
14
|
const hasImportQuery = (moduleSpecifier) => moduleSpecifier.includes("?");
|
|
15
|
-
const getLocalDefinitionNodes = (node) => {
|
|
16
|
-
if (!ts_morph.Node.isIdentifier(node)) return [];
|
|
17
|
-
const name = node.getText();
|
|
18
|
-
const nodeStart = node.getStart();
|
|
19
|
-
const sourceFile = node.getSourceFile();
|
|
20
|
-
return [
|
|
21
|
-
...sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.VariableDeclaration).filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),
|
|
22
|
-
...sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.Parameter).filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),
|
|
23
|
-
...sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.BindingElement).filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),
|
|
24
|
-
...sourceFile.getFunctions().filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart)
|
|
25
|
-
].sort((left, right) => right.getStart() - left.getStart()).slice(0, 1);
|
|
26
|
-
};
|
|
27
|
-
const getDefinitionNodesSafe = (node) => {
|
|
28
|
-
return getLocalDefinitionNodes(node);
|
|
29
|
-
};
|
|
30
15
|
const isExistingFile = (candidate) => node_fs.default.existsSync(candidate) && node_fs.default.statSync(candidate).isFile();
|
|
31
16
|
const resolveRelativeImportPath = (sourceFilePath, moduleSpecifier) => {
|
|
32
17
|
if (!node_path.default.isAbsolute(sourceFilePath) || !moduleSpecifier.startsWith(".") || hasImportQuery(moduleSpecifier)) return null;
|
|
@@ -71,55 +56,69 @@ const findNearestTypeScriptConfig = (sourceFilePath) => {
|
|
|
71
56
|
currentDir = parentDir;
|
|
72
57
|
}
|
|
73
58
|
};
|
|
74
|
-
const
|
|
59
|
+
const getResolverForConfig = (configPath) => {
|
|
60
|
+
const cached = resolverCache.get(configPath);
|
|
61
|
+
if (cached) return cached;
|
|
62
|
+
const resolver = new oxc_resolver.ResolverFactory({
|
|
63
|
+
tsconfig: {
|
|
64
|
+
configFile: configPath,
|
|
65
|
+
references: "auto"
|
|
66
|
+
},
|
|
67
|
+
extensions: [
|
|
68
|
+
".ts",
|
|
69
|
+
".tsx",
|
|
70
|
+
".mts",
|
|
71
|
+
".cts",
|
|
72
|
+
".js",
|
|
73
|
+
".jsx",
|
|
74
|
+
".mjs",
|
|
75
|
+
".cjs"
|
|
76
|
+
],
|
|
77
|
+
conditionNames: [
|
|
78
|
+
"import",
|
|
79
|
+
"require",
|
|
80
|
+
"node"
|
|
81
|
+
]
|
|
82
|
+
});
|
|
83
|
+
resolverCache.set(configPath, resolver);
|
|
84
|
+
return resolver;
|
|
85
|
+
};
|
|
86
|
+
const resolveConfigImportPath = (sourceFilePath, moduleSpecifier) => {
|
|
87
|
+
if (hasImportQuery(moduleSpecifier)) return null;
|
|
75
88
|
const configPath = findNearestTypeScriptConfig(sourceFilePath);
|
|
76
89
|
if (!configPath) return null;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
90
|
+
try {
|
|
91
|
+
const resolved = getResolverForConfig(configPath).sync(node_path.default.dirname(sourceFilePath), moduleSpecifier).path;
|
|
92
|
+
if (!resolved) return null;
|
|
93
|
+
if (resolved.includes(`${node_path.default.sep}node_modules${node_path.default.sep}`)) return null;
|
|
94
|
+
return isExistingFile(resolved) ? resolved : null;
|
|
95
|
+
} catch {
|
|
82
96
|
return null;
|
|
83
97
|
}
|
|
84
|
-
const parsed = ts_morph.ts.parseJsonConfigFileContent(readResult.config, ts_morph.ts.sys, node_path.default.dirname(configPath));
|
|
85
|
-
const compilerOptions = parsed.options.paths && !parsed.options.baseUrl ? {
|
|
86
|
-
...parsed.options,
|
|
87
|
-
baseUrl: node_path.default.dirname(configPath)
|
|
88
|
-
} : parsed.options;
|
|
89
|
-
compilerOptionsCache.set(configPath, compilerOptions);
|
|
90
|
-
return compilerOptions;
|
|
91
|
-
};
|
|
92
|
-
const resolveConfigImportPath = (sourceFilePath, moduleSpecifier) => {
|
|
93
|
-
if (hasImportQuery(moduleSpecifier)) return null;
|
|
94
|
-
const compilerOptions = getCompilerOptionsForSourceFile(sourceFilePath);
|
|
95
|
-
if (!compilerOptions) return null;
|
|
96
|
-
const resolvedModule = ts_morph.ts.resolveModuleName(moduleSpecifier, sourceFilePath, compilerOptions, ts_morph.ts.sys).resolvedModule;
|
|
97
|
-
if (!resolvedModule) return null;
|
|
98
|
-
return isExistingFile(resolvedModule.resolvedFileName) ? resolvedModule.resolvedFileName : null;
|
|
99
98
|
};
|
|
100
99
|
const resolveImportPath = (sourceFilePath, moduleSpecifier) => moduleSpecifier.startsWith(".") ? resolveRelativeImportPath(sourceFilePath, moduleSpecifier) : resolveConfigImportPath(sourceFilePath, moduleSpecifier);
|
|
101
|
-
const
|
|
102
|
-
const cached =
|
|
100
|
+
const getImportedSource = (filePath) => {
|
|
101
|
+
const cached = importedSourceCache.get(filePath);
|
|
103
102
|
if (cached) return cached;
|
|
104
103
|
if (!node_fs.default.existsSync(filePath)) return null;
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
return
|
|
104
|
+
const source = require_oxc.parseSource(filePath, node_fs.default.readFileSync(filePath, "utf-8"));
|
|
105
|
+
importedSourceCache.set(filePath, source);
|
|
106
|
+
return source;
|
|
108
107
|
};
|
|
109
|
-
const extractImportedIdentifierValues = (node, visited) => {
|
|
110
|
-
if (
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (!
|
|
117
|
-
const resolvedPath = resolveImportPath(
|
|
108
|
+
const extractImportedIdentifierValues = (node, source, visited) => {
|
|
109
|
+
if (node.type !== "Identifier") return [];
|
|
110
|
+
const localName = node.name;
|
|
111
|
+
const entry = source.staticImports.flatMap((staticImport) => staticImport.entries.map((importEntry) => ({
|
|
112
|
+
staticImport,
|
|
113
|
+
importEntry
|
|
114
|
+
}))).find(({ importEntry }) => importEntry.importName.kind === "Name" && importEntry.localName.value === localName);
|
|
115
|
+
if (!entry || !entry.importEntry.importName.name) return [];
|
|
116
|
+
const resolvedPath = resolveImportPath(source.filePath, entry.staticImport.moduleRequest.value);
|
|
118
117
|
if (!resolvedPath) return [];
|
|
119
|
-
const
|
|
120
|
-
if (!
|
|
121
|
-
const initializer =
|
|
122
|
-
return initializer ? extractStringLiterals(initializer, visited) : [];
|
|
118
|
+
const importedSource = getImportedSource(resolvedPath);
|
|
119
|
+
if (!importedSource) return [];
|
|
120
|
+
const initializer = importedSource.topLevelVariables.get(entry.importEntry.importName.name)?.init;
|
|
121
|
+
return initializer ? extractStringLiterals(initializer, importedSource, visited) : [];
|
|
123
122
|
};
|
|
124
123
|
/**
|
|
125
124
|
* Extracts string literal values from an expression.
|
|
@@ -134,93 +133,102 @@ const extractImportedIdentifierValues = (node, visited) => {
|
|
|
134
133
|
* - As expressions: value as Type
|
|
135
134
|
*
|
|
136
135
|
* @param node The expression node to extract values from
|
|
136
|
+
* @param source The parsed source containing the node
|
|
137
137
|
* @param visited Set of visited nodes to prevent infinite recursion
|
|
138
138
|
* @returns Array of extracted string literal values
|
|
139
139
|
*/
|
|
140
|
-
const extractStringLiterals = (node, visited = /* @__PURE__ */ new Set()) => {
|
|
140
|
+
const extractStringLiterals = (node, source, visited = /* @__PURE__ */ new Set()) => {
|
|
141
141
|
if (visited.has(node)) return [];
|
|
142
142
|
visited.add(node);
|
|
143
|
-
|
|
143
|
+
if (node.type === "ChainExpression") return extractStringLiterals(node.expression, source, visited);
|
|
144
|
+
const directValues = extractDirectLiteralValues(node, source);
|
|
144
145
|
if (directValues) return directValues;
|
|
145
|
-
const templateValues = extractTemplateExpressionValues(node, visited);
|
|
146
|
+
const templateValues = extractTemplateExpressionValues(node, source, visited);
|
|
146
147
|
if (templateValues) return templateValues;
|
|
147
|
-
if (
|
|
148
|
-
const binaryValues = extractBinaryExpressionValues(node, visited);
|
|
148
|
+
if (node.type === "ConditionalExpression") return [...extractStringLiterals(node.consequent, source, visited), ...extractStringLiterals(node.alternate, source, visited)];
|
|
149
|
+
const binaryValues = extractBinaryExpressionValues(node, source, visited);
|
|
149
150
|
if (binaryValues) return binaryValues;
|
|
150
|
-
const wrappedExpressionValues = extractWrappedExpressionValues(node, visited);
|
|
151
|
+
const wrappedExpressionValues = extractWrappedExpressionValues(node, source, visited);
|
|
151
152
|
if (wrappedExpressionValues) return wrappedExpressionValues;
|
|
152
|
-
const propertyAccessValues = extractPropertyAccessValues(node, visited);
|
|
153
|
+
const propertyAccessValues = extractPropertyAccessValues(node, source, visited);
|
|
153
154
|
if (propertyAccessValues) return propertyAccessValues;
|
|
154
|
-
const elementAccessValues = extractElementAccessValues(node, visited);
|
|
155
|
+
const elementAccessValues = extractElementAccessValues(node, source, visited);
|
|
155
156
|
if (elementAccessValues) return elementAccessValues;
|
|
156
|
-
const callExpressionValues = extractCallExpressionValues(node, visited);
|
|
157
|
+
const callExpressionValues = extractCallExpressionValues(node, source, visited);
|
|
157
158
|
if (callExpressionValues) return callExpressionValues;
|
|
158
|
-
const identifierValues = extractIdentifierValues(node, visited);
|
|
159
|
+
const identifierValues = extractIdentifierValues(node, source, visited);
|
|
159
160
|
if (identifierValues) return identifierValues;
|
|
160
161
|
return [];
|
|
161
162
|
};
|
|
162
|
-
const extractDirectLiteralValues = (node) => {
|
|
163
|
-
if (
|
|
163
|
+
const extractDirectLiteralValues = (node, _source) => {
|
|
164
|
+
if (require_oxc.isStringLiteral(node)) return [require_oxc.getStringLiteralValue(node)];
|
|
165
|
+
if (require_oxc.isNoSubstitutionTemplate(node) && node.type === "TemplateLiteral") return [node.quasis[0]?.value.cooked ?? ""];
|
|
164
166
|
return null;
|
|
165
167
|
};
|
|
166
|
-
const extractTemplateExpressionValues = (node, visited) => {
|
|
167
|
-
if (
|
|
168
|
-
const parts = [[node.
|
|
169
|
-
node.
|
|
170
|
-
const exprValues = extractStringLiterals(
|
|
171
|
-
const literalText =
|
|
168
|
+
const extractTemplateExpressionValues = (node, source, visited) => {
|
|
169
|
+
if (node.type !== "TemplateLiteral" || node.expressions.length === 0) return null;
|
|
170
|
+
const parts = [[node.quasis[0]?.value.cooked ?? ""]];
|
|
171
|
+
node.expressions.forEach((expression, index) => {
|
|
172
|
+
const exprValues = extractStringLiterals(expression, source, visited);
|
|
173
|
+
const literalText = node.quasis[index + 1]?.value.cooked ?? "";
|
|
172
174
|
parts.push(exprValues.length > 0 ? exprValues.map((value) => `${value}${literalText}`) : ["", literalText]);
|
|
173
175
|
});
|
|
174
176
|
return parts.reduce((acc, segment) => acc.flatMap((base) => segment.map((frag) => `${base}${frag}`)), [""]).filter((value) => value.length > 0);
|
|
175
177
|
};
|
|
176
|
-
const extractBinaryExpressionValues = (node, visited) => {
|
|
177
|
-
if (
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
178
|
+
const extractBinaryExpressionValues = (node, source, visited) => {
|
|
179
|
+
if (node.type === "BinaryExpression") {
|
|
180
|
+
if (node.operator === "+") {
|
|
181
|
+
const left = extractStringLiterals(node.left, source, visited);
|
|
182
|
+
const right = extractStringLiterals(node.right, source, visited);
|
|
183
|
+
const combined = left.flatMap((l) => right.map((r) => `${l}${r}`));
|
|
184
|
+
return combined.length > 0 ? combined : [];
|
|
185
|
+
}
|
|
186
|
+
return [];
|
|
184
187
|
}
|
|
185
|
-
if (
|
|
186
|
-
|
|
188
|
+
if (node.type === "LogicalExpression") {
|
|
189
|
+
if (node.operator === "||" || node.operator === "??") return [...extractStringLiterals(node.left, source, visited), ...extractStringLiterals(node.right, source, visited)];
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
187
193
|
};
|
|
188
|
-
const extractWrappedExpressionValues = (node, visited) => {
|
|
189
|
-
if (
|
|
194
|
+
const extractWrappedExpressionValues = (node, source, visited) => {
|
|
195
|
+
if (node.type === "ParenthesizedExpression" || node.type === "TSAsExpression") return extractStringLiterals(node.expression, source, visited);
|
|
190
196
|
return null;
|
|
191
197
|
};
|
|
192
|
-
const extractPropertyAccessValues = (node, visited) => {
|
|
193
|
-
if (
|
|
194
|
-
|
|
198
|
+
const extractPropertyAccessValues = (node, source, visited) => {
|
|
199
|
+
if (node.type !== "MemberExpression" || node.computed) return null;
|
|
200
|
+
if (node.property.type !== "Identifier") return null;
|
|
201
|
+
const typeValues = extractLiteralValuesFromType(node, source);
|
|
195
202
|
if (typeValues.length > 0) return typeValues;
|
|
196
|
-
const propertyName = node.
|
|
197
|
-
return extractObjectValues(node.
|
|
203
|
+
const propertyName = node.property.name;
|
|
204
|
+
return extractObjectValues(node.object, source, visited).filter((value) => typeof value === "object" && value !== null && propertyName in value).map((value) => value[propertyName]).filter((value) => typeof value === "string");
|
|
198
205
|
};
|
|
199
|
-
const extractElementAccessValues = (node, visited) => {
|
|
200
|
-
if (!
|
|
201
|
-
const typeValues = extractLiteralValuesFromType(node);
|
|
206
|
+
const extractElementAccessValues = (node, source, visited) => {
|
|
207
|
+
if (node.type !== "MemberExpression" || !node.computed) return null;
|
|
208
|
+
const typeValues = extractLiteralValuesFromType(node, source);
|
|
202
209
|
if (typeValues.length > 0) return typeValues;
|
|
203
|
-
return extractObjectValues(node.
|
|
210
|
+
return extractObjectValues(node.object, source, visited).flatMap((value) => {
|
|
204
211
|
if (typeof value === "string") return [value];
|
|
205
212
|
if (typeof value === "object" && value !== null) return Object.values(value).filter((entry) => typeof entry === "string");
|
|
206
213
|
return [];
|
|
207
214
|
});
|
|
208
215
|
};
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
216
|
+
const collectReturnExpressions = (node) => {
|
|
217
|
+
const returns = [];
|
|
218
|
+
require_oxc.forEachDescendant(node, (descendant) => {
|
|
219
|
+
if (descendant.type === "ReturnStatement" && descendant.argument) returns.push(descendant.argument);
|
|
220
|
+
});
|
|
221
|
+
return returns;
|
|
222
|
+
};
|
|
223
|
+
const extractCallExpressionValues = (node, source, visited) => {
|
|
224
|
+
if (node.type !== "CallExpression") return null;
|
|
225
|
+
const callee = node.callee;
|
|
226
|
+
const fromDefinitions = callee.type === "Identifier" ? require_oxc.findLocalDefinitions(source, callee).flatMap((definition) => {
|
|
227
|
+
if (definition.kind === "function") return collectReturnExpressions(definition.node).flatMap((expression) => extractStringLiterals(expression, source, visited));
|
|
228
|
+
if (definition.kind === "variable") return definition.init ? extractFromFunctionLike(definition.init, source, visited) : [];
|
|
221
229
|
return [];
|
|
222
230
|
}) : [];
|
|
223
|
-
const fromArguments = node.
|
|
231
|
+
const fromArguments = node.arguments.flatMap((arg) => extractStringLiterals(arg, source, visited));
|
|
224
232
|
return [...fromDefinitions, ...fromArguments];
|
|
225
233
|
};
|
|
226
234
|
/** Array methods that return (a subset of) the receiver's elements. */
|
|
@@ -238,19 +246,18 @@ const ARRAY_CHAIN_METHODS = new Set([
|
|
|
238
246
|
* If the definition is the first parameter of a `.map()`/`.flatMap()` callback,
|
|
239
247
|
* return the expression being mapped over (the array source).
|
|
240
248
|
*/
|
|
241
|
-
const getMappedArraySource = (definition) => {
|
|
242
|
-
if (!
|
|
243
|
-
const callback = definition.
|
|
244
|
-
if (
|
|
245
|
-
const callExpression =
|
|
246
|
-
if (!callExpression) return null;
|
|
247
|
-
const
|
|
248
|
-
if (
|
|
249
|
-
if (
|
|
250
|
-
if (
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
return expression.getExpression();
|
|
249
|
+
const getMappedArraySource = (definition, source) => {
|
|
250
|
+
if (definition.kind !== "parameter" || !definition.paramFunction) return null;
|
|
251
|
+
const callback = definition.paramFunction;
|
|
252
|
+
if (callback.type !== "ArrowFunctionExpression") return null;
|
|
253
|
+
const callExpression = require_oxc.getParent(source, callback);
|
|
254
|
+
if (!callExpression || callExpression.type !== "CallExpression") return null;
|
|
255
|
+
const callee = callExpression.callee;
|
|
256
|
+
if (callee.type !== "MemberExpression" || callee.computed) return null;
|
|
257
|
+
if (callee.property.type !== "Identifier") return null;
|
|
258
|
+
if (!["map", "flatMap"].includes(callee.property.name)) return null;
|
|
259
|
+
if (definition.paramIndex !== 0) return null;
|
|
260
|
+
return callee.object;
|
|
254
261
|
};
|
|
255
262
|
/**
|
|
256
263
|
* Resolve a node to the object-literal AST nodes it may evaluate to.
|
|
@@ -258,25 +265,23 @@ const getMappedArraySource = (definition) => {
|
|
|
258
265
|
* array-method chains, and `.map()` callback parameters (UDS-2557 follow-up:
|
|
259
266
|
* variant arrays nested inside const structures).
|
|
260
267
|
*/
|
|
261
|
-
const resolveObjectLiteralNodes = (node, visited) => {
|
|
268
|
+
const resolveObjectLiteralNodes = (node, source, visited) => {
|
|
262
269
|
if (visited.has(node)) return [];
|
|
263
270
|
visited.add(node);
|
|
264
|
-
if (
|
|
265
|
-
if (
|
|
266
|
-
if (
|
|
267
|
-
if (
|
|
268
|
-
if (
|
|
269
|
-
|
|
270
|
-
|
|
271
|
+
if (node.type === "ChainExpression") return resolveObjectLiteralNodes(node.expression, source, visited);
|
|
272
|
+
if (node.type === "ObjectExpression") return [node];
|
|
273
|
+
if (node.type === "ParenthesizedExpression" || node.type === "TSAsExpression" || node.type === "TSTypeAssertion" || node.type === "TSSatisfiesExpression") return resolveObjectLiteralNodes(node.expression, source, visited);
|
|
274
|
+
if (node.type === "ArrayExpression") return node.elements.flatMap((element) => element ? resolveObjectLiteralNodes(element, source, visited) : []);
|
|
275
|
+
if (node.type === "MemberExpression" && node.computed) return resolveObjectLiteralNodes(node.object, source, visited);
|
|
276
|
+
if (node.type === "CallExpression") {
|
|
277
|
+
const callee = node.callee;
|
|
278
|
+
if (callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier" && ARRAY_CHAIN_METHODS.has(callee.property.name)) return resolveObjectLiteralNodes(callee.object, source, visited);
|
|
271
279
|
return [];
|
|
272
280
|
}
|
|
273
|
-
if (
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
const mappedSource = getMappedArraySource(definition);
|
|
279
|
-
if (mappedSource) return resolveObjectLiteralNodes(mappedSource, visited);
|
|
281
|
+
if (node.type === "Identifier") return require_oxc.findLocalDefinitions(source, node).flatMap((definition) => {
|
|
282
|
+
if (definition.kind === "variable") return definition.init ? resolveObjectLiteralNodes(definition.init, source, visited) : [];
|
|
283
|
+
const mappedSource = getMappedArraySource(definition, source);
|
|
284
|
+
if (mappedSource) return resolveObjectLiteralNodes(mappedSource, source, visited);
|
|
280
285
|
return [];
|
|
281
286
|
});
|
|
282
287
|
return [];
|
|
@@ -284,74 +289,82 @@ const resolveObjectLiteralNodes = (node, visited) => {
|
|
|
284
289
|
/**
|
|
285
290
|
* Collect the initializers of a named property across object-literal candidates.
|
|
286
291
|
*/
|
|
287
|
-
const getPropertyInitializers = (objectLiterals, propertyName) => objectLiterals.flatMap((obj) => {
|
|
288
|
-
if (
|
|
289
|
-
return obj.
|
|
290
|
-
if (
|
|
291
|
-
|
|
292
|
-
return initializer ? [initializer] : [];
|
|
292
|
+
const getPropertyInitializers = (objectLiterals, propertyName, source) => objectLiterals.flatMap((obj) => {
|
|
293
|
+
if (obj.type !== "ObjectExpression") return [];
|
|
294
|
+
return obj.properties.flatMap((prop) => {
|
|
295
|
+
if (prop.type !== "Property" || prop.shorthand || require_oxc.getPropertyName(source, prop) !== propertyName) return [];
|
|
296
|
+
return prop.value ? [prop.value] : [];
|
|
293
297
|
});
|
|
294
298
|
});
|
|
295
299
|
/**
|
|
296
300
|
* For a destructured binding (e.g. `({ variants }) =>` map param or
|
|
297
301
|
* `const { variants } = GROUPS[0]`), resolve the bound property's initializers.
|
|
298
302
|
*/
|
|
299
|
-
const getBindingElementSources = (definition) => {
|
|
300
|
-
if (
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
303
|
+
const getBindingElementSources = (definition, source) => {
|
|
304
|
+
if (definition.kind !== "binding" || definition.bindingPattern?.type !== "ObjectPattern") return [];
|
|
305
|
+
const propertyName = definition.bindingPropertyName ?? definition.name;
|
|
306
|
+
const pattern = definition.bindingPattern;
|
|
307
|
+
const holder = require_oxc.getParent(source, pattern);
|
|
308
|
+
let arraySource = null;
|
|
309
|
+
if (holder && holder.type === "VariableDeclarator") arraySource = holder.init ?? null;
|
|
310
|
+
else {
|
|
311
|
+
const paramNode = holder && holder.type === "AssignmentPattern" ? holder : pattern;
|
|
312
|
+
const fn = holder && holder.type === "AssignmentPattern" ? require_oxc.getParent(source, holder) : holder;
|
|
313
|
+
if (fn && (fn.type === "ArrowFunctionExpression" || fn.type === "FunctionDeclaration" || fn.type === "FunctionExpression")) {
|
|
314
|
+
const paramIndex = fn.params.indexOf(paramNode);
|
|
315
|
+
if (paramIndex !== -1) arraySource = getMappedArraySource({
|
|
316
|
+
kind: "parameter",
|
|
317
|
+
name: propertyName,
|
|
318
|
+
start: pattern.start,
|
|
319
|
+
node: paramNode,
|
|
320
|
+
init: null,
|
|
321
|
+
typeNode: null,
|
|
322
|
+
paramFunction: fn,
|
|
323
|
+
paramIndex
|
|
324
|
+
}, source);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (!arraySource) return [];
|
|
328
|
+
return getPropertyInitializers(resolveObjectLiteralNodes(arraySource, source, /* @__PURE__ */ new Set()), propertyName, source);
|
|
310
329
|
};
|
|
311
|
-
const extractArrayElementValues = (node, visited) => {
|
|
312
|
-
if (
|
|
313
|
-
if (
|
|
314
|
-
if (
|
|
315
|
-
if (
|
|
316
|
-
if (
|
|
317
|
-
|
|
318
|
-
|
|
330
|
+
const extractArrayElementValues = (node, source, visited) => {
|
|
331
|
+
if (node.type === "ChainExpression") return extractArrayElementValues(node.expression, source, visited);
|
|
332
|
+
if (node.type === "ArrayExpression") return node.elements.flatMap((element) => element ? extractStringLiterals(element, source, visited) : []).filter((value, index, values) => values.indexOf(value) === index);
|
|
333
|
+
if (node.type === "ParenthesizedExpression") return extractArrayElementValues(node.expression, source, visited);
|
|
334
|
+
if (node.type === "TSAsExpression" || node.type === "TSTypeAssertion" || node.type === "TSSatisfiesExpression") return extractArrayElementValues(node.expression, source, visited);
|
|
335
|
+
if (node.type === "MemberExpression" && !node.computed) {
|
|
336
|
+
if (node.property.type !== "Identifier") return [];
|
|
337
|
+
return getPropertyInitializers(resolveObjectLiteralNodes(node.object, source, /* @__PURE__ */ new Set()), node.property.name, source).flatMap((initializer) => extractArrayElementValues(initializer, source, visited)).filter((value, index, values) => values.indexOf(value) === index);
|
|
338
|
+
}
|
|
339
|
+
if (node.type === "CallExpression") {
|
|
340
|
+
const callee = node.callee;
|
|
341
|
+
if (callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier" && ARRAY_CHAIN_METHODS.has(callee.property.name)) return extractArrayElementValues(callee.object, source, visited);
|
|
319
342
|
return [];
|
|
320
343
|
}
|
|
321
|
-
if (
|
|
322
|
-
if (
|
|
323
|
-
|
|
324
|
-
return initializer ? extractArrayElementValues(initializer, visited) : [];
|
|
325
|
-
}
|
|
326
|
-
return getBindingElementSources(definition).flatMap((source) => extractArrayElementValues(source, visited));
|
|
344
|
+
if (node.type === "Identifier") return require_oxc.findLocalDefinitions(source, node).flatMap((definition) => {
|
|
345
|
+
if (definition.kind === "variable") return definition.init ? extractArrayElementValues(definition.init, source, visited) : [];
|
|
346
|
+
return getBindingElementSources(definition, source).flatMap((elementSource) => extractArrayElementValues(elementSource, source, visited));
|
|
327
347
|
}).filter((value, index, values) => values.indexOf(value) === index);
|
|
328
348
|
return [];
|
|
329
349
|
};
|
|
330
|
-
const extractMappedParameterValues = (definition, visited) => {
|
|
331
|
-
const mappedSource = getMappedArraySource(definition);
|
|
350
|
+
const extractMappedParameterValues = (definition, source, visited) => {
|
|
351
|
+
const mappedSource = getMappedArraySource(definition, source);
|
|
332
352
|
if (!mappedSource) return [];
|
|
333
|
-
return extractArrayElementValues(mappedSource, visited);
|
|
353
|
+
return extractArrayElementValues(mappedSource, source, visited);
|
|
334
354
|
};
|
|
335
|
-
const extractIdentifierValues = (node, visited) => {
|
|
336
|
-
if (
|
|
337
|
-
const values =
|
|
338
|
-
const mappedParameterValues = extractMappedParameterValues(definition, visited);
|
|
355
|
+
const extractIdentifierValues = (node, source, visited) => {
|
|
356
|
+
if (node.type !== "Identifier") return null;
|
|
357
|
+
const values = require_oxc.findLocalDefinitions(source, node).flatMap((definition) => {
|
|
358
|
+
const mappedParameterValues = extractMappedParameterValues(definition, source, visited);
|
|
339
359
|
if (mappedParameterValues.length > 0) return mappedParameterValues;
|
|
340
|
-
if (
|
|
341
|
-
|
|
342
|
-
if (
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const
|
|
347
|
-
if (
|
|
348
|
-
const parentInit = parentDecl.getInitializer();
|
|
349
|
-
if (parentInit) {
|
|
350
|
-
const propName = definition.getNameNode().getText();
|
|
351
|
-
const propValues = extractObjectValues(parentInit, new Set(visited)).filter((obj) => typeof obj === "object" && obj !== null && propName in obj).map((obj) => obj[propName]).filter((v) => typeof v === "string");
|
|
352
|
-
if (propValues.length > 0) return propValues;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
360
|
+
if (definition.kind === "variable" || definition.kind === "parameter" || definition.kind === "binding") {
|
|
361
|
+
if (definition.init) return extractStringLiterals(definition.init, source, visited);
|
|
362
|
+
if (definition.kind === "binding" && definition.bindingPattern?.type === "ObjectPattern") {
|
|
363
|
+
const holder = require_oxc.getParent(source, definition.bindingPattern);
|
|
364
|
+
if (holder && holder.type === "VariableDeclarator" && holder.init) {
|
|
365
|
+
const propName = definition.name;
|
|
366
|
+
const propValues = extractObjectValues(holder.init, source, new Set(visited)).filter((obj) => typeof obj === "object" && obj !== null && propName in obj).map((obj) => obj[propName]).filter((v) => typeof v === "string");
|
|
367
|
+
if (propValues.length > 0) return propValues;
|
|
355
368
|
}
|
|
356
369
|
}
|
|
357
370
|
return [];
|
|
@@ -359,25 +372,23 @@ const extractIdentifierValues = (node, visited) => {
|
|
|
359
372
|
return [];
|
|
360
373
|
});
|
|
361
374
|
if (values.length > 0) return values;
|
|
362
|
-
const importedValues = extractImportedIdentifierValues(node, visited);
|
|
375
|
+
const importedValues = extractImportedIdentifierValues(node, source, visited);
|
|
363
376
|
if (importedValues.length > 0) return importedValues;
|
|
364
|
-
return extractLiteralValuesFromType(node);
|
|
377
|
+
return extractLiteralValuesFromType(node, source);
|
|
365
378
|
};
|
|
366
379
|
/**
|
|
367
380
|
* Extract string literals from arrow functions or function expressions
|
|
368
381
|
*/
|
|
369
|
-
const extractFromFunctionLike = (node, visited) => {
|
|
382
|
+
const extractFromFunctionLike = (node, source, visited) => {
|
|
370
383
|
const values = [];
|
|
371
|
-
if (
|
|
372
|
-
const body = node.
|
|
373
|
-
if (
|
|
374
|
-
|
|
375
|
-
if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
|
|
384
|
+
if (node.type === "ArrowFunctionExpression") {
|
|
385
|
+
const body = node.body;
|
|
386
|
+
if (body.type === "BlockStatement") collectReturnExpressions(body).forEach((returnExpr) => {
|
|
387
|
+
values.push(...extractStringLiterals(returnExpr, source, visited));
|
|
376
388
|
});
|
|
377
|
-
else values.push(...extractStringLiterals(body, visited));
|
|
378
|
-
} else if (
|
|
379
|
-
|
|
380
|
-
if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
|
|
389
|
+
else values.push(...extractStringLiterals(body, source, visited));
|
|
390
|
+
} else if (node.type === "FunctionExpression") collectReturnExpressions(node).forEach((returnExpr) => {
|
|
391
|
+
values.push(...extractStringLiterals(returnExpr, source, visited));
|
|
381
392
|
});
|
|
382
393
|
return values;
|
|
383
394
|
};
|
|
@@ -385,19 +396,20 @@ const extractFromFunctionLike = (node, visited) => {
|
|
|
385
396
|
* Extract object literal values from an expression.
|
|
386
397
|
* Returns an array of all possible object values (for union types or indexed access).
|
|
387
398
|
*/
|
|
388
|
-
const extractObjectValues = (node, visited) => {
|
|
399
|
+
const extractObjectValues = (node, source, visited) => {
|
|
389
400
|
if (visited.has(node)) return [];
|
|
390
401
|
visited.add(node);
|
|
402
|
+
if (node.type === "ChainExpression") return extractObjectValues(node.expression, source, visited);
|
|
391
403
|
const values = [];
|
|
392
|
-
if (
|
|
404
|
+
if (node.type === "ObjectExpression") {
|
|
393
405
|
const obj = {};
|
|
394
|
-
node.
|
|
395
|
-
if (
|
|
396
|
-
const name =
|
|
397
|
-
const init = prop.
|
|
398
|
-
if (init &&
|
|
399
|
-
else if (init &&
|
|
400
|
-
const nestedValues = extractObjectValues(init, visited);
|
|
406
|
+
node.properties.forEach((prop) => {
|
|
407
|
+
if (prop.type === "Property" && !prop.shorthand) {
|
|
408
|
+
const name = require_oxc.getPropertyName(source, prop);
|
|
409
|
+
const init = prop.value;
|
|
410
|
+
if (init && require_oxc.isStringLiteral(init)) obj[name] = require_oxc.getStringLiteralValue(init);
|
|
411
|
+
else if (init && init.type === "ObjectExpression") {
|
|
412
|
+
const nestedValues = extractObjectValues(init, source, visited);
|
|
401
413
|
if (nestedValues.length > 0) obj[name] = nestedValues[0];
|
|
402
414
|
}
|
|
403
415
|
}
|
|
@@ -405,58 +417,51 @@ const extractObjectValues = (node, visited) => {
|
|
|
405
417
|
values.push(obj);
|
|
406
418
|
return values;
|
|
407
419
|
}
|
|
408
|
-
if (
|
|
409
|
-
|
|
410
|
-
if (
|
|
411
|
-
const initializer = definition.
|
|
412
|
-
if (initializer)
|
|
413
|
-
|
|
414
|
-
values.push(...extractObjectValues(inner, visited));
|
|
415
|
-
} else values.push(...extractObjectValues(initializer, visited));
|
|
420
|
+
if (node.type === "Identifier") {
|
|
421
|
+
require_oxc.findLocalDefinitions(source, node).forEach((definition) => {
|
|
422
|
+
if (definition.kind === "variable" && definition.init) {
|
|
423
|
+
const initializer = definition.init;
|
|
424
|
+
if (initializer.type === "TSAsExpression") values.push(...extractObjectValues(initializer.expression, source, visited));
|
|
425
|
+
else values.push(...extractObjectValues(initializer, source, visited));
|
|
416
426
|
}
|
|
417
427
|
});
|
|
418
|
-
const enumDecl =
|
|
428
|
+
const enumDecl = source.topLevelEnums.get(node.name);
|
|
419
429
|
if (enumDecl) {
|
|
420
430
|
const obj = {};
|
|
421
|
-
enumDecl.
|
|
422
|
-
const initializer = member.
|
|
423
|
-
if (initializer &&
|
|
431
|
+
enumDecl.body.members.forEach((member) => {
|
|
432
|
+
const initializer = member.initializer;
|
|
433
|
+
if (initializer && require_oxc.isStringLiteral(initializer)) {
|
|
434
|
+
const memberName = member.id.type === "Identifier" ? member.id.name : require_oxc.isStringLiteral(member.id) ? require_oxc.getStringLiteralValue(member.id) : require_oxc.getText(source, member.id);
|
|
435
|
+
obj[memberName] = require_oxc.getStringLiteralValue(initializer);
|
|
436
|
+
}
|
|
424
437
|
});
|
|
425
438
|
if (Object.keys(obj).length > 0) values.push(obj);
|
|
426
439
|
}
|
|
427
440
|
return values;
|
|
428
441
|
}
|
|
429
|
-
if (
|
|
430
|
-
const
|
|
431
|
-
if (
|
|
432
|
-
if (
|
|
433
|
-
|
|
434
|
-
if (returnExpr) values.push(...extractObjectValues(returnExpr, visited));
|
|
442
|
+
if (node.type === "CallExpression") {
|
|
443
|
+
const callee = node.callee;
|
|
444
|
+
if (callee.type === "Identifier") require_oxc.findLocalDefinitions(source, callee).forEach((definition) => {
|
|
445
|
+
if (definition.kind === "function") collectReturnExpressions(definition.node).forEach((returnExpr) => {
|
|
446
|
+
values.push(...extractObjectValues(returnExpr, source, visited));
|
|
435
447
|
});
|
|
436
|
-
if (
|
|
437
|
-
const initializer = definition.
|
|
438
|
-
if (initializer) {
|
|
439
|
-
const
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
} else if (ts_morph.Node.isFunctionExpression(fn)) fn.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement).forEach((returnStmt) => {
|
|
448
|
-
const returnExpr = returnStmt.getExpression();
|
|
449
|
-
if (returnExpr) values.push(...extractObjectValues(returnExpr, visited));
|
|
450
|
-
});
|
|
451
|
-
};
|
|
452
|
-
extractFromFn(initializer);
|
|
453
|
-
}
|
|
448
|
+
if (definition.kind === "variable" && definition.init) {
|
|
449
|
+
const initializer = definition.init;
|
|
450
|
+
if (initializer.type === "ArrowFunctionExpression") {
|
|
451
|
+
const body = initializer.body;
|
|
452
|
+
if (body.type === "BlockStatement") collectReturnExpressions(body).forEach((returnExpr) => {
|
|
453
|
+
values.push(...extractObjectValues(returnExpr, source, visited));
|
|
454
|
+
});
|
|
455
|
+
else values.push(...extractObjectValues(body, source, visited));
|
|
456
|
+
} else if (initializer.type === "FunctionExpression") collectReturnExpressions(initializer).forEach((returnExpr) => {
|
|
457
|
+
values.push(...extractObjectValues(returnExpr, source, visited));
|
|
458
|
+
});
|
|
454
459
|
}
|
|
455
460
|
});
|
|
456
461
|
return values;
|
|
457
462
|
}
|
|
458
|
-
if (
|
|
459
|
-
extractObjectValues(node.
|
|
463
|
+
if (node.type === "MemberExpression" && node.computed) {
|
|
464
|
+
extractObjectValues(node.object, source, visited).forEach((obj) => {
|
|
460
465
|
if (typeof obj === "object" && obj !== null) Object.values(obj).forEach((value) => values.push(value));
|
|
461
466
|
});
|
|
462
467
|
return values;
|
|
@@ -465,46 +470,42 @@ const extractObjectValues = (node, visited) => {
|
|
|
465
470
|
};
|
|
466
471
|
/**
|
|
467
472
|
* Extract string literal values from a TypeScript type annotation AST node.
|
|
468
|
-
* Pure AST traversal —
|
|
473
|
+
* Pure AST traversal — no type checker involved.
|
|
469
474
|
*/
|
|
470
475
|
const extractStringLiteralsFromTypeNode = (typeNode) => {
|
|
471
|
-
if (
|
|
472
|
-
const literal = typeNode.
|
|
473
|
-
if (
|
|
476
|
+
if (typeNode.type === "TSLiteralType") {
|
|
477
|
+
const literal = typeNode.literal;
|
|
478
|
+
if (require_oxc.isStringLiteral(literal)) return [require_oxc.getStringLiteralValue(literal)];
|
|
474
479
|
return [];
|
|
475
480
|
}
|
|
476
|
-
if (
|
|
481
|
+
if (typeNode.type === "TSUnionType") return typeNode.types.flatMap(extractStringLiteralsFromTypeNode);
|
|
477
482
|
return [];
|
|
478
483
|
};
|
|
479
484
|
/**
|
|
480
485
|
* Extract literal values from a TypeScript type annotation (for union types like 'brand' | 'secondary').
|
|
481
|
-
* Uses pure AST traversal instead of the TS type checker
|
|
486
|
+
* Uses pure AST traversal instead of the TS type checker.
|
|
482
487
|
*/
|
|
483
|
-
const extractLiteralValuesFromType = (node) => {
|
|
484
|
-
if (
|
|
485
|
-
const definitions =
|
|
488
|
+
const extractLiteralValuesFromType = (node, source) => {
|
|
489
|
+
if (node.type === "Identifier") {
|
|
490
|
+
const definitions = require_oxc.findLocalDefinitions(source, node);
|
|
486
491
|
for (const def of definitions) {
|
|
487
|
-
if (
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
const values = extractStringLiteralsFromTypeNode(typeNode);
|
|
492
|
+
if (def.kind === "parameter" || def.kind === "variable") {
|
|
493
|
+
if (def.typeNode) {
|
|
494
|
+
const values = extractStringLiteralsFromTypeNode(def.typeNode);
|
|
491
495
|
if (values.length > 0) return values;
|
|
492
496
|
}
|
|
493
497
|
}
|
|
494
|
-
if (
|
|
495
|
-
const
|
|
496
|
-
if (
|
|
497
|
-
const
|
|
498
|
-
if (
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
const
|
|
502
|
-
|
|
503
|
-
const
|
|
504
|
-
if (
|
|
505
|
-
const values = extractStringLiteralsFromTypeNode(memberType);
|
|
506
|
-
if (values.length > 0) return values;
|
|
507
|
-
}
|
|
498
|
+
if (def.kind === "binding" && def.bindingPattern) {
|
|
499
|
+
const holder = require_oxc.getParent(source, def.bindingPattern);
|
|
500
|
+
if (holder && holder.type === "VariableDeclarator") {
|
|
501
|
+
const parentType = holder.id.typeAnnotation?.typeAnnotation;
|
|
502
|
+
if (parentType && parentType.type === "TSTypeLiteral") {
|
|
503
|
+
const propName = def.name;
|
|
504
|
+
for (const member of parentType.members) if (member.type === "TSPropertySignature" && member.key.type === "Identifier" && member.key.name === propName) {
|
|
505
|
+
const memberType = member.typeAnnotation?.typeAnnotation;
|
|
506
|
+
if (memberType) {
|
|
507
|
+
const values = extractStringLiteralsFromTypeNode(memberType);
|
|
508
|
+
if (values.length > 0) return values;
|
|
508
509
|
}
|
|
509
510
|
}
|
|
510
511
|
}
|
|
@@ -512,7 +513,6 @@ const extractLiteralValuesFromType = (node) => {
|
|
|
512
513
|
}
|
|
513
514
|
}
|
|
514
515
|
}
|
|
515
|
-
if (ts_morph.Node.isPropertyAccessExpression(node) || ts_morph.Node.isElementAccessExpression(node)) return [];
|
|
516
516
|
return [];
|
|
517
517
|
};
|
|
518
518
|
//#endregion
|