@jsopen/objects 1.2.0 → 1.4.0
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/CHANGELOG.md +3 -3
- package/cjs/merge.js +44 -26
- package/esm/merge.js +44 -26
- package/package.json +1 -1
- package/types/merge.d.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# v1.
|
|
2
|
-
[2024-11-
|
|
1
|
+
# v1.4.0
|
|
2
|
+
[2024-11-22]
|
|
3
3
|
|
|
4
4
|
### Changes
|
|
5
5
|
|
|
6
|
-
* feat: Added
|
|
6
|
+
* feat: Added "full" option to "deep" config ([`3d2a51a`](https://github.com/panates/jsopen-objects/commit/3d2a51adff14d2ac67f3ec0c8760ae167febc4d7))
|
package/cjs/merge.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.merge = merge;
|
|
4
4
|
exports.getMergeFunction = getMergeFunction;
|
|
5
5
|
const is_object_js_1 = require("./is-object.js");
|
|
6
|
+
const type_guards_js_1 = require("./type-guards.js");
|
|
6
7
|
function merge(target, source, options) {
|
|
7
8
|
if (!((0, is_object_js_1.isObject)(target) || typeof target === 'function')) {
|
|
8
9
|
throw new TypeError('"target" argument must be an object');
|
|
@@ -12,7 +13,7 @@ function merge(target, source, options) {
|
|
|
12
13
|
throw new TypeError('"target" argument must be an object');
|
|
13
14
|
}
|
|
14
15
|
const fn = getMergeFunction(options);
|
|
15
|
-
return fn(target, source, '', options, fn,
|
|
16
|
+
return fn(target, source, '', options, fn, type_guards_js_1.isBuiltIn, is_object_js_1.isObject, is_object_js_1.isPlainObject, arrayClone);
|
|
16
17
|
}
|
|
17
18
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
18
19
|
const functionCache = new Map();
|
|
@@ -31,9 +32,11 @@ function getMergeFunction(options) {
|
|
|
31
32
|
? 'n'
|
|
32
33
|
: typeof option === 'function'
|
|
33
34
|
? 'f'
|
|
34
|
-
: option
|
|
35
|
-
?
|
|
36
|
-
:
|
|
35
|
+
: typeof option === 'string'
|
|
36
|
+
? option
|
|
37
|
+
: option
|
|
38
|
+
? '1'
|
|
39
|
+
: '0')
|
|
37
40
|
.join();
|
|
38
41
|
let fn = functionCache.get(cacheKey);
|
|
39
42
|
if (!fn) {
|
|
@@ -49,14 +52,15 @@ function buildMerge(options) {
|
|
|
49
52
|
'curPath',
|
|
50
53
|
'options',
|
|
51
54
|
'mergeFunction',
|
|
52
|
-
'
|
|
55
|
+
'isBuiltIn',
|
|
53
56
|
'isObject',
|
|
57
|
+
'isPlainObject',
|
|
54
58
|
'arrayClone',
|
|
55
59
|
];
|
|
56
60
|
const scriptL0 = [
|
|
57
61
|
`
|
|
58
62
|
const _merge = (_trgVal, _srcVal, _curPath) =>
|
|
59
|
-
mergeFunction(_trgVal, _srcVal, _curPath, options, mergeFunction,
|
|
63
|
+
mergeFunction(_trgVal, _srcVal, _curPath, options, mergeFunction, isBuiltIn, isObject, isPlainObject, arrayClone);
|
|
60
64
|
const keys = Object.getOwnPropertyNames(source);
|
|
61
65
|
keys.push(...Object.getOwnPropertySymbols(source));
|
|
62
66
|
let key;
|
|
@@ -66,7 +70,7 @@ let trgVal;
|
|
|
66
70
|
`,
|
|
67
71
|
];
|
|
68
72
|
if (options?.deep) {
|
|
69
|
-
scriptL0.push(`let subPath;`, `let
|
|
73
|
+
scriptL0.push(`let subPath;`, `let _isArray;`);
|
|
70
74
|
if (typeof options?.deep === 'function') {
|
|
71
75
|
scriptL0.push(`const deepCallback = options.deep;`);
|
|
72
76
|
}
|
|
@@ -84,6 +88,7 @@ let trgVal;
|
|
|
84
88
|
scriptL0.push(`const moveArraysCallback = options.moveArrays;`);
|
|
85
89
|
}
|
|
86
90
|
scriptL0.push(`
|
|
91
|
+
if (isPlainObject(target)) Object.setPrototypeOf(target, Object.getPrototypeOf(source));
|
|
87
92
|
let i = 0;
|
|
88
93
|
const len = keys.length;
|
|
89
94
|
for (i = 0; i < len; i++) {
|
|
@@ -133,7 +138,7 @@ if (
|
|
|
133
138
|
srcVal = source[key];`);
|
|
134
139
|
}
|
|
135
140
|
else {
|
|
136
|
-
scriptL1For.push(`descriptor = {enumerable: true, configurable: true, writable: true}`, `srcVal =
|
|
141
|
+
scriptL1For.push(`descriptor = {enumerable: true, configurable: true, writable: true}`, `srcVal = source[key];`);
|
|
137
142
|
}
|
|
138
143
|
/** ************* keepExisting *****************/
|
|
139
144
|
if (options?.keepExisting) {
|
|
@@ -147,36 +152,35 @@ if (
|
|
|
147
152
|
if (options?.ignoreNulls) {
|
|
148
153
|
scriptL1For.push(`if (srcVal === null) continue;`);
|
|
149
154
|
}
|
|
155
|
+
const deepArray = !options?.moveArrays || typeof options?.moveArrays === 'function';
|
|
150
156
|
/** ************* deep *****************/
|
|
151
157
|
if (options?.deep) {
|
|
152
|
-
|
|
153
|
-
|
|
158
|
+
const deepCondition = options.deep === 'full'
|
|
159
|
+
? `typeof srcVal === 'object' && !isBuiltIn(srcVal)`
|
|
160
|
+
: `isPlainObject(srcVal)`;
|
|
161
|
+
if (deepArray) {
|
|
162
|
+
scriptL1For.push(`
|
|
154
163
|
_isArray = Array.isArray(srcVal);
|
|
155
|
-
if (
|
|
164
|
+
if (typeof key !== 'symbol' && (_isArray || (${deepCondition}))) {`);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
scriptL1For.push(`
|
|
168
|
+
if (typeof key !== 'symbol' && ${deepCondition}) {
|
|
169
|
+
subPath = curPath + (curPath ? '.' : '') + key;`);
|
|
170
|
+
}
|
|
171
|
+
scriptL1For.push(`subPath = curPath + (curPath ? '.' : '') + key;`);
|
|
156
172
|
const scriptL2Deep = [];
|
|
157
173
|
scriptL1For.push(scriptL2Deep);
|
|
158
174
|
scriptL1For.push('}');
|
|
159
175
|
let scriptL3Deep = scriptL2Deep;
|
|
160
176
|
if (typeof options?.deep === 'function') {
|
|
161
177
|
scriptL2Deep.push(`
|
|
162
|
-
subPath = curPath + (curPath ? '.' : '') + key;
|
|
163
178
|
if (deepCallback(key, subPath, target, source)) {`);
|
|
164
179
|
scriptL3Deep = [];
|
|
165
180
|
scriptL2Deep.push(scriptL3Deep);
|
|
166
181
|
scriptL2Deep.push('}');
|
|
167
182
|
}
|
|
168
|
-
/** *************
|
|
169
|
-
scriptL3Deep.push(`
|
|
170
|
-
if (_isPlain) {
|
|
171
|
-
trgVal = target[key];
|
|
172
|
-
if (!isObject(trgVal)) {
|
|
173
|
-
descriptor.value = trgVal = {};
|
|
174
|
-
Object.defineProperty(target, key, descriptor);
|
|
175
|
-
}
|
|
176
|
-
_merge(trgVal, srcVal, subPath, options);
|
|
177
|
-
continue;
|
|
178
|
-
}`);
|
|
179
|
-
/** ************* moveArrays *****************/
|
|
183
|
+
/** ************* Array *****************/
|
|
180
184
|
if (!options?.moveArrays || typeof options?.moveArrays === 'function') {
|
|
181
185
|
scriptL3Deep.push(`if (_isArray) {`);
|
|
182
186
|
const scriptL4IsArray = [];
|
|
@@ -184,7 +188,12 @@ if (_isPlain) {
|
|
|
184
188
|
scriptL3Deep.push('}');
|
|
185
189
|
let scriptL5CloneArrays = scriptL4IsArray;
|
|
186
190
|
if (typeof options?.moveArrays === 'function') {
|
|
187
|
-
scriptL4IsArray.push(`
|
|
191
|
+
scriptL4IsArray.push(`
|
|
192
|
+
if (moveArraysCallback(key, subPath, target, source)) {
|
|
193
|
+
descriptor.value = srcVal;
|
|
194
|
+
Object.defineProperty(target, key, descriptor);
|
|
195
|
+
continue;
|
|
196
|
+
} else {`);
|
|
188
197
|
scriptL5CloneArrays = [];
|
|
189
198
|
scriptL4IsArray.push(scriptL5CloneArrays);
|
|
190
199
|
scriptL4IsArray.push('}');
|
|
@@ -195,6 +204,15 @@ Object.defineProperty(target, key, descriptor);
|
|
|
195
204
|
continue;
|
|
196
205
|
`);
|
|
197
206
|
}
|
|
207
|
+
/** ************* object *****************/
|
|
208
|
+
scriptL3Deep.push(`
|
|
209
|
+
trgVal = target[key];
|
|
210
|
+
if (!isObject(trgVal)) {
|
|
211
|
+
descriptor.value = trgVal = {};
|
|
212
|
+
Object.defineProperty(target, key, descriptor);
|
|
213
|
+
}
|
|
214
|
+
_merge(trgVal, srcVal, subPath, options);
|
|
215
|
+
continue;`);
|
|
198
216
|
}
|
|
199
217
|
/** ************* finalize *****************/
|
|
200
218
|
scriptL1For.push(`
|
|
@@ -209,7 +227,7 @@ function arrayClone(arr, _merge, curPath) {
|
|
|
209
227
|
return arr.map((x) => {
|
|
210
228
|
if (Array.isArray(x))
|
|
211
229
|
return arrayClone(x, _merge, curPath);
|
|
212
|
-
if ((0,
|
|
230
|
+
if (typeof x === 'object' && !(0, type_guards_js_1.isBuiltIn)(x))
|
|
213
231
|
return _merge({}, x, curPath);
|
|
214
232
|
return x;
|
|
215
233
|
});
|
package/esm/merge.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isObject, isPlainObject } from './is-object.js';
|
|
2
|
+
import { isBuiltIn } from './type-guards.js';
|
|
2
3
|
export function merge(target, source, options) {
|
|
3
4
|
if (!(isObject(target) || typeof target === 'function')) {
|
|
4
5
|
throw new TypeError('"target" argument must be an object');
|
|
@@ -8,7 +9,7 @@ export function merge(target, source, options) {
|
|
|
8
9
|
throw new TypeError('"target" argument must be an object');
|
|
9
10
|
}
|
|
10
11
|
const fn = getMergeFunction(options);
|
|
11
|
-
return fn(target, source, '', options, fn,
|
|
12
|
+
return fn(target, source, '', options, fn, isBuiltIn, isObject, isPlainObject, arrayClone);
|
|
12
13
|
}
|
|
13
14
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14
15
|
const functionCache = new Map();
|
|
@@ -27,9 +28,11 @@ export function getMergeFunction(options) {
|
|
|
27
28
|
? 'n'
|
|
28
29
|
: typeof option === 'function'
|
|
29
30
|
? 'f'
|
|
30
|
-
: option
|
|
31
|
-
?
|
|
32
|
-
:
|
|
31
|
+
: typeof option === 'string'
|
|
32
|
+
? option
|
|
33
|
+
: option
|
|
34
|
+
? '1'
|
|
35
|
+
: '0')
|
|
33
36
|
.join();
|
|
34
37
|
let fn = functionCache.get(cacheKey);
|
|
35
38
|
if (!fn) {
|
|
@@ -45,14 +48,15 @@ function buildMerge(options) {
|
|
|
45
48
|
'curPath',
|
|
46
49
|
'options',
|
|
47
50
|
'mergeFunction',
|
|
48
|
-
'
|
|
51
|
+
'isBuiltIn',
|
|
49
52
|
'isObject',
|
|
53
|
+
'isPlainObject',
|
|
50
54
|
'arrayClone',
|
|
51
55
|
];
|
|
52
56
|
const scriptL0 = [
|
|
53
57
|
`
|
|
54
58
|
const _merge = (_trgVal, _srcVal, _curPath) =>
|
|
55
|
-
mergeFunction(_trgVal, _srcVal, _curPath, options, mergeFunction,
|
|
59
|
+
mergeFunction(_trgVal, _srcVal, _curPath, options, mergeFunction, isBuiltIn, isObject, isPlainObject, arrayClone);
|
|
56
60
|
const keys = Object.getOwnPropertyNames(source);
|
|
57
61
|
keys.push(...Object.getOwnPropertySymbols(source));
|
|
58
62
|
let key;
|
|
@@ -62,7 +66,7 @@ let trgVal;
|
|
|
62
66
|
`,
|
|
63
67
|
];
|
|
64
68
|
if (options?.deep) {
|
|
65
|
-
scriptL0.push(`let subPath;`, `let
|
|
69
|
+
scriptL0.push(`let subPath;`, `let _isArray;`);
|
|
66
70
|
if (typeof options?.deep === 'function') {
|
|
67
71
|
scriptL0.push(`const deepCallback = options.deep;`);
|
|
68
72
|
}
|
|
@@ -80,6 +84,7 @@ let trgVal;
|
|
|
80
84
|
scriptL0.push(`const moveArraysCallback = options.moveArrays;`);
|
|
81
85
|
}
|
|
82
86
|
scriptL0.push(`
|
|
87
|
+
if (isPlainObject(target)) Object.setPrototypeOf(target, Object.getPrototypeOf(source));
|
|
83
88
|
let i = 0;
|
|
84
89
|
const len = keys.length;
|
|
85
90
|
for (i = 0; i < len; i++) {
|
|
@@ -129,7 +134,7 @@ if (
|
|
|
129
134
|
srcVal = source[key];`);
|
|
130
135
|
}
|
|
131
136
|
else {
|
|
132
|
-
scriptL1For.push(`descriptor = {enumerable: true, configurable: true, writable: true}`, `srcVal =
|
|
137
|
+
scriptL1For.push(`descriptor = {enumerable: true, configurable: true, writable: true}`, `srcVal = source[key];`);
|
|
133
138
|
}
|
|
134
139
|
/** ************* keepExisting *****************/
|
|
135
140
|
if (options?.keepExisting) {
|
|
@@ -143,36 +148,35 @@ if (
|
|
|
143
148
|
if (options?.ignoreNulls) {
|
|
144
149
|
scriptL1For.push(`if (srcVal === null) continue;`);
|
|
145
150
|
}
|
|
151
|
+
const deepArray = !options?.moveArrays || typeof options?.moveArrays === 'function';
|
|
146
152
|
/** ************* deep *****************/
|
|
147
153
|
if (options?.deep) {
|
|
148
|
-
|
|
149
|
-
|
|
154
|
+
const deepCondition = options.deep === 'full'
|
|
155
|
+
? `typeof srcVal === 'object' && !isBuiltIn(srcVal)`
|
|
156
|
+
: `isPlainObject(srcVal)`;
|
|
157
|
+
if (deepArray) {
|
|
158
|
+
scriptL1For.push(`
|
|
150
159
|
_isArray = Array.isArray(srcVal);
|
|
151
|
-
if (
|
|
160
|
+
if (typeof key !== 'symbol' && (_isArray || (${deepCondition}))) {`);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
scriptL1For.push(`
|
|
164
|
+
if (typeof key !== 'symbol' && ${deepCondition}) {
|
|
165
|
+
subPath = curPath + (curPath ? '.' : '') + key;`);
|
|
166
|
+
}
|
|
167
|
+
scriptL1For.push(`subPath = curPath + (curPath ? '.' : '') + key;`);
|
|
152
168
|
const scriptL2Deep = [];
|
|
153
169
|
scriptL1For.push(scriptL2Deep);
|
|
154
170
|
scriptL1For.push('}');
|
|
155
171
|
let scriptL3Deep = scriptL2Deep;
|
|
156
172
|
if (typeof options?.deep === 'function') {
|
|
157
173
|
scriptL2Deep.push(`
|
|
158
|
-
subPath = curPath + (curPath ? '.' : '') + key;
|
|
159
174
|
if (deepCallback(key, subPath, target, source)) {`);
|
|
160
175
|
scriptL3Deep = [];
|
|
161
176
|
scriptL2Deep.push(scriptL3Deep);
|
|
162
177
|
scriptL2Deep.push('}');
|
|
163
178
|
}
|
|
164
|
-
/** *************
|
|
165
|
-
scriptL3Deep.push(`
|
|
166
|
-
if (_isPlain) {
|
|
167
|
-
trgVal = target[key];
|
|
168
|
-
if (!isObject(trgVal)) {
|
|
169
|
-
descriptor.value = trgVal = {};
|
|
170
|
-
Object.defineProperty(target, key, descriptor);
|
|
171
|
-
}
|
|
172
|
-
_merge(trgVal, srcVal, subPath, options);
|
|
173
|
-
continue;
|
|
174
|
-
}`);
|
|
175
|
-
/** ************* moveArrays *****************/
|
|
179
|
+
/** ************* Array *****************/
|
|
176
180
|
if (!options?.moveArrays || typeof options?.moveArrays === 'function') {
|
|
177
181
|
scriptL3Deep.push(`if (_isArray) {`);
|
|
178
182
|
const scriptL4IsArray = [];
|
|
@@ -180,7 +184,12 @@ if (_isPlain) {
|
|
|
180
184
|
scriptL3Deep.push('}');
|
|
181
185
|
let scriptL5CloneArrays = scriptL4IsArray;
|
|
182
186
|
if (typeof options?.moveArrays === 'function') {
|
|
183
|
-
scriptL4IsArray.push(`
|
|
187
|
+
scriptL4IsArray.push(`
|
|
188
|
+
if (moveArraysCallback(key, subPath, target, source)) {
|
|
189
|
+
descriptor.value = srcVal;
|
|
190
|
+
Object.defineProperty(target, key, descriptor);
|
|
191
|
+
continue;
|
|
192
|
+
} else {`);
|
|
184
193
|
scriptL5CloneArrays = [];
|
|
185
194
|
scriptL4IsArray.push(scriptL5CloneArrays);
|
|
186
195
|
scriptL4IsArray.push('}');
|
|
@@ -191,6 +200,15 @@ Object.defineProperty(target, key, descriptor);
|
|
|
191
200
|
continue;
|
|
192
201
|
`);
|
|
193
202
|
}
|
|
203
|
+
/** ************* object *****************/
|
|
204
|
+
scriptL3Deep.push(`
|
|
205
|
+
trgVal = target[key];
|
|
206
|
+
if (!isObject(trgVal)) {
|
|
207
|
+
descriptor.value = trgVal = {};
|
|
208
|
+
Object.defineProperty(target, key, descriptor);
|
|
209
|
+
}
|
|
210
|
+
_merge(trgVal, srcVal, subPath, options);
|
|
211
|
+
continue;`);
|
|
194
212
|
}
|
|
195
213
|
/** ************* finalize *****************/
|
|
196
214
|
scriptL1For.push(`
|
|
@@ -205,7 +223,7 @@ function arrayClone(arr, _merge, curPath) {
|
|
|
205
223
|
return arr.map((x) => {
|
|
206
224
|
if (Array.isArray(x))
|
|
207
225
|
return arrayClone(x, _merge, curPath);
|
|
208
|
-
if (
|
|
226
|
+
if (typeof x === 'object' && !isBuiltIn(x))
|
|
209
227
|
return _merge({}, x, curPath);
|
|
210
228
|
return x;
|
|
211
229
|
});
|
package/package.json
CHANGED
package/types/merge.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare namespace merge {
|
|
2
2
|
type NodeCallback = (key: string | symbol, source: any, target: any, path: string) => boolean;
|
|
3
3
|
interface Options {
|
|
4
|
-
deep?: boolean | NodeCallback;
|
|
4
|
+
deep?: boolean | 'full' | NodeCallback;
|
|
5
5
|
/**
|
|
6
6
|
*/
|
|
7
7
|
moveArrays?: boolean | NodeCallback;
|