@i18n-auto/core 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +496 -0
- package/dist/cli.cjs +597 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +591 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +172 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +108 -0
- package/dist/index.d.ts +108 -0
- package/dist/index.js +167 -0
- package/dist/index.js.map +1 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License Copyright (c) 2026 Muhammad Zubair Asim
|
|
2
|
+
|
|
3
|
+
Permission is hereby
|
|
4
|
+
granted, free of charge, to any person obtaining a copy of this software and
|
|
5
|
+
associated documentation files (the "Software"), to deal in the Software without
|
|
6
|
+
restriction, including without limitation the rights to use, copy, modify, merge,
|
|
7
|
+
publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to the
|
|
9
|
+
following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice
|
|
12
|
+
(including the next paragraph) shall be included in all copies or substantial
|
|
13
|
+
portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
16
|
+
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
|
18
|
+
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
19
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
# @i18n-auto/core
|
|
2
|
+
|
|
3
|
+
Automatic internationalization for Node.js and TypeScript backends. Write your code in English, run one CLI command, and get production-ready locale files for any language.
|
|
4
|
+
|
|
5
|
+
**How it works:**
|
|
6
|
+
|
|
7
|
+
1. You write `i18nTranslate("Hello world", { key: "greeting", locale: "ur" })` in your code
|
|
8
|
+
2. The CLI scans your source files using AST parsing, extracts all translation calls
|
|
9
|
+
3. The CLI batch-translates extracted strings via Google Translate
|
|
10
|
+
4. Locale JSON files are written to disk
|
|
11
|
+
5. At runtime, `i18nTranslate()` is a synchronous lookup from pre-loaded JSON — no API calls, no async
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
- [Installation](#installation)
|
|
16
|
+
- [Quick Start](#quick-start)
|
|
17
|
+
- [Configuration](#configuration)
|
|
18
|
+
- [Runtime API](#runtime-api)
|
|
19
|
+
- [CLI Usage](#cli-usage)
|
|
20
|
+
- [How It Works](#how-it-works)
|
|
21
|
+
- [Translation Providers](#translation-providers)
|
|
22
|
+
- [Project Structure](#project-structure)
|
|
23
|
+
- [Contributing](#contributing)
|
|
24
|
+
- [License](#license)
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @i18n-auto/core
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Prerequisites
|
|
33
|
+
|
|
34
|
+
- Node.js >= 18
|
|
35
|
+
- A Google Cloud API key with the Translation API enabled
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### 1. Create a configuration file
|
|
40
|
+
|
|
41
|
+
Create a file (e.g., `src/i18n.ts`) that initializes the library:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { initI18n } from '@i18n-auto/core';
|
|
45
|
+
|
|
46
|
+
initI18n({
|
|
47
|
+
provider: 'google',
|
|
48
|
+
apiKey: process.env.GOOGLE_TRANSLATE_API_KEY,
|
|
49
|
+
defaultLocale: 'en',
|
|
50
|
+
cachePath: './locales',
|
|
51
|
+
locales: ['ur', 'fr', 'de'],
|
|
52
|
+
sourcePath: './src',
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 2. Use translations in your code
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { i18nTranslate } from '@i18n-auto/core';
|
|
60
|
+
|
|
61
|
+
// Synchronous — reads from pre-loaded JSON, no API calls at runtime
|
|
62
|
+
const welcome = i18nTranslate("Welcome to our platform!", {
|
|
63
|
+
key: "welcome_msg",
|
|
64
|
+
locale: "ur",
|
|
65
|
+
});
|
|
66
|
+
// → "ہمارے پلیٹ فارم میں خوش آمدید!"
|
|
67
|
+
|
|
68
|
+
const error = i18nTranslate("Invalid email address", {
|
|
69
|
+
key: "err.invalid_email",
|
|
70
|
+
locale: "fr",
|
|
71
|
+
});
|
|
72
|
+
// → "Adresse e-mail invalide"
|
|
73
|
+
|
|
74
|
+
// Dynamic placeholders with params
|
|
75
|
+
const greeting = i18nTranslate("Hello {{name}}, you have {{count}} messages", {
|
|
76
|
+
key: "user.greeting",
|
|
77
|
+
locale: "ur",
|
|
78
|
+
params: { name: "Zubair", count: 5 },
|
|
79
|
+
});
|
|
80
|
+
// → "ہیلو Zubair، آپ کے پاس 5 پیغامات ہیں"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 3. Run the CLI to generate translations
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
GOOGLE_TRANSLATE_API_KEY=your-key npx i18n-auto translate --config ./src/i18n.ts
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This scans your source files, extracts all `i18nTranslate()` calls, translates new strings, and writes locale JSON files:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
locales/
|
|
93
|
+
├── ur.json
|
|
94
|
+
├── fr.json
|
|
95
|
+
└── de.json
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 4. Deploy
|
|
99
|
+
|
|
100
|
+
The generated JSON files are read synchronously at startup. No API calls happen at runtime. Your application stays fast.
|
|
101
|
+
|
|
102
|
+
## Configuration
|
|
103
|
+
|
|
104
|
+
All configuration is defined in the `initI18n()` call. The CLI reads this same config file, so there is a single source of truth.
|
|
105
|
+
|
|
106
|
+
| Option | Type | Default | Description |
|
|
107
|
+
|--------|------|---------|-------------|
|
|
108
|
+
| `provider` | `string` | `'google'` | Translation provider to use |
|
|
109
|
+
| `apiKey` | `string` | — | API key for the translation provider. Use `process.env.YOUR_KEY` |
|
|
110
|
+
| `defaultLocale` | `string` | `'en'` | Source language of your text strings |
|
|
111
|
+
| `cachePath` | `string` | `'./locales'` | Directory where locale JSON files are stored |
|
|
112
|
+
| `locales` | `string[]` | `[]` | Target locales to translate into (e.g., `['ur', 'fr', 'de']`) |
|
|
113
|
+
| `sourcePath` | `string` | `'./src'` | Directory to scan for `i18nTranslate()` calls |
|
|
114
|
+
|
|
115
|
+
### Environment Variables
|
|
116
|
+
|
|
117
|
+
The `apiKey` field must reference an environment variable using `process.env.VARIABLE_NAME`. The CLI reads the variable name from the AST and resolves it at runtime. This keeps secrets out of your source code.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// The CLI detects that the env var name is GOOGLE_TRANSLATE_API_KEY
|
|
121
|
+
// and reads process.env.GOOGLE_TRANSLATE_API_KEY when running
|
|
122
|
+
initI18n({
|
|
123
|
+
apiKey: process.env.GOOGLE_TRANSLATE_API_KEY,
|
|
124
|
+
// ...
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Runtime API
|
|
129
|
+
|
|
130
|
+
### `initI18n(options: I18nAutoOptions): void`
|
|
131
|
+
|
|
132
|
+
Initializes the i18n runtime. Synchronously loads all locale JSON files from `cachePath` into memory. Call this once at application startup, before any `i18nTranslate()` calls.
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { initI18n } from '@i18n-auto/core';
|
|
136
|
+
|
|
137
|
+
initI18n({
|
|
138
|
+
defaultLocale: 'en',
|
|
139
|
+
cachePath: './locales',
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### `i18nTranslate(text: string, options: TranslateOptions): string`
|
|
144
|
+
|
|
145
|
+
Returns the translated string for the given key and locale. This is a **synchronous** function — it performs a simple object lookup against the pre-loaded JSON data.
|
|
146
|
+
|
|
147
|
+
If the translation is not found, returns the original `text` as a fallback. Never throws.
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { i18nTranslate } from '@i18n-auto/core';
|
|
151
|
+
|
|
152
|
+
const msg = i18nTranslate("Hello", { key: "greeting", locale: "ur" });
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Parameters:**
|
|
156
|
+
|
|
157
|
+
| Parameter | Type | Description |
|
|
158
|
+
|-----------|------|-------------|
|
|
159
|
+
| `text` | `string` | The source text. Returned as fallback if no translation exists |
|
|
160
|
+
| `options.key` | `string` | The translation key (must match across all locales) |
|
|
161
|
+
| `options.locale` | `string` | The target locale (e.g., `'ur'`, `'fr'`) |
|
|
162
|
+
| `options.params` | `Record<string, string \| number>` | Optional. Dynamic values to interpolate into `{{placeholder}}` patterns |
|
|
163
|
+
| `options.lock` | `boolean` | Optional. If `true`, the CLI will not auto-translate this key. You provide the translation manually |
|
|
164
|
+
|
|
165
|
+
**Interpolation example:**
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
i18nTranslate("Hello {{name}}, you have {{count}} new messages", {
|
|
169
|
+
key: "inbox.greeting",
|
|
170
|
+
locale: "ur",
|
|
171
|
+
params: { name: "Zubair", count: 5 },
|
|
172
|
+
});
|
|
173
|
+
// → "ہیلو Zubair، آپ کے پاس 5 نئے پیغامات ہیں"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
If a `{{placeholder}}` has no matching key in `params`, it is left unchanged in the output.
|
|
177
|
+
|
|
178
|
+
### `reloadTranslations(): void`
|
|
179
|
+
|
|
180
|
+
Reloads all locale JSON files from disk. Call this after running the CLI if your application is long-running and you want to pick up new translations without restarting.
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { reloadTranslations } from '@i18n-auto/core';
|
|
184
|
+
|
|
185
|
+
reloadTranslations();
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### `getTranslationStats(): Record<string, number>`
|
|
189
|
+
|
|
190
|
+
Returns the number of loaded translations per locale. Useful for health checks and debugging.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { getTranslationStats } from '@i18n-auto/core';
|
|
194
|
+
|
|
195
|
+
console.log(getTranslationStats());
|
|
196
|
+
// { ur: 42, fr: 42, de: 40 }
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## CLI Usage
|
|
200
|
+
|
|
201
|
+
The CLI reads your `initI18n()` config file, scans source files, and generates translations.
|
|
202
|
+
|
|
203
|
+
### `translate`
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
npx i18n-auto translate --config <path>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
| Flag | Required | Default | Description |
|
|
210
|
+
|------|----------|---------|-------------|
|
|
211
|
+
| `--config <path>` | Yes | — | Path to the file containing the `initI18n()` call |
|
|
212
|
+
| `--force` | No | `false` | Re-translate all strings, ignoring cache and change detection |
|
|
213
|
+
|
|
214
|
+
**What it does:**
|
|
215
|
+
|
|
216
|
+
1. Parses the `--config` file to read `provider`, `locales`, `cachePath`, and `sourcePath`
|
|
217
|
+
2. Globs all `.ts`, `.tsx`, `.js`, `.jsx` files in the source directory
|
|
218
|
+
3. AST-parses each file and extracts all `i18nTranslate()` calls
|
|
219
|
+
4. For each target locale:
|
|
220
|
+
- Identifies **new** keys (not yet in locale JSON)
|
|
221
|
+
- Identifies **changed** keys (source text modified since last run, detected via hash comparison)
|
|
222
|
+
- Batch-translates only new and changed strings via the configured provider
|
|
223
|
+
5. Writes updated locale JSON files and updates `.meta.json` with source text hashes
|
|
224
|
+
|
|
225
|
+
**Example output:**
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
[i18n-auto] Scanning 24 files...
|
|
229
|
+
[i18n-auto] Found 15 translation entries
|
|
230
|
+
[i18n-auto] ur: Translating 3 new strings...
|
|
231
|
+
[i18n-auto] ur: Re-translating 1 changed strings...
|
|
232
|
+
[i18n-auto] ur: Translated 4 strings
|
|
233
|
+
[i18n-auto] fr: Translating 3 new strings...
|
|
234
|
+
[i18n-auto] fr: Re-translating 1 changed strings...
|
|
235
|
+
[i18n-auto] fr: Translated 4 strings
|
|
236
|
+
[i18n-auto] Done! Translated 8 strings for 3 locale(s)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Force mode** re-translates everything, useful when you want to refresh all translations (e.g., after switching providers):
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
npx i18n-auto translate --config ./src/i18n.ts --force
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### `stats`
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
npx i18n-auto stats --config <path>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Shows translation progress per locale:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
[i18n-auto] Total translation keys found: 15
|
|
255
|
+
|
|
256
|
+
ur: 15/15 translated ✓
|
|
257
|
+
fr: 15/15 translated ✓
|
|
258
|
+
de: 12/15 translated (3 missing)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## How It Works
|
|
262
|
+
|
|
263
|
+
### Architecture
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
@i18n-auto/core
|
|
267
|
+
│
|
|
268
|
+
├── Runtime (imported in your app)
|
|
269
|
+
│ ├── initI18n() — loads locale JSON into memory at startup
|
|
270
|
+
│ ├── i18nTranslate() — synchronous key lookup, returns string
|
|
271
|
+
│ ├── reloadTranslations() — re-reads JSON from disk
|
|
272
|
+
│ └── getTranslationStats() — returns per-locale counts
|
|
273
|
+
│
|
|
274
|
+
├── CLI (runs before deploy)
|
|
275
|
+
│ ├── AST Scanner — parses source files, extracts i18nTranslate() calls
|
|
276
|
+
│ ├── Provider — batch translates via Google Translate API
|
|
277
|
+
│ └── File Cache — reads/writes locale JSON files
|
|
278
|
+
│
|
|
279
|
+
└── Locale Files (generated output)
|
|
280
|
+
├── ur.json
|
|
281
|
+
├── fr.json
|
|
282
|
+
└── de.json
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Locale File Format
|
|
286
|
+
|
|
287
|
+
Each locale gets a flat JSON file at `{cachePath}/{locale}.json`:
|
|
288
|
+
|
|
289
|
+
```json
|
|
290
|
+
{
|
|
291
|
+
"welcome_msg": "ہمارے پلیٹ فارم میں خوش آمدید!",
|
|
292
|
+
"err.invalid_email": "غلط ای میل پتہ",
|
|
293
|
+
"auth.login_success": "آپ کامیابی سے لاگ ان ہو گئے ہیں"
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Simple key-value pairs. No nesting, no metadata. Human-readable and easy to review in pull requests.
|
|
298
|
+
|
|
299
|
+
### AST Extraction
|
|
300
|
+
|
|
301
|
+
The CLI uses `@babel/parser` and `@babel/traverse` to find translation calls. It only processes files that:
|
|
302
|
+
|
|
303
|
+
1. Import `i18nTranslate` from `@i18n-auto/core`
|
|
304
|
+
2. Call `i18nTranslate()` with a string literal as the first argument and an object with a `key` property as the second
|
|
305
|
+
|
|
306
|
+
Calls with dynamic values (variables instead of string literals) are skipped with a warning.
|
|
307
|
+
|
|
308
|
+
### Manual Translations (Lock)
|
|
309
|
+
|
|
310
|
+
Sometimes machine translation isn't good enough — you want to provide your own translation for specific keys. Use the `lock` option:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
i18nTranslate("Hello friend", {
|
|
314
|
+
key: "greeting",
|
|
315
|
+
locale: "ur",
|
|
316
|
+
lock: true,
|
|
317
|
+
});
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**What happens when the CLI runs:**
|
|
321
|
+
|
|
322
|
+
1. The CLI detects `lock: true` on this key
|
|
323
|
+
2. It adds the key to the locale JSON with an empty string `""`
|
|
324
|
+
3. It marks the key as `"locked"` in `.meta.json`
|
|
325
|
+
4. It **never** auto-translates or overwrites this key — even with `--force`
|
|
326
|
+
|
|
327
|
+
```json
|
|
328
|
+
// locales/ur.json (after CLI runs)
|
|
329
|
+
{
|
|
330
|
+
"welcome_msg": "ہمارے پلیٹ فارم میں خوش آمدید!",
|
|
331
|
+
"greeting": ""
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
You then manually edit `locales/ur.json` and fill in your translation:
|
|
336
|
+
|
|
337
|
+
```json
|
|
338
|
+
{
|
|
339
|
+
"welcome_msg": "ہمارے پلیٹ فارم میں خوش آمدید!",
|
|
340
|
+
"greeting": "خوش آمدید دوست!"
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Future CLI runs will never touch this key. Your manual translation is safe.
|
|
345
|
+
|
|
346
|
+
Until you fill in the translation, the runtime returns the original English text as a fallback (empty strings are treated as missing).
|
|
347
|
+
|
|
348
|
+
### Dynamic Placeholders
|
|
349
|
+
|
|
350
|
+
Use `{{placeholder}}` syntax for dynamic values like usernames, counts, or dates:
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
i18nTranslate("Hello {{name}}, your order #{{orderId}} is ready", {
|
|
354
|
+
key: "order.ready",
|
|
355
|
+
locale: "fr",
|
|
356
|
+
params: { name: "Zubair", orderId: 1234 },
|
|
357
|
+
});
|
|
358
|
+
// → "Bonjour Zubair, votre commande #1234 est prête"
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**How placeholders are protected during translation:**
|
|
362
|
+
|
|
363
|
+
The CLI automatically detects `{{placeholder}}` patterns and replaces them with XML tokens (`<x0>`, `<x1>`, etc.) before sending text to the translation API. Google Translate preserves XML/HTML tags, so the placeholders survive translation intact. After receiving the translated text, the tokens are restored back to `{{placeholder}}` format.
|
|
364
|
+
|
|
365
|
+
```
|
|
366
|
+
Source: "Hello {{name}}, welcome to {{platform}}"
|
|
367
|
+
Sent to API: "Hello <x0>, welcome to <x1>"
|
|
368
|
+
API returns: "مرحبا <x0>، <x1> میں خوش آمدید"
|
|
369
|
+
Restored: "مرحبا {{name}}، {{platform}} میں خوش آمدید"
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
At runtime, `i18nTranslate()` replaces `{{placeholder}}` with actual values from the `params` option.
|
|
373
|
+
|
|
374
|
+
### Incremental Translation and Change Detection
|
|
375
|
+
|
|
376
|
+
The CLI uses two mechanisms to minimize unnecessary API calls:
|
|
377
|
+
|
|
378
|
+
**New key detection:** If a key doesn't exist in the locale JSON, it's treated as new and translated.
|
|
379
|
+
|
|
380
|
+
**Change detection:** The CLI maintains a `.meta.json` file in the cache directory that stores a SHA-256 hash of each source text. When you modify the source text for an existing key (e.g., fixing a typo), the CLI detects the hash mismatch and re-translates that key across all locales.
|
|
381
|
+
|
|
382
|
+
```
|
|
383
|
+
locales/
|
|
384
|
+
├── ur.json # Translated strings
|
|
385
|
+
├── fr.json
|
|
386
|
+
├── de.json
|
|
387
|
+
└── .meta.json # Source text hashes (auto-generated)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
The `.meta.json` file is auto-generated and managed by the CLI. You can choose to commit it to version control (recommended for teams) or add it to `.gitignore`.
|
|
391
|
+
|
|
392
|
+
**Force mode:** Use `--force` to bypass all caching and re-translate every string. This is useful when switching translation providers or when you want a fresh set of translations.
|
|
393
|
+
|
|
394
|
+
## Translation Providers
|
|
395
|
+
|
|
396
|
+
### Google Translate (default)
|
|
397
|
+
|
|
398
|
+
Uses the [Google Cloud Translation API v2](https://cloud.google.com/translate/docs/reference/rest/v2/translations/translate).
|
|
399
|
+
|
|
400
|
+
**Setup:**
|
|
401
|
+
|
|
402
|
+
1. Create a project in [Google Cloud Console](https://console.cloud.google.com/)
|
|
403
|
+
2. Enable the Cloud Translation API
|
|
404
|
+
3. Create an API key under APIs & Services > Credentials
|
|
405
|
+
4. Set the environment variable:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
export GOOGLE_TRANSLATE_API_KEY=your-api-key-here
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**Batch limits:** The provider automatically chunks requests to stay within the 128-string-per-request API limit.
|
|
412
|
+
|
|
413
|
+
### Adding a Custom Provider
|
|
414
|
+
|
|
415
|
+
Implement the `TranslationProvider` interface:
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
interface TranslationProvider {
|
|
419
|
+
translateBatch(texts: string[], from: string, to: string): Promise<string[]>;
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Project Structure
|
|
424
|
+
|
|
425
|
+
```
|
|
426
|
+
src/
|
|
427
|
+
├── index.ts # Library entry — exports runtime functions and types
|
|
428
|
+
├── cli.ts # CLI entry — commander setup, orchestration
|
|
429
|
+
├── i18n-auto.ts # Runtime: initI18n, i18nTranslate, reload, stats
|
|
430
|
+
├── interfaces/
|
|
431
|
+
│ ├── index.ts
|
|
432
|
+
│ ├── i18n-auto-options.interface.ts
|
|
433
|
+
│ ├── translate-options.interface.ts
|
|
434
|
+
│ └── translation-provider.interface.ts
|
|
435
|
+
├── scanner/
|
|
436
|
+
│ ├── index.ts
|
|
437
|
+
│ └── extractor.ts # AST parsing + extraction
|
|
438
|
+
├── providers/
|
|
439
|
+
│ ├── index.ts
|
|
440
|
+
│ ├── google.provider.ts
|
|
441
|
+
│ └── provider.factory.ts
|
|
442
|
+
└── cache/
|
|
443
|
+
├── index.ts
|
|
444
|
+
└── file-cache.ts # Read/write locale JSON
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## Typical Workflow
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
# Development: write code with i18nTranslate() calls
|
|
451
|
+
# ↓
|
|
452
|
+
# Before deploy: generate translations
|
|
453
|
+
GOOGLE_TRANSLATE_API_KEY=your-key npx i18n-auto translate --config ./src/i18n.ts
|
|
454
|
+
|
|
455
|
+
# Check progress
|
|
456
|
+
npx i18n-auto stats --config ./src/i18n.ts
|
|
457
|
+
|
|
458
|
+
# Commit generated locale files
|
|
459
|
+
git add locales/
|
|
460
|
+
git commit -m "chore: update translations"
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
## Contributing
|
|
464
|
+
|
|
465
|
+
This project uses [conventional commits](https://www.conventionalcommits.org/). All commit messages are validated by commitlint via a git hook.
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
# Valid commit messages
|
|
469
|
+
git commit -m "feat: add DeepL provider support"
|
|
470
|
+
git commit -m "fix: handle empty translation response"
|
|
471
|
+
git commit -m "docs: update API reference"
|
|
472
|
+
|
|
473
|
+
# Run tests
|
|
474
|
+
npm test
|
|
475
|
+
|
|
476
|
+
# Type check
|
|
477
|
+
npm run typecheck
|
|
478
|
+
|
|
479
|
+
# Build
|
|
480
|
+
npm run build
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Commit Types
|
|
484
|
+
|
|
485
|
+
| Type | When to use |
|
|
486
|
+
|------|-------------|
|
|
487
|
+
| `feat` | New feature |
|
|
488
|
+
| `fix` | Bug fix |
|
|
489
|
+
| `docs` | Documentation only |
|
|
490
|
+
| `chore` | Maintenance, dependencies |
|
|
491
|
+
| `refactor` | Code change that neither fixes a bug nor adds a feature |
|
|
492
|
+
| `test` | Adding or updating tests |
|
|
493
|
+
|
|
494
|
+
## License
|
|
495
|
+
|
|
496
|
+
[MIT](LICENSE)
|