deepie-merge 3.0.2 → 3.1.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/README.md +5 -3
- package/dist/index.d.ts +9 -14
- package/dist/index.js +13 -13
- package/package.json +17 -15
package/README.md
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
> Yay, another deep merge
|
|
5
5
|
|
|
6
6
|
## Usage
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pnpm add deepie-merge
|
|
9
10
|
```
|
|
10
11
|
|
|
11
12
|
```js
|
|
@@ -31,6 +32,7 @@ Deep-merge `b` into `a`.
|
|
|
31
32
|
- `b` *any*: Source value
|
|
32
33
|
- `options` *object*:
|
|
33
34
|
- `arrayExtend` *boolean* or *string[]*: Whether to extend arrays instead of replacing them. When passed a string array, it will only extend the object keys provided in that array.
|
|
34
|
-
- `
|
|
35
|
+
- `maxRecursion` *number*: Amount of nesting levels to recurse into. Default: `20`
|
|
36
|
+
- `clone` *boolean* or *function*: Return a new value instead of mutating `a`. A function is used to clone `a`, otherwise `structuredClone`. Default: `false`
|
|
35
37
|
|
|
36
38
|
© [silverwind](https://github.com/silverwind), distributed under BSD licence
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
//#region index.d.ts
|
|
2
2
|
type ArrayExtend = boolean | Array<string>;
|
|
3
3
|
type DeepieMergeOpts<T = any> = {
|
|
4
|
-
/** Either a boolean or
|
|
5
|
-
|
|
4
|
+
/** Either a boolean or an array of property keys to allow extension. Default: false */
|
|
5
|
+
arrayExtend?: ArrayExtend;
|
|
6
|
+
/** Maximum recursions to perform. Default: 20. */
|
|
7
|
+
maxRecursion?: number;
|
|
8
|
+
/** Return a new value instead of mutating the first argument. Default: false */
|
|
6
9
|
clone?: boolean | ((value: NoInfer<T>) => NoInfer<T>);
|
|
7
10
|
};
|
|
8
11
|
type DeepMergeable = {
|
|
9
12
|
[key: string]: any;
|
|
10
13
|
} | Array<any>;
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
* excess keys on fresh literals, while accepting wider override types
|
|
14
|
-
* (e.g. `Partial<UserConfig>` against a `satisfies`-narrowed literal). */
|
|
15
|
-
type DeepMergeSource<T> = T extends ReadonlyArray<any> ? ReadonlyArray<unknown> : T extends object ? { [K in keyof T]?: unknown } : never;
|
|
14
|
+
/** Top-level shape and keys of `T` with `unknown` values: rejects excess keys, accepts wider overrides */
|
|
15
|
+
type DeepMergeSource<T> = T extends ReadonlyArray<any> ? ReadonlyArray<unknown> : T extends object ? { [K in keyof T]?: unknown; } : never;
|
|
16
16
|
/** deep-merge b into a */
|
|
17
|
-
declare function deepMerge<T extends DeepMergeable>(a: T, b: NoInfer<T> | DeepMergeSource<NoInfer<T>> | null | undefined, {
|
|
18
|
-
|
|
19
|
-
maxRecursion,
|
|
20
|
-
clone
|
|
21
|
-
}?: DeepieMergeOpts<T>): T;
|
|
22
|
-
//#endregion
|
|
23
|
-
export { deepMerge };
|
|
17
|
+
export declare function deepMerge<T extends DeepMergeable>(a: T, b: NoInfer<T> | DeepMergeSource<NoInfer<T>> | null | undefined, { arrayExtend, maxRecursion, clone }?: DeepieMergeOpts<T>): T;
|
|
18
|
+
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -8,28 +8,28 @@ function getType(obj) {
|
|
|
8
8
|
return typeof obj;
|
|
9
9
|
}
|
|
10
10
|
/** deep-merge b into a */
|
|
11
|
-
function deepMerge(a, b, { arrayExtend = false, maxRecursion = 20, clone = false } = {
|
|
12
|
-
arrayExtend: false,
|
|
13
|
-
maxRecursion: 10
|
|
14
|
-
}) {
|
|
11
|
+
function deepMerge(a, b, { arrayExtend = false, maxRecursion = 20, clone = false } = {}) {
|
|
15
12
|
return merge(clone ? typeof clone === "function" ? clone(a) : structuredClone(a) : a, b, arrayExtend, maxRecursion);
|
|
16
13
|
}
|
|
14
|
+
function union(target, source) {
|
|
15
|
+
const set = new Set(target);
|
|
16
|
+
for (const value of source) set.add(value);
|
|
17
|
+
return Array.from(set);
|
|
18
|
+
}
|
|
17
19
|
function merge(a, b, arrayExtend, maxRecursion) {
|
|
18
20
|
if (maxRecursion === 0) return a;
|
|
19
|
-
if (Array.isArray(a))
|
|
20
|
-
if (Array.isArray(b)) return arrayExtend ? Array.from(new Set([...a, ...b])) : b;
|
|
21
|
-
return b;
|
|
22
|
-
}
|
|
21
|
+
if (Array.isArray(a)) return arrayExtend && Array.isArray(b) ? union(a, b) : b;
|
|
23
22
|
if (Array.isArray(b)) return b;
|
|
24
23
|
if (isObject(a) && isObject(b)) {
|
|
25
24
|
const keys = Object.keys(b);
|
|
26
25
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
27
26
|
const key = keys[i];
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
else a[key] =
|
|
27
|
+
const valueA = a[key];
|
|
28
|
+
if (key === "__proto__" || (key === "constructor" || key === "prototype") && isObject(valueA) && !Object.hasOwn(a, key)) continue;
|
|
29
|
+
const valueB = b[key];
|
|
30
|
+
if (isObject(valueA) && isObject(valueB)) a[key] = merge(valueA, valueB, arrayExtend, maxRecursion - 1);
|
|
31
|
+
else if (Array.isArray(valueA) && Array.isArray(valueB) && (Array.isArray(arrayExtend) ? arrayExtend.includes(key) : arrayExtend)) a[key] = union(valueA, valueB);
|
|
32
|
+
else a[key] = valueB === null && getType(valueA) === "object" ? valueA : valueB;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
return a;
|
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepie-merge",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Yay, another deep merge",
|
|
5
5
|
"author": "silverwind <me@silverwind.io>",
|
|
6
|
-
"repository":
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/silverwind/deepie-merge.git"
|
|
9
|
+
},
|
|
7
10
|
"license": "BSD-2-Clause",
|
|
8
11
|
"type": "module",
|
|
9
12
|
"sideEffects": false,
|
|
@@ -17,19 +20,18 @@
|
|
|
17
20
|
"node": ">=22"
|
|
18
21
|
},
|
|
19
22
|
"devDependencies": {
|
|
20
|
-
"@types/node": "
|
|
21
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
22
|
-
"eslint": "10.
|
|
23
|
-
"eslint-config-silverwind": "
|
|
24
|
-
"
|
|
25
|
-
"tsdown": "
|
|
26
|
-
"tsdown-config-silverwind": "3.0.0",
|
|
23
|
+
"@types/node": "26.6.3",
|
|
24
|
+
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
25
|
+
"eslint": "10.11.0",
|
|
26
|
+
"eslint-config-silverwind": "151.0.1",
|
|
27
|
+
"tsdown": "0.23.0",
|
|
28
|
+
"tsdown-config-silverwind": "4.1.2",
|
|
27
29
|
"typescript": "6.0.3",
|
|
28
|
-
"typescript-config-silverwind": "
|
|
29
|
-
"updates": "
|
|
30
|
-
"updates-config-silverwind": "
|
|
31
|
-
"versions": "15.
|
|
32
|
-
"vitest": "
|
|
33
|
-
"vitest-config-silverwind": "
|
|
30
|
+
"typescript-config-silverwind": "21.0.1",
|
|
31
|
+
"updates": "19.0.2",
|
|
32
|
+
"updates-config-silverwind": "4.0.7",
|
|
33
|
+
"versions": "15.5.1",
|
|
34
|
+
"vitest": "5.0.2",
|
|
35
|
+
"vitest-config-silverwind": "12.0.5"
|
|
34
36
|
}
|
|
35
37
|
}
|