@ccgp/i18n-ai 0.1.0 → 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/README.md +24 -1
- package/dist/{chunk-NY2C35K2.mjs → chunk-X4OG3I7N.mjs} +24 -3
- package/dist/cli.js +24 -3
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +24 -3
- package/dist/index.mjs +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -43,10 +43,33 @@ bun x i18n-ai sync
|
|
|
43
43
|
|
|
44
44
|
The CLI attempts to auto-detect your configuration from `i18n/routing.ts` if you are using `next-intl`. Otherwise, you can specify options:
|
|
45
45
|
|
|
46
|
-
```bash
|
|
47
46
|
i18n-ai sync --locales en,es,fr --default en --dir messages
|
|
48
47
|
```
|
|
49
48
|
|
|
49
|
+
### Configuration File (Recommended)
|
|
50
|
+
|
|
51
|
+
You can run `i18n-ai init` to generate a configuration file interactively:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bun x i18n-ai init
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This will create an `i18n-ai.config.json` file:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"defaultLocale": "en",
|
|
62
|
+
"locales": ["en", "es", "fr"],
|
|
63
|
+
"messagesDir": "messages"
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then you can simply run:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
bun x i18n-ai sync
|
|
71
|
+
```
|
|
72
|
+
|
|
50
73
|
### Environment Variables
|
|
51
74
|
|
|
52
75
|
You need to provide an API key for the AI provider.
|
|
@@ -236,9 +236,30 @@ var TranslationService = class {
|
|
|
236
236
|
}
|
|
237
237
|
let translatedCount = 0;
|
|
238
238
|
if (toTranslate.length > 0) {
|
|
239
|
-
|
|
239
|
+
const limit = (concurrency) => {
|
|
240
|
+
let active = 0;
|
|
241
|
+
const queue = [];
|
|
242
|
+
const run = async (fn) => {
|
|
243
|
+
if (active >= concurrency) {
|
|
244
|
+
await new Promise((resolve) => queue.push(resolve));
|
|
245
|
+
}
|
|
246
|
+
active++;
|
|
247
|
+
try {
|
|
248
|
+
return await fn();
|
|
249
|
+
} finally {
|
|
250
|
+
active--;
|
|
251
|
+
if (queue.length > 0) {
|
|
252
|
+
queue.shift()();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
return run;
|
|
257
|
+
};
|
|
258
|
+
const runTask = limit(5);
|
|
259
|
+
await Promise.all(toTranslate.map((change) => runTask(async () => {
|
|
240
260
|
try {
|
|
241
|
-
const
|
|
261
|
+
const _translate = this.config.translator || translate;
|
|
262
|
+
const translatedValue = await _translate({
|
|
242
263
|
text: change.sourceText,
|
|
243
264
|
lang: this.config.defaultLocale,
|
|
244
265
|
targetLang: targetLocale,
|
|
@@ -258,7 +279,7 @@ var TranslationService = class {
|
|
|
258
279
|
targetFlat.set(change.key, change.currentTranslation);
|
|
259
280
|
}
|
|
260
281
|
}
|
|
261
|
-
}
|
|
282
|
+
})));
|
|
262
283
|
}
|
|
263
284
|
for (const change of changes.unchanged) {
|
|
264
285
|
if (change.currentTranslation) {
|
package/dist/cli.js
CHANGED
|
@@ -268,9 +268,30 @@ var TranslationService = class {
|
|
|
268
268
|
}
|
|
269
269
|
let translatedCount = 0;
|
|
270
270
|
if (toTranslate.length > 0) {
|
|
271
|
-
|
|
271
|
+
const limit = (concurrency) => {
|
|
272
|
+
let active = 0;
|
|
273
|
+
const queue = [];
|
|
274
|
+
const run = async (fn) => {
|
|
275
|
+
if (active >= concurrency) {
|
|
276
|
+
await new Promise((resolve2) => queue.push(resolve2));
|
|
277
|
+
}
|
|
278
|
+
active++;
|
|
279
|
+
try {
|
|
280
|
+
return await fn();
|
|
281
|
+
} finally {
|
|
282
|
+
active--;
|
|
283
|
+
if (queue.length > 0) {
|
|
284
|
+
queue.shift()();
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
return run;
|
|
289
|
+
};
|
|
290
|
+
const runTask = limit(5);
|
|
291
|
+
await Promise.all(toTranslate.map((change) => runTask(async () => {
|
|
272
292
|
try {
|
|
273
|
-
const
|
|
293
|
+
const _translate = this.config.translator || translate;
|
|
294
|
+
const translatedValue = await _translate({
|
|
274
295
|
text: change.sourceText,
|
|
275
296
|
lang: this.config.defaultLocale,
|
|
276
297
|
targetLang: targetLocale,
|
|
@@ -290,7 +311,7 @@ var TranslationService = class {
|
|
|
290
311
|
targetFlat.set(change.key, change.currentTranslation);
|
|
291
312
|
}
|
|
292
313
|
}
|
|
293
|
-
}
|
|
314
|
+
})));
|
|
294
315
|
}
|
|
295
316
|
for (const change of changes.unchanged) {
|
|
296
317
|
if (change.currentTranslation) {
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -75,6 +75,13 @@ interface SyncConfig {
|
|
|
75
75
|
lockFilePath: string;
|
|
76
76
|
apiKey?: string;
|
|
77
77
|
model?: string;
|
|
78
|
+
translator?: (params: {
|
|
79
|
+
text: string;
|
|
80
|
+
lang: string;
|
|
81
|
+
targetLang: string;
|
|
82
|
+
apiKey?: string;
|
|
83
|
+
model?: string;
|
|
84
|
+
}) => Promise<string>;
|
|
78
85
|
}
|
|
79
86
|
/**
|
|
80
87
|
* Flattens a nested object to a map of flat paths
|
package/dist/index.d.ts
CHANGED
|
@@ -75,6 +75,13 @@ interface SyncConfig {
|
|
|
75
75
|
lockFilePath: string;
|
|
76
76
|
apiKey?: string;
|
|
77
77
|
model?: string;
|
|
78
|
+
translator?: (params: {
|
|
79
|
+
text: string;
|
|
80
|
+
lang: string;
|
|
81
|
+
targetLang: string;
|
|
82
|
+
apiKey?: string;
|
|
83
|
+
model?: string;
|
|
84
|
+
}) => Promise<string>;
|
|
78
85
|
}
|
|
79
86
|
/**
|
|
80
87
|
* Flattens a nested object to a map of flat paths
|
package/dist/index.js
CHANGED
|
@@ -282,9 +282,30 @@ var TranslationService = class {
|
|
|
282
282
|
}
|
|
283
283
|
let translatedCount = 0;
|
|
284
284
|
if (toTranslate.length > 0) {
|
|
285
|
-
|
|
285
|
+
const limit = (concurrency) => {
|
|
286
|
+
let active = 0;
|
|
287
|
+
const queue = [];
|
|
288
|
+
const run = async (fn) => {
|
|
289
|
+
if (active >= concurrency) {
|
|
290
|
+
await new Promise((resolve) => queue.push(resolve));
|
|
291
|
+
}
|
|
292
|
+
active++;
|
|
293
|
+
try {
|
|
294
|
+
return await fn();
|
|
295
|
+
} finally {
|
|
296
|
+
active--;
|
|
297
|
+
if (queue.length > 0) {
|
|
298
|
+
queue.shift()();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
return run;
|
|
303
|
+
};
|
|
304
|
+
const runTask = limit(5);
|
|
305
|
+
await Promise.all(toTranslate.map((change) => runTask(async () => {
|
|
286
306
|
try {
|
|
287
|
-
const
|
|
307
|
+
const _translate = this.config.translator || translate;
|
|
308
|
+
const translatedValue = await _translate({
|
|
288
309
|
text: change.sourceText,
|
|
289
310
|
lang: this.config.defaultLocale,
|
|
290
311
|
targetLang: targetLocale,
|
|
@@ -304,7 +325,7 @@ var TranslationService = class {
|
|
|
304
325
|
targetFlat.set(change.key, change.currentTranslation);
|
|
305
326
|
}
|
|
306
327
|
}
|
|
307
|
-
}
|
|
328
|
+
})));
|
|
308
329
|
}
|
|
309
330
|
for (const change of changes.unchanged) {
|
|
310
331
|
if (change.currentTranslation) {
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ccgp/i18n-ai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "AI-powered i18n translation and synchronization library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
"build": "tsup src/index.ts src/cli.ts --format esm,cjs --dts --clean",
|
|
20
20
|
"dev": "tsup --watch",
|
|
21
21
|
"start": "node dist/cli.js",
|
|
22
|
-
"lint": "tsc --noEmit"
|
|
23
|
-
"prepublishOnly": "bun run build"
|
|
22
|
+
"lint": "tsc --noEmit"
|
|
24
23
|
},
|
|
25
24
|
"repository": {
|
|
26
25
|
"type": "git",
|