Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
merge-dictionaries
Advanced tools
A wrapper around the Lodash 3 .merge()
function that addresses some issues with arrays and object references. Intended for merging configuration files together.
npm install merge-dictionaries
var mergeDictionaries = require('merge-dictionaries');
mergeDictionaries(dictA, dictB);
The .merge()
function works great in most cases, but the default behavior has two problems:
First, array values in the second argument are merged weirdly with values in the first argument. Examples:
// Two arrays are "merged" together by replacing values in the first array with values from
// the second, by index:
var dictA = { foo: ['owl', 'snake', 'fish'] };
var dictB = { foo: ['cat', 'dog']};
_.merge(dictA, dictB);
// Results in:
// { foo: ['cat', 'dog', 'fish'] }
// Merging an array into a string causes the string to be busted up into an array of characters,
// which is then merged on-top-of as above:
var dictA = { foo: 'abcde' };
var dictB = { foo: ['cat', 'dog']};
_.merge(dictA, dictB);
// Results in:
// { foo: ['cat', 'dog', 'c', 'd', 'e'] }
Second, dictionaries in the second argument that do not have corresponding dictionary values in the first argument (or whose corresponding values are {}
) are copied over by value instead of by reference:
var dictA = { foo: 'bar' };
var dictB = { nested: { owl: 'hoot' } };
var owl = dictB.nested; // <-- owl is { owl: 'hoot' }
var merged = _.merge(dictA, dictB);
// Results in:
// { foo: 'bar', nested: { owl: 'hoot' } }
console.log(owl === merged.nested);
// Results in:
// false
This might not seem like a big issue, but it can be a real problem when merging dictionaries that contain references to objects created by another module. For example imagine:
var configA = { someConfigValue: 'some default value' };
var configB = { someConfigValue: 'a custom value', someModule: require('my-module') };
var mergedObj = _.merge(configA, configB);
where my-module
looks like:
module.exports = ( function() {
// Declare the public data dictionary exposed by this module.
var publicData = {};
return {
// Expose the public data to the outside world.
somePublicData: publicData
// Declare a function for initializing the module.
init: function() {
publicData.foo = 'bar';
}
}
} )()
If you call mergedObj.someModule.init()
later, you might expect mergedObj.someModule.somePublicData
to be set to {foo: 'bar'}
, but it’ll still just be an empty dictionary, because a different somePublicData
dictionary was copied into the merged object.
The solution is very simple, because the _.merge()
function can take a third argument that allows you to customize the merge behavior. We can use this to tell _.merge()
to only do its regular thing when the left-hand value is a non-empty plain dictionary. In all other cases, a
is replaced by b
.
Keep in mind that this means that if
a
looks like a dictionary, but was created by a custom constructor (i.e. it is not a “plain” dictionary, it will be replaced byb
! For example:var myClass = function() {this.foo = 'bar'}; var obj1 = { abc: new myClass() }; // Result: // { abc: { foo: 'bar' } } var obj2 = { abc: { owl: 'hoot' } }; var merged = mergeDictionaries(obj1, obj2); // Result: // { abc: { owl: 'hoot' } }
If you have questions or are having trouble, click here.
To report a bug, click here.
Please observe the guidelines and conventions laid out in the Sails project contribution guide when opening issues or submitting pull requests.
Like the Sails framework, this package is free and open-source under the MIT License.
FAQs
Recursively merge two dictionaries together
The npm package merge-dictionaries receives a total of 39,365 weekly downloads. As such, merge-dictionaries popularity was classified as popular.
We found that merge-dictionaries demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.