Files
fusion/packages/dashboard/scripts/sync-locales.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

35 lines
1.5 KiB
JavaScript

/* global console */
// Copies the authored @fusion/i18n catalogs into the dashboard tree so Vite can
// code-split them per locale via a plainly app-relative dynamic import. The
// generated app/locales/ dir is gitignored — @fusion/i18n/locales is the
// source-of-truth. Only the dashboard namespaces are copied (the terminal-only
// `cli` namespace is skipped). Runs as a predev/prebuild step.
import { cpSync, mkdirSync, readdirSync, readFileSync, rmSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const here = dirname(fileURLToPath(import.meta.url));
const dashboardRoot = join(here, "..");
const i18nRoot = join(dashboardRoot, "..", "i18n");
const srcLocales = join(i18nRoot, "locales");
const destLocales = join(dashboardRoot, "app", "locales");
// Single source of truth shared with @fusion/i18n config.ts.
const DASHBOARD_NAMESPACES = JSON.parse(
readFileSync(join(i18nRoot, "namespaces.json"), "utf8"),
).dashboard;
const locales = readdirSync(srcLocales, { withFileTypes: true })
.filter((d) => d.isDirectory())
.map((d) => d.name);
rmSync(destLocales, { recursive: true, force: true });
for (const lng of locales) {
mkdirSync(join(destLocales, lng), { recursive: true });
for (const ns of DASHBOARD_NAMESPACES) {
cpSync(join(srcLocales, lng, `${ns}.json`), join(destLocales, lng, `${ns}.json`));
}
}
console.log(`Synced ${locales.length} locale(s) into app/locales: ${locales.join(", ")}`);