Files
fusion/packages/i18n/scripts/gen-cli-catalogs.mjs
gsxdsm 4f6013ff3a test+refactor(i18n): close code-review residuals
- Extract a shared normalizeToSupportedLocale helper in @fusion/i18n used by
  both the CLI env detection and the dashboard navigator detection
  (convertDetectedLanguage), fixing multi-subtag navigator tags (zh-Hans-CN)
  and unifying Chinese script resolution.
- Add a cross-tab storage listener to useLanguage so a language change in one
  tab propagates to others.
- Dedup the namespace lists into packages/i18n/namespaces.json, consumed by
  config.ts and all three build scripts (no more 3-way drift risk).
- Add tests: dashboard i18n/index.ts (document.lang mirror, init non-blocking),
  useLanguage concurrent-hydration race + cross-tab adoption,
  normalizeToSupportedLocale, namespace-source consistency.

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

51 lines
1.8 KiB
JavaScript

/* global console */
// 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, readFileSync, 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");
// Single source of truth shared with src/config.ts and the dashboard scripts.
const CLI_NAMESPACES = JSON.parse(readFileSync(join(root, "namespaces.json"), "utf8")).cli;
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(", ")}`);