merge-anything
Advanced tools
Comparing version 2.3.5 to 2.4.0
@@ -7,2 +7,17 @@ 'use strict'; | ||
function assignProp(carry, key, newVal, originalObject) { | ||
var propType = originalObject.propertyIsEnumerable(key) | ||
? 'enumerable' | ||
: 'nonenumerable'; | ||
if (propType === 'enumerable') | ||
carry[key] = newVal; | ||
if (propType === 'nonenumerable') { | ||
Object.defineProperty(carry, key, { | ||
value: newVal, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
}); | ||
} | ||
} | ||
function mergeRecursively(origin, newComer, extensions) { | ||
@@ -20,17 +35,23 @@ // work directly on newComer if its not an object | ||
// define newObject to merge all values upon | ||
var newObject = (isWhat.isPlainObject(origin)) | ||
? Object.keys(origin) | ||
.reduce(function (carry, key) { | ||
var newObject = {}; | ||
if (isWhat.isPlainObject(origin)) { | ||
var props_1 = Object.getOwnPropertyNames(origin); | ||
var symbols_1 = Object.getOwnPropertySymbols(origin); | ||
newObject = props_1.concat(symbols_1).reduce(function (carry, key) { | ||
// @ts-ignore | ||
var targetVal = origin[key]; | ||
// @ts-ignore | ||
if (!Object.keys(newComer).includes(key)) | ||
carry[key] = targetVal; | ||
if ((!isWhat.isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) || | ||
(isWhat.isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))) { | ||
assignProp(carry, key, targetVal, origin); | ||
} | ||
return carry; | ||
}, {}) | ||
: {}; | ||
return Object.keys(newComer) | ||
.reduce(function (carry, key) { | ||
}, {}); | ||
} | ||
var props = Object.getOwnPropertyNames(newComer); | ||
var symbols = Object.getOwnPropertySymbols(newComer); | ||
var result = props.concat(symbols).reduce(function (carry, key) { | ||
// re-define the origin and newComer as targetVal and newVal | ||
var newVal = newComer[key]; | ||
var targetVal = (isWhat.isPlainObject(origin)) | ||
// @ts-ignore | ||
? origin[key] | ||
@@ -44,16 +65,10 @@ : undefined; | ||
} | ||
// early return when targetVal === undefined | ||
if (targetVal === undefined) { | ||
carry[key] = newVal; | ||
return carry; | ||
} | ||
// When newVal is an object do the merge recursively | ||
if (isWhat.isPlainObject(newVal)) { | ||
carry[key] = mergeRecursively(targetVal, newVal, extensions); | ||
return carry; | ||
if (targetVal !== undefined && isWhat.isPlainObject(newVal)) { | ||
newVal = mergeRecursively(targetVal, newVal, extensions); | ||
} | ||
// all the rest | ||
carry[key] = newVal; | ||
assignProp(carry, key, newVal, newComer); | ||
return carry; | ||
}, newObject); | ||
return result; | ||
} | ||
@@ -69,3 +84,3 @@ /** | ||
*/ | ||
function merge (origin) { | ||
function merge(origin) { | ||
var newComers = []; | ||
@@ -72,0 +87,0 @@ for (var _i = 1; _i < arguments.length; _i++) { |
@@ -1,3 +0,18 @@ | ||
import { isArray, isPlainObject } from 'is-what'; | ||
import { isArray, isPlainObject, isSymbol } from 'is-what'; | ||
function assignProp(carry, key, newVal, originalObject) { | ||
var propType = originalObject.propertyIsEnumerable(key) | ||
? 'enumerable' | ||
: 'nonenumerable'; | ||
if (propType === 'enumerable') | ||
carry[key] = newVal; | ||
if (propType === 'nonenumerable') { | ||
Object.defineProperty(carry, key, { | ||
value: newVal, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
}); | ||
} | ||
} | ||
function mergeRecursively(origin, newComer, extensions) { | ||
@@ -15,17 +30,23 @@ // work directly on newComer if its not an object | ||
// define newObject to merge all values upon | ||
var newObject = (isPlainObject(origin)) | ||
? Object.keys(origin) | ||
.reduce(function (carry, key) { | ||
var newObject = {}; | ||
if (isPlainObject(origin)) { | ||
var props_1 = Object.getOwnPropertyNames(origin); | ||
var symbols_1 = Object.getOwnPropertySymbols(origin); | ||
newObject = props_1.concat(symbols_1).reduce(function (carry, key) { | ||
// @ts-ignore | ||
var targetVal = origin[key]; | ||
// @ts-ignore | ||
if (!Object.keys(newComer).includes(key)) | ||
carry[key] = targetVal; | ||
if ((!isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) || | ||
(isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))) { | ||
assignProp(carry, key, targetVal, origin); | ||
} | ||
return carry; | ||
}, {}) | ||
: {}; | ||
return Object.keys(newComer) | ||
.reduce(function (carry, key) { | ||
}, {}); | ||
} | ||
var props = Object.getOwnPropertyNames(newComer); | ||
var symbols = Object.getOwnPropertySymbols(newComer); | ||
var result = props.concat(symbols).reduce(function (carry, key) { | ||
// re-define the origin and newComer as targetVal and newVal | ||
var newVal = newComer[key]; | ||
var targetVal = (isPlainObject(origin)) | ||
// @ts-ignore | ||
? origin[key] | ||
@@ -39,16 +60,10 @@ : undefined; | ||
} | ||
// early return when targetVal === undefined | ||
if (targetVal === undefined) { | ||
carry[key] = newVal; | ||
return carry; | ||
} | ||
// When newVal is an object do the merge recursively | ||
if (isPlainObject(newVal)) { | ||
carry[key] = mergeRecursively(targetVal, newVal, extensions); | ||
return carry; | ||
if (targetVal !== undefined && isPlainObject(newVal)) { | ||
newVal = mergeRecursively(targetVal, newVal, extensions); | ||
} | ||
// all the rest | ||
carry[key] = newVal; | ||
assignProp(carry, key, newVal, newComer); | ||
return carry; | ||
}, newObject); | ||
return result; | ||
} | ||
@@ -64,3 +79,3 @@ /** | ||
*/ | ||
function merge (origin) { | ||
function merge(origin) { | ||
var newComers = []; | ||
@@ -67,0 +82,0 @@ for (var _i = 1; _i < arguments.length; _i++) { |
{ | ||
"name": "merge-anything", | ||
"version": "2.3.5", | ||
"version": "2.4.0", | ||
"description": "Merge objects & other types recursively. A simple & small integration.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.cjs.js", |
@@ -122,3 +122,2 @@ # Merge anything 🥡 | ||
{nested: {prop: {array: ['b']}}}, | ||
{array: ['b']} | ||
) | ||
@@ -161,11 +160,11 @@ // returns {nested: {prop: {array: ['a', 'b']}}}, | ||
```js | ||
const original = {airport: {airplane: '🛫'}} | ||
const new = {country: {location: 'Brussels'}} | ||
const merged = merge(original, merged) | ||
const original = {airport: {airplane: 'dep. 🛫'}} | ||
const extraInfo = {airport: {location: 'Brussels'}} | ||
const merged = merge(original, extraInfo) | ||
// we change the airplane from departuring 🛫 to landing 🛬 | ||
original.airport.airplane = '🛬' | ||
// This will change the value for `original` AND `merged`!!! | ||
original.airport.airplane === '🛬' // true | ||
merged.airport.airplane === '🛬' // true | ||
merged.airport.airplane = 'lan. 🛬' | ||
(merged.airport.airplane === 'lan. 🛬') // true | ||
// However, `original` was also modified! | ||
(original.airport.airplane === 'lan. 🛬') // true | ||
``` | ||
@@ -180,17 +179,19 @@ | ||
See below how we integrate 'copy-anything': | ||
```js | ||
import copy from 'copy-anything' | ||
const original = {airport: {airplane: '🛫'}} | ||
const new = {country: {location: 'Brussels'}} | ||
const merged = merge(original, merged) | ||
const mergedNotReactive = copy(merged) | ||
const original = {airport: {airplane: 'dep. 🛫'}} | ||
const extraInfo = {airport: {location: 'Brussels'}} | ||
const merged = copy(merge(original, extraInfo)) | ||
// we change the airplane from departuring 🛫 to landing 🛬 | ||
original.airport.airplane = '🛬' | ||
// `original` and `mergedNotReactive` are not linked anymore! | ||
original.airport.airplane === '🛬' // true | ||
mergedNotReactive.airport.airplane === '🛫' // true | ||
merged.airport.airplane = 'lan. 🛬' | ||
(merged.airport.airplane === 'lan. 🛬') // true | ||
// `original` won't be modified! | ||
(original.airport.airplane === 'lan. 🛬') // true | ||
``` | ||
You can then play around where you want to place the `copy()` function. | ||
## Source code | ||
@@ -197,0 +198,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { isArray, isPlainObject } from 'is-what' | ||
import { isArray, isPlainObject, isSymbol } from 'is-what' | ||
@@ -9,2 +9,17 @@ type Extension = (param1: any, param2: any) => any | ||
function assignProp (carry, key, newVal, originalObject) { | ||
const propType = originalObject.propertyIsEnumerable(key) | ||
? 'enumerable' | ||
: 'nonenumerable' | ||
if (propType === 'enumerable') carry[key] = newVal | ||
if (propType === 'nonenumerable') { | ||
Object.defineProperty(carry, key, { | ||
value: newVal, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
}) | ||
} | ||
} | ||
function mergeRecursively(origin: any, newComer: any, extensions: Extension[]) { | ||
@@ -22,12 +37,22 @@ // work directly on newComer if its not an object | ||
// define newObject to merge all values upon | ||
const newObject = (isPlainObject(origin)) | ||
? Object.keys(origin) | ||
let newObject = {} | ||
if (isPlainObject(origin)) { | ||
const props = Object.getOwnPropertyNames(origin) | ||
const symbols = Object.getOwnPropertySymbols(origin) | ||
newObject = [...props, ...symbols] | ||
.reduce((carry, key) => { | ||
// @ts-ignore | ||
const targetVal = origin[key] | ||
// @ts-ignore | ||
if (!Object.keys(newComer).includes(key)) carry[key] = targetVal | ||
if ( | ||
(!isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) || | ||
(isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key)) | ||
) { | ||
assignProp(carry, key, targetVal, origin) | ||
} | ||
return carry | ||
}, {}) | ||
: {} | ||
return Object.keys(newComer) | ||
} | ||
const props = Object.getOwnPropertyNames(newComer) | ||
const symbols = Object.getOwnPropertySymbols(newComer) | ||
let result = [...props, ...symbols] | ||
.reduce((carry, key) => { | ||
@@ -37,2 +62,3 @@ // re-define the origin and newComer as targetVal and newVal | ||
const targetVal = (isPlainObject(origin)) | ||
// @ts-ignore | ||
? origin[key] | ||
@@ -46,16 +72,10 @@ : undefined | ||
} | ||
// early return when targetVal === undefined | ||
if (targetVal === undefined) { | ||
carry[key] = newVal | ||
return carry | ||
} | ||
// When newVal is an object do the merge recursively | ||
if (isPlainObject(newVal)) { | ||
carry[key] = mergeRecursively(targetVal, newVal, extensions) | ||
return carry | ||
if (targetVal !== undefined && isPlainObject(newVal)) { | ||
newVal = mergeRecursively(targetVal, newVal, extensions) | ||
} | ||
// all the rest | ||
carry[key] = newVal | ||
assignProp(carry, key, newVal, newComer) | ||
return carry | ||
}, newObject) | ||
return result | ||
} | ||
@@ -72,3 +92,3 @@ | ||
*/ | ||
export default function (origin: IConfig | any, ...newComers: any[]) { | ||
export default function merge (origin: IConfig | any, ...newComers: any[]) { | ||
let extensions = null | ||
@@ -75,0 +95,0 @@ let base = origin |
@@ -375,9 +375,56 @@ import test from 'ava' | ||
test('symbols as keys', t => { | ||
let res, x, y | ||
const mySymbol = Symbol('mySymbol') | ||
const x = { value: 42, [mySymbol]: 'hello' } | ||
const y = { other: 33 } | ||
const res = merge(x, y) | ||
x = { value: 42, [mySymbol]: 'hello' } | ||
y = { other: 33 } | ||
res = merge(x, y) | ||
t.is(res.value, 42) | ||
t.is(res.other, 33) | ||
t.is(res[mySymbol], 'hello') | ||
x = { value: 42 } | ||
y = { other: 33, [mySymbol]: 'hello' } | ||
res = merge(x, y) | ||
t.is(res.value, 42) | ||
t.is(res.other, 33) | ||
t.is(res[mySymbol], 'hello') | ||
}) | ||
test('nonenumerable keys', t => { | ||
let x, y, res | ||
const mySymbol = Symbol('mySymbol') | ||
x = { value: 42 } | ||
y = { other: 33 } | ||
Object.defineProperty(x, 'xid', { | ||
value: 1, | ||
writable: true, | ||
enumerable: false, | ||
configurable: true | ||
}) | ||
Object.defineProperty(x, mySymbol, { | ||
value: 'original', | ||
writable: true, | ||
enumerable: false, | ||
configurable: true | ||
}) | ||
Object.defineProperty(y, 'yid', { | ||
value: 2, | ||
writable: true, | ||
enumerable: false, | ||
configurable: true | ||
}) | ||
Object.defineProperty(y, mySymbol, { | ||
value: 'new', | ||
writable: true, | ||
enumerable: false, | ||
configurable: true | ||
}) | ||
res = merge(x, y) | ||
t.is(res.value, 42) | ||
t.is(res.other, 33) | ||
t.is(res.xid, 1) | ||
t.is(res.yid, 2) | ||
t.is(res[mySymbol], 'new') | ||
t.is(Object.keys(res).length, 2) | ||
t.true(Object.keys(res).includes('value')) | ||
t.true(Object.keys(res).includes('other')) | ||
}) |
@@ -14,3 +14,3 @@ declare type Extension = (param1: any, param2: any) => any; | ||
*/ | ||
export default function (origin: IConfig | any, ...newComers: any[]): any; | ||
export default function merge(origin: IConfig | any, ...newComers: any[]): any; | ||
export {}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37644
833
234