json-p3 1.3.3 → 1.3.5

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 1.3.3
2
+ * json-p3 version 1.3.5
3
3
  * https://github.com/jg-rp/json-p3
4
4
  *
5
5
  * MIT License
@@ -1042,16 +1042,16 @@ var expression = /*#__PURE__*/Object.freeze({
1042
1042
  });
1043
1043
 
1044
1044
  class Count {
1045
- argTypes = [FunctionExpressionType.NodesType];
1046
- returnType = FunctionExpressionType.ValueType;
1045
+ argTypes = (() => [FunctionExpressionType.NodesType])();
1046
+ returnType = (() => FunctionExpressionType.ValueType)();
1047
1047
  call(nodes) {
1048
1048
  return nodes.length;
1049
1049
  }
1050
1050
  }
1051
1051
 
1052
1052
  class Length {
1053
- argTypes = [FunctionExpressionType.ValueType];
1054
- returnType = FunctionExpressionType.ValueType;
1053
+ argTypes = (() => [FunctionExpressionType.ValueType])();
1054
+ returnType = (() => FunctionExpressionType.ValueType)();
1055
1055
  call(value) {
1056
1056
  if (isArray(value) || isString(value)) return value.length;
1057
1057
  if (isObject(value)) return Object.keys(value).length;
@@ -1085,7 +1085,10 @@ class LRUCache extends Map {
1085
1085
  if (this.has(key)) {
1086
1086
  this.delete(key);
1087
1087
  } else if (this.size >= this.maxSize) {
1088
- this.delete(this.first());
1088
+ const first = this.first();
1089
+ if (first !== undefined) {
1090
+ this.delete(first);
1091
+ }
1089
1092
  }
1090
1093
  return super.set(key, value);
1091
1094
  }
@@ -2344,8 +2347,8 @@ var check_1 = {
2344
2347
  var check$1 = check_1.check;
2345
2348
 
2346
2349
  class Match {
2347
- argTypes = [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType];
2348
- returnType = FunctionExpressionType.LogicalType;
2350
+ argTypes = (() => [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType])();
2351
+ returnType = (() => FunctionExpressionType.LogicalType)();
2349
2352
  #cache;
2350
2353
  constructor() {
2351
2354
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -2402,8 +2405,8 @@ class Match {
2402
2405
  }
2403
2406
 
2404
2407
  class Search {
2405
- argTypes = [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType];
2406
- returnType = FunctionExpressionType.LogicalType;
2408
+ argTypes = (() => [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType])();
2409
+ returnType = (() => FunctionExpressionType.LogicalType)();
2407
2410
  #cache;
2408
2411
  constructor() {
2409
2412
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -2451,8 +2454,8 @@ class Search {
2451
2454
  }
2452
2455
 
2453
2456
  class Value {
2454
- argTypes = [FunctionExpressionType.NodesType];
2455
- returnType = FunctionExpressionType.ValueType;
2457
+ argTypes = (() => [FunctionExpressionType.NodesType])();
2458
+ returnType = (() => FunctionExpressionType.ValueType)();
2456
2459
  call(nodes) {
2457
2460
  if (nodes.length === 1) return nodes.nodes[0].value;
2458
2461
  return Nothing;
@@ -2552,6 +2555,12 @@ class TokenStream {
2552
2555
  throw new JSONPathSyntaxError(`expected token '${kind}', found '${peeked.kind}'`, peeked);
2553
2556
  }
2554
2557
  }
2558
+ expectPeekNot(kind, message) {
2559
+ const peeked = this.peek;
2560
+ if (peeked.kind === kind) {
2561
+ throw new JSONPathSyntaxError(message, peeked);
2562
+ }
2563
+ }
2555
2564
  }
2556
2565
 
2557
2566
  /** A lexer that accepts additional, non-standard tokens. */
@@ -2559,7 +2568,7 @@ class TokenStream {
2559
2568
 
2560
2569
  // These regular expressions are to be used with Lexer.acceptMatchRun(),
2561
2570
  // which expects the sticky flag to be set.
2562
- const exponentPattern = /e[+-]?\d+/y;
2571
+ const exponentPattern = /[eE][+-]?\d+/y;
2563
2572
  const functionNamePattern = /[a-z][a-z_0-9]*/y;
2564
2573
  const indexPattern = /-?\d+/y;
2565
2574
  const intPattern = /-?[0-9]+/y;
@@ -4002,7 +4011,7 @@ class Parser {
4002
4011
  switch (stream.current.kind) {
4003
4012
  case TokenKind.SINGLE_QUOTE_STRING:
4004
4013
  case TokenKind.DOUBLE_QUOTE_STRING:
4005
- items.push(new NameSelector(this.environment, stream.current, this.decodeString(stream.current, true), false));
4014
+ items.push(new NameSelector(this.environment, stream.current, this.decodeString(stream.current), false));
4006
4015
  break;
4007
4016
  case TokenKind.FILTER:
4008
4017
  items.push(this.parseFilter(stream));
@@ -4022,7 +4031,7 @@ class Parser {
4022
4031
  break;
4023
4032
  case TokenKind.KEY_SINGLE_QUOTE_STRING:
4024
4033
  case TokenKind.KEY_DOUBLE_QUOTE_STRING:
4025
- items.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current, true), false));
4034
+ items.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current), false));
4026
4035
  break;
4027
4036
  case TokenKind.KEYS_FILTER:
4028
4037
  items.push(this.parseFilter(stream, true));
@@ -4038,6 +4047,7 @@ class Parser {
4038
4047
  if (stream.peek.kind !== TokenKind.RBRACKET) {
4039
4048
  stream.expectPeek(TokenKind.COMMA);
4040
4049
  stream.next();
4050
+ stream.expectPeekNot(TokenKind.RBRACKET, "unexpected trailing comma");
4041
4051
  }
4042
4052
  stream.next();
4043
4053
  }
@@ -4070,7 +4080,15 @@ class Parser {
4070
4080
  return new StringLiteral(stream.current, this.decodeString(stream.current));
4071
4081
  }
4072
4082
  parseNumber(stream) {
4073
- return new NumberLiteral(stream.current, Number(stream.current.value));
4083
+ const value = stream.current.value;
4084
+ if (value.startsWith("0") && value.length > 1) {
4085
+ throw new JSONPathSyntaxError(`invalid number literal '${value}'`, stream.current);
4086
+ }
4087
+ const num = Number(stream.current.value);
4088
+ if (isNaN(num)) {
4089
+ throw new JSONPathSyntaxError(`invalid number literal '${value}'`, stream.current);
4090
+ }
4091
+ return new NumberLiteral(stream.current, num);
4074
4092
  }
4075
4093
  parsePrefixExpression(stream) {
4076
4094
  stream.expect(TokenKind.NOT);
@@ -4181,11 +4199,155 @@ class Parser {
4181
4199
  return left;
4182
4200
  }
4183
4201
  decodeString(token) {
4184
- let isName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
4202
+ return this.unescapeString(token.kind === TokenKind.SINGLE_QUOTE_STRING ? token.value.replaceAll('"', '\\"').replaceAll("\\'", "'") : token.value, token);
4203
+ }
4204
+ unescapeString(value, token) {
4205
+ const rv = [];
4206
+ const length = value.length;
4207
+ let index = 0;
4208
+ let codepoint;
4209
+ while (index < length) {
4210
+ const ch = value[index];
4211
+ if (ch === "\\") {
4212
+ // Handle escape sequences
4213
+ index += 1; // Move past '\'
4214
+
4215
+ switch (value[index]) {
4216
+ case '"':
4217
+ rv.push('"');
4218
+ break;
4219
+ case "\\":
4220
+ rv.push("\\");
4221
+ break;
4222
+ case "/":
4223
+ rv.push("/");
4224
+ break;
4225
+ case "b":
4226
+ rv.push("\x08");
4227
+ break;
4228
+ case "f":
4229
+ rv.push("\x0C");
4230
+ break;
4231
+ case "n":
4232
+ rv.push("\n");
4233
+ break;
4234
+ case "r":
4235
+ rv.push("\r");
4236
+ break;
4237
+ case "t":
4238
+ rv.push("\t");
4239
+ break;
4240
+ case "u":
4241
+ [codepoint, index] = this.decodeHexChar(value, index, token);
4242
+ rv.push(this.stringFromCodePoint(codepoint, token));
4243
+ break;
4244
+ default:
4245
+ // TODO: This is unreachable. The lexer will catch unknown escape sequences.
4246
+ throw new JSONPathSyntaxError(`unknown escape sequence at index ${token.index + index - 1}`, token);
4247
+ }
4248
+ } else {
4249
+ this.stringFromCodePoint(ch.codePointAt(0), token);
4250
+ rv.push(ch);
4251
+ }
4252
+ index += 1;
4253
+ }
4254
+ return rv.join("");
4255
+ }
4256
+
4257
+ /**
4258
+ * Decode a `\uXXXX` or `\uXXXX\uXXXX` escape sequence from _value_ at _index_.
4259
+ *
4260
+ * @param value - A string value containing the sequence to decode.
4261
+ * @param index - The start index of an escape sequence in _value_.
4262
+ * @param token - The token for the string value.
4263
+ * @returns - A codepoint, new index tuple.
4264
+ */
4265
+ decodeHexChar(value, index, token) {
4266
+ const length = value.length;
4267
+ if (index + 4 >= length) {
4268
+ throw new JSONPathSyntaxError(`incomplete escape sequence at index ${token.index + index - 1}`, token);
4269
+ }
4270
+ index += 1; // Move past 'u'
4271
+ let codepoint = this.parseHexDigits(value.slice(index, index + 4), token);
4272
+ if (isLowSurrogate(codepoint)) {
4273
+ throw new JSONPathSyntaxError(`unexpected low surrogate codepoint at index ${token.index + index - 2}`, token);
4274
+ }
4275
+ if (isHighSurrogate(codepoint)) {
4276
+ // Expect a surrogate pair.
4277
+ if (!(index + 9 < length && value[index + 4] === "\\" && value[index + 5] === "u")) {
4278
+ throw new JSONPathSyntaxError(`incomplete escape sequence at index ${token.index + index - 2}`, token);
4279
+ }
4280
+ const lowSurrogate = this.parseHexDigits(value.slice(index + 6, index + 10), token);
4281
+ if (!isLowSurrogate(lowSurrogate)) {
4282
+ throw new JSONPathSyntaxError(`unexpected codepoint at index ${token.index + index + 4}`, token);
4283
+ }
4284
+ codepoint = 0x10000 + ((codepoint & 0x03ff) << 10 | lowSurrogate & 0x03ff);
4285
+ return [codepoint, index + 9];
4286
+ }
4287
+ return [codepoint, index + 3];
4288
+ }
4289
+
4290
+ /**
4291
+ * Parse a hexadecimal string as an integer.
4292
+ *
4293
+ * @param digits - Hexadecimal digit string.
4294
+ * @param token - The token for the string value.
4295
+ * @returns - The number representation of _digits_.
4296
+ *
4297
+ * Note that we're not using `parseInt(digits, 16)` because it accepts `+`
4298
+ * and `-` and things we don't allow.
4299
+ */
4300
+ parseHexDigits(digits, token) {
4301
+ const encoder = new TextEncoder();
4302
+ let codepoint = 0;
4303
+ for (const digit of encoder.encode(digits)) {
4304
+ codepoint <<= 4;
4305
+ switch (digit) {
4306
+ case 48:
4307
+ case 49:
4308
+ case 50:
4309
+ case 51:
4310
+ case 52:
4311
+ case 53:
4312
+ case 54:
4313
+ case 55:
4314
+ case 56:
4315
+ case 57:
4316
+ codepoint |= digit - 48; // '0'
4317
+ break;
4318
+ case 97:
4319
+ case 98:
4320
+ case 99:
4321
+ case 100:
4322
+ case 101:
4323
+ case 102:
4324
+ codepoint |= digit - 97 + 10; // 'a'
4325
+ break;
4326
+ case 65:
4327
+ case 66:
4328
+ case 67:
4329
+ case 68:
4330
+ case 69:
4331
+ case 70:
4332
+ codepoint |= digit - 65 + 10; // 'A'
4333
+ break;
4334
+ default:
4335
+ throw new JSONPathSyntaxError("invalid \\uXXXX escape sequence", token);
4336
+ }
4337
+ }
4338
+ return codepoint;
4339
+ }
4340
+
4341
+ /** Check the codepoint is valid and return its string representation. */
4342
+ stringFromCodePoint(codepoint, token) {
4343
+ if (codepoint === undefined || codepoint <= 0x1f) {
4344
+ throw new JSONPathSyntaxError(`invalid character`, token);
4345
+ }
4185
4346
  try {
4186
- return JSON.parse(token.kind === TokenKind.SINGLE_QUOTE_STRING ? `"${token.value.replaceAll('"', '\\"').replaceAll("\\'", "'")}"` : `"${token.value}"`);
4347
+ return String.fromCodePoint(codepoint);
4187
4348
  } catch {
4188
- throw new JSONPathSyntaxError(`invalid ${isName ? "name selector" : "string literal"} '${token.value}'`, token);
4349
+ // This should not be reachable.
4350
+ throw new JSONPathSyntaxError("invalid escape sequence", token);
4189
4351
  }
4190
4352
  }
4191
4353
  throwForNonComparable(expr) {
@@ -4205,6 +4367,12 @@ class Parser {
4205
4367
  }
4206
4368
  }
4207
4369
  }
4370
+ function isHighSurrogate(codepoint) {
4371
+ return codepoint >= 0xd800 && codepoint <= 0xdbff;
4372
+ }
4373
+ function isLowSurrogate(codepoint) {
4374
+ return codepoint >= 0xdc00 && codepoint <= 0xdfff;
4375
+ }
4208
4376
 
4209
4377
  /**
4210
4378
  * JSONPath environment options. The defaults are in compliance with JSONPath
@@ -4254,7 +4422,7 @@ class JSONPathEnvironment {
4254
4422
  * A map of function names to objects implementing the {@link FilterFunction}
4255
4423
  * interface. You are free to set or delete custom filter functions directly.
4256
4424
  */
4257
- functionRegister = new Map();
4425
+ functionRegister = (() => new Map())();
4258
4426
  /**
4259
4427
  * @param options - Environment configuration options.
4260
4428
  */
@@ -4262,7 +4430,7 @@ class JSONPathEnvironment {
4262
4430
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
4263
4431
  this.strict = options.strict ?? true;
4264
4432
  this.maxIntIndex = options.maxIntIndex ?? Math.pow(2, 53) - 1;
4265
- this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) - 1;
4433
+ this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) + 1;
4266
4434
  this.maxRecursionDepth = options.maxRecursionDepth ?? 50;
4267
4435
  this.nondeterministic = options.nondeterministic ?? false;
4268
4436
  this.keysPattern = options.keysPattern ?? /~/y;
@@ -4697,7 +4865,11 @@ class OpMove {
4697
4865
  throw new JSONPatchError(`unexpected operation on 'undefined' (${this.name}:${index})`);
4698
4866
  }
4699
4867
  if (isArray(destParent)) {
4700
- destParent.splice(Number(destTarget), 0, sourceObj);
4868
+ if (destTarget === "-") {
4869
+ destParent.push(sourceObj);
4870
+ } else {
4871
+ destParent.splice(Number(destTarget), 0, sourceObj);
4872
+ }
4701
4873
  } else if (isObject(destParent)) {
4702
4874
  destParent[destTarget] = sourceObj;
4703
4875
  } else {
@@ -4739,11 +4911,15 @@ class OpCopy {
4739
4911
  throw new JSONPatchError(`unexpected operation on 'undefined' (${this.name}:${index})`);
4740
4912
  }
4741
4913
  if (isArray(destParent)) {
4742
- destParent.splice(Number(destTarget), 0, this.deepCopy(sourceObj));
4914
+ if (destTarget === "-") {
4915
+ destParent.push(this.deepCopy(sourceObj));
4916
+ } else {
4917
+ destParent.splice(Number(destTarget), 0, this.deepCopy(sourceObj));
4918
+ }
4743
4919
  } else if (isObject(destParent)) {
4744
4920
  destParent[destTarget] = this.deepCopy(sourceObj);
4745
4921
  } else {
4746
- throw new JSONPatchError(`unexpected operation on '${typeof parent}' (${this.name}:${index})`);
4922
+ throw new JSONPatchError(`unexpected operation on '${typeof destParent}' (${this.name}:${index})`);
4747
4923
  }
4748
4924
  return value;
4749
4925
  }
@@ -4986,7 +5162,7 @@ var index = /*#__PURE__*/Object.freeze({
4986
5162
  apply: apply
4987
5163
  });
4988
5164
 
4989
- const version = "1.3.3";
5165
+ const version = "1.3.5";
4990
5166
 
4991
5167
  exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT;
4992
5168
  exports.FunctionExpressionType = FunctionExpressionType;