{"version":3,"file":"mergeInto.mjs","names":[],"sources":["../../src/util/mergeInto.ts"],"sourcesContent":["import { getType } from './typeUtils'\n\ntype Merged<TDestination, TSource> =\n  // case 1 - source is undefined - return destination\n  TSource extends undefined\n    ? TDestination\n    : // case 2 - destination is undefined - return source\n      TDestination extends undefined\n      ? TSource\n      : // case 3 - source is an array - see if it merges or overwrites\n        TSource extends any[]\n        ? TDestination extends any[]\n          ? TDestination & TSource\n          : TSource\n        : // case 4 - source is an object - see if it merges or overwrites\n          TSource extends object\n          ? TDestination extends object\n            ? TDestination extends any[]\n              ? TSource\n              : TDestination & TSource\n            : TSource\n          : // case 5 - cannot merge - return source\n            TSource\n\n/**\n * Recursively merges `source` into `destination` in place and returns the result.\n * - Objects are merged key by key.\n * - Arrays are merged index by index.\n * - Primitive and class-instance values replace the destination.\n * - `undefined` source values leave the destination unchanged.\n * - Circular references in `source` are silently dropped.\n *\n * Prefer `combine` for a non-mutating deep merge or `deepClone` for a simple deep copy.\n *\n * @returns The merged value — either `destination` (mutated) or `source` when they cannot be merged.\n */\nexport function mergeInto<D, S>(destination: D, source: S): Merged<D, S> {\n  return mergeIntoInternal(destination, source, createCircularReferenceChecker())\n}\n\nfunction mergeIntoInternal<D, S>(\n  destination: D,\n  source: S,\n  circularReferenceChecker: CircularReferenceChecker\n): Merged<D, S> {\n  // ignore the source if it is undefined\n  if (source === undefined) {\n    return destination as Merged<D, S>\n  }\n\n  if (typeof source !== 'object' || source === null) {\n    // primitive values - just return source\n    return source as Merged<D, S>\n  } else if (source instanceof Date) {\n    return new Date(source.getTime()) as unknown as Merged<D, S>\n  } else if (source instanceof RegExp) {\n    return new RegExp(source.source, source.flags) as unknown as Merged<D, S>\n  }\n\n  if (circularReferenceChecker.hasAlreadyBeenSeen(source)) {\n    // remove circular references\n    return undefined as unknown as Merged<D, S>\n  } else if (Array.isArray(source)) {\n    const merged: any[] = Array.isArray(destination) ? destination : []\n    for (let i = 0; i < source.length; ++i) {\n      merged[i] = mergeIntoInternal(merged[i], source[i], circularReferenceChecker)\n    }\n    return merged as unknown as Merged<D, S>\n  }\n\n  const merged = getType(destination) === 'object' ? (destination as Record<any, any>) : {}\n  for (const key in source) {\n    // Skip __proto__: it resolves to Object.prototype via [[Get]], enabling prototype pollution\n    if (Object.prototype.hasOwnProperty.call(source, key) && key !== '__proto__') {\n      merged[key] = mergeIntoInternal(merged[key], source[key], circularReferenceChecker)\n    }\n  }\n  return merged as unknown as Merged<D, S>\n}\n\n/**\n * A simplistic implementation of a deep clone algorithm.\n * Caveats:\n * - It doesn't maintain prototype chains - don't use with instances of custom classes.\n * - It doesn't handle Map and Set\n *\n * @returns A deep copy of `value` with the same type.\n */\nexport function deepClone<T>(value: T): T {\n  return mergeInto(undefined, value) as T\n}\n\ntype Combined<A, B> = A extends null ? B : B extends null ? A : Merged<A, B>\n\n/**\n * Performs a non-mutating deep merge of two or more values.\n * - All arguments are left unchanged; the result is always a new value.\n * - Objects are merged key by key; arrays are merged index by index.\n * - `undefined` values are skipped (they do not overwrite existing values).\n * - `null` values replace existing values.\n *\n * @returns A new deeply-merged value of the combined type.\n * @example\n * combine({ a: 1 }, { b: 2 }) // { a: 1, b: 2 }\n * combine({ a: { x: 1 } }, { a: { y: 2 } }) // { a: { x: 1, y: 2 } }\n */\nexport function combine<A, B>(a: A, b: B): Combined<A, B>\nexport function combine<A, B, C>(a: A, b: B, c: C): Combined<Combined<A, B>, C>\nexport function combine<A, B, C, D>(a: A, b: B, c: C, d: D): Combined<Combined<Combined<A, B>, C>, D>\nexport function combine<A, B, C, D, E>(\n  a: A,\n  b: B,\n  c: C,\n  d: D,\n  e: E\n): Combined<Combined<Combined<Combined<A, B>, C>, D>, E>\nexport function combine<A, B, C, D, E, F>(\n  a: A,\n  b: B,\n  c: C,\n  d: D,\n  e: E,\n  f: F\n): Combined<Combined<Combined<Combined<Combined<A, B>, C>, D>, E>, F>\nexport function combine<A, B, C, D, E, F, G>(\n  a: A,\n  b: B,\n  c: C,\n  d: D,\n  e: E,\n  f: F,\n  g: G\n): Combined<Combined<Combined<Combined<Combined<Combined<A, B>, C>, D>, E>, F>, G>\nexport function combine<A, B, C, D, E, F, G, H>(\n  a: A,\n  b: B,\n  c: C,\n  d: D,\n  e: E,\n  f: F,\n  g: G,\n  h: H\n): Combined<Combined<Combined<Combined<Combined<Combined<Combined<A, B>, C>, D>, E>, F>, G>, H>\nexport function combine(...sources: any[]): unknown {\n  let destination: any\n\n  for (const source of sources) {\n    // Ignore any undefined or null sources.\n    if (source === undefined || source === null) {\n      continue\n    }\n\n    destination = mergeInto(destination, source)\n  }\n\n  return destination as unknown\n}\n\ninterface CircularReferenceChecker {\n  hasAlreadyBeenSeen(value: any): boolean\n}\n\nfunction createCircularReferenceChecker(): CircularReferenceChecker {\n  const set = new WeakSet<any>()\n  return {\n    hasAlreadyBeenSeen(value) {\n      const has = set.has(value)\n      if (!has) {\n        set.add(value)\n      }\n      return has\n    },\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;AAoCA,SAAgB,UAAgB,aAAgB,QAAyB;CACvE,OAAO,kBAAkB,aAAa,QAAQ,+BAA+B,CAAC;AAChF;AAEA,SAAS,kBACP,aACA,QACA,0BACc;CAEd,IAAI,WAAW,KAAA,GACb,OAAO;CAGT,IAAI,OAAO,WAAW,YAAY,WAAW,MAE3C,OAAO;MACF,IAAI,kBAAkB,MAC3B,OAAO,IAAI,KAAK,OAAO,QAAQ,CAAC;MAC3B,IAAI,kBAAkB,QAC3B,OAAO,IAAI,OAAO,OAAO,QAAQ,OAAO,KAAK;CAG/C,IAAI,yBAAyB,mBAAmB,MAAM,GAEpD;MACK,IAAI,MAAM,QAAQ,MAAM,GAAG;EAChC,MAAM,SAAgB,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC;EAClE,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,EAAE,GACnC,OAAO,KAAK,kBAAkB,OAAO,IAAI,OAAO,IAAI,wBAAwB;EAE9E,OAAO;CACT;CAEA,MAAM,SAAS,QAAQ,WAAW,MAAM,WAAY,cAAmC,CAAC;CACxF,KAAK,MAAM,OAAO,QAEhB,IAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,GAAG,KAAK,QAAQ,aAC/D,OAAO,OAAO,kBAAkB,OAAO,MAAM,OAAO,MAAM,wBAAwB;CAGtF,OAAO;AACT;;;;;;;;;AAUA,SAAgB,UAAa,OAAa;CACxC,OAAO,UAAU,KAAA,GAAW,KAAK;AACnC;AAqDA,SAAgB,QAAQ,GAAG,SAAyB;CAClD,IAAI;CAEJ,KAAK,MAAM,UAAU,SAAS;EAE5B,IAAI,WAAW,KAAA,KAAa,WAAW,MACrC;EAGF,cAAc,UAAU,aAAa,MAAM;CAC7C;CAEA,OAAO;AACT;AAMA,SAAS,iCAA2D;CAClE,MAAM,sBAAM,IAAI,QAAa;CAC7B,OAAO,EACL,mBAAmB,OAAO;EACxB,MAAM,MAAM,IAAI,IAAI,KAAK;EACzB,IAAI,CAAC,KACH,IAAI,IAAI,KAAK;EAEf,OAAO;CACT,EACF;AACF"}