everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
103 lines (101 loc) • 4.83 kB
JavaScript
const require_domain = require('../domain.cjs');
const require_fs = require('../fs.cjs');
let effect = require("effect");
//#region src/services/scaffold/upgrade-audit/checks/i18n-seam.ts
const APP_PATH = "ui/src/app.ts";
const CATALOGS_PATH = "ui/src/i18n/catalogs.ts";
const RUNTIME_PATH = "ui/src/i18n/runtime.tsx";
const ROOT_PATH = "ui/src/routes/__root.tsx";
const RUNTIME_IMPORT = "@/i18n/runtime";
const parseAppLocale = (source) => {
const match = source.match(/export\s+const\s+appLocale[^=]*=\s*\{([\s\S]*?)\}/);
if (!match) return null;
const body = match[1];
const locales = body.match(/locales:\s*\[([^\]]*)\]/)?.[1];
const defaultLocale = body.match(/defaultLocale:\s*"([^"]+)"/)?.[1];
const cookieName = body.match(/cookieName:\s*"([^"]+)"/)?.[1];
if (!locales || !defaultLocale || !cookieName) return null;
return {
locales: locales.split(",").map((l) => l.trim().replace(/^["']|["']$/g, "")).filter(Boolean),
defaultLocale,
cookieName
};
};
const parseCatalogs = (source) => {
const locales = source.match(/APP_LOCALES\s*=\s*\[([^\]]*)\]/)?.[1];
const defaultLocale = source.match(/DEFAULT_APP_LOCALE[^=]*=\s*"([^"]+)"/)?.[1];
const cookieName = source.match(/APP_LOCALE_COOKIE[^=]*=\s*"([^"]+)"/)?.[1];
if (!locales || !defaultLocale || !cookieName) return null;
return {
locales: locales.split(",").map((l) => l.trim().replace(/^["']|["']$/g, "")).filter(Boolean),
defaultLocale,
cookieName
};
};
const localeDrift = (appLocale, catalogs) => {
const drift = [];
if (appLocale.defaultLocale !== catalogs.defaultLocale) drift.push(`defaultLocale: app.ts "${appLocale.defaultLocale}" vs catalogs "${catalogs.defaultLocale}"`);
if (appLocale.cookieName !== catalogs.cookieName) drift.push(`cookieName: app.ts "${appLocale.cookieName}" vs catalogs "${catalogs.cookieName}"`);
const a = appLocale.locales.join(",");
const b = catalogs.locales.join(",");
if (a !== b) drift.push(`locales: app.ts [${a}] vs catalogs [${b}]`);
return drift;
};
const readI18nSeam = (projectDir) => effect.Effect.gen(function* () {
const appLocale = (yield* require_fs.fileExists(projectDir, "ui/src/app.ts")) ? parseAppLocale(yield* require_fs.readText(projectDir, APP_PATH)) : null;
const runtimeExists = yield* require_fs.fileExists(projectDir, RUNTIME_PATH);
const rootExists = yield* require_fs.fileExists(projectDir, ROOT_PATH);
let seam;
if (!runtimeExists) seam = "missing";
else if (!rootExists) seam = "absent-root";
else seam = (yield* require_fs.readText(projectDir, "ui/src/routes/__root.tsx")).includes("@/i18n/runtime") ? "wired" : "unmounted";
let catalogsDrift = [];
if (appLocale && (yield* require_fs.fileExists(projectDir, "ui/src/i18n/catalogs.ts"))) {
const catalogs = parseCatalogs(yield* require_fs.readText(projectDir, CATALOGS_PATH));
if (catalogs) catalogsDrift = localeDrift(appLocale, catalogs);
}
return {
appLocale,
seam,
catalogsDrift
};
});
const checkI18nSeam = (projectDir) => effect.Effect.gen(function* () {
const { appLocale, seam, catalogsDrift } = yield* readI18nSeam(projectDir);
const findings = [];
if (seam === "missing") findings.push(new require_domain.Finding({
check: "i18n-seam",
path: RUNTIME_PATH,
severity: "blocker",
message: "the shared i18n runtime is not wired — the UI bundle shares no @lingui/*, so the host's auth plugin fails SSR composition with RUNTIME-012 (shareKey @lingui/core). Run `pnpm i18n-seam` to scaffold ui/src/i18n and mount AppI18nProvider"
}));
else if (seam === "unmounted") findings.push(new require_domain.Finding({
check: "i18n-seam",
path: RUNTIME_PATH,
severity: "blocker",
message: "ui/src/i18n/runtime.tsx exists but no route imports it — the provider never enters the bundle, so @lingui/* stays out of the share scope (RUNTIME-012 at SSR composition). Mount AppI18nProvider in the root route"
}));
else if (seam === "absent-root") findings.push(new require_domain.Finding({
check: "i18n-seam",
path: ROOT_PATH,
severity: "blocker",
message: "ui/src/i18n/runtime.tsx exists but ui/src/routes/__root.tsx is absent — the provider cannot be mounted and the bundle shares no @lingui/* (RUNTIME-012 at SSR composition); inspect the route tree"
}));
if (appLocale && catalogsDrift.length > 0) findings.push(new require_domain.Finding({
check: "i18n-seam",
path: CATALOGS_PATH,
severity: "warn",
message: `i18n catalogs drift from app.ts's appLocale: ${catalogsDrift.join("; ")}`
}));
return findings;
});
//#endregion
exports.APP_PATH = APP_PATH;
exports.CATALOGS_PATH = CATALOGS_PATH;
exports.ROOT_PATH = ROOT_PATH;
exports.RUNTIME_IMPORT = RUNTIME_IMPORT;
exports.RUNTIME_PATH = RUNTIME_PATH;
exports.checkI18nSeam = checkI18nSeam;
exports.parseAppLocale = parseAppLocale;
exports.readI18nSeam = readI18nSeam;
//# sourceMappingURL=i18n-seam.cjs.map