merge-deeper-object 0.2.0 → 1.0.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 +63 -13
- package/dist/index.cjs +39 -0
- package/dist/index.mjs +37 -0
- package/package.json +20 -14
- package/index.d.ts +0 -2
- package/index.js +0 -18
package/README.md
CHANGED
|
@@ -1,32 +1,82 @@
|
|
|
1
1
|
## merge-deeper-object
|
|
2
|
-
Combine the attributes of objects deeply.
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
A lightweight, zero-dependency utility for deep merging objects
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Deep merge object:** recursively merges nested objects
|
|
8
|
+
- **Array concatenation:** arrays are combined, not overwritten
|
|
9
|
+
- **Immutable:** returns a new object, never mutates the originals
|
|
10
|
+
- **Symbol support:** handles Symbol keys alongside string keys
|
|
11
|
+
- **Secure:** blocks prototype pollution
|
|
12
|
+
- **Dual format:** ships both CJS and ESM builds
|
|
13
|
+
- **Zero dependencies**
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
5
17
|
```
|
|
6
|
-
npm install
|
|
18
|
+
npm install merge-deeper-object
|
|
7
19
|
```
|
|
8
20
|
|
|
9
|
-
## Running tests
|
|
10
21
|
```
|
|
11
|
-
|
|
12
|
-
|
|
22
|
+
yarn add merge-deeper-object
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
pnpm add merge-deeper-object
|
|
13
27
|
```
|
|
14
28
|
|
|
15
29
|
## Usage
|
|
30
|
+
|
|
31
|
+
### ESM
|
|
32
|
+
|
|
16
33
|
```javascript
|
|
17
|
-
|
|
34
|
+
import mergeDeeper from 'merge-deeper-object';
|
|
18
35
|
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
const base = {
|
|
37
|
+
server: { port: 3000, host: 'localhost' },
|
|
38
|
+
features: ['auth']
|
|
39
|
+
};
|
|
21
40
|
|
|
22
|
-
|
|
41
|
+
const overrides = {
|
|
42
|
+
server: { port: 8080, ssl: true },
|
|
43
|
+
features: ['logging']
|
|
44
|
+
};
|
|
23
45
|
|
|
46
|
+
const config = mergeDeeper(base, overrides);
|
|
47
|
+
// {
|
|
48
|
+
// server: { port: 8080, host: 'localhost', ssl: true },
|
|
49
|
+
// features: ['auth', 'logging']
|
|
50
|
+
// }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### CJS
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
const mergeDeeper = require('merge-deeper-object');
|
|
24
57
|
|
|
25
|
-
|
|
58
|
+
const result = mergeDeeper({ a: 1 }, { b: 2 });
|
|
59
|
+
// { a: 1, b: 2 }
|
|
26
60
|
```
|
|
27
61
|
|
|
28
|
-
##
|
|
29
|
-
|
|
62
|
+
## Testing
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
git clone git@github.com:work-state/merge-deeper-object.git
|
|
66
|
+
cd merge-deeper-object
|
|
67
|
+
npm install
|
|
68
|
+
npm test
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Compatibility
|
|
72
|
+
|
|
73
|
+
- **Node.js** >= 14
|
|
74
|
+
- **Browsers:** all modern browsers (ES2015+). If you need to support older browsers, configure yout bundler (Babel, SWC) to transpile `node_modules/merge-deeper-object`
|
|
30
75
|
|
|
31
76
|
## License
|
|
77
|
+
|
|
32
78
|
[MIT](https://github.com/work-state/merge-deeper-object/blob/master/LICENSE.md)
|
|
79
|
+
|
|
80
|
+
## Author
|
|
81
|
+
|
|
82
|
+
[Ilyass Mabrouk](https://github.com/work-state)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
4
|
+
|
|
5
|
+
function isSafe(key) {
|
|
6
|
+
return typeof key === 'symbol' || !UNSAFE_KEYS.has(key);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function isPlainObject(value) {
|
|
10
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function mergeDeeper(target, source) {
|
|
14
|
+
if (!isPlainObject(source)) return target;
|
|
15
|
+
|
|
16
|
+
const result = { ...target };
|
|
17
|
+
|
|
18
|
+
for (const key of [
|
|
19
|
+
...Object.keys(source),
|
|
20
|
+
...Object.getOwnPropertySymbols(source)
|
|
21
|
+
]) {
|
|
22
|
+
if (!isSafe(key)) continue;
|
|
23
|
+
|
|
24
|
+
const srcVal = source[key];
|
|
25
|
+
const targetVal = result[key];
|
|
26
|
+
|
|
27
|
+
if (Array.isArray(srcVal) && Array.isArray(targetVal)) {
|
|
28
|
+
result[key] = [...targetVal, ...srcVal];
|
|
29
|
+
} else if (isPlainObject(srcVal) && isPlainObject(targetVal)) {
|
|
30
|
+
result[key] = mergeDeeper(targetVal, srcVal);
|
|
31
|
+
} else {
|
|
32
|
+
result[key] = srcVal;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = mergeDeeper;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
2
|
+
|
|
3
|
+
function isSafe(key) {
|
|
4
|
+
return typeof key === 'symbol' || !UNSAFE_KEYS.has(key);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function isPlainObject(value) {
|
|
8
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function mergeDeeper(target, source) {
|
|
12
|
+
if (!isPlainObject(source)) return target;
|
|
13
|
+
|
|
14
|
+
const result = { ...target };
|
|
15
|
+
|
|
16
|
+
for (const key of [
|
|
17
|
+
...Object.keys(source),
|
|
18
|
+
...Object.getOwnPropertySymbols(source)
|
|
19
|
+
]) {
|
|
20
|
+
if (!isSafe(key)) continue;
|
|
21
|
+
|
|
22
|
+
const srcVal = source[key];
|
|
23
|
+
const targetVal = result[key];
|
|
24
|
+
|
|
25
|
+
if (Array.isArray(srcVal) && Array.isArray(targetVal)) {
|
|
26
|
+
result[key] = [...targetVal, ...srcVal];
|
|
27
|
+
} else if (isPlainObject(srcVal) && isPlainObject(targetVal)) {
|
|
28
|
+
result[key] = mergeDeeper(targetVal, srcVal);
|
|
29
|
+
} else {
|
|
30
|
+
result[key] = srcVal;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { mergeDeeper as default };
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "1.0.0",
|
|
3
3
|
"author": "Ilyass Mabrouk",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"name": "merge-deeper-object",
|
|
6
|
-
"description": "Deep merge
|
|
6
|
+
"description": "Deep merge utility for nested objects.",
|
|
7
7
|
"homepage": "https://github.com/work-state/merge-deeper-object",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -12,14 +12,19 @@
|
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/work-state/merge-deeper-object/issues"
|
|
14
14
|
},
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./dist/index.mjs",
|
|
18
|
+
"require": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"main": "dist/index.cjs",
|
|
22
|
+
"module": "dist/index.mjs",
|
|
23
|
+
"files": ["dist"],
|
|
21
24
|
"scripts": {
|
|
22
|
-
"test": "
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"build": "rollup -c",
|
|
27
|
+
"prepublishOnly": "npm run build && npm run test"
|
|
23
28
|
},
|
|
24
29
|
"keywords": [
|
|
25
30
|
"object",
|
|
@@ -37,7 +42,8 @@
|
|
|
37
42
|
"properties",
|
|
38
43
|
"property",
|
|
39
44
|
"entries",
|
|
40
|
-
"entry"
|
|
45
|
+
"entry",
|
|
46
|
+
"recursive"
|
|
41
47
|
],
|
|
42
48
|
"verb": {
|
|
43
49
|
"tasks": [
|
|
@@ -51,10 +57,10 @@
|
|
|
51
57
|
}
|
|
52
58
|
},
|
|
53
59
|
"devDependencies": {
|
|
54
|
-
"
|
|
55
|
-
"
|
|
60
|
+
"rollup": "^4.59.0",
|
|
61
|
+
"vitest": "^4.1.0"
|
|
56
62
|
},
|
|
57
|
-
"
|
|
58
|
-
"
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=14"
|
|
59
65
|
}
|
|
60
66
|
}
|
package/index.d.ts
DELETED
package/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
module.exports = function mergeDeeper(object, merge) {
|
|
2
|
-
if (!merge || typeof merge === "string") merge = {};
|
|
3
|
-
[...Object.keys(merge), ...Object.getOwnPropertySymbols(merge)].map((key) => {
|
|
4
|
-
if (Array.isArray(merge[key]) && Array.isArray(object[key])) {
|
|
5
|
-
object[key] = [...object[key], ...merge[key]];
|
|
6
|
-
} else {
|
|
7
|
-
if (
|
|
8
|
-
key in object &&
|
|
9
|
-
(typeof merge[key] && typeof object[key]) === "object"
|
|
10
|
-
) {
|
|
11
|
-
mergeDeeper(object[key], merge[key]);
|
|
12
|
-
} else {
|
|
13
|
-
object[key] = merge[key];
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
return object;
|
|
18
|
-
};
|