@terai/translator 0.0.14 → 0.0.16
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/translators/index.cjs +9 -8
- package/dist/translators/index.cjs.map +1 -1
- package/dist/translators/index.d.cts +1 -27
- package/dist/translators/index.d.cts.map +1 -1
- package/dist/translators/index.d.mts +1 -27
- package/dist/translators/index.d.mts.map +1 -1
- package/dist/translators/index.mjs +10 -9
- package/dist/translators/index.mjs.map +1 -1
- package/package.json +4 -21
|
@@ -40,7 +40,7 @@ contextually appropriate, and maintain the natural feel of native language.
|
|
|
40
40
|
|
|
41
41
|
## Output Format
|
|
42
42
|
- Return ONLY a valid JSON object
|
|
43
|
-
- Use the EXACT SAME KEYS as the input
|
|
43
|
+
- Use the EXACT SAME KEYS as the input (CRITICAL)
|
|
44
44
|
- Do NOT add newlines within string values
|
|
45
45
|
- Do NOT modify, remove, or add keys
|
|
46
46
|
- Do NOT include markdown code blocks or extra formatting
|
|
@@ -55,15 +55,16 @@ contextually appropriate, and maintain the natural feel of native language.
|
|
|
55
55
|
❌ INCORRECT:
|
|
56
56
|
- "Welcome \${var}" → "Bienvenido Juan" (translated variable)
|
|
57
57
|
- "You have {var} items" → "Tienes 3 elementos" (removed braces)
|
|
58
|
-
- "Click <strong>here</strong>" → "Haz clic **aquí**" (changed HTML to markdown)`,_=({model:e,systemPrompt:t=g})=>async({dictionary:n,projectLocale:r,locale:i})=>{let{object:a}=await(0,l.generateObject)({model:e,output:`
|
|
58
|
+
- "Click <strong>here</strong>" → "Haz clic **aquí**" (changed HTML to markdown)`,_=({model:e,systemPrompt:t=g})=>async({dictionary:n,projectLocale:r,locale:i})=>{let{object:a}=await(0,l.generateObject)({model:e,output:`no-schema`,system:t?h.outdent`
|
|
59
59
|
${g}
|
|
60
60
|
|
|
61
|
-
##
|
|
61
|
+
## Additional User System Instructions (highest priority)
|
|
62
62
|
${t}
|
|
63
63
|
`:g,prompt:h.outdent`
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
Translate the following JSON from locale:"${r}" to locale:"${i}".
|
|
65
|
+
|
|
66
|
+
<target-json>
|
|
67
|
+
${JSON.stringify(n,null,2)}
|
|
68
|
+
</target-json>
|
|
69
|
+
`});return v.parse(a)},v=u.z.record(u.z.string(),u.z.string()),y=({sourceLanguageCode:e=`auto`,...t})=>{let n=new d.TranslateClient(t);return async({dictionary:t,locale:r,projectLocale:i})=>{let a={},o=e===`auto`?i:e;return await Promise.all(Object.keys(t).map(async e=>{let i=t[e],s=new d.TranslateTextCommand({Text:i,SourceLanguageCode:o,TargetLanguageCode:r});a[e]=(await n.send(s)).TranslatedText||i})),a}},b=({subscriptionKey:e,region:t,endpoint:n=`https://api.cognitive.microsofttranslator.com`})=>async({dictionary:r,locale:i,projectLocale:a})=>{let o={},s=Object.keys(r),c=s.map(e=>({text:r[e]})),l=[];for(let e=0;e<c.length;e+=100)l.push(c.slice(e,e+100));let u=0;for(let c of l){let l=new URL(`/translate`,n);l.searchParams.set(`api-version`,`3.0`),l.searchParams.set(`from`,a),l.searchParams.set(`to`,i);let d=await fetch(l.toString(),{method:`POST`,headers:{"Ocp-Apim-Subscription-Key":e,"Ocp-Apim-Subscription-Region":t,"Content-Type":`application/json`},body:JSON.stringify(c)});if(!d.ok){let e=await d.text();throw Error(`Azure Translator API error: ${d.status} - ${e}`)}let f=await d.json();for(let e of f){let t=s[u];o[t]=e.translations[0]?.text||r[t],u++}}return o},x=({authKey:e,options:t,formality:n=`default`,preserveFormatting:r=!0,tagHandling:i=`xml`})=>{let a=new f.Translator(e,t);return async({dictionary:e,locale:t,projectLocale:o})=>{let s={},c=Object.keys(e),l=c.map(t=>e[t]),u=t.toUpperCase(),d=o.toUpperCase(),f=await a.translateText(l,d,u,{formality:n,preserveFormatting:r,tagHandling:i}),p=Array.isArray(f)?f:[f];for(let t=0;t<c.length;t++){let n=c[t];s[n]=p[t]?.text||e[n]}return s}},S=e=>{let t=new p.v2.Translate(e);return async({dictionary:e,locale:n})=>{let r={};return await Promise.all(Object.keys(e).map(async i=>{let a=e[i],[o]=await t.translate(a,n);r[i]=o})),r}};exports.createAiTranslator=_,exports.createAwsTranslator=y,exports.createAzureTranslator=b,exports.createDeepLTranslator=x,exports.createGoogleCloudTranslator=S;
|
|
69
70
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["outdent","translator: Translator","z","TranslateClient","translator: Translator","translatedOutput: Dictionary","TranslateTextCommand","translator: Translator","translatedOutput: Dictionary","batches: Array<Array<{ text: string }>>","results: AzureTranslationResponse","deepl","translator: Translator","translatedOutput: Dictionary","v2","translator: Translator","translatedOutput: Dictionary"],"sources":["../../../../node_modules/.pnpm/outdent@0.8.0/node_modules/outdent/lib/index.js","../../src/translators/ai.ts","../../src/translators/aws.ts","../../src/translators/azure.ts","../../src/translators/deepl.ts","../../src/translators/google-cloud.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.outdent = void 0;\n// In the absence of a WeakSet or WeakMap implementation, don't break, but don't cache either.\nfunction noop() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n}\nfunction createWeakMap() {\n if (typeof WeakMap !== \"undefined\") {\n return new WeakMap();\n }\n else {\n return fakeSetOrMap();\n }\n}\n/**\n * Creates and returns a no-op implementation of a WeakMap / WeakSet that never stores anything.\n */\nfunction fakeSetOrMap() {\n return {\n add: noop,\n delete: noop,\n get: noop,\n set: noop,\n has: function (k) {\n return false;\n },\n };\n}\n// Safe hasOwnProperty\nvar hop = Object.prototype.hasOwnProperty;\nvar has = function (obj, prop) {\n return hop.call(obj, prop);\n};\n// Copy all own enumerable properties from source to target\nfunction extend(target, source) {\n for (var prop in source) {\n if (has(source, prop)) {\n target[prop] = source[prop];\n }\n }\n return target;\n}\nvar reLeadingNewline = /^[ \\t]*(?:\\r\\n|\\r|\\n)/;\nvar reTrailingNewline = /(?:\\r\\n|\\r|\\n)[ \\t]*$/;\nvar reStartsWithNewlineOrIsEmpty = /^(?:[\\r\\n]|$)/;\nvar reDetectIndentation = /(?:\\r\\n|\\r|\\n)([ \\t]*)(?:[^ \\t\\r\\n]|$)/;\nvar reOnlyWhitespaceWithAtLeastOneNewline = /^[ \\t]*[\\r\\n][ \\t\\r\\n]*$/;\nfunction _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options) {\n // If first interpolated value is a reference to outdent,\n // determine indentation level from the indentation of the interpolated value.\n var indentationLevel = 0;\n var match = strings[0].match(reDetectIndentation);\n if (match) {\n indentationLevel = match[1].length;\n }\n var reSource = \"(\\\\r\\\\n|\\\\r|\\\\n).{0,\" + indentationLevel + \"}\";\n var reMatchIndent = new RegExp(reSource, \"g\");\n if (firstInterpolatedValueSetsIndentationLevel) {\n strings = strings.slice(1);\n }\n var newline = options.newline, trimLeadingNewline = options.trimLeadingNewline, trimTrailingNewline = options.trimTrailingNewline;\n var normalizeNewlines = typeof newline === \"string\";\n var l = strings.length;\n var outdentedStrings = strings.map(function (v, i) {\n // Remove leading indentation from all lines\n v = v.replace(reMatchIndent, \"$1\");\n // Trim a leading newline from the first string\n if (i === 0 && trimLeadingNewline) {\n v = v.replace(reLeadingNewline, \"\");\n }\n // Trim a trailing newline from the last string\n if (i === l - 1 && trimTrailingNewline) {\n v = v.replace(reTrailingNewline, \"\");\n }\n // Normalize newlines\n if (normalizeNewlines) {\n v = v.replace(/\\r\\n|\\n|\\r/g, function (_) { return newline; });\n }\n return v;\n });\n return outdentedStrings;\n}\nfunction concatStringsAndValues(strings, values) {\n var ret = \"\";\n for (var i = 0, l = strings.length; i < l; i++) {\n ret += strings[i];\n if (i < l - 1) {\n ret += values[i];\n }\n }\n return ret;\n}\nfunction isTemplateStringsArray(v) {\n return has(v, \"raw\") && has(v, \"length\");\n}\n/**\n * It is assumed that opts will not change. If this is a problem, clone your options object and pass the clone to\n * makeInstance\n * @param options\n * @return {outdent}\n */\nfunction createInstance(options) {\n /** Cache of pre-processed template literal arrays */\n var arrayAutoIndentCache = createWeakMap();\n /**\n * Cache of pre-processed template literal arrays, where first interpolated value is a reference to outdent,\n * before interpolated values are injected.\n */\n var arrayFirstInterpSetsIndentCache = createWeakMap();\n function outdent(stringsOrOptions) {\n var values = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n values[_i - 1] = arguments[_i];\n }\n /* tslint:enable:no-shadowed-variable */\n if (isTemplateStringsArray(stringsOrOptions)) {\n var strings = stringsOrOptions;\n // Is first interpolated value a reference to outdent, alone on its own line, without any preceding non-whitespace?\n var firstInterpolatedValueSetsIndentationLevel = (values[0] === outdent || values[0] === defaultOutdent) &&\n reOnlyWhitespaceWithAtLeastOneNewline.test(strings[0]) &&\n reStartsWithNewlineOrIsEmpty.test(strings[1]);\n // Perform outdentation\n var cache = firstInterpolatedValueSetsIndentationLevel\n ? arrayFirstInterpSetsIndentCache\n : arrayAutoIndentCache;\n var renderedArray = cache.get(strings);\n if (!renderedArray) {\n renderedArray = _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options);\n cache.set(strings, renderedArray);\n }\n /** If no interpolated values, skip concatenation step */\n if (values.length === 0) {\n return renderedArray[0];\n }\n /** Concatenate string literals with interpolated values */\n var rendered = concatStringsAndValues(renderedArray, firstInterpolatedValueSetsIndentationLevel ? values.slice(1) : values);\n return rendered;\n }\n else {\n // Create and return a new instance of outdent with the given options\n return createInstance(extend(extend({}, options), stringsOrOptions || {}));\n }\n }\n var fullOutdent = extend(outdent, {\n string: function (str) {\n return _outdentArray([str], false, options)[0];\n },\n });\n return fullOutdent;\n}\nvar defaultOutdent = createInstance({\n trimLeadingNewline: true,\n trimTrailingNewline: true,\n});\nexports.outdent = defaultOutdent;\n// Named exports. Simple and preferred.\n// import outdent from 'outdent';\nexports.default = defaultOutdent;\nif (typeof module !== \"undefined\") {\n // In webpack harmony-modules environments, module.exports is read-only,\n // so we fail gracefully.\n try {\n module.exports = defaultOutdent;\n Object.defineProperty(defaultOutdent, \"__esModule\", { value: true });\n defaultOutdent.default = defaultOutdent;\n defaultOutdent.outdent = defaultOutdent;\n }\n catch (e) { }\n}\n//# sourceMappingURL=index.js.map","// Dependencies\nimport { generateObject } from 'ai'\nimport { outdent } from 'outdent'\nimport { z } from 'zod'\n\n// Types\nimport type { LanguageModel } from 'ai'\nimport type { Translator } from '@terai/types'\n\nexport type CreateAiTranslatorOptions = {\n\t/**\n\t * The AI model to use for translation.\n\t * Can be any model from AI SDK providers (@ai-sdk/openai, @ai-sdk/anthropic, @ai-sdk/groq, etc.)\n\t *\n\t * @example\n\t * import { createOpenAI } from '@ai-sdk/openai'\n\t * const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })\n\t * const model = openai('gpt-4o')\n\t *\n\t * @example\n\t * import { createGroq } from '@ai-sdk/groq'\n\t * const groq = createGroq({ apiKey: process.env.GROQ_API_KEY })\n\t * const model = groq('llama-3.3-70b-versatile')\n\t */\n\tmodel: LanguageModel\n\n\t/**\n\t * Custom system prompt for translation.\n\t * If not provided, a generic prompt will be used that covers most app translation cases.\n\t */\n\tsystemPrompt?: string\n}\n\nconst DEFAULT_SYSTEM_PROMPT = outdent`\n# Expert AI Translator\n\n## Your Role\nYou are an expert translator and localization specialist with deep expertise in software\napplications, user interfaces, and technical documentation. Your translations are accurate,\ncontextually appropriate, and maintain the natural feel of native language.\n\n## Critical Requirements\n\n### 1. Preserve Code Patterns\n- **NEVER** translate template variables (e.g., \\${var}, {var}, %s, %d)\n- **ALWAYS** keep placeholder syntax exactly as provided\n- **MAINTAIN** all escape sequences and special characters\n- **PRESERVE** HTML tags, markdown syntax, and formatting codes\n\n### 2. Translation Quality\n- Use **natural, idiomatic** expressions in the target language\n- Maintain **consistent terminology** throughout all strings\n- Adapt **cultural references** appropriately for the target locale\n- Ensure **grammatical correctness** and proper sentence structure\n\n### 3. Context Awareness\n- **UI Elements**: Keep translations concise for buttons, labels, and menus\n- **Messages**: Maintain appropriate tone (error messages: clear, help text: friendly)\n- **Technical Terms**: Use standard industry terminology when available\n- **Brand Names**: Do not translate proper nouns, product names, or brand names\n\n### 4. Formatting Guidelines\n- **Punctuation**: Follow target language conventions\n- **Capitalization**: Match target language standards (e.g., German nouns)\n- **Numbers & Dates**: Keep placeholders unchanged; format will be handled at runtime\n- **Whitespace**: Preserve spacing around variables and special characters\n\n### 5. Tone & Style\n- **Consistency**: Maintain uniform voice across all translations\n- **Formality**: Match the formality level of the source text\n- **Clarity**: Prioritize understanding over literal translation\n- **Brevity**: Keep translations concise, especially for UI elements\n\n## Output Format\n- Return ONLY a valid JSON object\n- Use the EXACT SAME KEYS as the input\n- Do NOT add newlines within string values\n- Do NOT modify, remove, or add keys\n- Do NOT include markdown code blocks or extra formatting\n\n## Examples of What to Preserve\n\n✅ CORRECT:\n- \"Welcome \\${var}\" → \"Bienvenido \\${var}\"\n- \"You have {count} items\" → \"Tienes {count} elementos\"\n- \"Click <strong>here</strong>\" → \"Haz clic <strong>aquí</strong>\"\n\n❌ INCORRECT:\n- \"Welcome \\${var}\" → \"Bienvenido Juan\" (translated variable)\n- \"You have {var} items\" → \"Tienes 3 elementos\" (removed braces)\n- \"Click <strong>here</strong>\" → \"Haz clic **aquí**\" (changed HTML to markdown)`\n\n/**\n * Creates an AI-powered translator using the Vercel AI SDK.\n *\n * This translator uses structured output generation to translate dictionaries\n * while preserving template variables, formatting, and code patterns.\n *\n * @example\n * ```ts\n * import { createAiTranslator } from '@terai/translator/translators'\n * import { createOpenAI } from '@ai-sdk/openai'\n *\n * const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })\n * const translator = createAiTranslator({\n * model: openai('gpt-4o')\n * })\n * ```\n *\n * @example With Groq\n * ```ts\n * import { createAiTranslator } from '@terai/translator/translators'\n * import { createGroq } from '@ai-sdk/groq'\n *\n * const groq = createGroq({ apiKey: process.env.GROQ_API_KEY })\n * const translator = createAiTranslator({\n * model: groq('llama-3.3-70b-versatile')\n * })\n * ```\n *\n * @example With custom system prompt\n * ```ts\n * import { createAiTranslator } from '@terai/translator/translators'\n * import { createAnthropic } from '@ai-sdk/anthropic'\n *\n * const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY })\n * const translator = createAiTranslator({\n * model: anthropic('claude-3-5-sonnet-20241022'),\n * systemPrompt: 'Custom prompt for my specific use case...'\n * })\n * ```\n */\nexport const createAiTranslator = ({\n\tmodel,\n\tsystemPrompt = DEFAULT_SYSTEM_PROMPT\n}: CreateAiTranslatorOptions): Translator => {\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tprojectLocale,\n\t\tlocale\n\t}) => {\n\t\tconst { object: translation } = await generateObject({\n\t\t\tmodel,\n\t\t\toutput: 'object',\n\t\t\tschema: z.record(z.string(), z.string()),\n\t\t\tsystem: !systemPrompt\n\t\t\t\t? DEFAULT_SYSTEM_PROMPT\n\t\t\t\t: outdent`\n\t\t\t\t${DEFAULT_SYSTEM_PROMPT}\n\t\t\t\t\n\t\t\t\t## Additonal User System Instructions (highest priority)\n\t\t\t\t${systemPrompt}\n\t\t\t`,\n\t\t\tprompt: outdent`\n\t\t\tTranslate the following JSON from \"${projectLocale}\" to \"${locale}\".\n\t\t\t<target-json>\n\t\t\t\t${JSON.stringify(dictionary, null, 2)}\n\t\t\t</target-json>\n\t\t\t`\n\t\t})\n\n\t\treturn translation\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport {\n\tTranslateClient,\n\tTranslateTextCommand,\n\ttype TranslateClientConfig\n} from '@aws-sdk/client-translate'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateAwsTranslatorOptions = TranslateClientConfig & {\n\t/**\n\t * The source language code (e.g., 'en', 'es', 'fr').\n\t * If not provided, AWS Translate will auto-detect the source language.\n\t * @default 'auto'\n\t */\n\tsourceLanguageCode?: string\n}\n\n/**\n * Creates a translator using AWS Translate.\n *\n * AWS Translate is a neural machine translation service that delivers\n * fast, high-quality, and affordable language translation.\n *\n * @example\n * ```ts\n * import { createAwsTranslator } from '@terai/translator/translators'\n *\n * const translator = createAwsTranslator({\n * region: 'us-east-1',\n * credentials: {\n * accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n * secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY\n * }\n * })\n * ```\n *\n * @example With AWS profile\n * ```ts\n * import { createAwsTranslator } from '@terai/translator/translators'\n * import { fromIni } from '@aws-sdk/credential-providers'\n *\n * const translator = createAwsTranslator({\n * region: 'us-east-1',\n * credentials: fromIni({ profile: 'my-profile' })\n * })\n * ```\n */\nexport const createAwsTranslator = ({\n\tsourceLanguageCode = 'auto',\n\t...clientConfig\n}: CreateAwsTranslatorOptions): Translator => {\n\tconst client = new TranslateClient(clientConfig)\n\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\n\t\t// Use projectLocale as source if not set to auto\n\t\tconst source =\n\t\t\tsourceLanguageCode === 'auto' ? projectLocale : sourceLanguageCode\n\n\t\tawait Promise.all(\n\t\t\tObject.keys(dictionary).map(async (key) => {\n\t\t\t\tconst value = dictionary[key]\n\n\t\t\t\tconst command = new TranslateTextCommand({\n\t\t\t\t\tText: value,\n\t\t\t\t\tSourceLanguageCode: source,\n\t\t\t\t\tTargetLanguageCode: locale\n\t\t\t\t})\n\n\t\t\t\tconst response = await client.send(command)\n\n\t\t\t\ttranslatedOutput[key] = response.TranslatedText || value\n\t\t\t})\n\t\t)\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateAzureTranslatorOptions = {\n\t/**\n\t * Azure Translator subscription key.\n\t */\n\tsubscriptionKey: string\n\n\t/**\n\t * Azure region where the Translator resource is located.\n\t * @example 'eastus', 'westeurope', 'southeastasia'\n\t */\n\tregion: string\n\n\t/**\n\t * Custom endpoint URL. If not provided, uses the global endpoint.\n\t * @default 'https://api.cognitive.microsofttranslator.com'\n\t */\n\tendpoint?: string\n}\n\ntype AzureTranslationResponse = Array<{\n\ttranslations: Array<{\n\t\ttext: string\n\t\tto: string\n\t}>\n}>\n\n/**\n * Creates a translator using Microsoft Azure Translator.\n *\n * Azure Translator is a cloud-based machine translation service\n * that supports 100+ languages.\n *\n * @example\n * ```ts\n * import { createAzureTranslator } from '@terai/translator/translators'\n *\n * const translator = createAzureTranslator({\n * subscriptionKey: process.env.AZURE_TRANSLATOR_KEY,\n * region: 'eastus'\n * })\n * ```\n *\n * @example With custom endpoint\n * ```ts\n * import { createAzureTranslator } from '@terai/translator/translators'\n *\n * const translator = createAzureTranslator({\n * subscriptionKey: process.env.AZURE_TRANSLATOR_KEY,\n * region: 'eastus',\n * endpoint: 'https://my-custom-endpoint.cognitiveservices.azure.com'\n * })\n * ```\n */\nexport const createAzureTranslator = ({\n\tsubscriptionKey,\n\tregion,\n\tendpoint = 'https://api.cognitive.microsofttranslator.com'\n}: CreateAzureTranslatorOptions): Translator => {\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\t\tconst keys = Object.keys(dictionary)\n\t\tconst texts = keys.map((key) => ({ text: dictionary[key] }))\n\n\t\t// Azure Translator API accepts up to 100 texts per request\n\t\tconst batchSize = 100\n\t\tconst batches: Array<Array<{ text: string }>> = []\n\n\t\tfor (let i = 0; i < texts.length; i += batchSize) {\n\t\t\tbatches.push(texts.slice(i, i + batchSize))\n\t\t}\n\n\t\tlet keyIndex = 0\n\n\t\tfor (const batch of batches) {\n\t\t\tconst url = new URL('/translate', endpoint)\n\t\t\turl.searchParams.set('api-version', '3.0')\n\t\t\turl.searchParams.set('from', projectLocale)\n\t\t\turl.searchParams.set('to', locale)\n\n\t\t\tconst response = await fetch(url.toString(), {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Ocp-Apim-Subscription-Key': subscriptionKey,\n\t\t\t\t\t'Ocp-Apim-Subscription-Region': region,\n\t\t\t\t\t'Content-Type': 'application/json'\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(batch)\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorText = await response.text()\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Azure Translator API error: ${response.status} - ${errorText}`\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst results: AzureTranslationResponse = await response.json()\n\n\t\t\tfor (const result of results) {\n\t\t\t\tconst key = keys[keyIndex]\n\t\t\t\ttranslatedOutput[key] = result.translations[0]?.text || dictionary[key]\n\t\t\t\tkeyIndex++\n\t\t\t}\n\t\t}\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport * as deepl from 'deepl-node'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateDeepLTranslatorOptions = {\n\t/**\n\t * DeepL API authentication key.\n\t * Get your key from https://www.deepl.com/pro-api\n\t */\n\tauthKey: string\n\n\t/**\n\t * Additional options for the DeepL Translator.\n\t */\n\toptions?: deepl.TranslatorOptions\n\n\t/**\n\t * Formality preference for translations.\n\t * - 'default': Default formality\n\t * - 'more': More formal language\n\t * - 'less': Less formal language\n\t * - 'prefer_more': Prefer more formal if available\n\t * - 'prefer_less': Prefer less formal if available\n\t * @default 'default'\n\t */\n\tformality?: deepl.Formality\n\n\t/**\n\t * Whether to preserve formatting in translations.\n\t * @default true\n\t */\n\tpreserveFormatting?: boolean\n\n\t/**\n\t * Specify how to handle XML tags in text.\n\t * @default 'xml'\n\t */\n\ttagHandling?: 'xml' | 'html'\n}\n\n/**\n * Creates a translator using DeepL API.\n *\n * DeepL is known for producing high-quality, natural-sounding translations\n * and is often considered one of the best machine translation services available.\n *\n * @example\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY\n * })\n * ```\n *\n * @example With formality preference\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY,\n * formality: 'less' // Use informal language\n * })\n * ```\n *\n * @example With HTML tag handling\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY,\n * tagHandling: 'html',\n * preserveFormatting: true\n * })\n * ```\n */\nexport const createDeepLTranslator = ({\n\tauthKey,\n\toptions,\n\tformality = 'default',\n\tpreserveFormatting = true,\n\ttagHandling = 'xml'\n}: CreateDeepLTranslatorOptions): Translator => {\n\tconst deeplTranslator = new deepl.Translator(authKey, options)\n\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\t\tconst keys = Object.keys(dictionary)\n\t\tconst texts = keys.map((key) => dictionary[key])\n\n\t\t// DeepL uses specific language codes (e.g., 'EN-US' instead of 'en-US')\n\t\tconst targetLang = locale.toUpperCase() as deepl.TargetLanguageCode\n\t\tconst sourceLang = projectLocale.toUpperCase() as deepl.SourceLanguageCode\n\n\t\tconst results = await deeplTranslator.translateText(\n\t\t\ttexts,\n\t\t\tsourceLang,\n\t\t\ttargetLang,\n\t\t\t{\n\t\t\t\tformality,\n\t\t\t\tpreserveFormatting,\n\t\t\t\ttagHandling\n\t\t\t}\n\t\t)\n\n\t\t// Handle both single result and array of results\n\t\tconst translationResults = Array.isArray(results) ? results : [results]\n\n\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\tconst key = keys[i]\n\t\t\ttranslatedOutput[key] = translationResults[i]?.text || dictionary[key]\n\t\t}\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport { v2 } from '@google-cloud/translate'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateGoogleCloudTranslatorOptions = v2.TranslateConfig\n\n/**\n * Creates a translator using Google Cloud Translation API.\n *\n * This translator uses Google Cloud's Neural Machine Translation (NMT)\n * for high-quality translations.\n *\n * @example\n * ```ts\n * import { createGoogleCloudTranslator } from '@terai/translator/translators'\n *\n * const translator = createGoogleCloudTranslator({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT_ID,\n * keyFilename: './google-credentials.json'\n * })\n * ```\n *\n * @example With API key\n * ```ts\n * import { createGoogleCloudTranslator } from '@terai/translator/translators'\n *\n * const translator = createGoogleCloudTranslator({\n * key: process.env.GOOGLE_CLOUD_API_KEY\n * })\n * ```\n */\nexport const createGoogleCloudTranslator = (\n\toptions: CreateGoogleCloudTranslatorOptions\n): Translator => {\n\tconst translate = new v2.Translate(options)\n\n\tconst translator: Translator = async ({ dictionary, locale }) => {\n\t\tconst translatedOutput: Dictionary = {}\n\n\t\tawait Promise.all(\n\t\t\tObject.keys(dictionary).map(async (key) => {\n\t\t\t\tconst value = dictionary[key]\n\n\t\t\t\tconst [translation] = await translate.translate(value, locale)\n\n\t\t\t\ttranslatedOutput[key] = translation\n\t\t\t})\n\t\t)\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n"],"x_google_ignoreList":[0],"mappings":"6rBACA,OAAO,eAAe,EAAS,aAAc,CAAE,MAAO,GAAM,CAAC,CAC7D,EAAQ,QAAU,IAAK,GAEvB,SAAS,GAAO,CAEZ,IAAK,IADD,EAAO,EAAE,CACJ,EAAK,EAAG,EAAK,UAAU,OAAQ,IACpC,EAAK,GAAM,UAAU,GAG7B,SAAS,GAAgB,CAKjB,OAJA,OAAO,QAAY,IACZ,IAAI,QAGJ,GAAc,CAM7B,SAAS,GAAe,CACpB,MAAO,CACH,IAAK,EACL,OAAQ,EACR,IAAK,EACL,IAAK,EACL,IAAK,SAAU,EAAG,CACd,MAAO,IAEd,CAGL,IAAI,EAAM,OAAO,UAAU,eACvB,EAAM,SAAU,EAAK,EAAM,CAC3B,OAAO,EAAI,KAAK,EAAK,EAAK,EAG9B,SAAS,EAAO,EAAQ,EAAQ,CAC5B,IAAK,IAAI,KAAQ,EACT,EAAI,EAAQ,EAAK,GACjB,EAAO,GAAQ,EAAO,IAG9B,OAAO,EAEX,IAAI,EAAmB,wBACnB,EAAoB,wBACpB,EAA+B,gBAC/B,EAAsB,yCACtB,EAAwC,2BAC5C,SAAS,EAAc,EAAS,EAA4C,EAAS,CAGjF,IAAI,EAAmB,EACnB,EAAQ,EAAQ,GAAG,MAAM,EAAoB,CAC7C,IACA,EAAmB,EAAM,GAAG,QAEhC,IAAI,EAAW,uBAAyB,EAAmB,IACvD,EAAgB,IAAI,OAAO,EAAU,IAAI,CACzC,IACA,EAAU,EAAQ,MAAM,EAAE,EAE9B,IAAI,EAAU,EAAQ,QAAS,EAAqB,EAAQ,mBAAoB,EAAsB,EAAQ,oBAC1G,EAAoB,OAAO,GAAY,SACvC,EAAI,EAAQ,OAkBhB,OAjBuB,EAAQ,IAAI,SAAU,EAAG,EAAG,CAe/C,MAbA,GAAI,EAAE,QAAQ,EAAe,KAAK,CAE9B,IAAM,GAAK,IACX,EAAI,EAAE,QAAQ,EAAkB,GAAG,EAGnC,IAAM,EAAI,GAAK,IACf,EAAI,EAAE,QAAQ,EAAmB,GAAG,EAGpC,IACA,EAAI,EAAE,QAAQ,cAAe,SAAU,EAAG,CAAE,OAAO,GAAW,EAE3D,GACT,CAGN,SAAS,EAAuB,EAAS,EAAQ,CAE7C,IAAK,IADD,EAAM,GACD,EAAI,EAAG,EAAI,EAAQ,OAAQ,EAAI,EAAG,IACvC,GAAO,EAAQ,GACX,EAAI,EAAI,IACR,GAAO,EAAO,IAGtB,OAAO,EAEX,SAAS,EAAuB,EAAG,CAC/B,OAAO,EAAI,EAAG,MAAM,EAAI,EAAI,EAAG,SAAS,CAQ5C,SAAS,EAAe,EAAS,CAE7B,IAAI,EAAuB,GAAe,CAKtC,EAAkC,GAAe,CACrD,SAASA,EAAQ,EAAkB,CAE/B,IAAK,IADD,EAAS,EAAE,CACN,EAAK,EAAG,EAAK,UAAU,OAAQ,IACpC,EAAO,EAAK,GAAK,UAAU,GAG/B,GAAI,EAAuB,EAAiB,CAAE,CAC1C,IAAI,EAAU,EAEV,GAA8C,EAAO,KAAOA,GAAW,EAAO,KAAO,IACrF,EAAsC,KAAK,EAAQ,GAAG,EACtD,EAA6B,KAAK,EAAQ,GAAG,CAE7C,EAAQ,EACN,EACA,EACF,EAAgB,EAAM,IAAI,EAAQ,CAWtC,OAVK,IACD,EAAgB,EAAc,EAAS,EAA4C,EAAQ,CAC3F,EAAM,IAAI,EAAS,EAAc,EAGjC,EAAO,SAAW,EACX,EAAc,GAGV,EAAuB,EAAe,EAA6C,EAAO,MAAM,EAAE,CAAG,EAAO,MAK3H,OAAO,EAAe,EAAO,EAAO,EAAE,CAAE,EAAQ,CAAE,GAAoB,EAAE,CAAC,CAAC,CAQlF,OALkB,EAAOA,EAAS,CAC9B,OAAQ,SAAU,EAAK,CACnB,OAAO,EAAc,CAAC,EAAI,CAAE,GAAO,EAAQ,CAAC,IAEnD,CAAC,CAGN,IAAI,EAAiB,EAAe,CAChC,mBAAoB,GACpB,oBAAqB,GACxB,CAAC,CAKF,GAJA,EAAQ,QAAU,EAGlB,EAAQ,QAAU,EACP,IAAW,OAGlB,GAAI,CACA,EAAO,QAAU,EACjB,OAAO,eAAe,EAAgB,aAAc,CAAE,MAAO,GAAM,CAAC,CACpE,EAAe,QAAU,EACzB,EAAe,QAAU,OAEnB,YC1Id,MAAM,EAAwB,EAAA,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFAmGxB,GAAsB,CAClC,QACA,eAAe,KAEgB,MAAO,CACrC,aACA,gBACA,YACK,CACL,GAAM,CAAE,OAAQ,GAAgB,MAAA,EAAA,EAAA,gBAAqB,CACpD,QACA,OAAQ,SACR,OAAQE,EAAAA,EAAE,OAAOA,EAAAA,EAAE,QAAQ,CAAEA,EAAAA,EAAE,QAAQ,CAAC,CACxC,OAAS,EAEN,EAAA,OAAO;MACP,EAAsB;;;MAGtB,EAAa;KALb,EAOH,OAAQ,EAAA,OAAO;wCACsB,EAAc,QAAQ,EAAO;;MAE/D,KAAK,UAAU,EAAY,KAAM,EAAE,CAAC;;KAGvC,CAAC,CAEF,OAAO,GChHI,GAAuB,CACnC,qBAAqB,OACrB,GAAG,KAC0C,CAC7C,IAAM,EAAS,IAAIC,EAAAA,gBAAgB,EAAa,CAgChD,OA9B+B,MAAO,CACrC,aACA,SACA,mBACK,CACL,IAAME,EAA+B,EAAE,CAGjC,EACL,IAAuB,OAAS,EAAgB,EAkBjD,OAhBA,MAAM,QAAQ,IACb,OAAO,KAAK,EAAW,CAAC,IAAI,KAAO,IAAQ,CAC1C,IAAM,EAAQ,EAAW,GAEnB,EAAU,IAAIC,EAAAA,qBAAqB,CACxC,KAAM,EACN,mBAAoB,EACpB,mBAAoB,EACpB,CAAC,CAIF,EAAiB,IAFA,MAAM,EAAO,KAAK,EAAQ,EAEV,gBAAkB,GAClD,CACF,CAEM,IC1BI,GAAyB,CACrC,kBACA,SACA,WAAW,mDAEoB,MAAO,CACrC,aACA,SACA,mBACK,CACL,IAAME,EAA+B,EAAE,CACjC,EAAO,OAAO,KAAK,EAAW,CAC9B,EAAQ,EAAK,IAAK,IAAS,CAAE,KAAM,EAAW,GAAM,EAAE,CAItDC,EAA0C,EAAE,CAElD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,GAAK,IACtC,EAAQ,KAAK,EAAM,MAAM,EAAG,EAAI,IAAU,CAAC,CAG5C,IAAI,EAAW,EAEf,IAAK,IAAM,KAAS,EAAS,CAC5B,IAAM,EAAM,IAAI,IAAI,aAAc,EAAS,CAC3C,EAAI,aAAa,IAAI,cAAe,MAAM,CAC1C,EAAI,aAAa,IAAI,OAAQ,EAAc,CAC3C,EAAI,aAAa,IAAI,KAAM,EAAO,CAElC,IAAM,EAAW,MAAM,MAAM,EAAI,UAAU,CAAE,CAC5C,OAAQ,OACR,QAAS,CACR,4BAA6B,EAC7B,+BAAgC,EAChC,eAAgB,mBAChB,CACD,KAAM,KAAK,UAAU,EAAM,CAC3B,CAAC,CAEF,GAAI,CAAC,EAAS,GAAI,CACjB,IAAM,EAAY,MAAM,EAAS,MAAM,CACvC,MAAU,MACT,+BAA+B,EAAS,OAAO,KAAK,IACpD,CAGF,IAAMC,EAAoC,MAAM,EAAS,MAAM,CAE/D,IAAK,IAAM,KAAU,EAAS,CAC7B,IAAM,EAAM,EAAK,GACjB,EAAiB,GAAO,EAAO,aAAa,IAAI,MAAQ,EAAW,GACnE,KAIF,OAAO,GClCI,GAAyB,CACrC,UACA,UACA,YAAY,UACZ,qBAAqB,GACrB,cAAc,SACiC,CAC/C,IAAM,EAAkB,IAAIC,EAAM,WAAW,EAAS,EAAQ,CAqC9D,OAnC+B,MAAO,CACrC,aACA,SACA,mBACK,CACL,IAAME,EAA+B,EAAE,CACjC,EAAO,OAAO,KAAK,EAAW,CAC9B,EAAQ,EAAK,IAAK,GAAQ,EAAW,GAAK,CAG1C,EAAa,EAAO,aAAa,CACjC,EAAa,EAAc,aAAa,CAExC,EAAU,MAAM,EAAgB,cACrC,EACA,EACA,EACA,CACC,YACA,qBACA,cACA,CACD,CAGK,EAAqB,MAAM,QAAQ,EAAQ,CAAG,EAAU,CAAC,EAAQ,CAEvE,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACrC,IAAM,EAAM,EAAK,GACjB,EAAiB,GAAO,EAAmB,IAAI,MAAQ,EAAW,GAGnE,OAAO,ICtFI,EACZ,GACgB,CAChB,IAAM,EAAY,IAAIC,EAAAA,GAAG,UAAU,EAAQ,CAkB3C,OAhB+B,MAAO,CAAE,aAAY,YAAa,CAChE,IAAME,EAA+B,EAAE,CAYvC,OAVA,MAAM,QAAQ,IACb,OAAO,KAAK,EAAW,CAAC,IAAI,KAAO,IAAQ,CAC1C,IAAM,EAAQ,EAAW,GAEnB,CAAC,GAAe,MAAM,EAAU,UAAU,EAAO,EAAO,CAE9D,EAAiB,GAAO,GACvB,CACF,CAEM"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["outdent","translator: Translator","z","TranslateClient","translator: Translator","translatedOutput: Dictionary","TranslateTextCommand","translator: Translator","translatedOutput: Dictionary","batches: Array<Array<{ text: string }>>","results: AzureTranslationResponse","deepl","translator: Translator","translatedOutput: Dictionary","v2","translator: Translator","translatedOutput: Dictionary"],"sources":["../../../../node_modules/.pnpm/outdent@0.8.0/node_modules/outdent/lib/index.js","../../src/translators/ai.ts","../../src/translators/aws.ts","../../src/translators/azure.ts","../../src/translators/deepl.ts","../../src/translators/google-cloud.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.outdent = void 0;\n// In the absence of a WeakSet or WeakMap implementation, don't break, but don't cache either.\nfunction noop() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n}\nfunction createWeakMap() {\n if (typeof WeakMap !== \"undefined\") {\n return new WeakMap();\n }\n else {\n return fakeSetOrMap();\n }\n}\n/**\n * Creates and returns a no-op implementation of a WeakMap / WeakSet that never stores anything.\n */\nfunction fakeSetOrMap() {\n return {\n add: noop,\n delete: noop,\n get: noop,\n set: noop,\n has: function (k) {\n return false;\n },\n };\n}\n// Safe hasOwnProperty\nvar hop = Object.prototype.hasOwnProperty;\nvar has = function (obj, prop) {\n return hop.call(obj, prop);\n};\n// Copy all own enumerable properties from source to target\nfunction extend(target, source) {\n for (var prop in source) {\n if (has(source, prop)) {\n target[prop] = source[prop];\n }\n }\n return target;\n}\nvar reLeadingNewline = /^[ \\t]*(?:\\r\\n|\\r|\\n)/;\nvar reTrailingNewline = /(?:\\r\\n|\\r|\\n)[ \\t]*$/;\nvar reStartsWithNewlineOrIsEmpty = /^(?:[\\r\\n]|$)/;\nvar reDetectIndentation = /(?:\\r\\n|\\r|\\n)([ \\t]*)(?:[^ \\t\\r\\n]|$)/;\nvar reOnlyWhitespaceWithAtLeastOneNewline = /^[ \\t]*[\\r\\n][ \\t\\r\\n]*$/;\nfunction _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options) {\n // If first interpolated value is a reference to outdent,\n // determine indentation level from the indentation of the interpolated value.\n var indentationLevel = 0;\n var match = strings[0].match(reDetectIndentation);\n if (match) {\n indentationLevel = match[1].length;\n }\n var reSource = \"(\\\\r\\\\n|\\\\r|\\\\n).{0,\" + indentationLevel + \"}\";\n var reMatchIndent = new RegExp(reSource, \"g\");\n if (firstInterpolatedValueSetsIndentationLevel) {\n strings = strings.slice(1);\n }\n var newline = options.newline, trimLeadingNewline = options.trimLeadingNewline, trimTrailingNewline = options.trimTrailingNewline;\n var normalizeNewlines = typeof newline === \"string\";\n var l = strings.length;\n var outdentedStrings = strings.map(function (v, i) {\n // Remove leading indentation from all lines\n v = v.replace(reMatchIndent, \"$1\");\n // Trim a leading newline from the first string\n if (i === 0 && trimLeadingNewline) {\n v = v.replace(reLeadingNewline, \"\");\n }\n // Trim a trailing newline from the last string\n if (i === l - 1 && trimTrailingNewline) {\n v = v.replace(reTrailingNewline, \"\");\n }\n // Normalize newlines\n if (normalizeNewlines) {\n v = v.replace(/\\r\\n|\\n|\\r/g, function (_) { return newline; });\n }\n return v;\n });\n return outdentedStrings;\n}\nfunction concatStringsAndValues(strings, values) {\n var ret = \"\";\n for (var i = 0, l = strings.length; i < l; i++) {\n ret += strings[i];\n if (i < l - 1) {\n ret += values[i];\n }\n }\n return ret;\n}\nfunction isTemplateStringsArray(v) {\n return has(v, \"raw\") && has(v, \"length\");\n}\n/**\n * It is assumed that opts will not change. If this is a problem, clone your options object and pass the clone to\n * makeInstance\n * @param options\n * @return {outdent}\n */\nfunction createInstance(options) {\n /** Cache of pre-processed template literal arrays */\n var arrayAutoIndentCache = createWeakMap();\n /**\n * Cache of pre-processed template literal arrays, where first interpolated value is a reference to outdent,\n * before interpolated values are injected.\n */\n var arrayFirstInterpSetsIndentCache = createWeakMap();\n function outdent(stringsOrOptions) {\n var values = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n values[_i - 1] = arguments[_i];\n }\n /* tslint:enable:no-shadowed-variable */\n if (isTemplateStringsArray(stringsOrOptions)) {\n var strings = stringsOrOptions;\n // Is first interpolated value a reference to outdent, alone on its own line, without any preceding non-whitespace?\n var firstInterpolatedValueSetsIndentationLevel = (values[0] === outdent || values[0] === defaultOutdent) &&\n reOnlyWhitespaceWithAtLeastOneNewline.test(strings[0]) &&\n reStartsWithNewlineOrIsEmpty.test(strings[1]);\n // Perform outdentation\n var cache = firstInterpolatedValueSetsIndentationLevel\n ? arrayFirstInterpSetsIndentCache\n : arrayAutoIndentCache;\n var renderedArray = cache.get(strings);\n if (!renderedArray) {\n renderedArray = _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options);\n cache.set(strings, renderedArray);\n }\n /** If no interpolated values, skip concatenation step */\n if (values.length === 0) {\n return renderedArray[0];\n }\n /** Concatenate string literals with interpolated values */\n var rendered = concatStringsAndValues(renderedArray, firstInterpolatedValueSetsIndentationLevel ? values.slice(1) : values);\n return rendered;\n }\n else {\n // Create and return a new instance of outdent with the given options\n return createInstance(extend(extend({}, options), stringsOrOptions || {}));\n }\n }\n var fullOutdent = extend(outdent, {\n string: function (str) {\n return _outdentArray([str], false, options)[0];\n },\n });\n return fullOutdent;\n}\nvar defaultOutdent = createInstance({\n trimLeadingNewline: true,\n trimTrailingNewline: true,\n});\nexports.outdent = defaultOutdent;\n// Named exports. Simple and preferred.\n// import outdent from 'outdent';\nexports.default = defaultOutdent;\nif (typeof module !== \"undefined\") {\n // In webpack harmony-modules environments, module.exports is read-only,\n // so we fail gracefully.\n try {\n module.exports = defaultOutdent;\n Object.defineProperty(defaultOutdent, \"__esModule\", { value: true });\n defaultOutdent.default = defaultOutdent;\n defaultOutdent.outdent = defaultOutdent;\n }\n catch (e) { }\n}\n//# sourceMappingURL=index.js.map","// Dependencies\nimport { generateObject } from 'ai'\nimport { outdent } from 'outdent'\nimport { z } from 'zod'\n\n// Types\nimport type { LanguageModel } from 'ai'\nimport type { Translator } from '@terai/types'\n\nexport type CreateAiTranslatorOptions = {\n\t/**\n\t * The AI model to use for translation.\n\t * Can be any model from AI SDK providers (@ai-sdk/openai, @ai-sdk/anthropic, @ai-sdk/groq, etc.)\n\t *\n\t * @example\n\t * import { createOpenAI } from '@ai-sdk/openai'\n\t * const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })\n\t * const model = openai('gpt-4o')\n\t * const translator = createAiTranslator({ model })\n\t */\n\tmodel: LanguageModel\n\n\t/**\n\t * Custom system prompt for translation.\n\t * If not provided, a generic prompt will be used that covers most app translation cases.\n\t */\n\tsystemPrompt?: string\n}\n\nconst DEFAULT_SYSTEM_PROMPT = outdent`\n# Expert AI Translator\n\n## Your Role\nYou are an expert translator and localization specialist with deep expertise in software\napplications, user interfaces, and technical documentation. Your translations are accurate,\ncontextually appropriate, and maintain the natural feel of native language.\n\n## Critical Requirements\n\n### 1. Preserve Code Patterns\n- **NEVER** translate template variables (e.g., \\${var}, {var}, %s, %d)\n- **ALWAYS** keep placeholder syntax exactly as provided\n- **MAINTAIN** all escape sequences and special characters\n- **PRESERVE** HTML tags, markdown syntax, and formatting codes\n\n### 2. Translation Quality\n- Use **natural, idiomatic** expressions in the target language\n- Maintain **consistent terminology** throughout all strings\n- Adapt **cultural references** appropriately for the target locale\n- Ensure **grammatical correctness** and proper sentence structure\n\n### 3. Context Awareness\n- **UI Elements**: Keep translations concise for buttons, labels, and menus\n- **Messages**: Maintain appropriate tone (error messages: clear, help text: friendly)\n- **Technical Terms**: Use standard industry terminology when available\n- **Brand Names**: Do not translate proper nouns, product names, or brand names\n\n### 4. Formatting Guidelines\n- **Punctuation**: Follow target language conventions\n- **Capitalization**: Match target language standards (e.g., German nouns)\n- **Numbers & Dates**: Keep placeholders unchanged; format will be handled at runtime\n- **Whitespace**: Preserve spacing around variables and special characters\n\n### 5. Tone & Style\n- **Consistency**: Maintain uniform voice across all translations\n- **Formality**: Match the formality level of the source text\n- **Clarity**: Prioritize understanding over literal translation\n- **Brevity**: Keep translations concise, especially for UI elements\n\n## Output Format\n- Return ONLY a valid JSON object\n- Use the EXACT SAME KEYS as the input (CRITICAL)\n- Do NOT add newlines within string values\n- Do NOT modify, remove, or add keys\n- Do NOT include markdown code blocks or extra formatting\n\n## Examples of What to Preserve\n\n✅ CORRECT:\n- \"Welcome \\${var}\" → \"Bienvenido \\${var}\"\n- \"You have {count} items\" → \"Tienes {count} elementos\"\n- \"Click <strong>here</strong>\" → \"Haz clic <strong>aquí</strong>\"\n\n❌ INCORRECT:\n- \"Welcome \\${var}\" → \"Bienvenido Juan\" (translated variable)\n- \"You have {var} items\" → \"Tienes 3 elementos\" (removed braces)\n- \"Click <strong>here</strong>\" → \"Haz clic **aquí**\" (changed HTML to markdown)`\n\n/**\n * Creates an AI-powered translator using the Vercel AI SDK.\n *\n * This translator uses structured output generation to translate dictionaries\n * while preserving template variables, formatting, and code patterns.\n *\n * @example\n * ```ts\n * import { createAiTranslator } from '@terai/translator/translators'\n * import { createAnthropic } from '@ai-sdk/anthropic'\n *\n * const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY })\n * const translator = createAiTranslator({\n * model: anthropic('claude-3-5-sonnet-20241022'),\n * systemPrompt: 'Custom prompt for my specific use case...'\n * })\n * ```\n */\nexport const createAiTranslator = ({\n\tmodel,\n\tsystemPrompt = DEFAULT_SYSTEM_PROMPT\n}: CreateAiTranslatorOptions): Translator => {\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tprojectLocale,\n\t\tlocale\n\t}) => {\n\t\tconst { object: translation } = await generateObject({\n\t\t\tmodel,\n\t\t\toutput: 'no-schema',\n\t\t\tsystem: !systemPrompt\n\t\t\t\t? DEFAULT_SYSTEM_PROMPT\n\t\t\t\t: outdent`\n\t\t\t\t${DEFAULT_SYSTEM_PROMPT}\n\t\t\t\t\n\t\t\t\t## Additional User System Instructions (highest priority)\n\t\t\t\t${systemPrompt}\n\t\t\t`,\n\t\t\tprompt: outdent`\n\t\t\t\tTranslate the following JSON from locale:\"${projectLocale}\" to locale:\"${locale}\".\n\n\t\t\t\t<target-json>\n\t\t\t\t\t${JSON.stringify(dictionary, null, 2)}\n\t\t\t\t</target-json>\n\t\t\t`\n\t\t})\n\n\t\treturn JSONSchema.parse(translation)\n\t}\n\n\treturn translator\n}\n\nconst JSONSchema = z.record(z.string(), z.string())\n","// Dependencies\nimport {\n\tTranslateClient,\n\tTranslateTextCommand,\n\ttype TranslateClientConfig\n} from '@aws-sdk/client-translate'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateAwsTranslatorOptions = TranslateClientConfig & {\n\t/**\n\t * The source language code (e.g., 'en', 'es', 'fr').\n\t * If not provided, AWS Translate will auto-detect the source language.\n\t * @default 'auto'\n\t */\n\tsourceLanguageCode?: string\n}\n\n/**\n * Creates a translator using AWS Translate.\n *\n * AWS Translate is a neural machine translation service that delivers\n * fast, high-quality, and affordable language translation.\n *\n * @example\n * ```ts\n * import { createAwsTranslator } from '@terai/translator/translators'\n *\n * const translator = createAwsTranslator({\n * region: 'us-east-1',\n * credentials: {\n * accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n * secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY\n * }\n * })\n * ```\n *\n * @example With AWS profile\n * ```ts\n * import { createAwsTranslator } from '@terai/translator/translators'\n * import { fromIni } from '@aws-sdk/credential-providers'\n *\n * const translator = createAwsTranslator({\n * region: 'us-east-1',\n * credentials: fromIni({ profile: 'my-profile' })\n * })\n * ```\n */\nexport const createAwsTranslator = ({\n\tsourceLanguageCode = 'auto',\n\t...clientConfig\n}: CreateAwsTranslatorOptions): Translator => {\n\tconst client = new TranslateClient(clientConfig)\n\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\n\t\t// Use projectLocale as source if not set to auto\n\t\tconst source =\n\t\t\tsourceLanguageCode === 'auto' ? projectLocale : sourceLanguageCode\n\n\t\tawait Promise.all(\n\t\t\tObject.keys(dictionary).map(async (key) => {\n\t\t\t\tconst value = dictionary[key]\n\n\t\t\t\tconst command = new TranslateTextCommand({\n\t\t\t\t\tText: value,\n\t\t\t\t\tSourceLanguageCode: source,\n\t\t\t\t\tTargetLanguageCode: locale\n\t\t\t\t})\n\n\t\t\t\tconst response = await client.send(command)\n\n\t\t\t\ttranslatedOutput[key] = response.TranslatedText || value\n\t\t\t})\n\t\t)\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateAzureTranslatorOptions = {\n\t/**\n\t * Azure Translator subscription key.\n\t */\n\tsubscriptionKey: string\n\n\t/**\n\t * Azure region where the Translator resource is located.\n\t * @example 'eastus', 'westeurope', 'southeastasia'\n\t */\n\tregion: string\n\n\t/**\n\t * Custom endpoint URL. If not provided, uses the global endpoint.\n\t * @default 'https://api.cognitive.microsofttranslator.com'\n\t */\n\tendpoint?: string\n}\n\ntype AzureTranslationResponse = Array<{\n\ttranslations: Array<{\n\t\ttext: string\n\t\tto: string\n\t}>\n}>\n\n/**\n * Creates a translator using Microsoft Azure Translator.\n *\n * Azure Translator is a cloud-based machine translation service\n * that supports 100+ languages.\n *\n * @example\n * ```ts\n * import { createAzureTranslator } from '@terai/translator/translators'\n *\n * const translator = createAzureTranslator({\n * subscriptionKey: process.env.AZURE_TRANSLATOR_KEY,\n * region: 'eastus'\n * })\n * ```\n *\n * @example With custom endpoint\n * ```ts\n * import { createAzureTranslator } from '@terai/translator/translators'\n *\n * const translator = createAzureTranslator({\n * subscriptionKey: process.env.AZURE_TRANSLATOR_KEY,\n * region: 'eastus',\n * endpoint: 'https://my-custom-endpoint.cognitiveservices.azure.com'\n * })\n * ```\n */\nexport const createAzureTranslator = ({\n\tsubscriptionKey,\n\tregion,\n\tendpoint = 'https://api.cognitive.microsofttranslator.com'\n}: CreateAzureTranslatorOptions): Translator => {\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\t\tconst keys = Object.keys(dictionary)\n\t\tconst texts = keys.map((key) => ({ text: dictionary[key] }))\n\n\t\t// Azure Translator API accepts up to 100 texts per request\n\t\tconst batchSize = 100\n\t\tconst batches: Array<Array<{ text: string }>> = []\n\n\t\tfor (let i = 0; i < texts.length; i += batchSize) {\n\t\t\tbatches.push(texts.slice(i, i + batchSize))\n\t\t}\n\n\t\tlet keyIndex = 0\n\n\t\tfor (const batch of batches) {\n\t\t\tconst url = new URL('/translate', endpoint)\n\t\t\turl.searchParams.set('api-version', '3.0')\n\t\t\turl.searchParams.set('from', projectLocale)\n\t\t\turl.searchParams.set('to', locale)\n\n\t\t\tconst response = await fetch(url.toString(), {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Ocp-Apim-Subscription-Key': subscriptionKey,\n\t\t\t\t\t'Ocp-Apim-Subscription-Region': region,\n\t\t\t\t\t'Content-Type': 'application/json'\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(batch)\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorText = await response.text()\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Azure Translator API error: ${response.status} - ${errorText}`\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst results: AzureTranslationResponse = await response.json()\n\n\t\t\tfor (const result of results) {\n\t\t\t\tconst key = keys[keyIndex]\n\t\t\t\ttranslatedOutput[key] = result.translations[0]?.text || dictionary[key]\n\t\t\t\tkeyIndex++\n\t\t\t}\n\t\t}\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport * as deepl from 'deepl-node'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateDeepLTranslatorOptions = {\n\t/**\n\t * DeepL API authentication key.\n\t * Get your key from https://www.deepl.com/pro-api\n\t */\n\tauthKey: string\n\n\t/**\n\t * Additional options for the DeepL Translator.\n\t */\n\toptions?: deepl.TranslatorOptions\n\n\t/**\n\t * Formality preference for translations.\n\t * - 'default': Default formality\n\t * - 'more': More formal language\n\t * - 'less': Less formal language\n\t * - 'prefer_more': Prefer more formal if available\n\t * - 'prefer_less': Prefer less formal if available\n\t * @default 'default'\n\t */\n\tformality?: deepl.Formality\n\n\t/**\n\t * Whether to preserve formatting in translations.\n\t * @default true\n\t */\n\tpreserveFormatting?: boolean\n\n\t/**\n\t * Specify how to handle XML tags in text.\n\t * @default 'xml'\n\t */\n\ttagHandling?: 'xml' | 'html'\n}\n\n/**\n * Creates a translator using DeepL API.\n *\n * DeepL is known for producing high-quality, natural-sounding translations\n * and is often considered one of the best machine translation services available.\n *\n * @example\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY\n * })\n * ```\n *\n * @example With formality preference\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY,\n * formality: 'less' // Use informal language\n * })\n * ```\n *\n * @example With HTML tag handling\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY,\n * tagHandling: 'html',\n * preserveFormatting: true\n * })\n * ```\n */\nexport const createDeepLTranslator = ({\n\tauthKey,\n\toptions,\n\tformality = 'default',\n\tpreserveFormatting = true,\n\ttagHandling = 'xml'\n}: CreateDeepLTranslatorOptions): Translator => {\n\tconst deeplTranslator = new deepl.Translator(authKey, options)\n\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\t\tconst keys = Object.keys(dictionary)\n\t\tconst texts = keys.map((key) => dictionary[key])\n\n\t\t// DeepL uses specific language codes (e.g., 'EN-US' instead of 'en-US')\n\t\tconst targetLang = locale.toUpperCase() as deepl.TargetLanguageCode\n\t\tconst sourceLang = projectLocale.toUpperCase() as deepl.SourceLanguageCode\n\n\t\tconst results = await deeplTranslator.translateText(\n\t\t\ttexts,\n\t\t\tsourceLang,\n\t\t\ttargetLang,\n\t\t\t{\n\t\t\t\tformality,\n\t\t\t\tpreserveFormatting,\n\t\t\t\ttagHandling\n\t\t\t}\n\t\t)\n\n\t\t// Handle both single result and array of results\n\t\tconst translationResults = Array.isArray(results) ? results : [results]\n\n\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\tconst key = keys[i]\n\t\t\ttranslatedOutput[key] = translationResults[i]?.text || dictionary[key]\n\t\t}\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport { v2 } from '@google-cloud/translate'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateGoogleCloudTranslatorOptions = v2.TranslateConfig\n\n/**\n * Creates a translator using Google Cloud Translation API.\n *\n * This translator uses Google Cloud's Neural Machine Translation (NMT)\n * for high-quality translations.\n *\n * @example\n * ```ts\n * import { createGoogleCloudTranslator } from '@terai/translator/translators'\n *\n * const translator = createGoogleCloudTranslator({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT_ID,\n * keyFilename: './google-credentials.json'\n * })\n * ```\n *\n * @example With API key\n * ```ts\n * import { createGoogleCloudTranslator } from '@terai/translator/translators'\n *\n * const translator = createGoogleCloudTranslator({\n * key: process.env.GOOGLE_CLOUD_API_KEY\n * })\n * ```\n */\nexport const createGoogleCloudTranslator = (\n\toptions: CreateGoogleCloudTranslatorOptions\n): Translator => {\n\tconst translate = new v2.Translate(options)\n\n\tconst translator: Translator = async ({ dictionary, locale }) => {\n\t\tconst translatedOutput: Dictionary = {}\n\n\t\tawait Promise.all(\n\t\t\tObject.keys(dictionary).map(async (key) => {\n\t\t\t\tconst value = dictionary[key]\n\n\t\t\t\tconst [translation] = await translate.translate(value, locale)\n\n\t\t\t\ttranslatedOutput[key] = translation\n\t\t\t})\n\t\t)\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
@@ -14,11 +14,7 @@ type CreateAiTranslatorOptions = {
|
|
|
14
14
|
* import { createOpenAI } from '@ai-sdk/openai'
|
|
15
15
|
* const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })
|
|
16
16
|
* const model = openai('gpt-4o')
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* import { createGroq } from '@ai-sdk/groq'
|
|
20
|
-
* const groq = createGroq({ apiKey: process.env.GROQ_API_KEY })
|
|
21
|
-
* const model = groq('llama-3.3-70b-versatile')
|
|
17
|
+
* const translator = createAiTranslator({ model })
|
|
22
18
|
*/
|
|
23
19
|
model: LanguageModel;
|
|
24
20
|
/**
|
|
@@ -36,28 +32,6 @@ type CreateAiTranslatorOptions = {
|
|
|
36
32
|
* @example
|
|
37
33
|
* ```ts
|
|
38
34
|
* import { createAiTranslator } from '@terai/translator/translators'
|
|
39
|
-
* import { createOpenAI } from '@ai-sdk/openai'
|
|
40
|
-
*
|
|
41
|
-
* const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })
|
|
42
|
-
* const translator = createAiTranslator({
|
|
43
|
-
* model: openai('gpt-4o')
|
|
44
|
-
* })
|
|
45
|
-
* ```
|
|
46
|
-
*
|
|
47
|
-
* @example With Groq
|
|
48
|
-
* ```ts
|
|
49
|
-
* import { createAiTranslator } from '@terai/translator/translators'
|
|
50
|
-
* import { createGroq } from '@ai-sdk/groq'
|
|
51
|
-
*
|
|
52
|
-
* const groq = createGroq({ apiKey: process.env.GROQ_API_KEY })
|
|
53
|
-
* const translator = createAiTranslator({
|
|
54
|
-
* model: groq('llama-3.3-70b-versatile')
|
|
55
|
-
* })
|
|
56
|
-
* ```
|
|
57
|
-
*
|
|
58
|
-
* @example With custom system prompt
|
|
59
|
-
* ```ts
|
|
60
|
-
* import { createAiTranslator } from '@terai/translator/translators'
|
|
61
35
|
* import { createAnthropic } from '@ai-sdk/anthropic'
|
|
62
36
|
*
|
|
63
37
|
* const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/translators/ai.ts","../../src/translators/aws.ts","../../src/translators/azure.ts","../../src/translators/deepl.ts","../../src/translators/google-cloud.ts"],"sourcesContent":[],"mappings":";;;;;;;KASY,yBAAA;;;;;AAAZ;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/translators/ai.ts","../../src/translators/aws.ts","../../src/translators/azure.ts","../../src/translators/deepl.ts","../../src/translators/google-cloud.ts"],"sourcesContent":[],"mappings":";;;;;;;KASY,yBAAA;;;;;AAAZ;AAiGA;;;;;EAiCC,KAAA,EAvHO,aAuHP;;;;ACjID;EAuCa,YAAA,CAAA,EAAA,MAAA;CAAuB;;;;;;;AC9CpC;AAqDA;;;;;;;;;;AClDA;AAwEa,cH4BA,kBGiBZ,EAAA,CAAA;EAAA,KAAA;EAAA;AAAA,CAAA,EHdE,yBGcF,EAAA,GHd8B,UGc9B;;;KFjHW,0BAAA,GAA6B;;;;;ADDzC;EAiGa,kBAAA,CAAA,EAiCZ,MAAA;CAjCkC;;;;;;;;AChGnC;AAuCA;;;;;;;;AC9CA;AAqDA;;;;;;;;;;AClDA;AAwEA;;AAAsC,cF7BzB,mBE6ByB,EAAA,CAAA;EAAA,kBAAA;EAAA,GAAA;AAAA,CAAA,EF1BnC,0BE0BmC,EAAA,GF1BN,UE0BM;;;KD3E1B,4BAAA;;;;;;AFMZ;AAiGA;;EAAmC,MAAA,EAAA,MAAA;EAGhC;;;;;;ACnGH;AAuCA;;;;;;;;AC9CA;AAqDA;;;;;;;;;;AClDA;AAwEA;;;;;;AAMG,cD5BU,qBC4BV,EAAA,CAAA;EAAA,eAAA;EAAA,MAAA;EAAA;AAAA,CAAA,EDxBA,4BCwBA,EAAA,GDxB+B,UCwB/B;;;KA9ES,4BAAA;;;;;EHGA,OAAA,EAAA,MAAA;EAiGC;;;EAGV,OAAA,CAAA,EG7FQ,KAAA,CAAM,iBH6Fd;EAA4B;;;;;ACnG/B;AAuCA;;;EAGgC,SAAA,CAAA,EEzBnB,KAAA,CAAM,SFyBa;EAkC/B;;;;ECnFW,kBAAA,CAAA,EAAA,OAAA;EAqDC;;;;EAIV,WAAA,CAAA,EAAA,KAAA,GAAA,MAAA;CAA+B;;;;;ACtDlC;AAwEA;;;;;;;;;;;;ACxEA;AA2BA;;;;;;;;;;;;;;;;;;cD6Ca;;;;;;GAMV,iCAA+B;;;KC9EtB,kCAAA,GAAqC,EAAA,CAAG;;;;;AJGpD;AAiGA;;;;;;;;;AChGA;AAuCA;;;;;;;;AC9CA;AAqDA;AAAsC,cEvBzB,2BFuByB,EAAA,CAAA,OAAA,EEtB5B,kCFsB4B,EAAA,GErBnC,UFqBmC"}
|
|
@@ -14,11 +14,7 @@ type CreateAiTranslatorOptions = {
|
|
|
14
14
|
* import { createOpenAI } from '@ai-sdk/openai'
|
|
15
15
|
* const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })
|
|
16
16
|
* const model = openai('gpt-4o')
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* import { createGroq } from '@ai-sdk/groq'
|
|
20
|
-
* const groq = createGroq({ apiKey: process.env.GROQ_API_KEY })
|
|
21
|
-
* const model = groq('llama-3.3-70b-versatile')
|
|
17
|
+
* const translator = createAiTranslator({ model })
|
|
22
18
|
*/
|
|
23
19
|
model: LanguageModel;
|
|
24
20
|
/**
|
|
@@ -36,28 +32,6 @@ type CreateAiTranslatorOptions = {
|
|
|
36
32
|
* @example
|
|
37
33
|
* ```ts
|
|
38
34
|
* import { createAiTranslator } from '@terai/translator/translators'
|
|
39
|
-
* import { createOpenAI } from '@ai-sdk/openai'
|
|
40
|
-
*
|
|
41
|
-
* const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })
|
|
42
|
-
* const translator = createAiTranslator({
|
|
43
|
-
* model: openai('gpt-4o')
|
|
44
|
-
* })
|
|
45
|
-
* ```
|
|
46
|
-
*
|
|
47
|
-
* @example With Groq
|
|
48
|
-
* ```ts
|
|
49
|
-
* import { createAiTranslator } from '@terai/translator/translators'
|
|
50
|
-
* import { createGroq } from '@ai-sdk/groq'
|
|
51
|
-
*
|
|
52
|
-
* const groq = createGroq({ apiKey: process.env.GROQ_API_KEY })
|
|
53
|
-
* const translator = createAiTranslator({
|
|
54
|
-
* model: groq('llama-3.3-70b-versatile')
|
|
55
|
-
* })
|
|
56
|
-
* ```
|
|
57
|
-
*
|
|
58
|
-
* @example With custom system prompt
|
|
59
|
-
* ```ts
|
|
60
|
-
* import { createAiTranslator } from '@terai/translator/translators'
|
|
61
35
|
* import { createAnthropic } from '@ai-sdk/anthropic'
|
|
62
36
|
*
|
|
63
37
|
* const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/translators/ai.ts","../../src/translators/aws.ts","../../src/translators/azure.ts","../../src/translators/deepl.ts","../../src/translators/google-cloud.ts"],"sourcesContent":[],"mappings":";;;;;;;KASY,yBAAA;;;;;AAAZ;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/translators/ai.ts","../../src/translators/aws.ts","../../src/translators/azure.ts","../../src/translators/deepl.ts","../../src/translators/google-cloud.ts"],"sourcesContent":[],"mappings":";;;;;;;KASY,yBAAA;;;;;AAAZ;AAiGA;;;;;EAiCC,KAAA,EAvHO,aAuHP;;;;ACjID;EAuCa,YAAA,CAAA,EAAA,MAAA;CAAuB;;;;;;;AC9CpC;AAqDA;;;;;;;;;;AClDA;AAwEa,cH4BA,kBGiBZ,EAAA,CAAA;EAAA,KAAA;EAAA;AAAA,CAAA,EHdE,yBGcF,EAAA,GHd8B,UGc9B;;;KFjHW,0BAAA,GAA6B;;;;;ADDzC;EAiGa,kBAAA,CAAA,EAiCZ,MAAA;CAjCkC;;;;;;;;AChGnC;AAuCA;;;;;;;;AC9CA;AAqDA;;;;;;;;;;AClDA;AAwEA;;AAAsC,cF7BzB,mBE6ByB,EAAA,CAAA;EAAA,kBAAA;EAAA,GAAA;AAAA,CAAA,EF1BnC,0BE0BmC,EAAA,GF1BN,UE0BM;;;KD3E1B,4BAAA;;;;;;AFMZ;AAiGA;;EAAmC,MAAA,EAAA,MAAA;EAGhC;;;;;;ACnGH;AAuCA;;;;;;;;AC9CA;AAqDA;;;;;;;;;;AClDA;AAwEA;;;;;;AAMG,cD5BU,qBC4BV,EAAA,CAAA;EAAA,eAAA;EAAA,MAAA;EAAA;AAAA,CAAA,EDxBA,4BCwBA,EAAA,GDxB+B,UCwB/B;;;KA9ES,4BAAA;;;;;EHGA,OAAA,EAAA,MAAA;EAiGC;;;EAGV,OAAA,CAAA,EG7FQ,KAAA,CAAM,iBH6Fd;EAA4B;;;;;ACnG/B;AAuCA;;;EAGgC,SAAA,CAAA,EEzBnB,KAAA,CAAM,SFyBa;EAkC/B;;;;ECnFW,kBAAA,CAAA,EAAA,OAAA;EAqDC;;;;EAIV,WAAA,CAAA,EAAA,KAAA,GAAA,MAAA;CAA+B;;;;;ACtDlC;AAwEA;;;;;;;;;;;;ACxEA;AA2BA;;;;;;;;;;;;;;;;;;cD6Ca;;;;;;GAMV,iCAA+B;;;KC9EtB,kCAAA,GAAqC,EAAA,CAAG;;;;;AJGpD;AAiGA;;;;;;;;;AChGA;AAuCA;;;;;;;;AC9CA;AAqDA;AAAsC,cEvBzB,2BFuByB,EAAA,CAAA,OAAA,EEtB5B,kCFsB4B,EAAA,GErBnC,UFqBmC"}
|
|
@@ -40,7 +40,7 @@ contextually appropriate, and maintain the natural feel of native language.
|
|
|
40
40
|
|
|
41
41
|
## Output Format
|
|
42
42
|
- Return ONLY a valid JSON object
|
|
43
|
-
- Use the EXACT SAME KEYS as the input
|
|
43
|
+
- Use the EXACT SAME KEYS as the input (CRITICAL)
|
|
44
44
|
- Do NOT add newlines within string values
|
|
45
45
|
- Do NOT modify, remove, or add keys
|
|
46
46
|
- Do NOT include markdown code blocks or extra formatting
|
|
@@ -55,15 +55,16 @@ contextually appropriate, and maintain the natural feel of native language.
|
|
|
55
55
|
❌ INCORRECT:
|
|
56
56
|
- "Welcome \${var}" → "Bienvenido Juan" (translated variable)
|
|
57
57
|
- "You have {var} items" → "Tienes 3 elementos" (removed braces)
|
|
58
|
-
- "Click <strong>here</strong>" → "Haz clic **aquí**" (changed HTML to markdown)`,c=({model:
|
|
58
|
+
- "Click <strong>here</strong>" → "Haz clic **aquí**" (changed HTML to markdown)`,c=({model:t,systemPrompt:n=s})=>async({dictionary:r,projectLocale:i,locale:a})=>{let{object:c}=await e({model:t,output:`no-schema`,system:n?o.outdent`
|
|
59
59
|
${s}
|
|
60
60
|
|
|
61
|
-
##
|
|
62
|
-
${
|
|
61
|
+
## Additional User System Instructions (highest priority)
|
|
62
|
+
${n}
|
|
63
63
|
`:s,prompt:o.outdent`
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
Translate the following JSON from locale:"${i}" to locale:"${a}".
|
|
65
|
+
|
|
66
|
+
<target-json>
|
|
67
|
+
${JSON.stringify(r,null,2)}
|
|
68
|
+
</target-json>
|
|
69
|
+
`});return l.parse(c)},l=t.record(t.string(),t.string()),u=({sourceLanguageCode:e=`auto`,...t})=>{let i=new n(t);return async({dictionary:t,locale:n,projectLocale:a})=>{let o={},s=e===`auto`?a:e;return await Promise.all(Object.keys(t).map(async e=>{let a=t[e],c=new r({Text:a,SourceLanguageCode:s,TargetLanguageCode:n});o[e]=(await i.send(c)).TranslatedText||a})),o}},d=({subscriptionKey:e,region:t,endpoint:n=`https://api.cognitive.microsofttranslator.com`})=>async({dictionary:r,locale:i,projectLocale:a})=>{let o={},s=Object.keys(r),c=s.map(e=>({text:r[e]})),l=[];for(let e=0;e<c.length;e+=100)l.push(c.slice(e,e+100));let u=0;for(let c of l){let l=new URL(`/translate`,n);l.searchParams.set(`api-version`,`3.0`),l.searchParams.set(`from`,a),l.searchParams.set(`to`,i);let d=await fetch(l.toString(),{method:`POST`,headers:{"Ocp-Apim-Subscription-Key":e,"Ocp-Apim-Subscription-Region":t,"Content-Type":`application/json`},body:JSON.stringify(c)});if(!d.ok){let e=await d.text();throw Error(`Azure Translator API error: ${d.status} - ${e}`)}let f=await d.json();for(let e of f){let t=s[u];o[t]=e.translations[0]?.text||r[t],u++}}return o},f=({authKey:e,options:t,formality:n=`default`,preserveFormatting:r=!0,tagHandling:a=`xml`})=>{let o=new i.Translator(e,t);return async({dictionary:e,locale:t,projectLocale:i})=>{let s={},c=Object.keys(e),l=c.map(t=>e[t]),u=t.toUpperCase(),d=i.toUpperCase(),f=await o.translateText(l,d,u,{formality:n,preserveFormatting:r,tagHandling:a}),p=Array.isArray(f)?f:[f];for(let t=0;t<c.length;t++){let n=c[t];s[n]=p[t]?.text||e[n]}return s}},p=e=>{let t=new a.Translate(e);return async({dictionary:e,locale:n})=>{let r={};return await Promise.all(Object.keys(e).map(async i=>{let a=e[i],[o]=await t.translate(a,n);r[i]=o})),r}};export{c as createAiTranslator,u as createAwsTranslator,d as createAzureTranslator,f as createDeepLTranslator,p as createGoogleCloudTranslator};
|
|
69
70
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["outdent","translator: Translator","translator: Translator","translatedOutput: Dictionary","translator: Translator","translatedOutput: Dictionary","batches: Array<Array<{ text: string }>>","results: AzureTranslationResponse","translator: Translator","translatedOutput: Dictionary","translator: Translator","translatedOutput: Dictionary"],"sources":["../../../../node_modules/.pnpm/outdent@0.8.0/node_modules/outdent/lib/index.js","../../src/translators/ai.ts","../../src/translators/aws.ts","../../src/translators/azure.ts","../../src/translators/deepl.ts","../../src/translators/google-cloud.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.outdent = void 0;\n// In the absence of a WeakSet or WeakMap implementation, don't break, but don't cache either.\nfunction noop() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n}\nfunction createWeakMap() {\n if (typeof WeakMap !== \"undefined\") {\n return new WeakMap();\n }\n else {\n return fakeSetOrMap();\n }\n}\n/**\n * Creates and returns a no-op implementation of a WeakMap / WeakSet that never stores anything.\n */\nfunction fakeSetOrMap() {\n return {\n add: noop,\n delete: noop,\n get: noop,\n set: noop,\n has: function (k) {\n return false;\n },\n };\n}\n// Safe hasOwnProperty\nvar hop = Object.prototype.hasOwnProperty;\nvar has = function (obj, prop) {\n return hop.call(obj, prop);\n};\n// Copy all own enumerable properties from source to target\nfunction extend(target, source) {\n for (var prop in source) {\n if (has(source, prop)) {\n target[prop] = source[prop];\n }\n }\n return target;\n}\nvar reLeadingNewline = /^[ \\t]*(?:\\r\\n|\\r|\\n)/;\nvar reTrailingNewline = /(?:\\r\\n|\\r|\\n)[ \\t]*$/;\nvar reStartsWithNewlineOrIsEmpty = /^(?:[\\r\\n]|$)/;\nvar reDetectIndentation = /(?:\\r\\n|\\r|\\n)([ \\t]*)(?:[^ \\t\\r\\n]|$)/;\nvar reOnlyWhitespaceWithAtLeastOneNewline = /^[ \\t]*[\\r\\n][ \\t\\r\\n]*$/;\nfunction _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options) {\n // If first interpolated value is a reference to outdent,\n // determine indentation level from the indentation of the interpolated value.\n var indentationLevel = 0;\n var match = strings[0].match(reDetectIndentation);\n if (match) {\n indentationLevel = match[1].length;\n }\n var reSource = \"(\\\\r\\\\n|\\\\r|\\\\n).{0,\" + indentationLevel + \"}\";\n var reMatchIndent = new RegExp(reSource, \"g\");\n if (firstInterpolatedValueSetsIndentationLevel) {\n strings = strings.slice(1);\n }\n var newline = options.newline, trimLeadingNewline = options.trimLeadingNewline, trimTrailingNewline = options.trimTrailingNewline;\n var normalizeNewlines = typeof newline === \"string\";\n var l = strings.length;\n var outdentedStrings = strings.map(function (v, i) {\n // Remove leading indentation from all lines\n v = v.replace(reMatchIndent, \"$1\");\n // Trim a leading newline from the first string\n if (i === 0 && trimLeadingNewline) {\n v = v.replace(reLeadingNewline, \"\");\n }\n // Trim a trailing newline from the last string\n if (i === l - 1 && trimTrailingNewline) {\n v = v.replace(reTrailingNewline, \"\");\n }\n // Normalize newlines\n if (normalizeNewlines) {\n v = v.replace(/\\r\\n|\\n|\\r/g, function (_) { return newline; });\n }\n return v;\n });\n return outdentedStrings;\n}\nfunction concatStringsAndValues(strings, values) {\n var ret = \"\";\n for (var i = 0, l = strings.length; i < l; i++) {\n ret += strings[i];\n if (i < l - 1) {\n ret += values[i];\n }\n }\n return ret;\n}\nfunction isTemplateStringsArray(v) {\n return has(v, \"raw\") && has(v, \"length\");\n}\n/**\n * It is assumed that opts will not change. If this is a problem, clone your options object and pass the clone to\n * makeInstance\n * @param options\n * @return {outdent}\n */\nfunction createInstance(options) {\n /** Cache of pre-processed template literal arrays */\n var arrayAutoIndentCache = createWeakMap();\n /**\n * Cache of pre-processed template literal arrays, where first interpolated value is a reference to outdent,\n * before interpolated values are injected.\n */\n var arrayFirstInterpSetsIndentCache = createWeakMap();\n function outdent(stringsOrOptions) {\n var values = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n values[_i - 1] = arguments[_i];\n }\n /* tslint:enable:no-shadowed-variable */\n if (isTemplateStringsArray(stringsOrOptions)) {\n var strings = stringsOrOptions;\n // Is first interpolated value a reference to outdent, alone on its own line, without any preceding non-whitespace?\n var firstInterpolatedValueSetsIndentationLevel = (values[0] === outdent || values[0] === defaultOutdent) &&\n reOnlyWhitespaceWithAtLeastOneNewline.test(strings[0]) &&\n reStartsWithNewlineOrIsEmpty.test(strings[1]);\n // Perform outdentation\n var cache = firstInterpolatedValueSetsIndentationLevel\n ? arrayFirstInterpSetsIndentCache\n : arrayAutoIndentCache;\n var renderedArray = cache.get(strings);\n if (!renderedArray) {\n renderedArray = _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options);\n cache.set(strings, renderedArray);\n }\n /** If no interpolated values, skip concatenation step */\n if (values.length === 0) {\n return renderedArray[0];\n }\n /** Concatenate string literals with interpolated values */\n var rendered = concatStringsAndValues(renderedArray, firstInterpolatedValueSetsIndentationLevel ? values.slice(1) : values);\n return rendered;\n }\n else {\n // Create and return a new instance of outdent with the given options\n return createInstance(extend(extend({}, options), stringsOrOptions || {}));\n }\n }\n var fullOutdent = extend(outdent, {\n string: function (str) {\n return _outdentArray([str], false, options)[0];\n },\n });\n return fullOutdent;\n}\nvar defaultOutdent = createInstance({\n trimLeadingNewline: true,\n trimTrailingNewline: true,\n});\nexports.outdent = defaultOutdent;\n// Named exports. Simple and preferred.\n// import outdent from 'outdent';\nexports.default = defaultOutdent;\nif (typeof module !== \"undefined\") {\n // In webpack harmony-modules environments, module.exports is read-only,\n // so we fail gracefully.\n try {\n module.exports = defaultOutdent;\n Object.defineProperty(defaultOutdent, \"__esModule\", { value: true });\n defaultOutdent.default = defaultOutdent;\n defaultOutdent.outdent = defaultOutdent;\n }\n catch (e) { }\n}\n//# sourceMappingURL=index.js.map","// Dependencies\nimport { generateObject } from 'ai'\nimport { outdent } from 'outdent'\nimport { z } from 'zod'\n\n// Types\nimport type { LanguageModel } from 'ai'\nimport type { Translator } from '@terai/types'\n\nexport type CreateAiTranslatorOptions = {\n\t/**\n\t * The AI model to use for translation.\n\t * Can be any model from AI SDK providers (@ai-sdk/openai, @ai-sdk/anthropic, @ai-sdk/groq, etc.)\n\t *\n\t * @example\n\t * import { createOpenAI } from '@ai-sdk/openai'\n\t * const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })\n\t * const model = openai('gpt-4o')\n\t *\n\t * @example\n\t * import { createGroq } from '@ai-sdk/groq'\n\t * const groq = createGroq({ apiKey: process.env.GROQ_API_KEY })\n\t * const model = groq('llama-3.3-70b-versatile')\n\t */\n\tmodel: LanguageModel\n\n\t/**\n\t * Custom system prompt for translation.\n\t * If not provided, a generic prompt will be used that covers most app translation cases.\n\t */\n\tsystemPrompt?: string\n}\n\nconst DEFAULT_SYSTEM_PROMPT = outdent`\n# Expert AI Translator\n\n## Your Role\nYou are an expert translator and localization specialist with deep expertise in software\napplications, user interfaces, and technical documentation. Your translations are accurate,\ncontextually appropriate, and maintain the natural feel of native language.\n\n## Critical Requirements\n\n### 1. Preserve Code Patterns\n- **NEVER** translate template variables (e.g., \\${var}, {var}, %s, %d)\n- **ALWAYS** keep placeholder syntax exactly as provided\n- **MAINTAIN** all escape sequences and special characters\n- **PRESERVE** HTML tags, markdown syntax, and formatting codes\n\n### 2. Translation Quality\n- Use **natural, idiomatic** expressions in the target language\n- Maintain **consistent terminology** throughout all strings\n- Adapt **cultural references** appropriately for the target locale\n- Ensure **grammatical correctness** and proper sentence structure\n\n### 3. Context Awareness\n- **UI Elements**: Keep translations concise for buttons, labels, and menus\n- **Messages**: Maintain appropriate tone (error messages: clear, help text: friendly)\n- **Technical Terms**: Use standard industry terminology when available\n- **Brand Names**: Do not translate proper nouns, product names, or brand names\n\n### 4. Formatting Guidelines\n- **Punctuation**: Follow target language conventions\n- **Capitalization**: Match target language standards (e.g., German nouns)\n- **Numbers & Dates**: Keep placeholders unchanged; format will be handled at runtime\n- **Whitespace**: Preserve spacing around variables and special characters\n\n### 5. Tone & Style\n- **Consistency**: Maintain uniform voice across all translations\n- **Formality**: Match the formality level of the source text\n- **Clarity**: Prioritize understanding over literal translation\n- **Brevity**: Keep translations concise, especially for UI elements\n\n## Output Format\n- Return ONLY a valid JSON object\n- Use the EXACT SAME KEYS as the input\n- Do NOT add newlines within string values\n- Do NOT modify, remove, or add keys\n- Do NOT include markdown code blocks or extra formatting\n\n## Examples of What to Preserve\n\n✅ CORRECT:\n- \"Welcome \\${var}\" → \"Bienvenido \\${var}\"\n- \"You have {count} items\" → \"Tienes {count} elementos\"\n- \"Click <strong>here</strong>\" → \"Haz clic <strong>aquí</strong>\"\n\n❌ INCORRECT:\n- \"Welcome \\${var}\" → \"Bienvenido Juan\" (translated variable)\n- \"You have {var} items\" → \"Tienes 3 elementos\" (removed braces)\n- \"Click <strong>here</strong>\" → \"Haz clic **aquí**\" (changed HTML to markdown)`\n\n/**\n * Creates an AI-powered translator using the Vercel AI SDK.\n *\n * This translator uses structured output generation to translate dictionaries\n * while preserving template variables, formatting, and code patterns.\n *\n * @example\n * ```ts\n * import { createAiTranslator } from '@terai/translator/translators'\n * import { createOpenAI } from '@ai-sdk/openai'\n *\n * const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })\n * const translator = createAiTranslator({\n * model: openai('gpt-4o')\n * })\n * ```\n *\n * @example With Groq\n * ```ts\n * import { createAiTranslator } from '@terai/translator/translators'\n * import { createGroq } from '@ai-sdk/groq'\n *\n * const groq = createGroq({ apiKey: process.env.GROQ_API_KEY })\n * const translator = createAiTranslator({\n * model: groq('llama-3.3-70b-versatile')\n * })\n * ```\n *\n * @example With custom system prompt\n * ```ts\n * import { createAiTranslator } from '@terai/translator/translators'\n * import { createAnthropic } from '@ai-sdk/anthropic'\n *\n * const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY })\n * const translator = createAiTranslator({\n * model: anthropic('claude-3-5-sonnet-20241022'),\n * systemPrompt: 'Custom prompt for my specific use case...'\n * })\n * ```\n */\nexport const createAiTranslator = ({\n\tmodel,\n\tsystemPrompt = DEFAULT_SYSTEM_PROMPT\n}: CreateAiTranslatorOptions): Translator => {\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tprojectLocale,\n\t\tlocale\n\t}) => {\n\t\tconst { object: translation } = await generateObject({\n\t\t\tmodel,\n\t\t\toutput: 'object',\n\t\t\tschema: z.record(z.string(), z.string()),\n\t\t\tsystem: !systemPrompt\n\t\t\t\t? DEFAULT_SYSTEM_PROMPT\n\t\t\t\t: outdent`\n\t\t\t\t${DEFAULT_SYSTEM_PROMPT}\n\t\t\t\t\n\t\t\t\t## Additonal User System Instructions (highest priority)\n\t\t\t\t${systemPrompt}\n\t\t\t`,\n\t\t\tprompt: outdent`\n\t\t\tTranslate the following JSON from \"${projectLocale}\" to \"${locale}\".\n\t\t\t<target-json>\n\t\t\t\t${JSON.stringify(dictionary, null, 2)}\n\t\t\t</target-json>\n\t\t\t`\n\t\t})\n\n\t\treturn translation\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport {\n\tTranslateClient,\n\tTranslateTextCommand,\n\ttype TranslateClientConfig\n} from '@aws-sdk/client-translate'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateAwsTranslatorOptions = TranslateClientConfig & {\n\t/**\n\t * The source language code (e.g., 'en', 'es', 'fr').\n\t * If not provided, AWS Translate will auto-detect the source language.\n\t * @default 'auto'\n\t */\n\tsourceLanguageCode?: string\n}\n\n/**\n * Creates a translator using AWS Translate.\n *\n * AWS Translate is a neural machine translation service that delivers\n * fast, high-quality, and affordable language translation.\n *\n * @example\n * ```ts\n * import { createAwsTranslator } from '@terai/translator/translators'\n *\n * const translator = createAwsTranslator({\n * region: 'us-east-1',\n * credentials: {\n * accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n * secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY\n * }\n * })\n * ```\n *\n * @example With AWS profile\n * ```ts\n * import { createAwsTranslator } from '@terai/translator/translators'\n * import { fromIni } from '@aws-sdk/credential-providers'\n *\n * const translator = createAwsTranslator({\n * region: 'us-east-1',\n * credentials: fromIni({ profile: 'my-profile' })\n * })\n * ```\n */\nexport const createAwsTranslator = ({\n\tsourceLanguageCode = 'auto',\n\t...clientConfig\n}: CreateAwsTranslatorOptions): Translator => {\n\tconst client = new TranslateClient(clientConfig)\n\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\n\t\t// Use projectLocale as source if not set to auto\n\t\tconst source =\n\t\t\tsourceLanguageCode === 'auto' ? projectLocale : sourceLanguageCode\n\n\t\tawait Promise.all(\n\t\t\tObject.keys(dictionary).map(async (key) => {\n\t\t\t\tconst value = dictionary[key]\n\n\t\t\t\tconst command = new TranslateTextCommand({\n\t\t\t\t\tText: value,\n\t\t\t\t\tSourceLanguageCode: source,\n\t\t\t\t\tTargetLanguageCode: locale\n\t\t\t\t})\n\n\t\t\t\tconst response = await client.send(command)\n\n\t\t\t\ttranslatedOutput[key] = response.TranslatedText || value\n\t\t\t})\n\t\t)\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateAzureTranslatorOptions = {\n\t/**\n\t * Azure Translator subscription key.\n\t */\n\tsubscriptionKey: string\n\n\t/**\n\t * Azure region where the Translator resource is located.\n\t * @example 'eastus', 'westeurope', 'southeastasia'\n\t */\n\tregion: string\n\n\t/**\n\t * Custom endpoint URL. If not provided, uses the global endpoint.\n\t * @default 'https://api.cognitive.microsofttranslator.com'\n\t */\n\tendpoint?: string\n}\n\ntype AzureTranslationResponse = Array<{\n\ttranslations: Array<{\n\t\ttext: string\n\t\tto: string\n\t}>\n}>\n\n/**\n * Creates a translator using Microsoft Azure Translator.\n *\n * Azure Translator is a cloud-based machine translation service\n * that supports 100+ languages.\n *\n * @example\n * ```ts\n * import { createAzureTranslator } from '@terai/translator/translators'\n *\n * const translator = createAzureTranslator({\n * subscriptionKey: process.env.AZURE_TRANSLATOR_KEY,\n * region: 'eastus'\n * })\n * ```\n *\n * @example With custom endpoint\n * ```ts\n * import { createAzureTranslator } from '@terai/translator/translators'\n *\n * const translator = createAzureTranslator({\n * subscriptionKey: process.env.AZURE_TRANSLATOR_KEY,\n * region: 'eastus',\n * endpoint: 'https://my-custom-endpoint.cognitiveservices.azure.com'\n * })\n * ```\n */\nexport const createAzureTranslator = ({\n\tsubscriptionKey,\n\tregion,\n\tendpoint = 'https://api.cognitive.microsofttranslator.com'\n}: CreateAzureTranslatorOptions): Translator => {\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\t\tconst keys = Object.keys(dictionary)\n\t\tconst texts = keys.map((key) => ({ text: dictionary[key] }))\n\n\t\t// Azure Translator API accepts up to 100 texts per request\n\t\tconst batchSize = 100\n\t\tconst batches: Array<Array<{ text: string }>> = []\n\n\t\tfor (let i = 0; i < texts.length; i += batchSize) {\n\t\t\tbatches.push(texts.slice(i, i + batchSize))\n\t\t}\n\n\t\tlet keyIndex = 0\n\n\t\tfor (const batch of batches) {\n\t\t\tconst url = new URL('/translate', endpoint)\n\t\t\turl.searchParams.set('api-version', '3.0')\n\t\t\turl.searchParams.set('from', projectLocale)\n\t\t\turl.searchParams.set('to', locale)\n\n\t\t\tconst response = await fetch(url.toString(), {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Ocp-Apim-Subscription-Key': subscriptionKey,\n\t\t\t\t\t'Ocp-Apim-Subscription-Region': region,\n\t\t\t\t\t'Content-Type': 'application/json'\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(batch)\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorText = await response.text()\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Azure Translator API error: ${response.status} - ${errorText}`\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst results: AzureTranslationResponse = await response.json()\n\n\t\t\tfor (const result of results) {\n\t\t\t\tconst key = keys[keyIndex]\n\t\t\t\ttranslatedOutput[key] = result.translations[0]?.text || dictionary[key]\n\t\t\t\tkeyIndex++\n\t\t\t}\n\t\t}\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport * as deepl from 'deepl-node'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateDeepLTranslatorOptions = {\n\t/**\n\t * DeepL API authentication key.\n\t * Get your key from https://www.deepl.com/pro-api\n\t */\n\tauthKey: string\n\n\t/**\n\t * Additional options for the DeepL Translator.\n\t */\n\toptions?: deepl.TranslatorOptions\n\n\t/**\n\t * Formality preference for translations.\n\t * - 'default': Default formality\n\t * - 'more': More formal language\n\t * - 'less': Less formal language\n\t * - 'prefer_more': Prefer more formal if available\n\t * - 'prefer_less': Prefer less formal if available\n\t * @default 'default'\n\t */\n\tformality?: deepl.Formality\n\n\t/**\n\t * Whether to preserve formatting in translations.\n\t * @default true\n\t */\n\tpreserveFormatting?: boolean\n\n\t/**\n\t * Specify how to handle XML tags in text.\n\t * @default 'xml'\n\t */\n\ttagHandling?: 'xml' | 'html'\n}\n\n/**\n * Creates a translator using DeepL API.\n *\n * DeepL is known for producing high-quality, natural-sounding translations\n * and is often considered one of the best machine translation services available.\n *\n * @example\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY\n * })\n * ```\n *\n * @example With formality preference\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY,\n * formality: 'less' // Use informal language\n * })\n * ```\n *\n * @example With HTML tag handling\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY,\n * tagHandling: 'html',\n * preserveFormatting: true\n * })\n * ```\n */\nexport const createDeepLTranslator = ({\n\tauthKey,\n\toptions,\n\tformality = 'default',\n\tpreserveFormatting = true,\n\ttagHandling = 'xml'\n}: CreateDeepLTranslatorOptions): Translator => {\n\tconst deeplTranslator = new deepl.Translator(authKey, options)\n\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\t\tconst keys = Object.keys(dictionary)\n\t\tconst texts = keys.map((key) => dictionary[key])\n\n\t\t// DeepL uses specific language codes (e.g., 'EN-US' instead of 'en-US')\n\t\tconst targetLang = locale.toUpperCase() as deepl.TargetLanguageCode\n\t\tconst sourceLang = projectLocale.toUpperCase() as deepl.SourceLanguageCode\n\n\t\tconst results = await deeplTranslator.translateText(\n\t\t\ttexts,\n\t\t\tsourceLang,\n\t\t\ttargetLang,\n\t\t\t{\n\t\t\t\tformality,\n\t\t\t\tpreserveFormatting,\n\t\t\t\ttagHandling\n\t\t\t}\n\t\t)\n\n\t\t// Handle both single result and array of results\n\t\tconst translationResults = Array.isArray(results) ? results : [results]\n\n\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\tconst key = keys[i]\n\t\t\ttranslatedOutput[key] = translationResults[i]?.text || dictionary[key]\n\t\t}\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport { v2 } from '@google-cloud/translate'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateGoogleCloudTranslatorOptions = v2.TranslateConfig\n\n/**\n * Creates a translator using Google Cloud Translation API.\n *\n * This translator uses Google Cloud's Neural Machine Translation (NMT)\n * for high-quality translations.\n *\n * @example\n * ```ts\n * import { createGoogleCloudTranslator } from '@terai/translator/translators'\n *\n * const translator = createGoogleCloudTranslator({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT_ID,\n * keyFilename: './google-credentials.json'\n * })\n * ```\n *\n * @example With API key\n * ```ts\n * import { createGoogleCloudTranslator } from '@terai/translator/translators'\n *\n * const translator = createGoogleCloudTranslator({\n * key: process.env.GOOGLE_CLOUD_API_KEY\n * })\n * ```\n */\nexport const createGoogleCloudTranslator = (\n\toptions: CreateGoogleCloudTranslatorOptions\n): Translator => {\n\tconst translate = new v2.Translate(options)\n\n\tconst translator: Translator = async ({ dictionary, locale }) => {\n\t\tconst translatedOutput: Dictionary = {}\n\n\t\tawait Promise.all(\n\t\t\tObject.keys(dictionary).map(async (key) => {\n\t\t\t\tconst value = dictionary[key]\n\n\t\t\t\tconst [translation] = await translate.translate(value, locale)\n\n\t\t\t\ttranslatedOutput[key] = translation\n\t\t\t})\n\t\t)\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["outdent","translator: Translator","translator: Translator","translatedOutput: Dictionary","translator: Translator","translatedOutput: Dictionary","batches: Array<Array<{ text: string }>>","results: AzureTranslationResponse","translator: Translator","translatedOutput: Dictionary","translator: Translator","translatedOutput: Dictionary"],"sources":["../../../../node_modules/.pnpm/outdent@0.8.0/node_modules/outdent/lib/index.js","../../src/translators/ai.ts","../../src/translators/aws.ts","../../src/translators/azure.ts","../../src/translators/deepl.ts","../../src/translators/google-cloud.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.outdent = void 0;\n// In the absence of a WeakSet or WeakMap implementation, don't break, but don't cache either.\nfunction noop() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n}\nfunction createWeakMap() {\n if (typeof WeakMap !== \"undefined\") {\n return new WeakMap();\n }\n else {\n return fakeSetOrMap();\n }\n}\n/**\n * Creates and returns a no-op implementation of a WeakMap / WeakSet that never stores anything.\n */\nfunction fakeSetOrMap() {\n return {\n add: noop,\n delete: noop,\n get: noop,\n set: noop,\n has: function (k) {\n return false;\n },\n };\n}\n// Safe hasOwnProperty\nvar hop = Object.prototype.hasOwnProperty;\nvar has = function (obj, prop) {\n return hop.call(obj, prop);\n};\n// Copy all own enumerable properties from source to target\nfunction extend(target, source) {\n for (var prop in source) {\n if (has(source, prop)) {\n target[prop] = source[prop];\n }\n }\n return target;\n}\nvar reLeadingNewline = /^[ \\t]*(?:\\r\\n|\\r|\\n)/;\nvar reTrailingNewline = /(?:\\r\\n|\\r|\\n)[ \\t]*$/;\nvar reStartsWithNewlineOrIsEmpty = /^(?:[\\r\\n]|$)/;\nvar reDetectIndentation = /(?:\\r\\n|\\r|\\n)([ \\t]*)(?:[^ \\t\\r\\n]|$)/;\nvar reOnlyWhitespaceWithAtLeastOneNewline = /^[ \\t]*[\\r\\n][ \\t\\r\\n]*$/;\nfunction _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options) {\n // If first interpolated value is a reference to outdent,\n // determine indentation level from the indentation of the interpolated value.\n var indentationLevel = 0;\n var match = strings[0].match(reDetectIndentation);\n if (match) {\n indentationLevel = match[1].length;\n }\n var reSource = \"(\\\\r\\\\n|\\\\r|\\\\n).{0,\" + indentationLevel + \"}\";\n var reMatchIndent = new RegExp(reSource, \"g\");\n if (firstInterpolatedValueSetsIndentationLevel) {\n strings = strings.slice(1);\n }\n var newline = options.newline, trimLeadingNewline = options.trimLeadingNewline, trimTrailingNewline = options.trimTrailingNewline;\n var normalizeNewlines = typeof newline === \"string\";\n var l = strings.length;\n var outdentedStrings = strings.map(function (v, i) {\n // Remove leading indentation from all lines\n v = v.replace(reMatchIndent, \"$1\");\n // Trim a leading newline from the first string\n if (i === 0 && trimLeadingNewline) {\n v = v.replace(reLeadingNewline, \"\");\n }\n // Trim a trailing newline from the last string\n if (i === l - 1 && trimTrailingNewline) {\n v = v.replace(reTrailingNewline, \"\");\n }\n // Normalize newlines\n if (normalizeNewlines) {\n v = v.replace(/\\r\\n|\\n|\\r/g, function (_) { return newline; });\n }\n return v;\n });\n return outdentedStrings;\n}\nfunction concatStringsAndValues(strings, values) {\n var ret = \"\";\n for (var i = 0, l = strings.length; i < l; i++) {\n ret += strings[i];\n if (i < l - 1) {\n ret += values[i];\n }\n }\n return ret;\n}\nfunction isTemplateStringsArray(v) {\n return has(v, \"raw\") && has(v, \"length\");\n}\n/**\n * It is assumed that opts will not change. If this is a problem, clone your options object and pass the clone to\n * makeInstance\n * @param options\n * @return {outdent}\n */\nfunction createInstance(options) {\n /** Cache of pre-processed template literal arrays */\n var arrayAutoIndentCache = createWeakMap();\n /**\n * Cache of pre-processed template literal arrays, where first interpolated value is a reference to outdent,\n * before interpolated values are injected.\n */\n var arrayFirstInterpSetsIndentCache = createWeakMap();\n function outdent(stringsOrOptions) {\n var values = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n values[_i - 1] = arguments[_i];\n }\n /* tslint:enable:no-shadowed-variable */\n if (isTemplateStringsArray(stringsOrOptions)) {\n var strings = stringsOrOptions;\n // Is first interpolated value a reference to outdent, alone on its own line, without any preceding non-whitespace?\n var firstInterpolatedValueSetsIndentationLevel = (values[0] === outdent || values[0] === defaultOutdent) &&\n reOnlyWhitespaceWithAtLeastOneNewline.test(strings[0]) &&\n reStartsWithNewlineOrIsEmpty.test(strings[1]);\n // Perform outdentation\n var cache = firstInterpolatedValueSetsIndentationLevel\n ? arrayFirstInterpSetsIndentCache\n : arrayAutoIndentCache;\n var renderedArray = cache.get(strings);\n if (!renderedArray) {\n renderedArray = _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options);\n cache.set(strings, renderedArray);\n }\n /** If no interpolated values, skip concatenation step */\n if (values.length === 0) {\n return renderedArray[0];\n }\n /** Concatenate string literals with interpolated values */\n var rendered = concatStringsAndValues(renderedArray, firstInterpolatedValueSetsIndentationLevel ? values.slice(1) : values);\n return rendered;\n }\n else {\n // Create and return a new instance of outdent with the given options\n return createInstance(extend(extend({}, options), stringsOrOptions || {}));\n }\n }\n var fullOutdent = extend(outdent, {\n string: function (str) {\n return _outdentArray([str], false, options)[0];\n },\n });\n return fullOutdent;\n}\nvar defaultOutdent = createInstance({\n trimLeadingNewline: true,\n trimTrailingNewline: true,\n});\nexports.outdent = defaultOutdent;\n// Named exports. Simple and preferred.\n// import outdent from 'outdent';\nexports.default = defaultOutdent;\nif (typeof module !== \"undefined\") {\n // In webpack harmony-modules environments, module.exports is read-only,\n // so we fail gracefully.\n try {\n module.exports = defaultOutdent;\n Object.defineProperty(defaultOutdent, \"__esModule\", { value: true });\n defaultOutdent.default = defaultOutdent;\n defaultOutdent.outdent = defaultOutdent;\n }\n catch (e) { }\n}\n//# sourceMappingURL=index.js.map","// Dependencies\nimport { generateObject } from 'ai'\nimport { outdent } from 'outdent'\nimport { z } from 'zod'\n\n// Types\nimport type { LanguageModel } from 'ai'\nimport type { Translator } from '@terai/types'\n\nexport type CreateAiTranslatorOptions = {\n\t/**\n\t * The AI model to use for translation.\n\t * Can be any model from AI SDK providers (@ai-sdk/openai, @ai-sdk/anthropic, @ai-sdk/groq, etc.)\n\t *\n\t * @example\n\t * import { createOpenAI } from '@ai-sdk/openai'\n\t * const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY })\n\t * const model = openai('gpt-4o')\n\t * const translator = createAiTranslator({ model })\n\t */\n\tmodel: LanguageModel\n\n\t/**\n\t * Custom system prompt for translation.\n\t * If not provided, a generic prompt will be used that covers most app translation cases.\n\t */\n\tsystemPrompt?: string\n}\n\nconst DEFAULT_SYSTEM_PROMPT = outdent`\n# Expert AI Translator\n\n## Your Role\nYou are an expert translator and localization specialist with deep expertise in software\napplications, user interfaces, and technical documentation. Your translations are accurate,\ncontextually appropriate, and maintain the natural feel of native language.\n\n## Critical Requirements\n\n### 1. Preserve Code Patterns\n- **NEVER** translate template variables (e.g., \\${var}, {var}, %s, %d)\n- **ALWAYS** keep placeholder syntax exactly as provided\n- **MAINTAIN** all escape sequences and special characters\n- **PRESERVE** HTML tags, markdown syntax, and formatting codes\n\n### 2. Translation Quality\n- Use **natural, idiomatic** expressions in the target language\n- Maintain **consistent terminology** throughout all strings\n- Adapt **cultural references** appropriately for the target locale\n- Ensure **grammatical correctness** and proper sentence structure\n\n### 3. Context Awareness\n- **UI Elements**: Keep translations concise for buttons, labels, and menus\n- **Messages**: Maintain appropriate tone (error messages: clear, help text: friendly)\n- **Technical Terms**: Use standard industry terminology when available\n- **Brand Names**: Do not translate proper nouns, product names, or brand names\n\n### 4. Formatting Guidelines\n- **Punctuation**: Follow target language conventions\n- **Capitalization**: Match target language standards (e.g., German nouns)\n- **Numbers & Dates**: Keep placeholders unchanged; format will be handled at runtime\n- **Whitespace**: Preserve spacing around variables and special characters\n\n### 5. Tone & Style\n- **Consistency**: Maintain uniform voice across all translations\n- **Formality**: Match the formality level of the source text\n- **Clarity**: Prioritize understanding over literal translation\n- **Brevity**: Keep translations concise, especially for UI elements\n\n## Output Format\n- Return ONLY a valid JSON object\n- Use the EXACT SAME KEYS as the input (CRITICAL)\n- Do NOT add newlines within string values\n- Do NOT modify, remove, or add keys\n- Do NOT include markdown code blocks or extra formatting\n\n## Examples of What to Preserve\n\n✅ CORRECT:\n- \"Welcome \\${var}\" → \"Bienvenido \\${var}\"\n- \"You have {count} items\" → \"Tienes {count} elementos\"\n- \"Click <strong>here</strong>\" → \"Haz clic <strong>aquí</strong>\"\n\n❌ INCORRECT:\n- \"Welcome \\${var}\" → \"Bienvenido Juan\" (translated variable)\n- \"You have {var} items\" → \"Tienes 3 elementos\" (removed braces)\n- \"Click <strong>here</strong>\" → \"Haz clic **aquí**\" (changed HTML to markdown)`\n\n/**\n * Creates an AI-powered translator using the Vercel AI SDK.\n *\n * This translator uses structured output generation to translate dictionaries\n * while preserving template variables, formatting, and code patterns.\n *\n * @example\n * ```ts\n * import { createAiTranslator } from '@terai/translator/translators'\n * import { createAnthropic } from '@ai-sdk/anthropic'\n *\n * const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY })\n * const translator = createAiTranslator({\n * model: anthropic('claude-3-5-sonnet-20241022'),\n * systemPrompt: 'Custom prompt for my specific use case...'\n * })\n * ```\n */\nexport const createAiTranslator = ({\n\tmodel,\n\tsystemPrompt = DEFAULT_SYSTEM_PROMPT\n}: CreateAiTranslatorOptions): Translator => {\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tprojectLocale,\n\t\tlocale\n\t}) => {\n\t\tconst { object: translation } = await generateObject({\n\t\t\tmodel,\n\t\t\toutput: 'no-schema',\n\t\t\tsystem: !systemPrompt\n\t\t\t\t? DEFAULT_SYSTEM_PROMPT\n\t\t\t\t: outdent`\n\t\t\t\t${DEFAULT_SYSTEM_PROMPT}\n\t\t\t\t\n\t\t\t\t## Additional User System Instructions (highest priority)\n\t\t\t\t${systemPrompt}\n\t\t\t`,\n\t\t\tprompt: outdent`\n\t\t\t\tTranslate the following JSON from locale:\"${projectLocale}\" to locale:\"${locale}\".\n\n\t\t\t\t<target-json>\n\t\t\t\t\t${JSON.stringify(dictionary, null, 2)}\n\t\t\t\t</target-json>\n\t\t\t`\n\t\t})\n\n\t\treturn JSONSchema.parse(translation)\n\t}\n\n\treturn translator\n}\n\nconst JSONSchema = z.record(z.string(), z.string())\n","// Dependencies\nimport {\n\tTranslateClient,\n\tTranslateTextCommand,\n\ttype TranslateClientConfig\n} from '@aws-sdk/client-translate'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateAwsTranslatorOptions = TranslateClientConfig & {\n\t/**\n\t * The source language code (e.g., 'en', 'es', 'fr').\n\t * If not provided, AWS Translate will auto-detect the source language.\n\t * @default 'auto'\n\t */\n\tsourceLanguageCode?: string\n}\n\n/**\n * Creates a translator using AWS Translate.\n *\n * AWS Translate is a neural machine translation service that delivers\n * fast, high-quality, and affordable language translation.\n *\n * @example\n * ```ts\n * import { createAwsTranslator } from '@terai/translator/translators'\n *\n * const translator = createAwsTranslator({\n * region: 'us-east-1',\n * credentials: {\n * accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n * secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY\n * }\n * })\n * ```\n *\n * @example With AWS profile\n * ```ts\n * import { createAwsTranslator } from '@terai/translator/translators'\n * import { fromIni } from '@aws-sdk/credential-providers'\n *\n * const translator = createAwsTranslator({\n * region: 'us-east-1',\n * credentials: fromIni({ profile: 'my-profile' })\n * })\n * ```\n */\nexport const createAwsTranslator = ({\n\tsourceLanguageCode = 'auto',\n\t...clientConfig\n}: CreateAwsTranslatorOptions): Translator => {\n\tconst client = new TranslateClient(clientConfig)\n\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\n\t\t// Use projectLocale as source if not set to auto\n\t\tconst source =\n\t\t\tsourceLanguageCode === 'auto' ? projectLocale : sourceLanguageCode\n\n\t\tawait Promise.all(\n\t\t\tObject.keys(dictionary).map(async (key) => {\n\t\t\t\tconst value = dictionary[key]\n\n\t\t\t\tconst command = new TranslateTextCommand({\n\t\t\t\t\tText: value,\n\t\t\t\t\tSourceLanguageCode: source,\n\t\t\t\t\tTargetLanguageCode: locale\n\t\t\t\t})\n\n\t\t\t\tconst response = await client.send(command)\n\n\t\t\t\ttranslatedOutput[key] = response.TranslatedText || value\n\t\t\t})\n\t\t)\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateAzureTranslatorOptions = {\n\t/**\n\t * Azure Translator subscription key.\n\t */\n\tsubscriptionKey: string\n\n\t/**\n\t * Azure region where the Translator resource is located.\n\t * @example 'eastus', 'westeurope', 'southeastasia'\n\t */\n\tregion: string\n\n\t/**\n\t * Custom endpoint URL. If not provided, uses the global endpoint.\n\t * @default 'https://api.cognitive.microsofttranslator.com'\n\t */\n\tendpoint?: string\n}\n\ntype AzureTranslationResponse = Array<{\n\ttranslations: Array<{\n\t\ttext: string\n\t\tto: string\n\t}>\n}>\n\n/**\n * Creates a translator using Microsoft Azure Translator.\n *\n * Azure Translator is a cloud-based machine translation service\n * that supports 100+ languages.\n *\n * @example\n * ```ts\n * import { createAzureTranslator } from '@terai/translator/translators'\n *\n * const translator = createAzureTranslator({\n * subscriptionKey: process.env.AZURE_TRANSLATOR_KEY,\n * region: 'eastus'\n * })\n * ```\n *\n * @example With custom endpoint\n * ```ts\n * import { createAzureTranslator } from '@terai/translator/translators'\n *\n * const translator = createAzureTranslator({\n * subscriptionKey: process.env.AZURE_TRANSLATOR_KEY,\n * region: 'eastus',\n * endpoint: 'https://my-custom-endpoint.cognitiveservices.azure.com'\n * })\n * ```\n */\nexport const createAzureTranslator = ({\n\tsubscriptionKey,\n\tregion,\n\tendpoint = 'https://api.cognitive.microsofttranslator.com'\n}: CreateAzureTranslatorOptions): Translator => {\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\t\tconst keys = Object.keys(dictionary)\n\t\tconst texts = keys.map((key) => ({ text: dictionary[key] }))\n\n\t\t// Azure Translator API accepts up to 100 texts per request\n\t\tconst batchSize = 100\n\t\tconst batches: Array<Array<{ text: string }>> = []\n\n\t\tfor (let i = 0; i < texts.length; i += batchSize) {\n\t\t\tbatches.push(texts.slice(i, i + batchSize))\n\t\t}\n\n\t\tlet keyIndex = 0\n\n\t\tfor (const batch of batches) {\n\t\t\tconst url = new URL('/translate', endpoint)\n\t\t\turl.searchParams.set('api-version', '3.0')\n\t\t\turl.searchParams.set('from', projectLocale)\n\t\t\turl.searchParams.set('to', locale)\n\n\t\t\tconst response = await fetch(url.toString(), {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Ocp-Apim-Subscription-Key': subscriptionKey,\n\t\t\t\t\t'Ocp-Apim-Subscription-Region': region,\n\t\t\t\t\t'Content-Type': 'application/json'\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(batch)\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorText = await response.text()\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Azure Translator API error: ${response.status} - ${errorText}`\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst results: AzureTranslationResponse = await response.json()\n\n\t\t\tfor (const result of results) {\n\t\t\t\tconst key = keys[keyIndex]\n\t\t\t\ttranslatedOutput[key] = result.translations[0]?.text || dictionary[key]\n\t\t\t\tkeyIndex++\n\t\t\t}\n\t\t}\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport * as deepl from 'deepl-node'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateDeepLTranslatorOptions = {\n\t/**\n\t * DeepL API authentication key.\n\t * Get your key from https://www.deepl.com/pro-api\n\t */\n\tauthKey: string\n\n\t/**\n\t * Additional options for the DeepL Translator.\n\t */\n\toptions?: deepl.TranslatorOptions\n\n\t/**\n\t * Formality preference for translations.\n\t * - 'default': Default formality\n\t * - 'more': More formal language\n\t * - 'less': Less formal language\n\t * - 'prefer_more': Prefer more formal if available\n\t * - 'prefer_less': Prefer less formal if available\n\t * @default 'default'\n\t */\n\tformality?: deepl.Formality\n\n\t/**\n\t * Whether to preserve formatting in translations.\n\t * @default true\n\t */\n\tpreserveFormatting?: boolean\n\n\t/**\n\t * Specify how to handle XML tags in text.\n\t * @default 'xml'\n\t */\n\ttagHandling?: 'xml' | 'html'\n}\n\n/**\n * Creates a translator using DeepL API.\n *\n * DeepL is known for producing high-quality, natural-sounding translations\n * and is often considered one of the best machine translation services available.\n *\n * @example\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY\n * })\n * ```\n *\n * @example With formality preference\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY,\n * formality: 'less' // Use informal language\n * })\n * ```\n *\n * @example With HTML tag handling\n * ```ts\n * import { createDeepLTranslator } from '@terai/translator/translators'\n *\n * const translator = createDeepLTranslator({\n * authKey: process.env.DEEPL_API_KEY,\n * tagHandling: 'html',\n * preserveFormatting: true\n * })\n * ```\n */\nexport const createDeepLTranslator = ({\n\tauthKey,\n\toptions,\n\tformality = 'default',\n\tpreserveFormatting = true,\n\ttagHandling = 'xml'\n}: CreateDeepLTranslatorOptions): Translator => {\n\tconst deeplTranslator = new deepl.Translator(authKey, options)\n\n\tconst translator: Translator = async ({\n\t\tdictionary,\n\t\tlocale,\n\t\tprojectLocale\n\t}) => {\n\t\tconst translatedOutput: Dictionary = {}\n\t\tconst keys = Object.keys(dictionary)\n\t\tconst texts = keys.map((key) => dictionary[key])\n\n\t\t// DeepL uses specific language codes (e.g., 'EN-US' instead of 'en-US')\n\t\tconst targetLang = locale.toUpperCase() as deepl.TargetLanguageCode\n\t\tconst sourceLang = projectLocale.toUpperCase() as deepl.SourceLanguageCode\n\n\t\tconst results = await deeplTranslator.translateText(\n\t\t\ttexts,\n\t\t\tsourceLang,\n\t\t\ttargetLang,\n\t\t\t{\n\t\t\t\tformality,\n\t\t\t\tpreserveFormatting,\n\t\t\t\ttagHandling\n\t\t\t}\n\t\t)\n\n\t\t// Handle both single result and array of results\n\t\tconst translationResults = Array.isArray(results) ? results : [results]\n\n\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\tconst key = keys[i]\n\t\t\ttranslatedOutput[key] = translationResults[i]?.text || dictionary[key]\n\t\t}\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n","// Dependencies\nimport { v2 } from '@google-cloud/translate'\n\n// Types\nimport type { Dictionary, Translator } from '@terai/types'\n\nexport type CreateGoogleCloudTranslatorOptions = v2.TranslateConfig\n\n/**\n * Creates a translator using Google Cloud Translation API.\n *\n * This translator uses Google Cloud's Neural Machine Translation (NMT)\n * for high-quality translations.\n *\n * @example\n * ```ts\n * import { createGoogleCloudTranslator } from '@terai/translator/translators'\n *\n * const translator = createGoogleCloudTranslator({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT_ID,\n * keyFilename: './google-credentials.json'\n * })\n * ```\n *\n * @example With API key\n * ```ts\n * import { createGoogleCloudTranslator } from '@terai/translator/translators'\n *\n * const translator = createGoogleCloudTranslator({\n * key: process.env.GOOGLE_CLOUD_API_KEY\n * })\n * ```\n */\nexport const createGoogleCloudTranslator = (\n\toptions: CreateGoogleCloudTranslatorOptions\n): Translator => {\n\tconst translate = new v2.Translate(options)\n\n\tconst translator: Translator = async ({ dictionary, locale }) => {\n\t\tconst translatedOutput: Dictionary = {}\n\n\t\tawait Promise.all(\n\t\t\tObject.keys(dictionary).map(async (key) => {\n\t\t\t\tconst value = dictionary[key]\n\n\t\t\t\tconst [translation] = await translate.translate(value, locale)\n\n\t\t\t\ttranslatedOutput[key] = translation\n\t\t\t})\n\t\t)\n\n\t\treturn translatedOutput\n\t}\n\n\treturn translator\n}\n"],"x_google_ignoreList":[0],"mappings":"qSACA,OAAO,eAAe,EAAS,aAAc,CAAE,MAAO,GAAM,CAAC,CAC7D,EAAQ,QAAU,IAAK,GAEvB,SAAS,GAAO,EAMhB,SAAS,GAAgB,CAKjB,OAJA,OAAO,QAAY,IACZ,IAAI,QAGJ,GAAc,CAM7B,SAAS,GAAe,CACpB,MAAO,CACH,IAAK,EACL,OAAQ,EACR,IAAK,EACL,IAAK,EACL,IAAK,SAAU,EAAG,CACd,MAAO,IAEd,CAGL,IAAI,EAAM,OAAO,UAAU,eACvB,EAAM,SAAU,EAAK,EAAM,CAC3B,OAAO,EAAI,KAAK,EAAK,EAAK,EAG9B,SAAS,EAAO,EAAQ,EAAQ,CAC5B,IAAK,IAAI,KAAQ,EACT,EAAI,EAAQ,EAAK,GACjB,EAAO,GAAQ,EAAO,IAG9B,OAAO,EAEX,IAAI,EAAmB,wBACnB,EAAoB,wBACpB,EAA+B,gBAC/B,EAAsB,yCACtB,EAAwC,2BAC5C,SAAS,EAAc,EAAS,EAA4C,EAAS,CAGjF,IAAI,EAAmB,EACnB,EAAQ,EAAQ,GAAG,MAAM,EAAoB,CAC7C,IACA,EAAmB,EAAM,GAAG,QAEhC,IAAI,EAAW,uBAAyB,EAAmB,IACvD,EAAgB,IAAI,OAAO,EAAU,IAAI,CACzC,IACA,EAAU,EAAQ,MAAM,EAAE,EAE9B,IAAI,EAAU,EAAQ,QAAS,EAAqB,EAAQ,mBAAoB,EAAsB,EAAQ,oBAC1G,EAAoB,OAAO,GAAY,SACvC,EAAI,EAAQ,OAkBhB,OAjBuB,EAAQ,IAAI,SAAU,EAAG,EAAG,CAe/C,MAbA,GAAI,EAAE,QAAQ,EAAe,KAAK,CAE9B,IAAM,GAAK,IACX,EAAI,EAAE,QAAQ,EAAkB,GAAG,EAGnC,IAAM,EAAI,GAAK,IACf,EAAI,EAAE,QAAQ,EAAmB,GAAG,EAGpC,IACA,EAAI,EAAE,QAAQ,cAAe,SAAU,EAAG,CAAE,OAAO,GAAW,EAE3D,GACT,CAGN,SAAS,EAAuB,EAAS,EAAQ,CAE7C,IAAK,IADD,EAAM,GACD,EAAI,EAAG,EAAI,EAAQ,OAAQ,EAAI,EAAG,IACvC,GAAO,EAAQ,GACX,EAAI,EAAI,IACR,GAAO,EAAO,IAGtB,OAAO,EAEX,SAAS,EAAuB,EAAG,CAC/B,OAAO,EAAI,EAAG,MAAM,EAAI,EAAI,EAAG,SAAS,CAQ5C,SAAS,EAAe,EAAS,CAE7B,IAAI,EAAuB,GAAe,CAKtC,EAAkC,GAAe,CACrD,SAASA,EAAQ,EAAkB,CAE1B,IADD,MAEiB,oBAGrB,GAAI,EAAuB,EAAiB,CAAE,CAC1C,IAAI,EAAU,EAEV,GAA8C,EAAO,KAAOA,GAAW,EAAO,KAAO,IACrF,EAAsC,KAAK,EAAQ,GAAG,EACtD,EAA6B,KAAK,EAAQ,GAAG,CAE7C,EAAQ,EACN,EACA,EACF,EAAgB,EAAM,IAAI,EAAQ,CAWtC,OAVK,IACD,EAAgB,EAAc,EAAS,EAA4C,EAAQ,CAC3F,EAAM,IAAI,EAAS,EAAc,EAGjC,EAAO,SAAW,EACX,EAAc,GAGV,EAAuB,EAAe,EAA6C,EAAO,MAAM,EAAE,CAAG,EAAO,MAK3H,OAAO,EAAe,EAAO,EAAO,EAAE,CAAE,EAAQ,CAAE,GAAoB,EAAE,CAAC,CAAC,CAQlF,OALkB,EAAOA,EAAS,CAC9B,OAAQ,SAAU,EAAK,CACnB,OAAO,EAAc,CAAC,EAAI,CAAE,GAAO,EAAQ,CAAC,IAEnD,CAAC,CAGN,IAAI,EAAiB,EAAe,CAChC,mBAAoB,GACpB,oBAAqB,GACxB,CAAC,CAKF,GAJA,EAAQ,QAAU,EAGlB,EAAQ,QAAU,EACP,IAAW,OAGlB,GAAI,CACA,EAAO,QAAU,EACjB,OAAO,eAAe,EAAgB,aAAc,CAAE,MAAO,GAAM,CAAC,CACpE,EAAe,QAAU,EACzB,EAAe,QAAU,OAEnB,QC9Id,MAAM,EAAwB,EAAA,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFA6ExB,GAAsB,CAClC,QACA,eAAe,KAEgB,MAAO,CACrC,aACA,gBACA,YACK,CACL,GAAM,CAAE,OAAQ,GAAgB,MAAM,EAAe,CACpD,QACA,OAAQ,YACR,OAAS,EAEN,EAAA,OAAO;MACP,EAAsB;;;MAGtB,EAAa;KALb,EAOH,OAAQ,EAAA,OAAO;gDAC8B,EAAc,eAAe,EAAO;;;OAG7E,KAAK,UAAU,EAAY,KAAM,EAAE,CAAC;;KAGxC,CAAC,CAEF,OAAO,EAAW,MAAM,EAAY,EAMhC,EAAa,EAAE,OAAO,EAAE,QAAQ,CAAE,EAAE,QAAQ,CAAC,CC5FtC,GAAuB,CACnC,qBAAqB,OACrB,GAAG,KAC0C,CAC7C,IAAM,EAAS,IAAI,EAAgB,EAAa,CAgChD,OA9B+B,MAAO,CACrC,aACA,SACA,mBACK,CACL,IAAMG,EAA+B,EAAE,CAGjC,EACL,IAAuB,OAAS,EAAgB,EAkBjD,OAhBA,MAAM,QAAQ,IACb,OAAO,KAAK,EAAW,CAAC,IAAI,KAAO,IAAQ,CAC1C,IAAM,EAAQ,EAAW,GAEnB,EAAU,IAAI,EAAqB,CACxC,KAAM,EACN,mBAAoB,EACpB,mBAAoB,EACpB,CAAC,CAIF,EAAiB,IAFA,MAAM,EAAO,KAAK,EAAQ,EAEV,gBAAkB,GAClD,CACF,CAEM,IC1BI,GAAyB,CACrC,kBACA,SACA,WAAW,mDAEoB,MAAO,CACrC,aACA,SACA,mBACK,CACL,IAAME,EAA+B,EAAE,CACjC,EAAO,OAAO,KAAK,EAAW,CAC9B,EAAQ,EAAK,IAAK,IAAS,CAAE,KAAM,EAAW,GAAM,EAAE,CAItDC,EAA0C,EAAE,CAElD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,GAAK,IACtC,EAAQ,KAAK,EAAM,MAAM,EAAG,EAAI,IAAU,CAAC,CAG5C,IAAI,EAAW,EAEf,IAAK,IAAM,KAAS,EAAS,CAC5B,IAAM,EAAM,IAAI,IAAI,aAAc,EAAS,CAC3C,EAAI,aAAa,IAAI,cAAe,MAAM,CAC1C,EAAI,aAAa,IAAI,OAAQ,EAAc,CAC3C,EAAI,aAAa,IAAI,KAAM,EAAO,CAElC,IAAM,EAAW,MAAM,MAAM,EAAI,UAAU,CAAE,CAC5C,OAAQ,OACR,QAAS,CACR,4BAA6B,EAC7B,+BAAgC,EAChC,eAAgB,mBAChB,CACD,KAAM,KAAK,UAAU,EAAM,CAC3B,CAAC,CAEF,GAAI,CAAC,EAAS,GAAI,CACjB,IAAM,EAAY,MAAM,EAAS,MAAM,CACvC,MAAU,MACT,+BAA+B,EAAS,OAAO,KAAK,IACpD,CAGF,IAAMC,EAAoC,MAAM,EAAS,MAAM,CAE/D,IAAK,IAAM,KAAU,EAAS,CAC7B,IAAM,EAAM,EAAK,GACjB,EAAiB,GAAO,EAAO,aAAa,IAAI,MAAQ,EAAW,GACnE,KAIF,OAAO,GClCI,GAAyB,CACrC,UACA,UACA,YAAY,UACZ,qBAAqB,GACrB,cAAc,SACiC,CAC/C,IAAM,EAAkB,IAAI,EAAM,WAAW,EAAS,EAAQ,CAqC9D,OAnC+B,MAAO,CACrC,aACA,SACA,mBACK,CACL,IAAME,EAA+B,EAAE,CACjC,EAAO,OAAO,KAAK,EAAW,CAC9B,EAAQ,EAAK,IAAK,GAAQ,EAAW,GAAK,CAG1C,EAAa,EAAO,aAAa,CACjC,EAAa,EAAc,aAAa,CAExC,EAAU,MAAM,EAAgB,cACrC,EACA,EACA,EACA,CACC,YACA,qBACA,cACA,CACD,CAGK,EAAqB,MAAM,QAAQ,EAAQ,CAAG,EAAU,CAAC,EAAQ,CAEvE,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACrC,IAAM,EAAM,EAAK,GACjB,EAAiB,GAAO,EAAmB,IAAI,MAAQ,EAAW,GAGnE,OAAO,ICtFI,EACZ,GACgB,CAChB,IAAM,EAAY,IAAI,EAAG,UAAU,EAAQ,CAkB3C,OAhB+B,MAAO,CAAE,aAAY,YAAa,CAChE,IAAME,EAA+B,EAAE,CAYvC,OAVA,MAAM,QAAQ,IACb,OAAO,KAAK,EAAW,CAAC,IAAI,KAAO,IAAQ,CAC1C,IAAM,EAAQ,EAAW,GAEnB,CAAC,GAAe,MAAM,EAAU,UAAU,EAAO,EAAO,CAE9D,EAAiB,GAAO,GACvB,CACF,CAEM"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@terai/translator",
|
|
3
3
|
"description": "terai core translator",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.16",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -42,30 +42,13 @@
|
|
|
42
42
|
"deepl-node": "^1",
|
|
43
43
|
"zod": "^4"
|
|
44
44
|
},
|
|
45
|
-
"peerDependenciesMeta": {
|
|
46
|
-
"@aws-sdk/client-translate": {
|
|
47
|
-
"optional": true
|
|
48
|
-
},
|
|
49
|
-
"@google-cloud/translate": {
|
|
50
|
-
"optional": true
|
|
51
|
-
},
|
|
52
|
-
"ai": {
|
|
53
|
-
"optional": true
|
|
54
|
-
},
|
|
55
|
-
"deepl-node": {
|
|
56
|
-
"optional": true
|
|
57
|
-
},
|
|
58
|
-
"zod": {
|
|
59
|
-
"optional": true
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
45
|
"devDependencies": {
|
|
63
46
|
"@aws-sdk/client-translate": "^3.936.0",
|
|
64
47
|
"@google-cloud/translate": "^9.3.0",
|
|
65
48
|
"deepl-node": "^1.22.0",
|
|
66
|
-
"@terai/runtime": "0.0.
|
|
67
|
-
"@terai/types": "0.0.
|
|
68
|
-
"@terai/utils": "0.0.
|
|
49
|
+
"@terai/runtime": "0.0.16",
|
|
50
|
+
"@terai/types": "0.0.16",
|
|
51
|
+
"@terai/utils": "0.0.16"
|
|
69
52
|
},
|
|
70
53
|
"scripts": {
|
|
71
54
|
"dev": "tsdown --format=esm --no-dts --watch",
|