| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 | '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;	}};
 |