@capture.dev/fast-json-patch 3.2.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/dist/index.cjs ADDED
@@ -0,0 +1,766 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
+ JsonPatchError: () => PatchError,
23
+ _areEquals: () => _areEquals,
24
+ applyOperation: () => applyOperation,
25
+ applyPatch: () => applyPatch,
26
+ applyReducer: () => applyReducer,
27
+ compare: () => compare,
28
+ deepClone: () => _deepClone,
29
+ escapePathComponent: () => escapePathComponent,
30
+ generate: () => generate,
31
+ getValueByPointer: () => getValueByPointer,
32
+ observe: () => observe,
33
+ unescapePathComponent: () => unescapePathComponent,
34
+ unobserve: () => unobserve,
35
+ validate: () => validate,
36
+ validator: () => validator
37
+ });
38
+ module.exports = __toCommonJS(index_exports);
39
+
40
+ // src/helpers.ts
41
+ var _hasOwnProperty = Object.prototype.hasOwnProperty;
42
+ function hasOwnProperty(obj, key) {
43
+ return _hasOwnProperty.call(obj, key);
44
+ }
45
+ function _objectKeys(obj) {
46
+ if (Array.isArray(obj)) {
47
+ const keys2 = new Array(obj.length);
48
+ for (let k = 0; k < keys2.length; k++) {
49
+ keys2[k] = "" + k;
50
+ }
51
+ return keys2;
52
+ }
53
+ if (Object.keys) {
54
+ return Object.keys(obj);
55
+ }
56
+ let keys = [];
57
+ for (let i in obj) {
58
+ if (hasOwnProperty(obj, i)) {
59
+ keys.push(i);
60
+ }
61
+ }
62
+ return keys;
63
+ }
64
+ function _deepClone(obj) {
65
+ switch (typeof obj) {
66
+ case "object":
67
+ return JSON.parse(JSON.stringify(obj));
68
+ //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5
69
+ case "undefined":
70
+ return null;
71
+ //this is how JSON.stringify behaves for array items
72
+ default:
73
+ return obj;
74
+ }
75
+ }
76
+ function isInteger(str) {
77
+ let i = 0;
78
+ const len = str.length;
79
+ let charCode;
80
+ while (i < len) {
81
+ charCode = str.charCodeAt(i);
82
+ if (charCode >= 48 && charCode <= 57) {
83
+ i++;
84
+ continue;
85
+ }
86
+ return false;
87
+ }
88
+ return true;
89
+ }
90
+ function escapePathComponent(path) {
91
+ if (path.indexOf("/") === -1 && path.indexOf("~") === -1) return path;
92
+ return path.replace(/~/g, "~0").replace(/\//g, "~1");
93
+ }
94
+ function unescapePathComponent(path) {
95
+ return path.replace(/~1/g, "/").replace(/~0/g, "~");
96
+ }
97
+ function hasUndefined(obj) {
98
+ if (obj === void 0) {
99
+ return true;
100
+ }
101
+ if (obj) {
102
+ if (Array.isArray(obj)) {
103
+ for (let i2 = 0, len = obj.length; i2 < len; i2++) {
104
+ if (hasUndefined(obj[i2])) {
105
+ return true;
106
+ }
107
+ }
108
+ } else if (typeof obj === "object") {
109
+ const objKeys = _objectKeys(obj);
110
+ const objKeysLength = objKeys.length;
111
+ for (var i = 0; i < objKeysLength; i++) {
112
+ if (hasUndefined(obj[objKeys[i]])) {
113
+ return true;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ return false;
119
+ }
120
+ function patchErrorMessageFormatter(message, args) {
121
+ const messageParts = [message];
122
+ for (const key in args) {
123
+ const value = typeof args[key] === "object" ? JSON.stringify(args[key], null, 2) : args[key];
124
+ if (typeof value !== "undefined") {
125
+ messageParts.push(`${key}: ${value}`);
126
+ }
127
+ }
128
+ return messageParts.join("\n");
129
+ }
130
+ var PatchError = class extends Error {
131
+ constructor(message, name, index, operation, tree) {
132
+ super(
133
+ patchErrorMessageFormatter(message, { name, index, operation, tree })
134
+ );
135
+ this.name = name;
136
+ this.index = index;
137
+ this.operation = operation;
138
+ this.tree = tree;
139
+ Object.setPrototypeOf(this, new.target.prototype);
140
+ this.message = patchErrorMessageFormatter(message, {
141
+ name,
142
+ index,
143
+ operation,
144
+ tree
145
+ });
146
+ }
147
+ };
148
+
149
+ // src/core.ts
150
+ var JsonPatchError = PatchError;
151
+ var objOps = {
152
+ add: function(obj, key, document) {
153
+ obj[key] = this.value;
154
+ return { newDocument: document };
155
+ },
156
+ remove: function(obj, key, document) {
157
+ var removed = obj[key];
158
+ delete obj[key];
159
+ return { newDocument: document, removed };
160
+ },
161
+ replace: function(obj, key, document) {
162
+ var removed = obj[key];
163
+ obj[key] = this.value;
164
+ return { newDocument: document, removed };
165
+ },
166
+ move: function(obj, key, document) {
167
+ let removed = getValueByPointer(document, this.path);
168
+ if (removed) {
169
+ removed = _deepClone(removed);
170
+ }
171
+ const originalValue = applyOperation(document, {
172
+ op: "remove",
173
+ path: this.from
174
+ }).removed;
175
+ applyOperation(document, {
176
+ op: "add",
177
+ path: this.path,
178
+ value: originalValue
179
+ });
180
+ return { newDocument: document, removed };
181
+ },
182
+ copy: function(obj, key, document) {
183
+ const valueToCopy = getValueByPointer(document, this.from);
184
+ applyOperation(document, {
185
+ op: "add",
186
+ path: this.path,
187
+ value: _deepClone(valueToCopy)
188
+ });
189
+ return { newDocument: document };
190
+ },
191
+ test: function(obj, key, document) {
192
+ return { newDocument: document, test: _areEquals(obj[key], this.value) };
193
+ },
194
+ _get: function(obj, key, document) {
195
+ this.value = obj[key];
196
+ return { newDocument: document };
197
+ }
198
+ };
199
+ var arrOps = {
200
+ add: function(arr, i, document) {
201
+ if (isInteger(i)) {
202
+ arr.splice(i, 0, this.value);
203
+ } else {
204
+ arr[i] = this.value;
205
+ }
206
+ return { newDocument: document, index: i };
207
+ },
208
+ remove: function(arr, i, document) {
209
+ var removedList = arr.splice(i, 1);
210
+ return { newDocument: document, removed: removedList[0] };
211
+ },
212
+ replace: function(arr, i, document) {
213
+ var removed = arr[i];
214
+ arr[i] = this.value;
215
+ return { newDocument: document, removed };
216
+ },
217
+ move: objOps.move,
218
+ copy: objOps.copy,
219
+ test: objOps.test,
220
+ _get: objOps._get
221
+ };
222
+ function getValueByPointer(document, pointer) {
223
+ if (pointer == "") {
224
+ return document;
225
+ }
226
+ var getOriginalDestination = { op: "_get", path: pointer };
227
+ applyOperation(document, getOriginalDestination);
228
+ return getOriginalDestination.value;
229
+ }
230
+ function applyOperation(document, operation, validateOperation = false, mutateDocument = true, banPrototypeModifications = true, index = 0) {
231
+ if (validateOperation) {
232
+ if (typeof validateOperation == "function") {
233
+ validateOperation(operation, 0, document, operation.path);
234
+ } else {
235
+ validator(operation, 0);
236
+ }
237
+ }
238
+ if (operation.path === "") {
239
+ let returnValue = { newDocument: document };
240
+ if (operation.op === "add") {
241
+ returnValue.newDocument = operation.value;
242
+ return returnValue;
243
+ } else if (operation.op === "replace") {
244
+ returnValue.newDocument = operation.value;
245
+ returnValue.removed = document;
246
+ return returnValue;
247
+ } else if (operation.op === "move" || operation.op === "copy") {
248
+ returnValue.newDocument = getValueByPointer(document, operation.from);
249
+ if (operation.op === "move") {
250
+ returnValue.removed = document;
251
+ }
252
+ return returnValue;
253
+ } else if (operation.op === "test") {
254
+ returnValue.test = _areEquals(document, operation.value);
255
+ if (returnValue.test === false) {
256
+ throw new JsonPatchError(
257
+ "Test operation failed",
258
+ "TEST_OPERATION_FAILED",
259
+ index,
260
+ operation,
261
+ document
262
+ );
263
+ }
264
+ returnValue.newDocument = document;
265
+ return returnValue;
266
+ } else if (operation.op === "remove") {
267
+ returnValue.removed = document;
268
+ returnValue.newDocument = null;
269
+ return returnValue;
270
+ } else if (operation.op === "_get") {
271
+ operation.value = document;
272
+ return returnValue;
273
+ } else {
274
+ if (validateOperation) {
275
+ throw new JsonPatchError(
276
+ "Operation `op` property is not one of operations defined in RFC-6902",
277
+ "OPERATION_OP_INVALID",
278
+ index,
279
+ operation,
280
+ document
281
+ );
282
+ } else {
283
+ return returnValue;
284
+ }
285
+ }
286
+ } else {
287
+ if (!mutateDocument) {
288
+ document = _deepClone(document);
289
+ }
290
+ const path = operation.path || "";
291
+ const keys = path.split("/");
292
+ let obj = document;
293
+ let t = 1;
294
+ let len = keys.length;
295
+ let existingPathFragment = void 0;
296
+ let key;
297
+ let validateFunction;
298
+ if (typeof validateOperation == "function") {
299
+ validateFunction = validateOperation;
300
+ } else {
301
+ validateFunction = validator;
302
+ }
303
+ while (true) {
304
+ key = keys[t];
305
+ if (key && key.indexOf("~") != -1) {
306
+ key = unescapePathComponent(key);
307
+ }
308
+ if (banPrototypeModifications && (key == "__proto__" || key == "prototype" && t > 0 && keys[t - 1] == "constructor")) {
309
+ throw new TypeError(
310
+ "JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README"
311
+ );
312
+ }
313
+ if (validateOperation) {
314
+ if (existingPathFragment === void 0) {
315
+ if (obj[key] === void 0) {
316
+ existingPathFragment = keys.slice(0, t).join("/");
317
+ } else if (t == len - 1) {
318
+ existingPathFragment = operation.path;
319
+ }
320
+ if (existingPathFragment !== void 0) {
321
+ validateFunction(operation, 0, document, existingPathFragment);
322
+ }
323
+ }
324
+ }
325
+ t++;
326
+ if (Array.isArray(obj)) {
327
+ if (key === "-") {
328
+ key = obj.length;
329
+ } else {
330
+ if (validateOperation && !isInteger(key)) {
331
+ throw new JsonPatchError(
332
+ "Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index",
333
+ "OPERATION_PATH_ILLEGAL_ARRAY_INDEX",
334
+ index,
335
+ operation,
336
+ document
337
+ );
338
+ } else if (isInteger(key)) {
339
+ key = ~~key;
340
+ }
341
+ }
342
+ if (t >= len) {
343
+ if (validateOperation && operation.op === "add" && typeof key === "number" && key > obj.length) {
344
+ throw new JsonPatchError(
345
+ "The specified index MUST NOT be greater than the number of elements in the array",
346
+ "OPERATION_VALUE_OUT_OF_BOUNDS",
347
+ index,
348
+ operation,
349
+ document
350
+ );
351
+ }
352
+ const returnValue = arrOps[operation.op].call(
353
+ operation,
354
+ obj,
355
+ key,
356
+ document
357
+ );
358
+ if (returnValue.test === false) {
359
+ throw new JsonPatchError(
360
+ "Test operation failed",
361
+ "TEST_OPERATION_FAILED",
362
+ index,
363
+ operation,
364
+ document
365
+ );
366
+ }
367
+ return returnValue;
368
+ }
369
+ } else {
370
+ if (t >= len) {
371
+ const returnValue = objOps[operation.op].call(
372
+ operation,
373
+ obj,
374
+ key,
375
+ document
376
+ );
377
+ if (returnValue.test === false) {
378
+ throw new JsonPatchError(
379
+ "Test operation failed",
380
+ "TEST_OPERATION_FAILED",
381
+ index,
382
+ operation,
383
+ document
384
+ );
385
+ }
386
+ return returnValue;
387
+ }
388
+ }
389
+ obj = obj[key];
390
+ if (validateOperation && t < len && (!obj || typeof obj !== "object")) {
391
+ throw new JsonPatchError(
392
+ "Cannot perform operation at the desired path",
393
+ "OPERATION_PATH_UNRESOLVABLE",
394
+ index,
395
+ operation,
396
+ document
397
+ );
398
+ }
399
+ }
400
+ }
401
+ }
402
+ function applyPatch(document, patch, validateOperation, mutateDocument = true, banPrototypeModifications = true) {
403
+ if (validateOperation) {
404
+ if (!Array.isArray(patch)) {
405
+ throw new JsonPatchError(
406
+ "Patch sequence must be an array",
407
+ "SEQUENCE_NOT_AN_ARRAY"
408
+ );
409
+ }
410
+ }
411
+ if (!mutateDocument) {
412
+ document = _deepClone(document);
413
+ }
414
+ const results = new Array(patch.length);
415
+ for (let i = 0, length = patch.length; i < length; i++) {
416
+ results[i] = applyOperation(
417
+ document,
418
+ patch[i],
419
+ validateOperation,
420
+ true,
421
+ banPrototypeModifications,
422
+ i
423
+ );
424
+ document = results[i].newDocument;
425
+ }
426
+ results.newDocument = document;
427
+ return results;
428
+ }
429
+ function applyReducer(document, operation, index) {
430
+ const operationResult = applyOperation(
431
+ document,
432
+ operation
433
+ );
434
+ if (operationResult.test === false) {
435
+ throw new JsonPatchError(
436
+ "Test operation failed",
437
+ "TEST_OPERATION_FAILED",
438
+ index,
439
+ operation,
440
+ document
441
+ );
442
+ }
443
+ return operationResult.newDocument;
444
+ }
445
+ function validator(operation, index, document, existingPathFragment) {
446
+ if (typeof operation !== "object" || operation === null || Array.isArray(operation)) {
447
+ throw new JsonPatchError(
448
+ "Operation is not an object",
449
+ "OPERATION_NOT_AN_OBJECT",
450
+ index,
451
+ operation,
452
+ document
453
+ );
454
+ } else if (!objOps[operation.op]) {
455
+ throw new JsonPatchError(
456
+ "Operation `op` property is not one of operations defined in RFC-6902",
457
+ "OPERATION_OP_INVALID",
458
+ index,
459
+ operation,
460
+ document
461
+ );
462
+ } else if (typeof operation.path !== "string") {
463
+ throw new JsonPatchError(
464
+ "Operation `path` property is not a string",
465
+ "OPERATION_PATH_INVALID",
466
+ index,
467
+ operation,
468
+ document
469
+ );
470
+ } else if (operation.path.indexOf("/") !== 0 && operation.path.length > 0) {
471
+ throw new JsonPatchError(
472
+ 'Operation `path` property must start with "/"',
473
+ "OPERATION_PATH_INVALID",
474
+ index,
475
+ operation,
476
+ document
477
+ );
478
+ } else if ((operation.op === "move" || operation.op === "copy") && typeof operation.from !== "string") {
479
+ throw new JsonPatchError(
480
+ "Operation `from` property is not present (applicable in `move` and `copy` operations)",
481
+ "OPERATION_FROM_REQUIRED",
482
+ index,
483
+ operation,
484
+ document
485
+ );
486
+ } else if ((operation.op === "add" || operation.op === "replace" || operation.op === "test") && operation.value === void 0) {
487
+ throw new JsonPatchError(
488
+ "Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)",
489
+ "OPERATION_VALUE_REQUIRED",
490
+ index,
491
+ operation,
492
+ document
493
+ );
494
+ } else if ((operation.op === "add" || operation.op === "replace" || operation.op === "test") && hasUndefined(operation.value)) {
495
+ throw new JsonPatchError(
496
+ "Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)",
497
+ "OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",
498
+ index,
499
+ operation,
500
+ document
501
+ );
502
+ } else if (document) {
503
+ if (operation.op == "add") {
504
+ var pathLen = operation.path.split("/").length;
505
+ var existingPathLen = existingPathFragment.split("/").length;
506
+ if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) {
507
+ throw new JsonPatchError(
508
+ "Cannot perform an `add` operation at the desired path",
509
+ "OPERATION_PATH_CANNOT_ADD",
510
+ index,
511
+ operation,
512
+ document
513
+ );
514
+ }
515
+ } else if (operation.op === "replace" || operation.op === "remove" || operation.op === "_get") {
516
+ if (operation.path !== existingPathFragment) {
517
+ throw new JsonPatchError(
518
+ "Cannot perform the operation at a path that does not exist",
519
+ "OPERATION_PATH_UNRESOLVABLE",
520
+ index,
521
+ operation,
522
+ document
523
+ );
524
+ }
525
+ } else if (operation.op === "move" || operation.op === "copy") {
526
+ var existingValue = {
527
+ op: "_get",
528
+ path: operation.from,
529
+ value: void 0
530
+ };
531
+ var error = validate([existingValue], document);
532
+ if (error && error.name === "OPERATION_PATH_UNRESOLVABLE") {
533
+ throw new JsonPatchError(
534
+ "Cannot perform the operation from a path that does not exist",
535
+ "OPERATION_FROM_UNRESOLVABLE",
536
+ index,
537
+ operation,
538
+ document
539
+ );
540
+ }
541
+ }
542
+ }
543
+ }
544
+ function validate(sequence, document, externalValidator) {
545
+ try {
546
+ if (!Array.isArray(sequence)) {
547
+ throw new JsonPatchError(
548
+ "Patch sequence must be an array",
549
+ "SEQUENCE_NOT_AN_ARRAY"
550
+ );
551
+ }
552
+ if (document) {
553
+ applyPatch(
554
+ _deepClone(document),
555
+ _deepClone(sequence),
556
+ externalValidator || true
557
+ );
558
+ } else {
559
+ externalValidator = externalValidator || validator;
560
+ for (var i = 0; i < sequence.length; i++) {
561
+ externalValidator(sequence[i], i, document, void 0);
562
+ }
563
+ }
564
+ } catch (e) {
565
+ if (e instanceof JsonPatchError) {
566
+ return e;
567
+ } else {
568
+ throw e;
569
+ }
570
+ }
571
+ }
572
+ function _areEquals(a, b) {
573
+ if (a === b) return true;
574
+ if (a && b && typeof a == "object" && typeof b == "object") {
575
+ var arrA = Array.isArray(a), arrB = Array.isArray(b), i, length, key;
576
+ if (arrA && arrB) {
577
+ length = a.length;
578
+ if (length != b.length) return false;
579
+ for (i = length; i-- !== 0; ) if (!_areEquals(a[i], b[i])) return false;
580
+ return true;
581
+ }
582
+ if (arrA != arrB) return false;
583
+ var keys = Object.keys(a);
584
+ length = keys.length;
585
+ if (length !== Object.keys(b).length) return false;
586
+ for (i = length; i-- !== 0; ) if (!b.hasOwnProperty(keys[i])) return false;
587
+ for (i = length; i-- !== 0; ) {
588
+ key = keys[i];
589
+ if (!_areEquals(a[key], b[key])) return false;
590
+ }
591
+ return true;
592
+ }
593
+ return a !== a && b !== b;
594
+ }
595
+
596
+ // src/duplex.ts
597
+ var beforeDict = /* @__PURE__ */ new WeakMap();
598
+ var Mirror = class {
599
+ constructor(obj) {
600
+ this.observers = /* @__PURE__ */ new Map();
601
+ this.obj = obj;
602
+ }
603
+ };
604
+ var ObserverInfo = class {
605
+ constructor(callback, observer) {
606
+ this.callback = callback;
607
+ this.observer = observer;
608
+ }
609
+ };
610
+ function getMirror(obj) {
611
+ return beforeDict.get(obj);
612
+ }
613
+ function getObserverFromMirror(mirror, callback) {
614
+ return mirror.observers.get(callback);
615
+ }
616
+ function removeObserverFromMirror(mirror, observer) {
617
+ mirror.observers.delete(observer.callback);
618
+ }
619
+ function unobserve(root, observer) {
620
+ observer.unobserve();
621
+ }
622
+ function observe(obj, callback) {
623
+ var patches = [];
624
+ var observer;
625
+ var mirror = getMirror(obj);
626
+ if (!mirror) {
627
+ mirror = new Mirror(obj);
628
+ beforeDict.set(obj, mirror);
629
+ } else {
630
+ const observerInfo = getObserverFromMirror(mirror, callback);
631
+ observer = observerInfo && observerInfo.observer;
632
+ }
633
+ if (observer) {
634
+ return observer;
635
+ }
636
+ observer = {};
637
+ mirror.value = _deepClone(obj);
638
+ if (callback) {
639
+ observer.callback = callback;
640
+ observer.next = null;
641
+ var dirtyCheck = () => {
642
+ generate(observer);
643
+ };
644
+ var fastCheck = () => {
645
+ clearTimeout(observer.next);
646
+ observer.next = setTimeout(dirtyCheck);
647
+ };
648
+ if (typeof window !== "undefined") {
649
+ window.addEventListener("mouseup", fastCheck);
650
+ window.addEventListener("keyup", fastCheck);
651
+ window.addEventListener("mousedown", fastCheck);
652
+ window.addEventListener("keydown", fastCheck);
653
+ window.addEventListener("change", fastCheck);
654
+ }
655
+ }
656
+ observer.patches = patches;
657
+ observer.object = obj;
658
+ observer.unobserve = () => {
659
+ generate(observer);
660
+ clearTimeout(observer.next);
661
+ removeObserverFromMirror(mirror, observer);
662
+ if (typeof window !== "undefined") {
663
+ window.removeEventListener("mouseup", fastCheck);
664
+ window.removeEventListener("keyup", fastCheck);
665
+ window.removeEventListener("mousedown", fastCheck);
666
+ window.removeEventListener("keydown", fastCheck);
667
+ window.removeEventListener("change", fastCheck);
668
+ }
669
+ };
670
+ mirror.observers.set(callback, new ObserverInfo(callback, observer));
671
+ return observer;
672
+ }
673
+ function generate(observer, invertible = false) {
674
+ var mirror = beforeDict.get(observer.object);
675
+ _generate(mirror.value, observer.object, observer.patches, "", invertible);
676
+ if (observer.patches.length) {
677
+ applyPatch(mirror.value, observer.patches);
678
+ }
679
+ var temp = observer.patches;
680
+ if (temp.length > 0) {
681
+ observer.patches = [];
682
+ if (observer.callback) {
683
+ observer.callback(temp);
684
+ }
685
+ }
686
+ return temp;
687
+ }
688
+ function _generate(mirror, obj, patches, path, invertible) {
689
+ if (obj === mirror) {
690
+ return;
691
+ }
692
+ if (typeof obj.toJSON === "function") {
693
+ obj = obj.toJSON();
694
+ }
695
+ var newKeys = _objectKeys(obj);
696
+ var oldKeys = _objectKeys(mirror);
697
+ var changed = false;
698
+ var deleted = false;
699
+ for (var t = oldKeys.length - 1; t >= 0; t--) {
700
+ var key = oldKeys[t];
701
+ var oldVal = mirror[key];
702
+ if (hasOwnProperty(obj, key) && !(obj[key] === void 0 && oldVal !== void 0 && Array.isArray(obj) === false)) {
703
+ var newVal = obj[key];
704
+ if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) {
705
+ _generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key), invertible);
706
+ } else {
707
+ if (oldVal !== newVal) {
708
+ changed = true;
709
+ if (invertible) {
710
+ patches.push({ op: "test", path: path + "/" + escapePathComponent(key), value: _deepClone(oldVal) });
711
+ }
712
+ patches.push({ op: "replace", path: path + "/" + escapePathComponent(key), value: _deepClone(newVal) });
713
+ }
714
+ }
715
+ } else if (Array.isArray(mirror) === Array.isArray(obj)) {
716
+ if (invertible) {
717
+ patches.push({ op: "test", path: path + "/" + escapePathComponent(key), value: _deepClone(oldVal) });
718
+ }
719
+ patches.push({ op: "remove", path: path + "/" + escapePathComponent(key) });
720
+ deleted = true;
721
+ } else {
722
+ if (invertible) {
723
+ patches.push({ op: "test", path, value: mirror });
724
+ }
725
+ patches.push({ op: "replace", path, value: obj });
726
+ changed = true;
727
+ }
728
+ }
729
+ if (!deleted && newKeys.length == oldKeys.length) {
730
+ return;
731
+ }
732
+ for (var t = 0; t < newKeys.length; t++) {
733
+ var key = newKeys[t];
734
+ if (!hasOwnProperty(mirror, key) && obj[key] !== void 0) {
735
+ patches.push({ op: "add", path: path + "/" + escapePathComponent(key), value: _deepClone(obj[key]) });
736
+ }
737
+ }
738
+ }
739
+ function compare(tree1, tree2, invertible = false) {
740
+ var patches = [];
741
+ _generate(tree1, tree2, patches, "", invertible);
742
+ return patches;
743
+ }
744
+ // Annotate the CommonJS export names for ESM import in node:
745
+ 0 && (module.exports = {
746
+ JsonPatchError,
747
+ _areEquals,
748
+ applyOperation,
749
+ applyPatch,
750
+ applyReducer,
751
+ compare,
752
+ deepClone,
753
+ escapePathComponent,
754
+ generate,
755
+ getValueByPointer,
756
+ observe,
757
+ unescapePathComponent,
758
+ unobserve,
759
+ validate,
760
+ validator
761
+ });
762
+ /*!
763
+ * https://github.com/Starcounter-Jack/JSON-Patch
764
+ * (c) 2017-2021 Joachim Wester
765
+ * MIT license
766
+ */