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