@better-i18n/cli 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/dynamic-matcher.d.ts +53 -0
- package/dist/analyzer/dynamic-matcher.d.ts.map +1 -0
- package/dist/analyzer/dynamic-matcher.js +93 -0
- package/dist/analyzer/dynamic-matcher.js.map +1 -0
- package/dist/analyzer/index.d.ts +13 -4
- package/dist/analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/index.js +165 -22
- package/dist/analyzer/index.js.map +1 -1
- package/dist/analyzer/rules/data-structure.d.ts +13 -0
- package/dist/analyzer/rules/data-structure.d.ts.map +1 -0
- package/dist/analyzer/rules/data-structure.js +264 -0
- package/dist/analyzer/rules/data-structure.js.map +1 -0
- package/dist/analyzer/rules/index.d.ts +10 -7
- package/dist/analyzer/rules/index.d.ts.map +1 -1
- package/dist/analyzer/rules/index.js +10 -7
- package/dist/analyzer/rules/index.js.map +1 -1
- package/dist/analyzer/rules/jsx-text.js +1 -1
- package/dist/analyzer/rules/jsx-text.js.map +1 -1
- package/dist/analyzer/rules/translation-function.d.ts.map +1 -1
- package/dist/analyzer/rules/translation-function.js +94 -6
- package/dist/analyzer/rules/translation-function.js.map +1 -1
- package/dist/analyzer/types.d.ts +28 -3
- package/dist/analyzer/types.d.ts.map +1 -1
- package/dist/commands/check.d.ts +14 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +70 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/doctor.d.ts +20 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +77 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/sync.d.ts +1 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +158 -272
- package/dist/commands/sync.js.map +1 -1
- package/dist/context/detector.js +1 -1
- package/dist/context/detector.js.map +1 -1
- package/dist/context/oidc.d.ts +33 -0
- package/dist/context/oidc.d.ts.map +1 -0
- package/dist/context/oidc.js +63 -0
- package/dist/context/oidc.js.map +1 -0
- package/dist/doctor/index.d.ts +65 -0
- package/dist/doctor/index.d.ts.map +1 -0
- package/dist/doctor/index.js +252 -0
- package/dist/doctor/index.js.map +1 -0
- package/dist/doctor/project-discovery.d.ts +37 -0
- package/dist/doctor/project-discovery.d.ts.map +1 -0
- package/dist/doctor/project-discovery.js +140 -0
- package/dist/doctor/project-discovery.js.map +1 -0
- package/dist/doctor/score.d.ts +41 -0
- package/dist/doctor/score.d.ts.map +1 -0
- package/dist/doctor/score.js +107 -0
- package/dist/doctor/score.js.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -1
- package/dist/reporters/doctor-eslint.d.ts +17 -0
- package/dist/reporters/doctor-eslint.d.ts.map +1 -0
- package/dist/reporters/doctor-eslint.js +139 -0
- package/dist/reporters/doctor-eslint.js.map +1 -0
- package/dist/reporters/doctor-json.d.ts +12 -0
- package/dist/reporters/doctor-json.d.ts.map +1 -0
- package/dist/reporters/doctor-json.js +21 -0
- package/dist/reporters/doctor-json.js.map +1 -0
- package/dist/reporters/doctor-report.d.ts +23 -0
- package/dist/reporters/doctor-report.d.ts.map +1 -0
- package/dist/reporters/doctor-report.js +62 -0
- package/dist/reporters/doctor-report.js.map +1 -0
- package/dist/reporters/eslint-style.js +4 -4
- package/dist/reporters/eslint-style.js.map +1 -1
- package/dist/rules/categories.d.ts +36 -0
- package/dist/rules/categories.d.ts.map +1 -0
- package/dist/rules/categories.js +80 -0
- package/dist/rules/categories.js.map +1 -0
- package/dist/rules/code/index.d.ts +9 -0
- package/dist/rules/code/index.d.ts.map +1 -0
- package/dist/rules/code/index.js +9 -0
- package/dist/rules/code/index.js.map +1 -0
- package/dist/rules/code/jsx-attribute.d.ts +12 -0
- package/dist/rules/code/jsx-attribute.d.ts.map +1 -0
- package/dist/rules/code/jsx-attribute.js +78 -0
- package/dist/rules/code/jsx-attribute.js.map +1 -0
- package/dist/rules/code/jsx-text.d.ts +12 -0
- package/dist/rules/code/jsx-text.d.ts.map +1 -0
- package/dist/rules/code/jsx-text.js +47 -0
- package/dist/rules/code/jsx-text.js.map +1 -0
- package/dist/rules/code/string-variable.d.ts +13 -0
- package/dist/rules/code/string-variable.d.ts.map +1 -0
- package/dist/rules/code/string-variable.js +185 -0
- package/dist/rules/code/string-variable.js.map +1 -0
- package/dist/rules/code/ternary-locale.d.ts +12 -0
- package/dist/rules/code/ternary-locale.d.ts.map +1 -0
- package/dist/rules/code/ternary-locale.js +53 -0
- package/dist/rules/code/ternary-locale.js.map +1 -0
- package/dist/rules/code/toast-message.d.ts +13 -0
- package/dist/rules/code/toast-message.d.ts.map +1 -0
- package/dist/rules/code/toast-message.js +101 -0
- package/dist/rules/code/toast-message.js.map +1 -0
- package/dist/rules/extraction/data-structure.d.ts +13 -0
- package/dist/rules/extraction/data-structure.d.ts.map +1 -0
- package/dist/rules/extraction/data-structure.js +212 -0
- package/dist/rules/extraction/data-structure.js.map +1 -0
- package/dist/rules/extraction/index.d.ts +6 -0
- package/dist/rules/extraction/index.d.ts.map +1 -0
- package/dist/rules/extraction/index.js +6 -0
- package/dist/rules/extraction/index.js.map +1 -0
- package/dist/rules/extraction/translation-function.d.ts +12 -0
- package/dist/rules/extraction/translation-function.d.ts.map +1 -0
- package/dist/rules/extraction/translation-function.js +153 -0
- package/dist/rules/extraction/translation-function.js.map +1 -0
- package/dist/rules/health/index.d.ts +16 -0
- package/dist/rules/health/index.d.ts.map +1 -0
- package/dist/rules/health/index.js +22 -0
- package/dist/rules/health/index.js.map +1 -0
- package/dist/rules/health/missing-translations.d.ts +13 -0
- package/dist/rules/health/missing-translations.d.ts.map +1 -0
- package/dist/rules/health/missing-translations.js +48 -0
- package/dist/rules/health/missing-translations.js.map +1 -0
- package/dist/rules/health/orphan-keys.d.ts +16 -0
- package/dist/rules/health/orphan-keys.d.ts.map +1 -0
- package/dist/rules/health/orphan-keys.js +50 -0
- package/dist/rules/health/orphan-keys.js.map +1 -0
- package/dist/rules/health/placeholder-mismatch.d.ts +32 -0
- package/dist/rules/health/placeholder-mismatch.d.ts.map +1 -0
- package/dist/rules/health/placeholder-mismatch.js +120 -0
- package/dist/rules/health/placeholder-mismatch.js.map +1 -0
- package/dist/rules/registry.d.ts +84 -0
- package/dist/rules/registry.d.ts.map +1 -0
- package/dist/rules/registry.js +11 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist/utils/cdn-client.d.ts +30 -0
- package/dist/utils/cdn-client.d.ts.map +1 -0
- package/dist/utils/cdn-client.js +59 -0
- package/dist/utils/cdn-client.js.map +1 -0
- package/dist/utils/json-keys.d.ts +60 -0
- package/dist/utils/json-keys.d.ts.map +1 -0
- package/dist/utils/json-keys.js +103 -0
- package/dist/utils/json-keys.js.map +1 -0
- package/dist/utils/key-comparison.d.ts +67 -0
- package/dist/utils/key-comparison.d.ts.map +1 -0
- package/dist/utils/key-comparison.js +299 -0
- package/dist/utils/key-comparison.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data structure detection rule
|
|
3
|
+
*
|
|
4
|
+
* Detects translation keys stored in data structures (arrays, objects)
|
|
5
|
+
* Uses property name heuristics to identify translation-relevant strings
|
|
6
|
+
*/
|
|
7
|
+
import ts from "typescript";
|
|
8
|
+
/**
|
|
9
|
+
* Default property names that likely contain translation keys
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_PROPERTY_NAMES = new Set([
|
|
12
|
+
"message",
|
|
13
|
+
"label",
|
|
14
|
+
"title",
|
|
15
|
+
"text",
|
|
16
|
+
"description",
|
|
17
|
+
"placeholder",
|
|
18
|
+
"tooltip",
|
|
19
|
+
"translationKey",
|
|
20
|
+
"i18nKey",
|
|
21
|
+
"successMessage",
|
|
22
|
+
"errorMessage",
|
|
23
|
+
"warningMessage",
|
|
24
|
+
"infoMessage",
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* Default configuration for data structure detection
|
|
28
|
+
*/
|
|
29
|
+
const DEFAULT_CONFIG = {
|
|
30
|
+
enabled: true,
|
|
31
|
+
requireTranslationScope: true,
|
|
32
|
+
maxDepth: 3,
|
|
33
|
+
propertyNames: [],
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Check if a string value looks like a translation key
|
|
37
|
+
* Filters out obvious non-translation strings
|
|
38
|
+
*/
|
|
39
|
+
function looksLikeTranslationKey(value) {
|
|
40
|
+
// Too short (likely not meaningful)
|
|
41
|
+
if (value.length < 2)
|
|
42
|
+
return false;
|
|
43
|
+
// URLs
|
|
44
|
+
if (value.startsWith("http://") || value.startsWith("https://"))
|
|
45
|
+
return false;
|
|
46
|
+
// File paths
|
|
47
|
+
if (value.startsWith("/") || value.startsWith("./") || value.startsWith("../"))
|
|
48
|
+
return false;
|
|
49
|
+
// CSS classes (common patterns)
|
|
50
|
+
if (value.includes(" ") && (value.includes("-") || value.includes("_"))) {
|
|
51
|
+
// Likely CSS like "flex items-center gap-2"
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
// Data URLs
|
|
55
|
+
if (value.startsWith("data:"))
|
|
56
|
+
return false;
|
|
57
|
+
// RGB/Hex colors
|
|
58
|
+
if (/^#[0-9a-fA-F]{3,8}$/.test(value) || /^rgb\(/.test(value))
|
|
59
|
+
return false;
|
|
60
|
+
// Numbers only
|
|
61
|
+
if (/^\d+$/.test(value))
|
|
62
|
+
return false;
|
|
63
|
+
// Single special characters
|
|
64
|
+
if (/^[^a-zA-Z0-9]+$/.test(value))
|
|
65
|
+
return false;
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Extract string literals from object literal expression
|
|
70
|
+
*/
|
|
71
|
+
function extractFromObjectLiteral(node, propertyNames, currentDepth, maxDepth) {
|
|
72
|
+
if (currentDepth > maxDepth) {
|
|
73
|
+
// console.log(`[DEBUG] Stopping at depth ${currentDepth} (maxDepth: ${maxDepth})`);
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const keys = [];
|
|
77
|
+
for (const prop of node.properties) {
|
|
78
|
+
// Handle property assignments: { message: "translationKey" }
|
|
79
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
80
|
+
const propName = prop.name.getText();
|
|
81
|
+
// console.log(`[DEBUG depth=${currentDepth}] Property: ${propName}, isArray: ${ts.isArrayLiteralExpression(prop.initializer)}`);
|
|
82
|
+
// Check if property name matches our heuristics
|
|
83
|
+
if (propertyNames.has(propName)) {
|
|
84
|
+
// Extract string literal value
|
|
85
|
+
if (ts.isStringLiteral(prop.initializer)) {
|
|
86
|
+
const value = prop.initializer.text;
|
|
87
|
+
if (looksLikeTranslationKey(value)) {
|
|
88
|
+
// console.log(`[DEBUG depth=${currentDepth}] Found key: ${value}`);
|
|
89
|
+
keys.push(value);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Recursively check nested objects
|
|
94
|
+
if (ts.isObjectLiteralExpression(prop.initializer)) {
|
|
95
|
+
const nestedKeys = extractFromObjectLiteral(prop.initializer, propertyNames, currentDepth + 1, maxDepth);
|
|
96
|
+
// console.log(`[DEBUG depth=${currentDepth}] Nested object returned ${nestedKeys.length} keys`);
|
|
97
|
+
keys.push(...nestedKeys);
|
|
98
|
+
}
|
|
99
|
+
// Recursively check nested arrays
|
|
100
|
+
if (ts.isArrayLiteralExpression(prop.initializer)) {
|
|
101
|
+
// console.log(`[DEBUG depth=${currentDepth}] Processing nested array for prop: ${propName}`);
|
|
102
|
+
const nestedKeys = extractFromArrayLiteral(prop.initializer, propertyNames, currentDepth + 1, maxDepth);
|
|
103
|
+
// console.log(`[DEBUG depth=${currentDepth}] Nested array returned ${nestedKeys.length} keys`);
|
|
104
|
+
keys.push(...nestedKeys);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Handle shorthand properties: { message } (less common for translation keys)
|
|
108
|
+
// Skip for now as these are references, not literals
|
|
109
|
+
}
|
|
110
|
+
return keys;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Check if an array looks like a language selector pattern
|
|
114
|
+
* Examples: [{ value: "en", label: "English" }, { value: "tr", label: "Türkçe" }]
|
|
115
|
+
*/
|
|
116
|
+
function isLanguageSelectorPattern(node) {
|
|
117
|
+
// Need at least 2 elements to be a selector
|
|
118
|
+
if (node.elements.length < 2)
|
|
119
|
+
return false;
|
|
120
|
+
// Check if all elements are object literals with value + label properties
|
|
121
|
+
const allMatchPattern = node.elements.every((element) => {
|
|
122
|
+
if (!ts.isObjectLiteralExpression(element))
|
|
123
|
+
return false;
|
|
124
|
+
let hasValue = false;
|
|
125
|
+
let hasLabel = false;
|
|
126
|
+
let valueIsLanguageCode = false;
|
|
127
|
+
for (const prop of element.properties) {
|
|
128
|
+
if (!ts.isPropertyAssignment(prop))
|
|
129
|
+
continue;
|
|
130
|
+
const propName = prop.name.getText();
|
|
131
|
+
if (propName === "value" && ts.isStringLiteral(prop.initializer)) {
|
|
132
|
+
hasValue = true;
|
|
133
|
+
// Check if value looks like ISO language code (2-5 lowercase letters, optionally with dash)
|
|
134
|
+
const value = prop.initializer.text;
|
|
135
|
+
valueIsLanguageCode = /^[a-z]{2}(-[a-z]{2,3})?$/i.test(value);
|
|
136
|
+
}
|
|
137
|
+
if (propName === "label") {
|
|
138
|
+
hasLabel = true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return hasValue && hasLabel && valueIsLanguageCode;
|
|
142
|
+
});
|
|
143
|
+
return allMatchPattern;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Extract string literals from array literal expression
|
|
147
|
+
*/
|
|
148
|
+
function extractFromArrayLiteral(node, propertyNames, currentDepth, maxDepth) {
|
|
149
|
+
if (currentDepth > maxDepth) {
|
|
150
|
+
// console.log(`[DEBUG ARRAY] Stopping at depth ${currentDepth} (maxDepth: ${maxDepth})`);
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
// Skip language selector patterns (native language names should not be translated)
|
|
154
|
+
if (isLanguageSelectorPattern(node)) {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
// console.log(`[DEBUG ARRAY depth=${currentDepth}] Processing array with ${node.elements.length} elements`);
|
|
158
|
+
const keys = [];
|
|
159
|
+
for (const element of node.elements) {
|
|
160
|
+
// console.log(`[DEBUG ARRAY depth=${currentDepth}] Element is object: ${ts.isObjectLiteralExpression(element)}, is array: ${ts.isArrayLiteralExpression(element)}`);
|
|
161
|
+
// Handle object literals in arrays: [{ message: "key1" }, { message: "key2" }]
|
|
162
|
+
if (ts.isObjectLiteralExpression(element)) {
|
|
163
|
+
const nestedKeys = extractFromObjectLiteral(element, propertyNames, currentDepth + 1, maxDepth);
|
|
164
|
+
// console.log(`[DEBUG ARRAY depth=${currentDepth}] Object element returned ${nestedKeys.length} keys`);
|
|
165
|
+
keys.push(...nestedKeys);
|
|
166
|
+
}
|
|
167
|
+
// Handle nested arrays
|
|
168
|
+
if (ts.isArrayLiteralExpression(element)) {
|
|
169
|
+
keys.push(...extractFromArrayLiteral(element, propertyNames, currentDepth + 1, maxDepth));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// console.log(`[DEBUG ARRAY depth=${currentDepth}] Total keys from array: ${keys.length}`);
|
|
173
|
+
return keys;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Check data structures for translation keys
|
|
177
|
+
*/
|
|
178
|
+
export function checkDataStructure(node, ctx, config) {
|
|
179
|
+
const cfg = { ...DEFAULT_CONFIG, ...config };
|
|
180
|
+
// Feature disabled
|
|
181
|
+
if (!cfg.enabled)
|
|
182
|
+
return [];
|
|
183
|
+
// Require translation scope and not in one
|
|
184
|
+
if (cfg.requireTranslationScope && !ctx.translationScope)
|
|
185
|
+
return [];
|
|
186
|
+
// Build property names set
|
|
187
|
+
const propertyNames = new Set([
|
|
188
|
+
...DEFAULT_PROPERTY_NAMES,
|
|
189
|
+
...(cfg.propertyNames || []),
|
|
190
|
+
]);
|
|
191
|
+
// Extract keys based on node type
|
|
192
|
+
let extractedKeys = [];
|
|
193
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
194
|
+
extractedKeys = extractFromObjectLiteral(node, propertyNames, 0, cfg.maxDepth || 3);
|
|
195
|
+
}
|
|
196
|
+
else if (ts.isArrayLiteralExpression(node)) {
|
|
197
|
+
extractedKeys = extractFromArrayLiteral(node, propertyNames, 0, cfg.maxDepth || 3);
|
|
198
|
+
}
|
|
199
|
+
// No keys found
|
|
200
|
+
if (extractedKeys.length === 0)
|
|
201
|
+
return [];
|
|
202
|
+
// Get current namespace binding from context
|
|
203
|
+
const issues = [];
|
|
204
|
+
for (const extractedKey of extractedKeys) {
|
|
205
|
+
// Try to apply namespace from current scope
|
|
206
|
+
let key = extractedKey;
|
|
207
|
+
let namespace;
|
|
208
|
+
let bindingType = "unbound";
|
|
209
|
+
// First try: scope-bound namespace (existing logic)
|
|
210
|
+
if (ctx.namespaceMap) {
|
|
211
|
+
for (const binding of Object.values(ctx.namespaceMap)) {
|
|
212
|
+
if (binding.type === "bound-scoped" && binding.namespace) {
|
|
213
|
+
namespace = binding.namespace;
|
|
214
|
+
bindingType = "bound-scoped";
|
|
215
|
+
// Apply namespace prefix
|
|
216
|
+
if (!key.startsWith(`${namespace}.`)) {
|
|
217
|
+
key = `${namespace}.${extractedKey}`;
|
|
218
|
+
}
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Second try: file-level namespace inference (NEW)
|
|
224
|
+
if (!namespace && ctx.fileNamespaces && ctx.fileNamespaces.length > 0) {
|
|
225
|
+
if (ctx.fileNamespaces.length === 1) {
|
|
226
|
+
// Single namespace in file - safe to apply
|
|
227
|
+
namespace = ctx.fileNamespaces[0];
|
|
228
|
+
bindingType = "bound-scoped";
|
|
229
|
+
key = `${namespace}.${extractedKey}`;
|
|
230
|
+
if (ctx.verbose) {
|
|
231
|
+
console.log(`[VERBOSE] Applied file-level namespace "${namespace}" to data structure key: ${extractedKey}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// Multiple namespaces - ambiguous, use first one but mark as unknown-scoped
|
|
236
|
+
namespace = ctx.fileNamespaces[0];
|
|
237
|
+
bindingType = "unknown-scoped";
|
|
238
|
+
key = `${namespace}.${extractedKey}`;
|
|
239
|
+
if (ctx.verbose) {
|
|
240
|
+
console.log(`[VERBOSE] Ambiguous namespace (${ctx.fileNamespaces.length} found in file), using "${namespace}" for: ${extractedKey}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const pos = ctx.sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
245
|
+
issues.push({
|
|
246
|
+
file: ctx.filePath,
|
|
247
|
+
line: pos.line + 1,
|
|
248
|
+
column: pos.character + 1,
|
|
249
|
+
text: extractedKey,
|
|
250
|
+
type: "string-variable",
|
|
251
|
+
severity: "info",
|
|
252
|
+
message: `Translation key in data structure: "${key}"`,
|
|
253
|
+
key,
|
|
254
|
+
bindingType,
|
|
255
|
+
namespace,
|
|
256
|
+
});
|
|
257
|
+
// Track stats
|
|
258
|
+
if (ctx.stats && ctx.stats.dataStructureKeys !== undefined) {
|
|
259
|
+
ctx.stats.dataStructureKeys++;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return issues;
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=data-structure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-structure.js","sourceRoot":"","sources":["../../../src/analyzer/rules/data-structure.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Rules index
|
|
2
|
+
* Rules index — backward compatibility barrel
|
|
3
|
+
*
|
|
4
|
+
* Canonical rule locations are now:
|
|
5
|
+
* src/rules/code/ — Code detection rules (JSX text, attributes, etc.)
|
|
6
|
+
* src/rules/extraction/ — Key extraction rules (t() calls, data structures)
|
|
7
|
+
*
|
|
8
|
+
* This file re-exports from the new locations so existing imports
|
|
9
|
+
* (e.g., analyzer/index.ts) continue to work without changes.
|
|
3
10
|
*/
|
|
4
|
-
export * from "
|
|
5
|
-
export * from "
|
|
6
|
-
export * from "./string-variable.js";
|
|
7
|
-
export * from "./ternary-locale.js";
|
|
8
|
-
export * from "./toast-message.js";
|
|
9
|
-
export * from "./translation-function.js";
|
|
11
|
+
export * from "../../rules/code/index.js";
|
|
12
|
+
export * from "../../rules/extraction/index.js";
|
|
10
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Rules index
|
|
2
|
+
* Rules index — backward compatibility barrel
|
|
3
|
+
*
|
|
4
|
+
* Canonical rule locations are now:
|
|
5
|
+
* src/rules/code/ — Code detection rules (JSX text, attributes, etc.)
|
|
6
|
+
* src/rules/extraction/ — Key extraction rules (t() calls, data structures)
|
|
7
|
+
*
|
|
8
|
+
* This file re-exports from the new locations so existing imports
|
|
9
|
+
* (e.g., analyzer/index.ts) continue to work without changes.
|
|
3
10
|
*/
|
|
4
|
-
export * from "
|
|
5
|
-
export * from "
|
|
6
|
-
export * from "./string-variable.js";
|
|
7
|
-
export * from "./ternary-locale.js";
|
|
8
|
-
export * from "./toast-message.js";
|
|
9
|
-
export * from "./translation-function.js";
|
|
11
|
+
export * from "../../rules/code/index.js";
|
|
12
|
+
export * from "../../rules/extraction/index.js";
|
|
10
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC"}
|
|
@@ -9,7 +9,7 @@ import { generateKeyFromContext, truncate } from "../../utils/text.js";
|
|
|
9
9
|
*/
|
|
10
10
|
const IGNORE_PATTERNS = [
|
|
11
11
|
/^[\s\n\r\t]+$/, // Whitespace only
|
|
12
|
-
/^[
|
|
12
|
+
/^[→←↑↓★•·\-–—/\\|,;:.!?()[\]{}]+$/, // Symbols only
|
|
13
13
|
/^\d+[+%KkMm]?$/, // Numbers with optional suffix
|
|
14
14
|
/^[A-Z_]+$/, // SCREAMING_CASE
|
|
15
15
|
/^https?:\/\//, // URLs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-text.js","sourceRoot":"","sources":["../../../src/analyzer/rules/jsx-text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGvE;;GAEG;AACH,MAAM,eAAe,GAAG;IACtB,eAAe,EAAE,kBAAkB;IACnC,
|
|
1
|
+
{"version":3,"file":"jsx-text.js","sourceRoot":"","sources":["../../../src/analyzer/rules/jsx-text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGvE;;GAEG;AACH,MAAM,eAAe,GAAG;IACtB,eAAe,EAAE,kBAAkB;IACnC,mCAAmC,EAAE,eAAe;IACpD,gBAAgB,EAAE,+BAA+B;IACjD,WAAW,EAAE,iBAAiB;IAC9B,cAAc,EAAE,OAAO;IACvB,KAAK,EAAE,QAAQ;IACf,WAAW,EAAE,yCAAyC;IACtD,YAAY,EAAE,yCAAyC;IACvD,UAAU,EAAE,mCAAmC;CAChD,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAgB,EAAE,GAAgB;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAE9B,2BAA2B;IAC3B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,wBAAwB;IACxB,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACtC,CAAC;IAED,eAAe;IACf,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE1E,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;QAClB,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,CAAC;QACzB,IAAI;QACJ,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,SAAS;QACnB,OAAO,EAAE,oBAAoB,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG;QAClD,YAAY,EAAE,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC;KACzD,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation-function.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/translation-function.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"translation-function.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/translation-function.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgBtD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,EAAE,CAAC,cAAc,EACvB,GAAG,EAAE,WAAW,GACf,KAAK,GAAG,IAAI,CA8Gd"}
|
|
@@ -8,6 +8,14 @@ import ts from "typescript";
|
|
|
8
8
|
* Translation function names to detect
|
|
9
9
|
*/
|
|
10
10
|
const TRANSLATION_FUNCTIONS = new Set(["t", "useTranslation"]);
|
|
11
|
+
/**
|
|
12
|
+
* Check if identifier looks like a translator variable
|
|
13
|
+
* Common patterns: t, tUser, tAuth, tCommon, etc.
|
|
14
|
+
*/
|
|
15
|
+
function looksLikeTranslator(name) {
|
|
16
|
+
// Single 't' or starts with 't' followed by uppercase (tUser, tAuth, etc.)
|
|
17
|
+
return name === "t" || /^t[A-Z]/.test(name);
|
|
18
|
+
}
|
|
11
19
|
/**
|
|
12
20
|
* Check for translation function calls
|
|
13
21
|
*/
|
|
@@ -16,12 +24,31 @@ export function checkTranslationFunction(node, ctx) {
|
|
|
16
24
|
if (!bindingId)
|
|
17
25
|
return null;
|
|
18
26
|
// Check if this identifier is bound to a translation namespace
|
|
19
|
-
const binding
|
|
20
|
-
|
|
27
|
+
// Use let instead of const so we can create a synthetic binding if pattern matches
|
|
28
|
+
let binding = ctx.namespaceMap?.[bindingId];
|
|
29
|
+
// If not bound and not a known global/default translation function, check if it looks like a translator
|
|
21
30
|
if (!binding && !TRANSLATION_FUNCTIONS.has(bindingId)) {
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
// Fallback: if it looks like a translator variable (tUser, tAuth, etc.), assume it's valid
|
|
32
|
+
// This helps catch cases where binding detection failed but the pattern is clear
|
|
33
|
+
if (looksLikeTranslator(bindingId)) {
|
|
34
|
+
if (ctx.verbose) {
|
|
35
|
+
const pos = ctx.sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
36
|
+
console.log(`[VERBOSE] Accepting translator by pattern: ${bindingId} at ${ctx.filePath}:${pos.line + 1}`);
|
|
37
|
+
}
|
|
38
|
+
// Create a synthetic "unknown-scoped" binding for this translator
|
|
39
|
+
// We don't know the namespace, so mark it as unknown-scoped for fuzzy matching later
|
|
40
|
+
binding = { type: "unknown-scoped", dynamic: false };
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
if (ctx.stats)
|
|
44
|
+
ctx.stats.unboundTranslators++;
|
|
45
|
+
// Log unbound translator in verbose mode for debugging
|
|
46
|
+
if (ctx.verbose) {
|
|
47
|
+
const pos = ctx.sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
48
|
+
console.log(`[VERBOSE] Unbound translator (not a recognized pattern): ${bindingId} at ${ctx.filePath}:${pos.line + 1}`);
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
25
52
|
}
|
|
26
53
|
// Get the first argument (translation key)
|
|
27
54
|
const args = node.arguments;
|
|
@@ -52,11 +79,72 @@ export function checkTranslationFunction(node, ctx) {
|
|
|
52
79
|
namespace: binding?.namespace,
|
|
53
80
|
};
|
|
54
81
|
}
|
|
55
|
-
// Handle template literal
|
|
82
|
+
// Handle template literal: t(`plans.${planKey}.name`)
|
|
83
|
+
if (ts.isTemplateExpression(firstArg) || ts.isNoSubstitutionTemplateLiteral(firstArg)) {
|
|
84
|
+
const pattern = extractTemplatePattern(firstArg);
|
|
85
|
+
const pos = ctx.sourceFile.getLineAndCharacterOfPosition(firstArg.getStart());
|
|
86
|
+
// Apply namespace prefix if bound
|
|
87
|
+
let fullPattern = pattern;
|
|
88
|
+
if (binding?.type === "bound-scoped" && binding.namespace) {
|
|
89
|
+
const prefix = binding.namespace;
|
|
90
|
+
if (!pattern.startsWith(`${prefix}.`)) {
|
|
91
|
+
fullPattern = `${prefix}.${pattern}`;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (ctx.stats)
|
|
95
|
+
ctx.stats.dynamicKeys++;
|
|
96
|
+
return {
|
|
97
|
+
file: ctx.filePath,
|
|
98
|
+
line: pos.line + 1,
|
|
99
|
+
column: pos.character + 1,
|
|
100
|
+
text: pattern,
|
|
101
|
+
type: "string-variable",
|
|
102
|
+
severity: "info",
|
|
103
|
+
message: `Dynamic translation key pattern: "${fullPattern}"`,
|
|
104
|
+
key: fullPattern, // Store the pattern as the key for now
|
|
105
|
+
pattern: fullPattern,
|
|
106
|
+
isDynamic: true,
|
|
107
|
+
bindingType: binding?.type || "unbound",
|
|
108
|
+
namespace: binding?.namespace,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// Other dynamic keys (computed, variables, etc.)
|
|
56
112
|
if (ctx.stats)
|
|
57
113
|
ctx.stats.dynamicKeys++;
|
|
58
114
|
return null;
|
|
59
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Extract pattern from template literal
|
|
118
|
+
* Examples:
|
|
119
|
+
* `plans.${planKey}.name` -> 'plans.${planKey}.name'
|
|
120
|
+
* `${namespace}.title` -> '${namespace}.title'
|
|
121
|
+
*/
|
|
122
|
+
function extractTemplatePattern(node) {
|
|
123
|
+
// NoSubstitutionTemplateLiteral is just a plain string (no ${})
|
|
124
|
+
if (ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
125
|
+
return node.text;
|
|
126
|
+
}
|
|
127
|
+
// TemplateExpression has head, templateSpans
|
|
128
|
+
if (!ts.isTemplateExpression(node)) {
|
|
129
|
+
return "";
|
|
130
|
+
}
|
|
131
|
+
let pattern = node.head.text;
|
|
132
|
+
for (const span of node.templateSpans) {
|
|
133
|
+
// Add placeholder for the expression
|
|
134
|
+
const expr = span.expression;
|
|
135
|
+
let placeholder = "${x}"; // Generic placeholder
|
|
136
|
+
// Try to use the actual variable name if it's an identifier
|
|
137
|
+
if (ts.isIdentifier(expr)) {
|
|
138
|
+
placeholder = `\${${expr.text}}`;
|
|
139
|
+
}
|
|
140
|
+
else if (ts.isPropertyAccessExpression(expr)) {
|
|
141
|
+
// Handle cases like ${item.key}
|
|
142
|
+
placeholder = `\${${expr.getText()}}`;
|
|
143
|
+
}
|
|
144
|
+
pattern += placeholder + span.literal.text;
|
|
145
|
+
}
|
|
146
|
+
return pattern;
|
|
147
|
+
}
|
|
60
148
|
/**
|
|
61
149
|
* Extract the binding identifier from a call expression.
|
|
62
150
|
* Handles: t(), t.raw(), t.rich(), t.has()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation-function.js","sourceRoot":"","sources":["../../../src/analyzer/rules/translation-function.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B;;GAEG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE/D;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAuB,EACvB,GAAgB;IAEhB,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAE5B,+DAA+D;IAC/D,
|
|
1
|
+
{"version":3,"file":"translation-function.js","sourceRoot":"","sources":["../../../src/analyzer/rules/translation-function.ts"],"names":[],"mappings":"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"}
|
package/dist/analyzer/types.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export interface Issue {
|
|
|
13
13
|
key?: string;
|
|
14
14
|
bindingType?: NamespaceBindingType;
|
|
15
15
|
namespace?: string;
|
|
16
|
+
isDynamic?: boolean;
|
|
17
|
+
pattern?: string;
|
|
16
18
|
}
|
|
17
19
|
export type NamespaceBindingType = "bound-scoped" | "root-scoped" | "unknown-scoped" | "unbound";
|
|
18
20
|
export interface NamespaceBinding {
|
|
@@ -25,12 +27,27 @@ export interface ScanStats {
|
|
|
25
27
|
dynamicNamespaces: number;
|
|
26
28
|
unboundTranslators: number;
|
|
27
29
|
rootScopedTranslators: number;
|
|
30
|
+
dataStructureKeys?: number;
|
|
31
|
+
dataStructureScopes?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Represents a dynamic key access pattern detected in code
|
|
35
|
+
*/
|
|
36
|
+
export interface DynamicPattern {
|
|
37
|
+
pattern: string;
|
|
38
|
+
file: string;
|
|
39
|
+
line: number;
|
|
40
|
+
namespace?: string;
|
|
41
|
+
bindingType?: NamespaceBindingType;
|
|
28
42
|
}
|
|
29
43
|
export interface RuleContext {
|
|
30
44
|
filePath: string;
|
|
31
45
|
sourceFile: import("typescript").SourceFile;
|
|
32
46
|
namespaceMap?: Record<string, NamespaceBinding>;
|
|
33
47
|
stats?: ScanStats;
|
|
48
|
+
verbose?: boolean;
|
|
49
|
+
translationScope?: boolean;
|
|
50
|
+
fileNamespaces?: string[];
|
|
34
51
|
}
|
|
35
52
|
export interface ScanOptions {
|
|
36
53
|
dir?: string;
|
|
@@ -48,6 +65,12 @@ export interface ProjectContext {
|
|
|
48
65
|
cdnBaseUrl?: string;
|
|
49
66
|
lint?: LintConfig;
|
|
50
67
|
}
|
|
68
|
+
export interface DataStructureConfig {
|
|
69
|
+
enabled?: boolean;
|
|
70
|
+
requireTranslationScope?: boolean;
|
|
71
|
+
maxDepth?: number;
|
|
72
|
+
propertyNames?: string[];
|
|
73
|
+
}
|
|
51
74
|
export interface LintConfig {
|
|
52
75
|
include?: string[];
|
|
53
76
|
exclude?: string[];
|
|
@@ -55,16 +78,18 @@ export interface LintConfig {
|
|
|
55
78
|
rules?: Record<string, "error" | "warning" | "off">;
|
|
56
79
|
ignorePatterns?: RegExp[];
|
|
57
80
|
translationFunctions?: string[];
|
|
81
|
+
dataStructureDetection?: DataStructureConfig;
|
|
58
82
|
}
|
|
59
83
|
export interface ScanResult {
|
|
60
84
|
project?: ProjectContext;
|
|
61
85
|
files: number;
|
|
62
86
|
issues: Issue[];
|
|
63
87
|
duration: number;
|
|
64
|
-
localKeys?:
|
|
88
|
+
localKeys?: Record<string, string[]>;
|
|
89
|
+
dynamicPatterns?: DynamicPattern[];
|
|
65
90
|
comparison?: {
|
|
66
|
-
localKeys:
|
|
67
|
-
remoteKeys:
|
|
91
|
+
localKeys: Record<string, string[]>;
|
|
92
|
+
remoteKeys: Record<string, string[]>;
|
|
68
93
|
missingKeys: Record<string, string[]>;
|
|
69
94
|
unusedKeys: Record<string, string[]>;
|
|
70
95
|
coverage: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzer/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzer/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check command - Interactive translation key checker
|
|
3
|
+
*
|
|
4
|
+
* Provides user-friendly interface for checking missing and unused keys
|
|
5
|
+
*/
|
|
6
|
+
export interface CheckOptions {
|
|
7
|
+
dir?: string;
|
|
8
|
+
format?: "eslint" | "json";
|
|
9
|
+
verbose?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function checkCommand(options: CheckOptions): Promise<void>;
|
|
12
|
+
export declare function checkMissingCommand(options: CheckOptions): Promise<void>;
|
|
13
|
+
export declare function checkUnusedCommand(options: CheckOptions): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,iBAwCvD;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,YAAY,iBAc9D;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,iBAc7D"}
|