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>
50 lines
1.7 KiB
JavaScript
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(", ")}`);
|