// Reine, abhängigkeitsfreie Umwandlung zwischen dem verschachtelten // Dict-Objekt (lib/i18n/dictionaries.ts) und flachen Schlüssel-Wert- // Paaren ("login.errorGeneric") – Grundlage für Vorlage-Export/-Import // von Sprachpaketen. Arrays (z. B. weekdays.long) werden über den // numerischen Index als eigene Schlüssel geflattet ("weekdays.long.0") // und beim Zurückbauen anhand rein numerischer Kind-Schlüssel wieder // als Array erkannt. export function flattenDict(value: unknown, prefix = ""): Record { const out: Record = {}; function walk(node: unknown, path: string) { if (Array.isArray(node)) { node.forEach((item, i) => walk(item, `${path}.${i}`)); } else if (node !== null && typeof node === "object") { for (const [key, child] of Object.entries(node)) { walk(child, path ? `${path}.${key}` : key); } } else { out[path] = String(node); } } walk(value, prefix); return out; } export function unflattenDict(flat: Record): unknown { const root: Record = {}; for (const [path, value] of Object.entries(flat)) { const parts = path.split("."); let node: Record = root; for (let i = 0; i < parts.length - 1; i++) { const key = parts[i]; if (node[key] === undefined) { const nextIsIndex = /^\d+$/.test(parts[i + 1]); node[key] = nextIsIndex ? [] : {}; } node = node[key] as Record; } node[parts[parts.length - 1]] = value; } return root; }