json-diff-ts 1.2.6 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,315 +4,266 @@
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
- TypeScript diff tool with support for array keys instead of just indexes and compatible with JSONPath.
7
+ `json-diff-ts` is a TypeScript library that calculates and applies differences between JSON objects. A standout feature is its ability to identify elements in arrays using keys instead of indices, which offers a more intuitive way to handle arrays. It also supports JSONPath, a query language for JSON, which enables you to target specific parts of a JSON document with precision.
8
8
 
9
- ## Features
9
+ Another significant feature of this library is its ability to transform changesets into atomic changes. This means that each change in the data can be isolated and applied independently, providing a granular level of control over the data manipulation process.
10
10
 
11
- ### diff
11
+ This library is particularly valuable for applications where tracking changes in JSON data is crucial. It simplifies the process of comparing JSON objects and applying changes. The support for key-based array identification can be especially useful in complex JSON structures where tracking by index is not efficient or intuitive. JSONPath support further enhances its capabilities by allowing precise targeting of specific parts in a JSON document, making it a versatile tool for handling JSON data.
12
12
 
13
- If a embedded key is specified for an array, the diff will be generated based on the objects with the same keys.
13
+ ## Installation
14
14
 
15
- #### Examples:
15
+ ```sh
16
+ npm install json-diff-ts
17
+ ```
18
+
19
+ ## Capabilities
20
+
21
+ ### `diff`
22
+
23
+ Generates a difference set for JSON objects. When comparing arrays, if a specific key is provided, differences are determined by matching elements via this key rather than array indices.
24
+
25
+ #### Examples using Star Wars data:
16
26
 
17
27
  ```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
+ import { diff } from 'json-diff-ts';
29
+
30
+ const oldData = {
31
+ planet: 'Tatooine',
32
+ faction: 'Jedi',
33
+ characters: [
34
+ { id: 'LUK', name: 'Luke Skywalker', force: true },
35
+ { id: 'LEI', name: 'Leia Organa', force: true }
28
36
  ]
29
37
  };
30
38
 
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 }
39
+ const newData = {
40
+ planet: 'Alderaan',
41
+ faction: 'Rebel Alliance',
42
+ characters: [
43
+ { id: 'LUK', name: 'Luke Skywalker', force: true, rank: 'Commander' },
44
+ { id: 'HAN', name: 'Han Solo', force: false }
38
45
  ]
39
46
  };
40
47
 
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
- // when you use a function flatten can not generate the correct path.
45
- // to fix this, you can add an additional parameter e.g. (obj, getKeyNameFlag) => {...}. getKeyNameFlag will be true when the diff library try to resolve the key name instead of the key value. You can return a static string or use obj to check which key name you should return. obj will be the first object of the array!
46
- diffs = changesets.diff(oldObj, newObj, { children: 'name' });
48
+ const diffs = diff(oldData, newData, { characters: 'id' });
47
49
 
48
- expect(diffs).to.eql([
50
+ const expectedDiffs = [
49
51
  {
50
- type: 'update',
51
- key: 'name',
52
- value: 'smith',
53
- oldValue: 'joe'
52
+ type: 'UPDATE',
53
+ key: 'planet',
54
+ value: 'Alderaan',
55
+ oldValue: 'Tatooine'
54
56
  },
55
57
  {
56
- type: 'update',
57
- key: 'coins',
58
- embededKey: '$index',
59
- changes: [{ type: 'add', key: '2', value: 1 }]
58
+ type: 'UPDATE',
59
+ key: 'faction',
60
+ value: 'Rebel Alliance',
61
+ oldValue: 'Jedi'
60
62
  },
61
63
  {
62
- type: 'update',
63
- key: 'children',
64
- embededKey: 'name',
64
+ type: 'UPDATE',
65
+ key: 'characters',
66
+ embeddedKey: 'id',
65
67
  changes: [
66
68
  {
67
- type: 'update',
68
- key: 'kid1',
69
- changes: [{ type: 'update', key: 'age', value: 0, oldValue: 1 }]
69
+ type: 'UPDATE',
70
+ key: 'LUK',
71
+ changes: [
72
+ {
73
+ type: 'ADD',
74
+ key: 'rank',
75
+ value: 'Commander'
76
+ }
77
+ ]
70
78
  },
71
79
  {
72
- type: 'add',
73
- key: 'kid3',
74
- value: { name: 'kid3', age: 3 }
80
+ type: 'ADD',
81
+ key: 'HAN',
82
+ value: {
83
+ id: 'HAN',
84
+ name: 'Han Solo',
85
+ force: false
86
+ }
87
+ },
88
+ {
89
+ type: 'REMOVE',
90
+ key: 'LEI',
91
+ value: {
92
+ id: 'LEI',
93
+ name: 'Leia Organa',
94
+ force: true
95
+ }
75
96
  }
76
97
  ]
77
98
  },
78
99
  {
79
- type: 'remove',
80
- key: 'age',
81
- value: 55
100
+ type: 'UPDATE',
101
+ key: 'weapons',
102
+ embeddedKey: '$index',
103
+ changes: [
104
+ {
105
+ type: 'ADD',
106
+ key: '2',
107
+ value: 'Bowcaster'
108
+ }
109
+ ]
82
110
  }
83
- ]);
111
+ ];
112
+ ```
113
+
114
+ #### Advanced
115
+
116
+ Paths can be utilized to identify keys within nested arrays.
117
+
118
+ ```javascript
119
+ const diffs = diff(oldData, newData, { characters.subarray: 'id' });
120
+ ```
121
+
122
+ Alternative Syntax
123
+
124
+ ```javascript
125
+ const diffs = diff(oldData, newData, { 'characters.subarray': 'id' });
126
+ ```
127
+
128
+ You can also designate the root by using '.' instead of an empty string ('').
129
+
130
+ ```javascript
131
+ const diffs = diff(oldData, newData, { '.characters.subarray': 'id' });
132
+ ```
133
+
134
+ You can use a function to dynamically resolve the key of the object.
135
+ The first parameter is the object and the second is to signal if the function should return the key name instead of the value. This is needed to flatten the changeset
136
+
137
+ ```javascript
138
+ const diffs = diff(oldData, newData, {
139
+ characters: (obj, shouldReturnKeyName) => (shouldReturnKeyName ? 'id' : obj.id)
140
+ });
141
+ ```
142
+
143
+ If you're using the Map type, you can employ regular expressions for path identification.
144
+
145
+ ```javascript
146
+ const embeddedObjKeys: EmbeddedObjKeysMapType = new Map();
147
+
148
+ embeddedObjKeys.set(/^char\w+$/, 'id'); // instead of 'id' you can specify a function
149
+
150
+ const diffs = diff(oldObj, newObj, embeddedObjKeys);
84
151
  ```
85
152
 
86
- ### flattenChangeset
153
+ ### `flattenChangeset`
87
154
 
88
- Converts the changeset into a flat atomic change list compatible with JSONPath.
155
+ Transforms a complex changeset into a flat list of atomic changes, each describable by a JSONPath.
89
156
 
90
157
  #### Examples:
91
158
 
92
159
  ```javascript
93
160
  const flatChanges = flattenChangeset(diffs);
94
- // convert changes back to changeset format
95
- const changeset = unflattenChanges(flatChanges.slice(1, 5));
96
- // or use a JSONPath library to apply the patches
161
+ // Restore the changeset from a selection of flat changes
162
+ const changeset = unflattenChanges(flatChanges.slice(0, 3));
163
+ // Alternatively, apply the changes using a JSONPath-capable library
97
164
  // ...
98
165
  ```
99
166
 
100
- The **flatChange** format will look like this:
167
+ A **flatChange** will have the following structure:
101
168
 
102
169
  ```javascript
103
170
  [
104
- { type: 'UPDATE', key: 'name', value: 'smith', oldValue: 'joe', path: '$.name', valueType: 'String' },
105
- { type: 'REMOVE', key: 'mixed', value: 10, path: '$.mixed', valueType: 'Number' },
106
- { type: 'UPDATE', key: 'inner', value: 2, oldValue: 1, path: '$.nested.inner', valueType: 'Number' },
107
- {
108
- type: 'UPDATE',
109
- key: 'date',
110
- value: '2014-10-12T09:13:00.000Z',
111
- oldValue: '2014-10-13T09:13:00.000Z',
112
- path: '$.date',
113
- valueType: 'Date'
114
- },
115
- { type: 'ADD', key: '2', value: 1, path: '$.coins[2]', valueType: 'Number' },
116
- { type: 'REMOVE', key: '0', value: 'car', path: '$.toys[0]', valueType: 'String' },
117
- { type: 'REMOVE', key: '1', value: 'doll', path: '$.toys[1]', valueType: 'String' },
118
- { type: 'REMOVE', key: '0', path: '$.pets[0]', valueType: 'undefined' },
119
- { type: 'REMOVE', key: '1', value: null, path: '$.pets[1]', valueType: null },
120
- { type: 'UPDATE', key: 'age', value: 0, oldValue: 1, path: "$.children[?(@.name='kid1')].age", valueType: 'Number' },
121
- {
122
- type: 'UPDATE',
123
- key: 'value',
124
- value: 'heihei',
125
- oldValue: 'haha',
126
- path: "$.children[?(@.name='kid1')].subset[?(@.id='1')].value",
127
- valueType: 'String'
128
- },
129
- {
130
- type: 'REMOVE',
131
- key: '2',
132
- value: { id: 2, value: 'hehe' },
133
- path: "$.children[?(@.name='kid1')].subset[?(@.id='2')]",
134
- valueType: 'Object'
135
- },
136
- { type: 'ADD', key: 'kid3', value: { name: 'kid3', age: 3 }, path: '$.children', valueType: 'Object' }
171
+ { type: 'UPDATE', key: 'planet', value: 'Alderaan', oldValue: 'Tatooine', path: '$.planet', valueType: 'String' },
172
+ // ... Additional flat changes here
173
+ { type: 'ADD', key: 'rank', value: 'Commander', path: "$.characters[?(@.id=='LUK')].rank", valueType: 'String' }
137
174
  ];
138
175
  ```
139
176
 
140
- ### applyChange
177
+ ### `applyChange`
141
178
 
142
179
  #### Examples:
143
180
 
144
181
  ```javascript
145
- var changesets = require('json-diff-ts');
146
- var oldObj = {
147
- name: 'joe',
148
- age: 55,
149
- coins: [2, 5],
150
- children: [
151
- { name: 'kid1', age: 1 },
152
- { name: 'kid2', age: 2 }
153
- ]
182
+ const oldData = {
183
+ // ... Initial data here
154
184
  };
155
185
 
156
- // Assume children is an array of child object and the child object has 'name' as its primary key
157
- diffs = [
158
- {
159
- type: 'update',
160
- key: 'name',
161
- value: 'smith',
162
- oldValue: 'joe'
163
- },
164
- {
165
- type: 'update',
166
- key: 'coins',
167
- embededKey: '$index',
168
- changes: [{ type: 'add', key: '2', value: 1 }]
169
- },
170
- {
171
- type: 'update',
172
- key: 'children',
173
- embededKey: 'name', // The key property name of the elements in an array
174
- changes: [
175
- {
176
- type: 'update',
177
- key: 'kid1',
178
- changes: [{ type: 'update', key: 'age', value: 0, oldValue: 1 }]
179
- },
180
- {
181
- type: 'add',
182
- key: 'kid3',
183
- value: { name: 'kid3', age: 3 }
184
- }
185
- ]
186
- },
187
- {
188
- type: 'remove',
189
- key: 'age',
190
- value: 55
191
- }
186
+ // Sample diffs array, similar to the one generated in the diff example
187
+ const diffs = [
188
+ // ... Diff objects here
192
189
  ];
193
190
 
194
- changesets.applyChanges(oldObj, diffs);
195
- expect(oldObj).to.eql({
196
- name: 'smith',
197
- coins: [2, 5, 1],
198
- children: [
199
- { name: 'kid3', age: 3 },
200
- { name: 'kid1', age: 0 },
201
- { name: 'kid2', age: 2 }
202
- ]
191
+ changesets.applyChanges(oldData, diffs);
192
+
193
+ expect(oldData).to.eql({
194
+ // ... Updated data here
203
195
  });
204
196
  ```
205
197
 
206
- ### revertChange
198
+ ### `revertChange`
207
199
 
208
200
  #### Examples:
209
201
 
210
202
  ```javascript
203
+ const newData = {
204
+ // ... Updated data here
205
+ };
211
206
 
212
- var changesets = require('json-diff-ts');
213
-
214
- var newObj = {
215
- name: 'smith',
216
- coins: [2, 5, 1],
217
- children: [
218
- {name: 'kid3', age: 3},
219
- {name: 'kid1', age: 0},
220
- {name: 'kid2', age: 2}
221
- ]};
222
-
223
- // Assume children is an array of child object and the child object has 'name' as its primary key
224
- diffs = [
225
- {
226
- type: 'update', key: 'name', value: 'smith', oldValue: 'joe'
227
- },
228
- {
229
- type: 'update', key: 'coins', embededKey: '$index', changes: [
230
- {type: 'add', key: '2', value: 1 }
231
- ]
232
- },
233
- {
234
- type: 'update',
235
- key: 'children',
236
- embededKey: 'name', // The key property name of the elements in an array
237
- changes: [
238
- {
239
- type: 'update', key: 'kid1', changes: [
240
- {type: 'update', key: 'age', value: 0, oldValue: 1 }
241
- ]
242
- },
243
- {
244
- type: 'add', key: 'kid3', value: {name: 'kid3', age: 3 }
245
- }
246
- ]
247
- },
248
- {
249
- type: 'remove', key: 'age', value: 55
250
- }
251
- ]
252
-
253
- changesets.revertChanges(newObj, diffs)
254
- expect(newObj).to.eql {
255
- name: 'joe',
256
- age: 55,
257
- coins: [2, 5],
258
- children: [
259
- {name: 'kid1', age: 1},
260
- {name: 'kid2', age: 2}
261
- ]};
262
-
263
- ```
207
+ // Sample diffs array
208
+ const diffs = [
209
+ // ... Diff objects here
210
+ ];
264
211
 
265
- ## Get started
212
+ changesets.revertChanges(newData, diffs);
266
213
 
267
- ```
268
- npm install json-diff-ts
214
+ expect(newData).to.eql({
215
+ // ... Original data restored here
216
+ });
269
217
  ```
270
218
 
271
- ## Run the test
219
+ ### `jsonPath`
272
220
 
273
- ```
274
- npm run test
275
- ```
221
+ The `json-diff-ts` library uses JSONPath to address specific parts of a JSON document in both the changeset and the application/reversion of changes.
276
222
 
277
- ## Contact
223
+ #### Examples:
278
224
 
279
- Blog: https://blog.leitwolf.io
225
+ ```javascript
280
226
 
281
- Twitter: [@cglessner](https://twitter.com/cglessner)
227
+ const jsonPath = changesets.jsonPath;
282
228
 
283
- ## Changelog
284
- - v1.2.6 Improve handling of JSON Path segments that include periods (PR by [EdVinyard](https://github.com/EdVinyard))
285
- - v1.2.5 Patch all dependencies; add support for resolving a key name if a function is used to get the key value
286
- - v1.2.4 Fix readme (npm install); update TypeScript and Lodash
287
- - v1.2.3 Update outdated dependencies; update TypeScript version to 4.5.2
288
- - v1.2.2 Add support for functions to resove object keys (PR by [Abraxxa](https://github.com/abraxxa))
229
+ cost data = {
230
+ // ... Some JSON data
231
+ };
289
232
 
290
- ## Credits
233
+ const value = jsonPath.query(data, '$.characters[?(@.id=="LUK")].name');
291
234
 
292
- This project was based on https://www.npmjs.com/package/diff-json (viruschidai@gmail.com)
235
+ expect(value).to.eql(['Luke Skywalker']);
236
+ ```
293
237
 
294
- ## Licence
238
+ ## Contributing
295
239
 
296
- **The MIT License (MIT)**
240
+ Contributions are welcome! Please follow the provided issue templates and code of conduct.
297
241
 
298
- Copyright (c) 2019 Christian Glessner
242
+ ## Contact
299
243
 
300
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
244
+ Reach out to the maintainer via LinkedIn or Twitter:
301
245
 
302
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
246
+ - LinkedIn: [Christian Glessner](https://www.linkedin.com/in/christian-glessner/)
247
+ - Twitter: [@leitwolf_io](https://twitter.com/leitwolf_io)
303
248
 
304
- 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.
249
+ Discover more about the company behind this project: [hololux](https://hololux.com)
305
250
 
306
- The project is based on diff-json (https://www.npmjs.com/package/diff-json). Copyright 2013 viruschidai@gmail.com. for additional details.
251
+ ## Release Notes
307
252
 
308
- **Original License**
253
+ - **v2.1.0:** Resolves a problem related to JSON Path filters by replacing the single equal sign (=) with a double equal sign (==). This update maintains compatibility with existing flat changes. Allows to use either '' or '.' as root in the path.
254
+ - **v2.0.0:** json-diff-ts has been upgraded to an ECMAScript module! This major update brings optimizations and enhanced documentation. Additionally, a previously existing issue where all paths were treated as regex has been fixed. In this new version, you'll need to use a Map instead of a Record for regex paths. Please note that this is a breaking change if you were using regex paths in the previous versions.
255
+ - **v1.2.6:** Enhanced JSON Path handling for period-inclusive segments.
256
+ - **v1.2.5:** Patched dependencies; added key name resolution support for key functions.
257
+ - **v1.2.4:** Documentation updates; upgraded TypeScript and Lodash.
258
+ - **v1.2.3:** Dependency updates; switched to TypeScript 4.5.2.
259
+ - **v1.2.2:** Implemented object key resolution functions support.
309
260
 
310
- The MIT License (MIT)
261
+ ## Acknowledgments
311
262
 
312
- Copyright (c) 2013 viruschidai@gmail.com
263
+ This project takes inspiration and code from [diff-json](https://www.npmjs.com/package/diff-json) by viruschidai@gmail.com.
313
264
 
314
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
265
+ ## License
315
266
 
316
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
267
+ json-diff-ts is open-sourced software licensed under the [MIT license](LICENSE).
317
268
 
318
- 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.
269
+ The original diff-json project is also under the MIT License. For more information, refer to its [license details](https://www.npmjs.com/package/diff-json#license).
package/lib/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './jsonDiff';
2
- export * from './jsonCompare';
1
+ export * from './jsonDiff.js';
2
+ export * from './jsonCompare.js';
package/lib/index.js CHANGED
@@ -1,18 +1,2 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./jsonDiff"), exports);
18
- __exportStar(require("./jsonCompare"), exports);
1
+ export * from './jsonDiff.js';
2
+ export * from './jsonCompare.js';
@@ -1,4 +1,4 @@
1
- import { IFlatChange, Operation } from './jsonDiff';
1
+ import { IFlatChange, Operation } from './jsonDiff.js';
2
2
  export declare enum CompareOperation {
3
3
  CONTAINER = "CONTAINER",
4
4
  UNCHANGED = "UNCHANGED"
@@ -1,64 +1,61 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.compare = exports.applyChangelist = exports.enrich = exports.createContainer = exports.createValue = exports.CompareOperation = void 0;
4
- const lodash_1 = require("lodash");
5
- const jsonDiff_1 = require("./jsonDiff");
6
- var CompareOperation;
1
+ import { chain, keys, replace, set } from 'lodash-es';
2
+ import { diff, flattenChangeset, getTypeOfObj, Operation } from './jsonDiff.js';
3
+ export var CompareOperation;
7
4
  (function (CompareOperation) {
8
5
  CompareOperation["CONTAINER"] = "CONTAINER";
9
6
  CompareOperation["UNCHANGED"] = "UNCHANGED";
10
- })(CompareOperation = exports.CompareOperation || (exports.CompareOperation = {}));
11
- const createValue = (value) => ({ type: CompareOperation.UNCHANGED, value });
12
- exports.createValue = createValue;
13
- const createContainer = (value) => ({
7
+ })(CompareOperation || (CompareOperation = {}));
8
+ export const createValue = (value) => ({ type: CompareOperation.UNCHANGED, value });
9
+ export const createContainer = (value) => ({
14
10
  type: CompareOperation.CONTAINER,
15
11
  value
16
12
  });
17
- exports.createContainer = createContainer;
18
- const enrich = (object) => {
19
- const objectType = (0, jsonDiff_1.getTypeOfObj)(object);
13
+ export const enrich = (object) => {
14
+ const objectType = getTypeOfObj(object);
20
15
  switch (objectType) {
21
16
  case 'Object':
22
- return (0, lodash_1.keys)(object)
23
- .map((key) => ({ key, value: (0, exports.enrich)(object[key]) }))
17
+ return keys(object)
18
+ .map((key) => ({ key, value: enrich(object[key]) }))
24
19
  .reduce((accumulator, entry) => {
25
20
  accumulator.value[entry.key] = entry.value;
26
21
  return accumulator;
27
- }, (0, exports.createContainer)({}));
22
+ }, createContainer({}));
28
23
  case 'Array':
29
- return (0, lodash_1.chain)(object)
30
- .map(value => (0, exports.enrich)(value))
24
+ return chain(object)
25
+ .map((value) => enrich(value))
31
26
  .reduce((accumulator, value) => {
32
27
  accumulator.value.push(value);
33
28
  return accumulator;
34
- }, (0, exports.createContainer)([]))
29
+ }, createContainer([]))
35
30
  .value();
36
31
  case 'Function':
37
32
  return undefined;
38
33
  case 'Date':
39
34
  default:
40
35
  // Primitive value
41
- return (0, exports.createValue)(object);
36
+ return createValue(object);
42
37
  }
43
38
  };
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.') })))
39
+ export const applyChangelist = (object, changelist) => {
40
+ chain(changelist)
41
+ .map((entry) => ({ ...entry, path: replace(entry.path, '$.', '.') }))
42
+ .map((entry) => ({
43
+ ...entry,
44
+ path: replace(entry.path, /(\[(?<array>\d)\]\.)/g, 'ARRVAL_START$<array>ARRVAL_END')
45
+ }))
46
+ .map((entry) => ({ ...entry, path: replace(entry.path, /(?<dot>\.)/g, '.value$<dot>') }))
47
+ .map((entry) => ({ ...entry, path: replace(entry.path, /\./, '') }))
48
+ .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_START/g, '.value[') }))
49
+ .map((entry) => ({ ...entry, path: replace(entry.path, /ARRVAL_END/g, '].value.') }))
53
50
  .value()
54
- .forEach(entry => {
51
+ .forEach((entry) => {
55
52
  switch (entry.type) {
56
- case jsonDiff_1.Operation.ADD:
57
- case jsonDiff_1.Operation.UPDATE:
58
- (0, lodash_1.set)(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });
53
+ case Operation.ADD:
54
+ case Operation.UPDATE:
55
+ set(object, entry.path, { type: entry.type, value: entry.value, oldValue: entry.oldValue });
59
56
  break;
60
- case jsonDiff_1.Operation.REMOVE:
61
- (0, lodash_1.set)(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });
57
+ case Operation.REMOVE:
58
+ set(object, entry.path, { type: entry.type, value: undefined, oldValue: entry.value });
62
59
  break;
63
60
  default:
64
61
  throw new Error();
@@ -66,8 +63,6 @@ const applyChangelist = (object, changelist) => {
66
63
  });
67
64
  return object;
68
65
  };
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)));
66
+ export const compare = (oldObject, newObject) => {
67
+ return applyChangelist(enrich(oldObject), flattenChangeset(diff(oldObject, newObject)));
72
68
  };
73
- exports.compare = compare;