import { isMap, isArray, isPlainObject, isSet } from './is.js'; import { includes } from './util.js'; const getNthKey = (value, n) => { if (n > value.size) throw new Error('index out of bounds'); const keys = value.keys(); while (n > 0) { keys.next(); n--; } return keys.next().value; }; function validatePath(path) { if (includes(path, '__proto__')) { throw new Error('__proto__ is not allowed as a property'); } if (includes(path, 'prototype')) { throw new Error('prototype is not allowed as a property'); } if (includes(path, 'constructor')) { throw new Error('constructor is not allowed as a property'); } } export const getDeep = (object, path) => { validatePath(path); for (let i = 0; i < path.length; i++) { const key = path[i]; if (isSet(object)) { object = getNthKey(object, +key); } else if (isMap(object)) { const row = +key; const type = +path[++i] === 0 ? 'key' : 'value'; const keyOfRow = getNthKey(object, row); switch (type) { case 'key': object = keyOfRow; break; case 'value': object = object.get(keyOfRow); break; } } else { object = object[key]; } } return object; }; export const setDeep = (object, path, mapper) => { validatePath(path); if (path.length === 0) { return mapper(object); } let parent = object; for (let i = 0; i < path.length - 1; i++) { const key = path[i]; if (isArray(parent)) { const index = +key; parent = parent[index]; } else if (isPlainObject(parent)) { parent = parent[key]; } else if (isSet(parent)) { const row = +key; parent = getNthKey(parent, row); } else if (isMap(parent)) { const isEnd = i === path.length - 2; if (isEnd) { break; } const row = +key; const type = +path[++i] === 0 ? 'key' : 'value'; const keyOfRow = getNthKey(parent, row); switch (type) { case 'key': parent = keyOfRow; break; case 'value': parent = parent.get(keyOfRow); break; } } } const lastKey = path[path.length - 1]; if (isArray(parent)) { parent[+lastKey] = mapper(parent[+lastKey]); } else if (isPlainObject(parent)) { parent[lastKey] = mapper(parent[lastKey]); } if (isSet(parent)) { const oldValue = getNthKey(parent, +lastKey); const newValue = mapper(oldValue); if (oldValue !== newValue) { parent.delete(oldValue); parent.add(newValue); } } if (isMap(parent)) { const row = +path[path.length - 2]; const keyToRow = getNthKey(parent, row); const type = +lastKey === 0 ? 'key' : 'value'; switch (type) { case 'key': { const newKey = mapper(keyToRow); parent.set(newKey, parent.get(keyToRow)); if (newKey !== keyToRow) { parent.delete(keyToRow); } break; } case 'value': { parent.set(keyToRow, mapper(parent.get(keyToRow))); break; } } } return object; }; //# sourceMappingURL=accessDeep.js.map