// Parse a JSON-valued settings row, client side. // // The counterpart to server/src/utils/settingsJson.js, and deliberately the same // three lines of judgement: `settings.value` is TEXT, so theme_visual, // brand_assets and the three nav_* keys all arrive as strings, and a malformed // or wrong-shaped one must read as **absent** — the surface falls back to its // BRAND_* env / theme.css / hardcoded NAV default — never as an error and never // as a half-applied object. // // THEMING_AND_NAV.md §4.4 planned this "with its first consumer"; that consumer // is the public header reading nav_public. `parseLayout` in heroLayout.js keeps // its own version check because it validates a shape, not just a shape's kind. /** * @param {string|null|undefined} str the raw stored value * @returns {object|null} the parsed object, or null when absent/malformed */ export function parseJsonSetting(str) { if (typeof str !== 'string' || str === '') return null let parsed try { parsed = JSON.parse(str) } catch { return null } // Only plain objects. A stored `null`, `4`, `"x"` or array is as unusable to // every consumer of these keys as a syntax error is. if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return null return parsed } export default parseJsonSetting