json-diff-ts 1.2.0 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -108
- package/lib/index.js +12 -5
- package/lib/jsonCompare.js +29 -23
- package/lib/jsonDiff.d.ts +5 -3
- package/lib/jsonDiff.js +29 -22
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
# json-diff-ts
|
|
2
2
|
|
|
3
|
-

|
|
3
|
+

|
|
4
4
|
[](https://snyk.io/test/github/ltwlf/json-diff-ts?targetFile=package.json)
|
|
5
5
|
[](https://sonarcloud.io/dashboard?id=ltwlf_json-diff-ts)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
The most compelling feature of this diff library is the support for array keys instead of just indexes and is compatible with JSONPath.
|
|
7
|
+
TypeScript diff tool with support for array keys instead of just indexes and compatible with JSONPath.
|
|
10
8
|
|
|
11
9
|
## Features
|
|
12
10
|
|
|
@@ -17,60 +15,70 @@ If a key is specified for an embedded array, the diff will be generated based on
|
|
|
17
15
|
#### Examples:
|
|
18
16
|
|
|
19
17
|
```javascript
|
|
18
|
+
var changesets = require('json-diff-ts');
|
|
19
|
+
var newObj, oldObj;
|
|
20
|
+
|
|
21
|
+
oldObj = {
|
|
22
|
+
name: 'joe',
|
|
23
|
+
age: 55,
|
|
24
|
+
coins: [2, 5],
|
|
25
|
+
children: [
|
|
26
|
+
{ name: 'kid1', age: 1 },
|
|
27
|
+
{ name: 'kid2', age: 2 }
|
|
28
|
+
]
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
newObj = {
|
|
32
|
+
name: 'smith',
|
|
33
|
+
coins: [2, 5, 1],
|
|
34
|
+
children: [
|
|
35
|
+
{ name: 'kid3', age: 3 },
|
|
36
|
+
{ name: 'kid1', age: 0 },
|
|
37
|
+
{ name: 'kid2', age: 2 }
|
|
38
|
+
]
|
|
39
|
+
};
|
|
20
40
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
name: 'joe',
|
|
26
|
-
age: 55,
|
|
27
|
-
coins: [2, 5],
|
|
28
|
-
children: [
|
|
29
|
-
{name: 'kid1', age: 1},
|
|
30
|
-
{name: 'kid2', age: 2}
|
|
31
|
-
]};
|
|
32
|
-
|
|
33
|
-
newObj = {
|
|
34
|
-
name: 'smith',
|
|
35
|
-
coins: [2, 5, 1],
|
|
36
|
-
children: [
|
|
37
|
-
{name: 'kid3', age: 3},
|
|
38
|
-
{name: 'kid1', age: 0},
|
|
39
|
-
{name: 'kid2', age: 2}
|
|
40
|
-
]};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// Assume children is an array of child object and the child object has 'name' as its primary key
|
|
44
|
-
diffs = changesets.diff(oldObj, newObj, {children: 'name'}); // keys can also be hierarchical e.g. {children: 'name', 'children.grandChildren', 'age'}
|
|
41
|
+
// Assume children is an array of child object and the child object has 'name' as its primary key
|
|
42
|
+
// keys can also be hierarchical e.g. {children: 'name', 'children.grandChildren', 'age'}
|
|
43
|
+
// or use functions that return the key of an object e.g. {children: function(obj) { return obj.key; }}
|
|
44
|
+
diffs = changesets.diff(oldObj, newObj, { children: 'name' });
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
46
|
+
expect(diffs).to.eql([
|
|
47
|
+
{
|
|
48
|
+
type: 'update',
|
|
49
|
+
key: 'name',
|
|
50
|
+
value: 'smith',
|
|
51
|
+
oldValue: 'joe'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'update',
|
|
55
|
+
key: 'coins',
|
|
56
|
+
embededKey: '$index',
|
|
57
|
+
changes: [{ type: 'add', key: '2', value: 1 }]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: 'update',
|
|
61
|
+
key: 'children',
|
|
62
|
+
embededKey: 'name',
|
|
63
|
+
changes: [
|
|
64
|
+
{
|
|
65
|
+
type: 'update',
|
|
66
|
+
key: 'kid1',
|
|
67
|
+
changes: [{ type: 'update', key: 'age', value: 0, oldValue: 1 }]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: 'add',
|
|
71
|
+
key: 'kid3',
|
|
72
|
+
value: { name: 'kid3', age: 3 }
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: 'remove',
|
|
78
|
+
key: 'age',
|
|
79
|
+
value: 55
|
|
80
|
+
}
|
|
81
|
+
]);
|
|
74
82
|
```
|
|
75
83
|
|
|
76
84
|
### flattenChangeset
|
|
@@ -132,58 +140,65 @@ The **flatChange** format will look like this:
|
|
|
132
140
|
#### Examples:
|
|
133
141
|
|
|
134
142
|
```javascript
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
{name: 'kid2', age: 2}
|
|
144
|
-
]};
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
// Assume children is an array of child object and the child object has 'name' as its primary key
|
|
148
|
-
diffs = [
|
|
149
|
-
{
|
|
150
|
-
type: 'update', key: 'name', value: 'smith', oldValue: 'joe'
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
type: 'update', key: 'coins', embededKey: '$index', changes: [
|
|
154
|
-
{type: 'add', key: '2', value: 1 }
|
|
155
|
-
]
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
type: 'update',
|
|
159
|
-
key: 'children',
|
|
160
|
-
embededKey: 'name', // The key property name of the elements in an array
|
|
161
|
-
changes: [
|
|
162
|
-
{
|
|
163
|
-
type: 'update', key: 'kid1', changes: [
|
|
164
|
-
{type: 'update', key: 'age', value: 0, oldValue: 1 }
|
|
165
|
-
]
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
type: 'add', key: 'kid3', value: {name: 'kid3', age: 3 }
|
|
169
|
-
}
|
|
170
|
-
]
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
type: 'remove', key: 'age', value: 55
|
|
174
|
-
}
|
|
143
|
+
var changesets = require('json-diff-ts');
|
|
144
|
+
var oldObj = {
|
|
145
|
+
name: 'joe',
|
|
146
|
+
age: 55,
|
|
147
|
+
coins: [2, 5],
|
|
148
|
+
children: [
|
|
149
|
+
{ name: 'kid1', age: 1 },
|
|
150
|
+
{ name: 'kid2', age: 2 }
|
|
175
151
|
]
|
|
152
|
+
};
|
|
176
153
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
154
|
+
// Assume children is an array of child object and the child object has 'name' as its primary key
|
|
155
|
+
diffs = [
|
|
156
|
+
{
|
|
157
|
+
type: 'update',
|
|
158
|
+
key: 'name',
|
|
159
|
+
value: 'smith',
|
|
160
|
+
oldValue: 'joe'
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: 'update',
|
|
164
|
+
key: 'coins',
|
|
165
|
+
embededKey: '$index',
|
|
166
|
+
changes: [{ type: 'add', key: '2', value: 1 }]
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
type: 'update',
|
|
170
|
+
key: 'children',
|
|
171
|
+
embededKey: 'name', // The key property name of the elements in an array
|
|
172
|
+
changes: [
|
|
173
|
+
{
|
|
174
|
+
type: 'update',
|
|
175
|
+
key: 'kid1',
|
|
176
|
+
changes: [{ type: 'update', key: 'age', value: 0, oldValue: 1 }]
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
type: 'add',
|
|
180
|
+
key: 'kid3',
|
|
181
|
+
value: { name: 'kid3', age: 3 }
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
type: 'remove',
|
|
187
|
+
key: 'age',
|
|
188
|
+
value: 55
|
|
189
|
+
}
|
|
190
|
+
];
|
|
186
191
|
|
|
192
|
+
changesets.applyChanges(oldObj, diffs);
|
|
193
|
+
expect(oldObj).to.eql({
|
|
194
|
+
name: 'smith',
|
|
195
|
+
coins: [2, 5, 1],
|
|
196
|
+
children: [
|
|
197
|
+
{ name: 'kid3', age: 3 },
|
|
198
|
+
{ name: 'kid1', age: 0 },
|
|
199
|
+
{ name: 'kid2', age: 2 }
|
|
200
|
+
]
|
|
201
|
+
});
|
|
187
202
|
```
|
|
188
203
|
|
|
189
204
|
### revertChange
|
|
@@ -192,7 +207,7 @@ The **flatChange** format will look like this:
|
|
|
192
207
|
|
|
193
208
|
```javascript
|
|
194
209
|
|
|
195
|
-
var changesets = require('diff-
|
|
210
|
+
var changesets = require('json-diff-ts');
|
|
196
211
|
|
|
197
212
|
var newObj = {
|
|
198
213
|
name: 'smith',
|
|
@@ -248,7 +263,7 @@ The **flatChange** format will look like this:
|
|
|
248
263
|
## Get started
|
|
249
264
|
|
|
250
265
|
```
|
|
251
|
-
npm install diff-
|
|
266
|
+
npm install json-diff-ts
|
|
252
267
|
```
|
|
253
268
|
|
|
254
269
|
## Run the test
|
|
@@ -258,10 +273,20 @@ npm run test
|
|
|
258
273
|
```
|
|
259
274
|
|
|
260
275
|
## Contact
|
|
276
|
+
|
|
261
277
|
Blog: https://blog.leitwolf.io
|
|
262
278
|
|
|
263
279
|
Twitter: [@cglessner](https://twitter.com/cglessner)
|
|
264
280
|
|
|
281
|
+
## Changelog
|
|
282
|
+
|
|
283
|
+
- v1.2.4 Fix readme (npm install); update TypeScript and Lodash
|
|
284
|
+
- v1.2.3 Update outdated dependencies; update TypeScript version to 4.5.2
|
|
285
|
+
- v1.2.2 Add support for functions to resove object keys (PR by [Abraxxa](https://github.com/abraxxa))
|
|
286
|
+
|
|
287
|
+
## Credits
|
|
288
|
+
|
|
289
|
+
This project was based on https://www.npmjs.com/package/diff-json (viruschidai@gmail.com)
|
|
265
290
|
|
|
266
291
|
## Licence
|
|
267
292
|
|
|
@@ -275,7 +300,7 @@ The above copyright notice and this permission notice shall be included in all c
|
|
|
275
300
|
|
|
276
301
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
277
302
|
|
|
278
|
-
The project is based on diff-json (https://www.npmjs.com/package/diff-json). Copyright 2013 viruschidai@gmail.com. for additional details.
|
|
303
|
+
The project is based on diff-json (https://www.npmjs.com/package/diff-json). Copyright 2013 viruschidai@gmail.com. for additional details.
|
|
279
304
|
|
|
280
305
|
**Original License**
|
|
281
306
|
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
function
|
|
3
|
-
|
|
4
|
-
}
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
5
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
|
|
7
|
-
|
|
13
|
+
__exportStar(require("./jsonDiff"), exports);
|
|
14
|
+
__exportStar(require("./jsonCompare"), exports);
|
package/lib/jsonCompare.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compare = exports.applyChangelist = exports.enrich = exports.createContainer = exports.createValue = exports.CompareOperation = void 0;
|
|
3
4
|
const lodash_1 = require("lodash");
|
|
4
5
|
const jsonDiff_1 = require("./jsonDiff");
|
|
5
6
|
var CompareOperation;
|
|
@@ -7,54 +8,57 @@ var CompareOperation;
|
|
|
7
8
|
CompareOperation["CONTAINER"] = "CONTAINER";
|
|
8
9
|
CompareOperation["UNCHANGED"] = "UNCHANGED";
|
|
9
10
|
})(CompareOperation = exports.CompareOperation || (exports.CompareOperation = {}));
|
|
10
|
-
|
|
11
|
-
exports.
|
|
11
|
+
const createValue = (value) => ({ type: CompareOperation.UNCHANGED, value });
|
|
12
|
+
exports.createValue = createValue;
|
|
13
|
+
const createContainer = (value) => ({
|
|
12
14
|
type: CompareOperation.CONTAINER,
|
|
13
15
|
value
|
|
14
16
|
});
|
|
15
|
-
exports.
|
|
16
|
-
|
|
17
|
+
exports.createContainer = createContainer;
|
|
18
|
+
const enrich = (object) => {
|
|
19
|
+
const objectType = (0, jsonDiff_1.getTypeOfObj)(object);
|
|
17
20
|
switch (objectType) {
|
|
18
21
|
case 'Object':
|
|
19
|
-
return lodash_1.keys(object)
|
|
20
|
-
.map((key) => ({ key, value: exports.enrich(object[key]) }))
|
|
22
|
+
return (0, lodash_1.keys)(object)
|
|
23
|
+
.map((key) => ({ key, value: (0, exports.enrich)(object[key]) }))
|
|
21
24
|
.reduce((accumulator, entry) => {
|
|
22
25
|
accumulator.value[entry.key] = entry.value;
|
|
23
26
|
return accumulator;
|
|
24
|
-
}, exports.createContainer({}));
|
|
27
|
+
}, (0, exports.createContainer)({}));
|
|
25
28
|
case 'Array':
|
|
26
|
-
return lodash_1.chain(object)
|
|
27
|
-
.map(value => exports.enrich(value))
|
|
29
|
+
return (0, lodash_1.chain)(object)
|
|
30
|
+
.map(value => (0, exports.enrich)(value))
|
|
28
31
|
.reduce((accumulator, value) => {
|
|
29
32
|
accumulator.value.push(value);
|
|
30
33
|
return accumulator;
|
|
31
|
-
}, exports.createContainer([]))
|
|
34
|
+
}, (0, exports.createContainer)([]))
|
|
32
35
|
.value();
|
|
33
36
|
case 'Function':
|
|
34
37
|
return undefined;
|
|
35
38
|
case 'Date':
|
|
36
39
|
default:
|
|
37
40
|
// Primitive value
|
|
38
|
-
return exports.createValue(object);
|
|
41
|
+
return (0, exports.createValue)(object);
|
|
39
42
|
}
|
|
40
43
|
};
|
|
41
|
-
exports.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.map(entry => (Object.assign(Object.assign({}, entry), { path: lodash_1.replace(entry.path,
|
|
45
|
-
.map(entry => (Object.assign(Object.assign({}, entry), { path: lodash_1.replace(entry.path, /(?<
|
|
46
|
-
.map(entry => (Object.assign(Object.assign({}, entry), { path: lodash_1.replace(entry.path,
|
|
47
|
-
.map(entry => (Object.assign(Object.assign({}, entry), { path: lodash_1.replace(entry.path,
|
|
48
|
-
.map(entry => (Object.assign(Object.assign({}, entry), { path: lodash_1.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.') })))
|
|
49
53
|
.value()
|
|
50
54
|
.forEach(entry => {
|
|
51
55
|
switch (entry.type) {
|
|
52
56
|
case jsonDiff_1.Operation.ADD:
|
|
53
57
|
case jsonDiff_1.Operation.UPDATE:
|
|
54
|
-
lodash_1.set(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });
|
|
58
|
+
(0, lodash_1.set)(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });
|
|
55
59
|
break;
|
|
56
60
|
case jsonDiff_1.Operation.REMOVE:
|
|
57
|
-
lodash_1.set(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });
|
|
61
|
+
(0, lodash_1.set)(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });
|
|
58
62
|
break;
|
|
59
63
|
default:
|
|
60
64
|
throw new Error();
|
|
@@ -62,6 +66,8 @@ exports.applyChangelist = (object, changelist) => {
|
|
|
62
66
|
});
|
|
63
67
|
return object;
|
|
64
68
|
};
|
|
65
|
-
exports.
|
|
66
|
-
|
|
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)));
|
|
67
72
|
};
|
|
73
|
+
exports.compare = compare;
|
package/lib/jsonDiff.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Dictionary } from 'lodash';
|
|
2
|
+
declare type FunctionKey = (obj: any) => any;
|
|
2
3
|
export declare const getTypeOfObj: (obj: any) => string;
|
|
3
|
-
export declare const diff: (oldObj: any, newObj: any, embeddedObjKeys?: Dictionary<string>) => IChange[];
|
|
4
|
+
export declare const diff: (oldObj: any, newObj: any, embeddedObjKeys?: Dictionary<string | FunctionKey>) => IChange[];
|
|
4
5
|
export declare const applyChangeset: (obj: any, changeset: Changeset) => any;
|
|
5
6
|
export declare const revertChangeset: (obj: any, changeset: Changeset) => any;
|
|
6
7
|
export declare enum Operation {
|
|
@@ -11,7 +12,7 @@ export declare enum Operation {
|
|
|
11
12
|
export interface IChange {
|
|
12
13
|
type: Operation;
|
|
13
14
|
key: string;
|
|
14
|
-
embeddedKey?: string;
|
|
15
|
+
embeddedKey?: string | FunctionKey;
|
|
15
16
|
value?: any | any[];
|
|
16
17
|
oldValue?: any;
|
|
17
18
|
changes?: IChange[];
|
|
@@ -25,5 +26,6 @@ export interface IFlatChange {
|
|
|
25
26
|
value?: any;
|
|
26
27
|
oldValue?: any;
|
|
27
28
|
}
|
|
28
|
-
export declare const flattenChangeset: (obj:
|
|
29
|
+
export declare const flattenChangeset: (obj: Changeset | IChange, path?: string, embeddedKey?: string | FunctionKey) => IFlatChange[];
|
|
29
30
|
export declare const unflattenChanges: (changes: IFlatChange | IFlatChange[]) => IChange[];
|
|
31
|
+
export {};
|
package/lib/jsonDiff.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unflattenChanges = exports.flattenChangeset = exports.Operation = exports.revertChangeset = exports.applyChangeset = exports.diff = exports.getTypeOfObj = void 0;
|
|
3
4
|
const lodash_1 = require("lodash");
|
|
4
|
-
|
|
5
|
+
const getTypeOfObj = (obj) => {
|
|
5
6
|
if (typeof obj === 'undefined') {
|
|
6
7
|
return 'undefined';
|
|
7
8
|
}
|
|
@@ -10,14 +11,15 @@ exports.getTypeOfObj = (obj) => {
|
|
|
10
11
|
}
|
|
11
12
|
return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
|
|
12
13
|
};
|
|
14
|
+
exports.getTypeOfObj = getTypeOfObj;
|
|
13
15
|
const getKey = (path) => {
|
|
14
16
|
const left = path[path.length - 1];
|
|
15
17
|
return left != null ? left : '$root';
|
|
16
18
|
};
|
|
17
19
|
const compare = (oldObj, newObj, path, embeddedObjKeys, keyPath) => {
|
|
18
20
|
let changes = [];
|
|
19
|
-
const typeOfOldObj = exports.getTypeOfObj(oldObj);
|
|
20
|
-
const typeOfNewObj = exports.getTypeOfObj(newObj);
|
|
21
|
+
const typeOfOldObj = (0, exports.getTypeOfObj)(oldObj);
|
|
22
|
+
const typeOfNewObj = (0, exports.getTypeOfObj)(newObj);
|
|
21
23
|
// if type of object changes, consider it as old obj has been deleted and a new object has been added
|
|
22
24
|
if (typeOfOldObj !== typeOfNewObj) {
|
|
23
25
|
changes.push({ type: Operation.REMOVE, key: getKey(path), value: oldObj });
|
|
@@ -64,7 +66,7 @@ const compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath
|
|
|
64
66
|
let changes = [];
|
|
65
67
|
const oldObjKeys = Object.keys(oldObj);
|
|
66
68
|
const newObjKeys = Object.keys(newObj);
|
|
67
|
-
const intersectionKeys = lodash_1.intersection(oldObjKeys, newObjKeys);
|
|
69
|
+
const intersectionKeys = (0, lodash_1.intersection)(oldObjKeys, newObjKeys);
|
|
68
70
|
for (k of intersectionKeys) {
|
|
69
71
|
newPath = path.concat([k]);
|
|
70
72
|
newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
|
|
@@ -73,7 +75,7 @@ const compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath
|
|
|
73
75
|
changes = changes.concat(diffs);
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
|
-
const addedKeys = lodash_1.difference(newObjKeys, oldObjKeys);
|
|
78
|
+
const addedKeys = (0, lodash_1.difference)(newObjKeys, oldObjKeys);
|
|
77
79
|
for (k of addedKeys) {
|
|
78
80
|
newPath = path.concat([k]);
|
|
79
81
|
newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
|
|
@@ -83,7 +85,7 @@ const compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath
|
|
|
83
85
|
value: newObj[k]
|
|
84
86
|
});
|
|
85
87
|
}
|
|
86
|
-
const deletedKeys = lodash_1.difference(oldObjKeys, newObjKeys);
|
|
88
|
+
const deletedKeys = (0, lodash_1.difference)(oldObjKeys, newObjKeys);
|
|
87
89
|
for (k of deletedKeys) {
|
|
88
90
|
newPath = path.concat([k]);
|
|
89
91
|
newKeyPath = skipPath ? keyPath : keyPath.concat([k]);
|
|
@@ -133,7 +135,7 @@ const getObjectKey = (embeddedObjKeys, keyPath) => {
|
|
|
133
135
|
const convertArrayToObj = (arr, uniqKey) => {
|
|
134
136
|
let obj = {};
|
|
135
137
|
if (uniqKey !== '$index') {
|
|
136
|
-
obj = lodash_1.keyBy(arr, uniqKey);
|
|
138
|
+
obj = (0, lodash_1.keyBy)(arr, uniqKey);
|
|
137
139
|
}
|
|
138
140
|
else {
|
|
139
141
|
for (let i = 0; i < arr.length; i++) {
|
|
@@ -217,9 +219,9 @@ const applyArrayChange = (arr, change) => (() => {
|
|
|
217
219
|
element = arr[subchange.key];
|
|
218
220
|
}
|
|
219
221
|
else {
|
|
220
|
-
element = lodash_1.find(arr, el => el[change.embeddedKey].toString() === subchange.key.toString());
|
|
222
|
+
element = (0, lodash_1.find)(arr, el => el[change.embeddedKey].toString() === subchange.key.toString());
|
|
221
223
|
}
|
|
222
|
-
result.push(exports.applyChangeset(element, subchange.changes));
|
|
224
|
+
result.push((0, exports.applyChangeset)(element, subchange.changes));
|
|
223
225
|
}
|
|
224
226
|
}
|
|
225
227
|
return result;
|
|
@@ -229,7 +231,7 @@ const applyBranchChange = (obj, change) => {
|
|
|
229
231
|
return applyArrayChange(obj, change);
|
|
230
232
|
}
|
|
231
233
|
else {
|
|
232
|
-
return exports.applyChangeset(obj, change.changes);
|
|
234
|
+
return (0, exports.applyChangeset)(obj, change.changes);
|
|
233
235
|
}
|
|
234
236
|
};
|
|
235
237
|
const revertLeafChange = (obj, change, embeddedKey = '$index') => {
|
|
@@ -255,9 +257,9 @@ const revertArrayChange = (arr, change) => (() => {
|
|
|
255
257
|
element = arr[+subchange.key];
|
|
256
258
|
}
|
|
257
259
|
else {
|
|
258
|
-
element = lodash_1.find(arr, el => el[change.embeddedKey].toString() === subchange.key);
|
|
260
|
+
element = (0, lodash_1.find)(arr, el => el[change.embeddedKey].toString() === subchange.key);
|
|
259
261
|
}
|
|
260
|
-
result.push(exports.revertChangeset(element, subchange.changes));
|
|
262
|
+
result.push((0, exports.revertChangeset)(element, subchange.changes));
|
|
261
263
|
}
|
|
262
264
|
}
|
|
263
265
|
return result;
|
|
@@ -267,11 +269,12 @@ const revertBranchChange = (obj, change) => {
|
|
|
267
269
|
return revertArrayChange(obj, change);
|
|
268
270
|
}
|
|
269
271
|
else {
|
|
270
|
-
return exports.revertChangeset(obj, change.changes);
|
|
272
|
+
return (0, exports.revertChangeset)(obj, change.changes);
|
|
271
273
|
}
|
|
272
274
|
};
|
|
273
|
-
|
|
274
|
-
exports.
|
|
275
|
+
const diff = (oldObj, newObj, embeddedObjKeys) => compare(oldObj, newObj, [], embeddedObjKeys, []);
|
|
276
|
+
exports.diff = diff;
|
|
277
|
+
const applyChangeset = (obj, changeset) => {
|
|
275
278
|
if (changeset) {
|
|
276
279
|
changeset.forEach(change => (change.value !== null && change.value !== undefined) || change.type === Operation.REMOVE
|
|
277
280
|
? applyLeafChange(obj, change, change.embeddedKey)
|
|
@@ -279,7 +282,8 @@ exports.applyChangeset = (obj, changeset) => {
|
|
|
279
282
|
}
|
|
280
283
|
return obj;
|
|
281
284
|
};
|
|
282
|
-
exports.
|
|
285
|
+
exports.applyChangeset = applyChangeset;
|
|
286
|
+
const revertChangeset = (obj, changeset) => {
|
|
283
287
|
if (changeset) {
|
|
284
288
|
changeset
|
|
285
289
|
.reverse()
|
|
@@ -287,15 +291,16 @@ exports.revertChangeset = (obj, changeset) => {
|
|
|
287
291
|
}
|
|
288
292
|
return obj;
|
|
289
293
|
};
|
|
294
|
+
exports.revertChangeset = revertChangeset;
|
|
290
295
|
var Operation;
|
|
291
296
|
(function (Operation) {
|
|
292
297
|
Operation["REMOVE"] = "REMOVE";
|
|
293
298
|
Operation["ADD"] = "ADD";
|
|
294
299
|
Operation["UPDATE"] = "UPDATE";
|
|
295
300
|
})(Operation = exports.Operation || (exports.Operation = {}));
|
|
296
|
-
|
|
301
|
+
const flattenChangeset = (obj, path = '$', embeddedKey) => {
|
|
297
302
|
if (Array.isArray(obj)) {
|
|
298
|
-
return obj.reduce((memo, change) => [...memo, ...exports.flattenChangeset(change, path, embeddedKey)], []);
|
|
303
|
+
return obj.reduce((memo, change) => [...memo, ...(0, exports.flattenChangeset)(change, path, embeddedKey)], []);
|
|
299
304
|
}
|
|
300
305
|
else {
|
|
301
306
|
if (obj.changes || embeddedKey) {
|
|
@@ -306,17 +311,18 @@ exports.flattenChangeset = (obj, path = '$', embeddedKey) => {
|
|
|
306
311
|
? path
|
|
307
312
|
: `${path}[?(@.${embeddedKey}='${obj.key}')]`
|
|
308
313
|
: (path = `${path}.${obj.key}`);
|
|
309
|
-
return exports.flattenChangeset(obj.changes || obj, path, obj.embeddedKey);
|
|
314
|
+
return (0, exports.flattenChangeset)(obj.changes || obj, path, obj.embeddedKey);
|
|
310
315
|
}
|
|
311
316
|
else {
|
|
312
|
-
const valueType = exports.getTypeOfObj(obj.value);
|
|
317
|
+
const valueType = (0, exports.getTypeOfObj)(obj.value);
|
|
313
318
|
return [
|
|
314
319
|
Object.assign(Object.assign({}, obj), { path: valueType === 'Object' || path.endsWith(`[${obj.key}]`) ? path : `${path}.${obj.key}`, valueType })
|
|
315
320
|
];
|
|
316
321
|
}
|
|
317
322
|
}
|
|
318
323
|
};
|
|
319
|
-
exports.
|
|
324
|
+
exports.flattenChangeset = flattenChangeset;
|
|
325
|
+
const unflattenChanges = (changes) => {
|
|
320
326
|
if (!Array.isArray(changes)) {
|
|
321
327
|
changes = [changes];
|
|
322
328
|
}
|
|
@@ -327,7 +333,7 @@ exports.unflattenChanges = (changes) => {
|
|
|
327
333
|
const segments = change.path.split(/([^@])\./).reduce((acc, curr, i) => {
|
|
328
334
|
const x = Math.floor(i / 2);
|
|
329
335
|
if (!acc[x]) {
|
|
330
|
-
acc[x] =
|
|
336
|
+
acc[x] = '';
|
|
331
337
|
}
|
|
332
338
|
acc[x] += curr;
|
|
333
339
|
return acc;
|
|
@@ -431,3 +437,4 @@ exports.unflattenChanges = (changes) => {
|
|
|
431
437
|
});
|
|
432
438
|
return changesArr;
|
|
433
439
|
};
|
|
440
|
+
exports.unflattenChanges = unflattenChanges;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-diff-ts",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "A diff tool for JavaScript based on https://www.npmjs.com/package/diff-json written in TypeScript.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -37,14 +37,14 @@
|
|
|
37
37
|
},
|
|
38
38
|
"homepage": "https://github.com/ltwlf/json-diff-ts#readme",
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@types/jest": "^
|
|
40
|
+
"@types/jest": "^27.0.3",
|
|
41
41
|
"@types/lodash": "^4.14.149",
|
|
42
42
|
"jest": "^24.9.0",
|
|
43
|
-
"prettier": "^
|
|
43
|
+
"prettier": "^2.5.1",
|
|
44
44
|
"ts-jest": "^24.2.0",
|
|
45
|
-
"tslint": "^
|
|
45
|
+
"tslint": "^6.1.3",
|
|
46
46
|
"tslint-config-prettier": "^1.18.0",
|
|
47
|
-
"typescript": "^
|
|
47
|
+
"typescript": "^4.5.2"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"lodash": "^4.x"
|