es-toolkit 1.14.0-dev.409 → 1.14.0-dev.410
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/dist/browser.global.js +1 -1
- package/dist/browser.global.js.map +1 -1
- package/dist/compat/index.d.mts +1 -0
- package/dist/compat/index.d.ts +1 -0
- package/dist/compat/index.js +33 -22
- package/dist/compat/index.mjs +1 -0
- package/dist/compat/object/merge.mjs +3 -64
- package/dist/compat/object/mergeWith.d.mts +261 -0
- package/dist/compat/object/mergeWith.d.ts +261 -0
- package/dist/compat/object/mergeWith.mjs +75 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/dist/object/index.d.mts +1 -0
- package/dist/object/index.d.ts +1 -0
- package/dist/object/index.js +24 -0
- package/dist/object/index.mjs +1 -0
- package/dist/object/merge.d.mts +2 -0
- package/dist/object/merge.d.ts +2 -0
- package/dist/object/mergeWith.d.mts +57 -0
- package/dist/object/mergeWith.d.ts +57 -0
- package/dist/object/mergeWith.mjs +26 -0
- package/package.json +1 -1
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges the properties of one or more source objects into the target object.
|
|
3
|
+
*
|
|
4
|
+
* This function performs a deep merge, recursively merging nested objects and arrays.
|
|
5
|
+
* If a property in the source object is an array or object and the corresponding property in the target object is also an array or object, they will be merged.
|
|
6
|
+
* If a property in the source object is `undefined`, it will not overwrite a defined property in the target object.
|
|
7
|
+
*
|
|
8
|
+
* You can provide a custom `merge` function to control how properties are merged. The `merge` function is called for each property that is being merged and receives the following arguments:
|
|
9
|
+
*
|
|
10
|
+
* - `targetValue`: The current value of the property in the target object.
|
|
11
|
+
* - `sourceValue`: The value of the property in the source object.
|
|
12
|
+
* - `key`: The key of the property being merged.
|
|
13
|
+
* - `target`: The target object.
|
|
14
|
+
* - `source`: The source object.
|
|
15
|
+
* - `stack`: A `Map` used to keep track of objects that have already been processed to handle circular references.
|
|
16
|
+
*
|
|
17
|
+
* The `merge` function should return the value to be set in the target object. If it returns `undefined`, a default deep merge will be applied for arrays and objects.
|
|
18
|
+
*
|
|
19
|
+
* The function can handle multiple source objects and will merge them all into the target object.
|
|
20
|
+
*
|
|
21
|
+
* @param {T} target - The target object into which the source object properties will be merged. This object is modified in place.
|
|
22
|
+
* @param {S} source - The first source object whose properties will be merged into the target object.
|
|
23
|
+
* @returns {T & S} The updated target object with properties from the source object(s) merged in.
|
|
24
|
+
*
|
|
25
|
+
* @template T - Type of the target object.
|
|
26
|
+
* @template S - Type of the first source object.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const target = { a: 1, b: 2 };
|
|
30
|
+
* const source = { b: 3, c: 4 };
|
|
31
|
+
*
|
|
32
|
+
* mergeWith(target, source, (targetValue, sourceValue) => {
|
|
33
|
+
* if (typeof targetValue === 'number' && typeof sourceValue === 'number') {
|
|
34
|
+
* return targetValue + sourceValue;
|
|
35
|
+
* }
|
|
36
|
+
* });
|
|
37
|
+
* // Returns { a: 1, b: 5, c: 4 }
|
|
38
|
+
* @example
|
|
39
|
+
* const target = { a: [1], b: [2] };
|
|
40
|
+
* const source = { a: [3], b: [4] };
|
|
41
|
+
*
|
|
42
|
+
* const result = mergeWith(target, source, (objValue, srcValue) => {
|
|
43
|
+
* if (Array.isArray(objValue)) {
|
|
44
|
+
* return objValue.concat(srcValue);
|
|
45
|
+
* }
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* expect(result).toEqual({ a: [1, 3], b: [2, 4] });
|
|
49
|
+
*/
|
|
50
|
+
declare function mergeWith<T, S>(target: T, source: S, merge: (targetValue: any, sourceValue: any, key: string, target: T, source: S, stack: Map<any, any>) => any): T & S;
|
|
51
|
+
/**
|
|
52
|
+
* Merges the properties of one or more source objects into the target object.
|
|
53
|
+
*
|
|
54
|
+
* This function performs a deep merge, recursively merging nested objects and arrays.
|
|
55
|
+
* If a property in the source object is an array or object and the corresponding property in the target object is also an array or object, they will be merged.
|
|
56
|
+
* If a property in the source object is `undefined`, it will not overwrite a defined property in the target object.
|
|
57
|
+
*
|
|
58
|
+
* You can provide a custom `merge` function to control how properties are merged. The `merge` function is called for each property that is being merged and receives the following arguments:
|
|
59
|
+
*
|
|
60
|
+
* - `targetValue`: The current value of the property in the target object.
|
|
61
|
+
* - `sourceValue`: The value of the property in the source object.
|
|
62
|
+
* - `key`: The key of the property being merged.
|
|
63
|
+
* - `target`: The target object.
|
|
64
|
+
* - `source`: The source object.
|
|
65
|
+
* - `stack`: A `Map` used to keep track of objects that have already been processed to handle circular references.
|
|
66
|
+
*
|
|
67
|
+
* The `merge` function should return the value to be set in the target object. If it returns `undefined`, a default deep merge will be applied for arrays and objects.
|
|
68
|
+
*
|
|
69
|
+
* The function can handle multiple source objects and will merge them all into the target object.
|
|
70
|
+
*
|
|
71
|
+
* @param {O} object - The target object into which the source object properties will be merged. This object is modified in place.
|
|
72
|
+
* @param {S1} source1 - The first source object to be merged into the target object.
|
|
73
|
+
* @param {S2} source2 - The second source object to be merged into the target object.
|
|
74
|
+
* @returns {O & S1 & S2} The updated target object with properties from the source objects merged in.
|
|
75
|
+
*
|
|
76
|
+
* @template O - Type of the target object.
|
|
77
|
+
* @template S1 - Type of the first source object.
|
|
78
|
+
* @template S2 - Type of the second source object.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* const target = { a: 1, b: 2 };
|
|
82
|
+
* const source = { b: 3, c: 4 };
|
|
83
|
+
*
|
|
84
|
+
* mergeWith(target, source, (targetValue, sourceValue) => {
|
|
85
|
+
* if (typeof targetValue === 'number' && typeof sourceValue === 'number') {
|
|
86
|
+
* return targetValue + sourceValue;
|
|
87
|
+
* }
|
|
88
|
+
* });
|
|
89
|
+
* // Returns { a: 1, b: 5, c: 4 }
|
|
90
|
+
* @example
|
|
91
|
+
* const target = { a: [1], b: [2] };
|
|
92
|
+
* const source = { a: [3], b: [4] };
|
|
93
|
+
*
|
|
94
|
+
* const result = mergeWith(target, source, (objValue, srcValue) => {
|
|
95
|
+
* if (Array.isArray(objValue)) {
|
|
96
|
+
* return objValue.concat(srcValue);
|
|
97
|
+
* }
|
|
98
|
+
* });
|
|
99
|
+
*
|
|
100
|
+
* expect(result).toEqual({ a: [1, 3], b: [2, 4] });
|
|
101
|
+
*/
|
|
102
|
+
declare function mergeWith<O, S1, S2>(object: O, source1: S1, source2: S2, merge: (targetValue: any, sourceValue: any, key: string, target: any, source: any, stack: Map<any, any>) => any): O & S1 & S2;
|
|
103
|
+
/**
|
|
104
|
+
* Merges the properties of one or more source objects into the target object.
|
|
105
|
+
*
|
|
106
|
+
* This function performs a deep merge, recursively merging nested objects and arrays.
|
|
107
|
+
* If a property in the source object is an array or object and the corresponding property in the target object is also an array or object, they will be merged.
|
|
108
|
+
* If a property in the source object is `undefined`, it will not overwrite a defined property in the target object.
|
|
109
|
+
*
|
|
110
|
+
* You can provide a custom `merge` function to control how properties are merged. The `merge` function is called for each property that is being merged and receives the following arguments:
|
|
111
|
+
*
|
|
112
|
+
* - `targetValue`: The current value of the property in the target object.
|
|
113
|
+
* - `sourceValue`: The value of the property in the source object.
|
|
114
|
+
* - `key`: The key of the property being merged.
|
|
115
|
+
* - `target`: The target object.
|
|
116
|
+
* - `source`: The source object.
|
|
117
|
+
* - `stack`: A `Map` used to keep track of objects that have already been processed to handle circular references.
|
|
118
|
+
*
|
|
119
|
+
* The `merge` function should return the value to be set in the target object. If it returns `undefined`, a default deep merge will be applied for arrays and objects.
|
|
120
|
+
*
|
|
121
|
+
* The function can handle multiple source objects and will merge them all into the target object.
|
|
122
|
+
*
|
|
123
|
+
* @param {O} object - The target object into which the source object properties will be merged. This object is modified in place.
|
|
124
|
+
* @param {S1} source1 - The first source object whose properties will be merged into the target object.
|
|
125
|
+
* @param {S2} source2 - The second source object whose properties will be merged into the target object.
|
|
126
|
+
* @param {S3} source3 - The third source object whose properties will be merged into the target object.
|
|
127
|
+
* @returns {O & S1 & S2 & S3} The updated target object with properties from the source object(s) merged in.
|
|
128
|
+
*
|
|
129
|
+
* @template O - Type of the target object.
|
|
130
|
+
* @template S1 - Type of the first source object.
|
|
131
|
+
* @template S2 - Type of the second source object.
|
|
132
|
+
* @template S3 - Type of the third source object.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* const target = { a: 1, b: 2 };
|
|
136
|
+
* const source = { b: 3, c: 4 };
|
|
137
|
+
*
|
|
138
|
+
* mergeWith(target, source, (targetValue, sourceValue) => {
|
|
139
|
+
* if (typeof targetValue === 'number' && typeof sourceValue === 'number') {
|
|
140
|
+
* return targetValue + sourceValue;
|
|
141
|
+
* }
|
|
142
|
+
* });
|
|
143
|
+
* // Returns { a: 1, b: 5, c: 4 }
|
|
144
|
+
* @example
|
|
145
|
+
* const target = { a: [1], b: [2] };
|
|
146
|
+
* const source = { a: [3], b: [4] };
|
|
147
|
+
*
|
|
148
|
+
* const result = mergeWith(target, source, (objValue, srcValue) => {
|
|
149
|
+
* if (Array.isArray(objValue)) {
|
|
150
|
+
* return objValue.concat(srcValue);
|
|
151
|
+
* }
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* expect(result).toEqual({ a: [1, 3], b: [2, 4] });
|
|
155
|
+
*/
|
|
156
|
+
declare function mergeWith<O, S1, S2, S3>(object: O, source1: S1, source2: S2, source3: S3, merge: (targetValue: any, sourceValue: any, key: string, target: any, source: any, stack: Map<any, any>) => any): O & S1 & S2 & S3;
|
|
157
|
+
/**
|
|
158
|
+
* Merges the properties of one or more source objects into the target object.
|
|
159
|
+
*
|
|
160
|
+
* This function performs a deep merge, recursively merging nested objects and arrays.
|
|
161
|
+
* If a property in the source object is an array or object and the corresponding property in the target object is also an array or object, they will be merged.
|
|
162
|
+
* If a property in the source object is `undefined`, it will not overwrite a defined property in the target object.
|
|
163
|
+
*
|
|
164
|
+
* You can provide a custom `merge` function to control how properties are merged. The `merge` function is called for each property that is being merged and receives the following arguments:
|
|
165
|
+
*
|
|
166
|
+
* - `targetValue`: The current value of the property in the target object.
|
|
167
|
+
* - `sourceValue`: The value of the property in the source object.
|
|
168
|
+
* - `key`: The key of the property being merged.
|
|
169
|
+
* - `target`: The target object.
|
|
170
|
+
* - `source`: The source object.
|
|
171
|
+
* - `stack`: A `Map` used to keep track of objects that have already been processed to handle circular references.
|
|
172
|
+
*
|
|
173
|
+
* The `merge` function should return the value to be set in the target object. If it returns `undefined`, a default deep merge will be applied for arrays and objects.
|
|
174
|
+
*
|
|
175
|
+
* The function can handle multiple source objects and will merge them all into the target object.
|
|
176
|
+
*
|
|
177
|
+
* @param {O} object - The target object into which the source object properties will be merged. This object is modified in place.
|
|
178
|
+
* @param {S1} source1 - The first source object whose properties will be merged into the target object.
|
|
179
|
+
* @param {S2} source2 - The second source object whose properties will be merged into the target object.
|
|
180
|
+
* @param {S3} source3 - The third source object whose properties will be merged into the target object.
|
|
181
|
+
* @param {S4} source4 - The fourth source object whose properties will be merged into the target object.
|
|
182
|
+
* @returns {O & S1 & S2 & S3 & S4} The updated target object with properties from the source object(s) merged in.
|
|
183
|
+
*
|
|
184
|
+
* @template O - Type of the target object.
|
|
185
|
+
* @template S1 - Type of the first source object.
|
|
186
|
+
* @template S2 - Type of the second source object.
|
|
187
|
+
* @template S3 - Type of the third source object.
|
|
188
|
+
* @template S4 - Type of the fourth source object.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* const target = { a: 1, b: 2 };
|
|
192
|
+
* const source = { b: 3, c: 4 };
|
|
193
|
+
*
|
|
194
|
+
* mergeWith(target, source, (targetValue, sourceValue) => {
|
|
195
|
+
* if (typeof targetValue === 'number' && typeof sourceValue === 'number') {
|
|
196
|
+
* return targetValue + sourceValue;
|
|
197
|
+
* }
|
|
198
|
+
* });
|
|
199
|
+
* // Returns { a: 1, b: 5, c: 4 }
|
|
200
|
+
* @example
|
|
201
|
+
* const target = { a: [1], b: [2] };
|
|
202
|
+
* const source = { a: [3], b: [4] };
|
|
203
|
+
*
|
|
204
|
+
* const result = mergeWith(target, source, (objValue, srcValue) => {
|
|
205
|
+
* if (Array.isArray(objValue)) {
|
|
206
|
+
* return objValue.concat(srcValue);
|
|
207
|
+
* }
|
|
208
|
+
* });
|
|
209
|
+
*
|
|
210
|
+
* expect(result).toEqual({ a: [1, 3], b: [2, 4] });
|
|
211
|
+
*/
|
|
212
|
+
declare function mergeWith<O, S1, S2, S3, S4>(object: O, source1: S1, source2: S2, source3: S3, source4: S4, merge: (targetValue: any, sourceValue: any, key: string, target: any, source: any, stack: Map<any, any>) => any): O & S1 & S2 & S3;
|
|
213
|
+
/**
|
|
214
|
+
* Merges the properties of one or more source objects into the target object.
|
|
215
|
+
*
|
|
216
|
+
* This function performs a deep merge, recursively merging nested objects and arrays.
|
|
217
|
+
* If a property in the source object is an array or object and the corresponding property in the target object is also an array or object, they will be merged.
|
|
218
|
+
* If a property in the source object is `undefined`, it will not overwrite a defined property in the target object.
|
|
219
|
+
*
|
|
220
|
+
* You can provide a custom `merge` function to control how properties are merged. The `merge` function is called for each property that is being merged and receives the following arguments:
|
|
221
|
+
*
|
|
222
|
+
* - `targetValue`: The current value of the property in the target object.
|
|
223
|
+
* - `sourceValue`: The value of the property in the source object.
|
|
224
|
+
* - `key`: The key of the property being merged.
|
|
225
|
+
* - `target`: The target object.
|
|
226
|
+
* - `source`: The source object.
|
|
227
|
+
* - `stack`: A `Map` used to keep track of objects that have already been processed to handle circular references.
|
|
228
|
+
*
|
|
229
|
+
* The `merge` function should return the value to be set in the target object. If it returns `undefined`, a default deep merge will be applied for arrays and objects.
|
|
230
|
+
*
|
|
231
|
+
* The function can handle multiple source objects and will merge them all into the target object.
|
|
232
|
+
*
|
|
233
|
+
* @param {any} any - The target object into which the source object properties will be merged. This object is modified in place.
|
|
234
|
+
* @param {any[]} sources - The source objects whose properties will be merged into the target object.
|
|
235
|
+
* @returns {any} The updated target object with properties from the source object(s) merged in.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* const target = { a: 1, b: 2 };
|
|
239
|
+
* const source = { b: 3, c: 4 };
|
|
240
|
+
*
|
|
241
|
+
* mergeWith(target, source, (targetValue, sourceValue) => {
|
|
242
|
+
* if (typeof targetValue === 'number' && typeof sourceValue === 'number') {
|
|
243
|
+
* return targetValue + sourceValue;
|
|
244
|
+
* }
|
|
245
|
+
* });
|
|
246
|
+
* // Returns { a: 1, b: 5, c: 4 }
|
|
247
|
+
* @example
|
|
248
|
+
* const target = { a: [1], b: [2] };
|
|
249
|
+
* const source = { a: [3], b: [4] };
|
|
250
|
+
*
|
|
251
|
+
* const result = mergeWith(target, source, (objValue, srcValue) => {
|
|
252
|
+
* if (Array.isArray(objValue)) {
|
|
253
|
+
* return objValue.concat(srcValue);
|
|
254
|
+
* }
|
|
255
|
+
* });
|
|
256
|
+
*
|
|
257
|
+
* expect(result).toEqual({ a: [1, 3], b: [2, 4] });
|
|
258
|
+
*/
|
|
259
|
+
declare function mergeWith(object: any, ...otherArgs: any[]): any;
|
|
260
|
+
|
|
261
|
+
export { mergeWith };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { clone } from '../../object/clone.mjs';
|
|
2
|
+
import { isArguments } from '../predicate/isArguments.mjs';
|
|
3
|
+
import { isObjectLike } from '../predicate/isObjectLike.mjs';
|
|
4
|
+
import { isPlainObject } from '../predicate/isPlainObject.mjs';
|
|
5
|
+
import { isTypedArray } from '../predicate/isTypedArray.mjs';
|
|
6
|
+
import { cloneDeep } from './cloneDeep.mjs';
|
|
7
|
+
|
|
8
|
+
function mergeWith(object, ...otherArgs) {
|
|
9
|
+
const sources = otherArgs.slice(0, -1);
|
|
10
|
+
const merge = otherArgs[otherArgs.length - 1];
|
|
11
|
+
let result = object;
|
|
12
|
+
for (let i = 0; i < sources.length; i++) {
|
|
13
|
+
const source = sources[i];
|
|
14
|
+
result = mergeWithDeep(object, source, merge, new Map());
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
function mergeWithDeep(target, source, merge, stack) {
|
|
19
|
+
if (source == null || typeof source !== 'object') {
|
|
20
|
+
return target;
|
|
21
|
+
}
|
|
22
|
+
if (stack.has(source)) {
|
|
23
|
+
return clone(stack.get(source));
|
|
24
|
+
}
|
|
25
|
+
stack.set(source, target);
|
|
26
|
+
if (Array.isArray(source)) {
|
|
27
|
+
source = source.slice();
|
|
28
|
+
for (let i = 0; i < source.length; i++) {
|
|
29
|
+
source[i] = source[i] ?? undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const sourceKeys = Object.keys(source);
|
|
33
|
+
for (let i = 0; i < sourceKeys.length; i++) {
|
|
34
|
+
const key = sourceKeys[i];
|
|
35
|
+
let sourceValue = source[key];
|
|
36
|
+
let targetValue = target[key];
|
|
37
|
+
if (isArguments(sourceValue)) {
|
|
38
|
+
sourceValue = { ...sourceValue };
|
|
39
|
+
}
|
|
40
|
+
if (isArguments(targetValue)) {
|
|
41
|
+
targetValue = { ...targetValue };
|
|
42
|
+
}
|
|
43
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(sourceValue)) {
|
|
44
|
+
sourceValue = cloneDeep(sourceValue);
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(sourceValue)) {
|
|
47
|
+
targetValue = typeof targetValue === 'object' ? Array.from(targetValue ?? []) : [];
|
|
48
|
+
}
|
|
49
|
+
const merged = merge(targetValue, sourceValue, key, target, source, stack);
|
|
50
|
+
if (merged != null) {
|
|
51
|
+
target[key] = merged;
|
|
52
|
+
}
|
|
53
|
+
else if (Array.isArray(sourceValue)) {
|
|
54
|
+
target[key] = mergeWithDeep(targetValue, sourceValue, merge, stack);
|
|
55
|
+
}
|
|
56
|
+
else if (isObjectLike(targetValue) && isObjectLike(sourceValue)) {
|
|
57
|
+
target[key] = mergeWithDeep(targetValue, sourceValue, merge, stack);
|
|
58
|
+
}
|
|
59
|
+
else if (targetValue == null && Array.isArray(sourceValue)) {
|
|
60
|
+
target[key] = mergeWithDeep([], sourceValue, merge, stack);
|
|
61
|
+
}
|
|
62
|
+
else if (targetValue == null && isPlainObject(sourceValue)) {
|
|
63
|
+
target[key] = mergeWithDeep({}, sourceValue, merge, stack);
|
|
64
|
+
}
|
|
65
|
+
else if (targetValue == null && isTypedArray(sourceValue)) {
|
|
66
|
+
target[key] = cloneDeep(sourceValue);
|
|
67
|
+
}
|
|
68
|
+
else if (targetValue === undefined || sourceValue !== undefined) {
|
|
69
|
+
target[key] = sourceValue;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return target;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { mergeWith };
|
package/dist/index.d.mts
CHANGED
|
@@ -82,6 +82,7 @@ export { mapKeys } from './object/mapKeys.mjs';
|
|
|
82
82
|
export { mapValues } from './object/mapValues.mjs';
|
|
83
83
|
export { cloneDeep } from './object/cloneDeep.mjs';
|
|
84
84
|
export { merge } from './object/merge.mjs';
|
|
85
|
+
export { mergeWith } from './object/mergeWith.mjs';
|
|
85
86
|
export { isEqual } from './predicate/isEqual.mjs';
|
|
86
87
|
export { isNil } from './predicate/isNil.mjs';
|
|
87
88
|
export { isNotNil } from './predicate/isNotNil.mjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -82,6 +82,7 @@ export { mapKeys } from './object/mapKeys.js';
|
|
|
82
82
|
export { mapValues } from './object/mapValues.js';
|
|
83
83
|
export { cloneDeep } from './object/cloneDeep.js';
|
|
84
84
|
export { merge } from './object/merge.js';
|
|
85
|
+
export { mergeWith } from './object/mergeWith.js';
|
|
85
86
|
export { isEqual } from './predicate/isEqual.js';
|
|
86
87
|
export { isNil } from './predicate/isNil.js';
|
|
87
88
|
export { isNotNil } from './predicate/isNotNil.js';
|
package/dist/index.js
CHANGED
|
@@ -103,6 +103,7 @@ exports.omitBy = isObjectLike.omitBy;
|
|
|
103
103
|
exports.pick = isObjectLike.pick;
|
|
104
104
|
exports.pickBy = isObjectLike.pickBy;
|
|
105
105
|
exports.merge = object_index.merge;
|
|
106
|
+
exports.mergeWith = object_index.mergeWith;
|
|
106
107
|
exports.isEqual = isSymbol.isEqual;
|
|
107
108
|
exports.isFunction = isSymbol.isFunction;
|
|
108
109
|
exports.isLength = isSymbol.isLength;
|
package/dist/index.mjs
CHANGED
|
@@ -82,6 +82,7 @@ export { mapKeys } from './object/mapKeys.mjs';
|
|
|
82
82
|
export { mapValues } from './object/mapValues.mjs';
|
|
83
83
|
export { cloneDeep } from './object/cloneDeep.mjs';
|
|
84
84
|
export { merge } from './object/merge.mjs';
|
|
85
|
+
export { mergeWith } from './object/mergeWith.mjs';
|
|
85
86
|
export { isEqual } from './predicate/isEqual.mjs';
|
|
86
87
|
export { isNil } from './predicate/isNil.mjs';
|
|
87
88
|
export { isNotNil } from './predicate/isNotNil.mjs';
|
package/dist/object/index.d.mts
CHANGED
package/dist/object/index.d.ts
CHANGED
package/dist/object/index.js
CHANGED
|
@@ -23,6 +23,29 @@ function merge(target, source) {
|
|
|
23
23
|
return target;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
function mergeWith(target, source, merge) {
|
|
27
|
+
const sourceKeys = Object.keys(source);
|
|
28
|
+
for (let i = 0; i < sourceKeys.length; i++) {
|
|
29
|
+
const key = sourceKeys[i];
|
|
30
|
+
const sourceValue = source[key];
|
|
31
|
+
const targetValue = target[key];
|
|
32
|
+
const merged = merge(targetValue, sourceValue, key, target, source);
|
|
33
|
+
if (merged != null) {
|
|
34
|
+
target[key] = merged;
|
|
35
|
+
}
|
|
36
|
+
else if (Array.isArray(sourceValue)) {
|
|
37
|
+
target[key] = mergeWith(targetValue ?? [], sourceValue, merge);
|
|
38
|
+
}
|
|
39
|
+
else if (isObjectLike.isObjectLike(targetValue) && isObjectLike.isObjectLike(sourceValue)) {
|
|
40
|
+
target[key] = mergeWith(targetValue ?? {}, sourceValue, merge);
|
|
41
|
+
}
|
|
42
|
+
else if (targetValue === undefined || sourceValue !== undefined) {
|
|
43
|
+
target[key] = sourceValue;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return target;
|
|
47
|
+
}
|
|
48
|
+
|
|
26
49
|
exports.clone = isObjectLike.clone;
|
|
27
50
|
exports.cloneDeep = isObjectLike.cloneDeep;
|
|
28
51
|
exports.flattenObject = isObjectLike.flattenObject;
|
|
@@ -34,3 +57,4 @@ exports.omitBy = isObjectLike.omitBy;
|
|
|
34
57
|
exports.pick = isObjectLike.pick;
|
|
35
58
|
exports.pickBy = isObjectLike.pickBy;
|
|
36
59
|
exports.merge = merge;
|
|
60
|
+
exports.mergeWith = mergeWith;
|
package/dist/object/index.mjs
CHANGED
package/dist/object/merge.d.mts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* If a property in the source object is an array or an object and the corresponding property in the target object is also an array or object, they will be merged.
|
|
6
6
|
* If a property in the source object is undefined, it will not overwrite a defined property in the target object.
|
|
7
7
|
*
|
|
8
|
+
* Note that this function mutates the target object.
|
|
9
|
+
*
|
|
8
10
|
* @param {T} target - The target object into which the source object properties will be merged. This object is modified in place.
|
|
9
11
|
* @param {S} source - The source object whose properties will be merged into the target object.
|
|
10
12
|
* @returns {T & S} The updated target object with properties from the source object merged in.
|
package/dist/object/merge.d.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* If a property in the source object is an array or an object and the corresponding property in the target object is also an array or object, they will be merged.
|
|
6
6
|
* If a property in the source object is undefined, it will not overwrite a defined property in the target object.
|
|
7
7
|
*
|
|
8
|
+
* Note that this function mutates the target object.
|
|
9
|
+
*
|
|
8
10
|
* @param {T} target - The target object into which the source object properties will be merged. This object is modified in place.
|
|
9
11
|
* @param {S} source - The source object whose properties will be merged into the target object.
|
|
10
12
|
* @returns {T & S} The updated target object with properties from the source object merged in.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges the properties of the source object into the target object.
|
|
3
|
+
*
|
|
4
|
+
* You can provide a custom `merge` function to control how properties are merged. The `merge` function is called for each property that is being merged and receives the following arguments:
|
|
5
|
+
*
|
|
6
|
+
* - `targetValue`: The current value of the property in the target object.
|
|
7
|
+
* - `sourceValue`: The value of the property in the source object.
|
|
8
|
+
* - `key`: The key of the property being merged.
|
|
9
|
+
* - `target`: The target object.
|
|
10
|
+
* - `source`: The source object.
|
|
11
|
+
*
|
|
12
|
+
* The `merge` function should return the value to be set in the target object. If it returns `undefined`, a default deep merge will be applied for arrays and objects:
|
|
13
|
+
*
|
|
14
|
+
* - If a property in the source object is an array or an object and the corresponding property in the target object is also an array or object, they will be merged.
|
|
15
|
+
* - If a property in the source object is undefined, it will not overwrite a defined property in the target object.
|
|
16
|
+
*
|
|
17
|
+
* Note that this function mutates the target object.
|
|
18
|
+
*
|
|
19
|
+
* @param {T} target - The target object into which the source object properties will be merged. This object is modified in place.
|
|
20
|
+
* @param {S} source - The source object whose properties will be merged into the target object.
|
|
21
|
+
* @param {(targetValue: any, sourceValue: any, key: string, target: T, source: S) => any} merge - A custom merge function that defines how properties should be combined. It receives the following arguments:
|
|
22
|
+
* - `targetValue`: The current value of the property in the target object.
|
|
23
|
+
* - `sourceValue`: The value of the property in the source object.
|
|
24
|
+
* - `key`: The key of the property being merged.
|
|
25
|
+
* - `target`: The target object.
|
|
26
|
+
* - `source`: The source object.
|
|
27
|
+
*
|
|
28
|
+
* @returns {T & S} The updated target object with properties from the source object merged in.
|
|
29
|
+
*
|
|
30
|
+
* @template T - Type of the target object.
|
|
31
|
+
* @template S - Type of the source object.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const target = { a: 1, b: 2 };
|
|
35
|
+
* const source = { b: 3, c: 4 };
|
|
36
|
+
*
|
|
37
|
+
* mergeWith(target, source, (targetValue, sourceValue) => {
|
|
38
|
+
* if (typeof targetValue === 'number' && typeof sourceValue === 'number') {
|
|
39
|
+
* return targetValue + sourceValue;
|
|
40
|
+
* }
|
|
41
|
+
* });
|
|
42
|
+
* // Returns { a: 1, b: 5, c: 4 }
|
|
43
|
+
* @example
|
|
44
|
+
* const target = { a: [1], b: [2] };
|
|
45
|
+
* const source = { a: [3], b: [4] };
|
|
46
|
+
*
|
|
47
|
+
* const result = mergeWith(target, source, (objValue, srcValue) => {
|
|
48
|
+
* if (Array.isArray(objValue)) {
|
|
49
|
+
* return objValue.concat(srcValue);
|
|
50
|
+
* }
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* expect(result).toEqual({ a: [1, 3], b: [2, 4] });
|
|
54
|
+
*/
|
|
55
|
+
declare function mergeWith<T, S>(target: T, source: S, merge: (targetValue: any, sourceValue: any, key: string, target: T, source: S) => any): T & S;
|
|
56
|
+
|
|
57
|
+
export { mergeWith };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges the properties of the source object into the target object.
|
|
3
|
+
*
|
|
4
|
+
* You can provide a custom `merge` function to control how properties are merged. The `merge` function is called for each property that is being merged and receives the following arguments:
|
|
5
|
+
*
|
|
6
|
+
* - `targetValue`: The current value of the property in the target object.
|
|
7
|
+
* - `sourceValue`: The value of the property in the source object.
|
|
8
|
+
* - `key`: The key of the property being merged.
|
|
9
|
+
* - `target`: The target object.
|
|
10
|
+
* - `source`: The source object.
|
|
11
|
+
*
|
|
12
|
+
* The `merge` function should return the value to be set in the target object. If it returns `undefined`, a default deep merge will be applied for arrays and objects:
|
|
13
|
+
*
|
|
14
|
+
* - If a property in the source object is an array or an object and the corresponding property in the target object is also an array or object, they will be merged.
|
|
15
|
+
* - If a property in the source object is undefined, it will not overwrite a defined property in the target object.
|
|
16
|
+
*
|
|
17
|
+
* Note that this function mutates the target object.
|
|
18
|
+
*
|
|
19
|
+
* @param {T} target - The target object into which the source object properties will be merged. This object is modified in place.
|
|
20
|
+
* @param {S} source - The source object whose properties will be merged into the target object.
|
|
21
|
+
* @param {(targetValue: any, sourceValue: any, key: string, target: T, source: S) => any} merge - A custom merge function that defines how properties should be combined. It receives the following arguments:
|
|
22
|
+
* - `targetValue`: The current value of the property in the target object.
|
|
23
|
+
* - `sourceValue`: The value of the property in the source object.
|
|
24
|
+
* - `key`: The key of the property being merged.
|
|
25
|
+
* - `target`: The target object.
|
|
26
|
+
* - `source`: The source object.
|
|
27
|
+
*
|
|
28
|
+
* @returns {T & S} The updated target object with properties from the source object merged in.
|
|
29
|
+
*
|
|
30
|
+
* @template T - Type of the target object.
|
|
31
|
+
* @template S - Type of the source object.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const target = { a: 1, b: 2 };
|
|
35
|
+
* const source = { b: 3, c: 4 };
|
|
36
|
+
*
|
|
37
|
+
* mergeWith(target, source, (targetValue, sourceValue) => {
|
|
38
|
+
* if (typeof targetValue === 'number' && typeof sourceValue === 'number') {
|
|
39
|
+
* return targetValue + sourceValue;
|
|
40
|
+
* }
|
|
41
|
+
* });
|
|
42
|
+
* // Returns { a: 1, b: 5, c: 4 }
|
|
43
|
+
* @example
|
|
44
|
+
* const target = { a: [1], b: [2] };
|
|
45
|
+
* const source = { a: [3], b: [4] };
|
|
46
|
+
*
|
|
47
|
+
* const result = mergeWith(target, source, (objValue, srcValue) => {
|
|
48
|
+
* if (Array.isArray(objValue)) {
|
|
49
|
+
* return objValue.concat(srcValue);
|
|
50
|
+
* }
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* expect(result).toEqual({ a: [1, 3], b: [2, 4] });
|
|
54
|
+
*/
|
|
55
|
+
declare function mergeWith<T, S>(target: T, source: S, merge: (targetValue: any, sourceValue: any, key: string, target: T, source: S) => any): T & S;
|
|
56
|
+
|
|
57
|
+
export { mergeWith };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { isObjectLike } from '../compat/predicate/isObjectLike.mjs';
|
|
2
|
+
|
|
3
|
+
function mergeWith(target, source, merge) {
|
|
4
|
+
const sourceKeys = Object.keys(source);
|
|
5
|
+
for (let i = 0; i < sourceKeys.length; i++) {
|
|
6
|
+
const key = sourceKeys[i];
|
|
7
|
+
const sourceValue = source[key];
|
|
8
|
+
const targetValue = target[key];
|
|
9
|
+
const merged = merge(targetValue, sourceValue, key, target, source);
|
|
10
|
+
if (merged != null) {
|
|
11
|
+
target[key] = merged;
|
|
12
|
+
}
|
|
13
|
+
else if (Array.isArray(sourceValue)) {
|
|
14
|
+
target[key] = mergeWith(targetValue ?? [], sourceValue, merge);
|
|
15
|
+
}
|
|
16
|
+
else if (isObjectLike(targetValue) && isObjectLike(sourceValue)) {
|
|
17
|
+
target[key] = mergeWith(targetValue ?? {}, sourceValue, merge);
|
|
18
|
+
}
|
|
19
|
+
else if (targetValue === undefined || sourceValue !== undefined) {
|
|
20
|
+
target[key] = sourceValue;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return target;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { mergeWith };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "es-toolkit",
|
|
3
3
|
"description": "A state-of-the-art, high-performance JavaScript utility library with a small bundle size and strong type annotations.",
|
|
4
|
-
"version": "1.14.0-dev.
|
|
4
|
+
"version": "1.14.0-dev.410+cc3a4674",
|
|
5
5
|
"homepage": "https://es-toolkit.slash.page",
|
|
6
6
|
"bugs": "https://github.com/toss/es-toolkit/issues",
|
|
7
7
|
"repository": {
|