UNPKG

@opentelemetry/core

Version:

OpenTelemetry Core provides constants and utilities shared by all OpenTelemetry SDK packages.

114 lines (113 loc) • 3.52 kB
const require_lodash_merge = require("./lodash.merge.cjs"); //#region src/utils/merge.ts const MAX_LEVEL = 20; /** * Merges objects together * @param args - objects / values to be merged */ function merge(...args) { let result = args.shift(); const objects = /* @__PURE__ */ new WeakMap(); while (args.length > 0) result = mergeTwoObjects(result, args.shift(), 0, objects); return result; } function takeValue(value) { if (isArray(value)) return value.slice(); return value; } /** * Merges two objects * @param one - first object * @param two - second object * @param level - current deep level * @param objects - objects holder that has been already referenced - to prevent * cyclic dependency */ function mergeTwoObjects(one, two, level = 0, objects) { let result; if (level > MAX_LEVEL) return; level++; if (isPrimitive(one) || isPrimitive(two) || isFunction(two)) result = takeValue(two); else if (isArray(one)) { result = one.slice(); if (isArray(two)) for (let i = 0, j = two.length; i < j; i++) result.push(takeValue(two[i])); else if (isObject(two)) { const keys = Object.keys(two); for (let i = 0, j = keys.length; i < j; i++) { const key = keys[i]; if (key === "__proto__" || key === "constructor" || key === "prototype") continue; result[key] = takeValue(two[key]); } } } else if (isObject(one)) { if (isObject(two)) { if (!shouldMerge(one, two)) return two; result = Object.assign({}, one); const keys = Object.keys(two); for (let i = 0, j = keys.length; i < j; i++) { const key = keys[i]; if (key === "__proto__" || key === "constructor" || key === "prototype") continue; const twoValue = two[key]; if (isPrimitive(twoValue)) { if (typeof twoValue === "undefined") delete result[key]; else result[key] = twoValue; } else { const obj1 = result[key]; const obj2 = twoValue; if (wasObjectReferenced(one, key, objects) || wasObjectReferenced(two, key, objects)) delete result[key]; else { if (isObject(obj1) && isObject(obj2)) { const arr1 = objects.get(obj1) || []; const arr2 = objects.get(obj2) || []; arr1.push({ obj: one, key }); arr2.push({ obj: two, key }); objects.set(obj1, arr1); objects.set(obj2, arr2); } result[key] = mergeTwoObjects(result[key], twoValue, level, objects); } } } } else result = two; } return result; } /** * Function to check if object has been already reference * @param obj * @param key * @param objects */ function wasObjectReferenced(obj, key, objects) { const arr = objects.get(obj[key]) || []; for (let i = 0, j = arr.length; i < j; i++) { const info = arr[i]; if (info.key === key && info.obj === obj) return true; } return false; } function isArray(value) { return Array.isArray(value); } function isFunction(value) { return typeof value === "function"; } function isObject(value) { return !isPrimitive(value) && !isArray(value) && !isFunction(value) && typeof value === "object"; } function isPrimitive(value) { return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "undefined" || value instanceof Date || value instanceof RegExp || value === null; } function shouldMerge(one, two) { if (!require_lodash_merge.isPlainObject(one) || !require_lodash_merge.isPlainObject(two)) return false; return true; } //#endregion exports.merge = merge; //# sourceMappingURL=merge.cjs.map