12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- 'use strict';
- const Assert = require('./assert');
- const internals = {};
- module.exports = function (obj, chain, options) {
- if (chain === false ||
- chain === null ||
- chain === undefined) {
- return obj;
- }
- options = options || {};
- if (typeof options === 'string') {
- options = { separator: options };
- }
- const isChainArray = Array.isArray(chain);
- Assert(!isChainArray || !options.separator, 'Separator option no valid for array-based chain');
- const path = isChainArray ? chain : chain.split(options.separator || '.');
- let ref = obj;
- for (let i = 0; i < path.length; ++i) {
- let key = path[i];
- const type = options.iterables && internals.iterables(ref);
- if (Array.isArray(ref) ||
- type === 'set') {
- const number = Number(key);
- if (Number.isInteger(number)) {
- key = number < 0 ? ref.length + number : number;
- }
- }
- if (!ref ||
- typeof ref === 'function' && options.functions === false || // Defaults to true
- !type && ref[key] === undefined) {
- Assert(!options.strict || i + 1 === path.length, 'Missing segment', key, 'in reach path ', chain);
- Assert(typeof ref === 'object' || options.functions === true || typeof ref !== 'function', 'Invalid segment', key, 'in reach path ', chain);
- ref = options.default;
- break;
- }
- if (!type) {
- ref = ref[key];
- }
- else if (type === 'set') {
- ref = [...ref][key];
- }
- else { // type === 'map'
- ref = ref.get(key);
- }
- }
- return ref;
- };
- internals.iterables = function (ref) {
- if (ref instanceof Set) {
- return 'set';
- }
- if (ref instanceof Map) {
- return 'map';
- }
- };
|