{"version":3,"file":"mergeDeep.js","names":[],"sources":["../src/mergeDeep.ts"],"sourcesContent":["import type { MergeDeep } from \"type-fest\";\nimport { isPlainObject } from \"./isPlainObject\";\nimport { purry } from \"./purry\";\n\n/**\n * Merges the `source` object into the `destination` object. The merge is similar to performing `{ ...destination, ... source }` (where disjoint values from each object would be copied as-is, and for any overlapping props the value from `source` would be used); But for *each prop* (`p`), if **both** `destination` and `source` have a **plain-object** as a value, the value would be taken as the result of recursively deepMerging them (`result.p === deepMerge(destination.p, source.p)`).\n *\n * @param destination - The object to merge into. In general, this object would have it's values overridden.\n * @param source - The object to merge from. In general, shared keys would be taken from this object.\n * @returns The merged object.\n * @signature\n *    mergeDeep(destination, source)\n * @example\n *    mergeDeep({ foo: 'bar', x: 1 }, { foo: 'baz', y: 2 }) // => { foo: 'baz', x: 1, y: 2 }\n * @dataFirst\n * @category Object\n */\nexport function mergeDeep<Destination extends object, Source extends object>(\n  destination: Destination,\n  source: Source,\n): MergeDeep<Destination, Source>;\n\n/**\n * Merges the `source` object into the `destination` object. The merge is similar to performing `{ ...destination, ... source }` (where disjoint values from each object would be copied as-is, and for any overlapping props the value from `source` would be used); But for *each prop* (`p`), if **both** `destination` and `source` have a **plain-object** as a value, the value would be taken as the result of recursively deepMerging them (`result.p === deepMerge(destination.p, source.p)`).\n *\n * @param source - The object to merge from. In general, shared keys would be taken from this object.\n * @returns The merged object.\n * @signature\n *    mergeDeep(source)(destination)\n * @example\n *    pipe(\n *      { foo: 'bar', x: 1 },\n *      mergeDeep({ foo: 'baz', y: 2 }),\n *    );  // => { foo: 'baz', x: 1, y: 2 }\n * @dataLast\n * @category Object\n */\nexport function mergeDeep<Source extends object>(\n  source: Source,\n): <Destination extends object>(\n  target: Destination,\n) => MergeDeep<Destination, Source>;\n\nexport function mergeDeep(...args: readonly unknown[]): unknown {\n  return purry(mergeDeepImplementation, args);\n}\n\nfunction mergeDeepImplementation<\n  Destination extends object,\n  Source extends object,\n>(destination: Destination, source: Source): MergeDeep<Destination, Source> {\n  // At this point the output is already merged, simply not deeply merged.\n  const output = { ...destination, ...source } as Record<\n    keyof Destination | keyof Source,\n    unknown\n  >;\n\n  // now just scan the output and look for values that should have been deep-\n  // merged\n  for (const key in source) {\n    if (!(key in destination)) {\n      // They don't share this key.\n      continue;\n    }\n\n    const { [key]: destinationValue } = destination;\n    if (!isPlainObject(destinationValue)) {\n      // The value in destination is not a mergeable object so the value from\n      // source (which was already copied in the shallow merge) would be used\n      // as-is.\n      continue;\n    }\n\n    const { [key]: sourceValue } = source;\n    if (!isPlainObject(sourceValue)) {\n      // The value in source is not a mergeable object either, so it will\n      // override the object in destination.\n      continue;\n    }\n\n    // Both destination and source have a mergeable object for this key, so we\n    // recursively merge them.\n    // @ts-expect-error [ts2590] - We build the output object iteratively, I don't think it's possible to improve the types here so that typescript infers this correctly.\n    output[key] = mergeDeepImplementation(destinationValue, sourceValue);\n  }\n\n  // @ts-expect-error [ts2322] - We build the output object iteratively, I don't think it's possible to improve the types here so that typescript infers this correctly.\n  return output;\n}\n"],"mappings":"sFA2CA,SAAgB,EAAU,GAAG,EAAmC,CAC9D,OAAO,EAAM,EAAyB,EAAK,CAG7C,SAAS,EAGP,EAA0B,EAAgD,CAE1E,IAAM,EAAS,CAAE,GAAG,EAAa,GAAG,EAAQ,CAO5C,IAAK,IAAM,KAAO,EAAQ,CACxB,GAAI,EAAE,KAAO,GAEX,SAGF,GAAM,EAAG,GAAM,GAAqB,EACpC,GAAI,CAAC,EAAc,EAAiB,CAIlC,SAGF,GAAM,EAAG,GAAM,GAAgB,EAC1B,EAAc,EAAY,GAS/B,EAAO,GAAO,EAAwB,EAAkB,EAAY,EAItE,OAAO"}