Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

putil-merge

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

putil-merge - npm Package Compare versions

Comparing version 1.0.2 to 1.1.0

184

lib/merge.js
/* putil-merge
------------------------
(c) 2017-present Panates
SQB may be freely distributed under the MIT license.
This file may be freely distributed under the MIT license.
For details and documentation:
https://panates.github.io/putil-merge/
https://github.com/panates/putil-merge
*/
function merge(target, ...sources) {
return _merge({}, target, ...sources);
}
function merge(options, target, sources) {
if (typeof target !== 'object')
return target;
merge.init = function(cfg) {
return function(target, ...sources) {
return _merge(cfg, target, ...sources);
if (!sources) {
if (!target) {
target = options;
sources = null;
} else {
sources = target;
target = options;
}
options = {};
}
if (sources && !Array.isArray(sources))
sources = [sources];
var visited = Map();
const mergeValue = function(target, source, clone, deep) {
if (typeof source === 'object') {
// Circular reference detection
var o;
if ((o = visited.get(source)))
return o;
// If array
if (Array.isArray(source)) {
if (clone)
target = cloneArray(source, clone);
else target = source;
}
// If object
else if (isObject(source)) {
if (clone || deep) {
target = mergeObject((isObject(target) && deep ? target : {}),
source, clone, deep);
} else target = source;
}
// Add to map for circular reference detection
visited.put(source, target);
return target;
}
return source;
};
};
merge.deep = function(target, ...sources) {
return _merge({deep: true}, target, ...sources);
};
const mergeObject = function(target, source, clone, deep) {
if (source === target) return target;
Object.getOwnPropertyNames(source).forEach(function(key) {
var src = Object.getOwnPropertyDescriptor(source, key);
var trg = Object.getOwnPropertyDescriptor(target, key);
if (options.filter && !options.filter(source, key, src))
return;
var val = mergeValue(trg && trg.value, src.value, clone, deep);
if (options.descriptor) {
src.val = val;
Object.defineProperty(target, key, src);
} else target[key] = val;
});
return target;
};
merge.deepClone = function(target, ...sources) {
return _merge({deep: true, clone: true}, target, ...sources);
};
const cloneArray = function(source, cloneObjects) {
if (cloneObjects) {
// Clone object items
target = new Array(source.length);
source.forEach(function(v, i) {
target[i] = mergeValue(null, v, true);
});
return target;
}
return source.slice();
};
merge.clone = function(target, ...sources) {
return _merge({clone: true}, target, ...sources);
};
if (options.clone)
target = mergeObject({}, target, true, true);
function _merge(cfg, target, ...sources) {
if (sources)
sources.forEach(function(source, idx) {
if (!isObject(source))
throw new TypeError('Invalid source object at (' + idx +
'). Can`t merge different types');
target = mergeObject(target, source, options.clone, options.deep);
});
if (!isObject(target)) return target;
return target;
}
if (cfg.clone)
target = JSON.parse(JSON.stringify(target));
makeSequence(merge);
sources.forEach(source => {
if (isObject(source)) {
const keys = Object.getOwnPropertyNames(source);
for (const key of keys) {
const src = source[key];
if (!cfg.filter || cfg.filter(key, src)) {
if (isObject(src)) {
if (!isObject(target[key]))
target[key] = {};
if (cfg.deep)
target[key] = _merge(cfg, target[key], src);
else if (cfg.clone)
target[key] = JSON.parse(JSON.stringify(src));
else target[key] = src;
} else if (Array.isArray() && cfg.clone)
target[key] = JSON.parse(JSON.stringify(src));
else
target[key] = src;
}
function makeSequence(m) {
const bindFn = function(fn) {
if (!fn.options) {
var options = {};
fn = function(target, sources) {
return merge(options, target, sources);
};
fn.options = options;
makeSequence(fn);
}
return fn;
};
Object.defineProperties(m, {
clone: {
get: function() {
const fn = bindFn(this);
fn.options.clone = true;
return fn;
}
},
deep: {
get: function() {
const fn = bindFn(this);
fn.options.deep = true;
return fn;
}
},
descriptor: {
get: function() {
const fn = bindFn(this);
fn.options.descriptor = true;
return fn;
}
},
filter: {
value: function(filterFn) {
const fn = bindFn(this);
fn.options.filter = filterFn;
return fn;
}
}
});
return target;
}

@@ -67,2 +148,21 @@

function Map() {
var keys = [], values = [];
return {
put: function(key, value) {
var index = keys.indexOf(key);
if (index < 0) {
keys.push(key);
values.push(value);
} else {
values[index] = value;
}
},
get: function(key) {
return values[keys.indexOf(key)];
}
};
}
module.exports = merge;
{
"name": "putil-merge",
"description": "Lightweight solution for merging multiple objects into one. Also it supports deep merge and deep clone",
"version": "1.0.2",
"version": "1.1.0",
"author": "Panates Ltd.",

@@ -19,7 +19,7 @@ "contributors": [

"devDependencies": {
"babel-eslint": "^7.2.3",
"eslint": "^3.19.0",
"babel-eslint": "^8.0.0",
"eslint": "^4.7.2",
"eslint-config-google": "^0.9.1",
"istanbul": "^0.4.5",
"mocha": "^3.4.2"
"mocha": "^3.5.3"
},

@@ -26,0 +26,0 @@ "engines": {

@@ -10,38 +10,91 @@ # putil-merge

Lightweight solution for merging multiple objects into one. Also it supports deep merge
A 'swiss army knife' solution for merging multiple objects into one. It supports deep merge, cloning objects, copying descriptors and filtering.
## Installation
- `npm install putil-merge --save`
`$ npm install putil-merge --save`
## Usage
`merge(target, ...source)`
`merge([config], target, [source])`
Combines source objects with the target object without deep operation. Also it copies references instead of cloning.
- config [`Object`]
- deep [`Boolean`]: If true, it performs deep merge operation.
- clone [`Boolean`]: If true, it clones objects except setting references
- descriptor [`Boolean`]: If true, it copies descriptors
- filter [`Function(obj, key, value)`]
- target [`Object`]
- source [`Object|Array<Object>`]
## Sequential calling
`merge.deep(target, ...source)`
It supports sequential calling style.
Combines source objects with the target object with deep operation. Also it copies references instead of cloning.
`merge.(option).(option)...(target, source)`
`merge.clone(target, ...source)`
Etc:
Combines source objects with the target object without deep operation. Also it clones values.
`merge(target, source)`
`merge.deepClone(target, ...source)`
Combines source objects with the target object with deep operation. Also it clones values.
Merge source object over target object with deep operation:
`merge.deep(target, source)`
```javascript
const a = {l1a: 1, l1b: '2', l1d: {l2a: 1}};
const b = {l1b: 'b', l1c: 3, l1d: {l2b: {l3a: '2'}}, l1e: [1, 2, 3, 4]};
let o = merge(a, b);
Merge source object over target object with deep operation and cloning.
`merge.deep.clone(target, source)`
`merge.clone.deep(target, source)`
Merge source object descriptors over target object:
`merge.descriptor(target, source)`
Merge source object descriptors over target object with deep operation:
`merge.deep.descriptor(target, [source1, source2])`
`merge.clone.descriptor(target, source)`
`merge.deep.clone.descriptor(target, [source1, source2])`
`merge.deep.clone.descriptor(target, source)`
`merge.clone.deep.descriptor(target, source)`
`merge.descriptor.clone.deep(target, source)`
`merge.descriptor.filter(filterfn)(target, source)`
## Examples
Merge source object over target object:
```js
const a = {prm1: 1, prm2: 2};
const b = {prm1: 11, prm3: [1, 2, 3, 4]};
var merged = merge(a, b);
```
Clone any object:
```js
const a = {prm1: 1, prm2: { prm3: 3}};
var cloned = merge.clone(a);
var deepCloned = merge.deep.clone(a);
```
Merge source object over target object with custom filtering:
```js
var a = {id: 1};
var b = {name: 'John', surname: 'Wick'};
var merged = merge.deep.filter(function(o,k,v){
return k === 'name';
})(target, source);
```
## Node Compatibility
- node `>= 6.x`;
- node `>= 0.10`;

@@ -48,0 +101,0 @@ ### License

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc