59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
/**
|
|
* Helper for spinning up a real `@suaveplan/i18n` `I18nInstance` plus
|
|
* the `react-forms` recipe-default bundles for use inside tests. No
|
|
* mocks — every test that needs a `<TranslationProvider>` builds a
|
|
* real instance via this helper so wiring matches production.
|
|
*/
|
|
|
|
import { createI18n, type I18nInstance } from "@suaveplan/i18n/plugin";
|
|
import {
|
|
reactFormsBundles,
|
|
type SupportedFormsLocale,
|
|
} from "../../src/locales/locales.js";
|
|
|
|
export interface CreateTestI18nOptions {
|
|
readonly locale?: SupportedFormsLocale;
|
|
}
|
|
|
|
type NestedTranslationRecord = {
|
|
[key: string]: string | NestedTranslationRecord;
|
|
};
|
|
|
|
function nestFlatKeys(bag: Record<string, string>): NestedTranslationRecord {
|
|
const out: NestedTranslationRecord = {};
|
|
for (const [flatKey, value] of Object.entries(bag)) {
|
|
const parts = flatKey.split(".");
|
|
let cursor: NestedTranslationRecord = out;
|
|
for (let i = 0; i < parts.length - 1; i += 1) {
|
|
const seg = parts[i] as string;
|
|
const existing = cursor[seg];
|
|
if (
|
|
typeof existing !== "object" ||
|
|
existing === null ||
|
|
Array.isArray(existing)
|
|
) {
|
|
cursor[seg] = {};
|
|
}
|
|
cursor = cursor[seg] as NestedTranslationRecord;
|
|
}
|
|
cursor[parts[parts.length - 1] as string] = value;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
export async function createTestI18n(
|
|
options: CreateTestI18nOptions = {}
|
|
): Promise<I18nInstance> {
|
|
const locale = options.locale ?? "en-GB";
|
|
const i18n = createI18n({
|
|
defaultLocale: locale,
|
|
fallbackLocale: "en-GB",
|
|
});
|
|
for (const code of ["en-GB", "zh-CN", "ar-AE", "cy-GB", "ru-RU"] as const) {
|
|
const bundle = await reactFormsBundles[code]();
|
|
const nested = nestFlatKeys(bundle as Record<string, string>);
|
|
i18n.catalog.mergeMessages(code, nested as Record<string, unknown>);
|
|
}
|
|
return i18n;
|
|
}
|