mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-16 20:02:45 +03:00
feat(i18n): add-locale orchestrator (config, flag, ui, docs, cli, readme, bars, site)
One command brings a new locale to every surface, in order: config/i18n.json entry, flag SVG (lipis/flag-icons), dashboard catalog (scaffold + sync-ui-keys --translate-markers), docs mirrors (run-translation over the core set every existing locale carries, then the llm.txt / CHANGELOG.md stubs), CLI catalog (generate-locales --code + batched common/program translation), README flag link / docs index row / I18N guide row / locale counts (+ sync-llm-mirrors), language bars, and the marketing site (lang JSON, SUPPORTED_LANGS, dropdowns). Every phase checks presence first, so a re-run is a no-op apart from filling in what is still missing; --dry-run prints the whole plan and touches nothing (no files, network or child processes); --only / --skip select phases. - scripts/i18n/lib/docs-core-set.mjs: computeDocsCoreSet — intersection of the existing non-docsExcluded mirrors minus llm.txt / CHANGELOG.md / I18N.md and paths without an English source (22 files today). - scripts/i18n/lib/site-scaffold.mjs: addSupportedLang (re-flows the array in the file's own fill style) and addDropdownOption (code order, every menu). - bin/cli/scripts/generate-locales.mjs: --code=<locale> filter. - translate-backend parseBatchResponse: Object.hasOwn + trimmed values. - package.json: i18n:add-locale script.
This commit is contained in:
@@ -6,7 +6,9 @@
|
||||
* For top-tier languages, a translated `common` + `program` section is included.
|
||||
* All other keys fall back to `en` via i18n.mjs's existing fallback mechanism.
|
||||
*
|
||||
* Run: node bin/cli/scripts/generate-locales.mjs [--force]
|
||||
* Run: node bin/cli/scripts/generate-locales.mjs [--force] [--code=<locale>]
|
||||
* --code=<locale> generate only that locale (scripts/i18n/add-locale.mjs uses it
|
||||
* to scaffold the catalog of the locale it is adding)
|
||||
*/
|
||||
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
||||
import { join, dirname } from "node:path";
|
||||
@@ -17,8 +19,13 @@ const ROOT = join(__dirname, "..", "..", "..");
|
||||
const LOCALES_DIR = join(__dirname, "..", "locales");
|
||||
const I18N_CFG = join(ROOT, "config", "i18n.json");
|
||||
const FORCE = process.argv.includes("--force");
|
||||
const ONLY = process.argv.find((arg) => arg.startsWith("--code="))?.slice("--code=".length) || null;
|
||||
|
||||
const { locales } = JSON.parse(readFileSync(I18N_CFG, "utf8"));
|
||||
if (ONLY && !locales.some((locale) => locale.code === ONLY)) {
|
||||
console.error(`--code=${ONLY} is not listed in config/i18n.json`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// common + program translations for each language code.
|
||||
// Keys that are absent fall back to en automatically.
|
||||
@@ -888,7 +895,7 @@ const SCAFFOLD_ONLY = ["bn", "gu", "he", "in", "mr", "ms", "phi", "sw", "ta", "t
|
||||
let created = 0;
|
||||
let skipped = 0;
|
||||
|
||||
for (const locale of locales) {
|
||||
for (const locale of locales.filter((candidate) => !ONLY || candidate.code === ONLY)) {
|
||||
const { code } = locale;
|
||||
if (code === "en" || code === "pt-BR") {
|
||||
skipped++;
|
||||
|
||||
Reference in New Issue
Block a user