TehShrike / deepmerge

A library for deep (recursive) merging of Javascript objects
MIT License
2.75k stars 216 forks source link

[feature request] more contextual info customMerge #229

Closed tlouisse closed 3 years ago

tlouisse commented 3 years ago

Hi,

Would it be possible to supply the target and source object to options.customMerge?

In the situation below, I want to check for the existence of source.objNeedingCustomMerge. So I want to check on a child key name instead of the default key (in the below case I would get b and c as the 'key' parameter, but I would like to know if source[key].objNeedingCustomMerge exists).

const targetObj = {
  // this obj needs deep merge
  a : { keyA1: 'xTarget', keyA2: 'yTarget', },
  // this object needs to be replaced by source.b
  b : { objNeedingCustomMerge: true, keyB1: 'z' },
  c : { objNeedingCustomMerge: true, keyC1: 'z' },
}

const sourceObj = {
  a : { keyA2: 'ySource', keyA3: 'zSource', },
  b : { somethingCompletely: 'different' },
  c : { somethingElse: 'different' },
}

Expected result:

{
  a : { keyA1: 'xTarget', keyA2: 'ySource', keyA3: 'zSource', },
  b : { somethingCompletely: 'different' },
  c : { somethingElse: 'different' },
}

Would it be possible to allow for this?

const result = deepmerge(targetObj, sourceObj, {
  customMerge: (key, targetCurrLvl, sourceCurrLvl) => {
     if ('objNeedingCustomMerge' in targetCurrLvl[key]) {
       return () => sourceCurrLvl[key];
     }
  },
});
RebeccaStevens commented 3 years ago

This should hopefully do what you want (completely untested):

const result = deepmerge(targetObj, sourceObj, {
  customMerge: (key) => (targetCurrLvl, sourceCurrLvl, options) => {
    if ('objNeedingCustomMerge' in targetCurrLvl[key]) {
      return sourceCurrLvl[key];
    }
    return deepmerge(targetCurrLvl, sourceCurrLvl, options);
  },
});
tlouisse commented 3 years ago

Ah, I see, since the fallback function is deepmerge again (https://github.com/TehShrike/deepmerge/blob/master/index.js#L24) Thanks! 👍

I also noticed this merge request implements the exact thing requested above, so will wait for that as well: https://github.com/TehShrike/deepmerge/pull/228/files#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346R64