UNPKG

@dmvicent3/tcli

Version:

A CLI tool for managing translations in projects using next-translate

62 lines (61 loc) 2.47 kB
import { readFileSync } from 'fs'; import { text, isCancel } from '@clack/prompts'; import { requireConfig, getApiKey } from '../lib/config.js'; import { loadTranslationFile, saveTranslationFile } from '../lib/files.js'; import { GeminiTranslator } from '../lib/gemini.js'; export async function batchCommand(filePath, namespace, langs) { const config = requireConfig(); const ns = namespace || config.defaultNamespace; if (!config.namespaces.includes(ns)) { console.error(`[${config.defaultNamespace}] Namespace '${ns}' not found`); process.exit(1); } if (!filePath) { const fileInput = await text({ message: 'Enter path to JSON file with translations:', validate: (v) => (v.length === 0 ? 'File path is required' : undefined), }); if (isCancel(fileInput)) { console.log('[tcli] Operation cancelled'); process.exit(0); } filePath = fileInput; } const targetLangs = langs ? langs.split(',') : config.langs.filter((l) => l !== config.sourceLang); let batchData; try { batchData = JSON.parse(readFileSync(filePath, 'utf-8')); } catch (error) { console.error(`[${config.defaultNamespace}] Failed to read or parse file: ${filePath}`); process.exit(1); } const translator = new GeminiTranslator(getApiKey()); for (const targetLang of targetLangs) { if (!config.langs.includes(targetLang)) { console.error(`[${config.defaultNamespace}] Language '${targetLang}' not supported`); continue; } const translations = loadTranslationFile(config.langDir, targetLang, ns); const translatedBatch = await translator.batchTranslate(batchData, config.sourceLang, targetLang); Object.entries(translatedBatch).forEach(([key, value]) => { setNestedValue(translations, key, value); }); saveTranslationFile(config.langDir, targetLang, ns, translations); } console.log(`[${ns}] Batch translation completed`); } function setNestedValue(obj, key, value) { const parts = key.split('.'); let current = obj; for (let i = 0; i < parts.length - 1; i++) { const part = parts[i]; if (!(part in current) || typeof current[part] !== 'object') { current[part] = {}; } current = current[part]; } current[parts[parts.length - 1]] = value; }