/** * Tooling helpers for translation resources. Used by the repo-level * `pnpm i18n:check` script and its tests: every key must exist in every * language, in both directions. */ type TranslationTree = { [key: string]: string | TranslationTree }; /** Flattens {a:{b:"x"}} to ["a.b"]. */ export function translationKeys(tree: TranslationTree, prefix = ''): string[] { return Object.entries(tree).flatMap(([key, value]) => { const path = prefix ? `${prefix}.${key}` : key; return typeof value === 'string' ? [path] : translationKeys(value, path); }); } /** Keys present in `reference` but missing in `candidate`. */ export function missingTranslationKeys( reference: TranslationTree, candidate: TranslationTree, ): string[] { const have = new Set(translationKeys(candidate)); return translationKeys(reference).filter((key) => !have.has(key)); }