245 keys had accumulated in en/es only (trustUi, labOptions, cordnUi, socialUi, walletUi, marketTerms, …), leaving every other locale at 97%. Backfilled 245x20 = 4,900 strings into src/i18n/<lang>/drift.ts and merged them through a new shared src/i18n/deepMerge.ts — a shallow ...drift spread would clobber existing namespaces, so index.ts deep-merges instead. Verified: check-i18n all 20 at 100%, tsc + eslint clean.
23 lines
889 B
TypeScript
23 lines
889 B
TypeScript
type TranslationDict = { [key: string]: string | TranslationDict };
|
|
|
|
/**
|
|
* Recursively merge `extra` into `base`, so a partial fragment ADDS keys into
|
|
* existing namespaces instead of replacing them. A shallow spread would clobber a
|
|
* whole namespace (e.g. `...drift` last would drop every other `socialUi` key).
|
|
* Plain nested string dictionaries only.
|
|
*/
|
|
export function deepMerge<T extends TranslationDict>(base: T, extra: TranslationDict): T {
|
|
const out: TranslationDict = { ...base };
|
|
for (const [key, value] of Object.entries(extra)) {
|
|
const current = out[key];
|
|
if (
|
|
value && typeof value === 'object' && !Array.isArray(value) &&
|
|
current && typeof current === 'object' && !Array.isArray(current)
|
|
) {
|
|
out[key] = deepMerge(current as TranslationDict, value as TranslationDict);
|
|
} else {
|
|
out[key] = value;
|
|
}
|
|
}
|
|
return out as T;
|
|
}
|