@ou-imdt/utils
Version:
Utility library for interactive media development
36 lines (32 loc) • 1.65 kB
JavaScript
import getObjectProperty from './getObjectProperty.js'
import setObjectProperty from './setObjectProperty.js'
import splitPropertyPath from './splitPropertyPath.js';
import { default as mergeObject, isMergeable } from './mergeObject.js';
/**
* Transforms an object with the mapped values, optionally running the process in reverse.
* Merges objects by default to avoid overriding previous transforms.
* @param {object} target - The object to transform.
* @param {object} map - The values (from/to) for the transform.
* @param {(boolean|object)} [options] - options.reverse if boolean or object of options
* @param {boolean} [options.reverse=false] - The order mapped entries are applied.
* @param {boolean} [options.merge=true] - Whether mapped entries are merged
* @returns {object} - The cloned object with transforms applied
*/
export default function transformObject(target, map = {}, options = {}) {
const { reverse = false, merge = true } = (typeof options === 'boolean') ? { reverse: options } : options;
const clone = structuredClone(target);
for (const entry of Object.entries(map)) {
const [from, to] = reverse ? entry.reverse() : entry;
const sourceValue = getObjectProperty(target, from);
if (merge === true) {
if (isMergeable(sourceValue)) {
const targetValue = getObjectProperty(clone, to);
if (isMergeable(targetValue)) mergeObject(sourceValue, targetValue);
}
6 }
// option to handle undefined, options.callback?
if (typeof sourceValue !== 'undefined') setObjectProperty(clone, to, sourceValue);
delete clone[splitPropertyPath(from).shift()];
}
return clone;
}