json-diff-ts 1.2.7 → 1.2.8
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/lib/index.js +18 -2
- package/lib/jsonCompare.js +38 -30
- package/lib/jsonDiff.js +34 -25
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -1,2 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./jsonDiff"), exports);
|
|
18
|
+
__exportStar(require("./jsonCompare"), exports);
|
package/lib/jsonCompare.js
CHANGED
|
@@ -1,58 +1,64 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compare = exports.applyChangelist = exports.enrich = exports.createContainer = exports.createValue = exports.CompareOperation = void 0;
|
|
4
|
+
const lodash_1 = require("lodash");
|
|
5
|
+
const jsonDiff_1 = require("./jsonDiff");
|
|
6
|
+
var CompareOperation;
|
|
4
7
|
(function (CompareOperation) {
|
|
5
8
|
CompareOperation["CONTAINER"] = "CONTAINER";
|
|
6
9
|
CompareOperation["UNCHANGED"] = "UNCHANGED";
|
|
7
|
-
})(CompareOperation || (CompareOperation = {}));
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
})(CompareOperation = exports.CompareOperation || (exports.CompareOperation = {}));
|
|
11
|
+
const createValue = (value) => ({ type: CompareOperation.UNCHANGED, value });
|
|
12
|
+
exports.createValue = createValue;
|
|
13
|
+
const createContainer = (value) => ({
|
|
10
14
|
type: CompareOperation.CONTAINER,
|
|
11
15
|
value
|
|
12
16
|
});
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
exports.createContainer = createContainer;
|
|
18
|
+
const enrich = (object) => {
|
|
19
|
+
const objectType = (0, jsonDiff_1.getTypeOfObj)(object);
|
|
15
20
|
switch (objectType) {
|
|
16
21
|
case 'Object':
|
|
17
|
-
return keys(object)
|
|
18
|
-
.map((key) => ({ key, value: enrich(object[key]) }))
|
|
22
|
+
return (0, lodash_1.keys)(object)
|
|
23
|
+
.map((key) => ({ key, value: (0, exports.enrich)(object[key]) }))
|
|
19
24
|
.reduce((accumulator, entry) => {
|
|
20
25
|
accumulator.value[entry.key] = entry.value;
|
|
21
26
|
return accumulator;
|
|
22
|
-
}, createContainer({}));
|
|
27
|
+
}, (0, exports.createContainer)({}));
|
|
23
28
|
case 'Array':
|
|
24
|
-
return chain(object)
|
|
25
|
-
.map((value) => enrich(value))
|
|
29
|
+
return (0, lodash_1.chain)(object)
|
|
30
|
+
.map((value) => (0, exports.enrich)(value))
|
|
26
31
|
.reduce((accumulator, value) => {
|
|
27
32
|
accumulator.value.push(value);
|
|
28
33
|
return accumulator;
|
|
29
|
-
}, createContainer([]))
|
|
34
|
+
}, (0, exports.createContainer)([]))
|
|
30
35
|
.value();
|
|
31
36
|
case 'Function':
|
|
32
37
|
return undefined;
|
|
33
38
|
case 'Date':
|
|
34
39
|
default:
|
|
35
40
|
// Primitive value
|
|
36
|
-
return createValue(object);
|
|
41
|
+
return (0, exports.createValue)(object);
|
|
37
42
|
}
|
|
38
43
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
.map((entry) => (Object.assign(Object.assign({}, entry), { path: replace(entry.path,
|
|
43
|
-
.map((entry) => (Object.assign(Object.assign({}, entry), { path: replace(entry.path, /(?<
|
|
44
|
-
.map((entry) => (Object.assign(Object.assign({}, entry), { path: replace(entry.path,
|
|
45
|
-
.map((entry) => (Object.assign(Object.assign({}, entry), { path: replace(entry.path,
|
|
46
|
-
.map((entry) => (Object.assign(Object.assign({}, entry), { path: replace(entry.path, /
|
|
44
|
+
exports.enrich = enrich;
|
|
45
|
+
const applyChangelist = (object, changelist) => {
|
|
46
|
+
(0, lodash_1.chain)(changelist)
|
|
47
|
+
.map((entry) => (Object.assign(Object.assign({}, entry), { path: (0, lodash_1.replace)(entry.path, '$.', '.') })))
|
|
48
|
+
.map((entry) => (Object.assign(Object.assign({}, entry), { path: (0, lodash_1.replace)(entry.path, /(\[(?<array>\d)\]\.)/g, 'ARRVAL_START$<array>ARRVAL_END') })))
|
|
49
|
+
.map((entry) => (Object.assign(Object.assign({}, entry), { path: (0, lodash_1.replace)(entry.path, /(?<dot>\.)/g, '.value$<dot>') })))
|
|
50
|
+
.map((entry) => (Object.assign(Object.assign({}, entry), { path: (0, lodash_1.replace)(entry.path, /\./, '') })))
|
|
51
|
+
.map((entry) => (Object.assign(Object.assign({}, entry), { path: (0, lodash_1.replace)(entry.path, /ARRVAL_START/g, '.value[') })))
|
|
52
|
+
.map((entry) => (Object.assign(Object.assign({}, entry), { path: (0, lodash_1.replace)(entry.path, /ARRVAL_END/g, '].value.') })))
|
|
47
53
|
.value()
|
|
48
54
|
.forEach((entry) => {
|
|
49
55
|
switch (entry.type) {
|
|
50
|
-
case Operation.ADD:
|
|
51
|
-
case Operation.UPDATE:
|
|
52
|
-
set(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });
|
|
56
|
+
case jsonDiff_1.Operation.ADD:
|
|
57
|
+
case jsonDiff_1.Operation.UPDATE:
|
|
58
|
+
(0, lodash_1.set)(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });
|
|
53
59
|
break;
|
|
54
|
-
case Operation.REMOVE:
|
|
55
|
-
set(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });
|
|
60
|
+
case jsonDiff_1.Operation.REMOVE:
|
|
61
|
+
(0, lodash_1.set)(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });
|
|
56
62
|
break;
|
|
57
63
|
default:
|
|
58
64
|
throw new Error();
|
|
@@ -60,6 +66,8 @@ export const applyChangelist = (object, changelist) => {
|
|
|
60
66
|
});
|
|
61
67
|
return object;
|
|
62
68
|
};
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
exports.applyChangelist = applyChangelist;
|
|
70
|
+
const compare = (oldObject, newObject) => {
|
|
71
|
+
return (0, exports.applyChangelist)((0, exports.enrich)(oldObject), (0, jsonDiff_1.flattenChangeset)((0, jsonDiff_1.diff)(oldObject, newObject)));
|
|
65
72
|
};
|
|
73
|
+
exports.compare = compare;
|
package/lib/jsonDiff.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unflattenChanges = exports.flattenChangeset = exports.Operation = exports.revertChangeset = exports.applyChangeset = exports.diff = exports.getTypeOfObj = void 0;
|
|
4
|
+
const lodash_1 = require("lodash");
|
|
5
|
+
const getTypeOfObj = (obj) => {
|
|
3
6
|
if (typeof obj === 'undefined') {
|
|
4
7
|
return 'undefined';
|
|
5
8
|
}
|
|
@@ -8,14 +11,15 @@ export const getTypeOfObj = (obj) => {
|
|
|
8
11
|
}
|
|
9
12
|
return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
|
|
10
13
|
};
|
|
14
|
+
exports.getTypeOfObj = getTypeOfObj;
|
|
11
15
|
const getKey = (path) => {
|
|
12
16
|
const left = path[path.length - 1];
|
|
13
17
|
return left != null ? left : '$root';
|
|
14
18
|
};
|
|
15
19
|
const compare = (oldObj, newObj, path, embeddedObjKeys, keyPath) => {
|
|
16
20
|
let changes = [];
|
|
17
|
-
const typeOfOldObj = getTypeOfObj(oldObj);
|
|
18
|
-
const typeOfNewObj = getTypeOfObj(newObj);
|
|
21
|
+
const typeOfOldObj = (0, exports.getTypeOfObj)(oldObj);
|
|
22
|
+
const typeOfNewObj = (0, exports.getTypeOfObj)(newObj);
|
|
19
23
|
// if type of object changes, consider it as old obj has been deleted and a new object has been added
|
|
20
24
|
if (typeOfOldObj !== typeOfNewObj) {
|
|
21
25
|
changes.push({ type: Operation.REMOVE, key: getKey(path), value: oldObj });
|
|
@@ -62,7 +66,7 @@ const compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath
|
|
|
62
66
|
let changes = [];
|
|
63
67
|
const oldObjKeys = Object.keys(oldObj);
|
|
64
68
|
const newObjKeys = Object.keys(newObj);
|
|
65
|
-
const intersectionKeys = intersection(oldObjKeys, newObjKeys);
|
|
69
|
+
const intersectionKeys = (0, lodash_1.intersection)(oldObjKeys, newObjKeys);
|
|
66
70
|
for (k of intersectionKeys) {
|
|
67
71
|
newPath = path.concat([k]);
|
|
68
72
|
newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
|
|
@@ -71,7 +75,7 @@ const compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath
|
|
|
71
75
|
changes = changes.concat(diffs);
|
|
72
76
|
}
|
|
73
77
|
}
|
|
74
|
-
const addedKeys = difference(newObjKeys, oldObjKeys);
|
|
78
|
+
const addedKeys = (0, lodash_1.difference)(newObjKeys, oldObjKeys);
|
|
75
79
|
for (k of addedKeys) {
|
|
76
80
|
newPath = path.concat([k]);
|
|
77
81
|
newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
|
|
@@ -81,7 +85,7 @@ const compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath
|
|
|
81
85
|
value: newObj[k]
|
|
82
86
|
});
|
|
83
87
|
}
|
|
84
|
-
const deletedKeys = difference(oldObjKeys, newObjKeys);
|
|
88
|
+
const deletedKeys = (0, lodash_1.difference)(oldObjKeys, newObjKeys);
|
|
85
89
|
for (k of deletedKeys) {
|
|
86
90
|
newPath = path.concat([k]);
|
|
87
91
|
newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
|
|
@@ -136,7 +140,7 @@ const convertArrayToObj = (arr, uniqKey) => {
|
|
|
136
140
|
});
|
|
137
141
|
}
|
|
138
142
|
else if (uniqKey !== '$index') {
|
|
139
|
-
obj = keyBy(arr, uniqKey);
|
|
143
|
+
obj = (0, lodash_1.keyBy)(arr, uniqKey);
|
|
140
144
|
}
|
|
141
145
|
else {
|
|
142
146
|
for (let i = 0; i < arr.length; i++) {
|
|
@@ -229,9 +233,9 @@ const applyArrayChange = (arr, change) => (() => {
|
|
|
229
233
|
}
|
|
230
234
|
}
|
|
231
235
|
else {
|
|
232
|
-
element = find(arr, (el) => el[change.embeddedKey].toString() === subchange.key.toString());
|
|
236
|
+
element = (0, lodash_1.find)(arr, (el) => el[change.embeddedKey].toString() === subchange.key.toString());
|
|
233
237
|
}
|
|
234
|
-
result.push(applyChangeset(element, subchange.changes));
|
|
238
|
+
result.push((0, exports.applyChangeset)(element, subchange.changes));
|
|
235
239
|
}
|
|
236
240
|
}
|
|
237
241
|
return result;
|
|
@@ -241,7 +245,7 @@ const applyBranchChange = (obj, change) => {
|
|
|
241
245
|
return applyArrayChange(obj, change);
|
|
242
246
|
}
|
|
243
247
|
else {
|
|
244
|
-
return applyChangeset(obj, change.changes);
|
|
248
|
+
return (0, exports.applyChangeset)(obj, change.changes);
|
|
245
249
|
}
|
|
246
250
|
};
|
|
247
251
|
const revertLeafChange = (obj, change, embeddedKey = '$index') => {
|
|
@@ -267,9 +271,9 @@ const revertArrayChange = (arr, change) => (() => {
|
|
|
267
271
|
element = arr[+subchange.key];
|
|
268
272
|
}
|
|
269
273
|
else {
|
|
270
|
-
element = find(arr, (el) => el[change.embeddedKey].toString() === subchange.key);
|
|
274
|
+
element = (0, lodash_1.find)(arr, (el) => el[change.embeddedKey].toString() === subchange.key);
|
|
271
275
|
}
|
|
272
|
-
result.push(revertChangeset(element, subchange.changes));
|
|
276
|
+
result.push((0, exports.revertChangeset)(element, subchange.changes));
|
|
273
277
|
}
|
|
274
278
|
}
|
|
275
279
|
return result;
|
|
@@ -279,11 +283,12 @@ const revertBranchChange = (obj, change) => {
|
|
|
279
283
|
return revertArrayChange(obj, change);
|
|
280
284
|
}
|
|
281
285
|
else {
|
|
282
|
-
return revertChangeset(obj, change.changes);
|
|
286
|
+
return (0, exports.revertChangeset)(obj, change.changes);
|
|
283
287
|
}
|
|
284
288
|
};
|
|
285
|
-
|
|
286
|
-
|
|
289
|
+
const diff = (oldObj, newObj, embeddedObjKeys) => compare(oldObj, newObj, [], embeddedObjKeys, []);
|
|
290
|
+
exports.diff = diff;
|
|
291
|
+
const applyChangeset = (obj, changeset) => {
|
|
287
292
|
if (changeset) {
|
|
288
293
|
changeset.forEach((change) => (change.value !== null && change.value !== undefined) || change.type === Operation.REMOVE
|
|
289
294
|
? applyLeafChange(obj, change, change.embeddedKey)
|
|
@@ -291,7 +296,8 @@ export const applyChangeset = (obj, changeset) => {
|
|
|
291
296
|
}
|
|
292
297
|
return obj;
|
|
293
298
|
};
|
|
294
|
-
|
|
299
|
+
exports.applyChangeset = applyChangeset;
|
|
300
|
+
const revertChangeset = (obj, changeset) => {
|
|
295
301
|
if (changeset) {
|
|
296
302
|
changeset
|
|
297
303
|
.reverse()
|
|
@@ -299,15 +305,16 @@ export const revertChangeset = (obj, changeset) => {
|
|
|
299
305
|
}
|
|
300
306
|
return obj;
|
|
301
307
|
};
|
|
302
|
-
|
|
308
|
+
exports.revertChangeset = revertChangeset;
|
|
309
|
+
var Operation;
|
|
303
310
|
(function (Operation) {
|
|
304
311
|
Operation["REMOVE"] = "REMOVE";
|
|
305
312
|
Operation["ADD"] = "ADD";
|
|
306
313
|
Operation["UPDATE"] = "UPDATE";
|
|
307
|
-
})(Operation || (Operation = {}));
|
|
308
|
-
|
|
314
|
+
})(Operation = exports.Operation || (exports.Operation = {}));
|
|
315
|
+
const flattenChangeset = (obj, path = '$', embeddedKey) => {
|
|
309
316
|
if (Array.isArray(obj)) {
|
|
310
|
-
return obj.reduce((memo, change) => [...memo, ...flattenChangeset(change, path, embeddedKey)], []);
|
|
317
|
+
return obj.reduce((memo, change) => [...memo, ...(0, exports.flattenChangeset)(change, path, embeddedKey)], []);
|
|
311
318
|
}
|
|
312
319
|
else {
|
|
313
320
|
if (obj.changes || embeddedKey) {
|
|
@@ -317,7 +324,7 @@ export const flattenChangeset = (obj, path = '$', embeddedKey) => {
|
|
|
317
324
|
}
|
|
318
325
|
else if (embeddedKey === '$value') {
|
|
319
326
|
path = `${path}[?(@='${obj.key}')]`;
|
|
320
|
-
const valueType = getTypeOfObj(obj.value);
|
|
327
|
+
const valueType = (0, exports.getTypeOfObj)(obj.value);
|
|
321
328
|
return [
|
|
322
329
|
Object.assign(Object.assign({}, obj), { path,
|
|
323
330
|
valueType })
|
|
@@ -330,17 +337,18 @@ export const flattenChangeset = (obj, path = '$', embeddedKey) => {
|
|
|
330
337
|
else {
|
|
331
338
|
path = `${path}.${obj.key}`;
|
|
332
339
|
}
|
|
333
|
-
return flattenChangeset(obj.changes || obj, path, obj.embeddedKey);
|
|
340
|
+
return (0, exports.flattenChangeset)(obj.changes || obj, path, obj.embeddedKey);
|
|
334
341
|
}
|
|
335
342
|
else {
|
|
336
|
-
const valueType = getTypeOfObj(obj.value);
|
|
343
|
+
const valueType = (0, exports.getTypeOfObj)(obj.value);
|
|
337
344
|
return [
|
|
338
345
|
Object.assign(Object.assign({}, obj), { path: valueType === 'Object' || path.endsWith(`[${obj.key}]`) ? path : `${path}.${obj.key}`, valueType })
|
|
339
346
|
];
|
|
340
347
|
}
|
|
341
348
|
}
|
|
342
349
|
};
|
|
343
|
-
|
|
350
|
+
exports.flattenChangeset = flattenChangeset;
|
|
351
|
+
const unflattenChanges = (changes) => {
|
|
344
352
|
if (!Array.isArray(changes)) {
|
|
345
353
|
changes = [changes];
|
|
346
354
|
}
|
|
@@ -455,3 +463,4 @@ export const unflattenChanges = (changes) => {
|
|
|
455
463
|
});
|
|
456
464
|
return changesArr;
|
|
457
465
|
};
|
|
466
|
+
exports.unflattenChanges = unflattenChanges;
|
package/package.json
CHANGED