@saidksi/localizer-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +164 -0
  3. package/dist/ai/anthropic.d.ts +17 -0
  4. package/dist/ai/anthropic.d.ts.map +1 -0
  5. package/dist/ai/anthropic.js +58 -0
  6. package/dist/ai/anthropic.js.map +1 -0
  7. package/dist/ai/dedup.d.ts +19 -0
  8. package/dist/ai/dedup.d.ts.map +1 -0
  9. package/dist/ai/dedup.js +119 -0
  10. package/dist/ai/dedup.js.map +1 -0
  11. package/dist/ai/index.d.ts +65 -0
  12. package/dist/ai/index.d.ts.map +1 -0
  13. package/dist/ai/index.js +464 -0
  14. package/dist/ai/index.js.map +1 -0
  15. package/dist/ai/openai.d.ts +11 -0
  16. package/dist/ai/openai.d.ts.map +1 -0
  17. package/dist/ai/openai.js +62 -0
  18. package/dist/ai/openai.js.map +1 -0
  19. package/dist/ai/prompts.d.ts +20 -0
  20. package/dist/ai/prompts.d.ts.map +1 -0
  21. package/dist/ai/prompts.js +151 -0
  22. package/dist/ai/prompts.js.map +1 -0
  23. package/dist/cache/index.d.ts +69 -0
  24. package/dist/cache/index.d.ts.map +1 -0
  25. package/dist/cache/index.js +129 -0
  26. package/dist/cache/index.js.map +1 -0
  27. package/dist/index.d.ts +8 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +14 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/rewriter/index.d.ts +31 -0
  32. package/dist/rewriter/index.d.ts.map +1 -0
  33. package/dist/rewriter/index.js +128 -0
  34. package/dist/rewriter/index.js.map +1 -0
  35. package/dist/rewriter/transforms.d.ts +38 -0
  36. package/dist/rewriter/transforms.d.ts.map +1 -0
  37. package/dist/rewriter/transforms.js +189 -0
  38. package/dist/rewriter/transforms.js.map +1 -0
  39. package/dist/rewriter/ts-morph.d.ts +19 -0
  40. package/dist/rewriter/ts-morph.d.ts.map +1 -0
  41. package/dist/rewriter/ts-morph.js +121 -0
  42. package/dist/rewriter/ts-morph.js.map +1 -0
  43. package/dist/scanner/babel.d.ts +3 -0
  44. package/dist/scanner/babel.d.ts.map +1 -0
  45. package/dist/scanner/babel.js +504 -0
  46. package/dist/scanner/babel.js.map +1 -0
  47. package/dist/scanner/filters.d.ts +38 -0
  48. package/dist/scanner/filters.d.ts.map +1 -0
  49. package/dist/scanner/filters.js +133 -0
  50. package/dist/scanner/filters.js.map +1 -0
  51. package/dist/scanner/index.d.ts +22 -0
  52. package/dist/scanner/index.d.ts.map +1 -0
  53. package/dist/scanner/index.js +82 -0
  54. package/dist/scanner/index.js.map +1 -0
  55. package/dist/scanner/typescript.d.ts +3 -0
  56. package/dist/scanner/typescript.d.ts.map +1 -0
  57. package/dist/scanner/typescript.js +542 -0
  58. package/dist/scanner/typescript.js.map +1 -0
  59. package/dist/types.d.ts +205 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +3 -0
  62. package/dist/types.js.map +1 -0
  63. package/dist/validator/index.d.ts +65 -0
  64. package/dist/validator/index.d.ts.map +1 -0
  65. package/dist/validator/index.js +237 -0
  66. package/dist/validator/index.js.map +1 -0
  67. package/package.json +65 -0
@@ -0,0 +1,542 @@
1
+ import ts from "typescript";
2
+ import { shouldFilter, NON_TRANSLATABLE_ATTRS, TRANSLATION_FNS, STATE_INITIALIZATION_FNS } from "./filters.js";
3
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
4
+ function getSurroundingLines(lines, zeroBasedLine) {
5
+ const start = Math.max(0, zeroBasedLine - 2);
6
+ const end = Math.min(lines.length - 1, zeroBasedLine + 2);
7
+ return lines.slice(start, end + 1).join("\n");
8
+ }
9
+ function getJSXElementName(node) {
10
+ return node.tagName.getText();
11
+ }
12
+ /** Walk ancestors to check if node is inside a translation call expression. */
13
+ function isInsideTranslationCall(node) {
14
+ let current = node;
15
+ while (current.parent) {
16
+ current = current.parent;
17
+ if (ts.isCallExpression(current)) {
18
+ const expr = current.expression;
19
+ // t("key"), $t("key"), formatMessage(...)
20
+ if (ts.isIdentifier(expr) && TRANSLATION_FNS.has(expr.text))
21
+ return true;
22
+ // i18n.t("key"), obj.formatMessage(...)
23
+ if (ts.isPropertyAccessExpression(expr) &&
24
+ TRANSLATION_FNS.has(expr.name.text))
25
+ return true;
26
+ }
27
+ }
28
+ return false;
29
+ }
30
+ /** Walk ancestors to check if node is inside a console.* call. */
31
+ function isInsideConsoleCall(node) {
32
+ let current = node;
33
+ while (current.parent) {
34
+ current = current.parent;
35
+ if (ts.isCallExpression(current)) {
36
+ const expr = current.expression;
37
+ if (ts.isPropertyAccessExpression(expr) &&
38
+ ts.isIdentifier(expr.expression) &&
39
+ expr.expression.text === "console")
40
+ return true;
41
+ }
42
+ }
43
+ return false;
44
+ }
45
+ /** Walk ancestors to check if node is inside an import declaration. */
46
+ function isInsideImport(node) {
47
+ let current = node;
48
+ while (current.parent) {
49
+ current = current.parent;
50
+ if (ts.isImportDeclaration(current))
51
+ return true;
52
+ }
53
+ return false;
54
+ }
55
+ /**
56
+ * Check if a node is inside a state initialization call like useState("default").
57
+ * These strings are default/placeholder values, not user-facing text.
58
+ */
59
+ function isInsideStateInitialization(node) {
60
+ let current = node;
61
+ while (current.parent) {
62
+ current = current.parent;
63
+ if (ts.isCallExpression(current)) {
64
+ const expr = current.expression;
65
+ if (ts.isIdentifier(expr) && STATE_INITIALIZATION_FNS.has(expr.text)) {
66
+ return true;
67
+ }
68
+ }
69
+ }
70
+ return false;
71
+ }
72
+ /** True if node is inside a function body (not at module/file scope). */
73
+ function isInsideFunctionBody(node) {
74
+ let current = node;
75
+ while (current.parent) {
76
+ current = current.parent;
77
+ if (ts.isFunctionDeclaration(current) ||
78
+ ts.isFunctionExpression(current) ||
79
+ ts.isArrowFunction(current) ||
80
+ ts.isMethodDeclaration(current)) {
81
+ return true;
82
+ }
83
+ }
84
+ return false;
85
+ }
86
+ /** True if node is inside a JSX element or JSX attribute. */
87
+ function isInsideJSXElement(node) {
88
+ let current = node;
89
+ while (current.parent) {
90
+ current = current.parent;
91
+ if (ts.isJsxElement(current) ||
92
+ ts.isJsxFragment(current) ||
93
+ ts.isJsxAttribute(current) ||
94
+ ts.isJsxOpeningElement(current) ||
95
+ ts.isJsxSelfClosingElement(current)) {
96
+ return true;
97
+ }
98
+ }
99
+ return false;
100
+ }
101
+ /**
102
+ * Detect if a StringLiteral is part of a BinaryExpression string concatenation chain.
103
+ * Returns the root BinaryExpression if yes, null otherwise.
104
+ * E.g., "Overview" + " — " + "Real-time data" → root BinaryExpression node
105
+ *
106
+ * For a chain like A + B + C (parsed as (A + B) + C), walks up to find the outermost
107
+ * BinaryExpression with a + operator.
108
+ */
109
+ function getRootConcatenationChain(node) {
110
+ let current = node;
111
+ let lastBinExpr = null;
112
+ // Walk up the tree to find if this node is part of a + chain
113
+ while (current.parent) {
114
+ const parent = current.parent;
115
+ if (ts.isBinaryExpression(parent)) {
116
+ const binExpr = parent;
117
+ if (binExpr.operatorToken.kind === ts.SyntaxKind.PlusToken) {
118
+ lastBinExpr = binExpr;
119
+ current = parent;
120
+ }
121
+ else {
122
+ // Non-+ operator — stop walking up
123
+ break;
124
+ }
125
+ }
126
+ else {
127
+ // Parent is not a BinaryExpression — stop walking up
128
+ break;
129
+ }
130
+ }
131
+ return lastBinExpr;
132
+ }
133
+ /**
134
+ * Collect all StringLiterals from a BinaryExpression chain, filtering out separators.
135
+ * Separators are strings that contain only whitespace, dashes, punctuation, etc.
136
+ * Returns array of meaningful strings only: ["Overview", "Real-time data"]
137
+ * Returns null if not a pure string chain or no meaningful strings remain.
138
+ *
139
+ * Separator pattern: only whitespace, dashes, em-dashes, commas, periods, etc.
140
+ */
141
+ function collectBinaryStringChain(binExpr) {
142
+ const allOperands = [];
143
+ const SEPARATOR_RE = /^[\s\-—,\.;:/|+*]+$/; // Only punctuation/whitespace
144
+ // Recursively collect all operands
145
+ function collect(node) {
146
+ if (ts.isStringLiteral(node)) {
147
+ allOperands.push(node.text);
148
+ return true;
149
+ }
150
+ else if (ts.isBinaryExpression(node)) {
151
+ const be = node;
152
+ if (be.operatorToken.kind !== ts.SyntaxKind.PlusToken)
153
+ return false;
154
+ return collect(be.left) && collect(be.right);
155
+ }
156
+ return false;
157
+ }
158
+ if (!collect(binExpr))
159
+ return null; // Not a pure string chain
160
+ if (allOperands.length < 2)
161
+ return null; // Single operand — not a concatenation
162
+ // Filter out separator-only strings
163
+ const meaningfulStrings = allOperands.filter((str) => str.trim() && !SEPARATOR_RE.test(str));
164
+ return meaningfulStrings.length > 0 ? meaningfulStrings : null;
165
+ }
166
+ /**
167
+ * For a PropertyAssignment node, walk up to find the parent object's variable name.
168
+ * e.g. const statusConfig = { online: "..." } → "statusConfig"
169
+ * Returns null if the object is not assigned to a variable.
170
+ */
171
+ function getObjectVariableName(propAssignNode, sourceFile) {
172
+ let current = propAssignNode.parent;
173
+ while (current) {
174
+ // Found the object literal that contains this property
175
+ if (ts.isObjectLiteralExpression(current)) {
176
+ const objParent = current.parent;
177
+ if (!objParent)
178
+ break;
179
+ // Check if it's a variable declaration: const name = {...}
180
+ if (ts.isVariableDeclaration(objParent)) {
181
+ const name = objParent.name.getText(sourceFile);
182
+ return name;
183
+ }
184
+ // Check if it's a property assignment: { name: {...} }
185
+ if (ts.isPropertyAssignment(objParent)) {
186
+ // Continue walking to find the parent object
187
+ current = objParent.parent;
188
+ continue;
189
+ }
190
+ // Stop if object is in some other context (function arg, return value, etc.)
191
+ break;
192
+ }
193
+ current = current.parent;
194
+ }
195
+ return null;
196
+ }
197
+ /**
198
+ * Determine context description for non-JSX string literals.
199
+ * Returns null if the string is in a non-user-facing position (e.g. type annotation).
200
+ */
201
+ function getNonJSXContext(node, sourceFile) {
202
+ const parent = node.parent;
203
+ // Function call argument: setError("..."), alert("..."), new Error("...")
204
+ if (ts.isCallExpression(parent) || ts.isNewExpression(parent)) {
205
+ const fnName = ts.isCallExpression(parent)
206
+ ? parent.expression.getText(sourceFile)
207
+ : parent.expression.getText(sourceFile);
208
+ return `argument in ${fnName}()`;
209
+ }
210
+ // Object property value: { title: "..." }
211
+ if (ts.isPropertyAssignment(parent)) {
212
+ const key = parent.name.getText(sourceFile);
213
+ return `object property "${key}"`;
214
+ }
215
+ // Variable declaration: const msg = "..."
216
+ if (ts.isVariableDeclaration(parent)) {
217
+ const name = parent.name.getText(sourceFile);
218
+ return `variable "${name}"`;
219
+ }
220
+ // Return statement: return "..."
221
+ if (ts.isReturnStatement(parent)) {
222
+ return "return value";
223
+ }
224
+ // Binary expression (string concatenation): "Hello " + name
225
+ if (ts.isBinaryExpression(parent)) {
226
+ return "string concatenation";
227
+ }
228
+ // Conditional expression: condition ? "Yes" : "No"
229
+ if (ts.isConditionalExpression(parent)) {
230
+ return "conditional expression";
231
+ }
232
+ // Skip type-level positions (type assertions, type annotations, decorators)
233
+ return null;
234
+ }
235
+ function makeResult(filePath, lines, sourceFile, node, value, nodeType, context, objectKey) {
236
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
237
+ const result = {
238
+ file: filePath,
239
+ line: line + 1, // convert to 1-based
240
+ column: character,
241
+ value,
242
+ nodeType,
243
+ context,
244
+ surroundingCode: getSurroundingLines(lines, line),
245
+ alreadyTranslated: false,
246
+ isModuleLevel: !isInsideFunctionBody(node),
247
+ resolvedKey: null,
248
+ };
249
+ if (objectKey) {
250
+ result.objectKey = objectKey;
251
+ }
252
+ return result;
253
+ }
254
+ // ─── JSX interpolation helpers ───────────────────────────────────────────────
255
+ /**
256
+ * Derive a clean placeholder name from a JSX expression source string.
257
+ * "taskCount" → "taskCount", "user.name" → "name", "getCount()" → "getCount"
258
+ */
259
+ function simplifyExpressionName(expr) {
260
+ let name = expr.replace(/\(.*\)/g, "").trim(); // strip call args
261
+ const parts = name.split(".");
262
+ name = parts[parts.length - 1]; // last property segment
263
+ name = name.replace(/\[.*\]/g, "").replace(/[^a-zA-Z0-9_]/g, ""); // strip brackets/specials
264
+ return name || "value";
265
+ }
266
+ /**
267
+ * Detect a JSXElement whose direct children are a mix of JSXText and
268
+ * JSXExpressionContainer (no nested JSX elements). If found, emit a single
269
+ * JSXInterpolation result with an i18next-style template
270
+ * ("You have {{taskCount}} pending tasks") instead of splitting into fragments.
271
+ *
272
+ * Returns true if handled — caller should NOT recurse into children.
273
+ */
274
+ function tryHandleInterpolatedJSX(jsxElement, filePath, lines, sourceFile, config, results, isInsideTranslationCallFn) {
275
+ // Skip if already inside a translation call
276
+ if (isInsideTranslationCallFn(jsxElement))
277
+ return false;
278
+ const children = jsxElement.children;
279
+ if (children.length < 2)
280
+ return false;
281
+ const parts = [];
282
+ let hasText = false;
283
+ let hasExpr = false;
284
+ for (const child of children) {
285
+ if (ts.isJsxText(child)) {
286
+ parts.push({ kind: "text", raw: child.text, node: child });
287
+ if (child.text.trim())
288
+ hasText = true;
289
+ }
290
+ else if (ts.isJsxExpression(child) && child.expression) {
291
+ const source = child.expression.getText(sourceFile);
292
+ parts.push({ kind: "expr", source, node: child });
293
+ hasExpr = true;
294
+ }
295
+ else {
296
+ // Nested JSX element — cannot group as a single interpolated string
297
+ return false;
298
+ }
299
+ }
300
+ // Need at least one meaningful text part AND at least one expression
301
+ if (!hasText || !hasExpr)
302
+ return false;
303
+ // Build the interpolated template and variable map
304
+ const interpolations = [];
305
+ const usedNames = new Set();
306
+ const templateParts = [];
307
+ for (const part of parts) {
308
+ if (part.kind === "text") {
309
+ templateParts.push(part.raw);
310
+ }
311
+ else {
312
+ let placeholder = simplifyExpressionName(part.source);
313
+ // Deduplicate placeholder names
314
+ if (usedNames.has(placeholder)) {
315
+ let i = 2;
316
+ while (usedNames.has(`${placeholder}${i}`))
317
+ i++;
318
+ placeholder = `${placeholder}${i}`;
319
+ }
320
+ usedNames.add(placeholder);
321
+ interpolations.push({ placeholder, expression: part.source });
322
+ templateParts.push(`{{${placeholder}}}`);
323
+ }
324
+ }
325
+ // Trim outer whitespace from the assembled template
326
+ const rawTemplate = templateParts.join("");
327
+ const trimmedTemplate = rawTemplate.trim();
328
+ if (!trimmedTemplate)
329
+ return false;
330
+ if (shouldFilter(trimmedTemplate, config, true))
331
+ return false;
332
+ // rawSpan: original source of all children — used by the rewriter
333
+ const firstChild = children[0];
334
+ const lastChild = children[children.length - 1];
335
+ const rawSpan = sourceFile.text.substring(firstChild.getStart(sourceFile), lastChild.getEnd());
336
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(firstChild.getStart(sourceFile));
337
+ results.push({
338
+ file: filePath,
339
+ line: line + 1,
340
+ column: character,
341
+ value: trimmedTemplate,
342
+ nodeType: "JSXInterpolation",
343
+ context: `interpolated JSX in <${getJSXElementName(jsxElement.openingElement)}>`,
344
+ surroundingCode: getSurroundingLines(lines, line),
345
+ alreadyTranslated: false,
346
+ isModuleLevel: !isInsideFunctionBody(jsxElement),
347
+ resolvedKey: null,
348
+ interpolations,
349
+ rawSpan,
350
+ });
351
+ return true;
352
+ }
353
+ // ─── Main ────────────────────────────────────────────────────────────────────
354
+ export function scanWithTypeScript(filePath, source, config) {
355
+ const results = [];
356
+ const lines = source.split("\n");
357
+ const scriptKind = filePath.endsWith(".tsx")
358
+ ? ts.ScriptKind.TSX
359
+ : ts.ScriptKind.TS;
360
+ const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest,
361
+ /* setParentNodes */ true, scriptKind);
362
+ // Track BinaryExpression chains we've already processed to avoid duplicates
363
+ const processedBinaryChains = new WeakSet();
364
+ function visit(node) {
365
+ // ── JSXElement: detect interpolated children first
366
+ // e.g. <p>You have {count} tasks</p> → one key "You have {{count}} tasks"
367
+ if (ts.isJsxElement(node)) {
368
+ if (tryHandleInterpolatedJSX(node, filePath, lines, sourceFile, config, results, isInsideTranslationCall)) {
369
+ return; // Consumed as a single interpolated result — skip child visits
370
+ }
371
+ // Not interpolated — recurse normally into children
372
+ ts.forEachChild(node, visit);
373
+ return;
374
+ }
375
+ // ── JSX text node: <h1>Welcome back</h1>
376
+ if (ts.isJsxText(node)) {
377
+ const value = node.text.trim();
378
+ if (value && !isInsideTranslationCall(node) && !shouldFilter(value, config, true)) {
379
+ // Parent is JsxElement; grandparent opening element carries the tag name
380
+ const jsxEl = node.parent;
381
+ const elementName = ts.isJsxElement(jsxEl)
382
+ ? getJSXElementName(jsxEl.openingElement)
383
+ : "?";
384
+ results.push(makeResult(filePath, lines, sourceFile, node, value, "JSXText", `JSXText inside <${elementName}>`));
385
+ }
386
+ }
387
+ // ── String literal as JSX attribute value: <input placeholder="..." />
388
+ else if (ts.isStringLiteral(node)) {
389
+ const value = node.text.trim();
390
+ if (!value) {
391
+ ts.forEachChild(node, visit);
392
+ return;
393
+ }
394
+ const parent = node.parent;
395
+ // ── Check for string concatenation chains: "a" + "b" + "c"
396
+ // Split chains into individual meaningful strings (skip separators like " — ")
397
+ // Emit each string separately so they can be translated individually
398
+ if (parent && ts.isBinaryExpression(parent)) {
399
+ const rootChain = getRootConcatenationChain(node);
400
+ if (rootChain) {
401
+ // Process only on first visit (when not yet in processedBinaryChains)
402
+ if (!processedBinaryChains.has(rootChain)) {
403
+ const meaningfulStrings = collectBinaryStringChain(rootChain);
404
+ if (meaningfulStrings &&
405
+ meaningfulStrings.length > 0 &&
406
+ !isInsideTranslationCall(rootChain) &&
407
+ !isInsideConsoleCall(rootChain)) {
408
+ processedBinaryChains.add(rootChain);
409
+ const isInJSX = isInsideJSXElement(rootChain);
410
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(rootChain.getStart(sourceFile));
411
+ // Emit each meaningful string as a separate translatable result
412
+ for (const str of meaningfulStrings) {
413
+ if (!shouldFilter(str, config, isInJSX)) {
414
+ results.push({
415
+ file: filePath,
416
+ line: line + 1,
417
+ column: character,
418
+ value: str,
419
+ nodeType: "StringLiteral",
420
+ context: "string concatenation",
421
+ surroundingCode: getSurroundingLines(lines, line),
422
+ alreadyTranslated: false,
423
+ isModuleLevel: !isInsideFunctionBody(rootChain),
424
+ resolvedKey: null,
425
+ });
426
+ }
427
+ }
428
+ }
429
+ else {
430
+ // Mark as processed even if we don't emit (e.g., filtered)
431
+ processedBinaryChains.add(rootChain);
432
+ }
433
+ }
434
+ // Skip individual operand processing — chain already handled
435
+ ts.forEachChild(node, visit);
436
+ return;
437
+ }
438
+ }
439
+ if (ts.isJsxAttribute(parent)) {
440
+ // Skip non-translatable attribute names
441
+ const attrName = ts.isIdentifier(parent.name)
442
+ ? parent.name.text
443
+ : parent.name.getText(sourceFile);
444
+ if (!NON_TRANSLATABLE_ATTRS.has(attrName) &&
445
+ !attrName.startsWith("data-") &&
446
+ attrName !== "aria-labelledby" &&
447
+ attrName !== "aria-describedby" &&
448
+ !isInsideTranslationCall(node) &&
449
+ !isInsideConsoleCall(node) &&
450
+ !shouldFilter(value, config, true)) {
451
+ // Get element name from JsxOpeningElement (grandparent of JsxAttribute)
452
+ const openingEl = parent.parent;
453
+ const elementName = ts.isJsxOpeningElement(openingEl) ||
454
+ ts.isJsxSelfClosingElement(openingEl)
455
+ ? getJSXElementName(openingEl)
456
+ : "?";
457
+ results.push(makeResult(filePath, lines, sourceFile, node, value, "JSXAttribute", `"${attrName}" attribute on <${elementName}>`));
458
+ }
459
+ }
460
+ else if (!ts.isImportDeclaration(parent) && !ts.isExportDeclaration(parent)) {
461
+ // Skip state initialization defaults: useState("John Doe"), useRef("initial")
462
+ // These are placeholders, not user-facing text
463
+ if (isInsideStateInitialization(node)) {
464
+ ts.forEachChild(node, visit);
465
+ return;
466
+ }
467
+ // Non-JSX StringLiteral — capture if it looks user-facing
468
+ // If inside JSX (e.g., ternary in JSX), treat as JSX to skip MODULE_SPECIFIER_RE filter
469
+ const isInJSX = isInsideJSXElement(node);
470
+ if (!isInsideTranslationCall(node) &&
471
+ !isInsideConsoleCall(node) &&
472
+ !isInsideImport(node) &&
473
+ !shouldFilter(value, config, isInJSX)) {
474
+ const context = getNonJSXContext(node, sourceFile);
475
+ if (context) {
476
+ // For object properties, also track the parent object name
477
+ let objectKey;
478
+ if (context.startsWith("object property") &&
479
+ ts.isPropertyAssignment(parent)) {
480
+ objectKey = getObjectVariableName(parent, sourceFile) ?? undefined;
481
+ }
482
+ results.push(makeResult(filePath, lines, sourceFile, node, value, "StringLiteral", context, objectKey));
483
+ }
484
+ }
485
+ }
486
+ }
487
+ // ── Static-only template literal: `Hello world`
488
+ else if (ts.isNoSubstitutionTemplateLiteral(node)) {
489
+ const value = node.text.trim();
490
+ if (value &&
491
+ !isInsideTranslationCall(node) &&
492
+ !isInsideConsoleCall(node) &&
493
+ !isInsideImport(node) &&
494
+ !shouldFilter(value, config)) {
495
+ results.push(makeResult(filePath, lines, sourceFile, node, value, "TemplateLiteral", "Template literal"));
496
+ }
497
+ }
498
+ // ── Dynamic template literal with interpolation: `Hello ${name}, you have ${count} tasks`
499
+ // Extract each static span (head, middle spans, tail) as separate translatable strings
500
+ else if (ts.isTemplateExpression(node)) {
501
+ if (isInsideTranslationCall(node) ||
502
+ isInsideConsoleCall(node) ||
503
+ isInsideImport(node)) {
504
+ ts.forEachChild(node, visit);
505
+ return;
506
+ }
507
+ const isInJSX = isInsideJSXElement(node);
508
+ // Template head: the part before the first ${}
509
+ const headValue = node.head.text.trim();
510
+ if (headValue && !shouldFilter(headValue, config, isInJSX)) {
511
+ results.push(makeResult(filePath, lines, sourceFile, node.head, headValue, "TemplateLiteral", "Template literal (static part)"));
512
+ }
513
+ // Template spans: each middle/tail static part after a ${}
514
+ for (const span of node.templateSpans) {
515
+ const spanValue = span.literal.text.trim();
516
+ if (spanValue && !shouldFilter(spanValue, config, isInJSX)) {
517
+ results.push(makeResult(filePath, lines, sourceFile, span.literal, spanValue, "TemplateLiteral", "Template literal (static part)"));
518
+ }
519
+ }
520
+ }
521
+ // ── Array literal elements: ["Export Report", "Send Notification"]
522
+ // Capture UI text arrays but skip code/identifier arrays like ["admin", "user"]
523
+ if (ts.isArrayLiteralExpression(node)) {
524
+ const isInJSX = isInsideJSXElement(node);
525
+ for (const element of node.elements) {
526
+ if (ts.isStringLiteral(element)) {
527
+ const value = element.text.trim();
528
+ if (value &&
529
+ !isInsideTranslationCall(element) &&
530
+ !isInsideStateInitialization(node) &&
531
+ !shouldFilter(value, config, isInJSX)) {
532
+ results.push(makeResult(filePath, lines, sourceFile, element, value, "StringLiteral", "string in array"));
533
+ }
534
+ }
535
+ }
536
+ }
537
+ ts.forEachChild(node, visit);
538
+ }
539
+ visit(sourceFile);
540
+ return results;
541
+ }
542
+ //# sourceMappingURL=typescript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript.js","sourceRoot":"","sources":["../../src/scanner/typescript.ts"],"names":[],"mappings":"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"}