i18n-ai
Version:
AI-powered translation tool for i18n JSON files
71 lines (68 loc) • 7.56 kB
JavaScript
'use strict';var chunkMA7K6ATI_cjs=require('./chunk-MA7K6ATI.cjs'),commander=require('commander'),c=require('fs'),_=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var c__default=/*#__PURE__*/_interopDefault(c);var ___default=/*#__PURE__*/_interopDefault(_);function $(t,e=","){let o=t.split(/\r?\n/),s=[];for(let r of o){if(!r.trim())continue;let m=[],l="",n=false;for(let a=0;a<r.length;a++){let u=r[a];u==='"'?n&&r[a+1]==='"'?(l+='"',a++):n=!n:u===e&&!n?(m.push(l),l=""):l+=u;}m.push(l),s.push(m);}return s}async function V(t,e){let{inputPath:o,delimiter:s=",",skipHeader:r=true,overwrite:m=false}=e;if(!c__default.default.existsSync(o))throw new Error(`CSV file not found: ${o}`);let l=c__default.default.readFileSync(o,"utf-8"),n=$(l,s);if(n.length===0)throw new Error("CSV file is empty");let a=r?n[0]:null,u=r?1:0;if(a){let[,...i]=a,f=[t.source.code,...t.targets.map(g=>g.code)].filter(g=>!i.includes(g));if(f.length>0)throw new Error(`Missing language columns in CSV: ${f.join(", ")}`)}let j=[{...t.source,index:1},...t.targets.map((i,d)=>({...i,index:d+2}))];for(let i of j){let d={},f={};c__default.default.existsSync(i.path)&&(f=JSON.parse(c__default.default.readFileSync(i.path,"utf-8")));for(let h=u;h<n.length;h++){let O=n[h],y=O[0],C=O[i.index];y&&C&&(d[y]=C);}let g=m?{...f,...chunkMA7K6ATI_cjs.t(d)}:{...chunkMA7K6ATI_cjs.t(d),...f},E=___default.default.dirname(i.path);c__default.default.existsSync(E)||c__default.default.mkdirSync(E,{recursive:true}),c__default.default.writeFileSync(i.path,JSON.stringify(g,null,2),"utf-8"),console.log(`Updated translations for ${i.code}: ${i.path}`);}console.log(`
CSV import completed successfully!`);}var p=new commander.Command;p.name("i18n-ai").description(`AI-powered translation tool for i18n JSON files
Features:
\u2022 Translates i18n JSON files using AI language models
\u2022 Supports multiple AI providers (OpenAI, Anthropic, Gemini, DeepSeek, XAI)
\u2022 Preserves JSON structure and nested keys
\u2022 Smart chunking for large files
\u2022 Handles existing translations
\u2022 Configurable translation settings`).version("0.1.0");p.command("translate").description("Translate i18n JSON files").option("-c, --config <path>","Path to config file (default: translator.config.json)").option("-o, --overwrite","Overwrite existing translations").addHelpText("after",`
Configuration File (translator.config.json):
{
"source": {
"path": "./locales/en.json", // Source language file
"code": "en" // Source language code
},
"targets": [{ // Target languages to translate to
"path": "./locales/es.json",
"code": "es"
}],
"provider": "openai", // AI provider to use
"model": "gpt-4", // Model to use (optional)
"chunkSize": 50, // Number of keys per chunk (default: 50)
"description": "My app context", // Project context for better translations
"tone": "formal", // Desired tone (formal/casual/technical)
"translateAllAtOnce": false, // Translate entire file at once
"overwrite": false, // Overwrite existing translations
"customProvider": { // Custom translation API configuration
"url": "https://api.example.com/translate", // API endpoint
"method": "POST", // HTTP method (default: POST)
"headers": {}, // Custom HTTP headers
"body": {}, // Request body template (supports placeholders)
"responsePath": "translation", // Path to extract result from response
"apiKeyEnvVar": "CUSTOM_API_KEY" // Env var with API key
}
}
Environment Variables:
OPENAI_API_KEY - OpenAI API key
ANTHROPIC_API_KEY - Anthropic API key
GEMINI_API_KEY - Google Gemini API key
DEEPSEEK_API_KEY - DeepSeek API key
XAI_API_KEY - XAI API key
[] - For custom provider if configured
Examples:
$ i18n-ai translate
$ i18n-ai translate -c custom-config.json
$ i18n-ai translate --overwrite
`).action(async t=>{try{await chunkMA7K6ATI_cjs.u({configPath:t.config,overwrite:t.overwrite});}catch(e){console.error("Translation failed:",e),process.exit(1);}});p.command("models").description("List available AI models").option("-p, --provider <provider>","Show models for specific provider (openai, anthropic, gemini, deepseek, xai)").addHelpText("after",`
Examples:
$ i18n-ai models
$ i18n-ai models --provider openai
`).action(t=>{let e=(o,s)=>{console.log(`
${o.toUpperCase()}:`);let r=Object.keys(s).join(" | ");console.log(r),console.log();};if(t.provider){let o=t.provider.toLowerCase();switch(o){case "openai":e("OpenAI",chunkMA7K6ATI_cjs.f);break;case "anthropic":e("Anthropic",chunkMA7K6ATI_cjs.g);break;case "gemini":e("Gemini",chunkMA7K6ATI_cjs.h);break;case "deepseek":e("DeepSeek",chunkMA7K6ATI_cjs.i);break;case "xai":e("XAI",chunkMA7K6ATI_cjs.j);break;default:console.error(`Unknown provider: ${o}`),process.exit(1);}}else e("OpenAI",chunkMA7K6ATI_cjs.f),e("Anthropic",chunkMA7K6ATI_cjs.g),e("Gemini",chunkMA7K6ATI_cjs.h),e("DeepSeek",chunkMA7K6ATI_cjs.i),e("XAI",chunkMA7K6ATI_cjs.j);});p.command("export").description("Export translations to CSV format").option("-c, --config <path>","Path to config file (default: translator.config.json)").option("-o, --output <path>","Output path for CSV file (default: translations-export.csv)").option("-d, --delimiter <char>","Delimiter to use in CSV (default: ,)").addHelpText("after",`
Examples:
$ i18n-ai export
$ i18n-ai export --output ./exports/translations.csv
$ i18n-ai export --delimiter ";"
$ i18n-ai export -c custom-config.json
`).action(async t=>{try{let e=chunkMA7K6ATI_cjs.r(t.config);await chunkMA7K6ATI_cjs.v(e,{outputPath:t.output,delimiter:t.delimiter});}catch(e){console.error("Export failed:",e),process.exit(1);}});p.command("import").description("Import translations from a CSV file").option("-c, --config <path>","Path to config file (default: translator.config.json)").option("-i, --input <path>","Input CSV file path").option("-d, --delimiter <char>","Delimiter to use in CSV (default: ,)").option("--no-header","Skip header row in CSV").option("-o, --overwrite","Overwrite existing translations").addHelpText("after",`
Examples:
$ i18n-ai import -i translations.csv
$ i18n-ai import -i ./data/translations.csv
$ i18n-ai import -i translations.csv -d ";"
$ i18n-ai import -i translations.csv --no-header
$ i18n-ai import -i translations.csv --overwrite
$ i18n-ai import -c custom-config.json -i translations.csv
`).action(async t=>{try{let e=chunkMA7K6ATI_cjs.r(t.config);await V(e,{inputPath:t.input,delimiter:t.delimiter,skipHeader:t.header!==!1,overwrite:t.overwrite});}catch(e){console.error("Import failed:",e),process.exit(1);}});p.command("providers").description("List all available translation providers").action(()=>{let t=chunkMA7K6ATI_cjs.p();Object.entries(t.models).forEach(([e,o])=>{console.log(`
${e.toUpperCase()}:`);let s=Object.keys(o).join(" | ");console.log(s);});});p.parse();