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