@better-i18n/cli 0.1.2 → 0.1.3
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/README.md +147 -33
- package/dist/analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/index.js +7 -3
- package/dist/analyzer/index.js.map +1 -1
- package/dist/analyzer/rules/index.d.ts +4 -3
- package/dist/analyzer/rules/index.d.ts.map +1 -1
- package/dist/analyzer/rules/index.js +4 -3
- package/dist/analyzer/rules/index.js.map +1 -1
- package/dist/analyzer/rules/translation-function.d.ts +12 -0
- package/dist/analyzer/rules/translation-function.d.ts.map +1 -0
- package/dist/analyzer/rules/translation-function.js +65 -0
- package/dist/analyzer/rules/translation-function.js.map +1 -0
- package/dist/analyzer/types.d.ts +13 -1
- package/dist/analyzer/types.d.ts.map +1 -1
- package/dist/commands/extract-keys.d.ts +13 -0
- package/dist/commands/extract-keys.d.ts.map +1 -0
- package/dist/commands/extract-keys.js +347 -0
- package/dist/commands/extract-keys.js.map +1 -0
- package/dist/context/detector.js +2 -2
- package/dist/context/detector.js.map +1 -1
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +12 -13
- package/dist/reporters/json.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -101,13 +101,101 @@ better-i18n scan --staged # Only scan git staged files
|
|
|
101
101
|
better-i18n scan --verbose # Show detailed output
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
+
### `better-i18n extract-keys`
|
|
105
|
+
|
|
106
|
+
Extract all translation keys used in your codebase (t() function calls).
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Extract all translation keys
|
|
110
|
+
better-i18n extract-keys
|
|
111
|
+
|
|
112
|
+
# Compare with remote keys from CDN
|
|
113
|
+
better-i18n extract-keys --compare
|
|
114
|
+
|
|
115
|
+
# Compare with specific locale
|
|
116
|
+
better-i18n extract-keys --compare --locale tr
|
|
117
|
+
|
|
118
|
+
# JSON output (default)
|
|
119
|
+
better-i18n extract-keys --format json
|
|
120
|
+
|
|
121
|
+
# Show detailed output
|
|
122
|
+
better-i18n extract-keys --verbose
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Output format (JSON):**
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"localKeys": {
|
|
130
|
+
"project": "better-i18n/landing",
|
|
131
|
+
"namespaces": {
|
|
132
|
+
"auth": ["auth.login", "auth.register", "auth.forgot"],
|
|
133
|
+
"nav": ["nav.home", "nav.about"],
|
|
134
|
+
"hero": ["hero.title", "hero.description"]
|
|
135
|
+
},
|
|
136
|
+
"totalCount": 6,
|
|
137
|
+
"filesScanned": 42
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**With `--compare`:**
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"comparison": {
|
|
147
|
+
"localKeys": { ... },
|
|
148
|
+
"remoteKeys": {
|
|
149
|
+
"namespaces": { ... },
|
|
150
|
+
"totalCount": 150
|
|
151
|
+
},
|
|
152
|
+
"missingKeys": {
|
|
153
|
+
"hero": ["hero.cta", "hero.benefits"]
|
|
154
|
+
},
|
|
155
|
+
"unusedKeys": {
|
|
156
|
+
"old": ["old.section"]
|
|
157
|
+
},
|
|
158
|
+
"coverage": {
|
|
159
|
+
"local": 85,
|
|
160
|
+
"remote": 96
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Human-readable output with `--compare`:**
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
✓ Project: better-i18n/landing
|
|
170
|
+
✓ Found 57 files
|
|
171
|
+
✓ Fetched 12 namespaces from CDN
|
|
172
|
+
|
|
173
|
+
📊 Translation Keys Comparison
|
|
174
|
+
|
|
175
|
+
Coverage:
|
|
176
|
+
Local → Remote: 85%
|
|
177
|
+
Remote Used: 96%
|
|
178
|
+
|
|
179
|
+
❌ Missing in Remote (2 keys):
|
|
180
|
+
hero: 2 keys
|
|
181
|
+
• hero.cta
|
|
182
|
+
• hero.benefits
|
|
183
|
+
|
|
184
|
+
⚠️ Unused in Code (1 key):
|
|
185
|
+
old: 1 key
|
|
186
|
+
• old.section
|
|
187
|
+
|
|
188
|
+
Scanned 57 files in 0.12s
|
|
189
|
+
✓ Comparison complete
|
|
190
|
+
```
|
|
191
|
+
|
|
104
192
|
## Detection Rules
|
|
105
193
|
|
|
106
|
-
| Rule
|
|
107
|
-
|
|
108
|
-
| `jsx-text`
|
|
109
|
-
| `jsx-attribute`
|
|
110
|
-
| `ternary-locale` | error
|
|
194
|
+
| Rule | Severity | What it catches | Example |
|
|
195
|
+
| ---------------- | -------- | ---------------------- | --------------------------------- |
|
|
196
|
+
| `jsx-text` | missing | Hardcoded text in JSX | `<h1>Hello</h1>` |
|
|
197
|
+
| `jsx-attribute` | missing | Hardcoded attributes | `<img alt="Logo" />` |
|
|
198
|
+
| `ternary-locale` | error | Locale-based ternaries | `locale === 'en' ? 'Hi' : 'Hola'` |
|
|
111
199
|
|
|
112
200
|
### Automatically Ignored
|
|
113
201
|
|
|
@@ -133,19 +221,19 @@ export const i18nWorkspaceConfig = {
|
|
|
133
221
|
lint: {
|
|
134
222
|
// Files to scan (defaults: ["src", "app", "components", "pages"])
|
|
135
223
|
include: ["src/**/*.tsx", "app/**/*.tsx"],
|
|
136
|
-
|
|
224
|
+
|
|
137
225
|
// Files to ignore (automatically merges with defaults)
|
|
138
226
|
exclude: [
|
|
139
|
-
"**/skeletons.tsx",
|
|
140
|
-
"**/*.stories.tsx",
|
|
141
|
-
"**/*.test.tsx",
|
|
142
|
-
"**/components/ui/**",
|
|
227
|
+
"**/skeletons.tsx", // Mock/demo components
|
|
228
|
+
"**/*.stories.tsx", // Storybook files
|
|
229
|
+
"**/*.test.tsx", // Test files
|
|
230
|
+
"**/components/ui/**", // UI library components
|
|
143
231
|
],
|
|
144
|
-
|
|
232
|
+
|
|
145
233
|
// Rule configuration (optional)
|
|
146
234
|
rules: {
|
|
147
235
|
"jsx-text": "warning",
|
|
148
|
-
"jsx-attribute": "warning",
|
|
236
|
+
"jsx-attribute": "warning",
|
|
149
237
|
"ternary-locale": "error",
|
|
150
238
|
},
|
|
151
239
|
},
|
|
@@ -154,11 +242,11 @@ export const i18nWorkspaceConfig = {
|
|
|
154
242
|
|
|
155
243
|
### Config Options
|
|
156
244
|
|
|
157
|
-
| Option
|
|
158
|
-
|
|
245
|
+
| Option | Type | Description |
|
|
246
|
+
| --------- | ---------- | ---------------------------------------------------------------------------------- |
|
|
159
247
|
| `include` | `string[]` | Glob patterns for files to scan (default: `["src", "app", "components", "pages"]`) |
|
|
160
|
-
| `exclude` | `string[]` | Glob patterns to ignore (merges with defaults: `node_modules`, `.next`, etc.)
|
|
161
|
-
| `rules`
|
|
248
|
+
| `exclude` | `string[]` | Glob patterns to ignore (merges with defaults: `node_modules`, `.next`, etc.) |
|
|
249
|
+
| `rules` | `object` | Set severity: `"error"` \| `"warning"` \| `"off"` |
|
|
162
250
|
|
|
163
251
|
## Usage Scenarios
|
|
164
252
|
|
|
@@ -176,6 +264,7 @@ Add to your `package.json`:
|
|
|
176
264
|
```
|
|
177
265
|
|
|
178
266
|
Run before commits:
|
|
267
|
+
|
|
179
268
|
```bash
|
|
180
269
|
npm run lint:i18n
|
|
181
270
|
```
|
|
@@ -214,7 +303,7 @@ jobs:
|
|
|
214
303
|
- uses: actions/checkout@v4
|
|
215
304
|
- uses: actions/setup-node@v4
|
|
216
305
|
with:
|
|
217
|
-
node-version:
|
|
306
|
+
node-version: "20"
|
|
218
307
|
- run: npx @better-i18n/cli scan --ci --format json
|
|
219
308
|
```
|
|
220
309
|
|
|
@@ -302,13 +391,13 @@ interface ScanResult {
|
|
|
302
391
|
}
|
|
303
392
|
|
|
304
393
|
interface Issue {
|
|
305
|
-
file: string;
|
|
306
|
-
line: number;
|
|
307
|
-
column: number;
|
|
308
|
-
text: string;
|
|
394
|
+
file: string; // Relative path
|
|
395
|
+
line: number; // Line number
|
|
396
|
+
column: number; // Column number
|
|
397
|
+
text: string; // Hardcoded text
|
|
309
398
|
type: "jsx-text" | "jsx-attribute" | "ternary-locale";
|
|
310
399
|
severity: "error" | "warning";
|
|
311
|
-
message: string;
|
|
400
|
+
message: string; // Human-readable message
|
|
312
401
|
suggestedKey?: string; // Auto-generated translation key
|
|
313
402
|
}
|
|
314
403
|
```
|
|
@@ -346,32 +435,57 @@ npm-run-all --parallel typecheck lint:eslint lint:i18n
|
|
|
346
435
|
### Config not detected
|
|
347
436
|
|
|
348
437
|
Make sure your `i18n.config.ts` exports either:
|
|
438
|
+
|
|
349
439
|
- `export const project = "org/slug"`
|
|
350
440
|
- `export const i18nWorkspaceConfig = { project: "org/slug" }`
|
|
351
441
|
|
|
352
442
|
### Too many false positives
|
|
353
443
|
|
|
354
444
|
Add exclusions to your config:
|
|
445
|
+
|
|
355
446
|
```ts
|
|
356
|
-
exclude: [
|
|
357
|
-
"**/*.stories.tsx",
|
|
358
|
-
"**/demo/**",
|
|
359
|
-
"**/examples/**",
|
|
360
|
-
]
|
|
447
|
+
exclude: ["**/*.stories.tsx", "**/demo/**", "**/examples/**"];
|
|
361
448
|
```
|
|
362
449
|
|
|
363
450
|
### Clickable links not working
|
|
364
451
|
|
|
365
452
|
Make sure you're using VS Code's integrated terminal. External terminals may not support clickable file paths.
|
|
366
453
|
|
|
367
|
-
## Part of Better i18n
|
|
454
|
+
## Part of Better i18n Ecosystem
|
|
455
|
+
|
|
456
|
+
This CLI is one component of the **Better i18n translation management platform**:
|
|
457
|
+
|
|
458
|
+
### Platform Components
|
|
368
459
|
|
|
369
|
-
|
|
460
|
+
- **[@better-i18n/cli](https://www.npmjs.com/package/@better-i18n/cli)** - This CLI tool (detect hardcoded strings, extract keys)
|
|
461
|
+
- **[@better-i18n/next](https://www.npmjs.com/package/@better-i18n/next)** - Next.js SDK for runtime translation
|
|
462
|
+
- **[@better-i18n/app](https://dash.better-i18n.com)** - Web dashboard for translation management
|
|
463
|
+
- `@better-i18n/mcp`: Model Context Protocol server for AI assistants.
|
|
464
|
+
|
|
465
|
+
### Platform Features
|
|
466
|
+
|
|
467
|
+
- **GitHub Integration** - Sync translations with your repositories
|
|
468
|
+
- **Real-time Collaboration** - Team workflows on translations
|
|
469
|
+
- **CDN Delivery** - Serve translations globally from edge locations
|
|
470
|
+
- **Multi-language Editor** - Manage all languages in one interface
|
|
471
|
+
- **REST API** - Programmatic access for CI/CD automation
|
|
472
|
+
- **AI Context Analysis** - Automatically extract terminology from websites
|
|
473
|
+
- **Namespace Organization** - Organize translations by feature/module
|
|
474
|
+
|
|
475
|
+
### How This CLI Fits In
|
|
476
|
+
|
|
477
|
+
```
|
|
478
|
+
Developer Workflow:
|
|
479
|
+
├─ Write code with hardcoded strings
|
|
480
|
+
├─ Run: better-i18n scan → Detect hardcoded strings ⚠️
|
|
481
|
+
├─ Run: better-i18n extract-keys → Extract used keys
|
|
482
|
+
├─ Review in Better i18n Dashboard
|
|
483
|
+
├─ GitHub Hook: better-i18n scan --staged → Pre-commit check
|
|
484
|
+
├─ CI/CD: better-i18n scan --ci → Fail build if strings found
|
|
485
|
+
└─ Dashboard: Manage translations, sync with GitHub
|
|
486
|
+
```
|
|
370
487
|
|
|
371
|
-
|
|
372
|
-
- **[@better-i18n/cli](https://www.npmjs.com/package/@better-i18n/cli)** - This CLI tool
|
|
373
|
-
- **[Dashboard](https://better-i18n.com)** - Visual translation management
|
|
374
|
-
- **[MCP Server](https://github.com/better-i18n/better-i18n)** - AI-powered translation assistant
|
|
488
|
+
The CLI works **in your local development** to catch issues before they ship, while the platform handles the translation management workflow.
|
|
375
489
|
|
|
376
490
|
## Contributing
|
|
377
491
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAEjE;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,KAAK,EAAE,CAAC,CAGlB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,UAAU,GAClB,KAAK,EAAE,CAiDT"}
|
package/dist/analyzer/index.js
CHANGED
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { readFileSync } from "node:fs";
|
|
7
7
|
import ts from "typescript";
|
|
8
|
-
import { checkJsxAttribute } from "./rules/
|
|
9
|
-
import { checkJsxText } from "./rules/jsx-text.js";
|
|
10
|
-
import { checkTernaryLocale } from "./rules/ternary-locale.js";
|
|
8
|
+
import { checkJsxAttribute, checkJsxText, checkTernaryLocale, checkTranslationFunction, } from "./rules/index.js";
|
|
11
9
|
/**
|
|
12
10
|
* Analyze a single file for hardcoded strings
|
|
13
11
|
*/
|
|
@@ -46,6 +44,12 @@ export function analyzeSourceText(sourceText, filePath, config) {
|
|
|
46
44
|
if (issue)
|
|
47
45
|
issues.push(issue);
|
|
48
46
|
}
|
|
47
|
+
// Translation function calls
|
|
48
|
+
if (ts.isCallExpression(node)) {
|
|
49
|
+
const issue = checkTranslationFunction(node, ctx);
|
|
50
|
+
if (issue)
|
|
51
|
+
issues.push(issue);
|
|
52
|
+
}
|
|
49
53
|
ts.forEachChild(node, visit);
|
|
50
54
|
}
|
|
51
55
|
visit(sourceFile);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAG1B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAgB,EAChB,MAAmB;IAEnB,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,OAAO,iBAAiB,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAAkB,EAClB,QAAgB,EAChB,MAAmB;IAEnB,MAAM,UAAU,GAAG,EAAE,CAAC,gBAAgB,CACpC,QAAQ,EACR,UAAU,EACV,EAAE,CAAC,YAAY,CAAC,MAAM,EACtB,IAAI,EACJ,aAAa,CAAC,QAAQ,CAAC,CACxB,CAAC;IAEF,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IAElD,6BAA6B;IAC7B,MAAM,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;IAClC,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,KAAK,CAAC;IACnD,MAAM,cAAc,GAAG,KAAK,CAAC,eAAe,CAAC,KAAK,KAAK,CAAC;IACxD,MAAM,cAAc,GAAG,KAAK,CAAC,gBAAgB,CAAC,KAAK,KAAK,CAAC;IAEzD,SAAS,KAAK,CAAC,IAAa;QAC1B,WAAW;QACX,IAAI,cAAc,IAAI,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACtC,IAAI,KAAK;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,gBAAgB;QAChB,IAAI,cAAc,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC3C,IAAI,KAAK;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,sBAAsB;QACtB,IAAI,cAAc,IAAI,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC5C,IAAI,KAAK;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,6BAA6B;QAC7B,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAClD,IAAI,KAAK;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,CAAC;IAElB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,QAAgB;IACrC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;IACxD,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;IACxD,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;IACtD,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rules index - exports all detection rules
|
|
3
3
|
*/
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
4
|
+
export * from "./jsx-attribute.js";
|
|
5
|
+
export * from "./jsx-text.js";
|
|
6
|
+
export * from "./ternary-locale.js";
|
|
7
|
+
export * from "./translation-function.js";
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rules index - exports all detection rules
|
|
3
3
|
*/
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
4
|
+
export * from "./jsx-attribute.js";
|
|
5
|
+
export * from "./jsx-text.js";
|
|
6
|
+
export * from "./ternary-locale.js";
|
|
7
|
+
export * from "./translation-function.js";
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translation function detection rule
|
|
3
|
+
*
|
|
4
|
+
* Detects t() function calls to extract translation keys used in code
|
|
5
|
+
*/
|
|
6
|
+
import ts from "typescript";
|
|
7
|
+
import type { Issue, RuleContext } from "../types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Check for translation function calls
|
|
10
|
+
*/
|
|
11
|
+
export declare function checkTranslationFunction(node: ts.CallExpression, ctx: RuleContext): Issue | null;
|
|
12
|
+
//# sourceMappingURL=translation-function.d.ts.map
|
|
@@ -0,0 +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;AAOtD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,EAAE,CAAC,cAAc,EACvB,GAAG,EAAE,WAAW,GACf,KAAK,GAAG,IAAI,CAyCd"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translation function detection rule
|
|
3
|
+
*
|
|
4
|
+
* Detects t() function calls to extract translation keys used in code
|
|
5
|
+
*/
|
|
6
|
+
import ts from "typescript";
|
|
7
|
+
/**
|
|
8
|
+
* Translation function names to detect
|
|
9
|
+
*/
|
|
10
|
+
const TRANSLATION_FUNCTIONS = new Set(["t", "useTranslation"]);
|
|
11
|
+
/**
|
|
12
|
+
* Check for translation function calls
|
|
13
|
+
*/
|
|
14
|
+
export function checkTranslationFunction(node, ctx) {
|
|
15
|
+
// Check if it's a known translation function
|
|
16
|
+
const funcName = getFunctionName(node);
|
|
17
|
+
if (!funcName || !TRANSLATION_FUNCTIONS.has(funcName)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
// Get the first argument (usually the translation key)
|
|
21
|
+
const args = node.arguments;
|
|
22
|
+
if (args.length === 0) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const firstArg = args[0];
|
|
26
|
+
// Handle string literal: t("auth.login")
|
|
27
|
+
if (ts.isStringLiteral(firstArg)) {
|
|
28
|
+
const pos = ctx.sourceFile.getLineAndCharacterOfPosition(firstArg.getStart());
|
|
29
|
+
return {
|
|
30
|
+
file: ctx.filePath,
|
|
31
|
+
line: pos.line + 1,
|
|
32
|
+
column: pos.character + 1,
|
|
33
|
+
text: firstArg.text,
|
|
34
|
+
type: "string-variable",
|
|
35
|
+
severity: "info",
|
|
36
|
+
message: `Translation key: "${firstArg.text}"`,
|
|
37
|
+
key: firstArg.text,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// Handle template literal: t(`auth.${type}`)
|
|
41
|
+
if (ts.isTemplateExpression(firstArg)) {
|
|
42
|
+
// Skip dynamic keys - can't extract statically
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
// Handle identifier: t(keyVar) - can't extract statically
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extract function name from call expression
|
|
50
|
+
*/
|
|
51
|
+
function getFunctionName(node) {
|
|
52
|
+
const expr = node.expression;
|
|
53
|
+
// Simple identifier: t()
|
|
54
|
+
if (ts.isIdentifier(expr)) {
|
|
55
|
+
return expr.text;
|
|
56
|
+
}
|
|
57
|
+
// Property access: obj.t()
|
|
58
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
59
|
+
return expr.name.text;
|
|
60
|
+
}
|
|
61
|
+
// Hook destructuring: const { t } = useTranslation(); t()
|
|
62
|
+
// Already handled by Identifier case above
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=translation-function.js.map
|
|
@@ -0,0 +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,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uDAAuD;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;IAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAEzB,yCAAyC;IACzC,IAAI,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,6BAA6B,CACtD,QAAQ,CAAC,QAAQ,EAAE,CACpB,CAAC;QAEF,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,QAAQ;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC;YAClB,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,CAAC;YACzB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,qBAAqB,QAAQ,CAAC,IAAI,GAAG;YAC9C,GAAG,EAAE,QAAQ,CAAC,IAAI;SACnB,CAAC;IACJ,CAAC;IAED,6CAA6C;IAC7C,IAAI,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,+CAA+C;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0DAA0D;IAC1D,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,IAAuB;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;IAE7B,yBAAyB;IACzB,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,2BAA2B;IAC3B,IAAI,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;IAED,0DAA0D;IAC1D,2CAA2C;IAE3C,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/analyzer/types.d.ts
CHANGED
|
@@ -7,9 +7,10 @@ export interface Issue {
|
|
|
7
7
|
column: number;
|
|
8
8
|
text: string;
|
|
9
9
|
type: "jsx-text" | "jsx-attribute" | "ternary-locale" | "string-variable";
|
|
10
|
-
severity: "error" | "warning";
|
|
10
|
+
severity: "error" | "warning" | "info";
|
|
11
11
|
message: string;
|
|
12
12
|
suggestedKey?: string;
|
|
13
|
+
key?: string;
|
|
13
14
|
}
|
|
14
15
|
export interface RuleContext {
|
|
15
16
|
filePath: string;
|
|
@@ -44,5 +45,16 @@ export interface ScanResult {
|
|
|
44
45
|
files: number;
|
|
45
46
|
issues: Issue[];
|
|
46
47
|
duration: number;
|
|
48
|
+
localKeys?: any;
|
|
49
|
+
comparison?: {
|
|
50
|
+
localKeys: any;
|
|
51
|
+
remoteKeys: any;
|
|
52
|
+
missingKeys: Record<string, string[]>;
|
|
53
|
+
unusedKeys: Record<string, string[]>;
|
|
54
|
+
coverage: {
|
|
55
|
+
local: number;
|
|
56
|
+
remote: number;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
47
59
|
}
|
|
48
60
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -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,EAAE,UAAU,GAAG,eAAe,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;IAC1E,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;
|
|
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,EAAE,UAAU,GAAG,eAAe,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;IAC1E,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,YAAY,EAAE,UAAU,CAAC;CAC7C;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,KAAK,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,UAAU,CAAC,EAAE;QACX,SAAS,EAAE,GAAG,CAAC;QACf,UAAU,EAAE,GAAG,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACrC,QAAQ,EAAE;YACR,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC;KACH,CAAC;CACH"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract translation keys command
|
|
3
|
+
*
|
|
4
|
+
* Extracts all t() function calls and organizes by namespace
|
|
5
|
+
*/
|
|
6
|
+
import type { ScanOptions } from "../analyzer/types.js";
|
|
7
|
+
export interface ExtractKeysOptions extends ScanOptions {
|
|
8
|
+
compare?: boolean;
|
|
9
|
+
locale?: string;
|
|
10
|
+
format: "eslint" | "json";
|
|
11
|
+
}
|
|
12
|
+
export declare function extractKeysCommand(options: ExtractKeysOptions): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=extract-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-keys.d.ts","sourceRoot":"","sources":["../../src/commands/extract-keys.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAS,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAI/D,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;CAC3B;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,iBA6InE"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract translation keys command
|
|
3
|
+
*
|
|
4
|
+
* Extracts all t() function calls and organizes by namespace
|
|
5
|
+
*/
|
|
6
|
+
import ora from "ora";
|
|
7
|
+
import { collectFiles } from "../analyzer/file-collector.js";
|
|
8
|
+
import { analyzeFile } from "../analyzer/index.js";
|
|
9
|
+
import { detectProjectContext } from "../context/detector.js";
|
|
10
|
+
import { bold, dim, green, red, yellow } from "../utils/colors.js";
|
|
11
|
+
export async function extractKeysCommand(options) {
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
const isJson = options.format === "json";
|
|
14
|
+
const spinner = isJson
|
|
15
|
+
? {
|
|
16
|
+
start: () => { },
|
|
17
|
+
stop: () => { },
|
|
18
|
+
clear: () => { },
|
|
19
|
+
succeed: () => { },
|
|
20
|
+
fail: () => { },
|
|
21
|
+
warn: () => { },
|
|
22
|
+
}
|
|
23
|
+
: ora({ text: "Detecting project...", color: "cyan" }).start();
|
|
24
|
+
// Step 1: Detect project context
|
|
25
|
+
const rootDir = options.dir || process.cwd();
|
|
26
|
+
const context = await detectProjectContext(rootDir);
|
|
27
|
+
if (context) {
|
|
28
|
+
spinner.succeed(`Project: ${bold(context.workspaceId + "/" + context.projectSlug)}`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
spinner.warn("No i18n.config.ts found, using defaults");
|
|
32
|
+
}
|
|
33
|
+
// Step 2: Collect files
|
|
34
|
+
spinner.start("Collecting files...");
|
|
35
|
+
const files = await collectFiles({
|
|
36
|
+
rootDir,
|
|
37
|
+
include: context?.lint?.include,
|
|
38
|
+
exclude: context?.lint?.exclude,
|
|
39
|
+
});
|
|
40
|
+
if (files.length === 0) {
|
|
41
|
+
spinner.fail("No .tsx or .jsx files found");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
spinner.succeed(`Found ${files.length} files`);
|
|
45
|
+
// Step 3: Analyze files for t() calls
|
|
46
|
+
spinner.start("Extracting translation keys...");
|
|
47
|
+
const allIssues = [];
|
|
48
|
+
for (const file of files) {
|
|
49
|
+
try {
|
|
50
|
+
const issues = await analyzeFile(file, context?.lint);
|
|
51
|
+
// Filter only translation function calls
|
|
52
|
+
const translationKeys = issues.filter((i) => i.type === "string-variable");
|
|
53
|
+
allIssues.push(...translationKeys);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (options.verbose) {
|
|
57
|
+
console.error(`Error analyzing ${file}:`, error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
spinner.clear();
|
|
62
|
+
// Step 4: Organize keys by namespace
|
|
63
|
+
const keysByNamespace = groupKeysByNamespace(allIssues);
|
|
64
|
+
const localKeys = {
|
|
65
|
+
project: context
|
|
66
|
+
? `${context.workspaceId}/${context.projectSlug}`
|
|
67
|
+
: "unknown",
|
|
68
|
+
namespaces: keysByNamespace,
|
|
69
|
+
totalCount: allIssues.length,
|
|
70
|
+
filesScanned: files.length,
|
|
71
|
+
};
|
|
72
|
+
// Step 5: Compare with CDN if requested
|
|
73
|
+
if (options.compare && context?.cdnBaseUrl) {
|
|
74
|
+
const locale = options.locale || context.defaultLocale || "en";
|
|
75
|
+
spinner.start(`Comparing with CDN (${locale})...`);
|
|
76
|
+
try {
|
|
77
|
+
const remoteKeys = await fetchRemoteKeys(context.cdnBaseUrl, context.workspaceId, context.projectSlug, locale);
|
|
78
|
+
spinner.succeed(`Fetched ${Object.keys(remoteKeys).length} namespaces from CDN`);
|
|
79
|
+
// Compare
|
|
80
|
+
const comparison = compareKeys(localKeys.namespaces, remoteKeys);
|
|
81
|
+
const duration = Date.now() - startTime;
|
|
82
|
+
// Report comparison
|
|
83
|
+
if (options.format === "json") {
|
|
84
|
+
const output = {
|
|
85
|
+
comparison: {
|
|
86
|
+
localKeys,
|
|
87
|
+
remoteKeys: {
|
|
88
|
+
namespaces: remoteKeys,
|
|
89
|
+
totalCount: countTotalKeys(remoteKeys),
|
|
90
|
+
},
|
|
91
|
+
missingKeys: comparison.missing,
|
|
92
|
+
unusedKeys: comparison.unused,
|
|
93
|
+
coverage: {
|
|
94
|
+
local: calculateCoverage(localKeys.totalCount, comparison.missing),
|
|
95
|
+
remote: calculateRemoteCoverage(localKeys.namespaces, remoteKeys),
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
files: files.length,
|
|
99
|
+
duration,
|
|
100
|
+
};
|
|
101
|
+
console.log(JSON.stringify(output, null, 2));
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
reportComparisonReport(localKeys, remoteKeys, comparison, duration);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
spinner.fail(`Failed to fetch remote keys: ${error instanceof Error ? error.message : String(error)}`);
|
|
109
|
+
reportLocalKeys(localKeys, allIssues.length, Date.now() - startTime);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// Just report local keys
|
|
114
|
+
const duration = Date.now() - startTime;
|
|
115
|
+
if (options.format === "json") {
|
|
116
|
+
const output = {
|
|
117
|
+
localKeys,
|
|
118
|
+
files: files.length,
|
|
119
|
+
duration,
|
|
120
|
+
};
|
|
121
|
+
console.log(JSON.stringify(output, null, 2));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
reportLocalKeys(localKeys, allIssues.length, duration);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Group keys by namespace
|
|
130
|
+
*/
|
|
131
|
+
function groupKeysByNamespace(issues) {
|
|
132
|
+
const result = {};
|
|
133
|
+
for (const issue of issues) {
|
|
134
|
+
if (!issue.key)
|
|
135
|
+
continue;
|
|
136
|
+
const parts = issue.key.split(".");
|
|
137
|
+
const namespace = parts.length > 1 ? parts[0] : "default";
|
|
138
|
+
const fullKey = issue.key;
|
|
139
|
+
if (!result[namespace]) {
|
|
140
|
+
result[namespace] = new Set();
|
|
141
|
+
}
|
|
142
|
+
result[namespace].add(fullKey);
|
|
143
|
+
}
|
|
144
|
+
// Convert Sets to arrays
|
|
145
|
+
const output = {};
|
|
146
|
+
for (const [namespace, keys] of Object.entries(result)) {
|
|
147
|
+
output[namespace] = Array.from(keys).sort();
|
|
148
|
+
}
|
|
149
|
+
return output;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Fetch remote keys from CDN
|
|
153
|
+
*/
|
|
154
|
+
async function fetchRemoteKeys(cdnBaseUrl, workspaceId, projectSlug, locale) {
|
|
155
|
+
const url = `${cdnBaseUrl}/${workspaceId}/${projectSlug}/${locale}/translations.json`;
|
|
156
|
+
const response = await fetch(url);
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
throw new Error(`CDN fetch failed (${response.status})`);
|
|
159
|
+
}
|
|
160
|
+
return response.json();
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Compare local and remote keys
|
|
164
|
+
*/
|
|
165
|
+
function compareKeys(localKeys, remoteKeys) {
|
|
166
|
+
const missing = {};
|
|
167
|
+
const unused = {};
|
|
168
|
+
const allNamespaces = new Set([
|
|
169
|
+
...Object.keys(localKeys),
|
|
170
|
+
...Object.keys(flattenKeys(remoteKeys)),
|
|
171
|
+
]);
|
|
172
|
+
for (const namespace of allNamespaces) {
|
|
173
|
+
const local = new Set(localKeys[namespace] || []);
|
|
174
|
+
const remote = new Set(getNamespaceKeys(remoteKeys, namespace));
|
|
175
|
+
// Missing in remote (need to add)
|
|
176
|
+
const missingInRemote = Array.from(local).filter((k) => !remote.has(k));
|
|
177
|
+
if (missingInRemote.length > 0) {
|
|
178
|
+
missing[namespace] = missingInRemote;
|
|
179
|
+
}
|
|
180
|
+
// Unused in local (in remote but not used)
|
|
181
|
+
const unusedInLocal = Array.from(remote).filter((k) => !local.has(k));
|
|
182
|
+
if (unusedInLocal.length > 0) {
|
|
183
|
+
unused[namespace] = unusedInLocal;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return { missing, unused };
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Flatten remote keys to get all namespaces
|
|
190
|
+
*/
|
|
191
|
+
function flattenKeys(remoteKeys) {
|
|
192
|
+
const result = {};
|
|
193
|
+
function traverse(obj, prefix = "") {
|
|
194
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
195
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
196
|
+
if (typeof value === "string") {
|
|
197
|
+
const namespace = fullKey.split(".")[0] || "default";
|
|
198
|
+
if (!result[namespace])
|
|
199
|
+
result[namespace] = [];
|
|
200
|
+
result[namespace].push(fullKey);
|
|
201
|
+
}
|
|
202
|
+
else if (typeof value === "object" && value !== null) {
|
|
203
|
+
traverse(value, fullKey);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
traverse(remoteKeys);
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get keys for a specific namespace from remote
|
|
212
|
+
*/
|
|
213
|
+
function getNamespaceKeys(remoteKeys, namespace) {
|
|
214
|
+
const result = [];
|
|
215
|
+
const prefix = namespace + ".";
|
|
216
|
+
function traverse(obj, currentKey = "") {
|
|
217
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
218
|
+
const fullKey = currentKey ? `${currentKey}.${key}` : key;
|
|
219
|
+
if (typeof value === "string") {
|
|
220
|
+
if (fullKey.startsWith(prefix)) {
|
|
221
|
+
result.push(fullKey);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else if (typeof value === "object" && value !== null) {
|
|
225
|
+
traverse(value, fullKey);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
traverse(remoteKeys);
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Count total keys in nested structure
|
|
234
|
+
*/
|
|
235
|
+
function countTotalKeys(remoteKeys) {
|
|
236
|
+
let count = 0;
|
|
237
|
+
function traverse(obj) {
|
|
238
|
+
for (const value of Object.values(obj)) {
|
|
239
|
+
if (typeof value === "string") {
|
|
240
|
+
count++;
|
|
241
|
+
}
|
|
242
|
+
else if (typeof value === "object" && value !== null) {
|
|
243
|
+
traverse(value);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
traverse(remoteKeys);
|
|
248
|
+
return count;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Calculate local coverage (what % of local keys exist in remote)
|
|
252
|
+
*/
|
|
253
|
+
function calculateCoverage(localCount, missing) {
|
|
254
|
+
const missingCount = Object.values(missing).reduce((sum, arr) => sum + arr.length, 0);
|
|
255
|
+
if (localCount === 0)
|
|
256
|
+
return 100;
|
|
257
|
+
return Math.round(((localCount - missingCount) / localCount) * 100);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Calculate remote coverage (what % of remote keys are used)
|
|
261
|
+
*/
|
|
262
|
+
function calculateRemoteCoverage(localKeys, remoteKeys) {
|
|
263
|
+
const remoteFlattened = flattenKeys(remoteKeys);
|
|
264
|
+
let remoteUsedCount = 0;
|
|
265
|
+
let remoteTotalCount = 0;
|
|
266
|
+
for (const [namespace, keys] of Object.entries(remoteFlattened)) {
|
|
267
|
+
const local = new Set(localKeys[namespace] || []);
|
|
268
|
+
const used = keys.filter((k) => local.has(k));
|
|
269
|
+
remoteUsedCount += used.length;
|
|
270
|
+
remoteTotalCount += keys.length;
|
|
271
|
+
}
|
|
272
|
+
if (remoteTotalCount === 0)
|
|
273
|
+
return 0;
|
|
274
|
+
return Math.round((remoteUsedCount / remoteTotalCount) * 100);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Report local keys (human-readable)
|
|
278
|
+
*/
|
|
279
|
+
function reportLocalKeys(localKeys, _issueCount, duration) {
|
|
280
|
+
console.log();
|
|
281
|
+
console.log(bold("📦 Local Translation Keys"));
|
|
282
|
+
console.log();
|
|
283
|
+
const sortedNamespaces = Object.keys(localKeys.namespaces).sort();
|
|
284
|
+
for (const namespace of sortedNamespaces) {
|
|
285
|
+
const keys = localKeys.namespaces[namespace];
|
|
286
|
+
console.log(`${dim(`${namespace}:`)} ${keys.length} keys`);
|
|
287
|
+
for (const key of keys) {
|
|
288
|
+
console.log(` ${dim("•")} ${key}`);
|
|
289
|
+
}
|
|
290
|
+
console.log();
|
|
291
|
+
}
|
|
292
|
+
console.log(green(bold(`✓ Found ${localKeys.totalCount} translation keys`)));
|
|
293
|
+
console.log(dim(`Scanned ${localKeys.filesScanned} files in ${(duration / 1000).toFixed(2)}s`));
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Report comparison (human-readable)
|
|
297
|
+
*/
|
|
298
|
+
function reportComparisonReport(localKeys, remoteKeys, comparison, duration) {
|
|
299
|
+
console.log();
|
|
300
|
+
console.log(bold("📊 Translation Keys Comparison"));
|
|
301
|
+
console.log();
|
|
302
|
+
// Coverage
|
|
303
|
+
const localCoverage = calculateCoverage(localKeys.totalCount, comparison.missing);
|
|
304
|
+
const remoteCoverage = calculateRemoteCoverage(localKeys.namespaces, remoteKeys);
|
|
305
|
+
console.log(`${dim("Coverage:")}`);
|
|
306
|
+
console.log(` Local → Remote: ${localCoverage}%`);
|
|
307
|
+
console.log(` Remote Used: ${remoteCoverage}%`);
|
|
308
|
+
console.log();
|
|
309
|
+
// Missing keys
|
|
310
|
+
const totalMissing = Object.values(comparison.missing).reduce((sum, arr) => sum + arr.length, 0);
|
|
311
|
+
if (totalMissing > 0) {
|
|
312
|
+
console.log(`${red(bold(`❌ Missing in Remote (${totalMissing} keys):`))}`);
|
|
313
|
+
console.log();
|
|
314
|
+
for (const [namespace, keys] of Object.entries(comparison.missing)) {
|
|
315
|
+
console.log(`${dim(`${namespace}:`)} ${keys.length} keys`);
|
|
316
|
+
for (const key of keys) {
|
|
317
|
+
console.log(` ${dim("•")} ${key}`);
|
|
318
|
+
}
|
|
319
|
+
console.log();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
console.log(green(bold("✓ No missing keys!")));
|
|
324
|
+
console.log();
|
|
325
|
+
}
|
|
326
|
+
// Unused keys
|
|
327
|
+
const totalUnused = Object.values(comparison.unused).reduce((sum, arr) => sum + arr.length, 0);
|
|
328
|
+
if (totalUnused > 0) {
|
|
329
|
+
console.log(`${yellow(bold(`⚠️ Unused in Code (${totalUnused} keys):`))}`);
|
|
330
|
+
console.log();
|
|
331
|
+
for (const [namespace, keys] of Object.entries(comparison.unused).slice(0, 5)) {
|
|
332
|
+
console.log(`${dim(`${namespace}:`)} ${keys.length} keys`);
|
|
333
|
+
for (const key of keys.slice(0, 3)) {
|
|
334
|
+
console.log(` ${dim("•")} ${key}`);
|
|
335
|
+
}
|
|
336
|
+
if (keys.length > 3) {
|
|
337
|
+
console.log(` ${dim(` ... and ${keys.length - 3} more`)}`);
|
|
338
|
+
}
|
|
339
|
+
console.log();
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Summary
|
|
343
|
+
console.log();
|
|
344
|
+
console.log(dim(`Scanned ${localKeys.filesScanned} files in ${(duration / 1000).toFixed(2)}s`));
|
|
345
|
+
console.log(green(bold(`✓ Comparison complete`)));
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=extract-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-keys.js","sourceRoot":"","sources":["../../src/commands/extract-keys.ts"],"names":[],"mappings":"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"}
|
package/dist/context/detector.js
CHANGED
|
@@ -133,8 +133,8 @@ function parseI18nConfig(filePath) {
|
|
|
133
133
|
const projectConstMatch = content.match(/(?:export\s+)?const\s+project\s*=\s*['"]([^'"]+\/[^'"]+)['"]/);
|
|
134
134
|
if (projectConstMatch) {
|
|
135
135
|
const [workspaceId, projectSlug] = projectConstMatch[1].split("/");
|
|
136
|
-
const localeMatch = content.match(/defaultLocale[:\s]*['"]([^'"]+)['"]/);
|
|
137
|
-
const cdnMatch = content.match(/cdnBaseUrl[:\s]*['"]([^'"]+)['"]/);
|
|
136
|
+
const localeMatch = content.match(/defaultLocale[:\s=]*['"]([^'"]+)['"]/);
|
|
137
|
+
const cdnMatch = content.match(/cdnBaseUrl[:\s=]*['"]([^'"]+)['"]/);
|
|
138
138
|
const lint = parseLintConfig(content);
|
|
139
139
|
return {
|
|
140
140
|
workspaceId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/context/detector.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/context/detector.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
* Automatically reads i18n.config.ts for project context.
|
|
7
7
|
*/
|
|
8
8
|
import { program } from "commander";
|
|
9
|
+
import { extractKeysCommand } from "./commands/extract-keys.js";
|
|
9
10
|
import { scanCommand } from "./commands/scan.js";
|
|
10
11
|
program
|
|
11
12
|
.name("better-i18n")
|
|
12
|
-
.description("Detect hardcoded strings in your React/Next.js app")
|
|
13
|
-
.version("0.1.
|
|
13
|
+
.description("Detect hardcoded strings and extract translation keys in your React/Next.js app")
|
|
14
|
+
.version("0.1.2");
|
|
14
15
|
program
|
|
15
16
|
.command("scan")
|
|
16
17
|
.description("Scan source files for untranslated strings")
|
|
@@ -22,5 +23,15 @@ program
|
|
|
22
23
|
.option("--staged", "Only scan git staged files")
|
|
23
24
|
.option("--verbose", "Show detailed output")
|
|
24
25
|
.action(scanCommand);
|
|
26
|
+
program
|
|
27
|
+
.command("extract-keys")
|
|
28
|
+
.alias("extract")
|
|
29
|
+
.description("Extract all translation keys (t() calls) from codebase")
|
|
30
|
+
.option("-d, --dir <path>", "Directory to scan (default: current directory)")
|
|
31
|
+
.option("-f, --format <type>", "Output format: eslint, json", "eslint")
|
|
32
|
+
.option("--compare", "Compare with remote keys from CDN")
|
|
33
|
+
.option("--locale <code>", "Locale to fetch from CDN (default: en)")
|
|
34
|
+
.option("--verbose", "Show detailed output")
|
|
35
|
+
.action(extractKeysCommand);
|
|
25
36
|
program.parse();
|
|
26
37
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CACV,iFAAiF,CAClF;KACA,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CACL,uBAAuB,EACvB,oDAAoD,EACpD,QAAQ,CACT;KACA,MAAM,CAAC,OAAO,EAAE,wCAAwC,CAAC;KACzD,MAAM,CAAC,MAAM,EAAE,+CAA+C,CAAC;KAC/D,MAAM,CAAC,UAAU,EAAE,4BAA4B,CAAC;KAChD,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,KAAK,CAAC,SAAS,CAAC;KAChB,WAAW,CAAC,wDAAwD,CAAC;KACrE,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CAAC,WAAW,EAAE,mCAAmC,CAAC;KACxD,MAAM,CAAC,iBAAiB,EAAE,wCAAwC,CAAC;KACnE,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE9B,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/reporters/json.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/reporters/json.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAS,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CA2BnD"}
|
package/dist/reporters/json.js
CHANGED
|
@@ -13,22 +13,21 @@ export function reportJson(result) {
|
|
|
13
13
|
}
|
|
14
14
|
: null,
|
|
15
15
|
summary: {
|
|
16
|
-
|
|
16
|
+
issues: result.issues.length,
|
|
17
17
|
errors: result.issues.filter((i) => i.severity === "error").length,
|
|
18
18
|
warnings: result.issues.filter((i) => i.severity === "warning").length,
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
duration: result.duration,
|
|
20
|
+
results: result.issues.map((issue) => ({
|
|
21
|
+
file: issue.file,
|
|
22
|
+
line: issue.line,
|
|
23
|
+
column: issue.column,
|
|
24
|
+
type: issue.type,
|
|
25
|
+
severity: issue.severity,
|
|
26
|
+
message: issue.message,
|
|
27
|
+
text: issue.text,
|
|
28
|
+
suggestedKey: issue.suggestedKey,
|
|
29
|
+
})),
|
|
21
30
|
},
|
|
22
|
-
issues: result.issues.map((issue) => ({
|
|
23
|
-
file: issue.file,
|
|
24
|
-
line: issue.line,
|
|
25
|
-
column: issue.column,
|
|
26
|
-
type: issue.type,
|
|
27
|
-
severity: issue.severity,
|
|
28
|
-
message: issue.message,
|
|
29
|
-
text: issue.text,
|
|
30
|
-
suggestedKey: issue.suggestedKey,
|
|
31
|
-
})),
|
|
32
31
|
};
|
|
33
32
|
console.log(JSON.stringify(output, null, 2));
|
|
34
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/reporters/json.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAkB;IAC3C,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACrB,CAAC,CAAC;gBACA,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW;gBACrC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW;aACjC;YACD,CAAC,CAAC,IAAI;QACR,OAAO,EAAE;YACP,
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/reporters/json.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAkB;IAC3C,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACrB,CAAC,CAAC;gBACA,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW;gBACrC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW;aACjC;YACD,CAAC,CAAC,IAAI;QACR,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;YAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM;YACzE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM;YAC7E,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAY,EAAE,EAAE,CAAC,CAAC;gBAC5C,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,YAAY,EAAE,KAAK,CAAC,YAAY;aACjC,CAAC,CAAC;SACJ;KACF,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-i18n/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "CLI tool for detecting hardcoded strings in React/Next.js apps",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"typescript": "~5.9.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@
|
|
53
|
+
"@better-i18n/typescript-config": "workspace:*",
|
|
54
54
|
"@types/node": "^20.0.0"
|
|
55
55
|
},
|
|
56
56
|
"engines": {
|