merge-anything 3.0.7 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -16
- package/dist/index.cjs +92 -0
- package/dist/index.es.js +85 -0
- package/{types → dist/types}/extensions.d.ts +0 -0
- package/{types → dist/types}/index.d.ts +0 -0
- package/dist/types/merge.d.ts +11 -0
- package/package.json +67 -26
- package/.eslintignore +0 -8
- package/.eslintrc.js +0 -17
- package/.github/FUNDING.yml +0 -12
- package/.github/typescript-support.png +0 -0
- package/.prettierrc +0 -9
- package/_playground.ts +0 -27
- package/build/rollup.js +0 -55
- package/dist/index.cjs.js +0 -134
- package/dist/index.esm.js +0 -127
- package/src/extensions.ts +0 -9
- package/src/index.ts +0 -2
- package/src/merge.ts +0 -110
- package/test/index.ts +0 -320
- package/test/mergeAndCompare.ts +0 -64
- package/test/mergeAndConcat.ts +0 -15
- package/tsconfig.json +0 -10
- package/types/merge.d.ts +0 -16
package/dist/index.cjs.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var isWhat = require('is-what');
|
|
6
|
-
|
|
7
|
-
/*! *****************************************************************************
|
|
8
|
-
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
9
|
-
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
10
|
-
this file except in compliance with the License. You may obtain a copy of the
|
|
11
|
-
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
|
|
13
|
-
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
-
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
15
|
-
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
16
|
-
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
17
|
-
|
|
18
|
-
See the Apache Version 2.0 License for specific language governing permissions
|
|
19
|
-
and limitations under the License.
|
|
20
|
-
***************************************************************************** */
|
|
21
|
-
|
|
22
|
-
function __spreadArrays() {
|
|
23
|
-
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|
24
|
-
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|
25
|
-
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|
26
|
-
r[k] = a[j];
|
|
27
|
-
return r;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function concatArrays(originVal, newVal) {
|
|
31
|
-
if (isWhat.isArray(originVal) && isWhat.isArray(newVal)) {
|
|
32
|
-
// concat logic
|
|
33
|
-
return originVal.concat(newVal);
|
|
34
|
-
}
|
|
35
|
-
return newVal; // always return newVal as fallback!!
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function assignProp(carry, key, newVal, originalObject) {
|
|
39
|
-
var propType = {}.propertyIsEnumerable.call(originalObject, key)
|
|
40
|
-
? 'enumerable'
|
|
41
|
-
: 'nonenumerable';
|
|
42
|
-
if (propType === 'enumerable')
|
|
43
|
-
carry[key] = newVal;
|
|
44
|
-
if (propType === 'nonenumerable') {
|
|
45
|
-
Object.defineProperty(carry, key, {
|
|
46
|
-
value: newVal,
|
|
47
|
-
enumerable: false,
|
|
48
|
-
writable: true,
|
|
49
|
-
configurable: true,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
function mergeRecursively(origin, newComer, compareFn) {
|
|
54
|
-
// always return newComer if its not an object
|
|
55
|
-
if (!isWhat.isPlainObject(newComer))
|
|
56
|
-
return newComer;
|
|
57
|
-
// define newObject to merge all values upon
|
|
58
|
-
var newObject = {};
|
|
59
|
-
if (isWhat.isPlainObject(origin)) {
|
|
60
|
-
var props_1 = Object.getOwnPropertyNames(origin);
|
|
61
|
-
var symbols_1 = Object.getOwnPropertySymbols(origin);
|
|
62
|
-
newObject = __spreadArrays(props_1, symbols_1).reduce(function (carry, key) {
|
|
63
|
-
var targetVal = origin[key];
|
|
64
|
-
if ((!isWhat.isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) ||
|
|
65
|
-
(isWhat.isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))) {
|
|
66
|
-
assignProp(carry, key, targetVal, origin);
|
|
67
|
-
}
|
|
68
|
-
return carry;
|
|
69
|
-
}, {});
|
|
70
|
-
}
|
|
71
|
-
// newObject has all properties that newComer hasn't
|
|
72
|
-
var props = Object.getOwnPropertyNames(newComer);
|
|
73
|
-
var symbols = Object.getOwnPropertySymbols(newComer);
|
|
74
|
-
var result = __spreadArrays(props, symbols).reduce(function (carry, key) {
|
|
75
|
-
// re-define the origin and newComer as targetVal and newVal
|
|
76
|
-
var newVal = newComer[key];
|
|
77
|
-
var targetVal = isWhat.isPlainObject(origin) ? origin[key] : undefined;
|
|
78
|
-
// When newVal is an object do the merge recursively
|
|
79
|
-
if (targetVal !== undefined && isWhat.isPlainObject(newVal)) {
|
|
80
|
-
newVal = mergeRecursively(targetVal, newVal, compareFn);
|
|
81
|
-
}
|
|
82
|
-
var propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal;
|
|
83
|
-
assignProp(carry, key, propToAssign, newComer);
|
|
84
|
-
return carry;
|
|
85
|
-
}, newObject);
|
|
86
|
-
return result;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Merge anything recursively.
|
|
90
|
-
* Objects get merged, special objects (classes etc.) are re-assigned "as is".
|
|
91
|
-
* Basic types overwrite objects or other basic types.
|
|
92
|
-
*
|
|
93
|
-
* @export
|
|
94
|
-
* @template T
|
|
95
|
-
* @template Tn
|
|
96
|
-
* @param {T} origin
|
|
97
|
-
* @param {...Tn} newComers
|
|
98
|
-
* @returns {Assigned<T, Tn>}
|
|
99
|
-
*/
|
|
100
|
-
function merge(origin) {
|
|
101
|
-
var newComers = [];
|
|
102
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
103
|
-
newComers[_i - 1] = arguments[_i];
|
|
104
|
-
}
|
|
105
|
-
// @ts-ignore
|
|
106
|
-
return newComers.reduce(function (result, newComer) {
|
|
107
|
-
return mergeRecursively(result, newComer);
|
|
108
|
-
}, origin);
|
|
109
|
-
}
|
|
110
|
-
function mergeAndCompare(compareFn, origin) {
|
|
111
|
-
var newComers = [];
|
|
112
|
-
for (var _i = 2; _i < arguments.length; _i++) {
|
|
113
|
-
newComers[_i - 2] = arguments[_i];
|
|
114
|
-
}
|
|
115
|
-
// @ts-ignore
|
|
116
|
-
return newComers.reduce(function (result, newComer) {
|
|
117
|
-
return mergeRecursively(result, newComer, compareFn);
|
|
118
|
-
}, origin);
|
|
119
|
-
}
|
|
120
|
-
function mergeAndConcat(origin) {
|
|
121
|
-
var newComers = [];
|
|
122
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
123
|
-
newComers[_i - 1] = arguments[_i];
|
|
124
|
-
}
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
return newComers.reduce(function (result, newComer) {
|
|
127
|
-
return mergeRecursively(result, newComer, concatArrays);
|
|
128
|
-
}, origin);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
exports.concatArrays = concatArrays;
|
|
132
|
-
exports.merge = merge;
|
|
133
|
-
exports.mergeAndCompare = mergeAndCompare;
|
|
134
|
-
exports.mergeAndConcat = mergeAndConcat;
|
package/dist/index.esm.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { isArray, isPlainObject, isSymbol } from 'is-what';
|
|
2
|
-
|
|
3
|
-
/*! *****************************************************************************
|
|
4
|
-
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5
|
-
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
6
|
-
this file except in compliance with the License. You may obtain a copy of the
|
|
7
|
-
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
10
|
-
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
11
|
-
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
12
|
-
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
13
|
-
|
|
14
|
-
See the Apache Version 2.0 License for specific language governing permissions
|
|
15
|
-
and limitations under the License.
|
|
16
|
-
***************************************************************************** */
|
|
17
|
-
|
|
18
|
-
function __spreadArrays() {
|
|
19
|
-
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|
20
|
-
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|
21
|
-
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|
22
|
-
r[k] = a[j];
|
|
23
|
-
return r;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function concatArrays(originVal, newVal) {
|
|
27
|
-
if (isArray(originVal) && isArray(newVal)) {
|
|
28
|
-
// concat logic
|
|
29
|
-
return originVal.concat(newVal);
|
|
30
|
-
}
|
|
31
|
-
return newVal; // always return newVal as fallback!!
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function assignProp(carry, key, newVal, originalObject) {
|
|
35
|
-
var propType = {}.propertyIsEnumerable.call(originalObject, key)
|
|
36
|
-
? 'enumerable'
|
|
37
|
-
: 'nonenumerable';
|
|
38
|
-
if (propType === 'enumerable')
|
|
39
|
-
carry[key] = newVal;
|
|
40
|
-
if (propType === 'nonenumerable') {
|
|
41
|
-
Object.defineProperty(carry, key, {
|
|
42
|
-
value: newVal,
|
|
43
|
-
enumerable: false,
|
|
44
|
-
writable: true,
|
|
45
|
-
configurable: true,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function mergeRecursively(origin, newComer, compareFn) {
|
|
50
|
-
// always return newComer if its not an object
|
|
51
|
-
if (!isPlainObject(newComer))
|
|
52
|
-
return newComer;
|
|
53
|
-
// define newObject to merge all values upon
|
|
54
|
-
var newObject = {};
|
|
55
|
-
if (isPlainObject(origin)) {
|
|
56
|
-
var props_1 = Object.getOwnPropertyNames(origin);
|
|
57
|
-
var symbols_1 = Object.getOwnPropertySymbols(origin);
|
|
58
|
-
newObject = __spreadArrays(props_1, symbols_1).reduce(function (carry, key) {
|
|
59
|
-
var targetVal = origin[key];
|
|
60
|
-
if ((!isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) ||
|
|
61
|
-
(isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))) {
|
|
62
|
-
assignProp(carry, key, targetVal, origin);
|
|
63
|
-
}
|
|
64
|
-
return carry;
|
|
65
|
-
}, {});
|
|
66
|
-
}
|
|
67
|
-
// newObject has all properties that newComer hasn't
|
|
68
|
-
var props = Object.getOwnPropertyNames(newComer);
|
|
69
|
-
var symbols = Object.getOwnPropertySymbols(newComer);
|
|
70
|
-
var result = __spreadArrays(props, symbols).reduce(function (carry, key) {
|
|
71
|
-
// re-define the origin and newComer as targetVal and newVal
|
|
72
|
-
var newVal = newComer[key];
|
|
73
|
-
var targetVal = isPlainObject(origin) ? origin[key] : undefined;
|
|
74
|
-
// When newVal is an object do the merge recursively
|
|
75
|
-
if (targetVal !== undefined && isPlainObject(newVal)) {
|
|
76
|
-
newVal = mergeRecursively(targetVal, newVal, compareFn);
|
|
77
|
-
}
|
|
78
|
-
var propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal;
|
|
79
|
-
assignProp(carry, key, propToAssign, newComer);
|
|
80
|
-
return carry;
|
|
81
|
-
}, newObject);
|
|
82
|
-
return result;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Merge anything recursively.
|
|
86
|
-
* Objects get merged, special objects (classes etc.) are re-assigned "as is".
|
|
87
|
-
* Basic types overwrite objects or other basic types.
|
|
88
|
-
*
|
|
89
|
-
* @export
|
|
90
|
-
* @template T
|
|
91
|
-
* @template Tn
|
|
92
|
-
* @param {T} origin
|
|
93
|
-
* @param {...Tn} newComers
|
|
94
|
-
* @returns {Assigned<T, Tn>}
|
|
95
|
-
*/
|
|
96
|
-
function merge(origin) {
|
|
97
|
-
var newComers = [];
|
|
98
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
99
|
-
newComers[_i - 1] = arguments[_i];
|
|
100
|
-
}
|
|
101
|
-
// @ts-ignore
|
|
102
|
-
return newComers.reduce(function (result, newComer) {
|
|
103
|
-
return mergeRecursively(result, newComer);
|
|
104
|
-
}, origin);
|
|
105
|
-
}
|
|
106
|
-
function mergeAndCompare(compareFn, origin) {
|
|
107
|
-
var newComers = [];
|
|
108
|
-
for (var _i = 2; _i < arguments.length; _i++) {
|
|
109
|
-
newComers[_i - 2] = arguments[_i];
|
|
110
|
-
}
|
|
111
|
-
// @ts-ignore
|
|
112
|
-
return newComers.reduce(function (result, newComer) {
|
|
113
|
-
return mergeRecursively(result, newComer, compareFn);
|
|
114
|
-
}, origin);
|
|
115
|
-
}
|
|
116
|
-
function mergeAndConcat(origin) {
|
|
117
|
-
var newComers = [];
|
|
118
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
119
|
-
newComers[_i - 1] = arguments[_i];
|
|
120
|
-
}
|
|
121
|
-
// @ts-ignore
|
|
122
|
-
return newComers.reduce(function (result, newComer) {
|
|
123
|
-
return mergeRecursively(result, newComer, concatArrays);
|
|
124
|
-
}, origin);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export { concatArrays, merge, mergeAndCompare, mergeAndConcat };
|
package/src/extensions.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { isArray } from 'is-what'
|
|
2
|
-
|
|
3
|
-
export function concatArrays (originVal: any, newVal: any): any | any[] {
|
|
4
|
-
if (isArray(originVal) && isArray(newVal)) {
|
|
5
|
-
// concat logic
|
|
6
|
-
return originVal.concat(newVal)
|
|
7
|
-
}
|
|
8
|
-
return newVal // always return newVal as fallback!!
|
|
9
|
-
}
|
package/src/index.ts
DELETED
package/src/merge.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { O } from 'ts-toolbelt'
|
|
2
|
-
import { isPlainObject, isSymbol } from 'is-what'
|
|
3
|
-
import { concatArrays } from './extensions'
|
|
4
|
-
|
|
5
|
-
// @ts-ignore
|
|
6
|
-
type PlainObject = { [key: string | symbol]: any }
|
|
7
|
-
|
|
8
|
-
function assignProp (
|
|
9
|
-
carry: PlainObject,
|
|
10
|
-
key: string | symbol,
|
|
11
|
-
newVal: any,
|
|
12
|
-
originalObject: PlainObject
|
|
13
|
-
): void {
|
|
14
|
-
const propType = {}.propertyIsEnumerable.call(originalObject, key)
|
|
15
|
-
? 'enumerable'
|
|
16
|
-
: 'nonenumerable'
|
|
17
|
-
if (propType === 'enumerable') carry[key] = newVal
|
|
18
|
-
if (propType === 'nonenumerable') {
|
|
19
|
-
Object.defineProperty(carry, key, {
|
|
20
|
-
value: newVal,
|
|
21
|
-
enumerable: false,
|
|
22
|
-
writable: true,
|
|
23
|
-
configurable: true,
|
|
24
|
-
})
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function mergeRecursively<T1 extends PlainObject | any, T2 extends PlainObject | any> (
|
|
29
|
-
origin: T1,
|
|
30
|
-
newComer: T2,
|
|
31
|
-
compareFn?: (prop1: any, prop2: any, propName: string | symbol) => any
|
|
32
|
-
): (T1 & T2) | T2 {
|
|
33
|
-
// always return newComer if its not an object
|
|
34
|
-
if (!isPlainObject(newComer)) return newComer
|
|
35
|
-
// define newObject to merge all values upon
|
|
36
|
-
let newObject = {} as (T1 & T2) | T2
|
|
37
|
-
if (isPlainObject(origin)) {
|
|
38
|
-
const props = Object.getOwnPropertyNames(origin)
|
|
39
|
-
const symbols = Object.getOwnPropertySymbols(origin)
|
|
40
|
-
newObject = [...props, ...symbols].reduce((carry, key) => {
|
|
41
|
-
const targetVal = origin[key as any]
|
|
42
|
-
if (
|
|
43
|
-
(!isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) ||
|
|
44
|
-
(isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))
|
|
45
|
-
) {
|
|
46
|
-
assignProp(carry as any, key, targetVal, origin)
|
|
47
|
-
}
|
|
48
|
-
return carry
|
|
49
|
-
}, {} as (T1 & T2) | T2)
|
|
50
|
-
}
|
|
51
|
-
// newObject has all properties that newComer hasn't
|
|
52
|
-
const props = Object.getOwnPropertyNames(newComer)
|
|
53
|
-
const symbols = Object.getOwnPropertySymbols(newComer)
|
|
54
|
-
const result = [...props, ...symbols].reduce((carry, key) => {
|
|
55
|
-
// re-define the origin and newComer as targetVal and newVal
|
|
56
|
-
let newVal = newComer[key as any]
|
|
57
|
-
const targetVal = isPlainObject(origin) ? origin[key as any] : undefined
|
|
58
|
-
// When newVal is an object do the merge recursively
|
|
59
|
-
if (targetVal !== undefined && isPlainObject(newVal)) {
|
|
60
|
-
newVal = mergeRecursively(targetVal, newVal, compareFn)
|
|
61
|
-
}
|
|
62
|
-
const propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal
|
|
63
|
-
assignProp(carry as any, key, propToAssign, newComer)
|
|
64
|
-
return carry
|
|
65
|
-
}, newObject)
|
|
66
|
-
return result
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Merge anything recursively.
|
|
71
|
-
* Objects get merged, special objects (classes etc.) are re-assigned "as is".
|
|
72
|
-
* Basic types overwrite objects or other basic types.
|
|
73
|
-
*
|
|
74
|
-
* @export
|
|
75
|
-
* @template T
|
|
76
|
-
* @template Tn
|
|
77
|
-
* @param {T} origin
|
|
78
|
-
* @param {...Tn} newComers
|
|
79
|
-
* @returns {Assigned<T, Tn>}
|
|
80
|
-
*/
|
|
81
|
-
export function merge<T extends object, Tn extends object[]> (
|
|
82
|
-
origin: T,
|
|
83
|
-
...newComers: Tn
|
|
84
|
-
): O.Compact<T, Tn, 'deep'> {
|
|
85
|
-
// @ts-ignore
|
|
86
|
-
return newComers.reduce((result, newComer) => {
|
|
87
|
-
return mergeRecursively(result, newComer)
|
|
88
|
-
}, origin)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function mergeAndCompare<T extends object, Tn extends object[]> (
|
|
92
|
-
compareFn: (prop1: any, prop2: any, propName: string | symbol) => any,
|
|
93
|
-
origin: T,
|
|
94
|
-
...newComers: Tn
|
|
95
|
-
): O.Compact<T, Tn, 'deep'> {
|
|
96
|
-
// @ts-ignore
|
|
97
|
-
return newComers.reduce((result, newComer) => {
|
|
98
|
-
return mergeRecursively(result, newComer, compareFn)
|
|
99
|
-
}, origin)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function mergeAndConcat<T extends object, Tn extends object[]> (
|
|
103
|
-
origin: T,
|
|
104
|
-
...newComers: Tn
|
|
105
|
-
): O.Compact<T, Tn, 'deep'> {
|
|
106
|
-
// @ts-ignore
|
|
107
|
-
return newComers.reduce((result, newComer) => {
|
|
108
|
-
return mergeRecursively(result, newComer, concatArrays)
|
|
109
|
-
}, origin)
|
|
110
|
-
}
|
package/test/index.ts
DELETED
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
import test from 'ava'
|
|
2
|
-
import { isDate } from 'is-what'
|
|
3
|
-
import { merge } from '../src/index'
|
|
4
|
-
|
|
5
|
-
function copy<T> (any: T): T {
|
|
6
|
-
return JSON.parse(JSON.stringify(any))
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
test('1. origin & target stays the same | 2. works with dates', t => {
|
|
10
|
-
const nd = new Date()
|
|
11
|
-
const origin = { body: 'a' }
|
|
12
|
-
const target = { dueDate: nd }
|
|
13
|
-
const res = merge(origin, target)
|
|
14
|
-
t.deepEqual(res, { body: 'a', dueDate: nd })
|
|
15
|
-
t.deepEqual(origin, { body: 'a' })
|
|
16
|
-
t.deepEqual(target, { dueDate: nd })
|
|
17
|
-
})
|
|
18
|
-
test('adding a prop on target1|target2|mergedObj', t => {
|
|
19
|
-
const origin = { nested: {} }
|
|
20
|
-
const target = { nested: {} }
|
|
21
|
-
const res = merge(origin, target)
|
|
22
|
-
t.deepEqual(res, { nested: {} })
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
origin.nested.a = ''
|
|
25
|
-
// @ts-ignore
|
|
26
|
-
target.nested.b = ''
|
|
27
|
-
// @ts-ignore
|
|
28
|
-
res.nested.c = ''
|
|
29
|
-
t.deepEqual(origin, { nested: { a: '' } })
|
|
30
|
-
t.deepEqual(target, { nested: { b: '' } })
|
|
31
|
-
t.deepEqual(res, { nested: { c: '' } })
|
|
32
|
-
})
|
|
33
|
-
test('changing a prop on target1|target2|mergedObj: failing example', t => {
|
|
34
|
-
const origin = { nested: { a: 1 } }
|
|
35
|
-
const target = {}
|
|
36
|
-
const res = merge(origin, target)
|
|
37
|
-
t.deepEqual(res, { nested: { a: 1 } })
|
|
38
|
-
origin.nested.a = 2
|
|
39
|
-
t.deepEqual(origin, { nested: { a: 2 } }) // linked
|
|
40
|
-
t.deepEqual(target, {})
|
|
41
|
-
t.deepEqual(res, { nested: { a: 2 } }) // linked
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
target.nested = { a: 3 }
|
|
44
|
-
t.deepEqual(origin, { nested: { a: 2 } }) // not changed
|
|
45
|
-
t.deepEqual(target, { nested: { a: 3 } })
|
|
46
|
-
t.deepEqual(res, { nested: { a: 2 } }) // not changed
|
|
47
|
-
res.nested.a = 4
|
|
48
|
-
t.deepEqual(origin, { nested: { a: 4 } }) // linked
|
|
49
|
-
t.deepEqual(target, { nested: { a: 3 } })
|
|
50
|
-
t.deepEqual(res, { nested: { a: 4 } }) // linked
|
|
51
|
-
})
|
|
52
|
-
test('changing a prop on target1|target2|mergedObj: working example', t => {
|
|
53
|
-
const origin = { nested: { a: 1 } }
|
|
54
|
-
const target = {}
|
|
55
|
-
const merged = merge(origin, target)
|
|
56
|
-
const res = copy(merged)
|
|
57
|
-
t.deepEqual(res, { nested: { a: 1 } })
|
|
58
|
-
origin.nested.a = 2
|
|
59
|
-
t.deepEqual(origin, { nested: { a: 2 } }) // not linked
|
|
60
|
-
t.deepEqual(target, {})
|
|
61
|
-
t.deepEqual(res, { nested: { a: 1 } }) // not linked
|
|
62
|
-
// @ts-ignore
|
|
63
|
-
target.nested = { a: 3 }
|
|
64
|
-
t.deepEqual(origin, { nested: { a: 2 } }) // not changed
|
|
65
|
-
t.deepEqual(target, { nested: { a: 3 } })
|
|
66
|
-
t.deepEqual(res, { nested: { a: 1 } }) // not changed
|
|
67
|
-
res.nested.a = 4
|
|
68
|
-
t.deepEqual(origin, { nested: { a: 2 } }) // not linked
|
|
69
|
-
t.deepEqual(target, { nested: { a: 3 } })
|
|
70
|
-
t.deepEqual(res, { nested: { a: 4 } }) // not linked
|
|
71
|
-
})
|
|
72
|
-
test('1. works with multiple levels | 2. overwrites entire object with null', t => {
|
|
73
|
-
const origin = { body: '', head: null, toes: { big: true }, fingers: { '12': false } }
|
|
74
|
-
const target = { body: {}, head: {}, toes: {}, fingers: null }
|
|
75
|
-
const res = merge(origin, target)
|
|
76
|
-
// @ts-ignore
|
|
77
|
-
t.deepEqual(res, { body: {}, head: {}, toes: { big: true }, fingers: null })
|
|
78
|
-
})
|
|
79
|
-
test('origin and target are not modified', t => {
|
|
80
|
-
const origin = { body: '', head: null, toes: { big: true }, fingers: { '12': false } }
|
|
81
|
-
const target = { body: {}, head: {}, toes: {}, fingers: null }
|
|
82
|
-
const res = merge(origin, target)
|
|
83
|
-
// @ts-ignore
|
|
84
|
-
t.deepEqual(res, { body: {}, head: {}, toes: { big: true }, fingers: null })
|
|
85
|
-
t.deepEqual(origin, { body: '', head: null, toes: { big: true }, fingers: { '12': false } })
|
|
86
|
-
t.deepEqual(target, { body: {}, head: {}, toes: {}, fingers: null })
|
|
87
|
-
origin.body = 'a'
|
|
88
|
-
// @ts-ignore
|
|
89
|
-
origin.head = 'a'
|
|
90
|
-
// @ts-ignore
|
|
91
|
-
origin.toes.big = 'a'
|
|
92
|
-
// @ts-ignore
|
|
93
|
-
origin.fingers['12'] = 'a'
|
|
94
|
-
target.body = 'b'
|
|
95
|
-
target.head = 'b'
|
|
96
|
-
// @ts-ignore
|
|
97
|
-
target.toes = 'b'
|
|
98
|
-
// @ts-ignore
|
|
99
|
-
target.fingers = 'b'
|
|
100
|
-
// @ts-ignore
|
|
101
|
-
t.deepEqual(res, { body: {}, head: {}, toes: { big: true }, fingers: null })
|
|
102
|
-
// @ts-ignore
|
|
103
|
-
t.deepEqual(origin, { body: 'a', head: 'a', toes: { big: 'a' }, fingers: { '12': 'a' } })
|
|
104
|
-
// @ts-ignore
|
|
105
|
-
t.deepEqual(target, { body: 'b', head: 'b', toes: 'b', fingers: 'b' })
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
test('Overwrite arrays', t => {
|
|
109
|
-
const origin = { array: ['a'] }
|
|
110
|
-
const target = { array: ['b'] }
|
|
111
|
-
const res = merge(origin, target)
|
|
112
|
-
t.deepEqual(res, { array: ['b'] })
|
|
113
|
-
})
|
|
114
|
-
test('overwrites null with empty object', t => {
|
|
115
|
-
const origin = { body: null }
|
|
116
|
-
const target = { body: {} }
|
|
117
|
-
const res = merge(origin, target)
|
|
118
|
-
// @ts-ignore
|
|
119
|
-
t.deepEqual(res, { body: {} })
|
|
120
|
-
})
|
|
121
|
-
test('overwrites null with object with props', t => {
|
|
122
|
-
const origin = { body: null }
|
|
123
|
-
const target = { body: { props: true } }
|
|
124
|
-
const res = merge(origin, target)
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
t.deepEqual(res, { body: { props: true } })
|
|
127
|
-
})
|
|
128
|
-
test('overwrites string values', t => {
|
|
129
|
-
const origin = { body: 'a' }
|
|
130
|
-
const target = { body: 'b' }
|
|
131
|
-
const res = merge(origin, target)
|
|
132
|
-
t.deepEqual(res, { body: 'b' })
|
|
133
|
-
t.deepEqual(origin, { body: 'a' })
|
|
134
|
-
t.deepEqual(target, { body: 'b' })
|
|
135
|
-
})
|
|
136
|
-
test('works with very deep props & dates', t => {
|
|
137
|
-
const newDate = new Date()
|
|
138
|
-
const origin = {
|
|
139
|
-
info: {
|
|
140
|
-
time: 'now',
|
|
141
|
-
newDate,
|
|
142
|
-
very: { deep: { prop: false } },
|
|
143
|
-
},
|
|
144
|
-
}
|
|
145
|
-
const target = {
|
|
146
|
-
info: {
|
|
147
|
-
date: 'tomorrow',
|
|
148
|
-
very: { deep: { prop: true } },
|
|
149
|
-
},
|
|
150
|
-
}
|
|
151
|
-
const res = merge(origin, target)
|
|
152
|
-
t.deepEqual(res, {
|
|
153
|
-
info: {
|
|
154
|
-
// @ts-ignore
|
|
155
|
-
time: 'now',
|
|
156
|
-
newDate,
|
|
157
|
-
date: 'tomorrow',
|
|
158
|
-
very: { deep: { prop: true } },
|
|
159
|
-
},
|
|
160
|
-
})
|
|
161
|
-
t.deepEqual(origin, {
|
|
162
|
-
info: {
|
|
163
|
-
time: 'now',
|
|
164
|
-
newDate,
|
|
165
|
-
very: { deep: { prop: false } },
|
|
166
|
-
},
|
|
167
|
-
})
|
|
168
|
-
t.deepEqual(target, {
|
|
169
|
-
info: {
|
|
170
|
-
date: 'tomorrow',
|
|
171
|
-
very: { deep: { prop: true } },
|
|
172
|
-
},
|
|
173
|
-
})
|
|
174
|
-
// @ts-ignore
|
|
175
|
-
t.true(isDate(res.info.newDate))
|
|
176
|
-
})
|
|
177
|
-
test('1. does not overwrite origin prop if target prop is an empty object | 2. properly merges deep props', t => {
|
|
178
|
-
const origin = {
|
|
179
|
-
info: {
|
|
180
|
-
time: { when: 'now' },
|
|
181
|
-
very: { deep: { prop: false } },
|
|
182
|
-
},
|
|
183
|
-
}
|
|
184
|
-
const target = {
|
|
185
|
-
info: {
|
|
186
|
-
time: {},
|
|
187
|
-
very: { whole: 1 },
|
|
188
|
-
},
|
|
189
|
-
}
|
|
190
|
-
const res = merge(origin, target)
|
|
191
|
-
t.deepEqual(res, {
|
|
192
|
-
info: {
|
|
193
|
-
time: { when: 'now' },
|
|
194
|
-
very: {
|
|
195
|
-
// @ts-ignore
|
|
196
|
-
deep: { prop: false },
|
|
197
|
-
whole: 1,
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
})
|
|
201
|
-
})
|
|
202
|
-
test('overwrites any origin prop when target prop is an object with props', t => {
|
|
203
|
-
const origin = {
|
|
204
|
-
body: 'a',
|
|
205
|
-
body2: { head: false },
|
|
206
|
-
tail: {},
|
|
207
|
-
}
|
|
208
|
-
const target = {
|
|
209
|
-
body: { head: true },
|
|
210
|
-
body2: { head: { eyes: true } },
|
|
211
|
-
}
|
|
212
|
-
const res = merge(origin, target)
|
|
213
|
-
t.deepEqual(res, {
|
|
214
|
-
// @ts-ignore
|
|
215
|
-
body: { head: true },
|
|
216
|
-
// @ts-ignore
|
|
217
|
-
body2: { head: { eyes: true } },
|
|
218
|
-
tail: {},
|
|
219
|
-
})
|
|
220
|
-
t.deepEqual(origin, {
|
|
221
|
-
body: 'a',
|
|
222
|
-
body2: { head: false },
|
|
223
|
-
tail: {},
|
|
224
|
-
})
|
|
225
|
-
t.deepEqual(target, {
|
|
226
|
-
body: { head: true },
|
|
227
|
-
body2: { head: { eyes: true } },
|
|
228
|
-
})
|
|
229
|
-
})
|
|
230
|
-
|
|
231
|
-
test('works with unlimited depth', t => {
|
|
232
|
-
const date = new Date()
|
|
233
|
-
const origin = { origin: 'a', t2: false, t3: {}, t4: 'false' }
|
|
234
|
-
const t1 = { t1: date }
|
|
235
|
-
const t2 = { t2: 'new' }
|
|
236
|
-
const t3 = { t3: 'new' }
|
|
237
|
-
const t4 = { t4: 'new', t3: {} }
|
|
238
|
-
const res = merge(origin, t1, t2, t3, t4)
|
|
239
|
-
// @ts-ignore
|
|
240
|
-
t.deepEqual(res, { origin: 'a', t1: date, t2: 'new', t3: {}, t4: 'new' })
|
|
241
|
-
t.deepEqual(origin, { origin: 'a', t2: false, t3: {}, t4: 'false' })
|
|
242
|
-
t.deepEqual(t1, { t1: date })
|
|
243
|
-
t.deepEqual(t2, { t2: 'new' })
|
|
244
|
-
t.deepEqual(t3, { t3: 'new' })
|
|
245
|
-
t.deepEqual(t4, { t4: 'new', t3: {} })
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
test('symbols as keys 1', t => {
|
|
249
|
-
const mySymbol = Symbol('mySymbol')
|
|
250
|
-
const x = { value: 42, [mySymbol]: 'hello' }
|
|
251
|
-
const y = { other: 33 }
|
|
252
|
-
const res = merge(x, y)
|
|
253
|
-
t.is(res.value, 42)
|
|
254
|
-
t.is(res.other, 33)
|
|
255
|
-
t.is(res[mySymbol], 'hello')
|
|
256
|
-
})
|
|
257
|
-
test('symbols as keys 2', t => {
|
|
258
|
-
const mySymbol = Symbol('mySymbol')
|
|
259
|
-
const x = { value: 42 }
|
|
260
|
-
const y = { other: 33, [mySymbol]: 'hello' }
|
|
261
|
-
const res = merge(x, y)
|
|
262
|
-
t.is(res.value, 42)
|
|
263
|
-
t.is(res.other, 33)
|
|
264
|
-
t.is(res[mySymbol], 'hello')
|
|
265
|
-
})
|
|
266
|
-
|
|
267
|
-
test('nonenumerable keys', t => {
|
|
268
|
-
const mySymbol = Symbol('mySymbol')
|
|
269
|
-
const x = { value: 42 }
|
|
270
|
-
const y = { other: 33 }
|
|
271
|
-
Object.defineProperty(x, 'xid', {
|
|
272
|
-
value: 1,
|
|
273
|
-
writable: true,
|
|
274
|
-
enumerable: false,
|
|
275
|
-
configurable: true,
|
|
276
|
-
})
|
|
277
|
-
Object.defineProperty(x, mySymbol, {
|
|
278
|
-
value: 'original',
|
|
279
|
-
writable: true,
|
|
280
|
-
enumerable: false,
|
|
281
|
-
configurable: true,
|
|
282
|
-
})
|
|
283
|
-
Object.defineProperty(y, 'yid', {
|
|
284
|
-
value: 2,
|
|
285
|
-
writable: true,
|
|
286
|
-
enumerable: false,
|
|
287
|
-
configurable: true,
|
|
288
|
-
})
|
|
289
|
-
Object.defineProperty(y, mySymbol, {
|
|
290
|
-
value: 'new',
|
|
291
|
-
writable: true,
|
|
292
|
-
enumerable: false,
|
|
293
|
-
configurable: true,
|
|
294
|
-
})
|
|
295
|
-
const res = merge(x, y)
|
|
296
|
-
t.is(res.value, 42)
|
|
297
|
-
t.is(res.other, 33)
|
|
298
|
-
// @ts-ignore
|
|
299
|
-
t.is(res.xid, 1)
|
|
300
|
-
// @ts-ignore
|
|
301
|
-
t.is(res.yid, 2)
|
|
302
|
-
t.is(res[mySymbol], 'new')
|
|
303
|
-
t.is(Object.keys(res).length, 2)
|
|
304
|
-
t.true(Object.keys(res).includes('value'))
|
|
305
|
-
t.true(Object.keys(res).includes('other'))
|
|
306
|
-
})
|
|
307
|
-
|
|
308
|
-
test('readme', t => {
|
|
309
|
-
const starter = { name: 'Squirtle', types: { water: true } }
|
|
310
|
-
const newValues = { name: 'Wartortle', types: { fighting: true }, level: 16 }
|
|
311
|
-
|
|
312
|
-
const evolution = merge(starter, newValues, { is: 'cool' })
|
|
313
|
-
|
|
314
|
-
t.deepEqual(evolution, {
|
|
315
|
-
name: 'Wartortle',
|
|
316
|
-
types: { water: true, fighting: true },
|
|
317
|
-
level: 16,
|
|
318
|
-
is: 'cool',
|
|
319
|
-
})
|
|
320
|
-
})
|