json-p3 0.1.1 → 0.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.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * json-p3 version 0.1.1
2
+ * json-p3 version 0.2.0
3
3
  * https://github.com/jg-rp/json-p3
4
4
  *
5
5
  * MIT License
@@ -125,6 +125,20 @@ var json_p3 = (function (exports) {
125
125
  }
126
126
  }
127
127
 
128
+ /**
129
+ * Error thrown when the maximum recursion depth is reached.
130
+ */
131
+ class JSONPathRecursionLimitError extends JSONPathError {
132
+ constructor(message, token) {
133
+ super(message, token);
134
+ this.message = message;
135
+ this.token = token;
136
+ Object.setPrototypeOf(this, new.target.prototype);
137
+ this.name = "JSONPathRecursionLimitError";
138
+ this.message = withErrorContext(message, token);
139
+ }
140
+ }
141
+
128
142
  /**
129
143
  * Common types and type predicates.
130
144
  */
@@ -233,6 +247,10 @@ var json_p3 = (function (exports) {
233
247
  this.name = "JSONPointerError";
234
248
  }
235
249
  }
250
+
251
+ /**
252
+ * Base class for JSON Pointer resolution errors.
253
+ */
236
254
  class JSONPointerResolutionError extends JSONPointerError {
237
255
  constructor(message) {
238
256
  super(message);
@@ -241,6 +259,10 @@ var json_p3 = (function (exports) {
241
259
  this.name = "JSONPointerResolutionError";
242
260
  }
243
261
  }
262
+
263
+ /**
264
+ * Error thrown due to an out of range index when resolving a JSON Pointer.
265
+ */
244
266
  class JSONPointerIndexError extends JSONPointerResolutionError {
245
267
  constructor(message) {
246
268
  super(message);
@@ -249,6 +271,10 @@ var json_p3 = (function (exports) {
249
271
  this.name = "JSONPointerIndexError";
250
272
  }
251
273
  }
274
+
275
+ /**
276
+ * Error thrown due to a missing property when resolving a JSON Pointer.
277
+ */
252
278
  class JSONPointerKeyError extends JSONPointerResolutionError {
253
279
  constructor(message) {
254
280
  super(message);
@@ -257,6 +283,10 @@ var json_p3 = (function (exports) {
257
283
  this.name = "JSONPointerKeyError";
258
284
  }
259
285
  }
286
+
287
+ /**
288
+ * Error thrown due to invalid JSON Pointer syntax.
289
+ */
260
290
  class JSONPointerSyntaxError extends JSONPointerError {
261
291
  constructor(message) {
262
292
  super(message);
@@ -265,6 +295,10 @@ var json_p3 = (function (exports) {
265
295
  this.name = "JSONPointerSyntaxError";
266
296
  }
267
297
  }
298
+
299
+ /**
300
+ * Error thrown when trying to resolve a property or index against a primitive value.
301
+ */
268
302
  class JSONPointerTypeError extends JSONPointerResolutionError {
269
303
  constructor(message) {
270
304
  super(message);
@@ -324,8 +358,6 @@ var json_p3 = (function (exports) {
324
358
  }
325
359
  }
326
360
 
327
- // TODO: add `resolveWithFallback` to handle explicit `undefined`
328
-
329
361
  /**
330
362
  *
331
363
  * @param value -
@@ -364,6 +396,8 @@ var json_p3 = (function (exports) {
364
396
  }
365
397
  return pointer.split("/").map(token => token.replaceAll("~1", "/").replaceAll("~0", "~")).slice(1);
366
398
  }
399
+
400
+ // eslint-disable-next-line sonarjs/cognitive-complexity
367
401
  getItem(val, token, idx) {
368
402
  // NOTE:
369
403
  // - string primitives "have own" indices and `length`.
@@ -373,12 +407,23 @@ var json_p3 = (function (exports) {
373
407
  if (isArray(val)) {
374
408
  if (token !== "length" && Object.hasOwn(val, token)) {
375
409
  return val[Number(token)];
410
+ } else if (token.startsWith("#")) {
411
+ // handle non-standard '#' from relative json pointer
412
+ const maybeIndex = token.slice(1);
413
+ if (RE_INT.test(maybeIndex) && Object.hasOwn(val, maybeIndex)) {
414
+ return Number(maybeIndex);
415
+ } else {
416
+ throw new JSONPointerIndexError(`index out of range '${JSONPointer.encode(this.tokens.slice(0, idx + 1))}'`);
417
+ }
376
418
  } else {
377
419
  throw new JSONPointerIndexError(`index out of range '${JSONPointer.encode(this.tokens.slice(0, idx + 1))}'`);
378
420
  }
379
421
  } else if (isObject(val)) {
380
422
  if (Object.hasOwn(val, token)) {
381
423
  return val[token];
424
+ } else if (token.startsWith("#") && Object.hasOwn(val, token.slice(1))) {
425
+ // handle non-standard '#' from relative json pointer
426
+ return token.slice(1);
382
427
  } else {
383
428
  throw new JSONPointerKeyError(`no such property '${JSONPointer.encode(this.tokens.slice(0, idx + 1))}'`);
384
429
  }
@@ -453,8 +498,111 @@ var json_p3 = (function (exports) {
453
498
  }
454
499
  return new JSONPointer(JSONPointer.encode(this.tokens.slice(0, this.tokens.length - 1)));
455
500
  }
501
+ to(rel) {
502
+ const relativePointer = isString(rel) ? new RelativeJSONPointer(rel) : rel;
503
+ return relativePointer.to(this);
504
+ }
505
+ }
506
+ const RE_RELATIVE_POINTER = /(?<ORIGIN>\d+)(?<INDEX_G>(?<SIGN>[+-])(?<INDEX>\d))?(?<POINTER>.*)/s;
507
+ const RE_INT = /(0|[1-9][0-9]*)/;
508
+
509
+ /**
510
+ * A relative JSON Pointer.
511
+ *
512
+ * See https://www.ietf.org/id/draft-hha-relative-json-pointer-00.html
513
+ */
514
+ class RelativeJSONPointer {
515
+ /**
516
+ *
517
+ * @param rel -
518
+ */
519
+ constructor(rel) {
520
+ [this.origin, this.index, this.pointer] = this.parse(rel);
521
+ }
522
+
523
+ /**
524
+ *
525
+ * @returns
526
+ */
527
+ toString() {
528
+ const sign = this.index > 0 ? "+" : "";
529
+ const index = this.index === 0 ? "" : `${sign}${this.index}`;
530
+ return `${this.origin}${index}${this.pointer}`;
531
+ }
532
+
533
+ /**
534
+ *
535
+ * @param pointer -
536
+ */
537
+ to(pointer) {
538
+ const p = isString(pointer) ? new JSONPointer(pointer) : pointer;
539
+
540
+ // move to origin
541
+ if (this.origin > p.tokens.length) {
542
+ throw new JSONPointerIndexError(`origin (${this.origin}) exceeds root (${p.tokens.length})`);
543
+ }
544
+ const tokens = this.origin < 1 ? p.tokens.slice() : p.tokens.slice(0, -this.origin);
545
+
546
+ // array index offset
547
+ if (this.index && tokens.length && this.isIntLike(tokens.at(-1))) {
548
+ const newIndex = Number(tokens.at(-1)) + this.index;
549
+ if (newIndex < 0) {
550
+ throw new JSONPointerIndexError(`index offset out of range (${newIndex})`);
551
+ }
552
+ tokens[tokens.length - 1] = String(newIndex);
553
+ }
554
+
555
+ // pointer or index/property
556
+ if (this.pointer instanceof JSONPointer) {
557
+ tokens.push(...this.pointer.tokens);
558
+ } else {
559
+ tokens[tokens.length - 1] = `#${tokens[tokens.length - 1]}`;
560
+ }
561
+ return new JSONPointer(JSONPointer.encode(tokens));
562
+ }
563
+ parse(rel) {
564
+ const match = RE_RELATIVE_POINTER.exec(rel);
565
+ if (!match || !match.groups) {
566
+ throw new JSONPointerSyntaxError("failed to parse relative pointer");
567
+ }
568
+
569
+ // steps to move
570
+ const origin = this.parseInt(match.groups.ORIGIN);
456
571
 
457
- // TODO: to (relative pointer)
572
+ // optional index manipulation
573
+ let index = 0;
574
+ if (match.groups["INDEX_G"]) {
575
+ index = this.parseInt(match.groups.INDEX);
576
+ if (index === 0) {
577
+ throw new JSONPointerSyntaxError("index offset can't be zero");
578
+ }
579
+ if (match.groups.SIGN === "-") {
580
+ index = -index;
581
+ }
582
+ }
583
+
584
+ // pointer or '#'. an empty string is OK.
585
+ if (match.groups.POINTER === "#") {
586
+ return [origin, index, "#"];
587
+ }
588
+ return [origin, index, new JSONPointer(match.groups.POINTER)];
589
+ }
590
+ parseInt(s) {
591
+ if (s.startsWith("0") && s.length > 1) {
592
+ throw new JSONPointerSyntaxError("unexpected leading zero");
593
+ }
594
+ if (RE_INT.test(s)) {
595
+ return Number(s);
596
+ }
597
+ throw new JSONPointerSyntaxError(`expected an integer, found '${s}'`);
598
+ }
599
+ isIntLike(value) {
600
+ if (value === undefined || isNumber(value)) {
601
+ return true;
602
+ } else {
603
+ return RE_INT.test(value);
604
+ }
605
+ }
458
606
  }
459
607
 
460
608
  /**
@@ -489,6 +637,7 @@ var json_p3 = (function (exports) {
489
637
  JSONPointerResolutionError: JSONPointerResolutionError,
490
638
  JSONPointerSyntaxError: JSONPointerSyntaxError,
491
639
  JSONPointerTypeError: JSONPointerTypeError,
640
+ RelativeJSONPointer: RelativeJSONPointer,
492
641
  UNDEFINED: UNDEFINED,
493
642
  resolve: resolve
494
643
  });
@@ -786,7 +935,7 @@ var json_p3 = (function (exports) {
786
935
  this.args = args;
787
936
  }
788
937
  evaluate(context) {
789
- const func = context.environment.filterRegister.get(this.name);
938
+ const func = context.environment.functionRegister.get(this.name);
790
939
  if (!func) {
791
940
  throw new UndefinedFilterFunctionError(`filter function '${this.name}' is undefined`, this.token);
792
941
  }
@@ -806,13 +955,6 @@ var json_p3 = (function (exports) {
806
955
  if (value instanceof JSONPathNodeList && value.empty()) return false;
807
956
  return !(typeof value === "boolean" && value === false);
808
957
  }
809
-
810
- /**
811
- *
812
- * @param left -
813
- * @param operator -
814
- * @param right -
815
- */
816
958
  function compare(left, operator, right) {
817
959
  switch (operator) {
818
960
  case "==":
@@ -866,7 +1008,8 @@ var json_p3 = (function (exports) {
866
1008
  PrefixExpression: PrefixExpression,
867
1009
  RelativeQuery: RelativeQuery,
868
1010
  RootQuery: RootQuery,
869
- StringLiteral: StringLiteral
1011
+ StringLiteral: StringLiteral,
1012
+ compare: compare
870
1013
  });
871
1014
 
872
1015
  class Count {
@@ -1390,6 +1533,10 @@ var json_p3 = (function (exports) {
1390
1533
  case "":
1391
1534
  case "]":
1392
1535
  l.filterLevel -= 1;
1536
+ if (l.parenStack.length === 1) {
1537
+ l.error("unbalanced parentheses");
1538
+ return null;
1539
+ }
1393
1540
  l.backup();
1394
1541
  return lexInsideBracketedSelection;
1395
1542
  case ",":
@@ -1619,7 +1766,7 @@ var json_p3 = (function (exports) {
1619
1766
  this.environment = environment;
1620
1767
  this.token = token;
1621
1768
  this.index = index;
1622
- if (index < this.environment.options.minIntIndex || index > this.environment.options.maxIntIndex) {
1769
+ if (index < this.environment.minIntIndex || index > this.environment.maxIntIndex) {
1623
1770
  throw new JSONPathIndexError("index out of range", this.token);
1624
1771
  }
1625
1772
  }
@@ -1674,15 +1821,11 @@ var json_p3 = (function (exports) {
1674
1821
  indices[_key] = arguments[_key];
1675
1822
  }
1676
1823
  for (const index of indices) {
1677
- if (index !== undefined && (index < this.environment.options.minIntIndex || index > this.environment.options.maxIntIndex)) {
1824
+ if (index !== undefined && (index < this.environment.minIntIndex || index > this.environment.maxIntIndex)) {
1678
1825
  throw new JSONPathIndexError("index out of range", this.token);
1679
1826
  }
1680
1827
  }
1681
1828
  }
1682
- normalizedIndex(length, index) {
1683
- if (index < 0 && length >= Math.abs(index)) return Math.min(length + index, length - 1);
1684
- return Math.min(index, length - 1);
1685
- }
1686
1829
 
1687
1830
  // eslint-disable-next-line sonarjs/cognitive-complexity
1688
1831
  slice(arr, start, stop, step) {
@@ -1766,17 +1909,21 @@ var json_p3 = (function (exports) {
1766
1909
  return "..";
1767
1910
  }
1768
1911
  visit(node) {
1912
+ let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
1913
+ if (depth >= this.environment.maxRecursionDepth) {
1914
+ throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
1915
+ }
1769
1916
  const rv = [];
1770
1917
  if (node.value instanceof String) return new JSONPathNodeList(rv);
1771
1918
  if (isArray(node.value)) {
1772
1919
  for (let i = 0; i < node.value.length; i++) {
1773
1920
  const _node = new JSONPathNode(node.value[i], node.location.concat(i), node.root);
1774
- rv.push(_node, ...this.visit(_node));
1921
+ rv.push(_node, ...this.visit(_node, depth + 1));
1775
1922
  }
1776
1923
  } else if (isObject(node.value)) {
1777
1924
  for (const [key, value] of Object.entries(node.value)) {
1778
1925
  const _node = new JSONPathNode(value, node.location.concat(key), node.root);
1779
- rv.push(_node, ...this.visit(_node));
1926
+ rv.push(_node, ...this.visit(_node, depth + 1));
1780
1927
  }
1781
1928
  }
1782
1929
  return new JSONPathNodeList(rv);
@@ -1886,6 +2033,18 @@ var json_p3 = (function (exports) {
1886
2033
  return nodes;
1887
2034
  }
1888
2035
 
2036
+ /**
2037
+ * Return a {@link JSONPathNode} instance for the first object found in
2038
+ * _value_ matching this query.
2039
+ *
2040
+ * @param value - JSON-like data to which this query will be applied.
2041
+ * @returns The first node in _value_ matching this query, or `undefined` if
2042
+ * there are no matches.
2043
+ */
2044
+ match(value) {
2045
+ return this.query(value).nodes.at(0);
2046
+ }
2047
+
1889
2048
  /**
1890
2049
  *
1891
2050
  */
@@ -2047,7 +2206,7 @@ var json_p3 = (function (exports) {
2047
2206
  const tok = stream.next();
2048
2207
  const expr = this.parseFilterExpression(stream);
2049
2208
  if (expr instanceof FunctionExtension) {
2050
- const func = this.environment.filterRegister.get(expr.name);
2209
+ const func = this.environment.functionRegister.get(expr.name);
2051
2210
  if (func && func.returnType === FunctionExpressionType.ValueType) {
2052
2211
  throw new JSONPathTypeError(`result of ${expr.name}() must be compared`, expr.token);
2053
2212
  }
@@ -2117,7 +2276,16 @@ var json_p3 = (function (exports) {
2117
2276
  if (!func) {
2118
2277
  throw new JSONPathSyntaxError(`unexpected '${stream.current.value}'`, stream.current);
2119
2278
  }
2120
- args.push(func.bind(this)(stream));
2279
+ let expr = func.bind(this)(stream);
2280
+
2281
+ // Could be a comparison/logical expression
2282
+ let peekKind = stream.peek.kind;
2283
+ while (BINARY_OPERATORS.has(peekKind)) {
2284
+ stream.next();
2285
+ expr = this.parseInfixExpression(stream, expr);
2286
+ peekKind = stream.peek.kind;
2287
+ }
2288
+ args.push(expr);
2121
2289
  if (stream.peek.kind !== TokenKind.RPAREN) {
2122
2290
  if (stream.peek.kind === TokenKind.RBRACKET) break;
2123
2291
  stream.expectPeek(TokenKind.COMMA);
@@ -2125,6 +2293,7 @@ var json_p3 = (function (exports) {
2125
2293
  }
2126
2294
  stream.next();
2127
2295
  }
2296
+ stream.expect(TokenKind.RPAREN);
2128
2297
  return new FunctionExtension(tok, tok.value, this.environment.checkWellTypedness(tok, args));
2129
2298
  }
2130
2299
  parseFilterExpression(stream) {
@@ -2169,7 +2338,7 @@ var json_p3 = (function (exports) {
2169
2338
  }
2170
2339
  throwForNonComparableFunction(expr) {
2171
2340
  if (!(expr instanceof FunctionExtension)) return;
2172
- const func = this.environment.filterRegister.get(expr.name);
2341
+ const func = this.environment.functionRegister.get(expr.name);
2173
2342
  if (func && func.returnType !== FunctionExpressionType.ValueType) {
2174
2343
  throw new JSONPathTypeError(`result of ${expr.name}() is not comparable`, expr.token);
2175
2344
  }
@@ -2177,30 +2346,53 @@ var json_p3 = (function (exports) {
2177
2346
  }
2178
2347
 
2179
2348
  /**
2180
- *
2349
+ * JSONPath environment options. The defaults are in compliance with JSONPath
2350
+ * standards.
2181
2351
  */
2182
2352
 
2183
- const defaultOptions = {
2184
- strict: true,
2185
- maxIntIndex: Math.pow(2, 53) - 1,
2186
- minIntIndex: -Math.pow(2, 53) - 1
2187
- };
2188
-
2189
2353
  /**
2190
2354
  *
2191
2355
  */
2192
2356
  class JSONPathEnvironment {
2193
2357
  /**
2358
+ * Indicates if the environment should to be strict about its compliance with
2359
+ * JSONPath standards.
2194
2360
  *
2361
+ * Defaults to `true`. Setting `strict` to `false` currently has no effect.
2362
+ * If/when we add non-standard features, the environment's strictness will
2363
+ * control their availability.
2195
2364
  */
2196
- filterRegister = new Map();
2365
+
2366
+ /**
2367
+ * The maximum number allowed when indexing or slicing an array. Defaults to
2368
+ * 2**53 -1.
2369
+ */
2370
+
2371
+ /**
2372
+ * The minimum number allowed when indexing or slicing an array. Defaults to
2373
+ * -(2**53) -1.
2374
+ */
2375
+
2376
+ /**
2377
+ * The maximum number of objects and/or arrays the recursive descent selector
2378
+ * can visit before a `JSONPathRecursionLimitError` is thrown.
2379
+ */
2380
+
2381
+ /**
2382
+ * A map of function names to objects implementing the {@link FilterFunction}
2383
+ * interface. You are free to set or delete custom filter functions directly.
2384
+ */
2385
+ functionRegister = new Map();
2197
2386
  /**
2198
2387
  *
2199
2388
  * @param options -
2200
2389
  */
2201
2390
  constructor() {
2202
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultOptions;
2203
- this.options = options;
2391
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2392
+ this.strict = options.strict ?? true;
2393
+ this.maxIntIndex = options.maxIntIndex ?? Math.pow(2, 53) - 1;
2394
+ this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) - 1;
2395
+ this.maxRecursionDepth = options.maxRecursionDepth ?? 50;
2204
2396
  this.parser = new Parser(this);
2205
2397
  this.setupFilterFunctions();
2206
2398
  }
@@ -2223,12 +2415,25 @@ var json_p3 = (function (exports) {
2223
2415
  query(path, value) {
2224
2416
  return this.compile(path).query(value);
2225
2417
  }
2418
+
2419
+ /**
2420
+ * Return a {@link JSONPathNode} instance for the first object found in
2421
+ * _value_ matching _path_.
2422
+ *
2423
+ * @param path - A JSONPath query.
2424
+ * @param value - JSON-like data to which the query _path_ will be applied.
2425
+ * @returns The first node in _value_ matching _path_, or `undefined` if
2426
+ * there are no matches.
2427
+ */
2428
+ match(path, value) {
2429
+ return this.compile(path).match(value);
2430
+ }
2226
2431
  setupFilterFunctions() {
2227
- this.filterRegister.set("count", new Count());
2228
- this.filterRegister.set("length", new Length());
2229
- this.filterRegister.set("search", new Search());
2230
- this.filterRegister.set("match", new Match());
2231
- this.filterRegister.set("value", new Value());
2432
+ this.functionRegister.set("count", new Count());
2433
+ this.functionRegister.set("length", new Length());
2434
+ this.functionRegister.set("search", new Search());
2435
+ this.functionRegister.set("match", new Match());
2436
+ this.functionRegister.set("value", new Value());
2232
2437
  }
2233
2438
 
2234
2439
  /**
@@ -2238,7 +2443,7 @@ var json_p3 = (function (exports) {
2238
2443
  */
2239
2444
  // eslint-disable-next-line sonarjs/cognitive-complexity
2240
2445
  checkWellTypedness(token, args) {
2241
- const func = this.filterRegister.get(token.value);
2446
+ const func = this.functionRegister.get(token.value);
2242
2447
  if (!func) {
2243
2448
  throw new UndefinedFilterFunctionError(`no such function '${token.value}'`, token);
2244
2449
  }
@@ -2252,17 +2457,17 @@ var json_p3 = (function (exports) {
2252
2457
  for (const [typ, arg, idx] of func.argTypes.map((t, i) => [t, args[i], i])) {
2253
2458
  switch (typ) {
2254
2459
  case FunctionExpressionType.ValueType:
2255
- if (!(arg instanceof FilterExpressionLiteral || arg instanceof JSONPathQuery && arg.path.singularQuery())) {
2460
+ if (!(arg instanceof FilterExpressionLiteral || arg instanceof JSONPathQuery && arg.path.singularQuery() || arg instanceof FunctionExtension && this.functionRegister.get(arg.name)?.returnType === FunctionExpressionType.ValueType)) {
2256
2461
  throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of ValueType`, arg.token);
2257
2462
  }
2258
2463
  break;
2259
2464
  case FunctionExpressionType.LogicalType:
2260
- if (!(arg instanceof BooleanLiteral)) {
2465
+ if (!(arg instanceof JSONPathQuery || arg instanceof InfixExpression)) {
2261
2466
  throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of LogicalType`, arg.token);
2262
2467
  }
2263
2468
  break;
2264
2469
  case FunctionExpressionType.NodesType:
2265
- if (!(arg instanceof JSONPathQuery)) {
2470
+ if (!(arg instanceof JSONPathQuery || arg instanceof FunctionExtension && this.functionRegister.get(arg.name)?.returnType === FunctionExpressionType.NodesType)) {
2266
2471
  throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of NodesType`, arg.token);
2267
2472
  }
2268
2473
  }
@@ -2317,6 +2522,19 @@ var json_p3 = (function (exports) {
2317
2522
  return DEFAULT_ENVIRONMENT.compile(path);
2318
2523
  }
2319
2524
 
2525
+ /**
2526
+ * Return a {@link JSONPathNode} instance for the first object found in
2527
+ * _value_ matching _path_.
2528
+ *
2529
+ * @param path - A JSONPath query.
2530
+ * @param value - JSON-like data to which the query _path_ will be applied.
2531
+ * @returns The first node in _value_ matching _path_, or `undefined` if
2532
+ * there are no matches.
2533
+ */
2534
+ function match(path, value) {
2535
+ return DEFAULT_ENVIRONMENT.match(path, value);
2536
+ }
2537
+
2320
2538
  var index$1 = /*#__PURE__*/Object.freeze({
2321
2539
  __proto__: null,
2322
2540
  DEFAULT_ENVIRONMENT: DEFAULT_ENVIRONMENT,
@@ -2328,6 +2546,7 @@ var json_p3 = (function (exports) {
2328
2546
  JSONPathLexerError: JSONPathLexerError,
2329
2547
  JSONPathNode: JSONPathNode,
2330
2548
  JSONPathNodeList: JSONPathNodeList,
2549
+ JSONPathRecursionLimitError: JSONPathRecursionLimitError,
2331
2550
  JSONPathSyntaxError: JSONPathSyntaxError,
2332
2551
  JSONPathTypeError: JSONPathTypeError,
2333
2552
  Nothing: Nothing,
@@ -2336,6 +2555,7 @@ var json_p3 = (function (exports) {
2336
2555
  compile: compile,
2337
2556
  expressions: expression,
2338
2557
  functions: index$2,
2558
+ match: match,
2339
2559
  query: query,
2340
2560
  selectors: selectors
2341
2561
  });
@@ -2636,6 +2856,15 @@ var json_p3 = (function (exports) {
2636
2856
  }
2637
2857
  }
2638
2858
 
2859
+ /**
2860
+ * @returns an iterator over ops in this patch.
2861
+ */
2862
+ *[Symbol.iterator]() {
2863
+ for (const op of this.ops) {
2864
+ yield op.toObject();
2865
+ }
2866
+ }
2867
+
2639
2868
  /**
2640
2869
  *
2641
2870
  * @param path -
@@ -2811,8 +3040,9 @@ var json_p3 = (function (exports) {
2811
3040
  apply: apply
2812
3041
  });
2813
3042
 
2814
- const version = "0.1.1";
3043
+ const version = "0.2.0";
2815
3044
 
3045
+ exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT;
2816
3046
  exports.FunctionExpressionType = FunctionExpressionType;
2817
3047
  exports.JSONPatch = JSONPatch;
2818
3048
  exports.JSONPatchError = JSONPatchError;
@@ -2824,10 +3054,12 @@ var json_p3 = (function (exports) {
2824
3054
  exports.JSONPathLexerError = JSONPathLexerError;
2825
3055
  exports.JSONPathNode = JSONPathNode;
2826
3056
  exports.JSONPathNodeList = JSONPathNodeList;
3057
+ exports.JSONPathRecursionLimitError = JSONPathRecursionLimitError;
2827
3058
  exports.JSONPathSyntaxError = JSONPathSyntaxError;
2828
3059
  exports.JSONPathTypeError = JSONPathTypeError;
2829
3060
  exports.JSONPointer = JSONPointer;
2830
3061
  exports.Nothing = Nothing;
3062
+ exports.RelativeJSONPointer = RelativeJSONPointer;
2831
3063
  exports.Token = Token;
2832
3064
  exports.TokenKind = TokenKind;
2833
3065
  exports.UNDEFINED = UNDEFINED;