xref: /openbmc/webui-vue/src/utilities/objectUtils.js (revision d2483622fc31f6b965a052d0c4f999ad963d0a0f)
1*d2483622Sjason westover/**
2*d2483622Sjason westover * Deeply merge two plain objects (or arrays) without mutating the inputs.
3*d2483622Sjason westover *
4*d2483622Sjason westover * Rules:
5*d2483622Sjason westover * - Arrays from the source replace arrays on the target.
6*d2483622Sjason westover * - Plain objects are merged recursively.
7*d2483622Sjason westover * - Primitive values from the source overwrite the target.
8*d2483622Sjason westover */
9*d2483622Sjason westoverexport function deepMerge(target, source) {
10*d2483622Sjason westover  if (typeof target !== 'object' || target === null) return source;
11*d2483622Sjason westover  if (typeof source !== 'object' || source === null) return target;
12*d2483622Sjason westover  const output = Array.isArray(target) ? target.slice() : { ...target };
13*d2483622Sjason westover  Object.keys(source).forEach((key) => {
14*d2483622Sjason westover    const sourceValue = source[key];
15*d2483622Sjason westover    const targetValue = output[key];
16*d2483622Sjason westover    if (Array.isArray(sourceValue)) {
17*d2483622Sjason westover      output[key] = sourceValue.slice();
18*d2483622Sjason westover    } else if (
19*d2483622Sjason westover      typeof sourceValue === 'object' &&
20*d2483622Sjason westover      sourceValue !== null &&
21*d2483622Sjason westover      typeof targetValue === 'object' &&
22*d2483622Sjason westover      targetValue !== null &&
23*d2483622Sjason westover      !Array.isArray(targetValue)
24*d2483622Sjason westover    ) {
25*d2483622Sjason westover      output[key] = deepMerge(targetValue, sourceValue);
26*d2483622Sjason westover    } else {
27*d2483622Sjason westover      output[key] = sourceValue;
28*d2483622Sjason westover    }
29*d2483622Sjason westover  });
30*d2483622Sjason westover  return output;
31*d2483622Sjason westover}
32