@sandboxed/diff 1.0.0 → 1.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/docs/config.md +40 -38
- package/docs/utils.md +12 -14
- package/lib/index.cjs +47 -17
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +10 -7
- package/lib/index.js +47 -17
- package/lib/index.js.map +1 -1
- package/package.json +2 -1
package/docs/config.md
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
|
|
2
1
|
## Config
|
|
3
2
|
|
|
4
3
|
#### `.include: ChangeType | ChangeType[]`
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
| | |
|
|
6
|
+
| --------------- | ------------------------------------------------------------------------------------- |
|
|
8
7
|
| **Description** | Include only these change types from the diff result. Can be combined with `exclude`. |
|
|
9
|
-
| **Default**
|
|
8
|
+
| **Default** | `[ChangeType.NOOP, ChangeType.ADD, ChangeType.UPDATE, ChangeType.REMOVE]` |
|
|
10
9
|
|
|
11
10
|
```javascript
|
|
12
11
|
diff(a, b, { include: [ChangeType.ADD] }); // only additions
|
|
@@ -19,10 +18,11 @@ diff(a, b, {
|
|
|
19
18
|
---
|
|
20
19
|
|
|
21
20
|
#### `.exclude: ChangeType | ChangeType[]`
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
|
|
22
|
+
| | |
|
|
23
|
+
| --------------- | ------------------------------------------------------------------------------- |
|
|
24
24
|
| **Description** | Excludes the change types from the diff result. Can be combined with `include`. |
|
|
25
|
-
| **Default**
|
|
25
|
+
| **Default** | `[]` |
|
|
26
26
|
|
|
27
27
|
```javascript
|
|
28
28
|
diff(a, b, { exclude: ChangeType.NOOP });
|
|
@@ -34,10 +34,10 @@ diff(a, b, { exclude: [ChangeType.ADD, ChangeType.NOOP] });
|
|
|
34
34
|
|
|
35
35
|
#### `.strict: boolean`
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
| | |
|
|
38
|
+
| --------------- | -------------------------------------- |
|
|
39
39
|
| **Description** | Performs loose type check if disabled. |
|
|
40
|
-
| **Default**
|
|
40
|
+
| **Default** | `true` |
|
|
41
41
|
|
|
42
42
|
```javascript
|
|
43
43
|
const a = { foo: 1 };
|
|
@@ -52,10 +52,10 @@ console.log(diff(a, b, { strict: false }).equal); // true
|
|
|
52
52
|
|
|
53
53
|
#### `.showUpdatedOnly: boolean`
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
| | |
|
|
56
|
+
| --------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
57
57
|
| **Description** | `@sandboxed/diff` creates a `ChangeType.REMOVE` entry for every `ChangeType.UPDATE`. This flags prevents this behavior. |
|
|
58
|
-
| **Default**
|
|
58
|
+
| **Default** | `false` |
|
|
59
59
|
|
|
60
60
|
```javascript
|
|
61
61
|
const a = { foo: 'baz' };
|
|
@@ -65,6 +65,7 @@ console.log(diff(a, b, { showUpdatedOnly: true }));
|
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
**Output**:
|
|
68
|
+
|
|
68
69
|
```javascript
|
|
69
70
|
[
|
|
70
71
|
{ type: 'noop', str: '{', depth: 0, path: [] },
|
|
@@ -72,20 +73,20 @@ console.log(diff(a, b, { showUpdatedOnly: true }));
|
|
|
72
73
|
type: 'update',
|
|
73
74
|
str: '"foo": "bar",',
|
|
74
75
|
depth: 1,
|
|
75
|
-
path: [
|
|
76
|
+
path: ['foo', { deleted: false, value: 'bar' }],
|
|
76
77
|
},
|
|
77
|
-
{ type: 'noop', str: '}', depth: 0, path: [] }
|
|
78
|
-
]
|
|
78
|
+
{ type: 'noop', str: '}', depth: 0, path: [] },
|
|
79
|
+
];
|
|
79
80
|
```
|
|
80
81
|
|
|
81
82
|
---
|
|
82
83
|
|
|
83
84
|
#### `.pathHints: PatHints`
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
| | |
|
|
87
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
87
88
|
| **Description** | Hashmap of `map` and `set` path hints. These strings will be used in the `path` array to provide a hit about the object's type. |
|
|
88
|
-
| **Default**
|
|
89
|
+
| **Default** | `{ map: '__MAP__', set: '__SET__' }` |
|
|
89
90
|
|
|
90
91
|
⚠️ Warning: **Complex keys are not recursively diffed**, they are treated as references only.
|
|
91
92
|
**Assume that any string entry in the path array comes from plain objects, and numeric entries come from arrays**. Without these hints, tracking back to the origin can be difficult, though can be disabled if not needed.
|
|
@@ -104,10 +105,10 @@ console.log(result[1].path); // ['__MAP__', 'foo', { deleted: false, value: 'bar
|
|
|
104
105
|
|
|
105
106
|
#### `.redactKeys: Array<string>`
|
|
106
107
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
| **Description** | List of keys that should be redacted from the output. Works with `string` based keys and serialized `Symbol
|
|
110
|
-
|
|
108
|
+
| | |
|
|
109
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
110
|
+
| **Description** | List of keys that should be redacted from the output. Works with `string` based keys and serialized `Symbol`. |
|
|
111
|
+
| **Default** | `[ 'password', 'secret', 'token', 'Symbol(password)', 'Symbol (secret)', 'Symbol(token)' ]` |
|
|
111
112
|
|
|
112
113
|
⚠️ Warning: Only the result `str` is redacted, the `path` array still contains the reference to the actual values. Be careful when using this for logging.
|
|
113
114
|
|
|
@@ -119,6 +120,7 @@ console.log(diff(a, b, { showUpdatedOnly: true }));
|
|
|
119
120
|
```
|
|
120
121
|
|
|
121
122
|
**Output**:
|
|
123
|
+
|
|
122
124
|
```javascript
|
|
123
125
|
[
|
|
124
126
|
{ type: 'noop', str: '{', depth: 0, path: [] },
|
|
@@ -126,40 +128,40 @@ console.log(diff(a, b, { showUpdatedOnly: true }));
|
|
|
126
128
|
type: 'update',
|
|
127
129
|
str: '"password": "*****",',
|
|
128
130
|
depth: 1,
|
|
129
|
-
path: [
|
|
131
|
+
path: ['password', { deleted: false, value: 'secret' }],
|
|
130
132
|
},
|
|
131
|
-
{ type: 'noop', str: '}', depth: 0, path: [] }
|
|
132
|
-
]
|
|
133
|
+
{ type: 'noop', str: '}', depth: 0, path: [] },
|
|
134
|
+
];
|
|
133
135
|
```
|
|
134
136
|
|
|
135
137
|
---
|
|
136
138
|
|
|
137
139
|
#### `.maxDepth: number`
|
|
138
140
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
| | |
|
|
142
|
+
| --------------- | ------------------------------------------------------------------------------- |
|
|
141
143
|
| **Description** | Max depth that the diffing function can traverse. Throws when reaching the max. |
|
|
142
|
-
| **Default**
|
|
143
|
-
| **Throws**
|
|
144
|
+
| **Default** | `50` |
|
|
145
|
+
| **Throws** | `Max depth exceeded!` |
|
|
144
146
|
|
|
145
147
|
---
|
|
146
148
|
|
|
147
149
|
#### `.maxKeys: number`
|
|
148
150
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
+
| | |
|
|
152
|
+
| --------------- | ------------------------------------------------------------------------- |
|
|
151
153
|
| **Description** | Max keys the diffing function can traverse. Throws when reaching the max. |
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
| **Default** | `50` |
|
|
155
|
+
| **Throws** | `Object is too big to continue! Aborting.` |
|
|
154
156
|
|
|
155
157
|
---
|
|
156
158
|
|
|
157
159
|
#### `.timeout: number`
|
|
158
160
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
+
| | |
|
|
162
|
+
| --------------- | --------------------------------------------- |
|
|
161
163
|
| **Description** | Milliseconds before throwing a timeout error. |
|
|
162
|
-
|
|
163
|
-
|
|
164
|
+
| **Default** | `1000` |
|
|
165
|
+
| **Throws** | `Diff took too much time! Aborting.` |
|
|
164
166
|
|
|
165
167
|
⚠️ Warning: The diffing function does not check for object size in memory. The process can still hang if the system is unable to handle the object in memory.
|
package/docs/utils.md
CHANGED
|
@@ -9,13 +9,14 @@ Highly configurable util that generates the diff string representation of the di
|
|
|
9
9
|
```javascript
|
|
10
10
|
import diff from '@sandboxed/diff';
|
|
11
11
|
|
|
12
|
-
const a = { name:
|
|
13
|
-
const b = { name:
|
|
12
|
+
const a = { name: 'Alice', age: 25 };
|
|
13
|
+
const b = { name: 'Alice', age: 26, city: 'New York' };
|
|
14
14
|
|
|
15
15
|
console.log(diff(a, b).toDiffString());
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
**Output**:
|
|
19
|
+
|
|
19
20
|
```
|
|
20
21
|
{
|
|
21
22
|
"name": "Alice",
|
|
@@ -27,14 +28,13 @@ console.log(diff(a, b).toDiffString());
|
|
|
27
28
|
|
|
28
29
|
#### Config options
|
|
29
30
|
|
|
30
|
-
|
|
|
31
|
-
|
|
32
|
-
| withColors | `
|
|
31
|
+
| config | default | Description |
|
|
32
|
+
| ---------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
+
| withColors | `false` | Formats the string using AnsiColors. |
|
|
33
34
|
| colors | `object` | Hashmap for coloring each line based on type: `[ChangeType]: (string) => string`. Should be compatible with `chalk`. |
|
|
34
|
-
| symbols | `object` | Hashmap for prefixing each line based on type: `[ChangeType]: string`.
|
|
35
|
-
| wrapper | `[]`
|
|
36
|
-
| indentSize | `2`
|
|
37
|
-
|
|
35
|
+
| symbols | `object` | Hashmap for prefixing each line based on type: `[ChangeType]: string`. |
|
|
36
|
+
| wrapper | `[]` | Array with `string` entries. Wraps the result between the first two strings. |
|
|
37
|
+
| indentSize | `2` | Whitespace after the `config.symbols`. Indentation is done using `space`. |
|
|
38
38
|
|
|
39
39
|
### Equality detection
|
|
40
40
|
|
|
@@ -45,8 +45,8 @@ Determines whether the inputs are structurally equal based on the diff result. I
|
|
|
45
45
|
```javascript
|
|
46
46
|
import diff from '@sandboxed/diff';
|
|
47
47
|
|
|
48
|
-
const a = { name:
|
|
49
|
-
const b = { name:
|
|
48
|
+
const a = { name: 'Alice', age: 25 };
|
|
49
|
+
const b = { name: 'Alice', age: 26, city: 'New York' };
|
|
50
50
|
|
|
51
51
|
console.log(diff(a, b).equal); // Output: false
|
|
52
52
|
|
|
@@ -68,9 +68,7 @@ import diff, { ChangeType } from '@sandboxed/diff';
|
|
|
68
68
|
const a = { name: 'Alice', foo: new Set([1, 2, 'test']) };
|
|
69
69
|
const b = { name: 'Alice', bar: new Set(['test', 2, 1]) };
|
|
70
70
|
|
|
71
|
-
console.log(
|
|
72
|
-
diff(a, b, { exclude: [ChangeType.ADD, ChangeType.REMOVE] }).equal
|
|
73
|
-
); // Output: true
|
|
71
|
+
console.log(diff(a, b, { exclude: [ChangeType.ADD, ChangeType.REMOVE] }).equal); // Output: true
|
|
74
72
|
```
|
|
75
73
|
|
|
76
74
|
Given that the diff result will not detect the changes in **`foo`**(`ChangeType.REMOVE`) or **`bar`** (`ChangeType.ADD`), the diff result will contain only `ChangeType.NOOP`, causing `.equal` to be `true`.
|
package/lib/index.cjs
CHANGED
|
@@ -110,21 +110,37 @@ function shouldRedactValue(key, config) {
|
|
|
110
110
|
const rawKey = getRawValue(key);
|
|
111
111
|
return config.redactKeys?.includes?.(rawKey);
|
|
112
112
|
}
|
|
113
|
-
function createReplacer(config) {
|
|
113
|
+
function createReplacer(config, obj) {
|
|
114
114
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
115
115
|
return function replacer(k, v) {
|
|
116
|
+
if (shouldRedactValue(k, config)) return REDACTED;
|
|
117
|
+
if (k !== "" && v === obj) return "[Circular]";
|
|
116
118
|
if (v && typeof v === "object") {
|
|
117
119
|
if (seen.has(v)) return "[Circular]";
|
|
118
120
|
seen.add(v);
|
|
119
121
|
}
|
|
120
122
|
if (v instanceof Set) {
|
|
121
|
-
|
|
123
|
+
const stringified = JSON.stringify([...v.values()], replacer);
|
|
124
|
+
seen.delete(v);
|
|
125
|
+
return `Set ${stringified}`;
|
|
122
126
|
}
|
|
123
127
|
if (v instanceof Map) {
|
|
124
128
|
const entries = [...v.entries()];
|
|
125
|
-
const stringified = entries.map(
|
|
126
|
-
(
|
|
127
|
-
|
|
129
|
+
const stringified = entries.map(([key, value]) => {
|
|
130
|
+
if (seen.has(key)) {
|
|
131
|
+
return `"[Circular]": ${JSON.stringify(value, replacer)}`;
|
|
132
|
+
}
|
|
133
|
+
if (!isPrimitive(key)) {
|
|
134
|
+
seen.add(key);
|
|
135
|
+
}
|
|
136
|
+
const serializedValue = shouldRedactValue(key, config) ? REDACTED : JSON.stringify(value, replacer);
|
|
137
|
+
const serialized = `${JSON.stringify(key, replacer)}: ${serializedValue}`;
|
|
138
|
+
if (!isPrimitive) {
|
|
139
|
+
seen.delete(key);
|
|
140
|
+
}
|
|
141
|
+
return serialized;
|
|
142
|
+
}).join(", ");
|
|
143
|
+
seen.delete(v);
|
|
128
144
|
return `Map (${entries.length}) { ${stringified} }`;
|
|
129
145
|
}
|
|
130
146
|
if (v instanceof Function) {
|
|
@@ -136,11 +152,12 @@ function createReplacer(config) {
|
|
|
136
152
|
if (typeof v === "bigint") {
|
|
137
153
|
return `BigInt(${v.toString()})`;
|
|
138
154
|
}
|
|
139
|
-
|
|
155
|
+
seen.delete(v);
|
|
156
|
+
return v;
|
|
140
157
|
};
|
|
141
158
|
}
|
|
142
159
|
function stringify(obj, config) {
|
|
143
|
-
return JSON.stringify(obj, createReplacer(config));
|
|
160
|
+
return JSON.stringify(obj, createReplacer(config, obj));
|
|
144
161
|
}
|
|
145
162
|
function getObjectChangeResult(lhs, rhs, depth, key, parsedKey, config, path) {
|
|
146
163
|
const isLhsMap = lhs instanceof Map;
|
|
@@ -160,13 +177,13 @@ function getObjectChangeResult(lhs, rhs, depth, key, parsedKey, config, path) {
|
|
|
160
177
|
const redactValue = shouldRedactValue(key, config);
|
|
161
178
|
const rawValueInLhs = getRawValue(valueInLhs);
|
|
162
179
|
const rawValueInRhs = getRawValue(valueInRhs);
|
|
163
|
-
const formattedValueInLhs =
|
|
180
|
+
const formattedValueInLhs = stringify(
|
|
164
181
|
redactValue ? REDACTED : rawValueInLhs,
|
|
165
|
-
|
|
182
|
+
config
|
|
166
183
|
);
|
|
167
|
-
const formattedValueInRhs =
|
|
184
|
+
const formattedValueInRhs = stringify(
|
|
168
185
|
redactValue ? REDACTED : rawValueInRhs,
|
|
169
|
-
|
|
186
|
+
config
|
|
170
187
|
);
|
|
171
188
|
let type = "noop" /* NOOP */;
|
|
172
189
|
let formattedValue = formattedValueInRhs;
|
|
@@ -182,17 +199,18 @@ function getObjectChangeResult(lhs, rhs, depth, key, parsedKey, config, path) {
|
|
|
182
199
|
}
|
|
183
200
|
const result = [];
|
|
184
201
|
if (includeDiffType(type, config)) {
|
|
202
|
+
const stringifiedParsedKey = stringify(parsedKey, config);
|
|
185
203
|
if (type === "update" /* UPDATE */ && !config.showUpdatedOnly) {
|
|
186
204
|
result.push({
|
|
187
205
|
type: "remove" /* REMOVE */,
|
|
188
|
-
str: `${
|
|
206
|
+
str: `${stringifiedParsedKey}: ${formattedValueInLhs},`,
|
|
189
207
|
depth,
|
|
190
208
|
path: [...path, lastPathValue("remove" /* REMOVE */, valueInLhs)]
|
|
191
209
|
});
|
|
192
210
|
}
|
|
193
211
|
result.push({
|
|
194
212
|
type,
|
|
195
|
-
str: `${
|
|
213
|
+
str: `${stringifiedParsedKey}: ${formattedValue},`,
|
|
196
214
|
depth,
|
|
197
215
|
path: [...path, lastPathValue(type, pathValue)]
|
|
198
216
|
});
|
|
@@ -294,6 +312,8 @@ function diffObjects({
|
|
|
294
312
|
)
|
|
295
313
|
);
|
|
296
314
|
}
|
|
315
|
+
seen.delete(lhs);
|
|
316
|
+
seen.delete(rhs);
|
|
297
317
|
return buildResult(
|
|
298
318
|
rhs,
|
|
299
319
|
result,
|
|
@@ -360,12 +380,14 @@ function diffSets({
|
|
|
360
380
|
if (includeDiffType(type, config)) {
|
|
361
381
|
result.push({
|
|
362
382
|
type,
|
|
363
|
-
str: `${
|
|
383
|
+
str: `${stringify(value, config)},`,
|
|
364
384
|
depth,
|
|
365
385
|
path: [...updatedPath, lastPathValue(type, value)]
|
|
366
386
|
});
|
|
367
387
|
}
|
|
368
388
|
}
|
|
389
|
+
seen.delete(lhs);
|
|
390
|
+
seen.delete(rhs);
|
|
369
391
|
return buildResult(
|
|
370
392
|
rhs,
|
|
371
393
|
result,
|
|
@@ -427,6 +449,8 @@ function diffMaps({
|
|
|
427
449
|
...getObjectChangeResult(lhs, rhs, depth, key, key, config, updatedPath)
|
|
428
450
|
);
|
|
429
451
|
}
|
|
452
|
+
seen.delete(lhs);
|
|
453
|
+
seen.delete(rhs);
|
|
430
454
|
return buildResult(
|
|
431
455
|
rhs,
|
|
432
456
|
result,
|
|
@@ -526,8 +550,8 @@ function recursiveDiff({
|
|
|
526
550
|
return [];
|
|
527
551
|
}
|
|
528
552
|
const parentDepth = depth - 1;
|
|
529
|
-
const lhsValue =
|
|
530
|
-
const rhsValue =
|
|
553
|
+
const lhsValue = stringify(lhs, config);
|
|
554
|
+
const rhsValue = stringify(rhs, config);
|
|
531
555
|
const result = [];
|
|
532
556
|
if (includeDiffType("update" /* UPDATE */, config)) {
|
|
533
557
|
if (!config.showUpdatedOnly) {
|
|
@@ -574,7 +598,7 @@ var ansiColors = {
|
|
|
574
598
|
};
|
|
575
599
|
function toDiffString(diff2, config) {
|
|
576
600
|
const defaultConfig = {
|
|
577
|
-
withColors:
|
|
601
|
+
withColors: false,
|
|
578
602
|
colors: ansiColors,
|
|
579
603
|
wrapper: [],
|
|
580
604
|
indentSize: 2,
|
|
@@ -598,6 +622,12 @@ function toDiffString(diff2, config) {
|
|
|
598
622
|
}
|
|
599
623
|
};
|
|
600
624
|
const diffString = diff2.map(({ type, str, depth }, index) => {
|
|
625
|
+
if (!Object.hasOwn(mergedConfig.symbols, type) || isNullOrUndefined(mergedConfig.symbols[type])) {
|
|
626
|
+
throw new Error(`<${type}> symbol missing in config`);
|
|
627
|
+
}
|
|
628
|
+
if (!Object.hasOwn(mergedConfig.colors, type) || isNullOrUndefined(mergedConfig.colors[type])) {
|
|
629
|
+
throw new Error(`<${type}> color function missing in config`);
|
|
630
|
+
}
|
|
601
631
|
let symbolString = mergedConfig.symbols[type];
|
|
602
632
|
if (index > 0 && index < diff2.length - 1 && !symbolString.length) {
|
|
603
633
|
symbolString = ` ${mergedConfig.symbols[type]}`;
|
package/lib/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/constants.ts","../src/utils/fns.ts","../src/diff/shared.ts","../src/diff/diffObjects.ts","../src/diff/diffSets.ts","../src/diff/diffMaps.ts","../src/diff/diffConstructors.ts","../src/diff/index.ts","../src/utils/toDiffString.ts"],"sourcesContent":["import recursiveDiff from './diff';\nimport type { DiffConfig, DiffStringConfig, Diff } from './types';\nimport {\n ChangeType,\n DefaultPathHints,\n MAX_DEPTH,\n MAX_KEYS,\n MAX_TIMEOUT_MS,\n} from './utils/constants';\nimport toDiffString from './utils/toDiffString';\n\n/**\n * Returns the deep difference between two objects. The return object contains the stringified difference for easy rendering.\n * @param {any} lhs - Lef-hand side object. Can be either Object, Array, Set or Map.\n * @param {any} rhs - Right-hand side object.\n * @param {DiffConfig} [config] - Configuration to be used\n * @param {DiffConfig['exclude']} [config.exclude=[]] - Type differences to be ignored.\n * @param {DiffConfig['include']} [config.include=['add', 'remove', 'update', 'noop']] - Type differences to be logged.\n * @param {DiffConfig['strict']} [config.strict=true] - Indicates whether to enforce type check.\n * @param {DiffConfig['showUpdatedOnly']} [config.showUpdatedOnly=false] - Indicates whether a `remove` operation should be included for every `update`\n * @param {DiffConfig['pathHints']} [config.pathHints={ map: '__MAP__', set: '__SET__' }] - Strings to use as hints for Sets and Maps in the path array\n * @param {DiffConfig['maxDepth']} [config.maxDepth=50] - Max recursive depth that can be traversed before throwing\n * @param {DiffConfig['maxKeys']} [config.maxKeys=1000] - Max keys that can be processed at a time. Throws when LHS + RHS keys > maxKeys\n * @param {DiffConfig['timeout']} [config.timeout=1000] - Throws when the diffing timeout is met\n * @param {DiffConfig['redactKeys']} [config.redactKeys=[]] - Replaces the values of these keys with *****\n */\nfunction diff(lhs: any, rhs: any, config: DiffConfig): Diff {\n const defaultConfig: DiffConfig = {\n include: [\n ChangeType.ADD,\n ChangeType.REMOVE,\n ChangeType.UPDATE,\n ChangeType.NOOP,\n ],\n exclude: [],\n strict: true,\n showUpdatedOnly: false,\n pathHints: {\n map: DefaultPathHints.map,\n set: DefaultPathHints.set,\n },\n maxDepth: MAX_DEPTH,\n maxKeys: MAX_KEYS,\n timeout: MAX_TIMEOUT_MS,\n redactKeys: [\n 'password',\n 'secret',\n 'token',\n 'Symbol(password)',\n 'Symbol(secret)',\n 'Symbol(token)',\n ],\n };\n\n const mergedConfig: DiffConfig = {\n ...defaultConfig,\n ...config,\n };\n\n if (!mergedConfig.maxDepth) mergedConfig.maxDepth = MAX_DEPTH;\n if (!mergedConfig.maxKeys) mergedConfig.maxKeys = MAX_KEYS;\n if (!mergedConfig.timeout) mergedConfig.timeout = MAX_TIMEOUT_MS;\n\n mergedConfig.include = Array.isArray(mergedConfig.include)\n ? mergedConfig.include\n : [mergedConfig.include];\n\n mergedConfig.exclude = Array.isArray(mergedConfig.exclude)\n ? mergedConfig.exclude\n : [mergedConfig.exclude];\n\n const diffResult = recursiveDiff({\n lhs,\n rhs,\n config: mergedConfig,\n depth: 1,\n parent: null,\n seen: new WeakMap(),\n initialChangeType: ChangeType.NOOP,\n path: [],\n startedAt: Date.now(),\n });\n\n // All the changes are \"noop\", or empty array\n const areEqual = diffResult.every(\n (result) => result.type === ChangeType.NOOP\n );\n\n Object.defineProperty(diffResult, 'toDiffString', {\n value: (diffStringConfig: DiffStringConfig) =>\n toDiffString(diffResult, diffStringConfig),\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(diffResult, 'equal', {\n value: areEqual,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n return diffResult as Diff;\n}\n\nexport { ChangeType };\n\nexport default diff;\n","export const Iterables = new Set([Object, Array, Set, Map]);\n\nexport enum ChangeType {\n ADD = 'add',\n UPDATE = 'update',\n REMOVE = 'remove',\n NOOP = 'noop',\n}\n\nexport const DefaultPathHints = {\n map: '__MAP__',\n set: '__SET__',\n};\n\nexport const MAX_DEPTH = 50;\n\nexport const MAX_KEYS = 1000;\n\nexport const ITERATION_TIMEOUT_CHECK = 1000;\n\nexport const MAX_TIMEOUT_MS = 1000;\n\nexport const REDACTED = '*****';\n","import { Iterables } from './constants';\n\nexport function isPrimitive(value: any) {\n return value !== Object(value);\n}\n\nexport function getRawValue(value: any) {\n // If value is primitive (except symbol), then perform validations in its pure form\n if (isPrimitive(value) && typeof value !== 'symbol') return value;\n\n // Serializes the value to perform validations\n return value.toString();\n}\n\nexport function isNullOrUndefined(value: any) {\n return value === null || value === undefined;\n}\nexport function isCustomClassInstance(object: any) {\n if (\n isNullOrUndefined(object) ||\n typeof object !== 'object' ||\n !object.constructor\n ) {\n return false;\n }\n\n return !object.constructor?.toString?.().includes('[native code]');\n}\n\nexport function emptyShellClone(object: any) {\n // Clone the instance shell\n if (isCustomClassInstance(object)) {\n return Object.create(Object.getPrototypeOf(object));\n }\n\n // Objects created with Object.create(null) don't have constructor\n if (isObject(object)) {\n return Object.create(null);\n }\n\n // Creates an empty instance from the native constructor\n return new object.constructor();\n}\n\nexport function getWrapper(obj: any) {\n let wrapper = ['{', '}'];\n\n if (Array.isArray(obj)) {\n wrapper = ['[', ']'];\n } else if (isCustomClassInstance(obj)) {\n wrapper = [`${obj.constructor.name} {`, '}'];\n } else if (obj instanceof Map) {\n wrapper = [`Map (${obj.size}) {`, '}'];\n } else if (obj instanceof Set) {\n wrapper = ['Set [', ']'];\n }\n\n return wrapper;\n}\n\n/**\n * Returns the ref type of the value\n * @param value - The value\n * @returns string\n */\nexport function getRef(value: any) {\n return `ref<${value?.constructor?.name || typeof value}>`;\n}\n\nexport function isObject(obj: any) {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n (Object.getPrototypeOf(obj) === Object.prototype ||\n Object.getPrototypeOf(obj) === null)\n );\n}\n\nexport function areObjects(a: any, b: any) {\n return isObject(a) && isObject(b);\n}\n\nexport function getEnumerableKeys(obj: any) {\n return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];\n}\n\nexport function isIterable(obj: any) {\n return (\n Iterables.has(obj?.constructor) ||\n isObject(obj) ||\n isCustomClassInstance(obj)\n );\n}\n","import type { DiffConfig, DiffResult, PathHints } from '../types';\nimport { ChangeType, REDACTED } from '../utils/constants';\nimport { getRawValue, getWrapper } from '../utils/fns';\n\nexport function lastPathValue(changeType: ChangeType, value: any) {\n return { deleted: changeType === ChangeType.REMOVE, value };\n}\n\nexport function includeDiffType(type: ChangeType, config: DiffConfig) {\n return config.include?.includes?.(type) && !config.exclude?.includes?.(type);\n}\n\nexport function shouldRedactValue(key: any, config: DiffConfig) {\n const rawKey = getRawValue(key);\n\n return config.redactKeys?.includes?.(rawKey);\n}\n\nexport function createReplacer(config: DiffConfig) {\n const seen = new WeakSet();\n\n return function replacer(k: any, v: any) {\n if (v && typeof v === 'object') {\n if (seen.has(v)) return '[Circular]';\n\n seen.add(v);\n }\n\n if (v instanceof Set) {\n return `Set ${JSON.stringify([...v.values()], replacer)}`;\n }\n\n if (v instanceof Map) {\n const entries = [...v.entries()];\n const stringified = entries\n .map(\n ([key, value]) =>\n `${JSON.stringify(key, replacer)}: ${JSON.stringify(shouldRedactValue(key, config) ? REDACTED : value, replacer)}`\n )\n .join(', ');\n\n return `Map (${entries.length}) { ${stringified} }`;\n }\n\n if (v instanceof Function) {\n return `Function ${v.name || '(anonymous)'}`;\n }\n\n if (typeof v === 'symbol') {\n return v.toString();\n }\n\n if (typeof v === 'bigint') {\n return `BigInt(${v.toString()})`;\n }\n\n return shouldRedactValue(k, config) ? REDACTED : v;\n };\n}\n\nexport function stringify(obj: any, config: DiffConfig) {\n return JSON.stringify(obj, createReplacer(config));\n}\n\nexport function getObjectChangeResult(\n lhs: any,\n rhs: any,\n depth: number,\n key: any,\n parsedKey: any,\n config: DiffConfig,\n path: Array<any>\n) {\n const isLhsMap = lhs instanceof Map;\n const isRhsMap = rhs instanceof Map;\n\n let valueInLhs = lhs?.[key];\n let valueInRhs = rhs?.[key];\n let keyInLhs = Object.hasOwn(lhs, key);\n let keyInRhs = Object.hasOwn(rhs, key);\n\n if (isLhsMap) {\n valueInLhs = lhs.get(key);\n keyInLhs = lhs.has(key);\n }\n\n if (isRhsMap) {\n valueInRhs = rhs.get(key);\n keyInRhs = rhs.has(key);\n }\n\n const redactValue = shouldRedactValue(key, config);\n const rawValueInLhs = getRawValue(valueInLhs);\n const rawValueInRhs = getRawValue(valueInRhs);\n const formattedValueInLhs = JSON.stringify(\n redactValue ? REDACTED : rawValueInLhs,\n createReplacer(config)\n );\n const formattedValueInRhs = JSON.stringify(\n redactValue ? REDACTED : rawValueInRhs,\n createReplacer(config)\n );\n\n let type = ChangeType.NOOP;\n let formattedValue = formattedValueInRhs; // Select the most recent change\n let pathValue = valueInRhs;\n\n if (!keyInLhs && keyInRhs) {\n // added in rhs\n type = ChangeType.ADD;\n } else if (keyInLhs && !keyInRhs) {\n // removed in rhs\n type = ChangeType.REMOVE;\n formattedValue = formattedValueInLhs;\n pathValue = valueInLhs;\n } else if (\n config.strict\n ? rawValueInLhs !== rawValueInRhs\n : rawValueInLhs != rawValueInRhs\n ) {\n // different in rhs\n type = ChangeType.UPDATE;\n }\n\n const result: DiffResult[] = [];\n\n // If the type of change should be included in the results\n if (includeDiffType(type, config)) {\n if (type === ChangeType.UPDATE && !config.showUpdatedOnly) {\n result.push({\n type: ChangeType.REMOVE,\n str: `${JSON.stringify(parsedKey, createReplacer(config))}: ${formattedValueInLhs},`,\n depth,\n path: [...path, lastPathValue(ChangeType.REMOVE, valueInLhs)],\n });\n }\n\n result.push({\n type,\n str: `${JSON.stringify(parsedKey, createReplacer(config))}: ${formattedValue},`,\n depth,\n path: [...path, lastPathValue(type, pathValue)],\n });\n }\n\n return result;\n}\n\nexport function getPathHint(config: DiffConfig, type: keyof PathHints) {\n if (typeof config.pathHints === 'object') {\n const hint = config.pathHints[type];\n\n if (typeof hint === 'string') return hint;\n }\n\n // no hint for this type\n return null;\n}\n\nexport function buildResult(\n rhs: any,\n result: DiffResult[],\n depth: number,\n initialChangeType: ChangeType,\n parent: any,\n path: any[],\n config: DiffConfig\n) {\n if (!includeDiffType(initialChangeType, config)) return result;\n\n const parentDepth = depth - 1;\n const [open, close] = getWrapper(rhs);\n\n return [\n {\n type: initialChangeType,\n str: parentDepth > 0 ? `${stringify(parent, config)}: ${open}` : open,\n depth: parentDepth,\n path,\n },\n ...result,\n {\n type: initialChangeType,\n str: parentDepth > 0 ? `${close},` : close,\n depth: parentDepth,\n path,\n },\n ];\n}\n\n// Prevents bloating the memory for large objects\nexport function timeoutSecurityCheck(startedAt: number, config: DiffConfig) {\n if (Date.now() - startedAt > config.timeout) {\n throw new Error('Diff took too much time! Aborting.');\n }\n}\n\nexport function maxKeysSecurityCheck(size: number, config: DiffConfig) {\n if (size > config.maxKeys) {\n throw new Error('Object is too big to continue! Aborting.');\n }\n}\n","import { type DiffResult, DiffObjectArgs } from '../types';\nimport { ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { getEnumerableKeys, isIterable } from '../utils/fns';\nimport {\n buildResult,\n getObjectChangeResult,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffObjects({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffObjectArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n const lhsKeys = getEnumerableKeys(lhs);\n maxKeysSecurityCheck(lhsKeys.length, config);\n\n const rhsKeys = getEnumerableKeys(rhs);\n maxKeysSecurityCheck(rhsKeys.length, config);\n\n const keys = new Set<string | number | symbol>([...lhsKeys, ...rhsKeys]);\n\n let i = 0;\n for (const key of keys) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const lhsValue = Array.isArray(lhs) ? lhs[key as number] : lhs?.[key];\n const rhsValue = Array.isArray(rhs) ? rhs[key as number] : rhs?.[key];\n const numericKey = typeof key !== 'symbol' ? Number(key) : NaN;\n const parsedKey = isNaN(numericKey) ? key : numericKey;\n const updatedPath = [...path, parsedKey];\n\n if (isIterable(lhsValue) || isIterable(rhsValue)) {\n result.push(\n ...recursiveDiff({\n lhs: lhsValue,\n rhs: rhsValue,\n config,\n depth: depth + 1,\n parent: parsedKey,\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n result.push(\n ...getObjectChangeResult(\n lhs,\n rhs,\n depth,\n key,\n parsedKey,\n config,\n updatedPath\n )\n );\n }\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffObjects;\n","import { DiffResult, DiffSetArgs } from '../types';\nimport { ChangeType, ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { getRef, isIterable } from '../utils/fns';\nimport {\n buildResult,\n getPathHint,\n includeDiffType,\n lastPathValue,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffSets({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffSetArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n maxKeysSecurityCheck(lhs.size, config);\n maxKeysSecurityCheck(rhs.size, config);\n\n const mergedSet = new Set([...lhs, ...rhs]);\n\n let i = 0;\n for (const value of mergedSet) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const existsInLhs = lhs.has(value);\n const existsInRhs = rhs.has(value);\n const hint = getPathHint(config, 'set');\n const updatedPath = [...path];\n\n if (hint) {\n updatedPath.push(hint);\n }\n\n if (isIterable(value)) {\n result.push(\n ...recursiveDiff({\n lhs: existsInLhs ? value : undefined,\n rhs: existsInRhs ? value : undefined,\n config,\n depth: depth + 1,\n parent: getRef(value),\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n let type = ChangeType.NOOP;\n\n if (existsInLhs && !existsInRhs) {\n type = ChangeType.REMOVE;\n } else if (!existsInLhs && existsInRhs) {\n type = ChangeType.ADD;\n }\n\n if (includeDiffType(type, config)) {\n result.push({\n type,\n str: `${JSON.stringify(value)},`,\n depth,\n path: [...updatedPath, lastPathValue(type, value)],\n });\n }\n }\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffSets;\n","import { DiffResult, DiffMapArgs } from '../types';\nimport { ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { isIterable } from '../utils/fns';\nimport {\n buildResult,\n getObjectChangeResult,\n getPathHint,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffMaps({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffMapArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n maxKeysSecurityCheck(lhs.size, config);\n maxKeysSecurityCheck(rhs.size, config);\n\n const mergedMapKeys = new Set([...lhs.keys(), ...rhs.keys()]);\n\n let i = 0;\n for (const key of mergedMapKeys) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const keyInLhs = lhs.has(key);\n const keyInRhs = rhs.has(key);\n const lhsValue = keyInLhs ? lhs.get(key) : null;\n const rhsValue = keyInRhs ? rhs.get(key) : null;\n const hint = getPathHint(config, 'map');\n const pathUpdate = hint ? [hint, key] : [key];\n const updatedPath = [...path, ...pathUpdate];\n\n if (isIterable(lhsValue) || isIterable(rhsValue)) {\n result.push(\n ...recursiveDiff({\n lhs: lhsValue,\n rhs: rhsValue,\n config,\n depth: depth + 1,\n parent: key,\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n result.push(\n ...getObjectChangeResult(lhs, rhs, depth, key, key, config, updatedPath)\n );\n }\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffMaps;\n","import { type DiffResult, DiffConstructorArgs } from '../types';\nimport { ChangeType } from '../utils/constants';\nimport { emptyShellClone, isObject } from '../utils/fns';\n\nfunction diffConstructors({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffConstructorArgs): DiffResult[] {\n // Different Constructors\n let modLhs = lhs;\n let modRhs = rhs;\n let defaultChangeType = initialChangeType;\n\n if (isObject(rhs) || rhs?.constructor) {\n // Added in rhs. Use rhs prototype to traverse the added properties\n modLhs = emptyShellClone(rhs);\n\n defaultChangeType = ChangeType.ADD;\n } else if (isObject(lhs) || lhs?.constructor) {\n // Removed in rhs. Use lhs prototype to traverse the removed properties\n modRhs = emptyShellClone(lhs);\n\n defaultChangeType = ChangeType.REMOVE;\n } else {\n // Fail for unknown edge cases\n throw new Error(\"Edge case raised, I don't know how to handle this input\");\n }\n\n return recursiveDiff({\n lhs: modLhs,\n rhs: modRhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType: defaultChangeType,\n path,\n startedAt,\n });\n}\n\nexport default diffConstructors;\n","import { type DiffResult, RecursiveDiffArgs } from '../types';\nimport diffObjects from './diffObjects';\nimport diffSets from './diffSets';\nimport diffMaps from './diffMaps';\nimport diffConstructors from './diffConstructors';\nimport { ChangeType } from '../utils/constants';\nimport { areObjects, isNullOrUndefined, isPrimitive } from '../utils/fns';\nimport {\n createReplacer,\n includeDiffType,\n lastPathValue,\n timeoutSecurityCheck,\n stringify,\n} from './shared';\n\nfunction recursiveDiff({\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: RecursiveDiffArgs): DiffResult[] {\n // Prevents stack overflow\n if (depth > config.maxDepth) {\n throw new Error('Max depth exceeded!');\n }\n\n // Checks for timeout before proceeding\n timeoutSecurityCheck(startedAt, config);\n\n // Allows printing the first level of circular references\n const lhsSeen = seen.get(lhs) ?? 0;\n const rhsSeen = seen.get(rhs) ?? 0;\n\n if (lhsSeen > 1 || rhsSeen > 1) {\n if (!includeDiffType(initialChangeType, config)) return [];\n\n return [\n {\n type: initialChangeType,\n str: `${stringify(parent, config)}: [Circular],`,\n depth: depth - 1,\n path,\n },\n ];\n }\n\n // Prevents circular references except for primitives\n if (typeof lhs === 'object' && lhs !== null) seen.set(lhs, lhsSeen + 1);\n if (typeof rhs === 'object' && rhs !== null) seen.set(rhs, rhsSeen + 1);\n\n const args = {\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n };\n\n // Handles comparing primitives\n if (isPrimitive(lhs) && isPrimitive(rhs)) {\n // Return early if it's the same primitive\n if (config.strict ? lhs === rhs : lhs == rhs) {\n return [];\n }\n\n const parentDepth = depth - 1;\n const lhsValue = JSON.stringify(lhs, createReplacer(config));\n const rhsValue = JSON.stringify(rhs, createReplacer(config));\n\n const result = [];\n\n if (includeDiffType(ChangeType.UPDATE, config)) {\n if (!config.showUpdatedOnly) {\n result.push({\n type: ChangeType.REMOVE,\n str: `${lhsValue}`,\n depth: parentDepth,\n path: [...path, lastPathValue(ChangeType.REMOVE, lhs)],\n });\n }\n\n result.push({\n type: ChangeType.UPDATE,\n str: `${rhsValue}`,\n depth: parentDepth,\n path: [...path, lastPathValue(ChangeType.UPDATE, rhs)],\n });\n }\n\n return result;\n }\n\n // Different constructor handler\n if (\n !areObjects(lhs, rhs) && // Skips for Object.create(null) vs {}\n (lhs?.constructor !== rhs?.constructor ||\n (isNullOrUndefined(lhs) && rhs) ||\n (lhs && isNullOrUndefined(rhs)))\n ) {\n return diffConstructors(args);\n }\n\n // SETS\n if (lhs instanceof Set && rhs instanceof Set) {\n return diffSets(args);\n }\n\n // MAPS\n if (lhs instanceof Map && rhs instanceof Map) {\n return diffMaps(args);\n }\n\n // Arrays and Objects\n return diffObjects(args);\n}\n\nexport default recursiveDiff;\n","import type { DiffResult, DiffStringConfig } from '../types';\nimport { ChangeType } from './constants';\n\nconst ANSI_RESET = '\\x1b[0m';\n\nfunction colorWrapper(color: string) {\n return (str: string) => `${color}${str}${ANSI_RESET}`;\n}\n\nconst ansiColors = {\n [ChangeType.REMOVE]: colorWrapper('\\x1b[31m'),\n [ChangeType.ADD]: colorWrapper('\\x1b[32m'),\n [ChangeType.UPDATE]: colorWrapper('\\x1b[33m'),\n [ChangeType.NOOP]: colorWrapper(''),\n};\n\n/**\n * Takes the diff result and returns a diff string in md. + Added, - Removed, ! Updated\n * @param {DiffResult[]} diff - The result from the diff\n * @param {DiffStringConfig} [config]\n * @param {DiffStringConfig['withColors']} [config.withColors=true] - If true, outputs the string formatted with AnsiColors\n * @param {DiffStringConfig['colors']} [config.colors] - Each function takes a string and returns it formatted with ansi colors. Maps to each ChangeType.\n * @param {DiffStringConfig['symbols']} [config.symbols] - String map for each ChangeType\n * @param {DiffStringConfig['wrapper']} [config.wrapper=['```diff', '```']] - Strings that wrap the diff string output\n * @param {DiffStringConfig['indentSize']} [config.indentSize=2]\n */\nexport default function toDiffString(\n diff: DiffResult[],\n config?: DiffStringConfig\n) {\n const defaultConfig: DiffStringConfig = {\n withColors: true,\n colors: ansiColors,\n wrapper: [],\n indentSize: 2,\n symbols: {\n [ChangeType.ADD]: '+',\n [ChangeType.REMOVE]: '-',\n [ChangeType.UPDATE]: '!',\n [ChangeType.NOOP]: '',\n },\n };\n\n const mergedConfig = {\n ...defaultConfig,\n ...config,\n colors: {\n ...defaultConfig.colors,\n ...config?.colors,\n },\n symbols: {\n ...defaultConfig.symbols,\n ...config?.symbols,\n },\n };\n\n const diffString = diff\n .map(({ type, str, depth }, index) => {\n let symbolString = mergedConfig.symbols[type];\n\n if (index > 0 && index < diff.length - 1 && !symbolString.length) {\n symbolString = ` ${mergedConfig.symbols[type]}`;\n }\n\n let buildStr = `${symbolString}${' '.repeat(depth * mergedConfig.indentSize)}${str}`;\n\n if (mergedConfig.withColors) {\n buildStr = mergedConfig.colors[type](buildStr);\n }\n\n return buildStr;\n })\n .join('\\n');\n\n const [open = '', close = ''] = mergedConfig.wrapper || [];\n\n return `${open ? `${open}\\n` : ''}${diffString}${close ? `\\n${close}` : ''}`;\n}\n"],"mappings":"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","names":["ChangeType","recursiveDiff","recursiveDiff","recursiveDiff","recursiveDiff","diff"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/constants.ts","../src/utils/fns.ts","../src/diff/shared.ts","../src/diff/diffObjects.ts","../src/diff/diffSets.ts","../src/diff/diffMaps.ts","../src/diff/diffConstructors.ts","../src/diff/index.ts","../src/utils/toDiffString.ts"],"sourcesContent":["import recursiveDiff from './diff';\nimport type { DiffConfig, DiffStringConfig, Diff } from './types';\nimport {\n ChangeType,\n DefaultPathHints,\n MAX_DEPTH,\n MAX_KEYS,\n MAX_TIMEOUT_MS,\n} from './utils/constants';\nimport toDiffString from './utils/toDiffString';\n\n/**\n * Returns the deep difference between two objects. The return object contains the stringified difference for easy rendering.\n * @param {any} lhs - Lef-hand side object. Can be either Object, Array, Set or Map.\n * @param {any} rhs - Right-hand side object.\n * @param {DiffConfig} [config] - Configuration to be used\n * @param {DiffConfig['exclude']} [config.exclude=[]] - Type differences to be ignored.\n * @param {DiffConfig['include']} [config.include=['add', 'remove', 'update', 'noop']] - Type differences to be logged.\n * @param {DiffConfig['strict']} [config.strict=true] - Indicates whether to enforce type check.\n * @param {DiffConfig['showUpdatedOnly']} [config.showUpdatedOnly=false] - Indicates whether a `remove` operation should be included for every `update`\n * @param {DiffConfig['pathHints']} [config.pathHints={ map: '__MAP__', set: '__SET__' }] - Strings to use as hints for Sets and Maps in the path array\n * @param {DiffConfig['maxDepth']} [config.maxDepth=50] - Max recursive depth that can be traversed before throwing\n * @param {DiffConfig['maxKeys']} [config.maxKeys=1000] - Max keys that can be processed at a time. Throws when LHS + RHS keys > maxKeys\n * @param {DiffConfig['timeout']} [config.timeout=1000] - Throws when the diffing timeout is met\n * @param {DiffConfig['redactKeys']} [config.redactKeys=[]] - Replaces the values of these keys with *****\n */\nfunction diff(lhs: any, rhs: any, config?: Partial<DiffConfig>): Diff {\n const defaultConfig: DiffConfig = {\n include: [\n ChangeType.ADD,\n ChangeType.REMOVE,\n ChangeType.UPDATE,\n ChangeType.NOOP,\n ],\n exclude: [],\n strict: true,\n showUpdatedOnly: false,\n pathHints: {\n map: DefaultPathHints.map,\n set: DefaultPathHints.set,\n },\n maxDepth: MAX_DEPTH,\n maxKeys: MAX_KEYS,\n timeout: MAX_TIMEOUT_MS,\n redactKeys: [\n 'password',\n 'secret',\n 'token',\n 'Symbol(password)',\n 'Symbol(secret)',\n 'Symbol(token)',\n ],\n };\n\n const mergedConfig: DiffConfig = {\n ...defaultConfig,\n ...config,\n };\n\n if (!mergedConfig.maxDepth) mergedConfig.maxDepth = MAX_DEPTH;\n if (!mergedConfig.maxKeys) mergedConfig.maxKeys = MAX_KEYS;\n if (!mergedConfig.timeout) mergedConfig.timeout = MAX_TIMEOUT_MS;\n\n mergedConfig.include = Array.isArray(mergedConfig.include)\n ? mergedConfig.include\n : [mergedConfig.include];\n\n mergedConfig.exclude = Array.isArray(mergedConfig.exclude)\n ? mergedConfig.exclude\n : [mergedConfig.exclude];\n\n const diffResult = recursiveDiff({\n lhs,\n rhs,\n config: mergedConfig,\n depth: 1,\n parent: null,\n seen: new WeakMap(),\n initialChangeType: ChangeType.NOOP,\n path: [],\n startedAt: Date.now(),\n });\n\n // All the changes are \"noop\", or empty array\n const areEqual = diffResult.every(\n (result) => result.type === ChangeType.NOOP\n );\n\n Object.defineProperty(diffResult, 'toDiffString', {\n value: (diffStringConfig: DiffStringConfig) =>\n toDiffString(diffResult, diffStringConfig),\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(diffResult, 'equal', {\n value: areEqual,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n return diffResult as Diff;\n}\n\nexport { ChangeType };\n\nexport default diff;\n","export const Iterables = new Set([Object, Array, Set, Map]);\n\nexport enum ChangeType {\n ADD = 'add',\n UPDATE = 'update',\n REMOVE = 'remove',\n NOOP = 'noop',\n}\n\nexport const DefaultPathHints = {\n map: '__MAP__',\n set: '__SET__',\n};\n\nexport const MAX_DEPTH = 50;\n\nexport const MAX_KEYS = 1000;\n\nexport const ITERATION_TIMEOUT_CHECK = 1000;\n\nexport const MAX_TIMEOUT_MS = 1000;\n\nexport const REDACTED = '*****';\n","import { Iterables } from './constants';\n\nexport function isPrimitive(value: any) {\n return value !== Object(value);\n}\n\nexport function getRawValue(value: any) {\n // If value is primitive (except symbol), then perform validations in its pure form\n if (isPrimitive(value) && typeof value !== 'symbol') return value;\n\n // Serializes the value to perform validations\n return value.toString();\n}\n\nexport function isNullOrUndefined(value: any) {\n return value === null || value === undefined;\n}\nexport function isCustomClassInstance(object: any) {\n if (\n isNullOrUndefined(object) ||\n typeof object !== 'object' ||\n !object.constructor\n ) {\n return false;\n }\n\n return !object.constructor?.toString?.().includes('[native code]');\n}\n\nexport function emptyShellClone(object: any) {\n // Clone the instance shell\n if (isCustomClassInstance(object)) {\n return Object.create(Object.getPrototypeOf(object));\n }\n\n // Objects created with Object.create(null) don't have constructor\n if (isObject(object)) {\n return Object.create(null);\n }\n\n // Creates an empty instance from the native constructor\n return new object.constructor();\n}\n\nexport function getWrapper(obj: any) {\n let wrapper = ['{', '}'];\n\n if (Array.isArray(obj)) {\n wrapper = ['[', ']'];\n } else if (isCustomClassInstance(obj)) {\n wrapper = [`${obj.constructor.name} {`, '}'];\n } else if (obj instanceof Map) {\n wrapper = [`Map (${obj.size}) {`, '}'];\n } else if (obj instanceof Set) {\n wrapper = ['Set [', ']'];\n }\n\n return wrapper;\n}\n\n/**\n * Returns the ref type of the value\n * @param value - The value\n * @returns string\n */\nexport function getRef(value: any) {\n return `ref<${value?.constructor?.name || typeof value}>`;\n}\n\nexport function isObject(obj: any) {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n (Object.getPrototypeOf(obj) === Object.prototype ||\n Object.getPrototypeOf(obj) === null)\n );\n}\n\nexport function areObjects(a: any, b: any) {\n return isObject(a) && isObject(b);\n}\n\nexport function getEnumerableKeys(obj: any) {\n return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];\n}\n\nexport function isIterable(obj: any) {\n return (\n Iterables.has(obj?.constructor) ||\n isObject(obj) ||\n isCustomClassInstance(obj)\n );\n}\n","import type { DiffConfig, DiffResult, PathHints } from '../types';\nimport { ChangeType, REDACTED } from '../utils/constants';\nimport { getRawValue, getWrapper, isPrimitive } from '../utils/fns';\n\nexport function lastPathValue(changeType: ChangeType, value: any) {\n return { deleted: changeType === ChangeType.REMOVE, value };\n}\n\nexport function includeDiffType(type: ChangeType, config: DiffConfig) {\n return config.include?.includes?.(type) && !config.exclude?.includes?.(type);\n}\n\nexport function shouldRedactValue(key: any, config: DiffConfig) {\n const rawKey = getRawValue(key);\n\n return config.redactKeys?.includes?.(rawKey);\n}\n\nexport function createReplacer(config: DiffConfig, obj: any) {\n const seen = new WeakSet();\n\n return function replacer(k: any, v: any) {\n // Redact the entire value if the key matches\n if (shouldRedactValue(k, config)) return REDACTED;\n\n // Returns circular if iterating over the same object from the replacer\n if (k !== '' && v === obj) return '[Circular]';\n\n if (v && typeof v === 'object') {\n if (seen.has(v)) return '[Circular]';\n\n seen.add(v);\n }\n\n if (v instanceof Set) {\n const stringified = JSON.stringify([...v.values()], replacer);\n\n seen.delete(v);\n return `Set ${stringified}`;\n }\n\n if (v instanceof Map) {\n const entries = [...v.entries()];\n const stringified = entries\n .map(([key, value]) => {\n if (seen.has(key)) {\n return `\"[Circular]\": ${JSON.stringify(value, replacer)}`;\n }\n\n if (!isPrimitive(key)) {\n seen.add(key);\n }\n\n const serializedValue = shouldRedactValue(key, config)\n ? REDACTED\n : JSON.stringify(value, replacer);\n const serialized = `${JSON.stringify(key, replacer)}: ${serializedValue}`;\n\n if (!isPrimitive) {\n seen.delete(key);\n }\n\n return serialized;\n })\n .join(', ');\n\n seen.delete(v);\n return `Map (${entries.length}) { ${stringified} }`;\n }\n\n if (v instanceof Function) {\n return `Function ${v.name || '(anonymous)'}`;\n }\n\n if (typeof v === 'symbol') {\n return v.toString();\n }\n\n if (typeof v === 'bigint') {\n return `BigInt(${v.toString()})`;\n }\n\n seen.delete(v);\n return v;\n };\n}\n\nexport function stringify(obj: any, config: DiffConfig) {\n return JSON.stringify(obj, createReplacer(config, obj));\n}\n\nexport function getObjectChangeResult(\n lhs: any,\n rhs: any,\n depth: number,\n key: any,\n parsedKey: any,\n config: DiffConfig,\n path: Array<any>\n) {\n const isLhsMap = lhs instanceof Map;\n const isRhsMap = rhs instanceof Map;\n\n let valueInLhs = lhs?.[key];\n let valueInRhs = rhs?.[key];\n let keyInLhs = Object.hasOwn(lhs, key);\n let keyInRhs = Object.hasOwn(rhs, key);\n\n if (isLhsMap) {\n valueInLhs = lhs.get(key);\n keyInLhs = lhs.has(key);\n }\n\n if (isRhsMap) {\n valueInRhs = rhs.get(key);\n keyInRhs = rhs.has(key);\n }\n\n const redactValue = shouldRedactValue(key, config);\n const rawValueInLhs = getRawValue(valueInLhs);\n const rawValueInRhs = getRawValue(valueInRhs);\n const formattedValueInLhs = stringify(\n redactValue ? REDACTED : rawValueInLhs,\n config\n );\n const formattedValueInRhs = stringify(\n redactValue ? REDACTED : rawValueInRhs,\n config\n );\n\n let type = ChangeType.NOOP;\n let formattedValue = formattedValueInRhs; // Select the most recent change\n let pathValue = valueInRhs;\n\n if (!keyInLhs && keyInRhs) {\n // added in rhs\n type = ChangeType.ADD;\n } else if (keyInLhs && !keyInRhs) {\n // removed in rhs\n type = ChangeType.REMOVE;\n formattedValue = formattedValueInLhs;\n pathValue = valueInLhs;\n } else if (\n config.strict\n ? rawValueInLhs !== rawValueInRhs\n : rawValueInLhs != rawValueInRhs\n ) {\n // different in rhs\n type = ChangeType.UPDATE;\n }\n\n const result: DiffResult[] = [];\n\n // If the type of change should be included in the results\n if (includeDiffType(type, config)) {\n const stringifiedParsedKey = stringify(parsedKey, config);\n\n if (type === ChangeType.UPDATE && !config.showUpdatedOnly) {\n result.push({\n type: ChangeType.REMOVE,\n str: `${stringifiedParsedKey}: ${formattedValueInLhs},`,\n depth,\n path: [...path, lastPathValue(ChangeType.REMOVE, valueInLhs)],\n });\n }\n\n result.push({\n type,\n str: `${stringifiedParsedKey}: ${formattedValue},`,\n depth,\n path: [...path, lastPathValue(type, pathValue)],\n });\n }\n\n return result;\n}\n\nexport function getPathHint(config: DiffConfig, type: keyof PathHints) {\n if (typeof config.pathHints === 'object') {\n const hint = config.pathHints[type];\n\n if (typeof hint === 'string') return hint;\n }\n\n // no hint for this type\n return null;\n}\n\nexport function buildResult(\n rhs: any,\n result: DiffResult[],\n depth: number,\n initialChangeType: ChangeType,\n parent: any,\n path: any[],\n config: DiffConfig\n) {\n if (!includeDiffType(initialChangeType, config)) return result;\n\n const parentDepth = depth - 1;\n const [open, close] = getWrapper(rhs);\n\n return [\n {\n type: initialChangeType,\n str: parentDepth > 0 ? `${stringify(parent, config)}: ${open}` : open,\n depth: parentDepth,\n path,\n },\n ...result,\n {\n type: initialChangeType,\n str: parentDepth > 0 ? `${close},` : close,\n depth: parentDepth,\n path,\n },\n ];\n}\n\n// Prevents bloating the memory for large objects\nexport function timeoutSecurityCheck(startedAt: number, config: DiffConfig) {\n if (Date.now() - startedAt > config.timeout) {\n throw new Error('Diff took too much time! Aborting.');\n }\n}\n\nexport function maxKeysSecurityCheck(size: number, config: DiffConfig) {\n if (size > config.maxKeys) {\n throw new Error('Object is too big to continue! Aborting.');\n }\n}\n","import { type DiffResult, DiffObjectArgs } from '../types';\nimport { ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { getEnumerableKeys, isIterable } from '../utils/fns';\nimport {\n buildResult,\n getObjectChangeResult,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffObjects({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffObjectArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n const lhsKeys = getEnumerableKeys(lhs);\n maxKeysSecurityCheck(lhsKeys.length, config);\n\n const rhsKeys = getEnumerableKeys(rhs);\n maxKeysSecurityCheck(rhsKeys.length, config);\n\n const keys = new Set<string | number | symbol>([...lhsKeys, ...rhsKeys]);\n\n let i = 0;\n for (const key of keys) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const lhsValue = Array.isArray(lhs) ? lhs[key as number] : lhs?.[key];\n const rhsValue = Array.isArray(rhs) ? rhs[key as number] : rhs?.[key];\n const numericKey = typeof key !== 'symbol' ? Number(key) : NaN;\n const parsedKey = isNaN(numericKey) ? key : numericKey;\n const updatedPath = [...path, parsedKey];\n\n if (isIterable(lhsValue) || isIterable(rhsValue)) {\n result.push(\n ...recursiveDiff({\n lhs: lhsValue,\n rhs: rhsValue,\n config,\n depth: depth + 1,\n parent: parsedKey,\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n result.push(\n ...getObjectChangeResult(\n lhs,\n rhs,\n depth,\n key,\n parsedKey,\n config,\n updatedPath\n )\n );\n }\n\n seen.delete(lhs);\n seen.delete(rhs);\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffObjects;\n","import { DiffResult, DiffSetArgs } from '../types';\nimport { ChangeType, ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { getRef, isIterable } from '../utils/fns';\nimport {\n buildResult,\n getPathHint,\n includeDiffType,\n lastPathValue,\n maxKeysSecurityCheck,\n stringify,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffSets({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffSetArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n maxKeysSecurityCheck(lhs.size, config);\n maxKeysSecurityCheck(rhs.size, config);\n\n const mergedSet = new Set([...lhs, ...rhs]);\n\n let i = 0;\n for (const value of mergedSet) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const existsInLhs = lhs.has(value);\n const existsInRhs = rhs.has(value);\n const hint = getPathHint(config, 'set');\n const updatedPath = [...path];\n\n if (hint) {\n updatedPath.push(hint);\n }\n\n if (isIterable(value)) {\n result.push(\n ...recursiveDiff({\n lhs: existsInLhs ? value : undefined,\n rhs: existsInRhs ? value : undefined,\n config,\n depth: depth + 1,\n parent: getRef(value),\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n let type = ChangeType.NOOP;\n\n if (existsInLhs && !existsInRhs) {\n type = ChangeType.REMOVE;\n } else if (!existsInLhs && existsInRhs) {\n type = ChangeType.ADD;\n }\n\n if (includeDiffType(type, config)) {\n result.push({\n type,\n str: `${stringify(value, config)},`,\n depth,\n path: [...updatedPath, lastPathValue(type, value)],\n });\n }\n }\n\n seen.delete(lhs);\n seen.delete(rhs);\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffSets;\n","import { DiffResult, DiffMapArgs } from '../types';\nimport { ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { isIterable } from '../utils/fns';\nimport {\n buildResult,\n getObjectChangeResult,\n getPathHint,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffMaps({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffMapArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n maxKeysSecurityCheck(lhs.size, config);\n maxKeysSecurityCheck(rhs.size, config);\n\n const mergedMapKeys = new Set([...lhs.keys(), ...rhs.keys()]);\n\n let i = 0;\n for (const key of mergedMapKeys) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const keyInLhs = lhs.has(key);\n const keyInRhs = rhs.has(key);\n const lhsValue = keyInLhs ? lhs.get(key) : null;\n const rhsValue = keyInRhs ? rhs.get(key) : null;\n const hint = getPathHint(config, 'map');\n const pathUpdate = hint ? [hint, key] : [key];\n const updatedPath = [...path, ...pathUpdate];\n\n if (isIterable(lhsValue) || isIterable(rhsValue)) {\n result.push(\n ...recursiveDiff({\n lhs: lhsValue,\n rhs: rhsValue,\n config,\n depth: depth + 1,\n parent: key,\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n result.push(\n ...getObjectChangeResult(lhs, rhs, depth, key, key, config, updatedPath)\n );\n }\n\n seen.delete(lhs);\n seen.delete(rhs);\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffMaps;\n","import { type DiffResult, DiffConstructorArgs } from '../types';\nimport { ChangeType } from '../utils/constants';\nimport { emptyShellClone, isObject } from '../utils/fns';\n\nfunction diffConstructors({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffConstructorArgs): DiffResult[] {\n // Different Constructors\n let modLhs = lhs;\n let modRhs = rhs;\n let defaultChangeType = initialChangeType;\n\n if (isObject(rhs) || rhs?.constructor) {\n // Added in rhs. Use rhs prototype to traverse the added properties\n modLhs = emptyShellClone(rhs);\n\n defaultChangeType = ChangeType.ADD;\n } else if (isObject(lhs) || lhs?.constructor) {\n // Removed in rhs. Use lhs prototype to traverse the removed properties\n modRhs = emptyShellClone(lhs);\n\n defaultChangeType = ChangeType.REMOVE;\n } else {\n // Fail for unknown edge cases\n throw new Error(\"Edge case raised, I don't know how to handle this input\");\n }\n\n return recursiveDiff({\n lhs: modLhs,\n rhs: modRhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType: defaultChangeType,\n path,\n startedAt,\n });\n}\n\nexport default diffConstructors;\n","import { type DiffResult, RecursiveDiffArgs } from '../types';\nimport diffObjects from './diffObjects';\nimport diffSets from './diffSets';\nimport diffMaps from './diffMaps';\nimport diffConstructors from './diffConstructors';\nimport { ChangeType } from '../utils/constants';\nimport { areObjects, isNullOrUndefined, isPrimitive } from '../utils/fns';\nimport {\n includeDiffType,\n lastPathValue,\n timeoutSecurityCheck,\n stringify,\n} from './shared';\n\nfunction recursiveDiff({\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: RecursiveDiffArgs): DiffResult[] {\n // Prevents stack overflow\n if (depth > config.maxDepth) {\n throw new Error('Max depth exceeded!');\n }\n\n // Checks for timeout before proceeding\n timeoutSecurityCheck(startedAt, config);\n\n // Allows printing the first level of circular references\n const lhsSeen = seen.get(lhs) ?? 0;\n const rhsSeen = seen.get(rhs) ?? 0;\n\n if (lhsSeen > 1 || rhsSeen > 1) {\n if (!includeDiffType(initialChangeType, config)) return [];\n\n return [\n {\n type: initialChangeType,\n str: `${stringify(parent, config)}: [Circular],`,\n depth: depth - 1,\n path,\n },\n ];\n }\n\n // Prevents circular references except for primitives\n if (typeof lhs === 'object' && lhs !== null) seen.set(lhs, lhsSeen + 1);\n if (typeof rhs === 'object' && rhs !== null) seen.set(rhs, rhsSeen + 1);\n\n const args = {\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n };\n\n // Handles comparing primitives\n if (isPrimitive(lhs) && isPrimitive(rhs)) {\n // Return early if it's the same primitive\n if (config.strict ? lhs === rhs : lhs == rhs) {\n return [];\n }\n\n const parentDepth = depth - 1;\n const lhsValue = stringify(lhs, config);\n const rhsValue = stringify(rhs, config);\n\n const result = [];\n\n if (includeDiffType(ChangeType.UPDATE, config)) {\n if (!config.showUpdatedOnly) {\n result.push({\n type: ChangeType.REMOVE,\n str: `${lhsValue}`,\n depth: parentDepth,\n path: [...path, lastPathValue(ChangeType.REMOVE, lhs)],\n });\n }\n\n result.push({\n type: ChangeType.UPDATE,\n str: `${rhsValue}`,\n depth: parentDepth,\n path: [...path, lastPathValue(ChangeType.UPDATE, rhs)],\n });\n }\n\n return result;\n }\n\n // Different constructor handler\n if (\n !areObjects(lhs, rhs) && // Skips for Object.create(null) vs {}\n (lhs?.constructor !== rhs?.constructor ||\n (isNullOrUndefined(lhs) && rhs) ||\n (lhs && isNullOrUndefined(rhs)))\n ) {\n return diffConstructors(args);\n }\n\n // SETS\n if (lhs instanceof Set && rhs instanceof Set) {\n return diffSets(args);\n }\n\n // MAPS\n if (lhs instanceof Map && rhs instanceof Map) {\n return diffMaps(args);\n }\n\n // Arrays and Objects\n return diffObjects(args);\n}\n\nexport default recursiveDiff;\n","import type { DiffResult, DiffStringConfig } from '../types';\nimport { ChangeType } from './constants';\nimport { isNullOrUndefined } from './fns';\n\nconst ANSI_RESET = '\\x1b[0m';\n\nfunction colorWrapper(color: string) {\n return (str: string) => `${color}${str}${ANSI_RESET}`;\n}\n\nconst ansiColors = {\n [ChangeType.REMOVE]: colorWrapper('\\x1b[31m'),\n [ChangeType.ADD]: colorWrapper('\\x1b[32m'),\n [ChangeType.UPDATE]: colorWrapper('\\x1b[33m'),\n [ChangeType.NOOP]: colorWrapper(''),\n};\n\n/**\n * Takes the diff result and returns a diff string in md. + Added, - Removed, ! Updated\n * @param {DiffResult[]} diff - The result from the diff\n * @param {DiffStringConfig} [config]\n * @param {DiffStringConfig['withColors']} [config.withColors=false] - If true, outputs the string formatted with AnsiColors\n * @param {DiffStringConfig['colors']} [config.colors] - Each function takes a string and returns it formatted with ansi colors. Maps to each ChangeType.\n * @param {DiffStringConfig['symbols']} [config.symbols] - String map for each ChangeType\n * @param {DiffStringConfig['wrapper']} [config.wrapper=['```diff', '```']] - Strings that wrap the diff string output\n * @param {DiffStringConfig['indentSize']} [config.indentSize=2]\n */\nexport default function toDiffString(\n diff: DiffResult[],\n config?: DiffStringConfig\n) {\n const defaultConfig: DiffStringConfig = {\n withColors: false,\n colors: ansiColors,\n wrapper: [],\n indentSize: 2,\n symbols: {\n [ChangeType.ADD]: '+',\n [ChangeType.REMOVE]: '-',\n [ChangeType.UPDATE]: '!',\n [ChangeType.NOOP]: '',\n },\n };\n\n const mergedConfig = {\n ...defaultConfig,\n ...config,\n colors: {\n ...defaultConfig.colors,\n ...config?.colors,\n },\n symbols: {\n ...defaultConfig.symbols,\n ...config?.symbols,\n },\n };\n\n const diffString = diff\n .map(({ type, str, depth }, index) => {\n if (\n !Object.hasOwn(mergedConfig.symbols, type) ||\n isNullOrUndefined(mergedConfig.symbols[type])\n ) {\n throw new Error(`<${type}> symbol missing in config`);\n }\n\n if (\n !Object.hasOwn(mergedConfig.colors, type) ||\n isNullOrUndefined(mergedConfig.colors[type])\n ) {\n throw new Error(`<${type}> color function missing in config`);\n }\n\n let symbolString = mergedConfig.symbols[type];\n\n if (index > 0 && index < diff.length - 1 && !symbolString.length) {\n symbolString = ` ${mergedConfig.symbols[type]}`;\n }\n\n let buildStr = `${symbolString}${' '.repeat(depth * mergedConfig.indentSize)}${str}`;\n\n if (mergedConfig.withColors) {\n buildStr = mergedConfig.colors[type](buildStr);\n }\n\n return buildStr;\n })\n .join('\\n');\n\n const [open = '', close = ''] = mergedConfig.wrapper || [];\n\n return `${open ? `${open}\\n` : ''}${diffString}${close ? `\\n${close}` : ''}`;\n}\n"],"mappings":"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","names":["ChangeType","recursiveDiff","recursiveDiff","recursiveDiff","recursiveDiff","diff"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -20,8 +20,8 @@ type DiffSymbols = Record<ChangeType, string>;
|
|
|
20
20
|
type DiffColors = Record<ChangeType, (str: string) => string>;
|
|
21
21
|
|
|
22
22
|
type PathHints = {
|
|
23
|
-
map
|
|
24
|
-
set
|
|
23
|
+
map?: string | boolean;
|
|
24
|
+
set?: string | boolean;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
type DiffConfig = {
|
|
@@ -66,22 +66,25 @@ type DiffConfig = {
|
|
|
66
66
|
redactKeys: Array<string>;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
type
|
|
69
|
+
type BaseDiffStringConfig = {
|
|
70
70
|
withColors: boolean;
|
|
71
71
|
indentSize: number;
|
|
72
72
|
wrapper: Array<string>;
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
type PartialDiffStringConfig = BaseDiffStringConfig & {
|
|
76
|
+
colors: Partial<DiffColors>;
|
|
77
|
+
symbols: Partial<DiffSymbols>;
|
|
75
78
|
};
|
|
76
79
|
|
|
77
80
|
interface Diff extends Array<DiffResult> {
|
|
78
81
|
/** String formatted with the Github's `diff` md format */
|
|
79
|
-
toDiffString: (config?:
|
|
82
|
+
toDiffString: (config?: Partial<PartialDiffStringConfig>) => string;
|
|
80
83
|
|
|
81
84
|
/** lsh and rhs are structurally equal */
|
|
82
85
|
equal: boolean;
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
declare function diff(lhs: any, rhs: any, config
|
|
88
|
+
declare function diff(lhs: any, rhs: any, config?: Partial<DiffConfig>): Diff;
|
|
86
89
|
|
|
87
90
|
export { ChangeType, diff as default };
|
package/lib/index.js
CHANGED
|
@@ -83,21 +83,37 @@ function shouldRedactValue(key, config) {
|
|
|
83
83
|
const rawKey = getRawValue(key);
|
|
84
84
|
return config.redactKeys?.includes?.(rawKey);
|
|
85
85
|
}
|
|
86
|
-
function createReplacer(config) {
|
|
86
|
+
function createReplacer(config, obj) {
|
|
87
87
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
88
88
|
return function replacer(k, v) {
|
|
89
|
+
if (shouldRedactValue(k, config)) return REDACTED;
|
|
90
|
+
if (k !== "" && v === obj) return "[Circular]";
|
|
89
91
|
if (v && typeof v === "object") {
|
|
90
92
|
if (seen.has(v)) return "[Circular]";
|
|
91
93
|
seen.add(v);
|
|
92
94
|
}
|
|
93
95
|
if (v instanceof Set) {
|
|
94
|
-
|
|
96
|
+
const stringified = JSON.stringify([...v.values()], replacer);
|
|
97
|
+
seen.delete(v);
|
|
98
|
+
return `Set ${stringified}`;
|
|
95
99
|
}
|
|
96
100
|
if (v instanceof Map) {
|
|
97
101
|
const entries = [...v.entries()];
|
|
98
|
-
const stringified = entries.map(
|
|
99
|
-
(
|
|
100
|
-
|
|
102
|
+
const stringified = entries.map(([key, value]) => {
|
|
103
|
+
if (seen.has(key)) {
|
|
104
|
+
return `"[Circular]": ${JSON.stringify(value, replacer)}`;
|
|
105
|
+
}
|
|
106
|
+
if (!isPrimitive(key)) {
|
|
107
|
+
seen.add(key);
|
|
108
|
+
}
|
|
109
|
+
const serializedValue = shouldRedactValue(key, config) ? REDACTED : JSON.stringify(value, replacer);
|
|
110
|
+
const serialized = `${JSON.stringify(key, replacer)}: ${serializedValue}`;
|
|
111
|
+
if (!isPrimitive) {
|
|
112
|
+
seen.delete(key);
|
|
113
|
+
}
|
|
114
|
+
return serialized;
|
|
115
|
+
}).join(", ");
|
|
116
|
+
seen.delete(v);
|
|
101
117
|
return `Map (${entries.length}) { ${stringified} }`;
|
|
102
118
|
}
|
|
103
119
|
if (v instanceof Function) {
|
|
@@ -109,11 +125,12 @@ function createReplacer(config) {
|
|
|
109
125
|
if (typeof v === "bigint") {
|
|
110
126
|
return `BigInt(${v.toString()})`;
|
|
111
127
|
}
|
|
112
|
-
|
|
128
|
+
seen.delete(v);
|
|
129
|
+
return v;
|
|
113
130
|
};
|
|
114
131
|
}
|
|
115
132
|
function stringify(obj, config) {
|
|
116
|
-
return JSON.stringify(obj, createReplacer(config));
|
|
133
|
+
return JSON.stringify(obj, createReplacer(config, obj));
|
|
117
134
|
}
|
|
118
135
|
function getObjectChangeResult(lhs, rhs, depth, key, parsedKey, config, path) {
|
|
119
136
|
const isLhsMap = lhs instanceof Map;
|
|
@@ -133,13 +150,13 @@ function getObjectChangeResult(lhs, rhs, depth, key, parsedKey, config, path) {
|
|
|
133
150
|
const redactValue = shouldRedactValue(key, config);
|
|
134
151
|
const rawValueInLhs = getRawValue(valueInLhs);
|
|
135
152
|
const rawValueInRhs = getRawValue(valueInRhs);
|
|
136
|
-
const formattedValueInLhs =
|
|
153
|
+
const formattedValueInLhs = stringify(
|
|
137
154
|
redactValue ? REDACTED : rawValueInLhs,
|
|
138
|
-
|
|
155
|
+
config
|
|
139
156
|
);
|
|
140
|
-
const formattedValueInRhs =
|
|
157
|
+
const formattedValueInRhs = stringify(
|
|
141
158
|
redactValue ? REDACTED : rawValueInRhs,
|
|
142
|
-
|
|
159
|
+
config
|
|
143
160
|
);
|
|
144
161
|
let type = "noop" /* NOOP */;
|
|
145
162
|
let formattedValue = formattedValueInRhs;
|
|
@@ -155,17 +172,18 @@ function getObjectChangeResult(lhs, rhs, depth, key, parsedKey, config, path) {
|
|
|
155
172
|
}
|
|
156
173
|
const result = [];
|
|
157
174
|
if (includeDiffType(type, config)) {
|
|
175
|
+
const stringifiedParsedKey = stringify(parsedKey, config);
|
|
158
176
|
if (type === "update" /* UPDATE */ && !config.showUpdatedOnly) {
|
|
159
177
|
result.push({
|
|
160
178
|
type: "remove" /* REMOVE */,
|
|
161
|
-
str: `${
|
|
179
|
+
str: `${stringifiedParsedKey}: ${formattedValueInLhs},`,
|
|
162
180
|
depth,
|
|
163
181
|
path: [...path, lastPathValue("remove" /* REMOVE */, valueInLhs)]
|
|
164
182
|
});
|
|
165
183
|
}
|
|
166
184
|
result.push({
|
|
167
185
|
type,
|
|
168
|
-
str: `${
|
|
186
|
+
str: `${stringifiedParsedKey}: ${formattedValue},`,
|
|
169
187
|
depth,
|
|
170
188
|
path: [...path, lastPathValue(type, pathValue)]
|
|
171
189
|
});
|
|
@@ -267,6 +285,8 @@ function diffObjects({
|
|
|
267
285
|
)
|
|
268
286
|
);
|
|
269
287
|
}
|
|
288
|
+
seen.delete(lhs);
|
|
289
|
+
seen.delete(rhs);
|
|
270
290
|
return buildResult(
|
|
271
291
|
rhs,
|
|
272
292
|
result,
|
|
@@ -333,12 +353,14 @@ function diffSets({
|
|
|
333
353
|
if (includeDiffType(type, config)) {
|
|
334
354
|
result.push({
|
|
335
355
|
type,
|
|
336
|
-
str: `${
|
|
356
|
+
str: `${stringify(value, config)},`,
|
|
337
357
|
depth,
|
|
338
358
|
path: [...updatedPath, lastPathValue(type, value)]
|
|
339
359
|
});
|
|
340
360
|
}
|
|
341
361
|
}
|
|
362
|
+
seen.delete(lhs);
|
|
363
|
+
seen.delete(rhs);
|
|
342
364
|
return buildResult(
|
|
343
365
|
rhs,
|
|
344
366
|
result,
|
|
@@ -400,6 +422,8 @@ function diffMaps({
|
|
|
400
422
|
...getObjectChangeResult(lhs, rhs, depth, key, key, config, updatedPath)
|
|
401
423
|
);
|
|
402
424
|
}
|
|
425
|
+
seen.delete(lhs);
|
|
426
|
+
seen.delete(rhs);
|
|
403
427
|
return buildResult(
|
|
404
428
|
rhs,
|
|
405
429
|
result,
|
|
@@ -499,8 +523,8 @@ function recursiveDiff({
|
|
|
499
523
|
return [];
|
|
500
524
|
}
|
|
501
525
|
const parentDepth = depth - 1;
|
|
502
|
-
const lhsValue =
|
|
503
|
-
const rhsValue =
|
|
526
|
+
const lhsValue = stringify(lhs, config);
|
|
527
|
+
const rhsValue = stringify(rhs, config);
|
|
504
528
|
const result = [];
|
|
505
529
|
if (includeDiffType("update" /* UPDATE */, config)) {
|
|
506
530
|
if (!config.showUpdatedOnly) {
|
|
@@ -547,7 +571,7 @@ var ansiColors = {
|
|
|
547
571
|
};
|
|
548
572
|
function toDiffString(diff2, config) {
|
|
549
573
|
const defaultConfig = {
|
|
550
|
-
withColors:
|
|
574
|
+
withColors: false,
|
|
551
575
|
colors: ansiColors,
|
|
552
576
|
wrapper: [],
|
|
553
577
|
indentSize: 2,
|
|
@@ -571,6 +595,12 @@ function toDiffString(diff2, config) {
|
|
|
571
595
|
}
|
|
572
596
|
};
|
|
573
597
|
const diffString = diff2.map(({ type, str, depth }, index) => {
|
|
598
|
+
if (!Object.hasOwn(mergedConfig.symbols, type) || isNullOrUndefined(mergedConfig.symbols[type])) {
|
|
599
|
+
throw new Error(`<${type}> symbol missing in config`);
|
|
600
|
+
}
|
|
601
|
+
if (!Object.hasOwn(mergedConfig.colors, type) || isNullOrUndefined(mergedConfig.colors[type])) {
|
|
602
|
+
throw new Error(`<${type}> color function missing in config`);
|
|
603
|
+
}
|
|
574
604
|
let symbolString = mergedConfig.symbols[type];
|
|
575
605
|
if (index > 0 && index < diff2.length - 1 && !symbolString.length) {
|
|
576
606
|
symbolString = ` ${mergedConfig.symbols[type]}`;
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/constants.ts","../src/utils/fns.ts","../src/diff/shared.ts","../src/diff/diffObjects.ts","../src/diff/diffSets.ts","../src/diff/diffMaps.ts","../src/diff/diffConstructors.ts","../src/diff/index.ts","../src/utils/toDiffString.ts","../src/index.ts"],"sourcesContent":["export const Iterables = new Set([Object, Array, Set, Map]);\n\nexport enum ChangeType {\n ADD = 'add',\n UPDATE = 'update',\n REMOVE = 'remove',\n NOOP = 'noop',\n}\n\nexport const DefaultPathHints = {\n map: '__MAP__',\n set: '__SET__',\n};\n\nexport const MAX_DEPTH = 50;\n\nexport const MAX_KEYS = 1000;\n\nexport const ITERATION_TIMEOUT_CHECK = 1000;\n\nexport const MAX_TIMEOUT_MS = 1000;\n\nexport const REDACTED = '*****';\n","import { Iterables } from './constants';\n\nexport function isPrimitive(value: any) {\n return value !== Object(value);\n}\n\nexport function getRawValue(value: any) {\n // If value is primitive (except symbol), then perform validations in its pure form\n if (isPrimitive(value) && typeof value !== 'symbol') return value;\n\n // Serializes the value to perform validations\n return value.toString();\n}\n\nexport function isNullOrUndefined(value: any) {\n return value === null || value === undefined;\n}\nexport function isCustomClassInstance(object: any) {\n if (\n isNullOrUndefined(object) ||\n typeof object !== 'object' ||\n !object.constructor\n ) {\n return false;\n }\n\n return !object.constructor?.toString?.().includes('[native code]');\n}\n\nexport function emptyShellClone(object: any) {\n // Clone the instance shell\n if (isCustomClassInstance(object)) {\n return Object.create(Object.getPrototypeOf(object));\n }\n\n // Objects created with Object.create(null) don't have constructor\n if (isObject(object)) {\n return Object.create(null);\n }\n\n // Creates an empty instance from the native constructor\n return new object.constructor();\n}\n\nexport function getWrapper(obj: any) {\n let wrapper = ['{', '}'];\n\n if (Array.isArray(obj)) {\n wrapper = ['[', ']'];\n } else if (isCustomClassInstance(obj)) {\n wrapper = [`${obj.constructor.name} {`, '}'];\n } else if (obj instanceof Map) {\n wrapper = [`Map (${obj.size}) {`, '}'];\n } else if (obj instanceof Set) {\n wrapper = ['Set [', ']'];\n }\n\n return wrapper;\n}\n\n/**\n * Returns the ref type of the value\n * @param value - The value\n * @returns string\n */\nexport function getRef(value: any) {\n return `ref<${value?.constructor?.name || typeof value}>`;\n}\n\nexport function isObject(obj: any) {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n (Object.getPrototypeOf(obj) === Object.prototype ||\n Object.getPrototypeOf(obj) === null)\n );\n}\n\nexport function areObjects(a: any, b: any) {\n return isObject(a) && isObject(b);\n}\n\nexport function getEnumerableKeys(obj: any) {\n return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];\n}\n\nexport function isIterable(obj: any) {\n return (\n Iterables.has(obj?.constructor) ||\n isObject(obj) ||\n isCustomClassInstance(obj)\n );\n}\n","import type { DiffConfig, DiffResult, PathHints } from '../types';\nimport { ChangeType, REDACTED } from '../utils/constants';\nimport { getRawValue, getWrapper } from '../utils/fns';\n\nexport function lastPathValue(changeType: ChangeType, value: any) {\n return { deleted: changeType === ChangeType.REMOVE, value };\n}\n\nexport function includeDiffType(type: ChangeType, config: DiffConfig) {\n return config.include?.includes?.(type) && !config.exclude?.includes?.(type);\n}\n\nexport function shouldRedactValue(key: any, config: DiffConfig) {\n const rawKey = getRawValue(key);\n\n return config.redactKeys?.includes?.(rawKey);\n}\n\nexport function createReplacer(config: DiffConfig) {\n const seen = new WeakSet();\n\n return function replacer(k: any, v: any) {\n if (v && typeof v === 'object') {\n if (seen.has(v)) return '[Circular]';\n\n seen.add(v);\n }\n\n if (v instanceof Set) {\n return `Set ${JSON.stringify([...v.values()], replacer)}`;\n }\n\n if (v instanceof Map) {\n const entries = [...v.entries()];\n const stringified = entries\n .map(\n ([key, value]) =>\n `${JSON.stringify(key, replacer)}: ${JSON.stringify(shouldRedactValue(key, config) ? REDACTED : value, replacer)}`\n )\n .join(', ');\n\n return `Map (${entries.length}) { ${stringified} }`;\n }\n\n if (v instanceof Function) {\n return `Function ${v.name || '(anonymous)'}`;\n }\n\n if (typeof v === 'symbol') {\n return v.toString();\n }\n\n if (typeof v === 'bigint') {\n return `BigInt(${v.toString()})`;\n }\n\n return shouldRedactValue(k, config) ? REDACTED : v;\n };\n}\n\nexport function stringify(obj: any, config: DiffConfig) {\n return JSON.stringify(obj, createReplacer(config));\n}\n\nexport function getObjectChangeResult(\n lhs: any,\n rhs: any,\n depth: number,\n key: any,\n parsedKey: any,\n config: DiffConfig,\n path: Array<any>\n) {\n const isLhsMap = lhs instanceof Map;\n const isRhsMap = rhs instanceof Map;\n\n let valueInLhs = lhs?.[key];\n let valueInRhs = rhs?.[key];\n let keyInLhs = Object.hasOwn(lhs, key);\n let keyInRhs = Object.hasOwn(rhs, key);\n\n if (isLhsMap) {\n valueInLhs = lhs.get(key);\n keyInLhs = lhs.has(key);\n }\n\n if (isRhsMap) {\n valueInRhs = rhs.get(key);\n keyInRhs = rhs.has(key);\n }\n\n const redactValue = shouldRedactValue(key, config);\n const rawValueInLhs = getRawValue(valueInLhs);\n const rawValueInRhs = getRawValue(valueInRhs);\n const formattedValueInLhs = JSON.stringify(\n redactValue ? REDACTED : rawValueInLhs,\n createReplacer(config)\n );\n const formattedValueInRhs = JSON.stringify(\n redactValue ? REDACTED : rawValueInRhs,\n createReplacer(config)\n );\n\n let type = ChangeType.NOOP;\n let formattedValue = formattedValueInRhs; // Select the most recent change\n let pathValue = valueInRhs;\n\n if (!keyInLhs && keyInRhs) {\n // added in rhs\n type = ChangeType.ADD;\n } else if (keyInLhs && !keyInRhs) {\n // removed in rhs\n type = ChangeType.REMOVE;\n formattedValue = formattedValueInLhs;\n pathValue = valueInLhs;\n } else if (\n config.strict\n ? rawValueInLhs !== rawValueInRhs\n : rawValueInLhs != rawValueInRhs\n ) {\n // different in rhs\n type = ChangeType.UPDATE;\n }\n\n const result: DiffResult[] = [];\n\n // If the type of change should be included in the results\n if (includeDiffType(type, config)) {\n if (type === ChangeType.UPDATE && !config.showUpdatedOnly) {\n result.push({\n type: ChangeType.REMOVE,\n str: `${JSON.stringify(parsedKey, createReplacer(config))}: ${formattedValueInLhs},`,\n depth,\n path: [...path, lastPathValue(ChangeType.REMOVE, valueInLhs)],\n });\n }\n\n result.push({\n type,\n str: `${JSON.stringify(parsedKey, createReplacer(config))}: ${formattedValue},`,\n depth,\n path: [...path, lastPathValue(type, pathValue)],\n });\n }\n\n return result;\n}\n\nexport function getPathHint(config: DiffConfig, type: keyof PathHints) {\n if (typeof config.pathHints === 'object') {\n const hint = config.pathHints[type];\n\n if (typeof hint === 'string') return hint;\n }\n\n // no hint for this type\n return null;\n}\n\nexport function buildResult(\n rhs: any,\n result: DiffResult[],\n depth: number,\n initialChangeType: ChangeType,\n parent: any,\n path: any[],\n config: DiffConfig\n) {\n if (!includeDiffType(initialChangeType, config)) return result;\n\n const parentDepth = depth - 1;\n const [open, close] = getWrapper(rhs);\n\n return [\n {\n type: initialChangeType,\n str: parentDepth > 0 ? `${stringify(parent, config)}: ${open}` : open,\n depth: parentDepth,\n path,\n },\n ...result,\n {\n type: initialChangeType,\n str: parentDepth > 0 ? `${close},` : close,\n depth: parentDepth,\n path,\n },\n ];\n}\n\n// Prevents bloating the memory for large objects\nexport function timeoutSecurityCheck(startedAt: number, config: DiffConfig) {\n if (Date.now() - startedAt > config.timeout) {\n throw new Error('Diff took too much time! Aborting.');\n }\n}\n\nexport function maxKeysSecurityCheck(size: number, config: DiffConfig) {\n if (size > config.maxKeys) {\n throw new Error('Object is too big to continue! Aborting.');\n }\n}\n","import { type DiffResult, DiffObjectArgs } from '../types';\nimport { ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { getEnumerableKeys, isIterable } from '../utils/fns';\nimport {\n buildResult,\n getObjectChangeResult,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffObjects({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffObjectArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n const lhsKeys = getEnumerableKeys(lhs);\n maxKeysSecurityCheck(lhsKeys.length, config);\n\n const rhsKeys = getEnumerableKeys(rhs);\n maxKeysSecurityCheck(rhsKeys.length, config);\n\n const keys = new Set<string | number | symbol>([...lhsKeys, ...rhsKeys]);\n\n let i = 0;\n for (const key of keys) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const lhsValue = Array.isArray(lhs) ? lhs[key as number] : lhs?.[key];\n const rhsValue = Array.isArray(rhs) ? rhs[key as number] : rhs?.[key];\n const numericKey = typeof key !== 'symbol' ? Number(key) : NaN;\n const parsedKey = isNaN(numericKey) ? key : numericKey;\n const updatedPath = [...path, parsedKey];\n\n if (isIterable(lhsValue) || isIterable(rhsValue)) {\n result.push(\n ...recursiveDiff({\n lhs: lhsValue,\n rhs: rhsValue,\n config,\n depth: depth + 1,\n parent: parsedKey,\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n result.push(\n ...getObjectChangeResult(\n lhs,\n rhs,\n depth,\n key,\n parsedKey,\n config,\n updatedPath\n )\n );\n }\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffObjects;\n","import { DiffResult, DiffSetArgs } from '../types';\nimport { ChangeType, ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { getRef, isIterable } from '../utils/fns';\nimport {\n buildResult,\n getPathHint,\n includeDiffType,\n lastPathValue,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffSets({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffSetArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n maxKeysSecurityCheck(lhs.size, config);\n maxKeysSecurityCheck(rhs.size, config);\n\n const mergedSet = new Set([...lhs, ...rhs]);\n\n let i = 0;\n for (const value of mergedSet) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const existsInLhs = lhs.has(value);\n const existsInRhs = rhs.has(value);\n const hint = getPathHint(config, 'set');\n const updatedPath = [...path];\n\n if (hint) {\n updatedPath.push(hint);\n }\n\n if (isIterable(value)) {\n result.push(\n ...recursiveDiff({\n lhs: existsInLhs ? value : undefined,\n rhs: existsInRhs ? value : undefined,\n config,\n depth: depth + 1,\n parent: getRef(value),\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n let type = ChangeType.NOOP;\n\n if (existsInLhs && !existsInRhs) {\n type = ChangeType.REMOVE;\n } else if (!existsInLhs && existsInRhs) {\n type = ChangeType.ADD;\n }\n\n if (includeDiffType(type, config)) {\n result.push({\n type,\n str: `${JSON.stringify(value)},`,\n depth,\n path: [...updatedPath, lastPathValue(type, value)],\n });\n }\n }\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffSets;\n","import { DiffResult, DiffMapArgs } from '../types';\nimport { ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { isIterable } from '../utils/fns';\nimport {\n buildResult,\n getObjectChangeResult,\n getPathHint,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffMaps({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffMapArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n maxKeysSecurityCheck(lhs.size, config);\n maxKeysSecurityCheck(rhs.size, config);\n\n const mergedMapKeys = new Set([...lhs.keys(), ...rhs.keys()]);\n\n let i = 0;\n for (const key of mergedMapKeys) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const keyInLhs = lhs.has(key);\n const keyInRhs = rhs.has(key);\n const lhsValue = keyInLhs ? lhs.get(key) : null;\n const rhsValue = keyInRhs ? rhs.get(key) : null;\n const hint = getPathHint(config, 'map');\n const pathUpdate = hint ? [hint, key] : [key];\n const updatedPath = [...path, ...pathUpdate];\n\n if (isIterable(lhsValue) || isIterable(rhsValue)) {\n result.push(\n ...recursiveDiff({\n lhs: lhsValue,\n rhs: rhsValue,\n config,\n depth: depth + 1,\n parent: key,\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n result.push(\n ...getObjectChangeResult(lhs, rhs, depth, key, key, config, updatedPath)\n );\n }\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffMaps;\n","import { type DiffResult, DiffConstructorArgs } from '../types';\nimport { ChangeType } from '../utils/constants';\nimport { emptyShellClone, isObject } from '../utils/fns';\n\nfunction diffConstructors({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffConstructorArgs): DiffResult[] {\n // Different Constructors\n let modLhs = lhs;\n let modRhs = rhs;\n let defaultChangeType = initialChangeType;\n\n if (isObject(rhs) || rhs?.constructor) {\n // Added in rhs. Use rhs prototype to traverse the added properties\n modLhs = emptyShellClone(rhs);\n\n defaultChangeType = ChangeType.ADD;\n } else if (isObject(lhs) || lhs?.constructor) {\n // Removed in rhs. Use lhs prototype to traverse the removed properties\n modRhs = emptyShellClone(lhs);\n\n defaultChangeType = ChangeType.REMOVE;\n } else {\n // Fail for unknown edge cases\n throw new Error(\"Edge case raised, I don't know how to handle this input\");\n }\n\n return recursiveDiff({\n lhs: modLhs,\n rhs: modRhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType: defaultChangeType,\n path,\n startedAt,\n });\n}\n\nexport default diffConstructors;\n","import { type DiffResult, RecursiveDiffArgs } from '../types';\nimport diffObjects from './diffObjects';\nimport diffSets from './diffSets';\nimport diffMaps from './diffMaps';\nimport diffConstructors from './diffConstructors';\nimport { ChangeType } from '../utils/constants';\nimport { areObjects, isNullOrUndefined, isPrimitive } from '../utils/fns';\nimport {\n createReplacer,\n includeDiffType,\n lastPathValue,\n timeoutSecurityCheck,\n stringify,\n} from './shared';\n\nfunction recursiveDiff({\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: RecursiveDiffArgs): DiffResult[] {\n // Prevents stack overflow\n if (depth > config.maxDepth) {\n throw new Error('Max depth exceeded!');\n }\n\n // Checks for timeout before proceeding\n timeoutSecurityCheck(startedAt, config);\n\n // Allows printing the first level of circular references\n const lhsSeen = seen.get(lhs) ?? 0;\n const rhsSeen = seen.get(rhs) ?? 0;\n\n if (lhsSeen > 1 || rhsSeen > 1) {\n if (!includeDiffType(initialChangeType, config)) return [];\n\n return [\n {\n type: initialChangeType,\n str: `${stringify(parent, config)}: [Circular],`,\n depth: depth - 1,\n path,\n },\n ];\n }\n\n // Prevents circular references except for primitives\n if (typeof lhs === 'object' && lhs !== null) seen.set(lhs, lhsSeen + 1);\n if (typeof rhs === 'object' && rhs !== null) seen.set(rhs, rhsSeen + 1);\n\n const args = {\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n };\n\n // Handles comparing primitives\n if (isPrimitive(lhs) && isPrimitive(rhs)) {\n // Return early if it's the same primitive\n if (config.strict ? lhs === rhs : lhs == rhs) {\n return [];\n }\n\n const parentDepth = depth - 1;\n const lhsValue = JSON.stringify(lhs, createReplacer(config));\n const rhsValue = JSON.stringify(rhs, createReplacer(config));\n\n const result = [];\n\n if (includeDiffType(ChangeType.UPDATE, config)) {\n if (!config.showUpdatedOnly) {\n result.push({\n type: ChangeType.REMOVE,\n str: `${lhsValue}`,\n depth: parentDepth,\n path: [...path, lastPathValue(ChangeType.REMOVE, lhs)],\n });\n }\n\n result.push({\n type: ChangeType.UPDATE,\n str: `${rhsValue}`,\n depth: parentDepth,\n path: [...path, lastPathValue(ChangeType.UPDATE, rhs)],\n });\n }\n\n return result;\n }\n\n // Different constructor handler\n if (\n !areObjects(lhs, rhs) && // Skips for Object.create(null) vs {}\n (lhs?.constructor !== rhs?.constructor ||\n (isNullOrUndefined(lhs) && rhs) ||\n (lhs && isNullOrUndefined(rhs)))\n ) {\n return diffConstructors(args);\n }\n\n // SETS\n if (lhs instanceof Set && rhs instanceof Set) {\n return diffSets(args);\n }\n\n // MAPS\n if (lhs instanceof Map && rhs instanceof Map) {\n return diffMaps(args);\n }\n\n // Arrays and Objects\n return diffObjects(args);\n}\n\nexport default recursiveDiff;\n","import type { DiffResult, DiffStringConfig } from '../types';\nimport { ChangeType } from './constants';\n\nconst ANSI_RESET = '\\x1b[0m';\n\nfunction colorWrapper(color: string) {\n return (str: string) => `${color}${str}${ANSI_RESET}`;\n}\n\nconst ansiColors = {\n [ChangeType.REMOVE]: colorWrapper('\\x1b[31m'),\n [ChangeType.ADD]: colorWrapper('\\x1b[32m'),\n [ChangeType.UPDATE]: colorWrapper('\\x1b[33m'),\n [ChangeType.NOOP]: colorWrapper(''),\n};\n\n/**\n * Takes the diff result and returns a diff string in md. + Added, - Removed, ! Updated\n * @param {DiffResult[]} diff - The result from the diff\n * @param {DiffStringConfig} [config]\n * @param {DiffStringConfig['withColors']} [config.withColors=true] - If true, outputs the string formatted with AnsiColors\n * @param {DiffStringConfig['colors']} [config.colors] - Each function takes a string and returns it formatted with ansi colors. Maps to each ChangeType.\n * @param {DiffStringConfig['symbols']} [config.symbols] - String map for each ChangeType\n * @param {DiffStringConfig['wrapper']} [config.wrapper=['```diff', '```']] - Strings that wrap the diff string output\n * @param {DiffStringConfig['indentSize']} [config.indentSize=2]\n */\nexport default function toDiffString(\n diff: DiffResult[],\n config?: DiffStringConfig\n) {\n const defaultConfig: DiffStringConfig = {\n withColors: true,\n colors: ansiColors,\n wrapper: [],\n indentSize: 2,\n symbols: {\n [ChangeType.ADD]: '+',\n [ChangeType.REMOVE]: '-',\n [ChangeType.UPDATE]: '!',\n [ChangeType.NOOP]: '',\n },\n };\n\n const mergedConfig = {\n ...defaultConfig,\n ...config,\n colors: {\n ...defaultConfig.colors,\n ...config?.colors,\n },\n symbols: {\n ...defaultConfig.symbols,\n ...config?.symbols,\n },\n };\n\n const diffString = diff\n .map(({ type, str, depth }, index) => {\n let symbolString = mergedConfig.symbols[type];\n\n if (index > 0 && index < diff.length - 1 && !symbolString.length) {\n symbolString = ` ${mergedConfig.symbols[type]}`;\n }\n\n let buildStr = `${symbolString}${' '.repeat(depth * mergedConfig.indentSize)}${str}`;\n\n if (mergedConfig.withColors) {\n buildStr = mergedConfig.colors[type](buildStr);\n }\n\n return buildStr;\n })\n .join('\\n');\n\n const [open = '', close = ''] = mergedConfig.wrapper || [];\n\n return `${open ? `${open}\\n` : ''}${diffString}${close ? `\\n${close}` : ''}`;\n}\n","import recursiveDiff from './diff';\nimport type { DiffConfig, DiffStringConfig, Diff } from './types';\nimport {\n ChangeType,\n DefaultPathHints,\n MAX_DEPTH,\n MAX_KEYS,\n MAX_TIMEOUT_MS,\n} from './utils/constants';\nimport toDiffString from './utils/toDiffString';\n\n/**\n * Returns the deep difference between two objects. The return object contains the stringified difference for easy rendering.\n * @param {any} lhs - Lef-hand side object. Can be either Object, Array, Set or Map.\n * @param {any} rhs - Right-hand side object.\n * @param {DiffConfig} [config] - Configuration to be used\n * @param {DiffConfig['exclude']} [config.exclude=[]] - Type differences to be ignored.\n * @param {DiffConfig['include']} [config.include=['add', 'remove', 'update', 'noop']] - Type differences to be logged.\n * @param {DiffConfig['strict']} [config.strict=true] - Indicates whether to enforce type check.\n * @param {DiffConfig['showUpdatedOnly']} [config.showUpdatedOnly=false] - Indicates whether a `remove` operation should be included for every `update`\n * @param {DiffConfig['pathHints']} [config.pathHints={ map: '__MAP__', set: '__SET__' }] - Strings to use as hints for Sets and Maps in the path array\n * @param {DiffConfig['maxDepth']} [config.maxDepth=50] - Max recursive depth that can be traversed before throwing\n * @param {DiffConfig['maxKeys']} [config.maxKeys=1000] - Max keys that can be processed at a time. Throws when LHS + RHS keys > maxKeys\n * @param {DiffConfig['timeout']} [config.timeout=1000] - Throws when the diffing timeout is met\n * @param {DiffConfig['redactKeys']} [config.redactKeys=[]] - Replaces the values of these keys with *****\n */\nfunction diff(lhs: any, rhs: any, config: DiffConfig): Diff {\n const defaultConfig: DiffConfig = {\n include: [\n ChangeType.ADD,\n ChangeType.REMOVE,\n ChangeType.UPDATE,\n ChangeType.NOOP,\n ],\n exclude: [],\n strict: true,\n showUpdatedOnly: false,\n pathHints: {\n map: DefaultPathHints.map,\n set: DefaultPathHints.set,\n },\n maxDepth: MAX_DEPTH,\n maxKeys: MAX_KEYS,\n timeout: MAX_TIMEOUT_MS,\n redactKeys: [\n 'password',\n 'secret',\n 'token',\n 'Symbol(password)',\n 'Symbol(secret)',\n 'Symbol(token)',\n ],\n };\n\n const mergedConfig: DiffConfig = {\n ...defaultConfig,\n ...config,\n };\n\n if (!mergedConfig.maxDepth) mergedConfig.maxDepth = MAX_DEPTH;\n if (!mergedConfig.maxKeys) mergedConfig.maxKeys = MAX_KEYS;\n if (!mergedConfig.timeout) mergedConfig.timeout = MAX_TIMEOUT_MS;\n\n mergedConfig.include = Array.isArray(mergedConfig.include)\n ? mergedConfig.include\n : [mergedConfig.include];\n\n mergedConfig.exclude = Array.isArray(mergedConfig.exclude)\n ? mergedConfig.exclude\n : [mergedConfig.exclude];\n\n const diffResult = recursiveDiff({\n lhs,\n rhs,\n config: mergedConfig,\n depth: 1,\n parent: null,\n seen: new WeakMap(),\n initialChangeType: ChangeType.NOOP,\n path: [],\n startedAt: Date.now(),\n });\n\n // All the changes are \"noop\", or empty array\n const areEqual = diffResult.every(\n (result) => result.type === ChangeType.NOOP\n );\n\n Object.defineProperty(diffResult, 'toDiffString', {\n value: (diffStringConfig: DiffStringConfig) =>\n toDiffString(diffResult, diffStringConfig),\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(diffResult, 'equal', {\n value: areEqual,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n return diffResult as Diff;\n}\n\nexport { ChangeType };\n\nexport default diff;\n"],"mappings":"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","names":["ChangeType","recursiveDiff","recursiveDiff","recursiveDiff","recursiveDiff","diff"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/constants.ts","../src/utils/fns.ts","../src/diff/shared.ts","../src/diff/diffObjects.ts","../src/diff/diffSets.ts","../src/diff/diffMaps.ts","../src/diff/diffConstructors.ts","../src/diff/index.ts","../src/utils/toDiffString.ts","../src/index.ts"],"sourcesContent":["export const Iterables = new Set([Object, Array, Set, Map]);\n\nexport enum ChangeType {\n ADD = 'add',\n UPDATE = 'update',\n REMOVE = 'remove',\n NOOP = 'noop',\n}\n\nexport const DefaultPathHints = {\n map: '__MAP__',\n set: '__SET__',\n};\n\nexport const MAX_DEPTH = 50;\n\nexport const MAX_KEYS = 1000;\n\nexport const ITERATION_TIMEOUT_CHECK = 1000;\n\nexport const MAX_TIMEOUT_MS = 1000;\n\nexport const REDACTED = '*****';\n","import { Iterables } from './constants';\n\nexport function isPrimitive(value: any) {\n return value !== Object(value);\n}\n\nexport function getRawValue(value: any) {\n // If value is primitive (except symbol), then perform validations in its pure form\n if (isPrimitive(value) && typeof value !== 'symbol') return value;\n\n // Serializes the value to perform validations\n return value.toString();\n}\n\nexport function isNullOrUndefined(value: any) {\n return value === null || value === undefined;\n}\nexport function isCustomClassInstance(object: any) {\n if (\n isNullOrUndefined(object) ||\n typeof object !== 'object' ||\n !object.constructor\n ) {\n return false;\n }\n\n return !object.constructor?.toString?.().includes('[native code]');\n}\n\nexport function emptyShellClone(object: any) {\n // Clone the instance shell\n if (isCustomClassInstance(object)) {\n return Object.create(Object.getPrototypeOf(object));\n }\n\n // Objects created with Object.create(null) don't have constructor\n if (isObject(object)) {\n return Object.create(null);\n }\n\n // Creates an empty instance from the native constructor\n return new object.constructor();\n}\n\nexport function getWrapper(obj: any) {\n let wrapper = ['{', '}'];\n\n if (Array.isArray(obj)) {\n wrapper = ['[', ']'];\n } else if (isCustomClassInstance(obj)) {\n wrapper = [`${obj.constructor.name} {`, '}'];\n } else if (obj instanceof Map) {\n wrapper = [`Map (${obj.size}) {`, '}'];\n } else if (obj instanceof Set) {\n wrapper = ['Set [', ']'];\n }\n\n return wrapper;\n}\n\n/**\n * Returns the ref type of the value\n * @param value - The value\n * @returns string\n */\nexport function getRef(value: any) {\n return `ref<${value?.constructor?.name || typeof value}>`;\n}\n\nexport function isObject(obj: any) {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n (Object.getPrototypeOf(obj) === Object.prototype ||\n Object.getPrototypeOf(obj) === null)\n );\n}\n\nexport function areObjects(a: any, b: any) {\n return isObject(a) && isObject(b);\n}\n\nexport function getEnumerableKeys(obj: any) {\n return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];\n}\n\nexport function isIterable(obj: any) {\n return (\n Iterables.has(obj?.constructor) ||\n isObject(obj) ||\n isCustomClassInstance(obj)\n );\n}\n","import type { DiffConfig, DiffResult, PathHints } from '../types';\nimport { ChangeType, REDACTED } from '../utils/constants';\nimport { getRawValue, getWrapper, isPrimitive } from '../utils/fns';\n\nexport function lastPathValue(changeType: ChangeType, value: any) {\n return { deleted: changeType === ChangeType.REMOVE, value };\n}\n\nexport function includeDiffType(type: ChangeType, config: DiffConfig) {\n return config.include?.includes?.(type) && !config.exclude?.includes?.(type);\n}\n\nexport function shouldRedactValue(key: any, config: DiffConfig) {\n const rawKey = getRawValue(key);\n\n return config.redactKeys?.includes?.(rawKey);\n}\n\nexport function createReplacer(config: DiffConfig, obj: any) {\n const seen = new WeakSet();\n\n return function replacer(k: any, v: any) {\n // Redact the entire value if the key matches\n if (shouldRedactValue(k, config)) return REDACTED;\n\n // Returns circular if iterating over the same object from the replacer\n if (k !== '' && v === obj) return '[Circular]';\n\n if (v && typeof v === 'object') {\n if (seen.has(v)) return '[Circular]';\n\n seen.add(v);\n }\n\n if (v instanceof Set) {\n const stringified = JSON.stringify([...v.values()], replacer);\n\n seen.delete(v);\n return `Set ${stringified}`;\n }\n\n if (v instanceof Map) {\n const entries = [...v.entries()];\n const stringified = entries\n .map(([key, value]) => {\n if (seen.has(key)) {\n return `\"[Circular]\": ${JSON.stringify(value, replacer)}`;\n }\n\n if (!isPrimitive(key)) {\n seen.add(key);\n }\n\n const serializedValue = shouldRedactValue(key, config)\n ? REDACTED\n : JSON.stringify(value, replacer);\n const serialized = `${JSON.stringify(key, replacer)}: ${serializedValue}`;\n\n if (!isPrimitive) {\n seen.delete(key);\n }\n\n return serialized;\n })\n .join(', ');\n\n seen.delete(v);\n return `Map (${entries.length}) { ${stringified} }`;\n }\n\n if (v instanceof Function) {\n return `Function ${v.name || '(anonymous)'}`;\n }\n\n if (typeof v === 'symbol') {\n return v.toString();\n }\n\n if (typeof v === 'bigint') {\n return `BigInt(${v.toString()})`;\n }\n\n seen.delete(v);\n return v;\n };\n}\n\nexport function stringify(obj: any, config: DiffConfig) {\n return JSON.stringify(obj, createReplacer(config, obj));\n}\n\nexport function getObjectChangeResult(\n lhs: any,\n rhs: any,\n depth: number,\n key: any,\n parsedKey: any,\n config: DiffConfig,\n path: Array<any>\n) {\n const isLhsMap = lhs instanceof Map;\n const isRhsMap = rhs instanceof Map;\n\n let valueInLhs = lhs?.[key];\n let valueInRhs = rhs?.[key];\n let keyInLhs = Object.hasOwn(lhs, key);\n let keyInRhs = Object.hasOwn(rhs, key);\n\n if (isLhsMap) {\n valueInLhs = lhs.get(key);\n keyInLhs = lhs.has(key);\n }\n\n if (isRhsMap) {\n valueInRhs = rhs.get(key);\n keyInRhs = rhs.has(key);\n }\n\n const redactValue = shouldRedactValue(key, config);\n const rawValueInLhs = getRawValue(valueInLhs);\n const rawValueInRhs = getRawValue(valueInRhs);\n const formattedValueInLhs = stringify(\n redactValue ? REDACTED : rawValueInLhs,\n config\n );\n const formattedValueInRhs = stringify(\n redactValue ? REDACTED : rawValueInRhs,\n config\n );\n\n let type = ChangeType.NOOP;\n let formattedValue = formattedValueInRhs; // Select the most recent change\n let pathValue = valueInRhs;\n\n if (!keyInLhs && keyInRhs) {\n // added in rhs\n type = ChangeType.ADD;\n } else if (keyInLhs && !keyInRhs) {\n // removed in rhs\n type = ChangeType.REMOVE;\n formattedValue = formattedValueInLhs;\n pathValue = valueInLhs;\n } else if (\n config.strict\n ? rawValueInLhs !== rawValueInRhs\n : rawValueInLhs != rawValueInRhs\n ) {\n // different in rhs\n type = ChangeType.UPDATE;\n }\n\n const result: DiffResult[] = [];\n\n // If the type of change should be included in the results\n if (includeDiffType(type, config)) {\n const stringifiedParsedKey = stringify(parsedKey, config);\n\n if (type === ChangeType.UPDATE && !config.showUpdatedOnly) {\n result.push({\n type: ChangeType.REMOVE,\n str: `${stringifiedParsedKey}: ${formattedValueInLhs},`,\n depth,\n path: [...path, lastPathValue(ChangeType.REMOVE, valueInLhs)],\n });\n }\n\n result.push({\n type,\n str: `${stringifiedParsedKey}: ${formattedValue},`,\n depth,\n path: [...path, lastPathValue(type, pathValue)],\n });\n }\n\n return result;\n}\n\nexport function getPathHint(config: DiffConfig, type: keyof PathHints) {\n if (typeof config.pathHints === 'object') {\n const hint = config.pathHints[type];\n\n if (typeof hint === 'string') return hint;\n }\n\n // no hint for this type\n return null;\n}\n\nexport function buildResult(\n rhs: any,\n result: DiffResult[],\n depth: number,\n initialChangeType: ChangeType,\n parent: any,\n path: any[],\n config: DiffConfig\n) {\n if (!includeDiffType(initialChangeType, config)) return result;\n\n const parentDepth = depth - 1;\n const [open, close] = getWrapper(rhs);\n\n return [\n {\n type: initialChangeType,\n str: parentDepth > 0 ? `${stringify(parent, config)}: ${open}` : open,\n depth: parentDepth,\n path,\n },\n ...result,\n {\n type: initialChangeType,\n str: parentDepth > 0 ? `${close},` : close,\n depth: parentDepth,\n path,\n },\n ];\n}\n\n// Prevents bloating the memory for large objects\nexport function timeoutSecurityCheck(startedAt: number, config: DiffConfig) {\n if (Date.now() - startedAt > config.timeout) {\n throw new Error('Diff took too much time! Aborting.');\n }\n}\n\nexport function maxKeysSecurityCheck(size: number, config: DiffConfig) {\n if (size > config.maxKeys) {\n throw new Error('Object is too big to continue! Aborting.');\n }\n}\n","import { type DiffResult, DiffObjectArgs } from '../types';\nimport { ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { getEnumerableKeys, isIterable } from '../utils/fns';\nimport {\n buildResult,\n getObjectChangeResult,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffObjects({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffObjectArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n const lhsKeys = getEnumerableKeys(lhs);\n maxKeysSecurityCheck(lhsKeys.length, config);\n\n const rhsKeys = getEnumerableKeys(rhs);\n maxKeysSecurityCheck(rhsKeys.length, config);\n\n const keys = new Set<string | number | symbol>([...lhsKeys, ...rhsKeys]);\n\n let i = 0;\n for (const key of keys) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const lhsValue = Array.isArray(lhs) ? lhs[key as number] : lhs?.[key];\n const rhsValue = Array.isArray(rhs) ? rhs[key as number] : rhs?.[key];\n const numericKey = typeof key !== 'symbol' ? Number(key) : NaN;\n const parsedKey = isNaN(numericKey) ? key : numericKey;\n const updatedPath = [...path, parsedKey];\n\n if (isIterable(lhsValue) || isIterable(rhsValue)) {\n result.push(\n ...recursiveDiff({\n lhs: lhsValue,\n rhs: rhsValue,\n config,\n depth: depth + 1,\n parent: parsedKey,\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n result.push(\n ...getObjectChangeResult(\n lhs,\n rhs,\n depth,\n key,\n parsedKey,\n config,\n updatedPath\n )\n );\n }\n\n seen.delete(lhs);\n seen.delete(rhs);\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffObjects;\n","import { DiffResult, DiffSetArgs } from '../types';\nimport { ChangeType, ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { getRef, isIterable } from '../utils/fns';\nimport {\n buildResult,\n getPathHint,\n includeDiffType,\n lastPathValue,\n maxKeysSecurityCheck,\n stringify,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffSets({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffSetArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n maxKeysSecurityCheck(lhs.size, config);\n maxKeysSecurityCheck(rhs.size, config);\n\n const mergedSet = new Set([...lhs, ...rhs]);\n\n let i = 0;\n for (const value of mergedSet) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const existsInLhs = lhs.has(value);\n const existsInRhs = rhs.has(value);\n const hint = getPathHint(config, 'set');\n const updatedPath = [...path];\n\n if (hint) {\n updatedPath.push(hint);\n }\n\n if (isIterable(value)) {\n result.push(\n ...recursiveDiff({\n lhs: existsInLhs ? value : undefined,\n rhs: existsInRhs ? value : undefined,\n config,\n depth: depth + 1,\n parent: getRef(value),\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n let type = ChangeType.NOOP;\n\n if (existsInLhs && !existsInRhs) {\n type = ChangeType.REMOVE;\n } else if (!existsInLhs && existsInRhs) {\n type = ChangeType.ADD;\n }\n\n if (includeDiffType(type, config)) {\n result.push({\n type,\n str: `${stringify(value, config)},`,\n depth,\n path: [...updatedPath, lastPathValue(type, value)],\n });\n }\n }\n\n seen.delete(lhs);\n seen.delete(rhs);\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffSets;\n","import { DiffResult, DiffMapArgs } from '../types';\nimport { ITERATION_TIMEOUT_CHECK } from '../utils/constants';\nimport { isIterable } from '../utils/fns';\nimport {\n buildResult,\n getObjectChangeResult,\n getPathHint,\n maxKeysSecurityCheck,\n timeoutSecurityCheck,\n} from './shared';\n\nfunction diffMaps({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffMapArgs): DiffResult[] {\n const result: DiffResult[] = [];\n\n maxKeysSecurityCheck(lhs.size, config);\n maxKeysSecurityCheck(rhs.size, config);\n\n const mergedMapKeys = new Set([...lhs.keys(), ...rhs.keys()]);\n\n let i = 0;\n for (const key of mergedMapKeys) {\n if (i++ % ITERATION_TIMEOUT_CHECK === 0) {\n timeoutSecurityCheck(startedAt, config);\n }\n\n const keyInLhs = lhs.has(key);\n const keyInRhs = rhs.has(key);\n const lhsValue = keyInLhs ? lhs.get(key) : null;\n const rhsValue = keyInRhs ? rhs.get(key) : null;\n const hint = getPathHint(config, 'map');\n const pathUpdate = hint ? [hint, key] : [key];\n const updatedPath = [...path, ...pathUpdate];\n\n if (isIterable(lhsValue) || isIterable(rhsValue)) {\n result.push(\n ...recursiveDiff({\n lhs: lhsValue,\n rhs: rhsValue,\n config,\n depth: depth + 1,\n parent: key,\n seen,\n initialChangeType,\n path: updatedPath,\n startedAt,\n })\n );\n continue;\n }\n\n result.push(\n ...getObjectChangeResult(lhs, rhs, depth, key, key, config, updatedPath)\n );\n }\n\n seen.delete(lhs);\n seen.delete(rhs);\n\n return buildResult(\n rhs,\n result,\n depth,\n initialChangeType,\n parent,\n path,\n config\n );\n}\n\nexport default diffMaps;\n","import { type DiffResult, DiffConstructorArgs } from '../types';\nimport { ChangeType } from '../utils/constants';\nimport { emptyShellClone, isObject } from '../utils/fns';\n\nfunction diffConstructors({\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: DiffConstructorArgs): DiffResult[] {\n // Different Constructors\n let modLhs = lhs;\n let modRhs = rhs;\n let defaultChangeType = initialChangeType;\n\n if (isObject(rhs) || rhs?.constructor) {\n // Added in rhs. Use rhs prototype to traverse the added properties\n modLhs = emptyShellClone(rhs);\n\n defaultChangeType = ChangeType.ADD;\n } else if (isObject(lhs) || lhs?.constructor) {\n // Removed in rhs. Use lhs prototype to traverse the removed properties\n modRhs = emptyShellClone(lhs);\n\n defaultChangeType = ChangeType.REMOVE;\n } else {\n // Fail for unknown edge cases\n throw new Error(\"Edge case raised, I don't know how to handle this input\");\n }\n\n return recursiveDiff({\n lhs: modLhs,\n rhs: modRhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType: defaultChangeType,\n path,\n startedAt,\n });\n}\n\nexport default diffConstructors;\n","import { type DiffResult, RecursiveDiffArgs } from '../types';\nimport diffObjects from './diffObjects';\nimport diffSets from './diffSets';\nimport diffMaps from './diffMaps';\nimport diffConstructors from './diffConstructors';\nimport { ChangeType } from '../utils/constants';\nimport { areObjects, isNullOrUndefined, isPrimitive } from '../utils/fns';\nimport {\n includeDiffType,\n lastPathValue,\n timeoutSecurityCheck,\n stringify,\n} from './shared';\n\nfunction recursiveDiff({\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n}: RecursiveDiffArgs): DiffResult[] {\n // Prevents stack overflow\n if (depth > config.maxDepth) {\n throw new Error('Max depth exceeded!');\n }\n\n // Checks for timeout before proceeding\n timeoutSecurityCheck(startedAt, config);\n\n // Allows printing the first level of circular references\n const lhsSeen = seen.get(lhs) ?? 0;\n const rhsSeen = seen.get(rhs) ?? 0;\n\n if (lhsSeen > 1 || rhsSeen > 1) {\n if (!includeDiffType(initialChangeType, config)) return [];\n\n return [\n {\n type: initialChangeType,\n str: `${stringify(parent, config)}: [Circular],`,\n depth: depth - 1,\n path,\n },\n ];\n }\n\n // Prevents circular references except for primitives\n if (typeof lhs === 'object' && lhs !== null) seen.set(lhs, lhsSeen + 1);\n if (typeof rhs === 'object' && rhs !== null) seen.set(rhs, rhsSeen + 1);\n\n const args = {\n recursiveDiff,\n lhs,\n rhs,\n config,\n depth,\n parent,\n seen,\n initialChangeType,\n path,\n startedAt,\n };\n\n // Handles comparing primitives\n if (isPrimitive(lhs) && isPrimitive(rhs)) {\n // Return early if it's the same primitive\n if (config.strict ? lhs === rhs : lhs == rhs) {\n return [];\n }\n\n const parentDepth = depth - 1;\n const lhsValue = stringify(lhs, config);\n const rhsValue = stringify(rhs, config);\n\n const result = [];\n\n if (includeDiffType(ChangeType.UPDATE, config)) {\n if (!config.showUpdatedOnly) {\n result.push({\n type: ChangeType.REMOVE,\n str: `${lhsValue}`,\n depth: parentDepth,\n path: [...path, lastPathValue(ChangeType.REMOVE, lhs)],\n });\n }\n\n result.push({\n type: ChangeType.UPDATE,\n str: `${rhsValue}`,\n depth: parentDepth,\n path: [...path, lastPathValue(ChangeType.UPDATE, rhs)],\n });\n }\n\n return result;\n }\n\n // Different constructor handler\n if (\n !areObjects(lhs, rhs) && // Skips for Object.create(null) vs {}\n (lhs?.constructor !== rhs?.constructor ||\n (isNullOrUndefined(lhs) && rhs) ||\n (lhs && isNullOrUndefined(rhs)))\n ) {\n return diffConstructors(args);\n }\n\n // SETS\n if (lhs instanceof Set && rhs instanceof Set) {\n return diffSets(args);\n }\n\n // MAPS\n if (lhs instanceof Map && rhs instanceof Map) {\n return diffMaps(args);\n }\n\n // Arrays and Objects\n return diffObjects(args);\n}\n\nexport default recursiveDiff;\n","import type { DiffResult, DiffStringConfig } from '../types';\nimport { ChangeType } from './constants';\nimport { isNullOrUndefined } from './fns';\n\nconst ANSI_RESET = '\\x1b[0m';\n\nfunction colorWrapper(color: string) {\n return (str: string) => `${color}${str}${ANSI_RESET}`;\n}\n\nconst ansiColors = {\n [ChangeType.REMOVE]: colorWrapper('\\x1b[31m'),\n [ChangeType.ADD]: colorWrapper('\\x1b[32m'),\n [ChangeType.UPDATE]: colorWrapper('\\x1b[33m'),\n [ChangeType.NOOP]: colorWrapper(''),\n};\n\n/**\n * Takes the diff result and returns a diff string in md. + Added, - Removed, ! Updated\n * @param {DiffResult[]} diff - The result from the diff\n * @param {DiffStringConfig} [config]\n * @param {DiffStringConfig['withColors']} [config.withColors=false] - If true, outputs the string formatted with AnsiColors\n * @param {DiffStringConfig['colors']} [config.colors] - Each function takes a string and returns it formatted with ansi colors. Maps to each ChangeType.\n * @param {DiffStringConfig['symbols']} [config.symbols] - String map for each ChangeType\n * @param {DiffStringConfig['wrapper']} [config.wrapper=['```diff', '```']] - Strings that wrap the diff string output\n * @param {DiffStringConfig['indentSize']} [config.indentSize=2]\n */\nexport default function toDiffString(\n diff: DiffResult[],\n config?: DiffStringConfig\n) {\n const defaultConfig: DiffStringConfig = {\n withColors: false,\n colors: ansiColors,\n wrapper: [],\n indentSize: 2,\n symbols: {\n [ChangeType.ADD]: '+',\n [ChangeType.REMOVE]: '-',\n [ChangeType.UPDATE]: '!',\n [ChangeType.NOOP]: '',\n },\n };\n\n const mergedConfig = {\n ...defaultConfig,\n ...config,\n colors: {\n ...defaultConfig.colors,\n ...config?.colors,\n },\n symbols: {\n ...defaultConfig.symbols,\n ...config?.symbols,\n },\n };\n\n const diffString = diff\n .map(({ type, str, depth }, index) => {\n if (\n !Object.hasOwn(mergedConfig.symbols, type) ||\n isNullOrUndefined(mergedConfig.symbols[type])\n ) {\n throw new Error(`<${type}> symbol missing in config`);\n }\n\n if (\n !Object.hasOwn(mergedConfig.colors, type) ||\n isNullOrUndefined(mergedConfig.colors[type])\n ) {\n throw new Error(`<${type}> color function missing in config`);\n }\n\n let symbolString = mergedConfig.symbols[type];\n\n if (index > 0 && index < diff.length - 1 && !symbolString.length) {\n symbolString = ` ${mergedConfig.symbols[type]}`;\n }\n\n let buildStr = `${symbolString}${' '.repeat(depth * mergedConfig.indentSize)}${str}`;\n\n if (mergedConfig.withColors) {\n buildStr = mergedConfig.colors[type](buildStr);\n }\n\n return buildStr;\n })\n .join('\\n');\n\n const [open = '', close = ''] = mergedConfig.wrapper || [];\n\n return `${open ? `${open}\\n` : ''}${diffString}${close ? `\\n${close}` : ''}`;\n}\n","import recursiveDiff from './diff';\nimport type { DiffConfig, DiffStringConfig, Diff } from './types';\nimport {\n ChangeType,\n DefaultPathHints,\n MAX_DEPTH,\n MAX_KEYS,\n MAX_TIMEOUT_MS,\n} from './utils/constants';\nimport toDiffString from './utils/toDiffString';\n\n/**\n * Returns the deep difference between two objects. The return object contains the stringified difference for easy rendering.\n * @param {any} lhs - Lef-hand side object. Can be either Object, Array, Set or Map.\n * @param {any} rhs - Right-hand side object.\n * @param {DiffConfig} [config] - Configuration to be used\n * @param {DiffConfig['exclude']} [config.exclude=[]] - Type differences to be ignored.\n * @param {DiffConfig['include']} [config.include=['add', 'remove', 'update', 'noop']] - Type differences to be logged.\n * @param {DiffConfig['strict']} [config.strict=true] - Indicates whether to enforce type check.\n * @param {DiffConfig['showUpdatedOnly']} [config.showUpdatedOnly=false] - Indicates whether a `remove` operation should be included for every `update`\n * @param {DiffConfig['pathHints']} [config.pathHints={ map: '__MAP__', set: '__SET__' }] - Strings to use as hints for Sets and Maps in the path array\n * @param {DiffConfig['maxDepth']} [config.maxDepth=50] - Max recursive depth that can be traversed before throwing\n * @param {DiffConfig['maxKeys']} [config.maxKeys=1000] - Max keys that can be processed at a time. Throws when LHS + RHS keys > maxKeys\n * @param {DiffConfig['timeout']} [config.timeout=1000] - Throws when the diffing timeout is met\n * @param {DiffConfig['redactKeys']} [config.redactKeys=[]] - Replaces the values of these keys with *****\n */\nfunction diff(lhs: any, rhs: any, config?: Partial<DiffConfig>): Diff {\n const defaultConfig: DiffConfig = {\n include: [\n ChangeType.ADD,\n ChangeType.REMOVE,\n ChangeType.UPDATE,\n ChangeType.NOOP,\n ],\n exclude: [],\n strict: true,\n showUpdatedOnly: false,\n pathHints: {\n map: DefaultPathHints.map,\n set: DefaultPathHints.set,\n },\n maxDepth: MAX_DEPTH,\n maxKeys: MAX_KEYS,\n timeout: MAX_TIMEOUT_MS,\n redactKeys: [\n 'password',\n 'secret',\n 'token',\n 'Symbol(password)',\n 'Symbol(secret)',\n 'Symbol(token)',\n ],\n };\n\n const mergedConfig: DiffConfig = {\n ...defaultConfig,\n ...config,\n };\n\n if (!mergedConfig.maxDepth) mergedConfig.maxDepth = MAX_DEPTH;\n if (!mergedConfig.maxKeys) mergedConfig.maxKeys = MAX_KEYS;\n if (!mergedConfig.timeout) mergedConfig.timeout = MAX_TIMEOUT_MS;\n\n mergedConfig.include = Array.isArray(mergedConfig.include)\n ? mergedConfig.include\n : [mergedConfig.include];\n\n mergedConfig.exclude = Array.isArray(mergedConfig.exclude)\n ? mergedConfig.exclude\n : [mergedConfig.exclude];\n\n const diffResult = recursiveDiff({\n lhs,\n rhs,\n config: mergedConfig,\n depth: 1,\n parent: null,\n seen: new WeakMap(),\n initialChangeType: ChangeType.NOOP,\n path: [],\n startedAt: Date.now(),\n });\n\n // All the changes are \"noop\", or empty array\n const areEqual = diffResult.every(\n (result) => result.type === ChangeType.NOOP\n );\n\n Object.defineProperty(diffResult, 'toDiffString', {\n value: (diffStringConfig: DiffStringConfig) =>\n toDiffString(diffResult, diffStringConfig),\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(diffResult, 'equal', {\n value: areEqual,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n return diffResult as Diff;\n}\n\nexport { ChangeType };\n\nexport default diff;\n"],"mappings":"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","names":["ChangeType","recursiveDiff","recursiveDiff","recursiveDiff","recursiveDiff","diff"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sandboxed/diff",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A zero dependency, high-performance, security-conscious JavaScript diffing library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.cjs",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"@babel/preset-typescript": "^7.26.0",
|
|
49
49
|
"@eslint/js": "^9.20.0",
|
|
50
50
|
"@stylistic/eslint-plugin": "^4.0.1",
|
|
51
|
+
"@types/jest": "^30.0.0",
|
|
51
52
|
"@types/node": "^22.13.4",
|
|
52
53
|
"babel-jest": "^29.7.0",
|
|
53
54
|
"eslint": "^9.20.1",
|