@scalar/json-magic 0.8.1 → 0.8.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.
Files changed (94) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/bundle/index.d.ts +1 -0
  3. package/dist/bundle/index.d.ts.map +1 -1
  4. package/dist/bundle/index.js.map +1 -1
  5. package/dist/bundle/plugins/browser.js.map +1 -1
  6. package/dist/bundle/plugins/node.d.ts +1 -1
  7. package/dist/bundle/plugins/node.js +1 -1
  8. package/dist/bundle/plugins/node.js.map +1 -1
  9. package/dist/bundle/value-generator.d.ts +2 -2
  10. package/dist/bundle/value-generator.d.ts.map +1 -1
  11. package/dist/bundle/value-generator.js +3 -3
  12. package/dist/bundle/value-generator.js.map +2 -2
  13. package/dist/dereference/index.d.ts.map +1 -1
  14. package/dist/dereference/index.js.map +2 -2
  15. package/dist/diff/index.d.ts +1 -1
  16. package/dist/diff/index.d.ts.map +1 -1
  17. package/dist/diff/index.js +1 -1
  18. package/dist/diff/index.js.map +2 -2
  19. package/dist/helpers/escape-json-pointer.d.ts +1 -1
  20. package/dist/helpers/escape-json-pointer.js.map +1 -1
  21. package/dist/magic-proxy/index.d.ts.map +1 -1
  22. package/dist/magic-proxy/index.js.map +2 -2
  23. package/dist/magic-proxy/proxy.d.ts +0 -1
  24. package/dist/magic-proxy/proxy.d.ts.map +1 -1
  25. package/dist/magic-proxy/proxy.js +1 -2
  26. package/dist/magic-proxy/proxy.js.map +2 -2
  27. package/package.json +12 -14
  28. package/.turbo/turbo-build.log +0 -10
  29. package/dist/helpers/generate-hash.d.ts +0 -11
  30. package/dist/helpers/generate-hash.d.ts.map +0 -1
  31. package/dist/helpers/generate-hash.js +0 -16
  32. package/dist/helpers/generate-hash.js.map +0 -7
  33. package/esbuild.ts +0 -15
  34. package/src/bundle/bundle.test.ts +0 -2921
  35. package/src/bundle/bundle.ts +0 -916
  36. package/src/bundle/create-limiter.test.ts +0 -28
  37. package/src/bundle/create-limiter.ts +0 -52
  38. package/src/bundle/index.ts +0 -3
  39. package/src/bundle/plugins/browser.ts +0 -4
  40. package/src/bundle/plugins/fetch-urls/index.test.ts +0 -144
  41. package/src/bundle/plugins/fetch-urls/index.ts +0 -105
  42. package/src/bundle/plugins/node.ts +0 -5
  43. package/src/bundle/plugins/parse-json/index.test.ts +0 -24
  44. package/src/bundle/plugins/parse-json/index.ts +0 -32
  45. package/src/bundle/plugins/parse-yaml/index.test.ts +0 -26
  46. package/src/bundle/plugins/parse-yaml/index.ts +0 -34
  47. package/src/bundle/plugins/read-files/index.test.ts +0 -36
  48. package/src/bundle/plugins/read-files/index.ts +0 -58
  49. package/src/bundle/value-generator.test.ts +0 -165
  50. package/src/bundle/value-generator.ts +0 -143
  51. package/src/dereference/dereference.test.ts +0 -145
  52. package/src/dereference/dereference.ts +0 -84
  53. package/src/dereference/index.ts +0 -2
  54. package/src/diff/apply.test.ts +0 -262
  55. package/src/diff/apply.ts +0 -83
  56. package/src/diff/diff.test.ts +0 -328
  57. package/src/diff/diff.ts +0 -93
  58. package/src/diff/index.test.ts +0 -150
  59. package/src/diff/index.ts +0 -5
  60. package/src/diff/merge.test.ts +0 -1109
  61. package/src/diff/merge.ts +0 -136
  62. package/src/diff/trie.test.ts +0 -30
  63. package/src/diff/trie.ts +0 -113
  64. package/src/diff/utils.test.ts +0 -169
  65. package/src/diff/utils.ts +0 -111
  66. package/src/helpers/convert-to-local-ref.test.ts +0 -211
  67. package/src/helpers/convert-to-local-ref.ts +0 -43
  68. package/src/helpers/escape-json-pointer.test.ts +0 -13
  69. package/src/helpers/escape-json-pointer.ts +0 -8
  70. package/src/helpers/generate-hash.test.ts +0 -74
  71. package/src/helpers/generate-hash.ts +0 -29
  72. package/src/helpers/get-schemas.test.ts +0 -356
  73. package/src/helpers/get-schemas.ts +0 -80
  74. package/src/helpers/get-segments-from-path.test.ts +0 -17
  75. package/src/helpers/get-segments-from-path.ts +0 -17
  76. package/src/helpers/get-value-by-path.test.ts +0 -338
  77. package/src/helpers/get-value-by-path.ts +0 -44
  78. package/src/helpers/is-json-object.ts +0 -31
  79. package/src/helpers/is-object.test.ts +0 -27
  80. package/src/helpers/is-object.ts +0 -4
  81. package/src/helpers/is-yaml.ts +0 -18
  82. package/src/helpers/json-path-utils.test.ts +0 -57
  83. package/src/helpers/json-path-utils.ts +0 -50
  84. package/src/helpers/normalize.test.ts +0 -92
  85. package/src/helpers/normalize.ts +0 -35
  86. package/src/helpers/unescape-json-pointer.test.ts +0 -23
  87. package/src/helpers/unescape-json-pointer.ts +0 -9
  88. package/src/magic-proxy/index.ts +0 -2
  89. package/src/magic-proxy/proxy.test.ts +0 -1987
  90. package/src/magic-proxy/proxy.ts +0 -323
  91. package/src/types.ts +0 -1
  92. package/tsconfig.build.json +0 -12
  93. package/tsconfig.json +0 -16
  94. package/vite.config.ts +0 -8
@@ -1,262 +0,0 @@
1
- import { apply, InvalidChangesDetectedError } from '@/diff/apply'
2
- import { describe, expect, test } from 'vitest'
3
-
4
- const deepClone = <T extends object>(obj: T) => JSON.parse(JSON.stringify(obj)) as T
5
-
6
- describe('apply', () => {
7
- describe('should apply `add` operations', () => {
8
- test('should apply `add` operation correctly', () => {
9
- const doc = {
10
- name: 'John',
11
- age: 25,
12
- }
13
-
14
- const docCopy = deepClone(doc)
15
- const location = { city: 'New York', street: '5th Avenue' }
16
-
17
- expect(apply(doc, [{ path: ['location'], changes: location, type: 'add' }])).toEqual({
18
- ...docCopy,
19
- location,
20
- })
21
- })
22
-
23
- test('should apply `add` operation on deeply nested objects correctly', () => {
24
- const doc = {
25
- name: 'John',
26
- age: 25,
27
- location: {
28
- city: 'New York',
29
- street: '5th Avenue',
30
- },
31
- }
32
-
33
- const docCopy = deepClone(doc)
34
- const coordinates = { lat: 40.7128, long: 74.006 }
35
-
36
- expect(
37
- apply(doc, [
38
- {
39
- path: ['location', 'coordinates'],
40
- changes: coordinates,
41
- type: 'add',
42
- },
43
- ]),
44
- ).toEqual({
45
- ...docCopy,
46
- location: {
47
- ...docCopy.location,
48
- coordinates,
49
- },
50
- })
51
- })
52
- })
53
-
54
- describe('should apply `update` operation', () => {
55
- test('should apply `update` operation correctly', () => {
56
- const doc = {
57
- name: 'John',
58
- age: 25,
59
- location: {
60
- city: 'New York',
61
- street: '5th Avenue',
62
- },
63
- }
64
- const docCopy = deepClone(doc)
65
- const updatedAge = 26
66
-
67
- expect(apply(doc, [{ path: ['age'], changes: updatedAge, type: 'update' }])).toEqual({
68
- ...docCopy,
69
- age: updatedAge,
70
- })
71
- })
72
-
73
- test('should apply `update` operation correctly on nested objects', () => {
74
- const doc = {
75
- name: 'John',
76
- age: 25,
77
- location: {
78
- city: 'New York',
79
- street: '5th Avenue',
80
- },
81
- }
82
-
83
- const docCopy = deepClone(doc)
84
- const updatedCity = 'Boston'
85
-
86
- expect(apply(doc, [{ path: ['location', 'city'], changes: updatedCity, type: 'update' }])).toEqual({
87
- ...docCopy,
88
- location: { ...docCopy.location, city: updatedCity },
89
- })
90
- })
91
- })
92
-
93
- describe('should apply `delete` operation', () => {
94
- test('should apply `delete` operation correctly', () => {
95
- const doc2 = {
96
- name: 'John',
97
- age: 25,
98
- }
99
-
100
- const doc1 = {
101
- ...doc2,
102
- location: {
103
- city: 'New York',
104
- street: '5th Avenue',
105
- },
106
- }
107
-
108
- expect(apply(doc1, [{ path: ['location'], changes: doc1.location, type: 'delete' }])).toEqual(doc2)
109
- })
110
-
111
- test('should apply `delete` operation correctly on nested objects', () => {
112
- const doc2 = {
113
- name: 'John',
114
- age: 25,
115
- location: {
116
- city: 'New York',
117
- },
118
- }
119
-
120
- const doc1 = {
121
- ...doc2,
122
- location: {
123
- ...doc2.location,
124
- street: '5th Avenue',
125
- },
126
- }
127
-
128
- expect(
129
- apply(doc1, [
130
- {
131
- path: ['location', 'street'],
132
- changes: doc1.location.street,
133
- type: 'delete',
134
- },
135
- ]),
136
- ).toEqual(doc2)
137
- })
138
- })
139
-
140
- describe('should throw on incorrect diff', () => {
141
- test('wrong nested key', () => {
142
- const doc = {
143
- name: 'John',
144
- age: 25,
145
- location: {
146
- city: 'New York',
147
- street: '5th Avenue',
148
- },
149
- }
150
-
151
- expect(() =>
152
- apply(doc, [
153
- {
154
- path: ['location', 'city', 'something'],
155
- changes: { test: 1 },
156
- type: 'add',
157
- },
158
- ]),
159
- ).toThrow(InvalidChangesDetectedError)
160
- })
161
-
162
- test('wrong non existing path', () => {
163
- const doc = {
164
- name: 'John',
165
- age: 25,
166
- location: {
167
- city: 'New York',
168
- street: '5th Avenue',
169
- },
170
- }
171
-
172
- expect(() =>
173
- apply(doc, [
174
- {
175
- path: ['location', 'coordinates', 'lang'],
176
- changes: 41.25,
177
- type: 'add',
178
- },
179
- ]),
180
- ).toThrow(InvalidChangesDetectedError)
181
- })
182
- })
183
-
184
- describe('should correctly handle arrays', () => {
185
- test('should correctly apply `add` changes on an array', () => {
186
- const doc = {
187
- name: 'John',
188
- age: 25,
189
- location: {
190
- city: 'New York',
191
- street: '5th Avenue',
192
- },
193
- hobbies: ['swimming'],
194
- }
195
-
196
- const docCopy = deepClone(doc)
197
- const newHobby = 'coding'
198
-
199
- expect(
200
- apply(doc, [
201
- {
202
- path: ['hobbies', '1'],
203
- changes: newHobby,
204
- type: 'add',
205
- },
206
- ]),
207
- ).toEqual({ ...docCopy, hobbies: [...docCopy.hobbies, newHobby] })
208
- })
209
- })
210
-
211
- test('should correctly apply `update` changes on an array', () => {
212
- const doc = {
213
- name: 'John',
214
- age: 25,
215
- location: {
216
- city: 'New York',
217
- street: '5th Avenue',
218
- },
219
- hobbies: ['swimming', 'fish', 'coding'],
220
- }
221
-
222
- const docCopy = deepClone(doc)
223
- const updatedHobby = 'running'
224
- docCopy.hobbies[1] = updatedHobby
225
-
226
- expect(
227
- apply(doc, [
228
- {
229
- path: ['hobbies', '1'],
230
- changes: updatedHobby,
231
- type: 'update',
232
- },
233
- ]),
234
- ).toEqual(docCopy)
235
- })
236
-
237
- test('should correctly apply `delete` changes on an array', () => {
238
- const doc = {
239
- name: 'John',
240
- age: 25,
241
- location: {
242
- city: 'New York',
243
- street: '5th Avenue',
244
- },
245
- hobbies: ['swimming', 'fish', 'coding'],
246
- }
247
-
248
- const docCopy = deepClone(doc)
249
- // Perform the delete operation
250
- docCopy.hobbies.splice(1, 1)
251
-
252
- expect(
253
- apply(doc, [
254
- {
255
- path: ['hobbies', '1'],
256
- changes: doc.hobbies[1],
257
- type: 'delete',
258
- },
259
- ]),
260
- ).toEqual(docCopy)
261
- })
262
- })
package/src/diff/apply.ts DELETED
@@ -1,83 +0,0 @@
1
- import type { Difference } from '@/diff/diff'
2
-
3
- export class InvalidChangesDetectedError extends Error {
4
- constructor(message: string) {
5
- super(message)
6
- this.name = 'InvalidChangesDetectedError'
7
- }
8
- }
9
-
10
- /**
11
- * Applies a set of differences to a document object.
12
- * The function traverses the document structure following the paths specified in the differences
13
- * and applies the corresponding changes (add, update, or delete) at each location.
14
- *
15
- * @param document - The original document to apply changes to
16
- * @param diff - Array of differences to apply, each containing a path and change type
17
- * @returns The modified document with all changes applied
18
- *
19
- * @example
20
- * const original = {
21
- * paths: {
22
- * '/users': {
23
- * get: { responses: { '200': { description: 'OK' } } }
24
- * }
25
- * }
26
- * }
27
- *
28
- * const changes = [
29
- * {
30
- * path: ['paths', '/users', 'get', 'responses', '200', 'content'],
31
- * type: 'add',
32
- * changes: { 'application/json': { schema: { type: 'object' } } }
33
- * }
34
- * ]
35
- *
36
- * const updated = apply(original, changes)
37
- * // Result: original document with content added to the 200 response
38
- */
39
- export const apply = <T extends Record<string, unknown>>(
40
- document: Record<string, unknown>,
41
- diff: Difference<T>[],
42
- ): T => {
43
- // Traverse the object and apply the change
44
- const applyChange = (current: any, path: string[], d: Difference<T>, depth = 0) => {
45
- if (path[depth] === undefined) {
46
- throw new InvalidChangesDetectedError(
47
- `Process aborted. Path ${path.join('.')} at depth ${depth} is undefined, check diff object`,
48
- )
49
- }
50
-
51
- // We reach where we want to be, now we can apply changes
52
- if (depth >= path.length - 1) {
53
- if (d.type === 'add' || d.type === 'update') {
54
- current[path[depth]] = d.changes
55
- } else {
56
- // For arrays we don't use delete operator since it will leave blank spots and not actually remove the element
57
- if (Array.isArray(current)) {
58
- current.splice(Number.parseInt(path[depth]), 1)
59
- } else {
60
- delete current[path[depth]]
61
- }
62
- }
63
- return
64
- }
65
-
66
- // Throw an error
67
- // This scenario should not happen
68
- // 1- if we are adding a new entry, the diff should only give us the higher level diff
69
- // 2- if we are updating/deleting an entry, the path to that entry should exists
70
- if (current[path[depth]] === undefined || typeof current[path[depth]] !== 'object') {
71
- throw new InvalidChangesDetectedError('Process aborted, check diff object')
72
- }
73
- applyChange(current[path[depth]], path, d, depth + 1)
74
- }
75
-
76
- for (const d of diff) {
77
- applyChange(document, d.path, d)
78
- }
79
-
80
- // It is safe to cast here because this function mutates the input document
81
- // to match the target type T as described by the diff changeset.
82
- return document as T
83
- }
@@ -1,328 +0,0 @@
1
- import { diff } from '@/diff'
2
- import { describe, expect, test } from 'vitest'
3
-
4
- describe('diff', () => {
5
- describe('Should correctly detect `add` type diff', () => {
6
- test('should correctly get added properties between two json objects', () => {
7
- const doc1 = {
8
- name: 'John',
9
- age: 25,
10
- }
11
-
12
- const doc2 = {
13
- ...doc1,
14
- address: {
15
- city: 'New York',
16
- street: '5th Avenue',
17
- },
18
- }
19
-
20
- expect(diff(doc1, doc2)).toEqual([{ path: ['address'], changes: doc2.address, type: 'add' }])
21
- })
22
-
23
- test('should correctly get added properties in nested objects between two json objects', () => {
24
- const doc1 = {
25
- name: 'John',
26
- age: 25,
27
- address: {
28
- city: 'New York',
29
- street: '5th Avenue',
30
- },
31
- }
32
-
33
- const doc2 = {
34
- ...doc1,
35
- address: {
36
- ...doc1.address,
37
- coordinates: {
38
- lat: 40.7128,
39
- long: 74.006,
40
- },
41
- },
42
- }
43
-
44
- expect(diff(doc1, doc2)).toEqual([
45
- {
46
- path: ['address', 'coordinates'],
47
- changes: doc2.address.coordinates,
48
- type: 'add',
49
- },
50
- ])
51
- })
52
-
53
- test('should correctly get added properties in deeply nested objects between two json objects', () => {
54
- const doc1 = {
55
- name: 'John',
56
- age: 25,
57
- address: {
58
- city: 'New York',
59
- street: '5th Avenue',
60
- coordinates: {
61
- lat: 40.7128,
62
- },
63
- },
64
- }
65
-
66
- const doc2 = {
67
- ...doc1,
68
- address: {
69
- ...doc1.address,
70
- coordinates: {
71
- ...doc1.address.coordinates,
72
- long: 74.006,
73
- },
74
- },
75
- }
76
-
77
- expect(diff(doc1, doc2)).toEqual([
78
- {
79
- path: ['address', 'coordinates', 'long'],
80
- changes: doc2.address.coordinates.long,
81
- type: 'add',
82
- },
83
- ])
84
- })
85
- })
86
-
87
- describe('Should correctly detect `update` type diff', () => {
88
- test('should correctly get updates on primitives between two objects', () => {
89
- const doc1 = {
90
- name: 'John',
91
- age: 25,
92
- address: {
93
- city: 'New York',
94
- street: '5th Avenue',
95
- },
96
- }
97
-
98
- const doc2: typeof doc1 = {
99
- ...doc1,
100
- age: 26,
101
- }
102
-
103
- expect(diff(doc1, doc2)).toEqual([{ path: ['age'], changes: doc2.age, type: 'update' }])
104
- })
105
-
106
- test('should correctly get updates on nested objects between two objects', () => {
107
- const doc1 = {
108
- name: 'John',
109
- age: 25,
110
- address: {
111
- city: 'New York',
112
- street: '5th Avenue',
113
- },
114
- }
115
-
116
- const doc2: typeof doc1 = {
117
- ...doc1,
118
- address: {
119
- ...doc1.address,
120
- city: 'Los Angeles',
121
- },
122
- }
123
-
124
- expect(diff(doc1, doc2)).toEqual([
125
- {
126
- path: ['address', 'city'],
127
- changes: doc2.address.city,
128
- type: 'update',
129
- },
130
- ])
131
- })
132
-
133
- test('should correctly get updates when the type is different', () => {
134
- const doc1 = {
135
- name: 'John',
136
- age: 25,
137
- address: {
138
- city: 'New York',
139
- street: '5th Avenue',
140
- },
141
- isStudent: 1,
142
- }
143
-
144
- const doc2 = {
145
- ...doc1,
146
- isStudent: true,
147
- }
148
-
149
- expect(diff(doc1, doc2)).toEqual([{ path: ['isStudent'], changes: doc2.isStudent, type: 'update' }])
150
- })
151
- })
152
-
153
- describe('Should correctly detect `delete` type diff', () => {
154
- test('should correctly get removed properties between two objects', () => {
155
- const doc2 = {
156
- name: 'John',
157
- age: 25,
158
- }
159
-
160
- const doc1 = {
161
- ...doc2,
162
- address: {
163
- city: 'New York',
164
- street: '5th Avenue',
165
- },
166
- }
167
-
168
- expect(diff(doc1, doc2)).toEqual([{ path: ['address'], changes: doc1.address, type: 'delete' }])
169
- })
170
-
171
- test('should correctly get removed properties on deeply nested objects', () => {
172
- const doc2 = {
173
- name: 'John',
174
- age: 25,
175
- address: {
176
- city: 'New York',
177
- street: '5th Avenue',
178
- },
179
- }
180
-
181
- const doc1 = {
182
- ...doc2,
183
- address: {
184
- ...doc2.address,
185
- coordinates: {
186
- lat: 40.7128,
187
- long: 74.006,
188
- },
189
- },
190
- }
191
-
192
- expect(diff(doc1, doc2)).toEqual([
193
- {
194
- path: ['address', 'coordinates'],
195
- changes: doc1.address.coordinates,
196
- type: 'delete',
197
- },
198
- ])
199
- })
200
- })
201
-
202
- describe('Should correctly detect changes on arrays', () => {
203
- test('detect adding elements on arrays of primitives', () => {
204
- const doc1 = {
205
- name: 'John',
206
- age: 25,
207
- hobbies: ['reading', 'running'],
208
- }
209
-
210
- const doc2 = {
211
- ...doc1,
212
- hobbies: ['reading', 'running', 'swimming'],
213
- }
214
-
215
- expect(diff(doc1, doc2)).toEqual([{ path: ['hobbies', '2'], changes: doc2.hobbies[2], type: 'add' }])
216
- })
217
-
218
- test('detect adding elements on arrays of objects', () => {
219
- const doc1 = {
220
- name: 'John',
221
- age: 25,
222
- hobbies: [
223
- { name: 'reading', duration: 2 },
224
- { name: 'running', duration: 1 },
225
- ],
226
- }
227
-
228
- const doc2 = {
229
- ...doc1,
230
- hobbies: [...doc1.hobbies, { name: 'swimming', duration: 3 }],
231
- }
232
-
233
- expect(diff(doc1, doc2)).toEqual([{ path: ['hobbies', '2'], changes: doc2.hobbies[2], type: 'add' }])
234
- })
235
-
236
- test('detects updates on objects on array of objects', () => {
237
- const doc1 = {
238
- name: 'John',
239
- age: 25,
240
- hobbies: [
241
- { name: 'reading', duration: 2 },
242
- { name: 'running', duration: 1 },
243
- ],
244
- }
245
-
246
- const doc2 = {
247
- ...doc1,
248
- hobbies: [doc1.hobbies[0], { name: 'swimming', duration: 3 }],
249
- }
250
-
251
- expect(diff(doc1, doc2)).toEqual([
252
- {
253
- path: ['hobbies', '1', 'name'],
254
- changes: doc2.hobbies[1]?.name,
255
- type: 'update',
256
- },
257
- {
258
- path: ['hobbies', '1', 'duration'],
259
- changes: doc2.hobbies[1]?.duration,
260
- type: 'update',
261
- },
262
- ])
263
- })
264
-
265
- test('detects delete operations on array of objects', () => {
266
- const doc1 = {
267
- name: 'John',
268
- age: 25,
269
- hobbies: [
270
- { name: 'reading', duration: 2 },
271
- { name: 'running', duration: 1 },
272
- ],
273
- }
274
-
275
- const doc2 = {
276
- ...doc1,
277
- hobbies: [doc1.hobbies[0]],
278
- }
279
-
280
- expect(diff(doc1, doc2)).toEqual([{ path: ['hobbies', '1'], changes: doc1.hobbies[1], type: 'delete' }])
281
- })
282
- })
283
-
284
- test('Should correctly detect multiple changes', () => {
285
- const doc1 = {
286
- name: 'John',
287
- age: 25,
288
- address: {
289
- city: 'New York',
290
- street: '5th Avenue',
291
- },
292
- hobbies: [
293
- { name: 'reading', duration: 2 },
294
- { name: 'running', duration: 1 },
295
- ],
296
- isStudent: true,
297
- }
298
-
299
- const doc2 = {
300
- ...(doc1 as Partial<typeof doc1>), // Partial is needed to remove the key student key from doc2
301
- age: 26,
302
- address: {
303
- ...doc1.address,
304
- city: 'Los Angeles',
305
- },
306
- hobbies: [doc1.hobbies[0], { name: 'swimming', duration: 3 }, { name: 'running', duration: 2 }],
307
- }
308
-
309
- delete doc2.isStudent
310
-
311
- expect(diff(doc1, doc2)).toEqual([
312
- { path: ['age'], changes: doc2.age, type: 'update' },
313
- { path: ['address', 'city'], changes: doc2.address.city, type: 'update' },
314
- {
315
- path: ['hobbies', '1', 'name'],
316
- changes: doc2.hobbies[1]?.name,
317
- type: 'update',
318
- },
319
- {
320
- path: ['hobbies', '1', 'duration'],
321
- changes: doc2.hobbies[1]?.duration,
322
- type: 'update',
323
- },
324
- { path: ['hobbies', '2'], changes: doc2.hobbies[2], type: 'add' },
325
- { path: ['isStudent'], changes: doc1.isStudent, type: 'delete' },
326
- ])
327
- })
328
- })