42 lines
1.4 KiB
JavaScript
42 lines
1.4 KiB
JavaScript
import { Translator } from "deepl-node";
|
|
const DEFAULT_BATCH_SIZE = 50;
|
|
const MAX_RETRIES = 3;
|
|
async function translateStrings(strings, sourceLang, targetLang, apiKey, deeplOptions, batchSize = DEFAULT_BATCH_SIZE) {
|
|
if (strings.length === 0) return [];
|
|
const key = apiKey ?? process.env.DEEPL_AUTH_KEY;
|
|
if (!key) throw new Error("DeepL API key must be provided via options.apiKey or DEEPL_AUTH_KEY environment variable");
|
|
const deepl = new Translator(key);
|
|
const translations = new Array(strings.length).fill("");
|
|
const textOptions = {
|
|
tagHandling: "html",
|
|
splitSentences: "nonewlines",
|
|
...deeplOptions
|
|
};
|
|
for (let i = 0; i < strings.length; i += batchSize) {
|
|
const batch = strings.slice(i, i + batchSize);
|
|
const results = await retry(
|
|
() => deepl.translateText(batch, sourceLang, targetLang, textOptions)
|
|
);
|
|
for (let j = 0; j < batch.length; j++) {
|
|
translations[i + j] = results[j].text;
|
|
}
|
|
}
|
|
return translations;
|
|
}
|
|
async function retry(fn, retries = MAX_RETRIES) {
|
|
for (let attempt = 0; ; attempt++) {
|
|
try {
|
|
return await fn();
|
|
} catch (err) {
|
|
const status = err?.statusCode ?? err?.status;
|
|
const retryable = status === 429 || status === 456 || status >= 500 && status < 600;
|
|
if (!retryable || attempt >= retries) throw err;
|
|
const delay = Math.min(1e3 * 2 ** attempt, 1e4);
|
|
await new Promise((r) => setTimeout(r, delay));
|
|
}
|
|
}
|
|
}
|
|
export {
|
|
translateStrings
|
|
};
|