You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
'use strict'; const isObj = require('is-obj');
const disallowedKeys = [ '__proto__', 'prototype', 'constructor' ];
const isValidPath = pathSegments => !pathSegments.some(segment => disallowedKeys.includes(segment));
function getPathSegments(path) { const pathArray = path.split('.'); const parts = [];
for (let i = 0; i < pathArray.length; i++) { let p = pathArray[i];
while (p[p.length - 1] === '\\' && pathArray[i + 1] !== undefined) { p = p.slice(0, -1) + '.'; p += pathArray[++i]; }
parts.push(p); }
if (!isValidPath(parts)) { return []; }
return parts; }
module.exports = { get(object, path, value) { if (!isObj(object) || typeof path !== 'string') { return value === undefined ? object : value; }
const pathArray = getPathSegments(path); if (pathArray.length === 0) { return; }
for (let i = 0; i < pathArray.length; i++) { if (!Object.prototype.propertyIsEnumerable.call(object, pathArray[i])) { return value; }
object = object[pathArray[i]];
if (object === undefined || object === null) { // `object` is either `undefined` or `null` so we want to stop the loop, and
// if this is not the last bit of the path, and
// if it did't return `undefined`
// it would return `null` if `object` is `null`
// but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied value, not `null`
if (i !== pathArray.length - 1) { return value; }
break; } }
return object; },
set(object, path, value) { if (!isObj(object) || typeof path !== 'string') { return object; }
const root = object; const pathArray = getPathSegments(path);
for (let i = 0; i < pathArray.length; i++) { const p = pathArray[i];
if (!isObj(object[p])) { object[p] = {}; }
if (i === pathArray.length - 1) { object[p] = value; }
object = object[p]; }
return root; },
delete(object, path) { if (!isObj(object) || typeof path !== 'string') { return false; }
const pathArray = getPathSegments(path);
for (let i = 0; i < pathArray.length; i++) { const p = pathArray[i];
if (i === pathArray.length - 1) { delete object[p]; return true; }
object = object[p];
if (!isObj(object)) { return false; } } },
has(object, path) { if (!isObj(object) || typeof path !== 'string') { return false; }
const pathArray = getPathSegments(path); if (pathArray.length === 0) { return false; }
// eslint-disable-next-line unicorn/no-for-loop
for (let i = 0; i < pathArray.length; i++) { if (isObj(object)) { if (!(pathArray[i] in object)) { return false; }
object = object[pathArray[i]]; } else { return false; } }
return true; } };
|