@scoutello/i18n-magic
Version:
Intelligent CLI toolkit that automates internationalization workflows for JavaScript/TypeScript projects and auto-translates new string keys to other languages
108 lines • 4.42 kB
JavaScript
import { Command } from "commander";
import dotenv from "dotenv";
import OpenAI from "openai";
import { checkMissing } from "./commands/check-missing.js";
import { removeUnusedKeys } from "./commands/clean.js";
import { removeKey } from "./commands/remove-key.js";
import { replaceTranslation } from "./commands/replace.js";
import { restoreFromNamespaces } from "./commands/restore-from-namespaces.js";
import { translateMissing } from "./commands/scan.js";
import { syncLocales } from "./commands/sync-locales.js";
import { loadConfig } from "./lib/utils.js";
const program = new Command();
program
.name("i18n-magic")
.description("CLI to help you manage your locales JSON with translations, replacements, etc. with OpenAI.")
.version("0.2.0")
.option("-c, --config <path>", "path to config file")
.option("-e, --env <path>", "path to .env file");
const commands = [
{
name: "scan",
description: "Scan for missing translations, get prompted for each, translate it to the other locales and save it to the JSON file.",
action: translateMissing,
},
{
name: "replace",
description: "Replace a translation based on the key, and translate it to the other locales and save it to the JSON file.",
action: replaceTranslation,
},
{
name: "check-missing",
description: "Check if there are any missing translations. Useful for a CI/CD pipeline or husky hook.",
action: checkMissing,
},
{
name: "sync",
description: "Sync the translations from the default locale to the other locales. Useful for a CI/CD pipeline or husky hook.",
action: syncLocales,
},
{
name: "clean",
description: "Remove unused translations from all locales. Useful for a CI/CD pipeline or husky hook.",
action: removeUnusedKeys,
},
{
name: "restore-from-namespaces",
description: "Restore missing keys by searching for them in other namespace files across all locales.",
action: restoreFromNamespaces,
},
{
name: "remove-key",
description: "Remove a specific translation key from all namespaces and locales.",
action: removeKey,
},
];
for (const command of commands) {
const cmd = program.command(command.name).description(command.description);
// Add key option to replace and remove-key commands
if (command.name === "replace") {
cmd
.option("-k, --key <key>", "translation key to replace")
.allowExcessArguments(true)
.argument("[key]", "translation key to replace");
}
if (command.name === "remove-key") {
cmd
.option("-k, --key <key>", "translation key to remove")
.allowExcessArguments(true)
.argument("[key]", "translation key to remove");
}
cmd.action(async (arg, options) => {
dotenv.config({
path: program.opts().env || ".env",
});
const config = await loadConfig({
configPath: program.opts().config,
});
const isGemini = config.model?.includes("gemini");
// Get API key from config only
const openaiKey = config.OPENAI_API_KEY;
const geminiKey = config.GEMINI_API_KEY;
// Select appropriate key based on model type
const key = isGemini ? geminiKey : openaiKey;
if (!key) {
const keyType = isGemini ? "GEMINI_API_KEY" : "OPENAI_API_KEY";
console.error(`Please provide a${isGemini ? " Gemini" : "n OpenAI"} API key in your i18n-magic config file as ${keyType}.`);
process.exit(1);
}
const openai = new OpenAI({
apiKey: key,
...(isGemini && {
baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/",
}),
});
// For replace and remove-key commands, check for key in argument or option
if (command.name === "replace" || command.name === "remove-key") {
// If key is provided as positional argument, use that first
const keyToUse = typeof arg === "string" ? arg : options.key;
command.action({ ...config, openai }, keyToUse);
}
else {
command.action({ ...config, openai });
}
});
}
program.parse(process.argv);
//# sourceMappingURL=cli.js.map