(path: string, value: unknown)
| 30 | const KNOB_BY_PATH = new Map(CONFIG_KNOBS.map(k => [k.path, k])); |
| 31 | |
| 32 | /** Validate + coerce a config-set against the whitelist. PURE. */ |
| 33 | export function validateConfigSet(path: string, value: unknown): { ok: true; coerced: boolean | string } | { ok: false; error: string } { |
| 34 | const knob = KNOB_BY_PATH.get(path); |
| 35 | if (!knob) return { ok: false, error: `"${path}" is not a controllable setting` }; |
| 36 | if (knob.type === 'bool') { |
| 37 | if (value === true || value === false) return { ok: true, coerced: value }; |
| 38 | if (value === 'true' || value === 'false') return { ok: true, coerced: value === 'true' }; |
| 39 | return { ok: false, error: `${knob.label} expects true/false` }; |
| 40 | } |
| 41 | // enum |
| 42 | if (typeof value === 'string' && knob.values!.includes(value)) return { ok: true, coerced: value }; |
| 43 | return { ok: false, error: `${knob.label} expects one of: ${knob.values!.join(', ')}` }; |
| 44 | } |
| 45 | |
| 46 | /** Set a dotted path on a plain object, creating intermediate objects. PURE. */ |
no test coverage detected