json-diff-ts 1.1.0 → 1.2.3

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 CHANGED
@@ -1,12 +1,10 @@
1
1
  # json-diff-ts
2
2
 
3
- ![Master CI/Publish](https://github.com/ltwlf/json-diff-ts/workflows/Master%20CI/Publish/badge.svg)
3
+ ![Master CI/Publish](https://github.com/ltwlf/json-diff-ts/workflows/Master%20CI/Publish/badge.svg)
4
4
  [![Known Vulnerabilities](https://snyk.io/test/github/ltwlf/json-diff-ts/badge.svg?targetFile=package.json)](https://snyk.io/test/github/ltwlf/json-diff-ts?targetFile=package.json)
5
5
  [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ltwlf_json-diff-ts&metric=alert_status)](https://sonarcloud.io/dashboard?id=ltwlf_json-diff-ts)
6
6
 
7
- A diff tool for JavaScript based on https://www.npmjs.com/package/diff-json (viruschidai@gmail.com) rewritten in TypeScript.
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
- var changesets = require('diff-json-ts');
22
- var newObj, oldObj;
23
-
24
- oldObj = {
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
- expect(diffs).to.eql([
47
- {
48
- type: 'update', key: 'name', value: 'smith', oldValue: 'joe'
49
- },
50
- {
51
- type: 'update', key: 'coins', embededKey: '$index', changes: [
52
- {type: 'add', key: '2', value: 1 }
53
- ]
54
- },
55
- {
56
- type: 'update',
57
- key: 'children',
58
- embededKey: 'name',
59
- changes: [
60
- {
61
- type: 'update', key: 'kid1', changes: [
62
- {type: 'update', key: 'age', value: 0, oldValue: 1 }
63
- ]
64
- },
65
- {
66
- type: 'add', key: 'kid3', value: {name: 'kid3', age: 3 }
67
- }
68
- ]
69
- },
70
- {
71
- type: 'remove', key: 'age', value: 55
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
@@ -87,7 +95,7 @@ const changeset = unflattenChanges(flatChanges.slice(1, 5));
87
95
  // ...
88
96
  ```
89
97
 
90
- The **flatChange** formant will look like this:
98
+ The **flatChange** format will look like this:
91
99
 
92
100
  ```javascript
93
101
  [
@@ -132,58 +140,65 @@ The **flatChange** formant will look like this:
132
140
  #### Examples:
133
141
 
134
142
  ```javascript
135
-
136
- var changesets = require('diff-json-ts');
137
- var oldObj = {
138
- name: 'joe',
139
- age: 55,
140
- coins: [2, 5],
141
- children: [
142
- {name: 'kid1', age: 1},
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
- changesets.applyChanges(oldObj, diffs)
178
- expect(oldObj).to.eql({
179
- name: 'smith',
180
- coins: [2, 5, 1],
181
- children: [
182
- {name: 'kid3', age: 3},
183
- {name: 'kid1', age: 0},
184
- {name: 'kid2', age: 2}
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** formant will look like this:
192
207
 
193
208
  ```javascript
194
209
 
195
- var changesets = require('diff-json-ts');
210
+ var changesets = require('json-diff-ts');
196
211
 
197
212
  var newObj = {
198
213
  name: 'smith',
@@ -203,7 +218,7 @@ The **flatChange** formant will look like this:
203
218
  {name: 'kid2', age: 2}
204
219
  ]};
205
220
 
206
- # Assume children is an array of child object and the child object has 'name' as its primary key
221
+ // Assume children is an array of child object and the child object has 'name' as its primary key
207
222
  diffs = [
208
223
  {
209
224
  type: 'update', key: 'name', value: 'smith', oldValue: 'joe'
@@ -258,10 +273,19 @@ 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.3 Update outdated dependencies; update TypeScript version to 4.5.2
284
+ - v1.2.2 Add support for functions to resove object keys (PR by [Abraxxa](https://github.com/abraxxa))
285
+
286
+ ## Credits
287
+
288
+ This project was based on https://www.npmjs.com/package/diff-json (viruschidai@gmail.com)
265
289
 
266
290
  ## Licence
267
291
 
@@ -275,7 +299,7 @@ The above copyright notice and this permission notice shall be included in all c
275
299
 
276
300
  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
301
 
278
- The project is based on diff-json (https://www.npmjs.com/package/diff-json). Copyright 2013 viruschidai@gmail.com. for additional details.
302
+ The project is based on diff-json (https://www.npmjs.com/package/diff-json). Copyright 2013 viruschidai@gmail.com. for additional details.
279
303
 
280
304
  **Original License**
281
305
 
package/lib/index.js CHANGED
@@ -1,7 +1,14 @@
1
1
  "use strict";
2
- function __export(m) {
3
- for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
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
- __export(require("./jsonDiff"));
7
- __export(require("./jsonCompare"));
13
+ __exportStar(require("./jsonDiff"), exports);
14
+ __exportStar(require("./jsonCompare"), exports);
@@ -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
- exports.createValue = (value) => ({ type: CompareOperation.UNCHANGED, value });
11
- exports.createContainer = (value) => ({
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.enrich = (object) => {
16
- const objectType = jsonDiff_1.getTypeOfObj(object);
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.applyChangelist = (object, changelist) => {
42
- lodash_1.chain(changelist)
43
- .map(entry => (Object.assign(Object.assign({}, entry), { path: lodash_1.replace(entry.path, '$.', '.') })))
44
- .map(entry => (Object.assign(Object.assign({}, entry), { path: lodash_1.replace(entry.path, /(\[(?<array>\d)\]\.)/g, 'ARRVAL_START$<array>ARRVAL_END') })))
45
- .map(entry => (Object.assign(Object.assign({}, entry), { path: lodash_1.replace(entry.path, /(?<dot>\.)/g, '.value$<dot>') })))
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, /ARRVAL_START/g, '.value[') })))
48
- .map(entry => (Object.assign(Object.assign({}, entry), { path: lodash_1.replace(entry.path, /ARRVAL_END/g, '].value.') })))
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.compare = (oldObject, newObject) => {
66
- return exports.applyChangelist(exports.enrich(oldObject), jsonDiff_1.flattenChangeset(jsonDiff_1.diff(oldObject, newObject)));
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: IChange | Changeset, path?: string, embeddedKey?: string) => IFlatChange[];
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
- exports.getTypeOfObj = (obj) => {
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]);
@@ -96,7 +98,7 @@ const compareObject = (oldObj, newObj, path, embeddedObjKeys, keyPath, skipPath
96
98
  return changes;
97
99
  };
98
100
  const compareArray = (oldObj, newObj, path, embeddedObjKeys, keyPath) => {
99
- const left = embeddedObjKeys != null ? embeddedObjKeys[keyPath.join('.')] : undefined;
101
+ const left = getObjectKey(embeddedObjKeys, keyPath);
100
102
  const uniqKey = left != null ? left : '$index';
101
103
  const indexedOldObj = convertArrayToObj(oldObj, uniqKey);
102
104
  const indexedNewObj = convertArrayToObj(newObj, uniqKey);
@@ -115,10 +117,25 @@ const compareArray = (oldObj, newObj, path, embeddedObjKeys, keyPath) => {
115
117
  return [];
116
118
  }
117
119
  };
120
+ const getObjectKey = (embeddedObjKeys, keyPath) => {
121
+ if (embeddedObjKeys != null) {
122
+ const path = keyPath.join('.');
123
+ const key = embeddedObjKeys[path];
124
+ if (key != null) {
125
+ return key;
126
+ }
127
+ for (const regex in embeddedObjKeys) {
128
+ if (path.match(new RegExp(regex))) {
129
+ return embeddedObjKeys[regex];
130
+ }
131
+ }
132
+ }
133
+ return undefined;
134
+ };
118
135
  const convertArrayToObj = (arr, uniqKey) => {
119
136
  let obj = {};
120
137
  if (uniqKey !== '$index') {
121
- obj = lodash_1.keyBy(arr, uniqKey);
138
+ obj = (0, lodash_1.keyBy)(arr, uniqKey);
122
139
  }
123
140
  else {
124
141
  for (let i = 0; i < arr.length; i++) {
@@ -202,9 +219,9 @@ const applyArrayChange = (arr, change) => (() => {
202
219
  element = arr[subchange.key];
203
220
  }
204
221
  else {
205
- 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());
206
223
  }
207
- result.push(exports.applyChangeset(element, subchange.changes));
224
+ result.push((0, exports.applyChangeset)(element, subchange.changes));
208
225
  }
209
226
  }
210
227
  return result;
@@ -214,7 +231,7 @@ const applyBranchChange = (obj, change) => {
214
231
  return applyArrayChange(obj, change);
215
232
  }
216
233
  else {
217
- return exports.applyChangeset(obj, change.changes);
234
+ return (0, exports.applyChangeset)(obj, change.changes);
218
235
  }
219
236
  };
220
237
  const revertLeafChange = (obj, change, embeddedKey = '$index') => {
@@ -240,9 +257,9 @@ const revertArrayChange = (arr, change) => (() => {
240
257
  element = arr[+subchange.key];
241
258
  }
242
259
  else {
243
- 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);
244
261
  }
245
- result.push(exports.revertChangeset(element, subchange.changes));
262
+ result.push((0, exports.revertChangeset)(element, subchange.changes));
246
263
  }
247
264
  }
248
265
  return result;
@@ -252,11 +269,12 @@ const revertBranchChange = (obj, change) => {
252
269
  return revertArrayChange(obj, change);
253
270
  }
254
271
  else {
255
- return exports.revertChangeset(obj, change.changes);
272
+ return (0, exports.revertChangeset)(obj, change.changes);
256
273
  }
257
274
  };
258
- exports.diff = (oldObj, newObj, embeddedObjKeys) => compare(oldObj, newObj, [], embeddedObjKeys, []);
259
- exports.applyChangeset = (obj, changeset) => {
275
+ const diff = (oldObj, newObj, embeddedObjKeys) => compare(oldObj, newObj, [], embeddedObjKeys, []);
276
+ exports.diff = diff;
277
+ const applyChangeset = (obj, changeset) => {
260
278
  if (changeset) {
261
279
  changeset.forEach(change => (change.value !== null && change.value !== undefined) || change.type === Operation.REMOVE
262
280
  ? applyLeafChange(obj, change, change.embeddedKey)
@@ -264,7 +282,8 @@ exports.applyChangeset = (obj, changeset) => {
264
282
  }
265
283
  return obj;
266
284
  };
267
- exports.revertChangeset = (obj, changeset) => {
285
+ exports.applyChangeset = applyChangeset;
286
+ const revertChangeset = (obj, changeset) => {
268
287
  if (changeset) {
269
288
  changeset
270
289
  .reverse()
@@ -272,15 +291,16 @@ exports.revertChangeset = (obj, changeset) => {
272
291
  }
273
292
  return obj;
274
293
  };
294
+ exports.revertChangeset = revertChangeset;
275
295
  var Operation;
276
296
  (function (Operation) {
277
297
  Operation["REMOVE"] = "REMOVE";
278
298
  Operation["ADD"] = "ADD";
279
299
  Operation["UPDATE"] = "UPDATE";
280
300
  })(Operation = exports.Operation || (exports.Operation = {}));
281
- exports.flattenChangeset = (obj, path = '$', embeddedKey) => {
301
+ const flattenChangeset = (obj, path = '$', embeddedKey) => {
282
302
  if (Array.isArray(obj)) {
283
- return obj.reduce((memo, change) => [...memo, ...exports.flattenChangeset(change, path, embeddedKey)], []);
303
+ return obj.reduce((memo, change) => [...memo, ...(0, exports.flattenChangeset)(change, path, embeddedKey)], []);
284
304
  }
285
305
  else {
286
306
  if (obj.changes || embeddedKey) {
@@ -291,17 +311,18 @@ exports.flattenChangeset = (obj, path = '$', embeddedKey) => {
291
311
  ? path
292
312
  : `${path}[?(@.${embeddedKey}='${obj.key}')]`
293
313
  : (path = `${path}.${obj.key}`);
294
- return exports.flattenChangeset(obj.changes || obj, path, obj.embeddedKey);
314
+ return (0, exports.flattenChangeset)(obj.changes || obj, path, obj.embeddedKey);
295
315
  }
296
316
  else {
297
- const valueType = exports.getTypeOfObj(obj.value);
317
+ const valueType = (0, exports.getTypeOfObj)(obj.value);
298
318
  return [
299
319
  Object.assign(Object.assign({}, obj), { path: valueType === 'Object' || path.endsWith(`[${obj.key}]`) ? path : `${path}.${obj.key}`, valueType })
300
320
  ];
301
321
  }
302
322
  }
303
323
  };
304
- exports.unflattenChanges = (changes) => {
324
+ exports.flattenChangeset = flattenChangeset;
325
+ const unflattenChanges = (changes) => {
305
326
  if (!Array.isArray(changes)) {
306
327
  changes = [changes];
307
328
  }
@@ -309,7 +330,14 @@ exports.unflattenChanges = (changes) => {
309
330
  changes.forEach(change => {
310
331
  const obj = {};
311
332
  let ptr = obj;
312
- const segments = change.path.split(/((?<!@)\.)/).filter(x => x !== '.');
333
+ const segments = change.path.split(/([^@])\./).reduce((acc, curr, i) => {
334
+ const x = Math.floor(i / 2);
335
+ if (!acc[x]) {
336
+ acc[x] = '';
337
+ }
338
+ acc[x] += curr;
339
+ return acc;
340
+ }, []);
313
341
  // $.childern[@.name='chris'].age
314
342
  // =>
315
343
  // $
@@ -409,3 +437,4 @@ exports.unflattenChanges = (changes) => {
409
437
  });
410
438
  return changesArr;
411
439
  };
440
+ exports.unflattenChanges = unflattenChanges;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-diff-ts",
3
- "version": "1.1.0",
3
+ "version": "1.2.3",
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": "^24.0.23",
40
+ "@types/jest": "^27.0.3",
41
41
  "@types/lodash": "^4.14.149",
42
42
  "jest": "^24.9.0",
43
- "prettier": "^1.19.1",
43
+ "prettier": "^2.5.1",
44
44
  "ts-jest": "^24.2.0",
45
- "tslint": "^5.20.1",
45
+ "tslint": "^6.1.3",
46
46
  "tslint-config-prettier": "^1.18.0",
47
- "typescript": "^3.7.2"
47
+ "typescript": "^4.5.2"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "lodash": "^4.x"