@yahoo/uds 3.171.1 → 3.172.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.
Files changed (28) hide show
  1. package/dist/automated-config/dist/utils/getConfigVariantProperties.d.cts +2 -2
  2. package/dist/automated-config/dist/utils/getConfigVariantProperties.d.ts +2 -2
  3. package/dist/components/Link.cjs +3 -3
  4. package/dist/components/Link.js +3 -3
  5. package/dist/components/client/Popover/UDSPopoverConfigProvider.d.cts +1 -1
  6. package/dist/components/client/Popover/UDSPopoverConfigProvider.d.ts +1 -1
  7. package/dist/css/dist/purger/optimized/ast/expressions.cjs +278 -278
  8. package/dist/css/dist/purger/optimized/ast/expressions.js +278 -278
  9. package/dist/css/dist/purger/optimized/ast/jsx.cjs +67 -36
  10. package/dist/css/dist/purger/optimized/ast/jsx.js +67 -35
  11. package/dist/css/dist/purger/optimized/ast/oxc.cjs +265 -0
  12. package/dist/css/dist/purger/optimized/ast/oxc.js +253 -0
  13. package/dist/css/dist/purger/optimized/ast/props.cjs +21 -15
  14. package/dist/css/dist/purger/optimized/ast/props.js +21 -14
  15. package/dist/css/dist/purger/optimized/ast/spread.cjs +19 -19
  16. package/dist/css/dist/purger/optimized/ast/spread.js +19 -18
  17. package/dist/css/dist/purger/optimized/purgeFromCode.cjs +86 -101
  18. package/dist/css/dist/purger/optimized/purgeFromCode.js +86 -100
  19. package/dist/tailwind-internal/dist/utils/getShadowStyles.d.cts +2 -2
  20. package/dist/tailwind-internal/dist/utils/getShadowStyles.d.ts +2 -2
  21. package/dist/tailwind-v3/dist/purger/legacy/purgeCSS.cjs +1 -1
  22. package/dist/tailwind-v3/dist/purger/legacy/purgeCSS.js +1 -1
  23. package/dist/uds/generated/componentData.cjs +340 -340
  24. package/dist/uds/generated/componentData.js +340 -340
  25. package/dist/uds/package.cjs +2 -0
  26. package/dist/uds/package.js +2 -0
  27. package/generated/componentData.json +783 -783
  28. 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 ts_morph = require("ts-morph");
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 importedSourceProject = new ts_morph.Project({ useInMemoryFileSystem: true });
11
- const importedSourceFileCache = /* @__PURE__ */ new Map();
11
+ const importedSourceCache = /* @__PURE__ */ new Map();
12
12
  const tsConfigPathCache = /* @__PURE__ */ new Map();
13
- const compilerOptionsCache = /* @__PURE__ */ new Map();
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 getCompilerOptionsForSourceFile = (sourceFilePath) => {
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
- const cached = compilerOptionsCache.get(configPath);
78
- if (cached !== void 0) return cached;
79
- const readResult = ts_morph.ts.readConfigFile(configPath, ts_morph.ts.sys.readFile);
80
- if (readResult.error) {
81
- compilerOptionsCache.set(configPath, null);
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 getImportedSourceFile = (filePath) => {
102
- const cached = importedSourceFileCache.get(filePath);
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 sourceFile = importedSourceProject.createSourceFile(filePath, node_fs.default.readFileSync(filePath, "utf-8"), { overwrite: true });
106
- importedSourceFileCache.set(filePath, sourceFile);
107
- return sourceFile;
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 (!ts_morph.Node.isIdentifier(node)) return [];
111
- const sourceFile = node.getSourceFile();
112
- const sourceFilePath = sourceFile.getFilePath();
113
- const importMatch = sourceFile.getImportDeclarations().find((importDecl) => importDecl.getNamedImports().some((namedImport) => (namedImport.getAliasNode()?.getText() ?? namedImport.getName()) === node.getText()));
114
- if (!importMatch) return [];
115
- const namedImport = importMatch.getNamedImports().find((candidate) => (candidate.getAliasNode()?.getText() ?? candidate.getName()) === node.getText());
116
- if (!namedImport) return [];
117
- const resolvedPath = resolveImportPath(sourceFilePath, importMatch.getModuleSpecifierValue());
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 importedSourceFile = getImportedSourceFile(resolvedPath);
120
- if (!importedSourceFile) return [];
121
- const initializer = importedSourceFile.getVariableDeclaration(namedImport.getName())?.getInitializer();
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
- const directValues = extractDirectLiteralValues(node);
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 (ts_morph.Node.isConditionalExpression(node)) return [...extractStringLiterals(node.getWhenTrue(), visited), ...extractStringLiterals(node.getWhenFalse(), visited)];
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 (ts_morph.Node.isStringLiteral(node) || ts_morph.Node.isNoSubstitutionTemplateLiteral(node)) return [node.getLiteralValue()];
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 (!ts_morph.Node.isTemplateExpression(node)) return null;
168
- const parts = [[node.getHead().getLiteralText()]];
169
- node.getTemplateSpans().forEach((span) => {
170
- const exprValues = extractStringLiterals(span.getExpression(), visited);
171
- const literalText = span.getLiteral().getLiteralText();
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 (!ts_morph.Node.isBinaryExpression(node)) return null;
178
- const operator = node.getOperatorToken().getText();
179
- if (operator === "+") {
180
- const left = extractStringLiterals(node.getLeft(), visited);
181
- const right = extractStringLiterals(node.getRight(), visited);
182
- const combined = left.flatMap((l) => right.map((r) => `${l}${r}`));
183
- return combined.length > 0 ? combined : [];
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 (operator === "||" || operator === "??") return [...extractStringLiterals(node.getLeft(), visited), ...extractStringLiterals(node.getRight(), visited)];
186
- return [];
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 (ts_morph.Node.isParenthesizedExpression(node) || ts_morph.Node.isAsExpression(node)) return extractStringLiterals(node.getExpression(), visited);
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 (!ts_morph.Node.isPropertyAccessExpression(node)) return null;
194
- const typeValues = extractLiteralValuesFromType(node);
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.getName();
197
- return extractObjectValues(node.getExpression(), visited).filter((value) => typeof value === "object" && value !== null && propertyName in value).map((value) => value[propertyName]).filter((value) => typeof value === "string");
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 (!ts_morph.Node.isElementAccessExpression(node)) return null;
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.getExpression(), visited).flatMap((value) => {
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 extractCallExpressionValues = (node, visited) => {
210
- if (!ts_morph.Node.isCallExpression(node)) return null;
211
- const expression = node.getExpression();
212
- const fromDefinitions = ts_morph.Node.isIdentifier(expression) ? getDefinitionNodesSafe(expression).flatMap((definition) => {
213
- if (ts_morph.Node.isFunctionDeclaration(definition)) return definition.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement).flatMap((returnStmt) => {
214
- const expression = returnStmt.getExpression();
215
- return expression ? extractStringLiterals(expression, visited) : [];
216
- });
217
- if (ts_morph.Node.isVariableDeclaration(definition)) {
218
- const initializer = definition.getInitializer();
219
- return initializer ? extractFromFunctionLike(initializer, visited) : [];
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.getArguments().flatMap((arg) => extractStringLiterals(arg, visited));
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 (!ts_morph.Node.isParameterDeclaration(definition)) return null;
243
- const callback = definition.getParentIfKind(ts_morph.SyntaxKind.ArrowFunction);
244
- if (!callback) return null;
245
- const callExpression = callback.getParentIfKind(ts_morph.SyntaxKind.CallExpression);
246
- if (!callExpression) return null;
247
- const expression = callExpression.getExpression();
248
- if (!ts_morph.Node.isPropertyAccessExpression(expression)) return null;
249
- if (!["map", "flatMap"].includes(expression.getName())) return null;
250
- if (callback.getParameters().findIndex((parameter) => {
251
- return parameter.getNameNode().getText() === definition.getNameNode().getText();
252
- }) !== 0) return null;
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 (ts_morph.Node.isObjectLiteralExpression(node)) return [node];
265
- if (ts_morph.Node.isParenthesizedExpression(node) || ts_morph.Node.isAsExpression(node) || ts_morph.Node.isTypeAssertion(node) || ts_morph.Node.isSatisfiesExpression(node)) return resolveObjectLiteralNodes(node.getExpression(), visited);
266
- if (ts_morph.Node.isArrayLiteralExpression(node)) return node.getElements().flatMap((element) => resolveObjectLiteralNodes(element, visited));
267
- if (ts_morph.Node.isElementAccessExpression(node)) return resolveObjectLiteralNodes(node.getExpression(), visited);
268
- if (ts_morph.Node.isCallExpression(node)) {
269
- const expression = node.getExpression();
270
- if (ts_morph.Node.isPropertyAccessExpression(expression) && ARRAY_CHAIN_METHODS.has(expression.getName())) return resolveObjectLiteralNodes(expression.getExpression(), visited);
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 (ts_morph.Node.isIdentifier(node)) return getLocalDefinitionNodes(node).flatMap((definition) => {
274
- if (ts_morph.Node.isVariableDeclaration(definition)) {
275
- const initializer = definition.getInitializer();
276
- return initializer ? resolveObjectLiteralNodes(initializer, visited) : [];
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 (!ts_morph.Node.isObjectLiteralExpression(obj)) return [];
289
- return obj.getProperties().flatMap((prop) => {
290
- if (!ts_morph.Node.isPropertyAssignment(prop) || prop.getName() !== propertyName) return [];
291
- const initializer = prop.getInitializer();
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 (!ts_morph.Node.isBindingElement(definition)) return [];
301
- const bindingPattern = definition.getParent();
302
- if (!ts_morph.Node.isObjectBindingPattern(bindingPattern)) return [];
303
- const propertyName = definition.getPropertyNameNode()?.getText() ?? definition.getName();
304
- const holder = bindingPattern.getParent();
305
- let source = null;
306
- if (ts_morph.Node.isParameterDeclaration(holder)) source = getMappedArraySource(holder);
307
- else if (ts_morph.Node.isVariableDeclaration(holder)) source = holder.getInitializer() ?? null;
308
- if (!source) return [];
309
- return getPropertyInitializers(resolveObjectLiteralNodes(source, /* @__PURE__ */ new Set()), propertyName);
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 (ts_morph.Node.isArrayLiteralExpression(node)) return node.getElements().flatMap((element) => extractStringLiterals(element, visited)).filter((value, index, values) => values.indexOf(value) === index);
313
- if (ts_morph.Node.isParenthesizedExpression(node)) return extractArrayElementValues(node.getExpression(), visited);
314
- if (ts_morph.Node.isAsExpression(node) || ts_morph.Node.isTypeAssertion(node) || ts_morph.Node.isSatisfiesExpression(node)) return extractArrayElementValues(node.getExpression(), visited);
315
- if (ts_morph.Node.isPropertyAccessExpression(node)) return getPropertyInitializers(resolveObjectLiteralNodes(node.getExpression(), /* @__PURE__ */ new Set()), node.getName()).flatMap((initializer) => extractArrayElementValues(initializer, visited)).filter((value, index, values) => values.indexOf(value) === index);
316
- if (ts_morph.Node.isCallExpression(node)) {
317
- const expression = node.getExpression();
318
- if (ts_morph.Node.isPropertyAccessExpression(expression) && ARRAY_CHAIN_METHODS.has(expression.getName())) return extractArrayElementValues(expression.getExpression(), visited);
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 (ts_morph.Node.isIdentifier(node)) return getLocalDefinitionNodes(node).flatMap((definition) => {
322
- if (ts_morph.Node.isVariableDeclaration(definition)) {
323
- const initializer = definition.getInitializer();
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 (!ts_morph.Node.isIdentifier(node)) return null;
337
- const values = getDefinitionNodesSafe(node).flatMap((definition) => {
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 (ts_morph.Node.isVariableDeclaration(definition) || ts_morph.Node.isParameterDeclaration(definition) || ts_morph.Node.isBindingElement(definition)) {
341
- const initializer = definition.getInitializer();
342
- if (initializer) return extractStringLiterals(initializer, visited);
343
- if (ts_morph.Node.isBindingElement(definition)) {
344
- const bindingPattern = definition.getParent();
345
- if (ts_morph.Node.isObjectBindingPattern(bindingPattern)) {
346
- const parentDecl = bindingPattern.getParent();
347
- if (ts_morph.Node.isVariableDeclaration(parentDecl)) {
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 (ts_morph.Node.isArrowFunction(node)) {
372
- const body = node.getBody();
373
- if (ts_morph.Node.isBlock(body)) body.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement).forEach((returnStmt) => {
374
- const returnExpr = returnStmt.getExpression();
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 (ts_morph.Node.isFunctionExpression(node)) node.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement).forEach((returnStmt) => {
379
- const returnExpr = returnStmt.getExpression();
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 (ts_morph.Node.isObjectLiteralExpression(node)) {
404
+ if (node.type === "ObjectExpression") {
393
405
  const obj = {};
394
- node.getProperties().forEach((prop) => {
395
- if (ts_morph.Node.isPropertyAssignment(prop)) {
396
- const name = prop.getName();
397
- const init = prop.getInitializer();
398
- if (init && ts_morph.Node.isStringLiteral(init)) obj[name] = init.getLiteralValue();
399
- else if (init && ts_morph.Node.isObjectLiteralExpression(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 (ts_morph.Node.isIdentifier(node)) {
409
- getDefinitionNodesSafe(node).forEach((definition) => {
410
- if (ts_morph.Node.isVariableDeclaration(definition)) {
411
- const initializer = definition.getInitializer();
412
- if (initializer) if (ts_morph.Node.isAsExpression(initializer)) {
413
- const inner = initializer.getExpression();
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 = node.getSourceFile().getEnum(node.getText());
428
+ const enumDecl = source.topLevelEnums.get(node.name);
419
429
  if (enumDecl) {
420
430
  const obj = {};
421
- enumDecl.getMembers().forEach((member) => {
422
- const initializer = member.getInitializer();
423
- if (initializer && ts_morph.Node.isStringLiteral(initializer)) obj[member.getName()] = initializer.getLiteralValue();
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 (ts_morph.Node.isCallExpression(node)) {
430
- const expression = node.getExpression();
431
- if (ts_morph.Node.isIdentifier(expression)) getDefinitionNodesSafe(expression).forEach((definition) => {
432
- if (ts_morph.Node.isFunctionDeclaration(definition)) definition.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement).forEach((returnStmt) => {
433
- const returnExpr = returnStmt.getExpression();
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 (ts_morph.Node.isVariableDeclaration(definition)) {
437
- const initializer = definition.getInitializer();
438
- if (initializer) {
439
- const extractFromFn = (fn) => {
440
- if (ts_morph.Node.isArrowFunction(fn)) {
441
- const body = fn.getBody();
442
- if (ts_morph.Node.isBlock(body)) body.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement).forEach((returnStmt) => {
443
- const returnExpr = returnStmt.getExpression();
444
- if (returnExpr) values.push(...extractObjectValues(returnExpr, visited));
445
- });
446
- else values.push(...extractObjectValues(body, visited));
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 (ts_morph.Node.isElementAccessExpression(node)) {
459
- extractObjectValues(node.getExpression(), visited).forEach((obj) => {
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 — avoids expensive TS Language Service `getType()` calls.
473
+ * Pure AST traversal — no type checker involved.
469
474
  */
470
475
  const extractStringLiteralsFromTypeNode = (typeNode) => {
471
- if (ts_morph.Node.isLiteralTypeNode(typeNode)) {
472
- const literal = typeNode.getLiteral();
473
- if (ts_morph.Node.isStringLiteral(literal)) return [literal.getLiteralValue()];
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 (ts_morph.Node.isUnionTypeNode(typeNode)) return typeNode.getTypeNodes().flatMap(extractStringLiteralsFromTypeNode);
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 to avoid expensive LS initialization.
486
+ * Uses pure AST traversal instead of the TS type checker.
482
487
  */
483
- const extractLiteralValuesFromType = (node) => {
484
- if (ts_morph.Node.isIdentifier(node)) {
485
- const definitions = getLocalDefinitionNodes(node);
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 (ts_morph.Node.isParameterDeclaration(def) || ts_morph.Node.isVariableDeclaration(def) || ts_morph.Node.isPropertyDeclaration(def) || ts_morph.Node.isPropertySignature(def)) {
488
- const typeNode = def.getTypeNode?.();
489
- if (typeNode) {
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 (ts_morph.Node.isBindingElement(def)) {
495
- const bindingPattern = def.getParent();
496
- if (bindingPattern) {
497
- const parentDecl = bindingPattern.getParent();
498
- if (parentDecl && ts_morph.Node.isVariableDeclaration(parentDecl)) {
499
- const parentType = parentDecl.getTypeNode();
500
- if (parentType && ts_morph.Node.isTypeLiteral(parentType)) {
501
- const propName = def.getNameNode().getText();
502
- for (const member of parentType.getMembers()) if (ts_morph.Node.isPropertySignature(member) && member.getName() === propName) {
503
- const memberType = member.getTypeNode();
504
- if (memberType) {
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