Files
fusion/packages/i18n/scripts/gen-cli-catalogs.mjs
gsxdsm 9072d71306 feat(i18n): add @fusion/i18n package, catalogs, and i18next-cli tooling (U2)
Create the @fusion/i18n package as the authored source-of-truth: shared
i18next config (namespace split, script-aware zh-CN/zh-TW fallback, plural
setup), en base catalogs, and a generated CLI static-import map so the
terminal surface is drop-in for new locales. Add the i18next-cli workflow
(extract/sync/types/status/lint) wired as root i18n:* scripts, install the
i18next stack into dashboard + CLI, strip @fusion/i18n from the published CLI
manifest, gitignore the generated dashboard catalog tree, and add a changeset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:00:31 -07:00

50 lines
1.7 KiB
JavaScript

// Generates src/cli-catalogs.ts: a static import map of the CLI-relevant
// catalogs for every locale present under locales/. The terminal UI bundles
// catalogs statically (tsup, no lazy loading), so it needs an explicit import
// map rather than a dynamic loader. Driving this off the locales/ directory
// listing keeps "add a language" a no-code operation on the CLI side: add the
// locale (via `i18next-cli sync`), regenerate, done.
import { readdirSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const here = dirname(fileURLToPath(import.meta.url));
const root = join(here, "..");
const localesDir = join(root, "locales");
// Keep in sync with CLI_NAMESPACES in src/config.ts.
const CLI_NAMESPACES = ["common", "cli", "errors"];
const locales = readdirSync(localesDir, { withFileTypes: true })
.filter((d) => d.isDirectory())
.map((d) => d.name)
.sort();
const ident = (s) => s.replace(/[^a-zA-Z0-9]/g, "_");
const imports = [];
const entries = [];
for (const lng of locales) {
const nsLines = [];
for (const ns of CLI_NAMESPACES) {
const id = `${ident(lng)}_${ns}`;
imports.push(`import ${id} from "../locales/${lng}/${ns}.json";`);
nsLines.push(` ${ns}: ${id},`);
}
entries.push(` "${lng}": {\n${nsLines.join("\n")}\n },`);
}
const out = [
"// GENERATED by scripts/gen-cli-catalogs.mjs — do not edit by hand.",
"// Run `pnpm --filter @fusion/i18n gen:cli-catalogs` to regenerate.",
...imports,
"",
"export const cliResources = {",
...entries,
"} as const;",
"",
].join("\n");
writeFileSync(join(root, "src", "cli-catalogs.ts"), out);
console.log(`Generated cli-catalogs.ts for ${locales.length} locale(s): ${locales.join(", ")}`);