@ccgp/i18n-ai 0.2.1 → 0.2.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/dist/{chunk-5QO2MVWV.mjs → chunk-IOH4K3A3.mjs} +70 -47
- package/dist/cli.js +71 -47
- package/dist/cli.mjs +2 -2
- package/dist/index.d.mts +1 -9
- package/dist/index.d.ts +1 -9
- package/dist/index.js +70 -48
- package/dist/index.mjs +1 -3
- package/package.json +1 -1
|
@@ -83,55 +83,79 @@ function updateLock(lock, locale, base, final) {
|
|
|
83
83
|
// src/core/translator.ts
|
|
84
84
|
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
85
85
|
import { generateText, Output } from "ai";
|
|
86
|
-
import
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
- Input: "Hello {name}, welcome back!" -> Output (ES): "Hola {name}, \xA1bienvenido de nuevo!"
|
|
106
|
-
- Input: "Contact us calling to {number}" -> Output (FR): "Contactez-nous en appelant le {number}"
|
|
107
|
-
`;
|
|
108
|
-
const { output } = await generateText({
|
|
109
|
-
model: openrouter.languageModel(model || "google/gemini-2.5-flash"),
|
|
110
|
-
system,
|
|
111
|
-
prompt: `Text to translate: "${text}"`,
|
|
112
|
-
output: Output.object({
|
|
113
|
-
schema: z.object({
|
|
114
|
-
translatedText: z.string()
|
|
115
|
-
})
|
|
86
|
+
import * as z2 from "zod";
|
|
87
|
+
|
|
88
|
+
// src/env.ts
|
|
89
|
+
import { createEnv } from "@t3-oss/env-core";
|
|
90
|
+
import * as z from "zod";
|
|
91
|
+
var env = createEnv({
|
|
92
|
+
server: {
|
|
93
|
+
OPENROUTER_API_KEY: z.string()
|
|
94
|
+
},
|
|
95
|
+
runtimeEnv: process.env
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// src/core/translator.ts
|
|
99
|
+
var DEFAULT_MODEL = "google/gemini-2.5-flash";
|
|
100
|
+
var translationSchema = z2.object({
|
|
101
|
+
translations: z2.array(
|
|
102
|
+
z2.object({
|
|
103
|
+
key: z2.string(),
|
|
104
|
+
value: z2.string()
|
|
116
105
|
})
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
106
|
+
)
|
|
107
|
+
});
|
|
108
|
+
var openrouter = null;
|
|
109
|
+
var getOpenRouter = () => openrouter ?? (openrouter = createOpenRouter({ apiKey: env.OPENROUTER_API_KEY }));
|
|
110
|
+
var SYSTEM_PROMPT = `You are a professional translator.
|
|
111
|
+
|
|
112
|
+
RULES:
|
|
113
|
+
1. Translate the provided key-value pairs from the source language to the target language
|
|
114
|
+
2. Return an array of translations with the EXACT same keys and their translated values
|
|
115
|
+
3. Do NOT translate variables in curly braces: {name}, {count}, etc. Keep them exactly as-is
|
|
116
|
+
4. Maintain original tone and context
|
|
117
|
+
5. For single words or short phrases, translate directly`;
|
|
118
|
+
async function withRetry(fn, maxAttempts = 3) {
|
|
119
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
120
|
+
try {
|
|
121
|
+
return await fn();
|
|
122
|
+
} catch (error) {
|
|
123
|
+
const msg = error.message?.toLowerCase() ?? "";
|
|
124
|
+
const retryable = msg.includes("network") || msg.includes("timeout") || msg.includes("econnreset") || msg.includes("429") || msg.includes("503") || msg.includes("502");
|
|
125
|
+
if (attempt === maxAttempts || !retryable) throw error;
|
|
126
|
+
await new Promise((r) => setTimeout(r, 2 ** (attempt - 1) * 1e3));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
throw new Error("Unreachable");
|
|
130
|
+
}
|
|
120
131
|
async function translateBatch(batch) {
|
|
121
132
|
if (batch.entries.length === 0) return /* @__PURE__ */ new Map();
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
const inputArray = batch.entries.map((e) => ({ key: e.key, text: e.text }));
|
|
134
|
+
return withRetry(async () => {
|
|
135
|
+
const { output } = await generateText({
|
|
136
|
+
model: getOpenRouter().languageModel(DEFAULT_MODEL),
|
|
137
|
+
output: Output.object({
|
|
138
|
+
schema: translationSchema
|
|
139
|
+
}),
|
|
140
|
+
system: SYSTEM_PROMPT,
|
|
141
|
+
prompt: `Translate from "${batch.sourceLang}" to "${batch.targetLang}":
|
|
142
|
+
|
|
143
|
+
${JSON.stringify(inputArray, null, 2)}
|
|
144
|
+
|
|
145
|
+
Return the translations array with the same keys and translated values.`
|
|
146
|
+
});
|
|
147
|
+
if (!output.translations || output.translations.length === 0) {
|
|
148
|
+
throw new Error("Translation returned empty result");
|
|
149
|
+
}
|
|
150
|
+
const resultMap = new Map(output.translations.map((t) => [t.key, t.value]));
|
|
151
|
+
const missingKeys = batch.entries.filter((e) => !resultMap.has(e.key));
|
|
152
|
+
if (missingKeys.length > 0) {
|
|
153
|
+
throw new Error(
|
|
154
|
+
`Missing translations for keys: ${missingKeys.map((e) => e.key).join(", ")}`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
return resultMap;
|
|
158
|
+
});
|
|
135
159
|
}
|
|
136
160
|
|
|
137
161
|
// src/core/sync.ts
|
|
@@ -257,7 +281,6 @@ export {
|
|
|
257
281
|
withLockFile,
|
|
258
282
|
analyzeLocale,
|
|
259
283
|
updateLock,
|
|
260
|
-
translate,
|
|
261
284
|
translateBatch,
|
|
262
285
|
TranslationService
|
|
263
286
|
};
|
package/dist/cli.js
CHANGED
|
@@ -119,55 +119,79 @@ function updateLock(lock, locale, base, final) {
|
|
|
119
119
|
// src/core/translator.ts
|
|
120
120
|
var import_ai_sdk_provider = require("@openrouter/ai-sdk-provider");
|
|
121
121
|
var import_ai = require("ai");
|
|
122
|
-
var
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
- Input: "Hello {name}, welcome back!" -> Output (ES): "Hola {name}, \xA1bienvenido de nuevo!"
|
|
142
|
-
- Input: "Contact us calling to {number}" -> Output (FR): "Contactez-nous en appelant le {number}"
|
|
143
|
-
`;
|
|
144
|
-
const { output } = await (0, import_ai.generateText)({
|
|
145
|
-
model: openrouter.languageModel(model || "google/gemini-2.5-flash"),
|
|
146
|
-
system,
|
|
147
|
-
prompt: `Text to translate: "${text}"`,
|
|
148
|
-
output: import_ai.Output.object({
|
|
149
|
-
schema: import_zod.default.object({
|
|
150
|
-
translatedText: import_zod.default.string()
|
|
151
|
-
})
|
|
122
|
+
var z2 = __toESM(require("zod"));
|
|
123
|
+
|
|
124
|
+
// src/env.ts
|
|
125
|
+
var import_env_core = require("@t3-oss/env-core");
|
|
126
|
+
var z = __toESM(require("zod"));
|
|
127
|
+
var env = (0, import_env_core.createEnv)({
|
|
128
|
+
server: {
|
|
129
|
+
OPENROUTER_API_KEY: z.string()
|
|
130
|
+
},
|
|
131
|
+
runtimeEnv: process.env
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// src/core/translator.ts
|
|
135
|
+
var DEFAULT_MODEL = "google/gemini-2.5-flash";
|
|
136
|
+
var translationSchema = z2.object({
|
|
137
|
+
translations: z2.array(
|
|
138
|
+
z2.object({
|
|
139
|
+
key: z2.string(),
|
|
140
|
+
value: z2.string()
|
|
152
141
|
})
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
142
|
+
)
|
|
143
|
+
});
|
|
144
|
+
var openrouter = null;
|
|
145
|
+
var getOpenRouter = () => openrouter ?? (openrouter = (0, import_ai_sdk_provider.createOpenRouter)({ apiKey: env.OPENROUTER_API_KEY }));
|
|
146
|
+
var SYSTEM_PROMPT = `You are a professional translator.
|
|
147
|
+
|
|
148
|
+
RULES:
|
|
149
|
+
1. Translate the provided key-value pairs from the source language to the target language
|
|
150
|
+
2. Return an array of translations with the EXACT same keys and their translated values
|
|
151
|
+
3. Do NOT translate variables in curly braces: {name}, {count}, etc. Keep them exactly as-is
|
|
152
|
+
4. Maintain original tone and context
|
|
153
|
+
5. For single words or short phrases, translate directly`;
|
|
154
|
+
async function withRetry(fn, maxAttempts = 3) {
|
|
155
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
156
|
+
try {
|
|
157
|
+
return await fn();
|
|
158
|
+
} catch (error) {
|
|
159
|
+
const msg = error.message?.toLowerCase() ?? "";
|
|
160
|
+
const retryable = msg.includes("network") || msg.includes("timeout") || msg.includes("econnreset") || msg.includes("429") || msg.includes("503") || msg.includes("502");
|
|
161
|
+
if (attempt === maxAttempts || !retryable) throw error;
|
|
162
|
+
await new Promise((r) => setTimeout(r, 2 ** (attempt - 1) * 1e3));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
throw new Error("Unreachable");
|
|
166
|
+
}
|
|
156
167
|
async function translateBatch(batch) {
|
|
157
168
|
if (batch.entries.length === 0) return /* @__PURE__ */ new Map();
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
const inputArray = batch.entries.map((e) => ({ key: e.key, text: e.text }));
|
|
170
|
+
return withRetry(async () => {
|
|
171
|
+
const { output } = await (0, import_ai.generateText)({
|
|
172
|
+
model: getOpenRouter().languageModel(DEFAULT_MODEL),
|
|
173
|
+
output: import_ai.Output.object({
|
|
174
|
+
schema: translationSchema
|
|
175
|
+
}),
|
|
176
|
+
system: SYSTEM_PROMPT,
|
|
177
|
+
prompt: `Translate from "${batch.sourceLang}" to "${batch.targetLang}":
|
|
178
|
+
|
|
179
|
+
${JSON.stringify(inputArray, null, 2)}
|
|
180
|
+
|
|
181
|
+
Return the translations array with the same keys and translated values.`
|
|
182
|
+
});
|
|
183
|
+
if (!output.translations || output.translations.length === 0) {
|
|
184
|
+
throw new Error("Translation returned empty result");
|
|
185
|
+
}
|
|
186
|
+
const resultMap = new Map(output.translations.map((t) => [t.key, t.value]));
|
|
187
|
+
const missingKeys = batch.entries.filter((e) => !resultMap.has(e.key));
|
|
188
|
+
if (missingKeys.length > 0) {
|
|
189
|
+
throw new Error(
|
|
190
|
+
`Missing translations for keys: ${missingKeys.map((e) => e.key).join(", ")}`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
return resultMap;
|
|
194
|
+
});
|
|
171
195
|
}
|
|
172
196
|
|
|
173
197
|
// src/core/sync.ts
|
|
@@ -290,7 +314,7 @@ var TranslationService = class {
|
|
|
290
314
|
var import_prompts = __toESM(require("prompts"));
|
|
291
315
|
var import_chalk = __toESM(require("chalk"));
|
|
292
316
|
(0, import_dotenv.config)({ path: (0, import_node_path2.resolve)(process.cwd(), ".env") });
|
|
293
|
-
var VERSION = "0.2.
|
|
317
|
+
var VERSION = "0.2.3";
|
|
294
318
|
var program = new import_commander.Command();
|
|
295
319
|
program.name("i18n-ai").description("AI-powered translation CLI").version(VERSION);
|
|
296
320
|
var CONFIG_FILE = "i18n.config.json";
|
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
TranslationService
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IOH4K3A3.mjs";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { config as loadEnv } from "dotenv";
|
|
@@ -11,7 +11,7 @@ import { readFile, writeFile, mkdir } from "fs/promises";
|
|
|
11
11
|
import prompts from "prompts";
|
|
12
12
|
import chalk from "chalk";
|
|
13
13
|
loadEnv({ path: resolve(process.cwd(), ".env") });
|
|
14
|
-
var VERSION = "0.2.
|
|
14
|
+
var VERSION = "0.2.3";
|
|
15
15
|
var program = new Command();
|
|
16
16
|
program.name("i18n-ai").description("AI-powered translation CLI").version(VERSION);
|
|
17
17
|
var CONFIG_FILE = "i18n.config.json";
|
package/dist/index.d.mts
CHANGED
|
@@ -21,14 +21,6 @@ declare function withLockFile<T>(path: string, fn: (lock: TranslationLock) => Pr
|
|
|
21
21
|
declare function analyzeLocale(base: Map<string, string>, target: Map<string, string>, locale: string, lock: TranslationLock): LocaleChanges;
|
|
22
22
|
declare function updateLock(lock: TranslationLock, locale: string, base: Map<string, string>, final: Map<string, string>): void;
|
|
23
23
|
|
|
24
|
-
interface TranslateProps {
|
|
25
|
-
text: string;
|
|
26
|
-
lang: string;
|
|
27
|
-
targetLang: string;
|
|
28
|
-
apiKey?: string;
|
|
29
|
-
model?: string;
|
|
30
|
-
}
|
|
31
|
-
declare const translate: ({ text, lang, targetLang, apiKey, model }: TranslateProps) => Promise<string>;
|
|
32
24
|
interface TranslationBatch {
|
|
33
25
|
entries: Array<{
|
|
34
26
|
key: string;
|
|
@@ -61,4 +53,4 @@ declare class TranslationService {
|
|
|
61
53
|
private translateAll;
|
|
62
54
|
}
|
|
63
55
|
|
|
64
|
-
export { type LocaleChanges, type LockEntry, type SyncConfig, type TranslationBatch, type TranslationLock, TranslationService, analyzeLocale,
|
|
56
|
+
export { type LocaleChanges, type LockEntry, type SyncConfig, type TranslationBatch, type TranslationLock, TranslationService, analyzeLocale, translateBatch, updateLock, withLockFile };
|
package/dist/index.d.ts
CHANGED
|
@@ -21,14 +21,6 @@ declare function withLockFile<T>(path: string, fn: (lock: TranslationLock) => Pr
|
|
|
21
21
|
declare function analyzeLocale(base: Map<string, string>, target: Map<string, string>, locale: string, lock: TranslationLock): LocaleChanges;
|
|
22
22
|
declare function updateLock(lock: TranslationLock, locale: string, base: Map<string, string>, final: Map<string, string>): void;
|
|
23
23
|
|
|
24
|
-
interface TranslateProps {
|
|
25
|
-
text: string;
|
|
26
|
-
lang: string;
|
|
27
|
-
targetLang: string;
|
|
28
|
-
apiKey?: string;
|
|
29
|
-
model?: string;
|
|
30
|
-
}
|
|
31
|
-
declare const translate: ({ text, lang, targetLang, apiKey, model }: TranslateProps) => Promise<string>;
|
|
32
24
|
interface TranslationBatch {
|
|
33
25
|
entries: Array<{
|
|
34
26
|
key: string;
|
|
@@ -61,4 +53,4 @@ declare class TranslationService {
|
|
|
61
53
|
private translateAll;
|
|
62
54
|
}
|
|
63
55
|
|
|
64
|
-
export { type LocaleChanges, type LockEntry, type SyncConfig, type TranslationBatch, type TranslationLock, TranslationService, analyzeLocale,
|
|
56
|
+
export { type LocaleChanges, type LockEntry, type SyncConfig, type TranslationBatch, type TranslationLock, TranslationService, analyzeLocale, translateBatch, updateLock, withLockFile };
|
package/dist/index.js
CHANGED
|
@@ -32,7 +32,6 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
TranslationService: () => TranslationService,
|
|
34
34
|
analyzeLocale: () => analyzeLocale,
|
|
35
|
-
translate: () => translate,
|
|
36
35
|
translateBatch: () => translateBatch,
|
|
37
36
|
updateLock: () => updateLock,
|
|
38
37
|
withLockFile: () => withLockFile
|
|
@@ -124,55 +123,79 @@ function updateLock(lock, locale, base, final) {
|
|
|
124
123
|
// src/core/translator.ts
|
|
125
124
|
var import_ai_sdk_provider = require("@openrouter/ai-sdk-provider");
|
|
126
125
|
var import_ai = require("ai");
|
|
127
|
-
var
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
- Input: "Hello {name}, welcome back!" -> Output (ES): "Hola {name}, \xA1bienvenido de nuevo!"
|
|
147
|
-
- Input: "Contact us calling to {number}" -> Output (FR): "Contactez-nous en appelant le {number}"
|
|
148
|
-
`;
|
|
149
|
-
const { output } = await (0, import_ai.generateText)({
|
|
150
|
-
model: openrouter.languageModel(model || "google/gemini-2.5-flash"),
|
|
151
|
-
system,
|
|
152
|
-
prompt: `Text to translate: "${text}"`,
|
|
153
|
-
output: import_ai.Output.object({
|
|
154
|
-
schema: import_zod.default.object({
|
|
155
|
-
translatedText: import_zod.default.string()
|
|
156
|
-
})
|
|
126
|
+
var z2 = __toESM(require("zod"));
|
|
127
|
+
|
|
128
|
+
// src/env.ts
|
|
129
|
+
var import_env_core = require("@t3-oss/env-core");
|
|
130
|
+
var z = __toESM(require("zod"));
|
|
131
|
+
var env = (0, import_env_core.createEnv)({
|
|
132
|
+
server: {
|
|
133
|
+
OPENROUTER_API_KEY: z.string()
|
|
134
|
+
},
|
|
135
|
+
runtimeEnv: process.env
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// src/core/translator.ts
|
|
139
|
+
var DEFAULT_MODEL = "google/gemini-2.5-flash";
|
|
140
|
+
var translationSchema = z2.object({
|
|
141
|
+
translations: z2.array(
|
|
142
|
+
z2.object({
|
|
143
|
+
key: z2.string(),
|
|
144
|
+
value: z2.string()
|
|
157
145
|
})
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
146
|
+
)
|
|
147
|
+
});
|
|
148
|
+
var openrouter = null;
|
|
149
|
+
var getOpenRouter = () => openrouter ?? (openrouter = (0, import_ai_sdk_provider.createOpenRouter)({ apiKey: env.OPENROUTER_API_KEY }));
|
|
150
|
+
var SYSTEM_PROMPT = `You are a professional translator.
|
|
151
|
+
|
|
152
|
+
RULES:
|
|
153
|
+
1. Translate the provided key-value pairs from the source language to the target language
|
|
154
|
+
2. Return an array of translations with the EXACT same keys and their translated values
|
|
155
|
+
3. Do NOT translate variables in curly braces: {name}, {count}, etc. Keep them exactly as-is
|
|
156
|
+
4. Maintain original tone and context
|
|
157
|
+
5. For single words or short phrases, translate directly`;
|
|
158
|
+
async function withRetry(fn, maxAttempts = 3) {
|
|
159
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
160
|
+
try {
|
|
161
|
+
return await fn();
|
|
162
|
+
} catch (error) {
|
|
163
|
+
const msg = error.message?.toLowerCase() ?? "";
|
|
164
|
+
const retryable = msg.includes("network") || msg.includes("timeout") || msg.includes("econnreset") || msg.includes("429") || msg.includes("503") || msg.includes("502");
|
|
165
|
+
if (attempt === maxAttempts || !retryable) throw error;
|
|
166
|
+
await new Promise((r) => setTimeout(r, 2 ** (attempt - 1) * 1e3));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
throw new Error("Unreachable");
|
|
170
|
+
}
|
|
161
171
|
async function translateBatch(batch) {
|
|
162
172
|
if (batch.entries.length === 0) return /* @__PURE__ */ new Map();
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
const inputArray = batch.entries.map((e) => ({ key: e.key, text: e.text }));
|
|
174
|
+
return withRetry(async () => {
|
|
175
|
+
const { output } = await (0, import_ai.generateText)({
|
|
176
|
+
model: getOpenRouter().languageModel(DEFAULT_MODEL),
|
|
177
|
+
output: import_ai.Output.object({
|
|
178
|
+
schema: translationSchema
|
|
179
|
+
}),
|
|
180
|
+
system: SYSTEM_PROMPT,
|
|
181
|
+
prompt: `Translate from "${batch.sourceLang}" to "${batch.targetLang}":
|
|
182
|
+
|
|
183
|
+
${JSON.stringify(inputArray, null, 2)}
|
|
184
|
+
|
|
185
|
+
Return the translations array with the same keys and translated values.`
|
|
186
|
+
});
|
|
187
|
+
if (!output.translations || output.translations.length === 0) {
|
|
188
|
+
throw new Error("Translation returned empty result");
|
|
189
|
+
}
|
|
190
|
+
const resultMap = new Map(output.translations.map((t) => [t.key, t.value]));
|
|
191
|
+
const missingKeys = batch.entries.filter((e) => !resultMap.has(e.key));
|
|
192
|
+
if (missingKeys.length > 0) {
|
|
193
|
+
throw new Error(
|
|
194
|
+
`Missing translations for keys: ${missingKeys.map((e) => e.key).join(", ")}`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
return resultMap;
|
|
198
|
+
});
|
|
176
199
|
}
|
|
177
200
|
|
|
178
201
|
// src/core/sync.ts
|
|
@@ -297,7 +320,6 @@ var TranslationService = class {
|
|
|
297
320
|
0 && (module.exports = {
|
|
298
321
|
TranslationService,
|
|
299
322
|
analyzeLocale,
|
|
300
|
-
translate,
|
|
301
323
|
translateBatch,
|
|
302
324
|
updateLock,
|
|
303
325
|
withLockFile
|
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TranslationService,
|
|
3
3
|
analyzeLocale,
|
|
4
|
-
translate,
|
|
5
4
|
translateBatch,
|
|
6
5
|
updateLock,
|
|
7
6
|
withLockFile
|
|
8
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IOH4K3A3.mjs";
|
|
9
8
|
export {
|
|
10
9
|
TranslationService,
|
|
11
10
|
analyzeLocale,
|
|
12
|
-
translate,
|
|
13
11
|
translateBatch,
|
|
14
12
|
updateLock,
|
|
15
13
|
withLockFile
|