@yahoo/uds 3.134.0 → 3.134.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 (55) hide show
  1. package/dist/cli/dist/lib/args.cjs +7 -3
  2. package/dist/cli/dist/lib/args.js +7 -3
  3. package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
  4. package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
  5. package/dist/styles/styler.d.cts +26 -26
  6. package/dist/styles/styler.d.ts +26 -26
  7. package/dist/tailwind/dist/commands/css.cjs +1 -0
  8. package/dist/tailwind/dist/commands/css.d.cts.map +1 -1
  9. package/dist/tailwind/dist/commands/css.d.ts.map +1 -1
  10. package/dist/tailwind/dist/commands/css.helpers.cjs +8 -1
  11. package/dist/tailwind/dist/commands/css.helpers.js +8 -1
  12. package/dist/tailwind/dist/commands/css.helpers.js.map +1 -1
  13. package/dist/tailwind/dist/commands/css.js +1 -0
  14. package/dist/tailwind/dist/commands/css.js.map +1 -1
  15. package/dist/tailwind/dist/css/generate.cjs +7 -4
  16. package/dist/tailwind/dist/css/generate.d.cts.map +1 -1
  17. package/dist/tailwind/dist/css/generate.d.ts.map +1 -1
  18. package/dist/tailwind/dist/css/generate.js +7 -4
  19. package/dist/tailwind/dist/css/generate.js.map +1 -1
  20. package/dist/tailwind/dist/css/nodeUtils.cjs +19 -8
  21. package/dist/tailwind/dist/css/nodeUtils.js +19 -8
  22. package/dist/tailwind/dist/css/nodeUtils.js.map +1 -1
  23. package/dist/tailwind/dist/css/perf.cjs +92 -0
  24. package/dist/tailwind/dist/css/perf.js +89 -0
  25. package/dist/tailwind/dist/css/perf.js.map +1 -0
  26. package/dist/tailwind/dist/css/purgeWorker.cjs +47 -0
  27. package/dist/tailwind/dist/css/purgeWorker.d.cts +2 -0
  28. package/dist/tailwind/dist/css/purgeWorker.d.ts +2 -0
  29. package/dist/tailwind/dist/css/purgeWorker.js +48 -0
  30. package/dist/tailwind/dist/css/purgeWorker.js.map +1 -0
  31. package/dist/tailwind/dist/css/runner.cjs +158 -145
  32. package/dist/tailwind/dist/css/runner.js +158 -145
  33. package/dist/tailwind/dist/css/runner.js.map +1 -1
  34. package/dist/tailwind/dist/css/workerPool.cjs +89 -0
  35. package/dist/tailwind/dist/css/workerPool.js +90 -0
  36. package/dist/tailwind/dist/css/workerPool.js.map +1 -0
  37. package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +95 -15
  38. package/dist/tailwind/dist/purger/optimized/ast/expressions.js +95 -15
  39. package/dist/tailwind/dist/purger/optimized/ast/expressions.js.map +1 -1
  40. package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +38 -14
  41. package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.cts.map +1 -1
  42. package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.ts.map +1 -1
  43. package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +39 -15
  44. package/dist/tailwind/dist/purger/optimized/purgeFromCode.js.map +1 -1
  45. package/dist/tailwind/dist/purger/optimized/types.d.cts +10 -0
  46. package/dist/tailwind/dist/purger/optimized/types.d.cts.map +1 -1
  47. package/dist/tailwind/dist/purger/optimized/types.d.ts +10 -0
  48. package/dist/tailwind/dist/purger/optimized/types.d.ts.map +1 -1
  49. package/dist/uds/generated/componentData.cjs +557 -557
  50. package/dist/uds/generated/componentData.js +557 -557
  51. package/generated/componentData.json +915 -915
  52. package/package.json +1 -1
  53. package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +0 -16
  54. package/dist/tailwind/dist/purger/optimized/ast/jsx.js +0 -17
  55. package/dist/tailwind/dist/purger/optimized/ast/jsx.js.map +0 -1
@@ -0,0 +1,90 @@
1
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
2
+ import { cpus } from "node:os";
3
+ import { Worker } from "node:worker_threads";
4
+ //#region src/css/workerPool.ts
5
+ const createWorkerPool = async (config, numWorkers) => {
6
+ const workerCount = numWorkers ?? Math.max(1, cpus().length - 1);
7
+ const workerUrl = new URL("./purgeWorker.js", import.meta.url);
8
+ const workers = [];
9
+ const available = [];
10
+ const pending = /* @__PURE__ */ new Map();
11
+ const queue = [];
12
+ let nextId = 0;
13
+ await Promise.all(Array.from({ length: workerCount }, () => {
14
+ return new Promise((resolve, reject) => {
15
+ const worker = new Worker(workerUrl);
16
+ let initialized = false;
17
+ worker.on("message", (msg) => {
18
+ if (msg.type === "ready") {
19
+ initialized = true;
20
+ workers.push(worker);
21
+ available.push(worker);
22
+ resolve();
23
+ return;
24
+ }
25
+ if (msg.type === "result" || msg.type === "error") {
26
+ const task = msg.id != null ? pending.get(msg.id) : void 0;
27
+ if (task) {
28
+ pending.delete(msg.id);
29
+ if (msg.type === "result") task.resolve(msg.result);
30
+ else task.reject(new Error(msg.error ?? "Unknown worker error"));
31
+ }
32
+ available.push(worker);
33
+ if (queue.length > 0 && available.length > 0) {
34
+ const next = queue.shift();
35
+ const nextWorker = available.pop();
36
+ pending.set(next.msg.id, next.task);
37
+ nextWorker.postMessage(next.msg);
38
+ }
39
+ }
40
+ });
41
+ worker.on("error", (err) => {
42
+ if (!initialized) reject(err);
43
+ });
44
+ worker.postMessage({
45
+ type: "init",
46
+ config: JSON.parse(JSON.stringify(config))
47
+ });
48
+ });
49
+ }));
50
+ const processFile = (options) => {
51
+ return new Promise((resolve, reject) => {
52
+ const id = nextId++;
53
+ const msg = {
54
+ type: "task",
55
+ id,
56
+ code: options.code,
57
+ filePath: options.filePath,
58
+ colorModes: options.colorModes,
59
+ variantDefaults: options.variantDefaults,
60
+ runtimeConfigValues: options.runtimeConfigValues,
61
+ includeAllClassNamePrimitives: options.includeAllClassNamePrimitives
62
+ };
63
+ const task = {
64
+ resolve,
65
+ reject
66
+ };
67
+ if (available.length > 0) {
68
+ const worker = available.pop();
69
+ pending.set(id, task);
70
+ worker.postMessage(msg);
71
+ } else queue.push({
72
+ msg,
73
+ task
74
+ });
75
+ });
76
+ };
77
+ const destroy = async () => {
78
+ for (const worker of workers) worker.postMessage({ type: "done" });
79
+ await Promise.all(workers.map((w) => new Promise((res) => w.on("exit", () => res()))));
80
+ };
81
+ return {
82
+ processFile,
83
+ destroy,
84
+ workerCount
85
+ };
86
+ };
87
+ //#endregion
88
+ export { createWorkerPool };
89
+
90
+ //# sourceMappingURL=workerPool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workerPool.js","names":[],"sources":["../../src/css/workerPool.ts"],"sourcesContent":["import { cpus } from 'node:os';\nimport { Worker } from 'node:worker_threads';\n\nimport type { PurgeFromCodeOptions, PurgeFromCodeResult } from '../purger/optimized/purgeFromCode';\n\ntype SharedConfig = Pick<PurgeFromCodeOptions, 'variants' | 'autoVariants' | 'componentData'>;\n\ninterface TaskOptions {\n code: string;\n filePath: string;\n colorModes?: ('dark' | 'light')[];\n variantDefaults?: PurgeFromCodeOptions['variantDefaults'];\n runtimeConfigValues?: PurgeFromCodeOptions['runtimeConfigValues'];\n includeAllClassNamePrimitives?: boolean;\n}\n\ninterface PendingTask {\n resolve: (result: PurgeFromCodeResult) => void;\n reject: (error: Error) => void;\n}\n\nexport interface WorkerPool {\n processFile: (options: TaskOptions) => Promise<PurgeFromCodeResult>;\n destroy: () => Promise<void>;\n workerCount: number;\n}\n\nexport const createWorkerPool = async (\n config: SharedConfig,\n numWorkers?: number,\n): Promise<WorkerPool> => {\n const workerCount = numWorkers ?? Math.max(1, cpus().length - 1);\n const workerUrl = new URL('./purgeWorker.js', import.meta.url);\n\n const workers: Worker[] = [];\n const available: Worker[] = [];\n const pending = new Map<number, PendingTask>();\n const queue: Array<{ msg: Record<string, unknown>; task: PendingTask }> = [];\n let nextId = 0;\n\n // Create workers, init with shared config, and set up message handlers\n await Promise.all(\n Array.from({ length: workerCount }, () => {\n return new Promise<void>((resolve, reject) => {\n const worker = new Worker(workerUrl);\n let initialized = false;\n\n worker.on(\n 'message',\n (msg: { type: string; id?: number; result?: PurgeFromCodeResult; error?: string }) => {\n if (msg.type === 'ready') {\n initialized = true;\n workers.push(worker);\n available.push(worker);\n resolve();\n return;\n }\n\n if (msg.type === 'result' || msg.type === 'error') {\n const task = msg.id != null ? pending.get(msg.id) : undefined;\n if (task) {\n pending.delete(msg.id!);\n if (msg.type === 'result') {\n task.resolve(msg.result!);\n } else {\n task.reject(new Error(msg.error ?? 'Unknown worker error'));\n }\n }\n\n available.push(worker);\n\n // Drain queue\n if (queue.length > 0 && available.length > 0) {\n const next = queue.shift()!;\n const nextWorker = available.pop()!;\n pending.set(next.msg.id as number, next.task);\n nextWorker.postMessage(next.msg);\n }\n }\n },\n );\n\n worker.on('error', (err) => {\n if (!initialized) {\n reject(err);\n }\n });\n\n // JSON round-trip ensures config is a plain object (ES module namespaces can't be cloned)\n worker.postMessage({ type: 'init', config: JSON.parse(JSON.stringify(config)) });\n });\n }),\n );\n\n const processFile = (options: TaskOptions): Promise<PurgeFromCodeResult> => {\n return new Promise((resolve, reject) => {\n const id = nextId++;\n const msg = {\n type: 'task' as const,\n id,\n code: options.code,\n filePath: options.filePath,\n colorModes: options.colorModes,\n variantDefaults: options.variantDefaults,\n runtimeConfigValues: options.runtimeConfigValues,\n includeAllClassNamePrimitives: options.includeAllClassNamePrimitives,\n };\n const task = { resolve, reject };\n\n if (available.length > 0) {\n const worker = available.pop()!;\n pending.set(id, task);\n worker.postMessage(msg);\n } else {\n queue.push({ msg, task });\n }\n });\n };\n\n const destroy = async () => {\n for (const worker of workers) {\n worker.postMessage({ type: 'done' });\n }\n await Promise.all(workers.map((w) => new Promise<void>((res) => w.on('exit', () => res()))));\n };\n\n return { processFile, destroy, workerCount };\n};\n"],"mappings":";;;;AA2BA,MAAa,mBAAmB,OAC9B,QACA,eACwB;CACxB,MAAM,cAAc,cAAc,KAAK,IAAI,GAAG,MAAM,CAAC,SAAS,EAAE;CAChE,MAAM,YAAY,IAAI,IAAI,oBAAoB,OAAO,KAAK,IAAI;CAE9D,MAAM,UAAoB,EAAE;CAC5B,MAAM,YAAsB,EAAE;CAC9B,MAAM,0BAAU,IAAI,KAA0B;CAC9C,MAAM,QAAoE,EAAE;CAC5E,IAAI,SAAS;AAGb,OAAM,QAAQ,IACZ,MAAM,KAAK,EAAE,QAAQ,aAAa,QAAQ;AACxC,SAAO,IAAI,SAAe,SAAS,WAAW;GAC5C,MAAM,SAAS,IAAI,OAAO,UAAU;GACpC,IAAI,cAAc;AAElB,UAAO,GACL,YACC,QAAqF;AACpF,QAAI,IAAI,SAAS,SAAS;AACxB,mBAAc;AACd,aAAQ,KAAK,OAAO;AACpB,eAAU,KAAK,OAAO;AACtB,cAAS;AACT;;AAGF,QAAI,IAAI,SAAS,YAAY,IAAI,SAAS,SAAS;KACjD,MAAM,OAAO,IAAI,MAAM,OAAO,QAAQ,IAAI,IAAI,GAAG,GAAG,KAAA;AACpD,SAAI,MAAM;AACR,cAAQ,OAAO,IAAI,GAAI;AACvB,UAAI,IAAI,SAAS,SACf,MAAK,QAAQ,IAAI,OAAQ;UAEzB,MAAK,OAAO,IAAI,MAAM,IAAI,SAAS,uBAAuB,CAAC;;AAI/D,eAAU,KAAK,OAAO;AAGtB,SAAI,MAAM,SAAS,KAAK,UAAU,SAAS,GAAG;MAC5C,MAAM,OAAO,MAAM,OAAO;MAC1B,MAAM,aAAa,UAAU,KAAK;AAClC,cAAQ,IAAI,KAAK,IAAI,IAAc,KAAK,KAAK;AAC7C,iBAAW,YAAY,KAAK,IAAI;;;KAIvC;AAED,UAAO,GAAG,UAAU,QAAQ;AAC1B,QAAI,CAAC,YACH,QAAO,IAAI;KAEb;AAGF,UAAO,YAAY;IAAE,MAAM;IAAQ,QAAQ,KAAK,MAAM,KAAK,UAAU,OAAO,CAAC;IAAE,CAAC;IAChF;GACF,CACH;CAED,MAAM,eAAe,YAAuD;AAC1E,SAAO,IAAI,SAAS,SAAS,WAAW;GACtC,MAAM,KAAK;GACX,MAAM,MAAM;IACV,MAAM;IACN;IACA,MAAM,QAAQ;IACd,UAAU,QAAQ;IAClB,YAAY,QAAQ;IACpB,iBAAiB,QAAQ;IACzB,qBAAqB,QAAQ;IAC7B,+BAA+B,QAAQ;IACxC;GACD,MAAM,OAAO;IAAE;IAAS;IAAQ;AAEhC,OAAI,UAAU,SAAS,GAAG;IACxB,MAAM,SAAS,UAAU,KAAK;AAC9B,YAAQ,IAAI,IAAI,KAAK;AACrB,WAAO,YAAY,IAAI;SAEvB,OAAM,KAAK;IAAE;IAAK;IAAM,CAAC;IAE3B;;CAGJ,MAAM,UAAU,YAAY;AAC1B,OAAK,MAAM,UAAU,QACnB,QAAO,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,QAAM,QAAQ,IAAI,QAAQ,KAAK,MAAM,IAAI,SAAe,QAAQ,EAAE,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC;;AAG9F,QAAO;EAAE;EAAa;EAAS;EAAa"}
@@ -24,11 +24,7 @@ const getLocalDefinitionNodes = (node) => {
24
24
  ].sort((left, right) => right.getStart() - left.getStart()).slice(0, 1);
25
25
  };
26
26
  const getDefinitionNodesSafe = (node) => {
27
- try {
28
- return node.getDefinitionNodes();
29
- } catch {
30
- return getLocalDefinitionNodes(node);
31
- }
27
+ return getLocalDefinitionNodes(node);
32
28
  };
33
29
  const isExistingFile = (candidate) => node_fs.default.existsSync(candidate) && node_fs.default.statSync(candidate).isFile();
34
30
  const resolveRelativeImportPath = (sourceFilePath, moduleSpecifier) => {
@@ -230,7 +226,7 @@ const extractArrayElementValues = (node, visited) => {
230
226
  if (ts_morph.Node.isArrayLiteralExpression(node)) return node.getElements().flatMap((element) => extractStringLiterals(element, visited)).filter((value, index, values) => values.indexOf(value) === index);
231
227
  if (ts_morph.Node.isParenthesizedExpression(node)) return extractArrayElementValues(node.getExpression(), visited);
232
228
  if (ts_morph.Node.isAsExpression(node) || ts_morph.Node.isTypeAssertion(node) || ts_morph.Node.isSatisfiesExpression(node)) return extractArrayElementValues(node.getExpression(), visited);
233
- if (ts_morph.Node.isIdentifier(node)) return node.getDefinitionNodes().flatMap((definition) => {
229
+ if (ts_morph.Node.isIdentifier(node)) return getLocalDefinitionNodes(node).flatMap((definition) => {
234
230
  if (ts_morph.Node.isVariableDeclaration(definition)) {
235
231
  const initializer = definition.getInitializer();
236
232
  return initializer ? extractArrayElementValues(initializer, visited) : [];
@@ -258,7 +254,22 @@ const extractIdentifierValues = (node, visited) => {
258
254
  if (mappedParameterValues.length > 0) return mappedParameterValues;
259
255
  if (ts_morph.Node.isVariableDeclaration(definition) || ts_morph.Node.isParameterDeclaration(definition) || ts_morph.Node.isBindingElement(definition)) {
260
256
  const initializer = definition.getInitializer();
261
- return initializer ? extractStringLiterals(initializer, visited) : [];
257
+ if (initializer) return extractStringLiterals(initializer, visited);
258
+ if (ts_morph.Node.isBindingElement(definition)) {
259
+ const bindingPattern = definition.getParent();
260
+ if (ts_morph.Node.isObjectBindingPattern(bindingPattern)) {
261
+ const parentDecl = bindingPattern.getParent();
262
+ if (ts_morph.Node.isVariableDeclaration(parentDecl)) {
263
+ const parentInit = parentDecl.getInitializer();
264
+ if (parentInit) {
265
+ const propName = definition.getNameNode().getText();
266
+ 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");
267
+ if (propValues.length > 0) return propValues;
268
+ }
269
+ }
270
+ }
271
+ }
272
+ return [];
262
273
  }
263
274
  return [];
264
275
  });
@@ -321,6 +332,35 @@ const extractObjectValues = (node, visited) => {
321
332
  });
322
333
  return values;
323
334
  }
335
+ if (ts_morph.Node.isCallExpression(node)) {
336
+ const expression = node.getExpression();
337
+ if (ts_morph.Node.isIdentifier(expression)) getDefinitionNodesSafe(expression).forEach((definition) => {
338
+ if (ts_morph.Node.isFunctionDeclaration(definition)) definition.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement).forEach((returnStmt) => {
339
+ const returnExpr = returnStmt.getExpression();
340
+ if (returnExpr) values.push(...extractObjectValues(returnExpr, visited));
341
+ });
342
+ if (ts_morph.Node.isVariableDeclaration(definition)) {
343
+ const initializer = definition.getInitializer();
344
+ if (initializer) {
345
+ const extractFromFn = (fn) => {
346
+ if (ts_morph.Node.isArrowFunction(fn)) {
347
+ const body = fn.getBody();
348
+ if (ts_morph.Node.isBlock(body)) body.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement).forEach((returnStmt) => {
349
+ const returnExpr = returnStmt.getExpression();
350
+ if (returnExpr) values.push(...extractObjectValues(returnExpr, visited));
351
+ });
352
+ else values.push(...extractObjectValues(body, visited));
353
+ } else if (ts_morph.Node.isFunctionExpression(fn)) fn.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement).forEach((returnStmt) => {
354
+ const returnExpr = returnStmt.getExpression();
355
+ if (returnExpr) values.push(...extractObjectValues(returnExpr, visited));
356
+ });
357
+ };
358
+ extractFromFn(initializer);
359
+ }
360
+ }
361
+ });
362
+ return values;
363
+ }
324
364
  if (ts_morph.Node.isElementAccessExpression(node)) {
325
365
  extractObjectValues(node.getExpression(), visited).forEach((obj) => {
326
366
  if (typeof obj === "object" && obj !== null) Object.values(obj).forEach((value) => values.push(value));
@@ -330,16 +370,56 @@ const extractObjectValues = (node, visited) => {
330
370
  return values;
331
371
  };
332
372
  /**
333
- * Extract literal values from a TypeScript type (for union types like 'brand' | 'secondary')
373
+ * Extract string literal values from a TypeScript type annotation AST node.
374
+ * Pure AST traversal — avoids expensive TS Language Service `getType()` calls.
375
+ */
376
+ const extractStringLiteralsFromTypeNode = (typeNode) => {
377
+ if (ts_morph.Node.isLiteralTypeNode(typeNode)) {
378
+ const literal = typeNode.getLiteral();
379
+ if (ts_morph.Node.isStringLiteral(literal)) return [literal.getLiteralValue()];
380
+ return [];
381
+ }
382
+ if (ts_morph.Node.isUnionTypeNode(typeNode)) return typeNode.getTypeNodes().flatMap(extractStringLiteralsFromTypeNode);
383
+ return [];
384
+ };
385
+ /**
386
+ * Extract literal values from a TypeScript type annotation (for union types like 'brand' | 'secondary').
387
+ * Uses pure AST traversal instead of the TS type checker to avoid expensive LS initialization.
334
388
  */
335
389
  const extractLiteralValuesFromType = (node) => {
336
- const values = [];
337
- const nodeType = node.getType();
338
- if (nodeType.isUnion()) nodeType.getUnionTypes().forEach((unionMember) => {
339
- if (unionMember.isStringLiteral()) values.push(unionMember.getLiteralValue());
340
- });
341
- else if (nodeType.isStringLiteral()) values.push(nodeType.getLiteralValue());
342
- return values;
390
+ if (ts_morph.Node.isIdentifier(node)) {
391
+ const definitions = getLocalDefinitionNodes(node);
392
+ for (const def of definitions) {
393
+ if (ts_morph.Node.isParameterDeclaration(def) || ts_morph.Node.isVariableDeclaration(def) || ts_morph.Node.isPropertyDeclaration(def) || ts_morph.Node.isPropertySignature(def)) {
394
+ const typeNode = def.getTypeNode?.();
395
+ if (typeNode) {
396
+ const values = extractStringLiteralsFromTypeNode(typeNode);
397
+ if (values.length > 0) return values;
398
+ }
399
+ }
400
+ if (ts_morph.Node.isBindingElement(def)) {
401
+ const bindingPattern = def.getParent();
402
+ if (bindingPattern) {
403
+ const parentDecl = bindingPattern.getParent();
404
+ if (parentDecl && ts_morph.Node.isVariableDeclaration(parentDecl)) {
405
+ const parentType = parentDecl.getTypeNode();
406
+ if (parentType && ts_morph.Node.isTypeLiteral(parentType)) {
407
+ const propName = def.getNameNode().getText();
408
+ for (const member of parentType.getMembers()) if (ts_morph.Node.isPropertySignature(member) && member.getName() === propName) {
409
+ const memberType = member.getTypeNode();
410
+ if (memberType) {
411
+ const values = extractStringLiteralsFromTypeNode(memberType);
412
+ if (values.length > 0) return values;
413
+ }
414
+ }
415
+ }
416
+ }
417
+ }
418
+ }
419
+ }
420
+ }
421
+ if (ts_morph.Node.isPropertyAccessExpression(node) || ts_morph.Node.isElementAccessExpression(node)) return [];
422
+ return [];
343
423
  };
344
424
  //#endregion
345
425
  exports.extractStringLiterals = extractStringLiterals;
@@ -21,11 +21,7 @@ const getLocalDefinitionNodes = (node) => {
21
21
  ].sort((left, right) => right.getStart() - left.getStart()).slice(0, 1);
22
22
  };
23
23
  const getDefinitionNodesSafe = (node) => {
24
- try {
25
- return node.getDefinitionNodes();
26
- } catch {
27
- return getLocalDefinitionNodes(node);
28
- }
24
+ return getLocalDefinitionNodes(node);
29
25
  };
30
26
  const isExistingFile = (candidate) => fs.existsSync(candidate) && fs.statSync(candidate).isFile();
31
27
  const resolveRelativeImportPath = (sourceFilePath, moduleSpecifier) => {
@@ -227,7 +223,7 @@ const extractArrayElementValues = (node, visited) => {
227
223
  if (Node.isArrayLiteralExpression(node)) return node.getElements().flatMap((element) => extractStringLiterals(element, visited)).filter((value, index, values) => values.indexOf(value) === index);
228
224
  if (Node.isParenthesizedExpression(node)) return extractArrayElementValues(node.getExpression(), visited);
229
225
  if (Node.isAsExpression(node) || Node.isTypeAssertion(node) || Node.isSatisfiesExpression(node)) return extractArrayElementValues(node.getExpression(), visited);
230
- if (Node.isIdentifier(node)) return node.getDefinitionNodes().flatMap((definition) => {
226
+ if (Node.isIdentifier(node)) return getLocalDefinitionNodes(node).flatMap((definition) => {
231
227
  if (Node.isVariableDeclaration(definition)) {
232
228
  const initializer = definition.getInitializer();
233
229
  return initializer ? extractArrayElementValues(initializer, visited) : [];
@@ -255,7 +251,22 @@ const extractIdentifierValues = (node, visited) => {
255
251
  if (mappedParameterValues.length > 0) return mappedParameterValues;
256
252
  if (Node.isVariableDeclaration(definition) || Node.isParameterDeclaration(definition) || Node.isBindingElement(definition)) {
257
253
  const initializer = definition.getInitializer();
258
- return initializer ? extractStringLiterals(initializer, visited) : [];
254
+ if (initializer) return extractStringLiterals(initializer, visited);
255
+ if (Node.isBindingElement(definition)) {
256
+ const bindingPattern = definition.getParent();
257
+ if (Node.isObjectBindingPattern(bindingPattern)) {
258
+ const parentDecl = bindingPattern.getParent();
259
+ if (Node.isVariableDeclaration(parentDecl)) {
260
+ const parentInit = parentDecl.getInitializer();
261
+ if (parentInit) {
262
+ const propName = definition.getNameNode().getText();
263
+ 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");
264
+ if (propValues.length > 0) return propValues;
265
+ }
266
+ }
267
+ }
268
+ }
269
+ return [];
259
270
  }
260
271
  return [];
261
272
  });
@@ -318,6 +329,35 @@ const extractObjectValues = (node, visited) => {
318
329
  });
319
330
  return values;
320
331
  }
332
+ if (Node.isCallExpression(node)) {
333
+ const expression = node.getExpression();
334
+ if (Node.isIdentifier(expression)) getDefinitionNodesSafe(expression).forEach((definition) => {
335
+ if (Node.isFunctionDeclaration(definition)) definition.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {
336
+ const returnExpr = returnStmt.getExpression();
337
+ if (returnExpr) values.push(...extractObjectValues(returnExpr, visited));
338
+ });
339
+ if (Node.isVariableDeclaration(definition)) {
340
+ const initializer = definition.getInitializer();
341
+ if (initializer) {
342
+ const extractFromFn = (fn) => {
343
+ if (Node.isArrowFunction(fn)) {
344
+ const body = fn.getBody();
345
+ if (Node.isBlock(body)) body.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {
346
+ const returnExpr = returnStmt.getExpression();
347
+ if (returnExpr) values.push(...extractObjectValues(returnExpr, visited));
348
+ });
349
+ else values.push(...extractObjectValues(body, visited));
350
+ } else if (Node.isFunctionExpression(fn)) fn.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {
351
+ const returnExpr = returnStmt.getExpression();
352
+ if (returnExpr) values.push(...extractObjectValues(returnExpr, visited));
353
+ });
354
+ };
355
+ extractFromFn(initializer);
356
+ }
357
+ }
358
+ });
359
+ return values;
360
+ }
321
361
  if (Node.isElementAccessExpression(node)) {
322
362
  extractObjectValues(node.getExpression(), visited).forEach((obj) => {
323
363
  if (typeof obj === "object" && obj !== null) Object.values(obj).forEach((value) => values.push(value));
@@ -327,16 +367,56 @@ const extractObjectValues = (node, visited) => {
327
367
  return values;
328
368
  };
329
369
  /**
330
- * Extract literal values from a TypeScript type (for union types like 'brand' | 'secondary')
370
+ * Extract string literal values from a TypeScript type annotation AST node.
371
+ * Pure AST traversal — avoids expensive TS Language Service `getType()` calls.
372
+ */
373
+ const extractStringLiteralsFromTypeNode = (typeNode) => {
374
+ if (Node.isLiteralTypeNode(typeNode)) {
375
+ const literal = typeNode.getLiteral();
376
+ if (Node.isStringLiteral(literal)) return [literal.getLiteralValue()];
377
+ return [];
378
+ }
379
+ if (Node.isUnionTypeNode(typeNode)) return typeNode.getTypeNodes().flatMap(extractStringLiteralsFromTypeNode);
380
+ return [];
381
+ };
382
+ /**
383
+ * Extract literal values from a TypeScript type annotation (for union types like 'brand' | 'secondary').
384
+ * Uses pure AST traversal instead of the TS type checker to avoid expensive LS initialization.
331
385
  */
332
386
  const extractLiteralValuesFromType = (node) => {
333
- const values = [];
334
- const nodeType = node.getType();
335
- if (nodeType.isUnion()) nodeType.getUnionTypes().forEach((unionMember) => {
336
- if (unionMember.isStringLiteral()) values.push(unionMember.getLiteralValue());
337
- });
338
- else if (nodeType.isStringLiteral()) values.push(nodeType.getLiteralValue());
339
- return values;
387
+ if (Node.isIdentifier(node)) {
388
+ const definitions = getLocalDefinitionNodes(node);
389
+ for (const def of definitions) {
390
+ if (Node.isParameterDeclaration(def) || Node.isVariableDeclaration(def) || Node.isPropertyDeclaration(def) || Node.isPropertySignature(def)) {
391
+ const typeNode = def.getTypeNode?.();
392
+ if (typeNode) {
393
+ const values = extractStringLiteralsFromTypeNode(typeNode);
394
+ if (values.length > 0) return values;
395
+ }
396
+ }
397
+ if (Node.isBindingElement(def)) {
398
+ const bindingPattern = def.getParent();
399
+ if (bindingPattern) {
400
+ const parentDecl = bindingPattern.getParent();
401
+ if (parentDecl && Node.isVariableDeclaration(parentDecl)) {
402
+ const parentType = parentDecl.getTypeNode();
403
+ if (parentType && Node.isTypeLiteral(parentType)) {
404
+ const propName = def.getNameNode().getText();
405
+ for (const member of parentType.getMembers()) if (Node.isPropertySignature(member) && member.getName() === propName) {
406
+ const memberType = member.getTypeNode();
407
+ if (memberType) {
408
+ const values = extractStringLiteralsFromTypeNode(memberType);
409
+ if (values.length > 0) return values;
410
+ }
411
+ }
412
+ }
413
+ }
414
+ }
415
+ }
416
+ }
417
+ }
418
+ if (Node.isPropertyAccessExpression(node) || Node.isElementAccessExpression(node)) return [];
419
+ return [];
340
420
  };
341
421
  //#endregion
342
422
  export { extractStringLiterals };
@@ -1 +1 @@
1
- {"version":3,"file":"expressions.js","names":[],"sources":["../../../../src/purger/optimized/ast/expressions.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { Identifier } from 'ts-morph';\nimport { Node, Project, SyntaxKind, ts } from 'ts-morph';\n\nconst importedSourceProject = new Project({ useInMemoryFileSystem: true });\nconst importedSourceFileCache = new Map<string, ReturnType<Project['createSourceFile']>>();\nconst tsConfigPathCache = new Map<string, string | null>();\nconst compilerOptionsCache = new Map<string, ts.CompilerOptions | null>();\nconst hasImportQuery = (moduleSpecifier: string): boolean => moduleSpecifier.includes('?');\n\nconst getLocalDefinitionNodes = (node: Node): Node[] => {\n if (!Node.isIdentifier(node)) {\n return [];\n }\n\n const name = node.getText();\n const nodeStart = node.getStart();\n const sourceFile = node.getSourceFile();\n\n const matches = [\n ...sourceFile\n .getDescendantsOfKind(SyntaxKind.VariableDeclaration)\n .filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),\n ...sourceFile\n .getDescendantsOfKind(SyntaxKind.Parameter)\n .filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),\n ...sourceFile\n .getDescendantsOfKind(SyntaxKind.BindingElement)\n .filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),\n ...sourceFile\n .getFunctions()\n .filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),\n ];\n\n return matches.sort((left, right) => right.getStart() - left.getStart()).slice(0, 1);\n};\n\nconst getDefinitionNodesSafe = (node: Identifier): Node[] => {\n try {\n return node.getDefinitionNodes();\n } catch {\n return getLocalDefinitionNodes(node);\n }\n};\n\nconst isExistingFile = (candidate: string): boolean =>\n fs.existsSync(candidate) && fs.statSync(candidate).isFile();\n\nconst resolveRelativeImportPath = (\n sourceFilePath: string,\n moduleSpecifier: string,\n): string | null => {\n if (\n !path.isAbsolute(sourceFilePath) ||\n !moduleSpecifier.startsWith('.') ||\n hasImportQuery(moduleSpecifier)\n ) {\n return null;\n }\n\n const basePath = path.resolve(path.dirname(sourceFilePath), moduleSpecifier);\n const candidates = [\n basePath,\n `${basePath}.ts`,\n `${basePath}.tsx`,\n `${basePath}.mjs`,\n `${basePath}.cjs`,\n `${basePath}.js`,\n `${basePath}.jsx`,\n path.join(basePath, 'index.ts'),\n path.join(basePath, 'index.tsx'),\n path.join(basePath, 'index.mjs'),\n path.join(basePath, 'index.cjs'),\n path.join(basePath, 'index.js'),\n path.join(basePath, 'index.jsx'),\n ];\n\n return candidates.find((candidate) => isExistingFile(candidate)) ?? null;\n};\n\nconst findNearestTypeScriptConfig = (sourceFilePath: string): string | null => {\n const sourceDir = path.dirname(sourceFilePath);\n const cached = tsConfigPathCache.get(sourceDir);\n\n if (cached !== undefined) {\n return cached;\n }\n\n let currentDir = sourceDir;\n\n while (true) {\n const tsConfigPath = path.join(currentDir, 'tsconfig.json');\n if (isExistingFile(tsConfigPath)) {\n tsConfigPathCache.set(sourceDir, tsConfigPath);\n return tsConfigPath;\n }\n\n const jsConfigPath = path.join(currentDir, 'jsconfig.json');\n if (isExistingFile(jsConfigPath)) {\n tsConfigPathCache.set(sourceDir, jsConfigPath);\n return jsConfigPath;\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n tsConfigPathCache.set(sourceDir, null);\n return null;\n }\n\n currentDir = parentDir;\n }\n};\n\nconst getCompilerOptionsForSourceFile = (sourceFilePath: string): ts.CompilerOptions | null => {\n const configPath = findNearestTypeScriptConfig(sourceFilePath);\n if (!configPath) {\n return null;\n }\n\n const cached = compilerOptionsCache.get(configPath);\n if (cached !== undefined) {\n return cached;\n }\n\n const readResult = ts.readConfigFile(configPath, ts.sys.readFile);\n if (readResult.error) {\n compilerOptionsCache.set(configPath, null);\n return null;\n }\n\n const parsed = ts.parseJsonConfigFileContent(readResult.config, ts.sys, path.dirname(configPath));\n\n const compilerOptions =\n parsed.options.paths && !parsed.options.baseUrl\n ? { ...parsed.options, baseUrl: path.dirname(configPath) }\n : parsed.options;\n\n compilerOptionsCache.set(configPath, compilerOptions);\n return compilerOptions;\n};\n\nconst resolveConfigImportPath = (\n sourceFilePath: string,\n moduleSpecifier: string,\n): string | null => {\n if (hasImportQuery(moduleSpecifier)) {\n return null;\n }\n\n const compilerOptions = getCompilerOptionsForSourceFile(sourceFilePath);\n if (!compilerOptions) {\n return null;\n }\n\n const resolvedModule = ts.resolveModuleName(\n moduleSpecifier,\n sourceFilePath,\n compilerOptions,\n ts.sys,\n ).resolvedModule;\n\n if (!resolvedModule) {\n return null;\n }\n\n return isExistingFile(resolvedModule.resolvedFileName) ? resolvedModule.resolvedFileName : null;\n};\n\nconst resolveImportPath = (sourceFilePath: string, moduleSpecifier: string): string | null =>\n moduleSpecifier.startsWith('.')\n ? resolveRelativeImportPath(sourceFilePath, moduleSpecifier)\n : resolveConfigImportPath(sourceFilePath, moduleSpecifier);\n\nconst getImportedSourceFile = (filePath: string) => {\n const cached = importedSourceFileCache.get(filePath);\n if (cached) {\n return cached;\n }\n\n if (!fs.existsSync(filePath)) {\n return null;\n }\n\n const sourceFile = importedSourceProject.createSourceFile(\n filePath,\n fs.readFileSync(filePath, 'utf-8'),\n {\n overwrite: true,\n },\n );\n importedSourceFileCache.set(filePath, sourceFile);\n return sourceFile;\n};\n\nconst extractImportedIdentifierValues = (node: Node, visited: Set<Node>): string[] => {\n if (!Node.isIdentifier(node)) {\n return [];\n }\n\n const sourceFile = node.getSourceFile();\n const sourceFilePath = sourceFile.getFilePath();\n const importMatch = sourceFile\n .getImportDeclarations()\n .find((importDecl) =>\n importDecl\n .getNamedImports()\n .some(\n (namedImport) =>\n (namedImport.getAliasNode()?.getText() ?? namedImport.getName()) === node.getText(),\n ),\n );\n\n if (!importMatch) {\n return [];\n }\n\n const namedImport = importMatch\n .getNamedImports()\n .find(\n (candidate) =>\n (candidate.getAliasNode()?.getText() ?? candidate.getName()) === node.getText(),\n );\n\n if (!namedImport) {\n return [];\n }\n\n const resolvedPath = resolveImportPath(sourceFilePath, importMatch.getModuleSpecifierValue());\n if (!resolvedPath) {\n return [];\n }\n\n const importedSourceFile = getImportedSourceFile(resolvedPath);\n if (!importedSourceFile) {\n return [];\n }\n\n const declaration = importedSourceFile.getVariableDeclaration(namedImport.getName());\n const initializer = declaration?.getInitializer();\n return initializer ? extractStringLiterals(initializer, visited) : [];\n};\n\n/**\n * Extracts string literal values from an expression.\n *\n * Handles:\n * - Direct string literals: 'value'\n * - Ternary expressions: condition ? 'a' : 'b' -> ['a', 'b']\n * - Variable references: traces back to initializer\n * - Logical expressions: a || 'fallback', a ?? 'default'\n * - Function calls: traces to return statements\n * - Template literals: `value`\n * - As expressions: value as Type\n *\n * @param node The expression node to extract values from\n * @param visited Set of visited nodes to prevent infinite recursion\n * @returns Array of extracted string literal values\n */\nconst extractStringLiterals = (node: Node, visited: Set<Node> = new Set()): string[] => {\n if (visited.has(node)) {\n return [];\n }\n visited.add(node);\n\n const directValues = extractDirectLiteralValues(node);\n if (directValues) {\n return directValues;\n }\n\n const templateValues = extractTemplateExpressionValues(node, visited);\n if (templateValues) {\n return templateValues;\n }\n\n // Ternary/conditional expression: condition ? 'a' : 'b'\n if (Node.isConditionalExpression(node)) {\n return [\n ...extractStringLiterals(node.getWhenTrue(), visited),\n ...extractStringLiterals(node.getWhenFalse(), visited),\n ];\n }\n\n const binaryValues = extractBinaryExpressionValues(node, visited);\n if (binaryValues) {\n return binaryValues;\n }\n\n const wrappedExpressionValues = extractWrappedExpressionValues(node, visited);\n if (wrappedExpressionValues) {\n return wrappedExpressionValues;\n }\n\n const propertyAccessValues = extractPropertyAccessValues(node, visited);\n if (propertyAccessValues) {\n return propertyAccessValues;\n }\n\n const elementAccessValues = extractElementAccessValues(node, visited);\n if (elementAccessValues) {\n return elementAccessValues;\n }\n\n const callExpressionValues = extractCallExpressionValues(node, visited);\n if (callExpressionValues) {\n return callExpressionValues;\n }\n\n const identifierValues = extractIdentifierValues(node, visited);\n if (identifierValues) {\n return identifierValues;\n }\n\n return [];\n};\n\nconst extractDirectLiteralValues = (node: Node): string[] | null => {\n if (Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)) {\n return [node.getLiteralValue()];\n }\n\n return null;\n};\n\nconst extractTemplateExpressionValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isTemplateExpression(node)) {\n return null;\n }\n\n const parts: string[][] = [[node.getHead().getLiteralText()]];\n\n node.getTemplateSpans().forEach((span) => {\n const exprValues = extractStringLiterals(span.getExpression(), visited);\n const literalText = span.getLiteral().getLiteralText();\n parts.push(\n exprValues.length > 0\n ? exprValues.map((value) => `${value}${literalText}`)\n : ['', literalText],\n );\n });\n\n return parts\n .reduce<\n string[]\n >((acc, segment) => acc.flatMap((base) => segment.map((frag) => `${base}${frag}`)), [''])\n .filter((value) => value.length > 0);\n};\n\nconst extractBinaryExpressionValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isBinaryExpression(node)) {\n return null;\n }\n\n const operator = node.getOperatorToken().getText();\n if (operator === '+') {\n const left = extractStringLiterals(node.getLeft(), visited);\n const right = extractStringLiterals(node.getRight(), visited);\n const combined = left.flatMap((l) => right.map((r) => `${l}${r}`));\n return combined.length > 0 ? combined : [];\n }\n\n if (operator === '||' || operator === '??') {\n return [\n ...extractStringLiterals(node.getLeft(), visited),\n ...extractStringLiterals(node.getRight(), visited),\n ];\n }\n\n return [];\n};\n\nconst extractWrappedExpressionValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (Node.isParenthesizedExpression(node) || Node.isAsExpression(node)) {\n return extractStringLiterals(node.getExpression(), visited);\n }\n\n return null;\n};\n\nconst extractPropertyAccessValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isPropertyAccessExpression(node)) {\n return null;\n }\n\n const typeValues = extractLiteralValuesFromType(node);\n if (typeValues.length > 0) {\n return typeValues;\n }\n\n const propertyName = node.getName();\n return extractObjectValues(node.getExpression(), visited)\n .filter(\n (value): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && propertyName in value,\n )\n .map((value) => value[propertyName])\n .filter((value): value is string => typeof value === 'string');\n};\n\nconst extractElementAccessValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isElementAccessExpression(node)) {\n return null;\n }\n\n const typeValues = extractLiteralValuesFromType(node);\n if (typeValues.length > 0) {\n return typeValues;\n }\n\n const expression = node.getExpression();\n return extractObjectValues(expression, visited).flatMap((value) => {\n if (typeof value === 'string') {\n return [value];\n }\n\n if (typeof value === 'object' && value !== null) {\n return Object.values(value).filter((entry): entry is string => typeof entry === 'string');\n }\n\n return [];\n });\n};\n\nconst extractCallExpressionValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isCallExpression(node)) {\n return null;\n }\n\n const expression = node.getExpression();\n\n const fromDefinitions = Node.isIdentifier(expression)\n ? getDefinitionNodesSafe(expression).flatMap((definition) => {\n if (Node.isFunctionDeclaration(definition)) {\n return definition\n .getDescendantsOfKind(SyntaxKind.ReturnStatement)\n .flatMap((returnStmt) => {\n const expression = returnStmt.getExpression();\n return expression ? extractStringLiterals(expression, visited) : [];\n });\n }\n\n if (Node.isVariableDeclaration(definition)) {\n const initializer = definition.getInitializer();\n return initializer ? extractFromFunctionLike(initializer, visited) : [];\n }\n\n return [];\n })\n : [];\n\n const fromArguments = node.getArguments().flatMap((arg) => extractStringLiterals(arg, visited));\n\n return [...fromDefinitions, ...fromArguments];\n};\n\nconst extractArrayElementValues = (node: Node, visited: Set<Node>): string[] => {\n if (Node.isArrayLiteralExpression(node)) {\n return node\n .getElements()\n .flatMap((element) => extractStringLiterals(element, visited))\n .filter((value, index, values) => values.indexOf(value) === index);\n }\n\n if (Node.isParenthesizedExpression(node)) {\n return extractArrayElementValues(node.getExpression(), visited);\n }\n\n if (Node.isAsExpression(node) || Node.isTypeAssertion(node) || Node.isSatisfiesExpression(node)) {\n return extractArrayElementValues(node.getExpression(), visited);\n }\n\n if (Node.isIdentifier(node)) {\n return node\n .getDefinitionNodes()\n .flatMap((definition) => {\n if (Node.isVariableDeclaration(definition)) {\n const initializer = definition.getInitializer();\n return initializer ? extractArrayElementValues(initializer, visited) : [];\n }\n\n return [];\n })\n .filter((value, index, values) => values.indexOf(value) === index);\n }\n\n return [];\n};\n\nconst extractMappedParameterValues = (definition: Node, visited: Set<Node>): string[] => {\n if (!Node.isParameterDeclaration(definition)) {\n return [];\n }\n\n const callback = definition.getParentIfKind(SyntaxKind.ArrowFunction);\n if (!callback) {\n return [];\n }\n\n const callExpression = callback.getParentIfKind(SyntaxKind.CallExpression);\n if (!callExpression) {\n return [];\n }\n\n const expression = callExpression.getExpression();\n if (!Node.isPropertyAccessExpression(expression)) {\n return [];\n }\n\n if (!['map', 'flatMap'].includes(expression.getName())) {\n return [];\n }\n\n const parameterIndex = callback\n .getParameters()\n .findIndex(\n (parameter) => parameter.getNameNode().getText() === definition.getNameNode().getText(),\n );\n\n if (parameterIndex !== 0) {\n return [];\n }\n\n return extractArrayElementValues(expression.getExpression(), visited);\n};\n\nconst extractIdentifierValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isIdentifier(node)) {\n return null;\n }\n\n const values = getDefinitionNodesSafe(node).flatMap((definition) => {\n const mappedParameterValues = extractMappedParameterValues(definition, visited);\n if (mappedParameterValues.length > 0) {\n return mappedParameterValues;\n }\n\n if (\n Node.isVariableDeclaration(definition) ||\n Node.isParameterDeclaration(definition) ||\n Node.isBindingElement(definition)\n ) {\n const initializer = definition.getInitializer();\n return initializer ? extractStringLiterals(initializer, visited) : [];\n }\n\n return [];\n });\n\n if (values.length > 0) {\n return values;\n }\n\n const importedValues = extractImportedIdentifierValues(node, visited);\n if (importedValues.length > 0) {\n return importedValues;\n }\n\n return extractLiteralValuesFromType(node);\n};\n\n/**\n * Extract string literals from arrow functions or function expressions\n */\nconst extractFromFunctionLike = (node: Node, visited: Set<Node>): string[] => {\n const values: string[] = [];\n\n if (Node.isArrowFunction(node)) {\n const body = node.getBody();\n if (Node.isBlock(body)) {\n body.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {\n const returnExpr = returnStmt.getExpression();\n if (returnExpr) {\n values.push(...extractStringLiterals(returnExpr, visited));\n }\n });\n } else {\n values.push(...extractStringLiterals(body, visited));\n }\n } else if (Node.isFunctionExpression(node)) {\n node.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {\n const returnExpr = returnStmt.getExpression();\n if (returnExpr) {\n values.push(...extractStringLiterals(returnExpr, visited));\n }\n });\n }\n\n return values;\n};\n\n/**\n * Extract object literal values from an expression.\n * Returns an array of all possible object values (for union types or indexed access).\n */\nconst extractObjectValues = (node: Node, visited: Set<Node>): unknown[] => {\n if (visited.has(node)) {\n return [];\n }\n visited.add(node);\n\n const values: unknown[] = [];\n\n // Object literal expression\n if (Node.isObjectLiteralExpression(node)) {\n const obj: Record<string, unknown> = {};\n node.getProperties().forEach((prop) => {\n if (Node.isPropertyAssignment(prop)) {\n const name = prop.getName();\n const init = prop.getInitializer();\n if (init && Node.isStringLiteral(init)) {\n obj[name] = init.getLiteralValue();\n } else if (init && Node.isObjectLiteralExpression(init)) {\n const nestedValues = extractObjectValues(init, visited);\n if (nestedValues.length > 0) {\n obj[name] = nestedValues[0];\n }\n }\n }\n });\n values.push(obj);\n return values;\n }\n\n // Identifier - trace to initializer\n if (Node.isIdentifier(node)) {\n getDefinitionNodesSafe(node).forEach((definition) => {\n if (Node.isVariableDeclaration(definition)) {\n const initializer = definition.getInitializer();\n if (initializer) {\n // Handle 'as const' assertion\n if (Node.isAsExpression(initializer)) {\n const inner = initializer.getExpression();\n values.push(...extractObjectValues(inner, visited));\n } else {\n values.push(...extractObjectValues(initializer, visited));\n }\n }\n }\n });\n return values;\n }\n\n // Element access - return all values from the object\n if (Node.isElementAccessExpression(node)) {\n const expression = node.getExpression();\n const baseObjects = extractObjectValues(expression, visited);\n\n // For indexed access, return all possible values\n baseObjects.forEach((obj) => {\n if (typeof obj === 'object' && obj !== null) {\n Object.values(obj).forEach((value) => values.push(value));\n }\n });\n return values;\n }\n\n return values;\n};\n\n/**\n * Extract literal values from a TypeScript type (for union types like 'brand' | 'secondary')\n */\nexport const extractLiteralValuesFromType = (node: Node): string[] => {\n const values: string[] = [];\n const nodeType = node.getType();\n\n if (nodeType.isUnion()) {\n nodeType.getUnionTypes().forEach((unionMember) => {\n if (unionMember.isStringLiteral()) {\n values.push(unionMember.getLiteralValue() as string);\n }\n });\n } else if (nodeType.isStringLiteral()) {\n values.push(nodeType.getLiteralValue() as string);\n }\n\n return values;\n};\n\nexport { extractStringLiterals };\n"],"mappings":"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"}
1
+ {"version":3,"file":"expressions.js","names":[],"sources":["../../../../src/purger/optimized/ast/expressions.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { Identifier } from 'ts-morph';\nimport { Node, Project, SyntaxKind, ts } from 'ts-morph';\n\nconst importedSourceProject = new Project({ useInMemoryFileSystem: true });\nconst importedSourceFileCache = new Map<string, ReturnType<Project['createSourceFile']>>();\nconst tsConfigPathCache = new Map<string, string | null>();\nconst compilerOptionsCache = new Map<string, ts.CompilerOptions | null>();\nconst hasImportQuery = (moduleSpecifier: string): boolean => moduleSpecifier.includes('?');\n\nconst getLocalDefinitionNodes = (node: Node): Node[] => {\n if (!Node.isIdentifier(node)) {\n return [];\n }\n\n const name = node.getText();\n const nodeStart = node.getStart();\n const sourceFile = node.getSourceFile();\n\n const matches = [\n ...sourceFile\n .getDescendantsOfKind(SyntaxKind.VariableDeclaration)\n .filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),\n ...sourceFile\n .getDescendantsOfKind(SyntaxKind.Parameter)\n .filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),\n ...sourceFile\n .getDescendantsOfKind(SyntaxKind.BindingElement)\n .filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),\n ...sourceFile\n .getFunctions()\n .filter((definition) => definition.getName() === name && definition.getStart() <= nodeStart),\n ];\n\n return matches.sort((left, right) => right.getStart() - left.getStart()).slice(0, 1);\n};\n\nconst getDefinitionNodesSafe = (node: Identifier): Node[] => {\n return getLocalDefinitionNodes(node);\n};\n\nconst isExistingFile = (candidate: string): boolean =>\n fs.existsSync(candidate) && fs.statSync(candidate).isFile();\n\nconst resolveRelativeImportPath = (\n sourceFilePath: string,\n moduleSpecifier: string,\n): string | null => {\n if (\n !path.isAbsolute(sourceFilePath) ||\n !moduleSpecifier.startsWith('.') ||\n hasImportQuery(moduleSpecifier)\n ) {\n return null;\n }\n\n const basePath = path.resolve(path.dirname(sourceFilePath), moduleSpecifier);\n const candidates = [\n basePath,\n `${basePath}.ts`,\n `${basePath}.tsx`,\n `${basePath}.mjs`,\n `${basePath}.cjs`,\n `${basePath}.js`,\n `${basePath}.jsx`,\n path.join(basePath, 'index.ts'),\n path.join(basePath, 'index.tsx'),\n path.join(basePath, 'index.mjs'),\n path.join(basePath, 'index.cjs'),\n path.join(basePath, 'index.js'),\n path.join(basePath, 'index.jsx'),\n ];\n\n return candidates.find((candidate) => isExistingFile(candidate)) ?? null;\n};\n\nconst findNearestTypeScriptConfig = (sourceFilePath: string): string | null => {\n const sourceDir = path.dirname(sourceFilePath);\n const cached = tsConfigPathCache.get(sourceDir);\n\n if (cached !== undefined) {\n return cached;\n }\n\n let currentDir = sourceDir;\n\n while (true) {\n const tsConfigPath = path.join(currentDir, 'tsconfig.json');\n if (isExistingFile(tsConfigPath)) {\n tsConfigPathCache.set(sourceDir, tsConfigPath);\n return tsConfigPath;\n }\n\n const jsConfigPath = path.join(currentDir, 'jsconfig.json');\n if (isExistingFile(jsConfigPath)) {\n tsConfigPathCache.set(sourceDir, jsConfigPath);\n return jsConfigPath;\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n tsConfigPathCache.set(sourceDir, null);\n return null;\n }\n\n currentDir = parentDir;\n }\n};\n\nconst getCompilerOptionsForSourceFile = (sourceFilePath: string): ts.CompilerOptions | null => {\n const configPath = findNearestTypeScriptConfig(sourceFilePath);\n if (!configPath) {\n return null;\n }\n\n const cached = compilerOptionsCache.get(configPath);\n if (cached !== undefined) {\n return cached;\n }\n\n const readResult = ts.readConfigFile(configPath, ts.sys.readFile);\n if (readResult.error) {\n compilerOptionsCache.set(configPath, null);\n return null;\n }\n\n const parsed = ts.parseJsonConfigFileContent(readResult.config, ts.sys, path.dirname(configPath));\n\n const compilerOptions =\n parsed.options.paths && !parsed.options.baseUrl\n ? { ...parsed.options, baseUrl: path.dirname(configPath) }\n : parsed.options;\n\n compilerOptionsCache.set(configPath, compilerOptions);\n return compilerOptions;\n};\n\nconst resolveConfigImportPath = (\n sourceFilePath: string,\n moduleSpecifier: string,\n): string | null => {\n if (hasImportQuery(moduleSpecifier)) {\n return null;\n }\n\n const compilerOptions = getCompilerOptionsForSourceFile(sourceFilePath);\n if (!compilerOptions) {\n return null;\n }\n\n const resolvedModule = ts.resolveModuleName(\n moduleSpecifier,\n sourceFilePath,\n compilerOptions,\n ts.sys,\n ).resolvedModule;\n\n if (!resolvedModule) {\n return null;\n }\n\n return isExistingFile(resolvedModule.resolvedFileName) ? resolvedModule.resolvedFileName : null;\n};\n\nconst resolveImportPath = (sourceFilePath: string, moduleSpecifier: string): string | null =>\n moduleSpecifier.startsWith('.')\n ? resolveRelativeImportPath(sourceFilePath, moduleSpecifier)\n : resolveConfigImportPath(sourceFilePath, moduleSpecifier);\n\nconst getImportedSourceFile = (filePath: string) => {\n const cached = importedSourceFileCache.get(filePath);\n if (cached) {\n return cached;\n }\n\n if (!fs.existsSync(filePath)) {\n return null;\n }\n\n const sourceFile = importedSourceProject.createSourceFile(\n filePath,\n fs.readFileSync(filePath, 'utf-8'),\n {\n overwrite: true,\n },\n );\n importedSourceFileCache.set(filePath, sourceFile);\n return sourceFile;\n};\n\nconst extractImportedIdentifierValues = (node: Node, visited: Set<Node>): string[] => {\n if (!Node.isIdentifier(node)) {\n return [];\n }\n\n const sourceFile = node.getSourceFile();\n const sourceFilePath = sourceFile.getFilePath();\n const importMatch = sourceFile\n .getImportDeclarations()\n .find((importDecl) =>\n importDecl\n .getNamedImports()\n .some(\n (namedImport) =>\n (namedImport.getAliasNode()?.getText() ?? namedImport.getName()) === node.getText(),\n ),\n );\n\n if (!importMatch) {\n return [];\n }\n\n const namedImport = importMatch\n .getNamedImports()\n .find(\n (candidate) =>\n (candidate.getAliasNode()?.getText() ?? candidate.getName()) === node.getText(),\n );\n\n if (!namedImport) {\n return [];\n }\n\n const resolvedPath = resolveImportPath(sourceFilePath, importMatch.getModuleSpecifierValue());\n if (!resolvedPath) {\n return [];\n }\n\n const importedSourceFile = getImportedSourceFile(resolvedPath);\n if (!importedSourceFile) {\n return [];\n }\n\n const declaration = importedSourceFile.getVariableDeclaration(namedImport.getName());\n const initializer = declaration?.getInitializer();\n return initializer ? extractStringLiterals(initializer, visited) : [];\n};\n\n/**\n * Extracts string literal values from an expression.\n *\n * Handles:\n * - Direct string literals: 'value'\n * - Ternary expressions: condition ? 'a' : 'b' -> ['a', 'b']\n * - Variable references: traces back to initializer\n * - Logical expressions: a || 'fallback', a ?? 'default'\n * - Function calls: traces to return statements\n * - Template literals: `value`\n * - As expressions: value as Type\n *\n * @param node The expression node to extract values from\n * @param visited Set of visited nodes to prevent infinite recursion\n * @returns Array of extracted string literal values\n */\nconst extractStringLiterals = (node: Node, visited: Set<Node> = new Set()): string[] => {\n if (visited.has(node)) {\n return [];\n }\n visited.add(node);\n\n const directValues = extractDirectLiteralValues(node);\n if (directValues) {\n return directValues;\n }\n\n const templateValues = extractTemplateExpressionValues(node, visited);\n if (templateValues) {\n return templateValues;\n }\n\n // Ternary/conditional expression: condition ? 'a' : 'b'\n if (Node.isConditionalExpression(node)) {\n return [\n ...extractStringLiterals(node.getWhenTrue(), visited),\n ...extractStringLiterals(node.getWhenFalse(), visited),\n ];\n }\n\n const binaryValues = extractBinaryExpressionValues(node, visited);\n if (binaryValues) {\n return binaryValues;\n }\n\n const wrappedExpressionValues = extractWrappedExpressionValues(node, visited);\n if (wrappedExpressionValues) {\n return wrappedExpressionValues;\n }\n\n const propertyAccessValues = extractPropertyAccessValues(node, visited);\n if (propertyAccessValues) {\n return propertyAccessValues;\n }\n\n const elementAccessValues = extractElementAccessValues(node, visited);\n if (elementAccessValues) {\n return elementAccessValues;\n }\n\n const callExpressionValues = extractCallExpressionValues(node, visited);\n if (callExpressionValues) {\n return callExpressionValues;\n }\n\n const identifierValues = extractIdentifierValues(node, visited);\n if (identifierValues) {\n return identifierValues;\n }\n\n return [];\n};\n\nconst extractDirectLiteralValues = (node: Node): string[] | null => {\n if (Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)) {\n return [node.getLiteralValue()];\n }\n\n return null;\n};\n\nconst extractTemplateExpressionValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isTemplateExpression(node)) {\n return null;\n }\n\n const parts: string[][] = [[node.getHead().getLiteralText()]];\n\n node.getTemplateSpans().forEach((span) => {\n const exprValues = extractStringLiterals(span.getExpression(), visited);\n const literalText = span.getLiteral().getLiteralText();\n parts.push(\n exprValues.length > 0\n ? exprValues.map((value) => `${value}${literalText}`)\n : ['', literalText],\n );\n });\n\n return parts\n .reduce<\n string[]\n >((acc, segment) => acc.flatMap((base) => segment.map((frag) => `${base}${frag}`)), [''])\n .filter((value) => value.length > 0);\n};\n\nconst extractBinaryExpressionValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isBinaryExpression(node)) {\n return null;\n }\n\n const operator = node.getOperatorToken().getText();\n if (operator === '+') {\n const left = extractStringLiterals(node.getLeft(), visited);\n const right = extractStringLiterals(node.getRight(), visited);\n const combined = left.flatMap((l) => right.map((r) => `${l}${r}`));\n return combined.length > 0 ? combined : [];\n }\n\n if (operator === '||' || operator === '??') {\n return [\n ...extractStringLiterals(node.getLeft(), visited),\n ...extractStringLiterals(node.getRight(), visited),\n ];\n }\n\n return [];\n};\n\nconst extractWrappedExpressionValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (Node.isParenthesizedExpression(node) || Node.isAsExpression(node)) {\n return extractStringLiterals(node.getExpression(), visited);\n }\n\n return null;\n};\n\nconst extractPropertyAccessValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isPropertyAccessExpression(node)) {\n return null;\n }\n\n const typeValues = extractLiteralValuesFromType(node);\n if (typeValues.length > 0) {\n return typeValues;\n }\n\n const propertyName = node.getName();\n return extractObjectValues(node.getExpression(), visited)\n .filter(\n (value): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && propertyName in value,\n )\n .map((value) => value[propertyName])\n .filter((value): value is string => typeof value === 'string');\n};\n\nconst extractElementAccessValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isElementAccessExpression(node)) {\n return null;\n }\n\n const typeValues = extractLiteralValuesFromType(node);\n if (typeValues.length > 0) {\n return typeValues;\n }\n\n const expression = node.getExpression();\n return extractObjectValues(expression, visited).flatMap((value) => {\n if (typeof value === 'string') {\n return [value];\n }\n\n if (typeof value === 'object' && value !== null) {\n return Object.values(value).filter((entry): entry is string => typeof entry === 'string');\n }\n\n return [];\n });\n};\n\nconst extractCallExpressionValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isCallExpression(node)) {\n return null;\n }\n\n const expression = node.getExpression();\n\n const fromDefinitions = Node.isIdentifier(expression)\n ? getDefinitionNodesSafe(expression).flatMap((definition) => {\n if (Node.isFunctionDeclaration(definition)) {\n return definition\n .getDescendantsOfKind(SyntaxKind.ReturnStatement)\n .flatMap((returnStmt) => {\n const expression = returnStmt.getExpression();\n return expression ? extractStringLiterals(expression, visited) : [];\n });\n }\n\n if (Node.isVariableDeclaration(definition)) {\n const initializer = definition.getInitializer();\n return initializer ? extractFromFunctionLike(initializer, visited) : [];\n }\n\n return [];\n })\n : [];\n\n const fromArguments = node.getArguments().flatMap((arg) => extractStringLiterals(arg, visited));\n\n return [...fromDefinitions, ...fromArguments];\n};\n\nconst extractArrayElementValues = (node: Node, visited: Set<Node>): string[] => {\n if (Node.isArrayLiteralExpression(node)) {\n return node\n .getElements()\n .flatMap((element) => extractStringLiterals(element, visited))\n .filter((value, index, values) => values.indexOf(value) === index);\n }\n\n if (Node.isParenthesizedExpression(node)) {\n return extractArrayElementValues(node.getExpression(), visited);\n }\n\n if (Node.isAsExpression(node) || Node.isTypeAssertion(node) || Node.isSatisfiesExpression(node)) {\n return extractArrayElementValues(node.getExpression(), visited);\n }\n\n if (Node.isIdentifier(node)) {\n return getLocalDefinitionNodes(node)\n .flatMap((definition) => {\n if (Node.isVariableDeclaration(definition)) {\n const initializer = definition.getInitializer();\n return initializer ? extractArrayElementValues(initializer, visited) : [];\n }\n\n return [];\n })\n .filter((value, index, values) => values.indexOf(value) === index);\n }\n\n return [];\n};\n\nconst extractMappedParameterValues = (definition: Node, visited: Set<Node>): string[] => {\n if (!Node.isParameterDeclaration(definition)) {\n return [];\n }\n\n const callback = definition.getParentIfKind(SyntaxKind.ArrowFunction);\n if (!callback) {\n return [];\n }\n\n const callExpression = callback.getParentIfKind(SyntaxKind.CallExpression);\n if (!callExpression) {\n return [];\n }\n\n const expression = callExpression.getExpression();\n if (!Node.isPropertyAccessExpression(expression)) {\n return [];\n }\n\n if (!['map', 'flatMap'].includes(expression.getName())) {\n return [];\n }\n\n const parameterIndex = callback\n .getParameters()\n .findIndex(\n (parameter) => parameter.getNameNode().getText() === definition.getNameNode().getText(),\n );\n\n if (parameterIndex !== 0) {\n return [];\n }\n\n return extractArrayElementValues(expression.getExpression(), visited);\n};\n\nconst extractIdentifierValues = (node: Node, visited: Set<Node>): string[] | null => {\n if (!Node.isIdentifier(node)) {\n return null;\n }\n\n const values = getDefinitionNodesSafe(node).flatMap((definition) => {\n const mappedParameterValues = extractMappedParameterValues(definition, visited);\n if (mappedParameterValues.length > 0) {\n return mappedParameterValues;\n }\n\n if (\n Node.isVariableDeclaration(definition) ||\n Node.isParameterDeclaration(definition) ||\n Node.isBindingElement(definition)\n ) {\n const initializer = definition.getInitializer();\n if (initializer) {\n return extractStringLiterals(initializer, visited);\n }\n\n // For BindingElement without initializer (e.g. `const { prop } = fn()`),\n // trace through the parent destructuring to resolve possible values.\n if (Node.isBindingElement(definition)) {\n const bindingPattern = definition.getParent();\n if (Node.isObjectBindingPattern(bindingPattern)) {\n const parentDecl = bindingPattern.getParent();\n if (Node.isVariableDeclaration(parentDecl)) {\n const parentInit = parentDecl.getInitializer();\n if (parentInit) {\n const propName = definition.getNameNode().getText();\n const objects = extractObjectValues(parentInit, new Set(visited));\n const propValues = objects\n .filter(\n (obj): obj is Record<string, unknown> =>\n typeof obj === 'object' && obj !== null && propName in obj,\n )\n .map((obj) => obj[propName])\n .filter((v): v is string => typeof v === 'string');\n if (propValues.length > 0) {\n return propValues;\n }\n }\n }\n }\n }\n\n return [];\n }\n\n return [];\n });\n\n if (values.length > 0) {\n return values;\n }\n\n const importedValues = extractImportedIdentifierValues(node, visited);\n if (importedValues.length > 0) {\n return importedValues;\n }\n\n return extractLiteralValuesFromType(node);\n};\n\n/**\n * Extract string literals from arrow functions or function expressions\n */\nconst extractFromFunctionLike = (node: Node, visited: Set<Node>): string[] => {\n const values: string[] = [];\n\n if (Node.isArrowFunction(node)) {\n const body = node.getBody();\n if (Node.isBlock(body)) {\n body.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {\n const returnExpr = returnStmt.getExpression();\n if (returnExpr) {\n values.push(...extractStringLiterals(returnExpr, visited));\n }\n });\n } else {\n values.push(...extractStringLiterals(body, visited));\n }\n } else if (Node.isFunctionExpression(node)) {\n node.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {\n const returnExpr = returnStmt.getExpression();\n if (returnExpr) {\n values.push(...extractStringLiterals(returnExpr, visited));\n }\n });\n }\n\n return values;\n};\n\n/**\n * Extract object literal values from an expression.\n * Returns an array of all possible object values (for union types or indexed access).\n */\nconst extractObjectValues = (node: Node, visited: Set<Node>): unknown[] => {\n if (visited.has(node)) {\n return [];\n }\n visited.add(node);\n\n const values: unknown[] = [];\n\n // Object literal expression\n if (Node.isObjectLiteralExpression(node)) {\n const obj: Record<string, unknown> = {};\n node.getProperties().forEach((prop) => {\n if (Node.isPropertyAssignment(prop)) {\n const name = prop.getName();\n const init = prop.getInitializer();\n if (init && Node.isStringLiteral(init)) {\n obj[name] = init.getLiteralValue();\n } else if (init && Node.isObjectLiteralExpression(init)) {\n const nestedValues = extractObjectValues(init, visited);\n if (nestedValues.length > 0) {\n obj[name] = nestedValues[0];\n }\n }\n }\n });\n values.push(obj);\n return values;\n }\n\n // Identifier - trace to initializer\n if (Node.isIdentifier(node)) {\n getDefinitionNodesSafe(node).forEach((definition) => {\n if (Node.isVariableDeclaration(definition)) {\n const initializer = definition.getInitializer();\n if (initializer) {\n // Handle 'as const' assertion\n if (Node.isAsExpression(initializer)) {\n const inner = initializer.getExpression();\n values.push(...extractObjectValues(inner, visited));\n } else {\n values.push(...extractObjectValues(initializer, visited));\n }\n }\n }\n });\n return values;\n }\n\n // Call expression - trace to function return statements\n if (Node.isCallExpression(node)) {\n const expression = node.getExpression();\n if (Node.isIdentifier(expression)) {\n getDefinitionNodesSafe(expression).forEach((definition) => {\n if (Node.isFunctionDeclaration(definition)) {\n definition.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {\n const returnExpr = returnStmt.getExpression();\n if (returnExpr) {\n values.push(...extractObjectValues(returnExpr, visited));\n }\n });\n }\n if (Node.isVariableDeclaration(definition)) {\n const initializer = definition.getInitializer();\n if (initializer) {\n const extractFromFn = (fn: Node) => {\n if (Node.isArrowFunction(fn)) {\n const body = fn.getBody();\n if (Node.isBlock(body)) {\n body.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {\n const returnExpr = returnStmt.getExpression();\n if (returnExpr) {\n values.push(...extractObjectValues(returnExpr, visited));\n }\n });\n } else {\n values.push(...extractObjectValues(body, visited));\n }\n } else if (Node.isFunctionExpression(fn)) {\n fn.getDescendantsOfKind(SyntaxKind.ReturnStatement).forEach((returnStmt) => {\n const returnExpr = returnStmt.getExpression();\n if (returnExpr) {\n values.push(...extractObjectValues(returnExpr, visited));\n }\n });\n }\n };\n extractFromFn(initializer);\n }\n }\n });\n }\n return values;\n }\n\n // Element access - return all values from the object\n if (Node.isElementAccessExpression(node)) {\n const expression = node.getExpression();\n const baseObjects = extractObjectValues(expression, visited);\n\n // For indexed access, return all possible values\n baseObjects.forEach((obj) => {\n if (typeof obj === 'object' && obj !== null) {\n Object.values(obj).forEach((value) => values.push(value));\n }\n });\n return values;\n }\n\n return values;\n};\n\n/**\n * Extract string literal values from a TypeScript type annotation AST node.\n * Pure AST traversal — avoids expensive TS Language Service `getType()` calls.\n */\nconst extractStringLiteralsFromTypeNode = (typeNode: Node): string[] => {\n if (Node.isLiteralTypeNode(typeNode)) {\n const literal = typeNode.getLiteral();\n if (Node.isStringLiteral(literal)) {\n return [literal.getLiteralValue()];\n }\n return [];\n }\n if (Node.isUnionTypeNode(typeNode)) {\n return typeNode.getTypeNodes().flatMap(extractStringLiteralsFromTypeNode);\n }\n return [];\n};\n\n/**\n * Extract literal values from a TypeScript type annotation (for union types like 'brand' | 'secondary').\n * Uses pure AST traversal instead of the TS type checker to avoid expensive LS initialization.\n */\nexport const extractLiteralValuesFromType = (node: Node): string[] => {\n // For identifiers, find the declaration and check its type annotation\n if (Node.isIdentifier(node)) {\n const definitions = getLocalDefinitionNodes(node);\n for (const def of definitions) {\n if (\n Node.isParameterDeclaration(def) ||\n Node.isVariableDeclaration(def) ||\n Node.isPropertyDeclaration(def) ||\n Node.isPropertySignature(def)\n ) {\n const typeNode = def.getTypeNode?.();\n if (typeNode) {\n const values = extractStringLiteralsFromTypeNode(typeNode);\n if (values.length > 0) {\n return values;\n }\n }\n }\n\n // For BindingElements, check the parent destructuring's type annotation\n // e.g. `const { prop }: { prop: 'a' | 'b' } = ...`\n if (Node.isBindingElement(def)) {\n const bindingPattern = def.getParent();\n if (bindingPattern) {\n const parentDecl = bindingPattern.getParent();\n if (parentDecl && Node.isVariableDeclaration(parentDecl)) {\n const parentType = parentDecl.getTypeNode();\n if (parentType && Node.isTypeLiteral(parentType)) {\n const propName = def.getNameNode().getText();\n for (const member of parentType.getMembers()) {\n if (Node.isPropertySignature(member) && member.getName() === propName) {\n const memberType = member.getTypeNode();\n if (memberType) {\n const values = extractStringLiteralsFromTypeNode(memberType);\n if (values.length > 0) {\n return values;\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n\n // For property access and element access, check if the expression has a type annotation\n if (Node.isPropertyAccessExpression(node) || Node.isElementAccessExpression(node)) {\n // These are complex to resolve via AST alone — let the existing AST-based\n // object extraction handle them instead of calling the type checker\n return [];\n }\n\n return [];\n};\n\nexport { extractStringLiterals };\n"],"mappings":"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"}