/** * @license nested-property https://github.com/cosmosio/nested-property * * The MIT License (MIT) * * Copyright (c) 2014-2020 Olivier Scherrer */ "use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } var ARRAY_WILDCARD = "+"; var PATH_DELIMITER = "."; var ObjectPrototypeMutationError = /*#__PURE__*/function (_Error) { _inherits(ObjectPrototypeMutationError, _Error); function ObjectPrototypeMutationError(params) { var _this; _classCallCheck(this, ObjectPrototypeMutationError); _this = _possibleConstructorReturn(this, _getPrototypeOf(ObjectPrototypeMutationError).call(this, params)); _this.name = "ObjectPrototypeMutationError"; return _this; } return ObjectPrototypeMutationError; }(_wrapNativeSuper(Error)); module.exports = { set: setNestedProperty, get: getNestedProperty, has: hasNestedProperty, hasOwn: function hasOwn(object, property, options) { return this.has(object, property, options || { own: true }); }, isIn: isInNestedProperty, ObjectPrototypeMutationError: ObjectPrototypeMutationError }; /** * Get the property of an object nested in one or more objects or array * Given an object such as a.b.c.d = 5, getNestedProperty(a, "b.c.d") will return 5. * It also works through arrays. Given a nested array such as a[0].b = 5, getNestedProperty(a, "0.b") will return 5. * For accessing nested properties through all items in an array, you may use the array wildcard "+". * For instance, getNestedProperty([{a:1}, {a:2}, {a:3}], "+.a") will return [1, 2, 3] * @param {Object} object the object to get the property from * @param {String} property the path to the property as a string * @returns the object or the the property value if found */ function getNestedProperty(object, property) { if (_typeof(object) != "object" || object === null) { return object; } if (typeof property == "undefined") { return object; } if (typeof property == "number") { return object[property]; } try { return traverse(object, property, function _getNestedProperty(currentObject, currentProperty) { return currentObject[currentProperty]; }); } catch (err) { return object; } } /** * Tell if a nested object has a given property (or array a given index) * given an object such as a.b.c.d = 5, hasNestedProperty(a, "b.c.d") will return true. * It also returns true if the property is in the prototype chain. * @param {Object} object the object to get the property from * @param {String} property the path to the property as a string * @param {Object} options: * - own: set to reject properties from the prototype * @returns true if has (property in object), false otherwise */ function hasNestedProperty(object, property) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (_typeof(object) != "object" || object === null) { return false; } if (typeof property == "undefined") { return false; } if (typeof property == "number") { return property in object; } try { var has = false; traverse(object, property, function _hasNestedProperty(currentObject, currentProperty, segments, index) { if (isLastSegment(segments, index)) { if (options.own) { has = currentObject.hasOwnProperty(currentProperty); } else { has = currentProperty in currentObject; } } else { return currentObject && currentObject[currentProperty]; } }); return has; } catch (err) { return false; } } /** * Set the property of an object nested in one or more objects * If the property doesn't exist, it gets created. * @param {Object} object * @param {String} property * @param value the value to set * @returns object if no assignment was made or the value if the assignment was made */ function setNestedProperty(object, property, value) { if (_typeof(object) != "object" || object === null) { return object; } if (typeof property == "undefined") { return object; } if (typeof property == "number") { object[property] = value; return object[property]; } try { return traverse(object, property, function _setNestedProperty(currentObject, currentProperty, segments, index) { if (currentObject === Reflect.getPrototypeOf({})) { throw new ObjectPrototypeMutationError("Attempting to mutate Object.prototype"); } if (!currentObject[currentProperty]) { var nextPropIsNumber = Number.isInteger(Number(segments[index + 1])); var nextPropIsArrayWildcard = segments[index + 1] === ARRAY_WILDCARD; if (nextPropIsNumber || nextPropIsArrayWildcard) { currentObject[currentProperty] = []; } else { currentObject[currentProperty] = {}; } } if (isLastSegment(segments, index)) { currentObject[currentProperty] = value; } return currentObject[currentProperty]; }); } catch (err) { if (err instanceof ObjectPrototypeMutationError) { // rethrow throw err; } else { return object; } } } /** * Tell if an object is on the path to a nested property * If the object is on the path, and the path exists, it returns true, and false otherwise. * @param {Object} object to get the nested property from * @param {String} property name of the nested property * @param {Object} objectInPath the object to check * @param {Object} options: * - validPath: return false if the path is invalid, even if the object is in the path * @returns {boolean} true if the object is on the path */ function isInNestedProperty(object, property, objectInPath) { var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; if (_typeof(object) != "object" || object === null) { return false; } if (typeof property == "undefined") { return false; } try { var isIn = false, pathExists = false; traverse(object, property, function _isInNestedProperty(currentObject, currentProperty, segments, index) { isIn = isIn || currentObject === objectInPath || !!currentObject && currentObject[currentProperty] === objectInPath; pathExists = isLastSegment(segments, index) && _typeof(currentObject) === "object" && currentProperty in currentObject; return currentObject && currentObject[currentProperty]; }); if (options.validPath) { return isIn && pathExists; } else { return isIn; } } catch (err) { return false; } } function traverse(object, path) { var callback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {}; var segments = path.split(PATH_DELIMITER); var length = segments.length; var _loop = function _loop(idx) { var currentSegment = segments[idx]; if (!object) { return { v: void 0 }; } if (currentSegment === ARRAY_WILDCARD) { if (Array.isArray(object)) { return { v: object.map(function (value, index) { var remainingSegments = segments.slice(idx + 1); if (remainingSegments.length > 0) { return traverse(value, remainingSegments.join(PATH_DELIMITER), callback); } else { return callback(object, index, segments, idx); } }) }; } else { var pathToHere = segments.slice(0, idx).join(PATH_DELIMITER); throw new Error("Object at wildcard (".concat(pathToHere, ") is not an array")); } } else { object = callback(object, currentSegment, segments, idx); } }; for (var idx = 0; idx < length; idx++) { var _ret = _loop(idx); if (_typeof(_ret) === "object") return _ret.v; } return object; } function isLastSegment(segments, index) { return segments.length === index + 1; }