@scopeact/autoi18n 1.0.6 → 1.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/README.md +198 -58
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,114 +3,254 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@scopeact/autoi18n)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
> CLI to automatically migrate React / TypeScript projects to i18n using AST and LLMs.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**auto-i18n** scans TS/TSX files, extracts hardcoded strings, replaces them with `t("key")`, generates translation files, and optionally injects the correct i18n imports — all with explicit, opinionated trade-offs.
|
|
9
|
+
|
|
10
|
+
This is a **migration tool**, not a runtime framework.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Why this exists
|
|
15
|
+
|
|
16
|
+
Internationalizing a React codebase usually means:
|
|
17
|
+
|
|
18
|
+
* Manually hunting hardcoded strings
|
|
19
|
+
* Guessing translation keys
|
|
20
|
+
* Rewriting components by hand
|
|
21
|
+
* Copy-pasting JSON across languages
|
|
22
|
+
|
|
23
|
+
It’s repetitive, boring, and easy to screw up.
|
|
24
|
+
|
|
25
|
+
**auto-i18n automates the mechanical work and delegates semantic decisions to an LLM.**
|
|
9
26
|
|
|
10
27
|
---
|
|
11
28
|
|
|
12
|
-
##
|
|
29
|
+
## What this tool does
|
|
13
30
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
31
|
+
* Parses **TypeScript and TSX using AST** (no regex hacks)
|
|
32
|
+
* Detects static hardcoded strings
|
|
33
|
+
* Rewrites code to use `t("key")`
|
|
34
|
+
* Generates translation files
|
|
35
|
+
* Uses an **LLM to generate semantic translation keys**
|
|
36
|
+
* Optionally injects i18n imports automatically
|
|
37
|
+
* Supports different i18n libraries
|
|
19
38
|
|
|
20
39
|
---
|
|
21
40
|
|
|
22
|
-
##
|
|
41
|
+
## Installation
|
|
23
42
|
|
|
24
|
-
|
|
25
|
-
Na raiz do seu projeto (onde está o `package.json`), execute:
|
|
43
|
+
No global install required:
|
|
26
44
|
|
|
27
45
|
```bash
|
|
28
|
-
npx @scopeact/
|
|
46
|
+
npx @scopeact/auto-i18n init
|
|
29
47
|
```
|
|
30
|
-
Isso criará um arquivo `autoi18n.config.json` com as configurações padrão.
|
|
31
48
|
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
34
52
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
# OU
|
|
40
|
-
DEEPSEEK_API_KEY=sua_chave_aqui
|
|
53
|
+
### 1. Initialize configuration
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx @scopeact/auto-i18n init
|
|
41
57
|
```
|
|
42
58
|
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
This creates:
|
|
60
|
+
|
|
61
|
+
* `auto-i18n.config.json`
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### 2. Run the migration
|
|
45
66
|
|
|
46
67
|
```bash
|
|
47
|
-
npx @scopeact/
|
|
68
|
+
npx @scopeact/auto-i18n run
|
|
48
69
|
```
|
|
49
70
|
|
|
71
|
+
The tool will:
|
|
72
|
+
|
|
73
|
+
1. Parse files into AST
|
|
74
|
+
2. Detect static string literals
|
|
75
|
+
3. Ask the LLM to infer **semantic translation keys**
|
|
76
|
+
4. Rewrite source code
|
|
77
|
+
5. Inject i18n imports if missing
|
|
78
|
+
6. Generate translation files
|
|
79
|
+
|
|
50
80
|
---
|
|
51
81
|
|
|
52
|
-
##
|
|
82
|
+
## Example
|
|
83
|
+
|
|
84
|
+
### Before
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
export function Home() {
|
|
88
|
+
return (
|
|
89
|
+
<div>
|
|
90
|
+
<h1>Hello world</h1>
|
|
91
|
+
<p>Welcome to our platform</p>
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### After
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { useTranslation } from "react-i18next";
|
|
101
|
+
|
|
102
|
+
export function Home() {
|
|
103
|
+
return (
|
|
104
|
+
<div>
|
|
105
|
+
<h1>{t("greeting")}</h1>
|
|
106
|
+
<p>{t("description")}</p>
|
|
107
|
+
</div>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Generated translation file:
|
|
53
113
|
|
|
54
114
|
```json
|
|
55
115
|
{
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"provider": "openai",
|
|
59
|
-
"model": "gpt-4o",
|
|
60
|
-
"localesDir": "./src/locales",
|
|
61
|
-
"files": ["src/**/*.tsx", "src/**/*.ts"]
|
|
116
|
+
"greeting": "Hello world",
|
|
117
|
+
"description": "Welcome to our platform"
|
|
62
118
|
}
|
|
63
119
|
```
|
|
64
120
|
|
|
65
|
-
- **`sourceLang`**: Idioma original do seu código.
|
|
66
|
-
- **`targetLangs`**: Lista de idiomas para os quais você deseja traduzir.
|
|
67
|
-
- **`localesDir`**: Onde os arquivos `.json` de tradução serão salvos.
|
|
68
|
-
- **`provider`**: `openai`, `google`, `deepseek`, `openrouter` ou `ollama`.
|
|
69
|
-
- **`files`**: Glob pattern dos arquivos que devem ser escaneados.
|
|
70
|
-
|
|
71
121
|
---
|
|
72
122
|
|
|
73
|
-
##
|
|
123
|
+
## Configuration
|
|
74
124
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
125
|
+
Example `auto-i18n.config.json`:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"sourceLang": "pt",
|
|
130
|
+
"targetLangs": [ "en", "es", "de" ],
|
|
131
|
+
"autoInject": true,
|
|
132
|
+
"i18nLibrary": "react-i18next",
|
|
133
|
+
"provider": "ollama",
|
|
134
|
+
"localesDir": "./locales",
|
|
135
|
+
"model": "gemma3-translator",
|
|
136
|
+
"files": [ "**/*.tsx" ]
|
|
137
|
+
}
|
|
80
138
|
```
|
|
81
139
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
140
|
+
### Options
|
|
141
|
+
|
|
142
|
+
#### `autoInject`
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"autoInject": true
|
|
147
|
+
}
|
|
87
148
|
```
|
|
88
149
|
|
|
89
|
-
**
|
|
150
|
+
Automatically injects the required i18n import at the top of the file **if it does not already exist**.
|
|
151
|
+
|
|
152
|
+
This avoids manual setup and keeps the migration fully automated.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
#### `i18nLibrary`
|
|
157
|
+
|
|
90
158
|
```json
|
|
91
159
|
{
|
|
92
|
-
"
|
|
160
|
+
"i18nLibrary": "react-i18next"
|
|
93
161
|
}
|
|
94
162
|
```
|
|
95
163
|
|
|
164
|
+
Defines which i18n library should be used when injecting imports and hooks.
|
|
165
|
+
|
|
166
|
+
Supported values:
|
|
167
|
+
|
|
168
|
+
* `react-i18next`
|
|
169
|
+
* `next-i18n`
|
|
170
|
+
|
|
171
|
+
This affects:
|
|
172
|
+
|
|
173
|
+
* import statements
|
|
174
|
+
* generated code structure
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Why keys are AI-generated (no dry-run)
|
|
179
|
+
|
|
180
|
+
Translation key naming is a **semantic problem**, not a mechanical one.
|
|
181
|
+
|
|
182
|
+
For example:
|
|
183
|
+
|
|
184
|
+
* Is `"Hello world"` a title, a CTA, or a heading?
|
|
185
|
+
* Does it belong to `home`, `layout`, or `marketing`?
|
|
186
|
+
|
|
187
|
+
These decisions cannot be inferred deterministically.
|
|
188
|
+
|
|
189
|
+
**auto-i18n intentionally requires an LLM to:**
|
|
190
|
+
|
|
191
|
+
* infer intent
|
|
192
|
+
* generate meaningful keys
|
|
193
|
+
* avoid arbitrary conventions
|
|
194
|
+
|
|
195
|
+
Because of this, a traditional dry-run would produce **misleading results** and is intentionally not supported.
|
|
196
|
+
|
|
197
|
+
This trade-off is explicit.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Why AST instead of regex
|
|
202
|
+
|
|
203
|
+
Regex does not understand JSX or TypeScript.
|
|
204
|
+
|
|
205
|
+
AST parsing:
|
|
206
|
+
|
|
207
|
+
* Preserves syntax structure
|
|
208
|
+
* Avoids accidental replacements
|
|
209
|
+
* Handles real-world React code
|
|
210
|
+
* Produces predictable transformations
|
|
211
|
+
|
|
212
|
+
This tool is designed for **production codebases**, not demos.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Limitations
|
|
217
|
+
|
|
218
|
+
This tool does **not** handle:
|
|
219
|
+
|
|
220
|
+
* Dynamic strings (`"Hello " + name`)
|
|
221
|
+
* Template literals with expressions
|
|
222
|
+
* Runtime-generated text
|
|
223
|
+
* Context-dependent translations
|
|
224
|
+
|
|
225
|
+
It is meant to **bootstrap i18n**, not replace human review.
|
|
226
|
+
|
|
96
227
|
---
|
|
97
228
|
|
|
98
|
-
##
|
|
229
|
+
## When you should NOT use this
|
|
99
230
|
|
|
100
|
-
|
|
101
|
-
|
|
231
|
+
* Your project already has a mature i18n setup
|
|
232
|
+
* Translations depend heavily on runtime logic
|
|
233
|
+
* You expect zero review after migration
|
|
102
234
|
|
|
103
235
|
---
|
|
104
236
|
|
|
105
|
-
##
|
|
237
|
+
## Design philosophy
|
|
238
|
+
|
|
239
|
+
* Explicit over clever
|
|
240
|
+
* Predictable over magical
|
|
241
|
+
* Narrow scope over feature bloat
|
|
106
242
|
|
|
107
|
-
|
|
243
|
+
This tool solves **one specific problem**, deliberately.
|
|
108
244
|
|
|
109
245
|
---
|
|
110
246
|
|
|
111
|
-
##
|
|
247
|
+
## License
|
|
112
248
|
|
|
113
|
-
|
|
249
|
+
Distributed under MIT license. See [LICENSE](LICENSE) for more details.
|
|
114
250
|
|
|
115
251
|
---
|
|
116
|
-
|
|
252
|
+
|
|
253
|
+
## 🇧🇷 Nota
|
|
254
|
+
|
|
255
|
+
README principal em inglês por usabilidade global.
|
|
256
|
+
Português aqui só pra lembrar que esse projeto nasceu no Brasil.
|
package/package.json
CHANGED