@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.
- package/LICENSE +21 -0
- package/README.md +164 -0
- package/dist/ai/anthropic.d.ts +17 -0
- package/dist/ai/anthropic.d.ts.map +1 -0
- package/dist/ai/anthropic.js +58 -0
- package/dist/ai/anthropic.js.map +1 -0
- package/dist/ai/dedup.d.ts +19 -0
- package/dist/ai/dedup.d.ts.map +1 -0
- package/dist/ai/dedup.js +119 -0
- package/dist/ai/dedup.js.map +1 -0
- package/dist/ai/index.d.ts +65 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +464 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/openai.d.ts +11 -0
- package/dist/ai/openai.d.ts.map +1 -0
- package/dist/ai/openai.js +62 -0
- package/dist/ai/openai.js.map +1 -0
- package/dist/ai/prompts.d.ts +20 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +151 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/cache/index.d.ts +69 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +129 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/rewriter/index.d.ts +31 -0
- package/dist/rewriter/index.d.ts.map +1 -0
- package/dist/rewriter/index.js +128 -0
- package/dist/rewriter/index.js.map +1 -0
- package/dist/rewriter/transforms.d.ts +38 -0
- package/dist/rewriter/transforms.d.ts.map +1 -0
- package/dist/rewriter/transforms.js +189 -0
- package/dist/rewriter/transforms.js.map +1 -0
- package/dist/rewriter/ts-morph.d.ts +19 -0
- package/dist/rewriter/ts-morph.d.ts.map +1 -0
- package/dist/rewriter/ts-morph.js +121 -0
- package/dist/rewriter/ts-morph.js.map +1 -0
- package/dist/scanner/babel.d.ts +3 -0
- package/dist/scanner/babel.d.ts.map +1 -0
- package/dist/scanner/babel.js +504 -0
- package/dist/scanner/babel.js.map +1 -0
- package/dist/scanner/filters.d.ts +38 -0
- package/dist/scanner/filters.d.ts.map +1 -0
- package/dist/scanner/filters.js +133 -0
- package/dist/scanner/filters.js.map +1 -0
- package/dist/scanner/index.d.ts +22 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +82 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/typescript.d.ts +3 -0
- package/dist/scanner/typescript.d.ts.map +1 -0
- package/dist/scanner/typescript.js +542 -0
- package/dist/scanner/typescript.js.map +1 -0
- package/dist/types.d.ts +205 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/validator/index.d.ts +65 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +237 -0
- package/dist/validator/index.js.map +1 -0
- 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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"}
|