UNPKG

@voxpelli/typed-utils

Version:

My personal (type-enabled) utils / helpers

107 lines (89 loc) 2.56 kB
/** * @overload * @param {unknown} obj * @param {string[]|string} path * @param {false} [createIfMissing] * @returns {Record<string, unknown>|undefined|false} */ /** * @overload * @param {unknown} obj * @param {string[]|string} path * @param {true} createIfMissing * @returns {Record<string, unknown>|false} */ /** * @param {unknown} obj * @param {string[]|string} path * @param {boolean} [createIfMissing] * @returns {Record<string, unknown>|undefined|false} */ export function getObjectValueByPath (obj, path, createIfMissing) { if (!obj || typeof obj !== 'object') { return false; } const pathKeys = Array.isArray(path) ? [...path] : path.split('.'); let currentValue = /** @type {Record<string, unknown>} */ (obj); for (const key of pathKeys) { if (key === '__proto__' || key === 'constructor' || key === 'prototype') { throw new Error(`Do not include "${key}" in your path`); } const nextValue = currentValue[key]; if (nextValue === undefined) { if (!createIfMissing) { return; } /** @type {Record<string, unknown>} */ const newValue = {}; currentValue[key] = newValue; currentValue = newValue; } else if (nextValue && typeof nextValue === 'object') { currentValue = /** @type {Record<string, unknown>} */ (nextValue); } else { return false; } } return currentValue; } /** * @param {unknown} obj * @param {string[]|string} path * @returns {{ value: unknown; }|undefined|false} */ export function getValueByPath (obj, path) { if (!obj || typeof obj !== 'object') { return false; } const pathKeys = Array.isArray(path) ? [...path] : path.split('.'); const finalKey = pathKeys.pop(); if (!finalKey) { return; } if (finalKey === '__proto__' || finalKey === 'constructor' || finalKey === 'prototype') { throw new Error(`Do not include "${finalKey}" in your path`); } const objectValue = pathKeys.length ? getObjectValueByPath(obj, pathKeys) : /** @type {Record<string, unknown>} */ (obj); if (!objectValue) { return objectValue; } const value = objectValue[finalKey]; return value === undefined ? undefined : { value }; } /** * @param {unknown} obj * @param {string[]|string} path * @returns {string|undefined|false} */ export function getStringValueByPath (obj, path) { const result = getValueByPath(obj, path); if (typeof result !== 'object') { return result; } return typeof result.value === 'string' ? result.value : false; }