json-p3 2.2.2 → 2.3.1

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.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * json-p3 version 2.2.2
2
+ * json-p3 version 2.3.1
3
3
  * https://github.com/jg-rp/json-p3
4
4
  *
5
5
  * MIT License
@@ -335,10 +335,7 @@ class JSONPointer {
335
335
  }
336
336
  static encode(tokens) {
337
337
  if (!tokens.length) return "";
338
- return (
339
- // eslint-disable-next-line prefer-template
340
- "/" + tokens.map(token => token.replaceAll("~", "~0").replaceAll("/", "~1")).join("/")
341
- );
338
+ return "/" + tokens.map(token => token.replaceAll("~", "~0").replaceAll("/", "~1")).join("/");
342
339
  }
343
340
 
344
341
  /**
@@ -355,8 +352,7 @@ class JSONPointer {
355
352
  * If the value pointed to by _pointer_ does not exist in _value_, and
356
353
  * no fallback value is given.
357
354
  */
358
- resolve(value) {
359
- let fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : UNDEFINED;
355
+ resolve(value, fallback = UNDEFINED) {
360
356
  try {
361
357
  return this.tokens.reduce(this.getItem.bind(this), value);
362
358
  } catch (error) {
@@ -461,10 +457,7 @@ class JSONPointer {
461
457
  * @returns A new JSON Pointer that is the concatenation of all tokens or
462
458
  * "parts".
463
459
  */
464
- join() {
465
- for (var _len = arguments.length, tokens = new Array(_len), _key = 0; _key < _len; _key++) {
466
- tokens[_key] = arguments[_key];
467
- }
460
+ join(...tokens) {
468
461
  if (!tokens.length) {
469
462
  return this;
470
463
  }
@@ -513,7 +506,7 @@ class JSONPointer {
513
506
  }
514
507
  }
515
508
  const RE_RELATIVE_POINTER = /(?<ORIGIN>\d+)(?<INDEX_G>(?<SIGN>[+-])(?<INDEX>\d))?(?<POINTER>.*)/s;
516
- const RE_INT = /(0|[1-9][0-9]*)/;
509
+ const RE_INT = /(0|[1-9]\d*)/;
517
510
 
518
511
  /**
519
512
  * A relative JSON Pointer.
@@ -632,8 +625,7 @@ class RelativeJSONPointer {
632
625
  * @throws {@link JSONPointerSyntaxError}
633
626
  * If _pointer_ is malformed according to RFC 6901.
634
627
  */
635
- function resolve(pointer, value) {
636
- let fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : UNDEFINED;
628
+ function resolve(pointer, value, fallback = UNDEFINED) {
637
629
  return new JSONPointer(pointer).resolve(value, fallback);
638
630
  }
639
631
 
@@ -737,10 +729,7 @@ class JSONPathNode {
737
729
  ...defaultSerializationOptions,
738
730
  ...options
739
731
  };
740
- return (
741
- // eslint-disable-next-line prefer-template
742
- "$" + this.location.map(s => isString(s) ? this.decodeNameLocation(s, opts) : `[${s}]`).join("")
743
- );
732
+ return "$" + this.location.map(s => isString(s) ? this.decodeNameLocation(s, opts) : `[${s}]`).join("");
744
733
  }
745
734
 
746
735
  /**
@@ -1135,16 +1124,16 @@ var expression = /*#__PURE__*/Object.freeze({
1135
1124
  });
1136
1125
 
1137
1126
  class Count {
1138
- argTypes = (() => [FunctionExpressionType.NodesType])();
1139
- returnType = (() => FunctionExpressionType.ValueType)();
1127
+ argTypes = [FunctionExpressionType.NodesType];
1128
+ returnType = FunctionExpressionType.ValueType;
1140
1129
  call(nodes) {
1141
1130
  return nodes.length;
1142
1131
  }
1143
1132
  }
1144
1133
 
1145
1134
  class Length {
1146
- argTypes = (() => [FunctionExpressionType.ValueType])();
1147
- returnType = (() => FunctionExpressionType.ValueType)();
1135
+ argTypes = [FunctionExpressionType.ValueType];
1136
+ returnType = FunctionExpressionType.ValueType;
1148
1137
  call(value) {
1149
1138
  if (isArray(value) || isString(value)) return value.length;
1150
1139
  if (isObject(value)) return Object.keys(value).length;
@@ -1156,9 +1145,7 @@ class Length {
1156
1145
  * A Least Recently Used cache, implemented as an extended Map.
1157
1146
  */
1158
1147
  class LRUCache extends Map {
1159
- constructor() {
1160
- let maxSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 128;
1161
- let entries = arguments.length > 1 ? arguments[1] : undefined;
1148
+ constructor(maxSize = 128, entries) {
1162
1149
  if (entries !== undefined) {
1163
1150
  super(entries);
1164
1151
  } else {
@@ -2476,11 +2463,10 @@ var check_1 = {
2476
2463
  var check$1 = check_1.check;
2477
2464
 
2478
2465
  class Match {
2479
- argTypes = (() => [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType])();
2480
- returnType = (() => FunctionExpressionType.LogicalType)();
2466
+ argTypes = [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType];
2467
+ returnType = FunctionExpressionType.LogicalType;
2481
2468
  #cache;
2482
- constructor() {
2483
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2469
+ constructor(options = {}) {
2484
2470
  this.options = options;
2485
2471
  this.cacheSize = options.cacheSize ?? 10;
2486
2472
  this.throwErrors = options.throwErrors ?? false;
@@ -2525,11 +2511,10 @@ class Match {
2525
2511
  }
2526
2512
 
2527
2513
  class Search {
2528
- argTypes = (() => [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType])();
2529
- returnType = (() => FunctionExpressionType.LogicalType)();
2514
+ argTypes = [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType];
2515
+ returnType = FunctionExpressionType.LogicalType;
2530
2516
  #cache;
2531
- constructor() {
2532
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2517
+ constructor(options = {}) {
2533
2518
  this.options = options;
2534
2519
  this.cacheSize = options.cacheSize ?? 10;
2535
2520
  this.throwErrors = options.throwErrors ?? false;
@@ -2574,8 +2559,8 @@ class Search {
2574
2559
  }
2575
2560
 
2576
2561
  class Value {
2577
- argTypes = (() => [FunctionExpressionType.NodesType])();
2578
- returnType = (() => FunctionExpressionType.ValueType)();
2562
+ argTypes = [FunctionExpressionType.NodesType];
2563
+ returnType = FunctionExpressionType.ValueType;
2579
2564
  call(nodes) {
2580
2565
  if (nodes.length === 1) return nodes.nodes[0].value;
2581
2566
  return Nothing;
@@ -2591,6 +2576,7 @@ let TokenKind = /*#__PURE__*/function (TokenKind) {
2591
2576
  TokenKind["COMMA"] = "TOKEN_COMMA";
2592
2577
  TokenKind["CURRENT"] = "TOKEN_CURRENT_VALUE";
2593
2578
  TokenKind["CURRENT_KEY"] = "TOKEN_CURRENT_KEY";
2579
+ // non-standard, default `#`
2594
2580
  TokenKind["DDOT"] = "TOKEN_DDOT";
2595
2581
  TokenKind["DOT"] = "TOKEN_DOT";
2596
2582
  TokenKind["DOUBLE_QUOTE_STRING"] = "TOKEN_DOUBLE_QUOTE_STRING";
@@ -2604,10 +2590,15 @@ let TokenKind = /*#__PURE__*/function (TokenKind) {
2604
2590
  TokenKind["GT"] = "TOKEN_GT";
2605
2591
  TokenKind["INDEX"] = "TOKEN_INDEX";
2606
2592
  TokenKind["KEY"] = "TOKEN_KEY";
2593
+ // non-standard, default `~<name>`
2607
2594
  TokenKind["KEY_DOUBLE_QUOTE_STRING"] = "TOKEN_KEY_DOUBLE_QUOTE_STRING";
2595
+ // non-standard, `~"<name>"`
2608
2596
  TokenKind["KEY_SINGLE_QUOTE_STRING"] = "TOKEN_KEY_SINGLE_QUOTE_STRING";
2597
+ // non-standard, `~'<name>'`
2609
2598
  TokenKind["KEYS"] = "TOKEN_KEYS";
2599
+ // non-standard, default `~`
2610
2600
  TokenKind["KEYS_FILTER"] = "TOKEN_KEYS_FILTER";
2601
+ // non-standard, `~?<expression>`
2611
2602
  TokenKind["LBRACKET"] = "TOKEN_LBRACKET";
2612
2603
  TokenKind["LE"] = "TOKEN_LE";
2613
2604
  TokenKind["LG"] = "TOKEN_LG";
@@ -2691,7 +2682,7 @@ class TokenStream {
2691
2682
  const exponentPattern = /[eE][+-]?\d+/y;
2692
2683
  const functionNamePattern = /[a-z][a-z_0-9]*/y;
2693
2684
  const indexPattern = /-?\d+/y;
2694
- const intPattern = /-?[0-9]+/y;
2685
+ const intPattern = /-?\d+/y;
2695
2686
  const namePattern = /[\u0080-\uFFFFa-zA-Z_][\u0080-\uFFFFa-zA-Z0-9_-]*/y;
2696
2687
  const whitespace = new Set([" ", "\n", "\t", "\r"]);
2697
2688
  const nameFirstPattern = /[\u0080-\uFFFFa-zA-Z_]/; // don't set sticky bit
@@ -3009,7 +3000,6 @@ function lexInsideBracketedSelection(l) {
3009
3000
  continue;
3010
3001
  }
3011
3002
  if (!l.environment.strict && l.acceptMatchRun(l.environment.keysPattern)) {
3012
- // FIXME: fall back to legacy behavior if keysPattern is not the default
3013
3003
  switch (l.peek()) {
3014
3004
  case "'":
3015
3005
  l.ignore(); // ~
@@ -3401,97 +3391,58 @@ class SliceSelector extends JSONPathSelector {
3401
3391
  const step = this.step ? this.step : "1";
3402
3392
  return `${start}:${stop}:${step}`;
3403
3393
  }
3404
- checkRange() {
3405
- for (var _len = arguments.length, indices = new Array(_len), _key = 0; _key < _len; _key++) {
3406
- indices[_key] = arguments[_key];
3407
- }
3394
+ checkRange(...indices) {
3408
3395
  for (const index of indices) {
3409
3396
  if (index !== undefined && (index < this.environment.minIntIndex || index > this.environment.maxIntIndex)) {
3410
3397
  throw new JSONPathIndexError("index out of range", this.token);
3411
3398
  }
3412
3399
  }
3413
3400
  }
3414
-
3415
- // eslint-disable-next-line sonarjs/cognitive-complexity
3416
3401
  slice(arr, start, stop, step) {
3417
- if (!arr.length) return [];
3418
-
3419
- // Handle negative start and stop values
3420
- if (start === undefined || start === null) {
3421
- start = step && step < 0 ? arr.length - 1 : 0;
3422
- } else if (start < 0) {
3423
- start = Math.max(arr.length + start, 0);
3424
- } else {
3425
- start = Math.min(start, arr.length - 1);
3426
- }
3427
- if (stop === undefined || stop === null) {
3428
- stop = step && step < 0 ? -1 : arr.length;
3429
- } else if (stop < 0) {
3430
- stop = Math.max(arr.length + stop, -1);
3431
- } else {
3432
- stop = Math.min(stop, arr.length);
3433
- }
3434
-
3435
- // Handle step value
3436
- if (step === 0) {
3437
- return [];
3438
- }
3439
- if (!step) {
3440
- step = 1;
3441
- }
3442
-
3443
- // Perform the slice
3444
- const slicedArray = [];
3402
+ const len = arr.length;
3403
+ step = step ?? 1;
3404
+ if (step === 0 || !len) return [];
3405
+ const result = [];
3406
+ let i;
3445
3407
  if (step > 0) {
3446
- for (let i = start; i < stop; i += step) {
3447
- slicedArray.push([i, arr[i]]);
3408
+ i = this.normalizeIndex(start, 0, len, step);
3409
+ const stop_ = this.normalizeIndex(stop, len, len, step);
3410
+ for (; i < stop_; i += step) {
3411
+ result.push([i, arr[i]]);
3448
3412
  }
3449
3413
  } else {
3450
- for (let i = start; i > stop; i += step) {
3451
- slicedArray.push([i, arr[i]]);
3414
+ i = this.normalizeIndex(start, len - 1, len, step);
3415
+ const stop_ = this.normalizeIndex(stop, -1, len, step);
3416
+ for (; i > stop_; i += step) {
3417
+ result.push([i, arr[i]]);
3452
3418
  }
3453
3419
  }
3454
- return slicedArray;
3420
+ return result;
3455
3421
  }
3456
-
3457
- // eslint-disable-next-line sonarjs/cognitive-complexity
3458
3422
  *lazySlice(arr, start, stop, step) {
3459
- if (!arr.length) return;
3460
-
3461
- // Handle negative and undefined start values
3462
- if (start === undefined || start === null) {
3463
- start = step && step < 0 ? arr.length - 1 : 0;
3464
- } else if (start < 0) {
3465
- start = Math.max(arr.length + start, 0);
3466
- } else {
3467
- start = Math.min(start, arr.length - 1);
3468
- }
3469
-
3470
- // Handle negative and undefined stop values
3471
- if (stop === undefined || stop === null) {
3472
- stop = step && step < 0 ? -1 : arr.length;
3473
- } else if (stop < 0) {
3474
- stop = Math.max(arr.length + stop, -1);
3475
- } else {
3476
- stop = Math.min(stop, arr.length);
3477
- }
3478
-
3479
- // Perform the slice
3480
- if (step === undefined) {
3481
- // Default to a step of 1
3482
- for (let i = start; i < stop; i += 1) {
3483
- yield [i, arr[i]];
3484
- }
3485
- } else if (step > 0) {
3486
- for (let i = start; i < stop; i += step) {
3423
+ const len = arr.length;
3424
+ step = step ?? 1;
3425
+ if (step === 0 || !len) return [];
3426
+ let i;
3427
+ if (step > 0) {
3428
+ i = this.normalizeIndex(start, 0, len, step);
3429
+ const stop_ = this.normalizeIndex(stop, len, len, step);
3430
+ for (; i < stop_; i += step) {
3487
3431
  yield [i, arr[i]];
3488
3432
  }
3489
- } else if (step < 0) {
3490
- for (let i = start; i > stop; i += step) {
3433
+ } else {
3434
+ i = this.normalizeIndex(start, len - 1, len, step);
3435
+ const stop_ = this.normalizeIndex(stop, -1, len, step);
3436
+ for (; i > stop_; i += step) {
3491
3437
  yield [i, arr[i]];
3492
3438
  }
3493
3439
  }
3494
3440
  }
3441
+ normalizeIndex(n, defaultValue, len, step) {
3442
+ if (n === undefined) return defaultValue;
3443
+ if (n < 0) return step < 0 ? Math.max(n + len, -1) : Math.max(n + len, 0);
3444
+ return step < 0 ? Math.min(n, len - 1) : Math.min(n, len);
3445
+ }
3495
3446
  }
3496
3447
  class WildcardSelector extends JSONPathSelector {
3497
3448
  constructor(environment, token) {
@@ -3691,53 +3642,45 @@ class DescendantSegment extends JSONPathSegment {
3691
3642
  toString(options) {
3692
3643
  return `..[${this.selectors.map(s => s.toString(options)).join(", ")}]`;
3693
3644
  }
3694
- visit(node) {
3695
- var _this = this;
3696
- let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
3697
- return function* () {
3698
- if (depth >= _this.environment.maxRecursionDepth) {
3699
- throw new JSONPathRecursionLimitError("recursion limit reached", _this.token);
3645
+ *visit(node, depth = 1) {
3646
+ if (depth >= this.environment.maxRecursionDepth) {
3647
+ throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
3648
+ }
3649
+ yield node;
3650
+ if (isArray(node.value)) {
3651
+ for (let i = 0; i < node.value.length; i++) {
3652
+ const _node = new JSONPathNode(node.value[i], node.location.concat(i), node.root);
3653
+ yield* this.visit(_node, depth + 1);
3654
+ }
3655
+ } else if (isObject(node.value)) {
3656
+ for (const [key, value] of this.environment.entries(node.value)) {
3657
+ const _node = new JSONPathNode(value, node.location.concat(key), node.root);
3658
+ yield* this.visit(_node, depth + 1);
3700
3659
  }
3660
+ }
3661
+ }
3662
+ *nondeterministicVisit(root, depth = 1) {
3663
+ let queue = Array.from(this.nondeterministicChildren(root)).map(node => [node, depth]);
3664
+ yield root;
3665
+ while (queue.length) {
3666
+ const [node, _depth] = queue.shift();
3701
3667
  yield node;
3702
- if (isArray(node.value)) {
3703
- for (let i = 0; i < node.value.length; i++) {
3704
- const _node = new JSONPathNode(node.value[i], node.location.concat(i), node.root);
3705
- yield* _this.visit(_node, depth + 1);
3706
- }
3707
- } else if (isObject(node.value)) {
3708
- for (const [key, value] of _this.environment.entries(node.value)) {
3709
- const _node = new JSONPathNode(value, node.location.concat(key), node.root);
3710
- yield* _this.visit(_node, depth + 1);
3711
- }
3668
+ if (_depth >= this.environment.maxRecursionDepth) {
3669
+ throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
3712
3670
  }
3713
- }();
3714
- }
3715
- nondeterministicVisit(root) {
3716
- var _this2 = this;
3717
- let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
3718
- return function* () {
3719
- let queue = Array.from(_this2.nondeterministicChildren(root)).map(node => [node, depth]);
3720
- yield root;
3721
- while (queue.length) {
3722
- const [node, _depth] = queue.shift();
3723
- yield node;
3724
- if (_depth >= _this2.environment.maxRecursionDepth) {
3725
- throw new JSONPathRecursionLimitError("recursion limit reached", _this2.token);
3726
- }
3727
3671
 
3728
- // Visit child nodes now or queue them for later?
3729
- const visitChildren = Math.random() < 0.5;
3730
- for (const child of _this2.nondeterministicChildren(node)) {
3731
- if (visitChildren) {
3732
- yield child;
3733
- const grandchildren = Array.from(_this2.nondeterministicChildren(child)).map(n => [n, _depth + 2]);
3734
- queue = interleave(queue, grandchildren);
3735
- } else {
3736
- queue.push([child, _depth + 1]);
3737
- }
3672
+ // Visit child nodes now or queue them for later?
3673
+ const visitChildren = Math.random() < 0.5;
3674
+ for (const child of this.nondeterministicChildren(node)) {
3675
+ if (visitChildren) {
3676
+ yield child;
3677
+ const grandchildren = Array.from(this.nondeterministicChildren(child)).map(n => [n, _depth + 2]);
3678
+ queue = interleave(queue, grandchildren);
3679
+ } else {
3680
+ queue.push([child, _depth + 1]);
3738
3681
  }
3739
3682
  }
3740
- }();
3683
+ }
3741
3684
  }
3742
3685
  *nondeterministicChildren(node) {
3743
3686
  if (isString(node.value)) return;
@@ -4003,8 +3946,7 @@ class Parser {
4003
3946
  }
4004
3947
  return segments;
4005
3948
  }
4006
- parseQuery(stream) {
4007
- let inFilter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
3949
+ parseQuery(stream, inFilter = false) {
4008
3950
  const segments = [];
4009
3951
  loop: for (;;) {
4010
3952
  switch (stream.current.kind) {
@@ -4156,8 +4098,7 @@ class Parser {
4156
4098
  }
4157
4099
  return selectors;
4158
4100
  }
4159
- parseFilter(stream) {
4160
- let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
4101
+ parseFilter(stream, keys = false) {
4161
4102
  const tok = stream.next();
4162
4103
  const expr = this.parseFilterExpression(stream);
4163
4104
  if (expr instanceof FunctionExtension) {
@@ -4271,8 +4212,7 @@ class Parser {
4271
4212
  stream.expect(TokenKind.RPAREN);
4272
4213
  return new FunctionExtension(tok, tok.value, this.environment.checkWellTypedness(tok, args));
4273
4214
  }
4274
- parseFilterExpression(stream) {
4275
- let precedence = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : PRECEDENCE_LOWEST;
4215
+ parseFilterExpression(stream, precedence = PRECEDENCE_LOWEST) {
4276
4216
  const func = this.tokenMap.get(stream.current.kind);
4277
4217
  if (!func) {
4278
4218
  let msg;
@@ -4342,7 +4282,6 @@ class Parser {
4342
4282
  rv.push(this.stringFromCodePoint(codepoint, token));
4343
4283
  break;
4344
4284
  default:
4345
- // TODO: This is unreachable. The lexer will catch unknown escape sequences.
4346
4285
  throw new JSONPathSyntaxError(`unknown escape sequence at index ${token.index + index - 1}`, token);
4347
4286
  }
4348
4287
  } else {
@@ -4522,12 +4461,11 @@ class JSONPathEnvironment {
4522
4461
  * A map of function names to objects implementing the {@link FilterFunction}
4523
4462
  * interface. You are free to set or delete custom filter functions directly.
4524
4463
  */
4525
- functionRegister = (() => new Map())();
4464
+ functionRegister = new Map();
4526
4465
  /**
4527
4466
  * @param options - Environment configuration options.
4528
4467
  */
4529
- constructor() {
4530
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
4468
+ constructor(options = {}) {
4531
4469
  this.strict = options.strict ?? true;
4532
4470
  this.maxIntIndex = options.maxIntIndex ?? Math.pow(2, 53) - 1;
4533
4471
  this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) + 1;
@@ -4672,11 +4610,10 @@ class JSONPathEnvironment {
4672
4610
  * value and it contains a property matching the second argument.
4673
4611
  */
4674
4612
  class Has {
4675
- argTypes = (() => [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType])();
4676
- returnType = (() => FunctionExpressionType.LogicalType)();
4613
+ argTypes = [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType];
4614
+ returnType = FunctionExpressionType.LogicalType;
4677
4615
  #cache;
4678
- constructor() {
4679
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
4616
+ constructor(options = {}) {
4680
4617
  this.options = options;
4681
4618
  this.cacheSize = options.cacheSize ?? 10;
4682
4619
  this.throwErrors = options.throwErrors ?? false;
@@ -4871,31 +4808,7 @@ class OpAdd {
4871
4808
  this.value = value;
4872
4809
  }
4873
4810
  apply(value, index) {
4874
- const [parent, obj] = this.path.resolveWithParent(value);
4875
- if (parent === UNDEFINED) {
4876
- // Replace the root object.
4877
- return this.value;
4878
- }
4879
- const target = this.path.tokens.at(-1);
4880
- if (target === undefined) {
4881
- // this should not be possible
4882
- throw new JSONPatchError(`unexpected operation on 'undefined' (${this.name}:${index})`);
4883
- } else if (isArray(parent)) {
4884
- if (obj === UNDEFINED) {
4885
- if (target === "-") {
4886
- parent.push(this.value);
4887
- } else {
4888
- throw new JSONPatchError(`index out of range (${this.name}:${index})`);
4889
- }
4890
- } else {
4891
- parent.splice(Number(target), 0, this.value);
4892
- }
4893
- } else if (isObject(parent)) {
4894
- parent[target] = this.value;
4895
- } else {
4896
- throw new JSONPatchError(`unexpected operation on '${typeof parent}' (${this.name}:${index})`);
4897
- }
4898
- return value;
4811
+ return add(value, this.path, this.value, this.name, index);
4899
4812
  }
4900
4813
  toObject() {
4901
4814
  return {
@@ -4915,27 +4828,7 @@ class OpRemove {
4915
4828
  this.path = path;
4916
4829
  }
4917
4830
  apply(value, index) {
4918
- const [parent, obj] = this.path.resolveWithParent(value);
4919
- if (parent === UNDEFINED) {
4920
- throw new JSONPatchError(`can't remove root (${this.name}:${index})`);
4921
- }
4922
- const target = this.path.tokens.at(-1);
4923
- if (target === undefined) {
4924
- // this should not be possible
4925
- throw new JSONPatchError(`unexpected operation on 'undefined' (${this.name}:${index})`);
4926
- } else if (isArray(parent)) {
4927
- if (obj === UNDEFINED) {
4928
- throw new JSONPatchError(`can't remove nonexistent item (${this.name}:${index})`);
4929
- }
4930
- parent.splice(Number(target), 1);
4931
- } else if (isObject(parent)) {
4932
- if (obj === UNDEFINED) {
4933
- throw new JSONPatchError(`can't remove nonexistent property (${this.name}:${index})`);
4934
- }
4935
- delete parent[target];
4936
- } else {
4937
- throw new JSONPatchError(`unexpected operation on '${typeof parent}' (${this.name}:${index})`);
4938
- }
4831
+ remove(value, this.path, this.name, index);
4939
4832
  return value;
4940
4833
  }
4941
4834
  toObject() {
@@ -4971,15 +4864,16 @@ class OpReplace {
4971
4864
  throw new JSONPatchError(`can't replace nonexistent item (${this.name}:${index})`);
4972
4865
  }
4973
4866
  parent.splice(Number(target), 1, this.value);
4974
- } else if (isObject(parent)) {
4867
+ return value;
4868
+ }
4869
+ if (isObject(parent)) {
4975
4870
  if (obj === UNDEFINED) {
4976
4871
  throw new JSONPatchError(`can't replace nonexistent property (${this.name}:${index})`);
4977
4872
  }
4978
4873
  parent[target] = this.value;
4979
- } else {
4980
- throw new JSONPatchError(`unexpected operation on '${typeof parent}' (${this.name}:${index})`);
4874
+ return value;
4981
4875
  }
4982
- return value;
4876
+ throw new JSONPatchError(`unexpected operation on '${typeof parent}' (${this.name}:${index})`);
4983
4877
  }
4984
4878
  toObject() {
4985
4879
  return {
@@ -5003,42 +4897,8 @@ class OpMove {
5003
4897
  if (this.path.isRelativeTo(this.from)) {
5004
4898
  throw new JSONPatchError(`can't move object to one of its own children (${this.name}:${index})`);
5005
4899
  }
5006
- const [sourceParent, sourceObj] = this.from.resolveWithParent(value);
5007
- if (sourceObj === UNDEFINED) {
5008
- throw new JSONPatchError(`source object does not exist (${this.name}:${index})`);
5009
- }
5010
- const sourceTarget = this.from.tokens.at(-1);
5011
- if (sourceTarget === undefined) {
5012
- // this should not be possible
5013
- throw new JSONPatchError(`unexpected operation on 'undefined' (${this.name}:${index})`);
5014
- }
5015
- if (isArray(sourceParent)) {
5016
- sourceParent.splice(Number(sourceTarget), 1);
5017
- } else if (isObject(sourceParent)) {
5018
- delete sourceParent[sourceTarget];
5019
- }
5020
- const [destParent, _] = this.path.resolveWithParent(value);
5021
- if (destParent === UNDEFINED) {
5022
- // move source to root
5023
- return sourceObj;
5024
- }
5025
- const destTarget = this.path.tokens.at(-1);
5026
- if (destTarget === undefined) {
5027
- // this should not be possible
5028
- throw new JSONPatchError(`unexpected operation on 'undefined' (${this.name}:${index})`);
5029
- }
5030
- if (isArray(destParent)) {
5031
- if (destTarget === "-") {
5032
- destParent.push(sourceObj);
5033
- } else {
5034
- destParent.splice(Number(destTarget), 0, sourceObj);
5035
- }
5036
- } else if (isObject(destParent)) {
5037
- destParent[destTarget] = sourceObj;
5038
- } else {
5039
- throw new JSONPatchError(`unexpected operation on '${typeof parent}' (${this.name}:${index})`);
5040
- }
5041
- return value;
4900
+ const obj = remove(value, this.from, this.name, index);
4901
+ return add(value, this.path, obj, this.name, index);
5042
4902
  }
5043
4903
  toObject() {
5044
4904
  return {
@@ -5063,28 +4923,7 @@ class OpCopy {
5063
4923
  if (sourceObj === UNDEFINED) {
5064
4924
  throw new JSONPatchError(`source object does not exist (${this.name}:${index})`);
5065
4925
  }
5066
- const [destParent] = this.path.resolveWithParent(value);
5067
- if (destParent === UNDEFINED) {
5068
- // copy source to root
5069
- return this.deepCopy(sourceObj);
5070
- }
5071
- const destTarget = this.path.tokens.at(-1);
5072
- if (destTarget === undefined) {
5073
- // this should not be possible
5074
- throw new JSONPatchError(`unexpected operation on 'undefined' (${this.name}:${index})`);
5075
- }
5076
- if (isArray(destParent)) {
5077
- if (destTarget === "-") {
5078
- destParent.push(this.deepCopy(sourceObj));
5079
- } else {
5080
- destParent.splice(Number(destTarget), 0, this.deepCopy(sourceObj));
5081
- }
5082
- } else if (isObject(destParent)) {
5083
- destParent[destTarget] = this.deepCopy(sourceObj);
5084
- } else {
5085
- throw new JSONPatchError(`unexpected operation on '${typeof destParent}' (${this.name}:${index})`);
5086
- }
5087
- return value;
4926
+ return add(value, this.path, sourceObj, this.name, index);
5088
4927
  }
5089
4928
 
5090
4929
  // eslint-disable-next-line sonarjs/no-identical-functions
@@ -5125,6 +4964,72 @@ class OpTest {
5125
4964
  }
5126
4965
  }
5127
4966
 
4967
+ /**
4968
+ * Add _value_ to _data_ at _path_.
4969
+ *
4970
+ * This is semantically the `add` operation, used by `OpAdd`, `OpMove` and
4971
+ * `OpCopy`.
4972
+ */
4973
+ function add(data, path, value, opLabel, opIndex) {
4974
+ const [parent, obj] = path.resolveWithParent(data);
4975
+ if (parent === UNDEFINED) {
4976
+ // Replace the root object.
4977
+ return value;
4978
+ }
4979
+ const target = path.tokens.at(-1);
4980
+ if (target === undefined) {
4981
+ throw new JSONPatchError(`unexpected operation on 'undefined' (${opLabel}:${opIndex})`);
4982
+ }
4983
+ if (isArray(parent)) {
4984
+ if (obj === UNDEFINED) {
4985
+ if (!(target === "-" || Number(target) === parent.length)) {
4986
+ throw new JSONPatchError(`index out of range (${opLabel}:${opIndex})`);
4987
+ }
4988
+ parent.push(value);
4989
+ return data;
4990
+ }
4991
+ parent.splice(Number(target), 0, value);
4992
+ return data;
4993
+ }
4994
+ if (isObject(parent)) {
4995
+ parent[target] = value;
4996
+ return data;
4997
+ }
4998
+ throw new JSONPatchError(`unexpected operation on '${typeof parent}' (${opLabel}:${opIndex})`);
4999
+ }
5000
+
5001
+ /**
5002
+ * Remove the element at _path_ from _data_ and return the removed value.
5003
+ *
5004
+ * This is semantically the `remove` operation used by `OpRemove` and
5005
+ * `OpMove`.
5006
+ */
5007
+ function remove(data, path, opLabel, opIndex) {
5008
+ const [parent, obj] = path.resolveWithParent(data);
5009
+ if (parent === UNDEFINED) {
5010
+ throw new JSONPatchError(`can't remove root (${opLabel}:${opIndex})`);
5011
+ }
5012
+ const target = path.tokens.at(-1);
5013
+ if (target === undefined) {
5014
+ throw new JSONPatchError(`unexpected operation on 'undefined' (${opLabel}:${opIndex})`);
5015
+ }
5016
+ if (isArray(parent)) {
5017
+ if (obj === UNDEFINED) {
5018
+ throw new JSONPatchError(`can't ${opLabel} nonexistent item (${opLabel}:${opIndex})`);
5019
+ }
5020
+ parent.splice(Number(target), 1);
5021
+ return obj;
5022
+ }
5023
+ if (isObject(parent)) {
5024
+ if (obj === UNDEFINED) {
5025
+ throw new JSONPatchError(`can't ${opLabel} nonexistent property (${opLabel}:${opIndex})`);
5026
+ }
5027
+ delete parent[target];
5028
+ return obj;
5029
+ }
5030
+ throw new JSONPatchError(`unexpected operation on '${typeof parent}' (${opLabel}:${opIndex})`);
5031
+ }
5032
+
5128
5033
  /**
5129
5034
  *
5130
5035
  */
@@ -5325,6 +5230,6 @@ var index = /*#__PURE__*/Object.freeze({
5325
5230
  apply: apply
5326
5231
  });
5327
5232
 
5328
- const version = "2.2.2";
5233
+ const version = "2.3.1";
5329
5234
 
5330
5235
  export { DEFAULT_ENVIRONMENT, FunctionExpressionType, JSONPatch, JSONPatchError, JSONPatchTestFailure, JSONPathEnvironment, JSONPathError, JSONPathIndexError, JSONPathLexerError, JSONPathNode, JSONPathNodeList, JSONPathQuery, JSONPathRecursionLimitError, JSONPathSyntaxError, JSONPathTypeError, JSONPointer, Nothing, RelativeJSONPointer, Token, TokenKind, UNDEFINED, apply, compile, index as jsonpatch, index$1 as jsonpath, index$3 as jsonpointer, lazyQuery, query, resolve, version };