@ccgp/i18n-ai 0.0.4 → 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 +109 -22
- package/dist/cli.mjs +87 -21
- 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 +4 -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) {
|
|
@@ -311,36 +332,102 @@ var TranslationService = class {
|
|
|
311
332
|
|
|
312
333
|
// src/cli.ts
|
|
313
334
|
var import_dotenv = __toESM(require("dotenv"));
|
|
335
|
+
var import_prompts = __toESM(require("prompts"));
|
|
336
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
314
337
|
import_dotenv.default.config();
|
|
315
338
|
var program = new import_commander.Command();
|
|
316
339
|
program.name("i18n-ai").description("AI-powered translation CLI").version("0.0.1");
|
|
317
|
-
|
|
340
|
+
var CONFIG_FILE = "i18n-ai.config.json";
|
|
341
|
+
async function loadConfig() {
|
|
342
|
+
try {
|
|
343
|
+
const configPath = (0, import_path2.join)(process.cwd(), CONFIG_FILE);
|
|
344
|
+
const content = await (0, import_promises3.readFile)(configPath, "utf-8");
|
|
345
|
+
return JSON.parse(content);
|
|
346
|
+
} catch {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
program.command("init").description("Initialize i18n-ai configuration").action(async () => {
|
|
351
|
+
console.log(import_chalk2.default.bold("\u{1F680} Initializing i18n-ai configuration\n"));
|
|
352
|
+
const response = await (0, import_prompts.default)([
|
|
353
|
+
{
|
|
354
|
+
type: "text",
|
|
355
|
+
name: "messagesDir",
|
|
356
|
+
message: "Where are your messages located?",
|
|
357
|
+
initial: "messages",
|
|
358
|
+
validate: (value) => value.length > 0 ? true : "Directory cannot be empty"
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
type: "text",
|
|
362
|
+
name: "defaultLocale",
|
|
363
|
+
message: "What is your default locale?",
|
|
364
|
+
initial: "en"
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
type: "list",
|
|
368
|
+
name: "locales",
|
|
369
|
+
message: "Which other locales do you support? (comma separated)",
|
|
370
|
+
initial: "es, fr",
|
|
371
|
+
separator: ","
|
|
372
|
+
}
|
|
373
|
+
]);
|
|
374
|
+
if (!response.messagesDir || !response.defaultLocale) {
|
|
375
|
+
console.log(import_chalk2.default.red("\n\u274C Initialization canceled"));
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const allLocales = [response.defaultLocale, ...response.locales.filter((l) => l !== response.defaultLocale)];
|
|
379
|
+
const config = {
|
|
380
|
+
defaultLocale: response.defaultLocale,
|
|
381
|
+
locales: allLocales,
|
|
382
|
+
messagesDir: response.messagesDir
|
|
383
|
+
};
|
|
384
|
+
await (0, import_promises3.writeFile)((0, import_path2.join)(process.cwd(), CONFIG_FILE), JSON.stringify(config, null, 2));
|
|
385
|
+
console.log(import_chalk2.default.green(`
|
|
386
|
+
\u2705 Created ${CONFIG_FILE}`));
|
|
387
|
+
const absMessagesDir = (0, import_path2.resolve)(process.cwd(), response.messagesDir);
|
|
388
|
+
await (0, import_promises3.mkdir)(absMessagesDir, { recursive: true });
|
|
389
|
+
const baseFilePath = (0, import_path2.join)(absMessagesDir, `${response.defaultLocale}.json`);
|
|
390
|
+
try {
|
|
391
|
+
await (0, import_promises3.readFile)(baseFilePath);
|
|
392
|
+
} catch {
|
|
393
|
+
await (0, import_promises3.writeFile)(baseFilePath, JSON.stringify({ welcome: "Hello World" }, null, 2));
|
|
394
|
+
console.log(import_chalk2.default.green(`\u2705 Created base file ${response.messagesDir}/${response.defaultLocale}.json`));
|
|
395
|
+
}
|
|
396
|
+
console.log(import_chalk2.default.blue('\n\u{1F389} Setup complete! You can now run "i18n-ai sync"'));
|
|
397
|
+
});
|
|
398
|
+
program.command("sync").description("Synchronize translations using AI").option("-d, --dir <path>", "Messages directory").option("-l, --locales <items>", "Comma separated list of locales").option("--default <locale>", "Default locale").option("--lock <path>", "Lock file path", "translation-lock.json").action(async (options) => {
|
|
318
399
|
try {
|
|
319
400
|
const cwd = process.cwd();
|
|
320
|
-
const
|
|
321
|
-
let
|
|
322
|
-
let
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
401
|
+
const config = await loadConfig();
|
|
402
|
+
let messagesDir = options.dir ? (0, import_path2.resolve)(cwd, options.dir) : config ? (0, import_path2.resolve)(cwd, config.messagesDir) : null;
|
|
403
|
+
let locales = options.locales ? options.locales.split(",") : config ? config.locales : [];
|
|
404
|
+
let defaultLocale = options.default || (config ? config.defaultLocale : null);
|
|
405
|
+
if (!messagesDir || locales.length === 0 || !defaultLocale) {
|
|
406
|
+
if (!config) {
|
|
407
|
+
try {
|
|
408
|
+
const routingPath = (0, import_path2.join)(cwd, "i18n", "routing.ts");
|
|
409
|
+
const routingContent = await (0, import_promises3.readFile)(routingPath, "utf-8").catch(() => "");
|
|
410
|
+
if (routingContent) {
|
|
411
|
+
const localesMatch = routingContent.match(/locales:\s*\[([\s\S]*?)\]/);
|
|
412
|
+
const defaultMatch = routingContent.match(/defaultLocale:\s*["'](\w+)["']/);
|
|
413
|
+
if (localesMatch && locales.length === 0) {
|
|
414
|
+
locales = localesMatch[1].split(",").map((l) => l.trim().replace(/['"]/g, "")).filter(Boolean);
|
|
415
|
+
}
|
|
416
|
+
if (defaultMatch && !defaultLocale) {
|
|
417
|
+
defaultLocale = defaultMatch[1];
|
|
418
|
+
}
|
|
335
419
|
}
|
|
420
|
+
} catch {
|
|
336
421
|
}
|
|
337
|
-
} catch (e) {
|
|
338
422
|
}
|
|
423
|
+
if (!messagesDir) messagesDir = (0, import_path2.resolve)(cwd, "messages");
|
|
424
|
+
if (!defaultLocale) defaultLocale = "en";
|
|
339
425
|
}
|
|
340
426
|
if (locales.length === 0) {
|
|
341
|
-
console.error(
|
|
427
|
+
console.error(import_chalk2.default.red('\u274C No locales found. Run "i18n-ai init" or specify --locales.'));
|
|
342
428
|
process.exit(1);
|
|
343
429
|
}
|
|
430
|
+
console.log(import_chalk2.default.dim(`Using Config: Default=${defaultLocale}, Locales=${locales.join(",")}, Dir=${messagesDir}`));
|
|
344
431
|
const service = new TranslationService({
|
|
345
432
|
locales,
|
|
346
433
|
defaultLocale,
|
|
@@ -349,7 +436,7 @@ program.command("sync").description("Synchronize translations using AI").option(
|
|
|
349
436
|
});
|
|
350
437
|
await service.sync();
|
|
351
438
|
} catch (error) {
|
|
352
|
-
console.error("Fatal error:", error);
|
|
439
|
+
console.error(import_chalk2.default.red("Fatal error:"), error);
|
|
353
440
|
process.exit(1);
|
|
354
441
|
}
|
|
355
442
|
});
|
package/dist/cli.mjs
CHANGED
|
@@ -1,43 +1,109 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
TranslationService
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-X4OG3I7N.mjs";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import { resolve, join } from "path";
|
|
9
|
-
import { readFile } from "fs/promises";
|
|
9
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
10
10
|
import dotenv from "dotenv";
|
|
11
|
+
import prompts from "prompts";
|
|
12
|
+
import chalk from "chalk";
|
|
11
13
|
dotenv.config();
|
|
12
14
|
var program = new Command();
|
|
13
15
|
program.name("i18n-ai").description("AI-powered translation CLI").version("0.0.1");
|
|
14
|
-
|
|
16
|
+
var CONFIG_FILE = "i18n-ai.config.json";
|
|
17
|
+
async function loadConfig() {
|
|
18
|
+
try {
|
|
19
|
+
const configPath = join(process.cwd(), CONFIG_FILE);
|
|
20
|
+
const content = await readFile(configPath, "utf-8");
|
|
21
|
+
return JSON.parse(content);
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
program.command("init").description("Initialize i18n-ai configuration").action(async () => {
|
|
27
|
+
console.log(chalk.bold("\u{1F680} Initializing i18n-ai configuration\n"));
|
|
28
|
+
const response = await prompts([
|
|
29
|
+
{
|
|
30
|
+
type: "text",
|
|
31
|
+
name: "messagesDir",
|
|
32
|
+
message: "Where are your messages located?",
|
|
33
|
+
initial: "messages",
|
|
34
|
+
validate: (value) => value.length > 0 ? true : "Directory cannot be empty"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: "text",
|
|
38
|
+
name: "defaultLocale",
|
|
39
|
+
message: "What is your default locale?",
|
|
40
|
+
initial: "en"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: "list",
|
|
44
|
+
name: "locales",
|
|
45
|
+
message: "Which other locales do you support? (comma separated)",
|
|
46
|
+
initial: "es, fr",
|
|
47
|
+
separator: ","
|
|
48
|
+
}
|
|
49
|
+
]);
|
|
50
|
+
if (!response.messagesDir || !response.defaultLocale) {
|
|
51
|
+
console.log(chalk.red("\n\u274C Initialization canceled"));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const allLocales = [response.defaultLocale, ...response.locales.filter((l) => l !== response.defaultLocale)];
|
|
55
|
+
const config = {
|
|
56
|
+
defaultLocale: response.defaultLocale,
|
|
57
|
+
locales: allLocales,
|
|
58
|
+
messagesDir: response.messagesDir
|
|
59
|
+
};
|
|
60
|
+
await writeFile(join(process.cwd(), CONFIG_FILE), JSON.stringify(config, null, 2));
|
|
61
|
+
console.log(chalk.green(`
|
|
62
|
+
\u2705 Created ${CONFIG_FILE}`));
|
|
63
|
+
const absMessagesDir = resolve(process.cwd(), response.messagesDir);
|
|
64
|
+
await mkdir(absMessagesDir, { recursive: true });
|
|
65
|
+
const baseFilePath = join(absMessagesDir, `${response.defaultLocale}.json`);
|
|
66
|
+
try {
|
|
67
|
+
await readFile(baseFilePath);
|
|
68
|
+
} catch {
|
|
69
|
+
await writeFile(baseFilePath, JSON.stringify({ welcome: "Hello World" }, null, 2));
|
|
70
|
+
console.log(chalk.green(`\u2705 Created base file ${response.messagesDir}/${response.defaultLocale}.json`));
|
|
71
|
+
}
|
|
72
|
+
console.log(chalk.blue('\n\u{1F389} Setup complete! You can now run "i18n-ai sync"'));
|
|
73
|
+
});
|
|
74
|
+
program.command("sync").description("Synchronize translations using AI").option("-d, --dir <path>", "Messages directory").option("-l, --locales <items>", "Comma separated list of locales").option("--default <locale>", "Default locale").option("--lock <path>", "Lock file path", "translation-lock.json").action(async (options) => {
|
|
15
75
|
try {
|
|
16
76
|
const cwd = process.cwd();
|
|
17
|
-
const
|
|
18
|
-
let
|
|
19
|
-
let
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
77
|
+
const config = await loadConfig();
|
|
78
|
+
let messagesDir = options.dir ? resolve(cwd, options.dir) : config ? resolve(cwd, config.messagesDir) : null;
|
|
79
|
+
let locales = options.locales ? options.locales.split(",") : config ? config.locales : [];
|
|
80
|
+
let defaultLocale = options.default || (config ? config.defaultLocale : null);
|
|
81
|
+
if (!messagesDir || locales.length === 0 || !defaultLocale) {
|
|
82
|
+
if (!config) {
|
|
83
|
+
try {
|
|
84
|
+
const routingPath = join(cwd, "i18n", "routing.ts");
|
|
85
|
+
const routingContent = await readFile(routingPath, "utf-8").catch(() => "");
|
|
86
|
+
if (routingContent) {
|
|
87
|
+
const localesMatch = routingContent.match(/locales:\s*\[([\s\S]*?)\]/);
|
|
88
|
+
const defaultMatch = routingContent.match(/defaultLocale:\s*["'](\w+)["']/);
|
|
89
|
+
if (localesMatch && locales.length === 0) {
|
|
90
|
+
locales = localesMatch[1].split(",").map((l) => l.trim().replace(/['"]/g, "")).filter(Boolean);
|
|
91
|
+
}
|
|
92
|
+
if (defaultMatch && !defaultLocale) {
|
|
93
|
+
defaultLocale = defaultMatch[1];
|
|
94
|
+
}
|
|
32
95
|
}
|
|
96
|
+
} catch {
|
|
33
97
|
}
|
|
34
|
-
} catch (e) {
|
|
35
98
|
}
|
|
99
|
+
if (!messagesDir) messagesDir = resolve(cwd, "messages");
|
|
100
|
+
if (!defaultLocale) defaultLocale = "en";
|
|
36
101
|
}
|
|
37
102
|
if (locales.length === 0) {
|
|
38
|
-
console.error(
|
|
103
|
+
console.error(chalk.red('\u274C No locales found. Run "i18n-ai init" or specify --locales.'));
|
|
39
104
|
process.exit(1);
|
|
40
105
|
}
|
|
106
|
+
console.log(chalk.dim(`Using Config: Default=${defaultLocale}, Locales=${locales.join(",")}, Dir=${messagesDir}`));
|
|
41
107
|
const service = new TranslationService({
|
|
42
108
|
locales,
|
|
43
109
|
defaultLocale,
|
|
@@ -46,7 +112,7 @@ program.command("sync").description("Synchronize translations using AI").option(
|
|
|
46
112
|
});
|
|
47
113
|
await service.sync();
|
|
48
114
|
} catch (error) {
|
|
49
|
-
console.error("Fatal error:", error);
|
|
115
|
+
console.error(chalk.red("Fatal error:"), error);
|
|
50
116
|
process.exit(1);
|
|
51
117
|
}
|
|
52
118
|
});
|
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.
|
|
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",
|
|
@@ -40,10 +39,12 @@
|
|
|
40
39
|
"chalk": "^5.4.1",
|
|
41
40
|
"commander": "^12.0.0",
|
|
42
41
|
"dotenv": "^16.4.5",
|
|
42
|
+
"prompts": "^2.4.2",
|
|
43
43
|
"zod": "^4.3.5"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^20.11.24",
|
|
47
|
+
"@types/prompts": "^2.4.9",
|
|
47
48
|
"tsup": "^8.3.5",
|
|
48
49
|
"tsx": "^4.7.1",
|
|
49
50
|
"typescript": "^5.3.3"
|