json-diff-ts 3.0.0-beta.0 → 3.0.0-beta.2
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/dist/index.cjs +567 -0
- package/dist/index.cjs.map +1 -0
- package/{lib/jsonDiff.d.ts → dist/index.d.cts} +30 -13
- package/dist/index.d.ts +115 -0
- package/dist/index.js +528 -0
- package/dist/index.js.map +1 -0
- package/package.json +8 -6
- package/lib/index.d.ts +0 -2
- package/lib/index.js +0 -2
- package/lib/jsonCompare.d.ts +0 -15
- package/lib/jsonCompare.js +0 -68
- package/lib/jsonDiff.js +0 -564
package/dist/index.js
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
// src/jsonDiff.ts
|
|
2
|
+
import { difference, find, intersection, keyBy } from "lodash-es";
|
|
3
|
+
var Operation = /* @__PURE__ */ ((Operation2) => {
|
|
4
|
+
Operation2["REMOVE"] = "REMOVE";
|
|
5
|
+
Operation2["ADD"] = "ADD";
|
|
6
|
+
Operation2["UPDATE"] = "UPDATE";
|
|
7
|
+
return Operation2;
|
|
8
|
+
})(Operation || {});
|
|
9
|
+
function diff(oldObj, newObj, embeddedObjKeys, keysToSkip) {
|
|
10
|
+
if (embeddedObjKeys instanceof Map) {
|
|
11
|
+
embeddedObjKeys = new Map(
|
|
12
|
+
Array.from(embeddedObjKeys.entries()).map(([key, value]) => [
|
|
13
|
+
key instanceof RegExp ? key : key.replace(/^\./, ""),
|
|
14
|
+
value
|
|
15
|
+
])
|
|
16
|
+
);
|
|
17
|
+
} else if (embeddedObjKeys) {
|
|
18
|
+
embeddedObjKeys = Object.fromEntries(
|
|
19
|
+
Object.entries(embeddedObjKeys).map(([key, value]) => [key.replace(/^\./, ""), value])
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return compare(oldObj, newObj, [], embeddedObjKeys, [], keysToSkip);
|
|
23
|
+
}
|
|
24
|
+
var applyChangeset = (obj, changeset) => {
|
|
25
|
+
if (changeset) {
|
|
26
|
+
changeset.forEach((change) => {
|
|
27
|
+
const { type, key, value, embeddedKey } = change;
|
|
28
|
+
if (value !== null && value !== void 0 || type === "REMOVE" /* REMOVE */) {
|
|
29
|
+
applyLeafChange(obj, change, embeddedKey);
|
|
30
|
+
} else {
|
|
31
|
+
applyBranchChange(obj[key], change);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return obj;
|
|
36
|
+
};
|
|
37
|
+
var revertChangeset = (obj, changeset) => {
|
|
38
|
+
if (changeset) {
|
|
39
|
+
changeset.reverse().forEach(
|
|
40
|
+
(change) => !change.changes ? revertLeafChange(obj, change) : revertBranchChange(obj[change.key], change)
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return obj;
|
|
44
|
+
};
|
|
45
|
+
var flattenChangeset = (obj, path = "$", embeddedKey) => {
|
|
46
|
+
if (Array.isArray(obj)) {
|
|
47
|
+
return obj.reduce((memo, change) => [...memo, ...flattenChangeset(change, path, embeddedKey)], []);
|
|
48
|
+
} else {
|
|
49
|
+
if (obj.changes || embeddedKey) {
|
|
50
|
+
if (embeddedKey) {
|
|
51
|
+
if (embeddedKey === "$index") {
|
|
52
|
+
path = `${path}[${obj.key}]`;
|
|
53
|
+
} else if (embeddedKey === "$value") {
|
|
54
|
+
path = `${path}[?(@='${obj.key}')]`;
|
|
55
|
+
const valueType = getTypeOfObj(obj.value);
|
|
56
|
+
return [
|
|
57
|
+
{
|
|
58
|
+
...obj,
|
|
59
|
+
path,
|
|
60
|
+
valueType
|
|
61
|
+
}
|
|
62
|
+
];
|
|
63
|
+
} else if (obj.type === "ADD" /* ADD */) {
|
|
64
|
+
} else {
|
|
65
|
+
path = filterExpression(path, embeddedKey, obj.key);
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
path = append(path, obj.key);
|
|
69
|
+
}
|
|
70
|
+
return flattenChangeset(obj.changes || obj, path, obj.embeddedKey);
|
|
71
|
+
} else {
|
|
72
|
+
const valueType = getTypeOfObj(obj.value);
|
|
73
|
+
return [
|
|
74
|
+
{
|
|
75
|
+
...obj,
|
|
76
|
+
path: valueType === "Object" || path.endsWith(`[${obj.key}]`) ? path : append(path, obj.key),
|
|
77
|
+
valueType
|
|
78
|
+
}
|
|
79
|
+
];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var unflattenChanges = (changes) => {
|
|
84
|
+
if (!Array.isArray(changes)) {
|
|
85
|
+
changes = [changes];
|
|
86
|
+
}
|
|
87
|
+
const changesArr = [];
|
|
88
|
+
changes.forEach((change) => {
|
|
89
|
+
const obj = {};
|
|
90
|
+
let ptr = obj;
|
|
91
|
+
const segments = change.path.split(/(?<=[^@])\.(?=[^@])/);
|
|
92
|
+
if (segments.length === 1) {
|
|
93
|
+
ptr.key = change.key;
|
|
94
|
+
ptr.type = change.type;
|
|
95
|
+
ptr.value = change.value;
|
|
96
|
+
ptr.oldValue = change.oldValue;
|
|
97
|
+
changesArr.push(ptr);
|
|
98
|
+
} else {
|
|
99
|
+
for (let i = 1; i < segments.length; i++) {
|
|
100
|
+
const segment = segments[i];
|
|
101
|
+
const result = /^(.+?)\[\?\(@.?(?:([^=]*))?={1,2}'(.*)'\)\]$|^(.+?)\[(\d+)\]$/.exec(segment);
|
|
102
|
+
if (result) {
|
|
103
|
+
let key;
|
|
104
|
+
let embeddedKey;
|
|
105
|
+
let arrKey;
|
|
106
|
+
if (result[1]) {
|
|
107
|
+
key = result[1];
|
|
108
|
+
embeddedKey = result[2] || "$value";
|
|
109
|
+
arrKey = result[3];
|
|
110
|
+
} else {
|
|
111
|
+
key = result[4];
|
|
112
|
+
embeddedKey = "$index";
|
|
113
|
+
arrKey = Number(result[4]);
|
|
114
|
+
}
|
|
115
|
+
if (i === segments.length - 1) {
|
|
116
|
+
ptr.key = key;
|
|
117
|
+
ptr.embeddedKey = embeddedKey;
|
|
118
|
+
ptr.type = "UPDATE" /* UPDATE */;
|
|
119
|
+
ptr.changes = [
|
|
120
|
+
{
|
|
121
|
+
type: change.type,
|
|
122
|
+
key: arrKey,
|
|
123
|
+
value: change.value,
|
|
124
|
+
oldValue: change.oldValue
|
|
125
|
+
}
|
|
126
|
+
];
|
|
127
|
+
} else {
|
|
128
|
+
ptr.key = key;
|
|
129
|
+
ptr.embeddedKey = embeddedKey;
|
|
130
|
+
ptr.type = "UPDATE" /* UPDATE */;
|
|
131
|
+
const newPtr = {};
|
|
132
|
+
ptr.changes = [
|
|
133
|
+
{
|
|
134
|
+
type: "UPDATE" /* UPDATE */,
|
|
135
|
+
key: arrKey,
|
|
136
|
+
changes: [newPtr]
|
|
137
|
+
}
|
|
138
|
+
];
|
|
139
|
+
ptr = newPtr;
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
if (i === segments.length - 1) {
|
|
143
|
+
if (change.value !== null && change.valueType === "Object") {
|
|
144
|
+
ptr.key = segment;
|
|
145
|
+
ptr.type = "UPDATE" /* UPDATE */;
|
|
146
|
+
ptr.changes = [
|
|
147
|
+
{
|
|
148
|
+
key: change.key,
|
|
149
|
+
type: change.type,
|
|
150
|
+
value: change.value
|
|
151
|
+
}
|
|
152
|
+
];
|
|
153
|
+
} else {
|
|
154
|
+
ptr.key = change.key;
|
|
155
|
+
ptr.type = change.type;
|
|
156
|
+
ptr.value = change.value;
|
|
157
|
+
ptr.oldValue = change.oldValue;
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
ptr.key = segment;
|
|
161
|
+
ptr.type = "UPDATE" /* UPDATE */;
|
|
162
|
+
const newPtr = {};
|
|
163
|
+
ptr.changes = [newPtr];
|
|
164
|
+
ptr = newPtr;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
changesArr.push(obj);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
return changesArr;
|
|
172
|
+
};
|
|
173
|
+
var getTypeOfObj = (obj) => {
|
|
174
|
+
if (typeof obj === "undefined") {
|
|
175
|
+
return "undefined";
|
|
176
|
+
}
|
|
177
|
+
if (obj === null) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
|
|
181
|
+
};
|
|
182
|
+
var getKey = (path) => {
|
|
183
|
+
const left = path[path.length - 1];
|
|
184
|
+
return left != null ? left : "$root";
|
|
185
|
+
};
|
|
186
|
+
var compare = (oldObj, newObj, path, embeddedObjKeys, keyPath, keysToSkip) => {
|
|
187
|
+
let changes = [];
|
|
188
|
+
const typeOfOldObj = getTypeOfObj(oldObj);
|
|
189
|
+
const typeOfNewObj = getTypeOfObj(newObj);
|
|
190
|
+
if (typeOfOldObj !== typeOfNewObj) {
|
|
191
|
+
changes.push({ type: "REMOVE" /* REMOVE */, key: getKey(path), value: oldObj });
|
|
192
|
+
changes.push({ type: "ADD" /* ADD */, key: getKey(path), value: newObj });
|
|
193
|
+
return changes;
|
|
194
|
+
}
|
|
195
|
+
switch (typeOfOldObj) {
|
|
196
|
+
case "Date":
|
|
197
|
+
changes = changes.concat(
|
|
198
|
+
comparePrimitives(oldObj.getTime(), newObj.getTime(), path).map((x) => ({
|
|
199
|
+
...x,
|
|
200
|
+
value: new Date(x.value),
|
|
201
|
+
oldValue: new Date(x.oldValue)
|
|
202
|
+
}))
|
|
203
|
+
);
|
|
204
|
+
break;
|
|
205
|
+
case "Object":
|
|
206
|
+
const diffs = compareObject(oldObj, newObj, path, embeddedObjKeys, keyPath, false, keysToSkip);
|
|
207
|
+
if (diffs.length) {
|
|
208
|
+
if (path.length) {
|
|
209
|
+
changes.push({
|
|
210
|
+
type: "UPDATE" /* UPDATE */,
|
|
211
|
+
key: getKey(path),
|
|
212
|
+
changes: diffs
|
|
213
|
+
});
|
|
214
|
+
} else {
|
|
215
|
+
changes = changes.concat(diffs);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
case "Array":
|
|
220
|
+
changes = changes.concat(compareArray(oldObj, newObj, path, embeddedObjKeys, keyPath, keysToSkip));
|
|
221
|
+
break;
|
|
222
|
+
case "Function":
|
|
223
|
+
break;
|
|
224
|
+
default:
|
|
225
|
+
changes = changes.concat(comparePrimitives(oldObj, newObj, path));
|
|
226
|
+
}
|
|
227
|
+
return changes;
|
|
228
|
+
};
|
|
229
|
+
var compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath = false, keysToSkip = []) => {
|
|
230
|
+
let k;
|
|
231
|
+
let newKeyPath;
|
|
232
|
+
let newPath;
|
|
233
|
+
if (skipPath == null) {
|
|
234
|
+
skipPath = false;
|
|
235
|
+
}
|
|
236
|
+
let changes = [];
|
|
237
|
+
const oldObjKeys = Object.keys(oldObj).filter((key) => keysToSkip.indexOf(key) === -1);
|
|
238
|
+
const newObjKeys = Object.keys(newObj).filter((key) => keysToSkip.indexOf(key) === -1);
|
|
239
|
+
const intersectionKeys = intersection(oldObjKeys, newObjKeys);
|
|
240
|
+
for (k of intersectionKeys) {
|
|
241
|
+
newPath = path.concat([k]);
|
|
242
|
+
newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
|
|
243
|
+
const diffs = compare(oldObj[k], newObj[k], newPath, embeddedObjKeys, newKeyPath, keysToSkip);
|
|
244
|
+
if (diffs.length) {
|
|
245
|
+
changes = changes.concat(diffs);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const addedKeys = difference(newObjKeys, oldObjKeys);
|
|
249
|
+
for (k of addedKeys) {
|
|
250
|
+
newPath = path.concat([k]);
|
|
251
|
+
newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
|
|
252
|
+
changes.push({
|
|
253
|
+
type: "ADD" /* ADD */,
|
|
254
|
+
key: getKey(newPath),
|
|
255
|
+
value: newObj[k]
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
const deletedKeys = difference(oldObjKeys, newObjKeys);
|
|
259
|
+
for (k of deletedKeys) {
|
|
260
|
+
newPath = path.concat([k]);
|
|
261
|
+
newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
|
|
262
|
+
changes.push({
|
|
263
|
+
type: "REMOVE" /* REMOVE */,
|
|
264
|
+
key: getKey(newPath),
|
|
265
|
+
value: oldObj[k]
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return changes;
|
|
269
|
+
};
|
|
270
|
+
var compareArray = (oldObj, newObj, path, embeddedObjKeys, keyPath, keysToSkip) => {
|
|
271
|
+
const left = getObjectKey(embeddedObjKeys, keyPath);
|
|
272
|
+
const uniqKey = left != null ? left : "$index";
|
|
273
|
+
const indexedOldObj = convertArrayToObj(oldObj, uniqKey);
|
|
274
|
+
const indexedNewObj = convertArrayToObj(newObj, uniqKey);
|
|
275
|
+
const diffs = compareObject(indexedOldObj, indexedNewObj, path, embeddedObjKeys, keyPath, true, keysToSkip);
|
|
276
|
+
if (diffs.length) {
|
|
277
|
+
return [
|
|
278
|
+
{
|
|
279
|
+
type: "UPDATE" /* UPDATE */,
|
|
280
|
+
key: getKey(path),
|
|
281
|
+
embeddedKey: typeof uniqKey === "function" && uniqKey.length === 2 ? uniqKey(newObj[0], true) : uniqKey,
|
|
282
|
+
changes: diffs
|
|
283
|
+
}
|
|
284
|
+
];
|
|
285
|
+
} else {
|
|
286
|
+
return [];
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
var getObjectKey = (embeddedObjKeys, keyPath) => {
|
|
290
|
+
if (embeddedObjKeys != null) {
|
|
291
|
+
const path = keyPath.join(".");
|
|
292
|
+
if (embeddedObjKeys instanceof Map) {
|
|
293
|
+
for (const [key2, value] of embeddedObjKeys.entries()) {
|
|
294
|
+
if (key2 instanceof RegExp) {
|
|
295
|
+
if (path.match(key2)) {
|
|
296
|
+
return value;
|
|
297
|
+
}
|
|
298
|
+
} else if (path === key2) {
|
|
299
|
+
return value;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
const key = embeddedObjKeys[path];
|
|
304
|
+
if (key != null) {
|
|
305
|
+
return key;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return void 0;
|
|
309
|
+
};
|
|
310
|
+
var convertArrayToObj = (arr, uniqKey) => {
|
|
311
|
+
let obj = {};
|
|
312
|
+
if (uniqKey === "$value") {
|
|
313
|
+
arr.forEach((value) => {
|
|
314
|
+
obj[value] = value;
|
|
315
|
+
});
|
|
316
|
+
} else if (uniqKey !== "$index") {
|
|
317
|
+
obj = keyBy(arr, uniqKey);
|
|
318
|
+
} else {
|
|
319
|
+
for (let i = 0; i < arr.length; i++) {
|
|
320
|
+
const value = arr[i];
|
|
321
|
+
obj[i] = value;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return obj;
|
|
325
|
+
};
|
|
326
|
+
var comparePrimitives = (oldObj, newObj, path) => {
|
|
327
|
+
const changes = [];
|
|
328
|
+
if (oldObj !== newObj) {
|
|
329
|
+
changes.push({
|
|
330
|
+
type: "UPDATE" /* UPDATE */,
|
|
331
|
+
key: getKey(path),
|
|
332
|
+
value: newObj,
|
|
333
|
+
oldValue: oldObj
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
return changes;
|
|
337
|
+
};
|
|
338
|
+
var removeKey = (obj, key, embeddedKey) => {
|
|
339
|
+
if (Array.isArray(obj)) {
|
|
340
|
+
if (embeddedKey === "$index") {
|
|
341
|
+
obj.splice(key);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const index = indexOfItemInArray(obj, embeddedKey, key);
|
|
345
|
+
if (index === -1) {
|
|
346
|
+
console.warn(`Element with the key '${embeddedKey}' and value '${key}' could not be found in the array'`);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
return obj.splice(index != null ? index : key, 1);
|
|
350
|
+
} else {
|
|
351
|
+
obj[key] = void 0;
|
|
352
|
+
delete obj[key];
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
var indexOfItemInArray = (arr, key, value) => {
|
|
357
|
+
if (key === "$value") {
|
|
358
|
+
return arr.indexOf(value);
|
|
359
|
+
}
|
|
360
|
+
for (let i = 0; i < arr.length; i++) {
|
|
361
|
+
const item = arr[i];
|
|
362
|
+
if (item && item[key] ? item[key].toString() === value.toString() : void 0) {
|
|
363
|
+
return i;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return -1;
|
|
367
|
+
};
|
|
368
|
+
var modifyKeyValue = (obj, key, value) => obj[key] = value;
|
|
369
|
+
var addKeyValue = (obj, key, value) => {
|
|
370
|
+
if (Array.isArray(obj)) {
|
|
371
|
+
return obj.push(value);
|
|
372
|
+
} else {
|
|
373
|
+
return obj ? obj[key] = value : null;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
var applyLeafChange = (obj, change, embeddedKey) => {
|
|
377
|
+
const { type, key, value } = change;
|
|
378
|
+
switch (type) {
|
|
379
|
+
case "ADD" /* ADD */:
|
|
380
|
+
return addKeyValue(obj, key, value);
|
|
381
|
+
case "UPDATE" /* UPDATE */:
|
|
382
|
+
return modifyKeyValue(obj, key, value);
|
|
383
|
+
case "REMOVE" /* REMOVE */:
|
|
384
|
+
return removeKey(obj, key, embeddedKey);
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
var applyArrayChange = (arr, change) => (() => {
|
|
388
|
+
const result = [];
|
|
389
|
+
for (const subchange of change.changes) {
|
|
390
|
+
if (subchange.value != null || subchange.type === "REMOVE" /* REMOVE */) {
|
|
391
|
+
result.push(applyLeafChange(arr, subchange, change.embeddedKey));
|
|
392
|
+
} else {
|
|
393
|
+
let element;
|
|
394
|
+
if (change.embeddedKey === "$index") {
|
|
395
|
+
element = arr[subchange.key];
|
|
396
|
+
} else if (change.embeddedKey === "$value") {
|
|
397
|
+
const index = arr.indexOf(subchange.key);
|
|
398
|
+
if (index !== -1) {
|
|
399
|
+
element = arr[index];
|
|
400
|
+
}
|
|
401
|
+
} else {
|
|
402
|
+
element = find(arr, (el) => el[change.embeddedKey]?.toString() === subchange.key.toString());
|
|
403
|
+
}
|
|
404
|
+
result.push(applyChangeset(element, subchange.changes));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return result;
|
|
408
|
+
})();
|
|
409
|
+
var applyBranchChange = (obj, change) => {
|
|
410
|
+
if (Array.isArray(obj)) {
|
|
411
|
+
return applyArrayChange(obj, change);
|
|
412
|
+
} else {
|
|
413
|
+
return applyChangeset(obj, change.changes);
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
var revertLeafChange = (obj, change, embeddedKey = "$index") => {
|
|
417
|
+
const { type, key, value, oldValue } = change;
|
|
418
|
+
switch (type) {
|
|
419
|
+
case "ADD" /* ADD */:
|
|
420
|
+
return removeKey(obj, key, embeddedKey);
|
|
421
|
+
case "UPDATE" /* UPDATE */:
|
|
422
|
+
return modifyKeyValue(obj, key, oldValue);
|
|
423
|
+
case "REMOVE" /* REMOVE */:
|
|
424
|
+
return addKeyValue(obj, key, value);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
var revertArrayChange = (arr, change) => (() => {
|
|
428
|
+
const result = [];
|
|
429
|
+
for (const subchange of change.changes) {
|
|
430
|
+
if (subchange.value != null || subchange.type === "REMOVE" /* REMOVE */) {
|
|
431
|
+
result.push(revertLeafChange(arr, subchange, change.embeddedKey));
|
|
432
|
+
} else {
|
|
433
|
+
let element;
|
|
434
|
+
if (change.embeddedKey === "$index") {
|
|
435
|
+
element = arr[+subchange.key];
|
|
436
|
+
} else {
|
|
437
|
+
element = find(arr, (el) => el[change.embeddedKey].toString() === subchange.key);
|
|
438
|
+
}
|
|
439
|
+
result.push(revertChangeset(element, subchange.changes));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return result;
|
|
443
|
+
})();
|
|
444
|
+
var revertBranchChange = (obj, change) => {
|
|
445
|
+
if (Array.isArray(obj)) {
|
|
446
|
+
return revertArrayChange(obj, change);
|
|
447
|
+
} else {
|
|
448
|
+
return revertChangeset(obj, change.changes);
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
function append(basePath, nextSegment) {
|
|
452
|
+
return nextSegment.includes(".") ? `${basePath}[${nextSegment}]` : `${basePath}.${nextSegment}`;
|
|
453
|
+
}
|
|
454
|
+
function filterExpression(basePath, filterKey, filterValue) {
|
|
455
|
+
const value = typeof filterValue === "number" ? filterValue : `'${filterValue}'`;
|
|
456
|
+
return typeof filterKey === "string" && filterKey.includes(".") ? `${basePath}[?(@[${filterKey}]==${value})]` : `${basePath}[?(@.${filterKey}==${value})]`;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// src/jsonCompare.ts
|
|
460
|
+
import { chain, keys, replace, set } from "lodash-es";
|
|
461
|
+
var CompareOperation = /* @__PURE__ */ ((CompareOperation2) => {
|
|
462
|
+
CompareOperation2["CONTAINER"] = "CONTAINER";
|
|
463
|
+
CompareOperation2["UNCHANGED"] = "UNCHANGED";
|
|
464
|
+
return CompareOperation2;
|
|
465
|
+
})(CompareOperation || {});
|
|
466
|
+
var createValue = (value) => ({ type: "UNCHANGED" /* UNCHANGED */, value });
|
|
467
|
+
var createContainer = (value) => ({
|
|
468
|
+
type: "CONTAINER" /* CONTAINER */,
|
|
469
|
+
value
|
|
470
|
+
});
|
|
471
|
+
var enrich = (object) => {
|
|
472
|
+
const objectType = getTypeOfObj(object);
|
|
473
|
+
switch (objectType) {
|
|
474
|
+
case "Object":
|
|
475
|
+
return keys(object).map((key) => ({ key, value: enrich(object[key]) })).reduce((accumulator, entry) => {
|
|
476
|
+
accumulator.value[entry.key] = entry.value;
|
|
477
|
+
return accumulator;
|
|
478
|
+
}, createContainer({}));
|
|
479
|
+
case "Array":
|
|
480
|
+
return chain(object).map((value) => enrich(value)).reduce((accumulator, value) => {
|
|
481
|
+
accumulator.value.push(value);
|
|
482
|
+
return accumulator;
|
|
483
|
+
}, createContainer([])).value();
|
|
484
|
+
case "Function":
|
|
485
|
+
return void 0;
|
|
486
|
+
case "Date":
|
|
487
|
+
default:
|
|
488
|
+
return createValue(object);
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
var applyChangelist = (object, changelist) => {
|
|
492
|
+
chain(changelist).map((entry) => ({ ...entry, path: replace(entry.path, "$.", ".") })).map((entry) => ({
|
|
493
|
+
...entry,
|
|
494
|
+
path: replace(entry.path, /(\[(?<array>\d)\]\.)/g, "ARRVAL_START$<array>ARRVAL_END")
|
|
495
|
+
})).map((entry) => ({ ...entry, path: replace(entry.path, /(?<dot>\.)/g, ".value$<dot>") })).map((entry) => ({ ...entry, path: replace(entry.path, /\./, "") })).map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_START/g, ".value[") })).map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_END/g, "].value.") })).value().forEach((entry) => {
|
|
496
|
+
switch (entry.type) {
|
|
497
|
+
case "ADD" /* ADD */:
|
|
498
|
+
case "UPDATE" /* UPDATE */:
|
|
499
|
+
set(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });
|
|
500
|
+
break;
|
|
501
|
+
case "REMOVE" /* REMOVE */:
|
|
502
|
+
set(object, entry.path, { type: entry.type, value: void 0, oldValue: entry.value });
|
|
503
|
+
break;
|
|
504
|
+
default:
|
|
505
|
+
throw new Error();
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
return object;
|
|
509
|
+
};
|
|
510
|
+
var compare2 = (oldObject, newObject) => {
|
|
511
|
+
return applyChangelist(enrich(oldObject), flattenChangeset(diff(oldObject, newObject)));
|
|
512
|
+
};
|
|
513
|
+
export {
|
|
514
|
+
CompareOperation,
|
|
515
|
+
Operation,
|
|
516
|
+
applyChangelist,
|
|
517
|
+
applyChangeset,
|
|
518
|
+
compare2 as compare,
|
|
519
|
+
createContainer,
|
|
520
|
+
createValue,
|
|
521
|
+
diff,
|
|
522
|
+
enrich,
|
|
523
|
+
flattenChangeset,
|
|
524
|
+
getTypeOfObj,
|
|
525
|
+
revertChangeset,
|
|
526
|
+
unflattenChanges
|
|
527
|
+
};
|
|
528
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/jsonDiff.ts","../src/jsonCompare.ts"],"sourcesContent":["import { difference, find, intersection, keyBy } from 'lodash-es';\n\ntype FunctionKey = (obj: any, shouldReturnKeyName?: boolean) => any;\nexport type EmbeddedObjKeysType = Record<string, string | FunctionKey>;\nexport type EmbeddedObjKeysMapType = Map<string | RegExp, string | FunctionKey>;\nexport enum Operation {\n REMOVE = 'REMOVE',\n ADD = 'ADD',\n UPDATE = 'UPDATE'\n}\n\nexport interface IChange {\n type: Operation;\n key: string;\n embeddedKey?: string | FunctionKey;\n value?: any | any[];\n oldValue?: any;\n changes?: IChange[];\n}\nexport type Changeset = IChange[];\n\nexport interface IFlatChange {\n type: Operation;\n key: string;\n path: string;\n valueType: string | null;\n value?: any;\n oldValue?: any;\n}\n\n/**\n * Computes the difference between two objects.\n *\n * @param {any} oldObj - The original object.\n * @param {any} newObj - The updated object.\n * @param {EmbeddedObjKeysType | EmbeddedObjKeysMapType} embeddedObjKeys - An optional parameter specifying keys of embedded objects.\n * @returns {IChange[]} - An array of changes that transform the old object into the new object.\n */\nexport function diff(\n oldObj: any,\n newObj: any,\n embeddedObjKeys?: EmbeddedObjKeysType | EmbeddedObjKeysMapType,\n keysToSkip?: string[]\n): IChange[] {\n // Trim leading '.' from keys in embeddedObjKeys\n if (embeddedObjKeys instanceof Map) {\n embeddedObjKeys = new Map(\n Array.from(embeddedObjKeys.entries()).map(([key, value]) => [\n key instanceof RegExp ? key : key.replace(/^\\./, ''),\n value\n ])\n );\n } else if (embeddedObjKeys) {\n embeddedObjKeys = Object.fromEntries(\n Object.entries(embeddedObjKeys).map(([key, value]) => [key.replace(/^\\./, ''), value])\n );\n }\n\n // Compare old and new objects to generate a list of changes\n return compare(oldObj, newObj, [], embeddedObjKeys, [], keysToSkip);\n}\n\n/**\n * Applies all changes in the changeset to the object.\n *\n * @param {any} obj - The object to apply changes to.\n * @param {Changeset} changeset - The changeset to apply.\n * @returns {any} - The object after the changes from the changeset have been applied.\n *\n * The function first checks if a changeset is provided. If so, it iterates over each change in the changeset.\n * If the change value is not null or undefined, or if the change type is REMOVE, it applies the change to the object directly.\n * Otherwise, it applies the change to the corresponding branch of the object.\n */\nexport const applyChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset.forEach((change) => {\n const { type, key, value, embeddedKey } = change;\n\n if ((value !== null && value !== undefined) || type === Operation.REMOVE) {\n // Apply the change to the object\n applyLeafChange(obj, change, embeddedKey);\n } else {\n // Apply the change to the branch\n applyBranchChange(obj[key], change);\n }\n });\n }\n return obj;\n};\n\n/**\n * Reverts the changes made to an object based on a given changeset.\n *\n * @param {any} obj - The object on which to revert changes.\n * @param {Changeset} changeset - The changeset to revert.\n * @returns {any} - The object after the changes from the changeset have been reverted.\n *\n * The function first checks if a changeset is provided. If so, it reverses the changeset to start reverting from the last change.\n * It then iterates over each change in the changeset. If the change does not have any nested changes, it reverts the change on the object directly.\n * If the change does have nested changes, it reverts the changes on the corresponding branch of the object.\n */\nexport const revertChangeset = (obj: any, changeset: Changeset) => {\n if (changeset) {\n changeset\n .reverse()\n .forEach((change: IChange): any =>\n !change.changes ? revertLeafChange(obj, change) : revertBranchChange(obj[change.key], change)\n );\n }\n\n return obj;\n};\n\n/**\n * Flattens a changeset into an array of flat changes.\n *\n * @param {Changeset | IChange} obj - The changeset or change to flatten.\n * @param {string} [path='$'] - The current path in the changeset.\n * @param {string | FunctionKey} [embeddedKey] - The key to use for embedded objects.\n * @returns {IFlatChange[]} - An array of flat changes.\n *\n * The function first checks if the input is an array. If so, it recursively flattens each change in the array.\n * If the input is not an array, it checks if the change has nested changes or an embedded key.\n * If so, it updates the path and recursively flattens the nested changes or the embedded object.\n * If the change does not have nested changes or an embedded key, it creates a flat change and returns it in an array.\n */\nexport const flattenChangeset = (\n obj: Changeset | IChange,\n path = '$',\n embeddedKey?: string | FunctionKey\n): IFlatChange[] => {\n if (Array.isArray(obj)) {\n return obj.reduce((memo, change) => [...memo, ...flattenChangeset(change, path, embeddedKey)], [] as IFlatChange[]);\n } else {\n if (obj.changes || embeddedKey) {\n if (embeddedKey) {\n if (embeddedKey === '$index') {\n path = `${path}[${obj.key}]`;\n } else if (embeddedKey === '$value') {\n path = `${path}[?(@='${obj.key}')]`;\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path,\n valueType\n }\n ];\n } else if (obj.type === Operation.ADD) {\n // do nothing\n } else {\n path = filterExpression(path, embeddedKey, obj.key);\n }\n } else {\n path = append(path, obj.key);\n }\n\n return flattenChangeset(obj.changes || obj, path, obj.embeddedKey);\n } else {\n const valueType = getTypeOfObj(obj.value);\n return [\n {\n ...obj,\n path: valueType === 'Object' || path.endsWith(`[${obj.key}]`) ? path : append(path, obj.key),\n valueType\n }\n ];\n }\n }\n};\n\n/**\n * Transforms a flat changeset into a nested changeset.\n *\n * @param {IFlatChange | IFlatChange[]} changes - The flat changeset to unflatten.\n * @returns {IChange[]} - The unflattened changeset.\n *\n * The function first checks if the input is a single change or an array of changes.\n * It then iterates over each change and splits its path into segments.\n * For each segment, it checks if it represents an array or a leaf node.\n * If it represents an array, it creates a new change object and updates the pointer to this new object.\n * If it represents a leaf node, it sets the key, type, value, and oldValue of the current change object.\n * Finally, it pushes the unflattened change object into the changes array.\n */\nexport const unflattenChanges = (changes: IFlatChange | IFlatChange[]) => {\n if (!Array.isArray(changes)) {\n changes = [changes];\n }\n\n const changesArr: IChange[] = [];\n\n changes.forEach((change) => {\n const obj = {} as IChange;\n let ptr = obj;\n\n const segments = change.path.split(/(?<=[^@])\\.(?=[^@])/);\n\n if (segments.length === 1) {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n changesArr.push(ptr);\n } else {\n for (let i = 1; i < segments.length; i++) {\n const segment = segments[i];\n // Matches JSONPath segments: \"items[?(@.id=='123')]\", \"items[?(@.id==123)]\", \"items[2]\", \"items[?(@='123')]\"\n const result = /^(.+?)\\[\\?\\(@.?(?:([^=]*))?={1,2}'(.*)'\\)\\]$|^(.+?)\\[(\\d+)\\]$/.exec(segment); //NOSONAR\n // array\n if (result) {\n let key: string;\n let embeddedKey: string;\n let arrKey: string | number;\n if (result[1]) {\n key = result[1];\n embeddedKey = result[2] || '$value';\n arrKey = result[3];\n } else {\n key = result[4];\n embeddedKey = '$index';\n arrKey = Number(result[4]);\n }\n // leaf\n if (i === segments.length - 1) {\n ptr.key = key!;\n ptr.embeddedKey = embeddedKey!;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n type: change.type,\n key: arrKey!,\n value: change.value,\n oldValue: change.oldValue\n } as IChange\n ];\n } else {\n // object\n ptr.key = key;\n ptr.embeddedKey = embeddedKey;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [\n {\n type: Operation.UPDATE,\n key: arrKey,\n changes: [newPtr]\n } as IChange\n ];\n ptr = newPtr;\n }\n } else {\n // leaf\n if (i === segments.length - 1) {\n // check if value is a primitive or object\n if (change.value !== null && change.valueType === 'Object') {\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n ptr.changes = [\n {\n key: change.key,\n type: change.type,\n value: change.value\n } as IChange\n ];\n } else {\n ptr.key = change.key;\n ptr.type = change.type;\n ptr.value = change.value;\n ptr.oldValue = change.oldValue;\n }\n } else {\n // branch\n ptr.key = segment;\n ptr.type = Operation.UPDATE;\n const newPtr = {} as IChange;\n ptr.changes = [newPtr];\n ptr = newPtr;\n }\n }\n }\n changesArr.push(obj);\n }\n });\n return changesArr;\n};\n\n/**\n * Determines the type of a given object.\n *\n * @param {any} obj - The object whose type is to be determined.\n * @returns {string | null} - The type of the object, or null if the object is null.\n *\n * This function first checks if the object is undefined or null, and returns 'undefined' or null respectively.\n * If the object is neither undefined nor null, it uses Object.prototype.toString to get the object's type.\n * The type is extracted from the string returned by Object.prototype.toString using a regular expression.\n */\nexport const getTypeOfObj = (obj: any) => {\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n\n if (obj === null) {\n return null;\n }\n\n // Extracts the \"Type\" from \"[object Type]\" string.\n return Object.prototype.toString.call(obj).match(/^\\[object\\s(.*)\\]$/)[1];\n};\n\nconst getKey = (path: string) => {\n const left = path[path.length - 1];\n return left != null ? left : '$root';\n};\n\nconst compare = (oldObj: any, newObj: any, path: any, embeddedObjKeys: any, keyPath: any, keysToSkip: string[]) => {\n let changes: any[] = [];\n\n const typeOfOldObj = getTypeOfObj(oldObj);\n const typeOfNewObj = getTypeOfObj(newObj);\n\n // if type of object changes, consider it as old obj has been deleted and a new object has been added\n if (typeOfOldObj !== typeOfNewObj) {\n changes.push({ type: Operation.REMOVE, key: getKey(path), value: oldObj });\n changes.push({ type: Operation.ADD, key: getKey(path), value: newObj });\n return changes;\n }\n\n switch (typeOfOldObj) {\n case 'Date':\n changes = changes.concat(\n comparePrimitives(oldObj.getTime(), newObj.getTime(), path).map((x) => ({\n ...x,\n value: new Date(x.value),\n oldValue: new Date(x.oldValue)\n }))\n );\n break;\n case 'Object':\n const diffs = compareObject(oldObj, newObj, path, embeddedObjKeys, keyPath, false, keysToSkip);\n if (diffs.length) {\n if (path.length) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n changes: diffs\n });\n } else {\n changes = changes.concat(diffs);\n }\n }\n break;\n case 'Array':\n changes = changes.concat(compareArray(oldObj, newObj, path, embeddedObjKeys, keyPath, keysToSkip));\n break;\n case 'Function':\n break;\n // do nothing\n default:\n changes = changes.concat(comparePrimitives(oldObj, newObj, path));\n }\n\n return changes;\n};\n\nconst compareObject = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n skipPath = false,\n keysToSkip: string[] = []\n) => {\n let k;\n let newKeyPath;\n let newPath;\n\n if (skipPath == null) {\n skipPath = false;\n }\n let changes: any[] = [];\n\n const oldObjKeys = Object.keys(oldObj).filter((key) => keysToSkip.indexOf(key) === -1);\n const newObjKeys = Object.keys(newObj).filter((key) => keysToSkip.indexOf(key) === -1);\n\n const intersectionKeys = intersection(oldObjKeys, newObjKeys);\n for (k of intersectionKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n const diffs = compare(oldObj[k], newObj[k], newPath, embeddedObjKeys, newKeyPath, keysToSkip);\n if (diffs.length) {\n changes = changes.concat(diffs);\n }\n }\n\n const addedKeys = difference(newObjKeys, oldObjKeys);\n for (k of addedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.ADD,\n key: getKey(newPath),\n value: newObj[k]\n });\n }\n\n const deletedKeys = difference(oldObjKeys, newObjKeys);\n for (k of deletedKeys) {\n newPath = path.concat([k]);\n newKeyPath = skipPath ? keyPath : keyPath.concat([k]);\n changes.push({\n type: Operation.REMOVE,\n key: getKey(newPath),\n value: oldObj[k]\n });\n }\n return changes;\n};\n\nconst compareArray = (\n oldObj: any,\n newObj: any,\n path: any,\n embeddedObjKeys: any,\n keyPath: any,\n keysToSkip: string[]\n) => {\n const left = getObjectKey(embeddedObjKeys, keyPath);\n const uniqKey = left != null ? left : '$index';\n const indexedOldObj = convertArrayToObj(oldObj, uniqKey);\n const indexedNewObj = convertArrayToObj(newObj, uniqKey);\n const diffs = compareObject(indexedOldObj, indexedNewObj, path, embeddedObjKeys, keyPath, true, keysToSkip);\n if (diffs.length) {\n return [\n {\n type: Operation.UPDATE,\n key: getKey(path),\n embeddedKey: typeof uniqKey === 'function' && uniqKey.length === 2 ? uniqKey(newObj[0], true) : uniqKey,\n changes: diffs\n }\n ];\n } else {\n return [];\n }\n};\n\nconst getObjectKey = (embeddedObjKeys: any, keyPath: any) => {\n if (embeddedObjKeys != null) {\n const path = keyPath.join('.');\n\n if (embeddedObjKeys instanceof Map) {\n for (const [key, value] of embeddedObjKeys.entries()) {\n if (key instanceof RegExp) {\n if (path.match(key)) {\n return value;\n }\n } else if (path === key) {\n return value;\n }\n }\n }\n\n const key = embeddedObjKeys[path];\n if (key != null) {\n return key;\n }\n }\n return undefined;\n};\n\nconst convertArrayToObj = (arr: any[], uniqKey: any) => {\n let obj: any = {};\n if (uniqKey === '$value') {\n arr.forEach((value) => {\n obj[value] = value;\n });\n } else if (uniqKey !== '$index') {\n obj = keyBy(arr, uniqKey);\n } else {\n for (let i = 0; i < arr.length; i++) {\n const value = arr[i];\n obj[i] = value;\n }\n }\n return obj;\n};\n\nconst comparePrimitives = (oldObj: any, newObj: any, path: any) => {\n const changes = [];\n if (oldObj !== newObj) {\n changes.push({\n type: Operation.UPDATE,\n key: getKey(path),\n value: newObj,\n oldValue: oldObj\n });\n }\n return changes;\n};\n\nconst removeKey = (obj: any, key: any, embeddedKey: any) => {\n if (Array.isArray(obj)) {\n if (embeddedKey === '$index') {\n obj.splice(key);\n return;\n }\n const index = indexOfItemInArray(obj, embeddedKey, key);\n if (index === -1) {\n // tslint:disable-next-line:no-console\n console.warn(`Element with the key '${embeddedKey}' and value '${key}' could not be found in the array'`);\n return;\n }\n return obj.splice(index != null ? index : key, 1);\n } else {\n obj[key] = undefined;\n delete obj[key];\n return;\n }\n};\n\nconst indexOfItemInArray = (arr: any[], key: any, value: any) => {\n if (key === '$value') {\n return arr.indexOf(value);\n }\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n if (item && item[key] ? item[key].toString() === value.toString() : undefined) {\n return i;\n }\n }\n return -1;\n};\n\nconst modifyKeyValue = (obj: any, key: any, value: any) => (obj[key] = value);\n\nconst addKeyValue = (obj: any, key: any, value: any) => {\n if (Array.isArray(obj)) {\n return obj.push(value);\n } else {\n return obj ? (obj[key] = value) : null;\n }\n};\n\nconst applyLeafChange = (obj: any, change: any, embeddedKey: any) => {\n const { type, key, value } = change;\n switch (type) {\n case Operation.ADD:\n return addKeyValue(obj, key, value);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, value);\n case Operation.REMOVE:\n return removeKey(obj, key, embeddedKey);\n }\n};\n\nconst applyArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(applyLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[subchange.key];\n } else if (change.embeddedKey === '$value') {\n const index = arr.indexOf(subchange.key);\n if (index !== -1) {\n element = arr[index];\n }\n } else {\n element = find(arr, (el) => el[change.embeddedKey]?.toString() === subchange.key.toString());\n }\n result.push(applyChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst applyBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return applyArrayChange(obj, change);\n } else {\n return applyChangeset(obj, change.changes);\n }\n};\n\nconst revertLeafChange = (obj: any, change: any, embeddedKey = '$index') => {\n const { type, key, value, oldValue } = change;\n switch (type) {\n case Operation.ADD:\n return removeKey(obj, key, embeddedKey);\n case Operation.UPDATE:\n return modifyKeyValue(obj, key, oldValue);\n case Operation.REMOVE:\n return addKeyValue(obj, key, value);\n }\n};\n\nconst revertArrayChange = (arr: any, change: any) =>\n (() => {\n const result = [];\n for (const subchange of change.changes) {\n if (subchange.value != null || subchange.type === Operation.REMOVE) {\n result.push(revertLeafChange(arr, subchange, change.embeddedKey));\n } else {\n let element;\n if (change.embeddedKey === '$index') {\n element = arr[+subchange.key];\n } else {\n element = find(arr, (el) => el[change.embeddedKey].toString() === subchange.key);\n }\n result.push(revertChangeset(element, subchange.changes));\n }\n }\n return result;\n })();\n\nconst revertBranchChange = (obj: any, change: any) => {\n if (Array.isArray(obj)) {\n return revertArrayChange(obj, change);\n } else {\n return revertChangeset(obj, change.changes);\n }\n};\n\n/** combine a base JSON Path with a subsequent segment */\nfunction append(basePath: string, nextSegment: string): string {\n return nextSegment.includes('.') ? `${basePath}[${nextSegment}]` : `${basePath}.${nextSegment}`;\n}\n\n/** returns a JSON Path filter expression; e.g., `$.pet[(?name='spot')]` */\nfunction filterExpression(basePath: string, filterKey: string | FunctionKey, filterValue: string | number) {\n const value = typeof filterValue === 'number' ? filterValue : `'${filterValue}'`;\n return typeof filterKey === 'string' && filterKey.includes('.')\n ? `${basePath}[?(@[${filterKey}]==${value})]`\n : `${basePath}[?(@.${filterKey}==${value})]`;\n}\n","import { chain, keys, replace, set } from 'lodash-es';\nimport { diff, flattenChangeset, getTypeOfObj, IFlatChange, Operation } from './jsonDiff.js';\n\nexport enum CompareOperation {\n CONTAINER = 'CONTAINER',\n UNCHANGED = 'UNCHANGED'\n}\n\nexport interface IComparisonEnrichedNode {\n type: Operation | CompareOperation;\n value: IComparisonEnrichedNode | IComparisonEnrichedNode[] | any | any[];\n oldValue?: any;\n}\n\nexport const createValue = (value: any): IComparisonEnrichedNode => ({ type: CompareOperation.UNCHANGED, value });\nexport const createContainer = (value: object | []): IComparisonEnrichedNode => ({\n type: CompareOperation.CONTAINER,\n value\n});\n\nexport const enrich = (object: any): IComparisonEnrichedNode => {\n const objectType = getTypeOfObj(object);\n\n switch (objectType) {\n case 'Object':\n return keys(object)\n .map((key: string) => ({ key, value: enrich(object[key]) }))\n .reduce((accumulator, entry) => {\n accumulator.value[entry.key] = entry.value;\n return accumulator;\n }, createContainer({}));\n case 'Array':\n return chain(object)\n .map((value) => enrich(value))\n .reduce((accumulator, value) => {\n accumulator.value.push(value);\n return accumulator;\n }, createContainer([]))\n .value();\n case 'Function':\n return undefined;\n case 'Date':\n default:\n // Primitive value\n return createValue(object);\n }\n};\n\nexport const applyChangelist = (\n object: IComparisonEnrichedNode,\n changelist: IFlatChange[]\n): IComparisonEnrichedNode => {\n chain(changelist)\n .map((entry) => ({ ...entry, path: replace(entry.path, '$.', '.') }))\n .map((entry) => ({\n ...entry,\n path: replace(entry.path, /(\\[(?<array>\\d)\\]\\.)/g, 'ARRVAL_START$<array>ARRVAL_END')\n }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /(?<dot>\\.)/g, '.value$<dot>') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /\\./, '') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_START/g, '.value[') }))\n .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_END/g, '].value.') }))\n .value()\n .forEach((entry) => {\n switch (entry.type) {\n case Operation.ADD:\n case Operation.UPDATE:\n set(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });\n break;\n case Operation.REMOVE:\n set(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });\n break;\n default:\n throw new Error();\n }\n });\n return object;\n};\n\nexport const compare = (oldObject: any, newObject: any): IComparisonEnrichedNode => {\n return applyChangelist(enrich(oldObject), flattenChangeset(diff(oldObject, newObject)));\n};\n"],"mappings":"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","names":["Operation","key","CompareOperation","compare"]}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-diff-ts",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.2",
|
|
4
4
|
"description": "A JSON diff tool for JavaScript written in TypeScript.",
|
|
5
|
-
"main": "
|
|
6
|
-
"
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
7
8
|
"type": "module",
|
|
8
9
|
"scripts": {
|
|
9
|
-
"build": "
|
|
10
|
+
"build": "tsup",
|
|
10
11
|
"format": "prettier --write \"src/**/*.ts\"",
|
|
11
12
|
"lint": "eslint 'src/**/*.ts'",
|
|
12
13
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.mjs",
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
"postversion": "git push && git push --tags"
|
|
19
20
|
},
|
|
20
21
|
"files": [
|
|
21
|
-
"
|
|
22
|
+
"dist"
|
|
22
23
|
],
|
|
23
24
|
"repository": {
|
|
24
25
|
"type": "git",
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"jest": "^29.7.0",
|
|
49
50
|
"prettier": "^3.0.3",
|
|
50
51
|
"ts-jest": "^29.0.5",
|
|
52
|
+
"tsup": "^8.0.2",
|
|
51
53
|
"typescript": "^5.3.2"
|
|
52
54
|
}
|
|
53
|
-
}
|
|
55
|
+
}
|
package/lib/index.d.ts
DELETED
package/lib/index.js
DELETED
package/lib/jsonCompare.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { IFlatChange, Operation } from './jsonDiff.js';
|
|
2
|
-
export declare enum CompareOperation {
|
|
3
|
-
CONTAINER = "CONTAINER",
|
|
4
|
-
UNCHANGED = "UNCHANGED"
|
|
5
|
-
}
|
|
6
|
-
export interface IComparisonEnrichedNode {
|
|
7
|
-
type: Operation | CompareOperation;
|
|
8
|
-
value: IComparisonEnrichedNode | IComparisonEnrichedNode[] | any | any[];
|
|
9
|
-
oldValue?: any;
|
|
10
|
-
}
|
|
11
|
-
export declare const createValue: (value: any) => IComparisonEnrichedNode;
|
|
12
|
-
export declare const createContainer: (value: object | []) => IComparisonEnrichedNode;
|
|
13
|
-
export declare const enrich: (object: any) => IComparisonEnrichedNode;
|
|
14
|
-
export declare const applyChangelist: (object: IComparisonEnrichedNode, changelist: IFlatChange[]) => IComparisonEnrichedNode;
|
|
15
|
-
export declare const compare: (oldObject: any, newObject: any) => IComparisonEnrichedNode;
|