All files / core/src/utilities deepMerge.ts

83.33% Statements 30/36
61.11% Branches 22/36
88.88% Functions 8/9
83.33% Lines 30/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87428x 47315x   47315x             428x           428x 86982x   86982x         428x 40x   40x 44x 44x                         40x     428x 12862x   12862x 12862x 57484x     12862x 34453x 29454x   4999x       12862x                   428x 12902x 12902x 12902x   12902x 40x         12862x        
const isMergeableObject = (val) => {
  const nonNullObject = val && typeof val === 'object';
 
  return (
    nonNullObject &&
    Object.prototype.toString.call(val) !== '[object RegExp]' &&
    Object.prototype.toString.call(val) !== '[object Date]'
  );
};
 
const emptyTarget = (val) => {
  const isEmpty = Array.isArray(val) ? [] : {};
 
  return isEmpty;
};
 
const cloneIfNecessary = (value, optionsArgument) => {
  const clone = optionsArgument && optionsArgument.clone === true;
 
  return clone && isMergeableObject(value)
    ? deepMerge(emptyTarget(value), value, optionsArgument)
    : value;
};
 
const defaultArrayMerge = (target, source, optionsArgument) => {
  const destination = target.slice();
 
  source.forEach(function (e, i) {
    if (typeof destination[i] === 'undefined') {
      destination[i] = cloneIfNecessary(e, optionsArgument);
    } else Eif (isMergeableObject(e)) {
      destination[i] = deepMerge(target[i], e, optionsArgument);
    } else if (target.indexOf(e) === -1) {
      // IMPORTANT: WE SHOULD NOT PUSH NEW ELEMENTS TO THE ARRAY
      // INSTEAD WE SHOULD REPLACE THE ELEMENT, this will result
      // in unexpected behaviors if the initial tool parameters
      // are desired to override the default tool parameters that are
      // arrays
      destination[i] = cloneIfNecessary(e, optionsArgument);
    }
  });
 
  return destination;
};
 
const mergeObject = (target, source, optionsArgument) => {
  const destination = {};
 
  Eif (isMergeableObject(target)) {
    Object.keys(target).forEach(function (key) {
      destination[key] = cloneIfNecessary(target[key], optionsArgument);
    });
  }
  Object.keys(source).forEach(function (key) {
    if (!isMergeableObject(source[key]) || !target[key]) {
      destination[key] = cloneIfNecessary(source[key], optionsArgument);
    } else {
      destination[key] = deepMerge(target[key], source[key], optionsArgument);
    }
  });
 
  return destination;
};
 
/**
 * Merge two objects, recursively merging any objects that are arrays
 * @param target - The target object.
 * @param source - The source object to merge into the target object.
 * @param optionsArgument - The options object.
 * @returns The merged object.
 */
const deepMerge = (target = {}, source = {}, optionsArgument = undefined) => {
  const array = Array.isArray(source);
  const options = optionsArgument || { arrayMerge: defaultArrayMerge };
  const arrayMerge = options.arrayMerge || defaultArrayMerge;
 
  if (array) {
    return Array.isArray(target)
      ? arrayMerge(target, source, optionsArgument)
      : cloneIfNecessary(source, optionsArgument);
  }
 
  return mergeObject(target, source, optionsArgument);
};
 
export default deepMerge;