UNPKG

@ou-imdt/utils

Version:

Utility library for interactive media development

46 lines (42 loc) 1.61 kB
import splitPropertyPath from './splitPropertyPath.js'; /** * Sets the value at the specified path of an object. * Supports propertyPathRegex groups @see {@link propertyPathRegex}. * @param {object} target - The object in which to set the value. * @param {string} path - The dot/bracket notation path specifying where to set the value. * @param {*} value - The value to set at the specified path. * @returns {boolean} `true` if successful, otherwise `false`. */ export default function setObjectProperty(target, path, value) { const parts = splitPropertyPath(path, true); const convert = { '?': val => Boolean(val), '$': val => String(val), '#': val => Number(val), default: val => val }; for (const el of parts) { const { part, before, key, type, after } = el; try { path = path.slice(part.length); if (typeof target[key] === 'undefined') { const nextPart = parts[parts.indexOf(el) + 1]; const expectsArray = (type === '[]') || (!Number.isNaN(parseInt(nextPart?.key)) && /[^'"]/.test(`${nextPart?.before}${nextPart?.after}`)); target[key] = (expectsArray ? [] : {}); } if (type === '[]') { return value.every((el, index) => setObjectProperty(target[key], `[${index}]${path}`, el)); } if (parts.indexOf(el) < parts.length - 1) { target = target[key]; continue; } target[key] = convert[type ?? 'default'](value); return true; } catch(err) { console.error(`unable to set object property '${key}':`, err); return false; } } return false; }