type PathNode = Record; const BLOCKED_KEYS = new Set(["__proto__", "prototype", "constructor"]); export function parseConfigPath(raw: string): { ok: boolean; path?: string[]; error?: string; } { const trimmed = raw.trim(); if (!trimmed) { return { ok: false, error: "Invalid path. Use dot notation (e.g. foo.bar).", }; } const parts = trimmed.split(".").map((part) => part.trim()); if (parts.some((part) => !part)) { return { ok: false, error: "Invalid path. Use dot notation (e.g. foo.bar).", }; } if (parts.some((part) => BLOCKED_KEYS.has(part))) { return { ok: false, error: "Invalid path segment." }; } return { ok: true, path: parts }; } export function setConfigValueAtPath( root: PathNode, path: string[], value: unknown, ): void { let cursor: PathNode = root; for (let idx = 0; idx < path.length - 1; idx += 1) { const key = path[idx]; const next = cursor[key]; if (!isPlainObject(next)) { cursor[key] = {}; } cursor = cursor[key] as PathNode; } cursor[path[path.length - 1]] = value; } export function unsetConfigValueAtPath( root: PathNode, path: string[], ): boolean { const stack: Array<{ node: PathNode; key: string }> = []; let cursor: PathNode = root; for (let idx = 0; idx < path.length - 1; idx += 1) { const key = path[idx]; const next = cursor[key]; if (!isPlainObject(next)) return false; stack.push({ node: cursor, key }); cursor = next; } const leafKey = path[path.length - 1]; if (!(leafKey in cursor)) return false; delete cursor[leafKey]; for (let idx = stack.length - 1; idx >= 0; idx -= 1) { const { node, key } = stack[idx]; const child = node[key]; if (isPlainObject(child) && Object.keys(child).length === 0) { delete node[key]; } else { break; } } return true; } export function getConfigValueAtPath(root: PathNode, path: string[]): unknown { let cursor: unknown = root; for (const key of path) { if (!isPlainObject(cursor)) return undefined; cursor = cursor[key]; } return cursor; } function isPlainObject(value: unknown): value is Record { return ( typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]" ); }