UNPKG

merge-left-utils

Version:

Merge objects without structure changes

111 lines (94 loc) 3.62 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); /* naive check is input is like Object source: https://stackoverflow.com/a/38555871 */ const isLikeObject = (value) => typeof value === 'object' && value !== null && value.constructor === Object && Object.prototype.toString.call(value) === '[object Object]'; /* Function which always return true */ const alwaysTrue = () => true; /** Function merge objects {a} and {b} by [keys] If key from {b} is not presented in {a} - it does nothing If both objects has key - result will get key from {b} if value is seems like object - then we run function recursive for value keys - which keys will be checked for objects a - left b - right customLogic (a[key], target[key]) : boolean - if it returns true - then get value from {b}, else from {a} */ function mergeLeftKeys(keys, source, target, customLogic = alwaysTrue) { if (!target) { return source; } return keys.reduce((prev, key) => { if (Object.prototype.hasOwnProperty.call(target, key) && customLogic(key, source, target)) { if (isLikeObject(source[key])) { return Object.assign(Object.assign({}, prev), { [key]: mergeLeftKeys(Object.keys(source[key]), source[key], target[key], customLogic) }); } else { return Object.assign(Object.assign({}, prev), { [key]: target[key] }); } } else { return Object.assign(Object.assign({}, prev), { [key]: source[key] }); } }, {}); } /** Shortcut function Replace only existing fields in {a} with {b} ex: ({ a: 0, b: 0 }, { a: 1, x: 1 }) -> { a: 1, b: 0 } */ function mergeLeft(source, target, customLogic = alwaysTrue) { return mergeLeftKeys(Object.keys(source), source, target, customLogic); } /** Shortcut function Drops keys listed in {dropKeys} and replace existing fields in {a} with {b} ex: (['a'], { a: 0, b: 0 }, { a: 1, x: 1 }) -> { b: 0 } */ function mergeLeftDropping(dropKeys, source, target) { const replaceableKeys = Object.keys(source).filter((keyOfSource) => dropKeys.indexOf(keyOfSource) === -1); return mergeLeftKeys(replaceableKeys, source, target); } /** Shortcut function Replace only existing fields in {a} with {b} skipping {b} keys from {keys} ex: (['a'], { a: 0, b: 0 }, { a: 1, b: 1 }) -> { a: 0, b: 1 } */ function mergeLeftExcept(skippingKeys, source, target) { return mergeLeftKeys(Object.keys(source), source, target, (keyOfSource) => skippingKeys.indexOf(keyOfSource) === -1); } /** Shortcut function Replace only fields from [keys] arg in {a} with {b} ex: (['b'], { a: 0, b: 0 }, { a: 1, b: 1 }) -> { a: 0, b: 1 } */ function mergeLeftOnly(keys, source, target) { return mergeLeft(source, target, (key) => keys.includes(key)); } /** Shortcut function Replace only existing fields in {a} with {b} When field from {b} is truthy ex: ({ a: 0, b: 0 }, { a: 1, x: 1 }) -> { a: 1, b: 0 } */ function mergeLeftTruthy(source, target, customLogic = alwaysTrue) { return mergeLeftKeys(Object.keys(source), source, target, (key, source, target) => { return !!target[key] && customLogic(key, source, target); }); } exports.mergeLeft = mergeLeft; exports.mergeLeftDropping = mergeLeftDropping; exports.mergeLeftExcept = mergeLeftExcept; exports.mergeLeftKeys = mergeLeftKeys; exports.mergeLeftOnly = mergeLeftOnly; exports.mergeLeftTruthy = mergeLeftTruthy; //# sourceMappingURL=index.js.map