UNPKG

super-utils-plus

Version:

A superior alternative to Lodash with improved performance, TypeScript support, and developer experience

86 lines (85 loc) 2.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.result = result; const is_1 = require("../utils/is"); /** * Resolves the value at path of object. If the resolved value is a function * it's invoked with the `this` binding of its parent object. * * @param object - The object to query * @param path - The path of the property to resolve * @param defaultValue - The value returned for undefined resolved values * @returns The resolved value */ function result(object, path, defaultValue) { if ((0, is_1.isNil)(object)) { return resolveDefaultValue(defaultValue, undefined); } const segments = normalizePath(path); if (!segments.length) { return object; } let current = object; let parent = object; for (const segment of segments) { if ((0, is_1.isNil)(current)) { return resolveDefaultValue(defaultValue, parent); } parent = current; current = current[segment]; } if (current === undefined) { return resolveDefaultValue(defaultValue, parent); } return (0, is_1.isFunction)(current) ? current.call(parent) : current; } function normalizePath(path) { if ((0, is_1.isString)(path)) { return parsePath(path); } if ((0, is_1.isArray)(path)) { return path; } return [path]; } function resolveDefaultValue(value, thisArg) { return (0, is_1.isFunction)(value) ? value.call(thisArg) : value; } function parsePath(path) { const segments = []; let currentSegment = ''; let inBrackets = false; for (let index = 0; index < path.length; index++) { const character = path[index]; if (character === '[') { if (currentSegment) { segments.push(currentSegment); currentSegment = ''; } inBrackets = true; } else if (character === ']') { if (/^\d+$/.test(currentSegment)) { segments.push(parseInt(currentSegment, 10)); } else { segments.push(currentSegment); } currentSegment = ''; inBrackets = false; } else if (character === '.' && !inBrackets) { if (currentSegment) { segments.push(currentSegment); currentSegment = ''; } } else { currentSegment += character; } } if (currentSegment) { segments.push(currentSegment); } return segments; }