@cleverbrush/deep 1.1.0 → 1.1.1
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 +71 -21
- package/dist/deepEqual.d.ts +1 -2
- package/dist/deepEqual.js +2 -5
- package/dist/deepExtend.d.ts +1 -2
- package/dist/deepExtend.js +23 -24
- package/dist/deepFlatten.d.ts +17 -0
- package/dist/deepFlatten.js +41 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +6 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,9 +8,11 @@ This is yet another library which provides operations over JavaScript objects, l
|
|
|
8
8
|
|
|
9
9
|
## Usage
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
```typescript
|
|
12
|
+
import deep from '@cleverbrush/deep';
|
|
13
|
+
// or import functions individually
|
|
14
|
+
import { deepEqual, deepExtend } from '@cleverbrush/deep';
|
|
15
|
+
```
|
|
14
16
|
|
|
15
17
|
## Functions
|
|
16
18
|
|
|
@@ -18,36 +20,45 @@ This is yet another library which provides operations over JavaScript objects, l
|
|
|
18
20
|
|
|
19
21
|
Takes two objects as parameters, compares it recursively and returns `true` if they are equal or `false` in other case.
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
```typescript
|
|
24
|
+
import { deepEqual } from '@cleverbrush/deep';
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
const equal1 = deepEqual({ a: { b: 1 } }, { a: { b: 1 } });
|
|
27
|
+
// equal1 === true
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
const equal2 = deepEqual({ a: { b: 1 } }, { a: { b: 20 } });
|
|
30
|
+
// equal2 === false
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
const equal3 = deepEqual({ a: { b: 1, c: 2 } }, { a: { b: 20 } });
|
|
33
|
+
// equal3 === false
|
|
34
|
+
```
|
|
31
35
|
|
|
32
36
|
### deepExtend
|
|
33
37
|
|
|
34
38
|
Works similary to `Object.extend`, but respects the deep structure of objects.
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
```typescript
|
|
41
|
+
import { deepExtend } from '@cleverbrush/deep';
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
deepExtend(
|
|
44
|
+
{},
|
|
45
|
+
{
|
|
46
|
+
a: 'something',
|
|
47
|
+
name: {
|
|
48
|
+
first: 'Ivan'
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: {
|
|
53
|
+
last: 'Ivanov'
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
```
|
|
48
58
|
|
|
49
59
|
will return the following object:
|
|
50
60
|
|
|
61
|
+
```typescript
|
|
51
62
|
{
|
|
52
63
|
a: 'something',
|
|
53
64
|
name: {
|
|
@@ -55,3 +66,42 @@ will return the following object:
|
|
|
55
66
|
last: 'Ivanov'
|
|
56
67
|
}
|
|
57
68
|
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### deepFlatten
|
|
72
|
+
|
|
73
|
+
Flattens an object to a single level. Accepts an optional separator as a second parameter.
|
|
74
|
+
If no separator is provided, the default separator is `.`.
|
|
75
|
+
Supports only objects with string keys. Supports nested objects of any depth.
|
|
76
|
+
Throws an error if the object contains circular references.
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { deepFlatten } from '@cleverbrush/deep';
|
|
80
|
+
|
|
81
|
+
deepFlatten({
|
|
82
|
+
a: {
|
|
83
|
+
b: 1,
|
|
84
|
+
c: 2
|
|
85
|
+
},
|
|
86
|
+
d: 3
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// => { 'a.b': 1, 'a.c': 2, d: 3 }
|
|
90
|
+
|
|
91
|
+
deepFlatten(
|
|
92
|
+
{
|
|
93
|
+
a: {
|
|
94
|
+
b: 1,
|
|
95
|
+
c: 2
|
|
96
|
+
},
|
|
97
|
+
d: {
|
|
98
|
+
e: {
|
|
99
|
+
f: 3
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
'-'
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
// => { 'a-b': 1, 'a-c': 2, 'd-e-f': 3 }
|
|
107
|
+
```
|
package/dist/deepEqual.d.ts
CHANGED
|
@@ -8,11 +8,10 @@
|
|
|
8
8
|
* @param options additional options
|
|
9
9
|
* @returns {boolean} `true` if the objects are equal, `false` otherwise
|
|
10
10
|
*/
|
|
11
|
-
declare const deepEqual: (p1: any, p2: any, options?: {
|
|
11
|
+
export declare const deepEqual: (p1: any, p2: any, options?: {
|
|
12
12
|
/**
|
|
13
13
|
* if true, the order of the elements in the array will be disregarded
|
|
14
14
|
* e.g. [1, 2] and [2, 1] will be considered equal
|
|
15
15
|
*/
|
|
16
16
|
disregardArrayOrder?: boolean;
|
|
17
17
|
}) => boolean;
|
|
18
|
-
export default deepEqual;
|
package/dist/deepEqual.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { HashObject } from './hashObject.js';
|
|
2
|
-
const isBothNaN =
|
|
3
|
-
return Number.isNaN(v1) && Number.isNaN(v2);
|
|
4
|
-
};
|
|
2
|
+
const isBothNaN = (v1, v2) => Number.isNaN(v1) && Number.isNaN(v2);
|
|
5
3
|
/**
|
|
6
4
|
* Compares two objects and returns true if they
|
|
7
5
|
* have the same structure and values. Can work
|
|
@@ -12,7 +10,7 @@ const isBothNaN = function (v1, v2) {
|
|
|
12
10
|
* @param options additional options
|
|
13
11
|
* @returns {boolean} `true` if the objects are equal, `false` otherwise
|
|
14
12
|
*/
|
|
15
|
-
const deepEqual = function (p1, p2, options) {
|
|
13
|
+
export const deepEqual = function (p1, p2, options) {
|
|
16
14
|
const cache = new Map();
|
|
17
15
|
const compare = function (o1, o2) {
|
|
18
16
|
const arraysAreIdentical = function (a1, a2) {
|
|
@@ -90,4 +88,3 @@ const deepEqual = function (p1, p2, options) {
|
|
|
90
88
|
};
|
|
91
89
|
return compare(p1, p2);
|
|
92
90
|
};
|
|
93
|
-
export default deepEqual;
|
package/dist/deepExtend.d.ts
CHANGED
|
@@ -6,5 +6,4 @@ export type MergeTwo<T1, T2> = PropsInFirstOnly<T1, T2> & PropsInFirstOnly<T2, T
|
|
|
6
6
|
[k in keyof CommonProps<T1, T2>]: T1[k] extends Record<string, unknown> ? T2[k] extends Record<string, unknown> ? MergeTwo<T1[k], T2[k]> : T2[k] : T2[k];
|
|
7
7
|
};
|
|
8
8
|
export type Merge<T extends unknown[]> = T['length'] extends 3 ? MergeTwo<T[0], MergeTwo<T[1], T[2]>> : T['length'] extends 2 ? MergeTwo<T[0], T[1]> : T['length'] extends 1 ? T[0] : T extends [...infer K, infer PL, infer L] ? Merge<[Merge<[...K]>, MergeTwo<PL, L>]> : never;
|
|
9
|
-
declare const deepExtend: <T extends unknown[]>(...args: T) => Merge<T>;
|
|
10
|
-
export default deepExtend;
|
|
9
|
+
export declare const deepExtend: <T extends unknown[]>(...args: T) => Merge<T>;
|
package/dist/deepExtend.js
CHANGED
|
@@ -1,38 +1,37 @@
|
|
|
1
|
-
const deepExtend =
|
|
2
|
-
if (
|
|
3
|
-
|
|
4
|
-
if (
|
|
5
|
-
|
|
6
|
-
if (
|
|
7
|
-
return
|
|
1
|
+
export const deepExtend = ((...rest) => {
|
|
2
|
+
if (rest.length === 0)
|
|
3
|
+
throw new Error('no arguments');
|
|
4
|
+
if (typeof rest[0] !== 'object' || rest[0] === null)
|
|
5
|
+
throw new Error('not a non-null object');
|
|
6
|
+
if (rest.length === 1)
|
|
7
|
+
return rest[0];
|
|
8
8
|
const result = {};
|
|
9
9
|
const extendObject = function (o1, o2) {
|
|
10
|
-
if (o2 == null)
|
|
11
|
-
return;
|
|
12
10
|
const keys = Object.keys(o2);
|
|
13
11
|
for (let i = 0; i < keys.length; i++) {
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
if (!Reflect.has(o1, keys[i]) ||
|
|
13
|
+
!(typeof o1[keys[i]] === 'object' &&
|
|
14
|
+
o1[keys[i]] !== null &&
|
|
15
|
+
typeof o2[keys[i]] === 'object')) {
|
|
16
|
+
o1[keys[i]] = o2[keys[i]];
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
if (o1[keys[i]] == null || o2[keys[i]] == null) {
|
|
18
20
|
o1[keys[i]] = o2[keys[i]];
|
|
19
21
|
}
|
|
20
22
|
else {
|
|
21
|
-
|
|
22
|
-
o1[keys[i]] = o2[keys[i]];
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
extendObject(o1[keys[i]], o2[keys[i]]);
|
|
26
|
-
}
|
|
23
|
+
extendObject(o1[keys[i]], o2[keys[i]]);
|
|
27
24
|
}
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
27
|
};
|
|
31
|
-
for (let i = 0; i <
|
|
32
|
-
if (typeof
|
|
33
|
-
extendObject(result,
|
|
28
|
+
for (let i = 0; i < rest.length; i++) {
|
|
29
|
+
if (typeof rest[i] === 'object' && rest[i] !== null && rest[i]) {
|
|
30
|
+
extendObject(result, rest[i]);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
throw new Error('not a non-null object');
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
return result;
|
|
37
|
-
};
|
|
38
|
-
export default deepExtend;
|
|
37
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flattens an object to a single level, with the nested keys separated by a `delimiter`.
|
|
3
|
+
* @example
|
|
4
|
+
* ```ts
|
|
5
|
+
* deepFlatten({ a: { b: 1, c: 2 } });
|
|
6
|
+
* // => { 'a.b': 1, 'a.c': 2 }
|
|
7
|
+
*
|
|
8
|
+
* deepFlatten({ a: { b: 1, c: 2 } }, '/');
|
|
9
|
+
* // => { 'a/b': 1, 'a/c': 2 }
|
|
10
|
+
*
|
|
11
|
+
* deepFlatten({ a: { b: 1, c: { d: 'some val' } }, d: 3 });
|
|
12
|
+
* // => { 'a.b': 1, 'a.c.d': 'some val', d: 3 }
|
|
13
|
+
*
|
|
14
|
+
* ```
|
|
15
|
+
* @param {string} [delimiter]
|
|
16
|
+
*/
|
|
17
|
+
export declare function deepFlatten(obj: Record<string, any>, delimiter?: string): Record<string, any>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flattens an object to a single level, with the nested keys separated by a `delimiter`.
|
|
3
|
+
* @example
|
|
4
|
+
* ```ts
|
|
5
|
+
* deepFlatten({ a: { b: 1, c: 2 } });
|
|
6
|
+
* // => { 'a.b': 1, 'a.c': 2 }
|
|
7
|
+
*
|
|
8
|
+
* deepFlatten({ a: { b: 1, c: 2 } }, '/');
|
|
9
|
+
* // => { 'a/b': 1, 'a/c': 2 }
|
|
10
|
+
*
|
|
11
|
+
* deepFlatten({ a: { b: 1, c: { d: 'some val' } }, d: 3 });
|
|
12
|
+
* // => { 'a.b': 1, 'a.c.d': 'some val', d: 3 }
|
|
13
|
+
*
|
|
14
|
+
* ```
|
|
15
|
+
* @param {string} [delimiter]
|
|
16
|
+
*/
|
|
17
|
+
export function deepFlatten(obj, delimiter = '.') {
|
|
18
|
+
const shouldFlatten = (obj) => typeof obj === 'object' &&
|
|
19
|
+
obj !== null &&
|
|
20
|
+
!Array.isArray(obj) &&
|
|
21
|
+
Object.getPrototypeOf(obj) === Object.prototype;
|
|
22
|
+
if (!shouldFlatten(obj))
|
|
23
|
+
throw new Error('cannot flatten this object');
|
|
24
|
+
const stack = [];
|
|
25
|
+
const result = {};
|
|
26
|
+
const deepFlattenHelper = (obj, prefix = '') => {
|
|
27
|
+
if (stack.find((o) => o === obj))
|
|
28
|
+
throw new Error('circular reference detected');
|
|
29
|
+
stack.push(obj);
|
|
30
|
+
Object.keys(obj).forEach((key) => {
|
|
31
|
+
if (!shouldFlatten(obj[key])) {
|
|
32
|
+
result[prefix ? `${prefix}${delimiter}${key}` : key] = obj[key];
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
deepFlattenHelper(obj[key], prefix ? `${prefix}${delimiter}${key}` : key);
|
|
36
|
+
});
|
|
37
|
+
stack.pop();
|
|
38
|
+
};
|
|
39
|
+
deepFlattenHelper(obj);
|
|
40
|
+
return result;
|
|
41
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import deepEqual from './deepEqual';
|
|
2
|
-
import deepExtend,
|
|
3
|
-
|
|
1
|
+
import { deepEqual } from './deepEqual.js';
|
|
2
|
+
import { deepExtend, type Merge } from './deepExtend.js';
|
|
3
|
+
import { deepFlatten } from './deepFlatten.js';
|
|
4
|
+
export { deepEqual, deepExtend, deepFlatten, type Merge };
|
|
4
5
|
declare const _default: {
|
|
5
6
|
deepEqual: (p1: any, p2: any, options?: {
|
|
6
7
|
disregardArrayOrder?: boolean;
|
|
7
8
|
}) => boolean;
|
|
8
9
|
deepExtend: <T extends unknown[]>(...args: T) => Merge<T>;
|
|
10
|
+
deepFlatten: typeof deepFlatten;
|
|
9
11
|
};
|
|
10
12
|
export default _default;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import deepEqual from './deepEqual';
|
|
2
|
-
import deepExtend from './deepExtend';
|
|
3
|
-
|
|
1
|
+
import { deepEqual } from './deepEqual.js';
|
|
2
|
+
import { deepExtend } from './deepExtend.js';
|
|
3
|
+
import { deepFlatten } from './deepFlatten.js';
|
|
4
|
+
export { deepEqual, deepExtend, deepFlatten };
|
|
4
5
|
export default {
|
|
5
6
|
deepEqual,
|
|
6
|
-
deepExtend
|
|
7
|
+
deepExtend,
|
|
8
|
+
deepFlatten
|
|
7
9
|
};
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
|
-
"homepage": "https://docs.cleverbrush.com/v1.
|
|
11
|
+
"homepage": "https://docs.cleverbrush.com/v1.1.1/modules/Deep_operations_on_objects.html",
|
|
12
12
|
"keywords": [
|
|
13
13
|
"deep operations on objects",
|
|
14
14
|
"deep equal",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
},
|
|
36
36
|
"type": "module",
|
|
37
37
|
"types": "./dist/index.d.ts",
|
|
38
|
-
"version": "1.1.
|
|
38
|
+
"version": "1.1.1"
|
|
39
39
|
}
|