json-p3 1.2.1 → 1.3.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/json-p3.cjs.js +204 -46
- package/dist/json-p3.esm.js +204 -46
- package/dist/json-p3.iife.js +204 -46
- package/dist/json-p3.iife.min.js +1 -1
- package/dist/json-p3.iife.min.js.map +1 -1
- package/dist/path/extra/selectors.d.ts +20 -0
- package/dist/path/index.d.ts +1 -1
- package/dist/path/lex.d.ts +1 -0
- package/dist/path/node.d.ts +1 -0
- package/dist/path/parse.d.ts +1 -1
- package/dist/path/token.d.ts +7 -3
- package/dist/path/types.d.ts +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/json-p3.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* json-p3 version 1.
|
|
2
|
+
* json-p3 version 1.3.0
|
|
3
3
|
* https://github.com/jg-rp/json-p3
|
|
4
4
|
*
|
|
5
5
|
* MIT License
|
|
@@ -639,6 +639,24 @@ var index$3 = /*#__PURE__*/Object.freeze({
|
|
|
639
639
|
resolve: resolve
|
|
640
640
|
});
|
|
641
641
|
|
|
642
|
+
const Nothing = Symbol.for("jsonpath.nothing");
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* ValueType for JSONPath function expression tye system.
|
|
646
|
+
*/
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Object passed to FilterExpression.evaluate().
|
|
650
|
+
*/
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* A type predicate for an object with a string property.
|
|
654
|
+
*/
|
|
655
|
+
function hasStringKey(value, key) {
|
|
656
|
+
return isObject(value) && Object.hasOwn(value, key);
|
|
657
|
+
}
|
|
658
|
+
const KEY_MARK = "\x02";
|
|
659
|
+
|
|
642
660
|
/**
|
|
643
661
|
* The pair of a JSON value and its location found in the target JSON value.
|
|
644
662
|
*/
|
|
@@ -656,7 +674,7 @@ class JSONPathNode {
|
|
|
656
674
|
get path() {
|
|
657
675
|
return (
|
|
658
676
|
// eslint-disable-next-line prefer-template
|
|
659
|
-
"$" + this.location.map(s => isString(s) ?
|
|
677
|
+
"$" + this.location.map(s => isString(s) ? this.decode_name_location(s) : `[${s}]`).join("")
|
|
660
678
|
);
|
|
661
679
|
}
|
|
662
680
|
|
|
@@ -669,6 +687,9 @@ class JSONPathNode {
|
|
|
669
687
|
}
|
|
670
688
|
return new JSONPointer(JSONPointer.encode(this.location.map(String)));
|
|
671
689
|
}
|
|
690
|
+
decode_name_location(name) {
|
|
691
|
+
return name.startsWith(KEY_MARK) ? `[~'${name.slice(1).replaceAll("'", "\\'")}']` : `['${name.replaceAll("'", "\\'")}']`;
|
|
692
|
+
}
|
|
672
693
|
}
|
|
673
694
|
|
|
674
695
|
/**
|
|
@@ -748,23 +769,6 @@ class JSONPathNodeList {
|
|
|
748
769
|
}
|
|
749
770
|
}
|
|
750
771
|
|
|
751
|
-
const Nothing = Symbol.for("jsonpath.nothing");
|
|
752
|
-
|
|
753
|
-
/**
|
|
754
|
-
* ValueType for JSONPath function expression tye system.
|
|
755
|
-
*/
|
|
756
|
-
|
|
757
|
-
/**
|
|
758
|
-
* Object passed to FilterExpression.evaluate().
|
|
759
|
-
*/
|
|
760
|
-
|
|
761
|
-
/**
|
|
762
|
-
* A type predicate for an object with a string property.
|
|
763
|
-
*/
|
|
764
|
-
function hasStringKey(value, key) {
|
|
765
|
-
return isObject(value) && Object.hasOwn(value, key);
|
|
766
|
-
}
|
|
767
|
-
|
|
768
772
|
/**
|
|
769
773
|
* Base class for all filter expressions.
|
|
770
774
|
*/
|
|
@@ -1167,7 +1171,8 @@ let TokenKind = /*#__PURE__*/function (TokenKind) {
|
|
|
1167
1171
|
TokenKind["AND"] = "TOKEN_AND";
|
|
1168
1172
|
TokenKind["COLON"] = "TOKEN_COLON";
|
|
1169
1173
|
TokenKind["COMMA"] = "TOKEN_COMMA";
|
|
1170
|
-
TokenKind["CURRENT"] = "
|
|
1174
|
+
TokenKind["CURRENT"] = "TOKEN_CURRENT_VALUE";
|
|
1175
|
+
TokenKind["CURRENT_KEY"] = "TOKEN_CURRENT_KEY";
|
|
1171
1176
|
TokenKind["DDOT"] = "TOKEN_DDOT";
|
|
1172
1177
|
TokenKind["DOT"] = "TOKEN_DOT";
|
|
1173
1178
|
TokenKind["DOUBLE_QUOTE_STRING"] = "TOKEN_DOUBLE_QUOTE_STRING";
|
|
@@ -1181,7 +1186,10 @@ let TokenKind = /*#__PURE__*/function (TokenKind) {
|
|
|
1181
1186
|
TokenKind["GT"] = "TOKEN_GT";
|
|
1182
1187
|
TokenKind["INDEX"] = "TOKEN_INDEX";
|
|
1183
1188
|
TokenKind["KEY"] = "TOKEN_KEY";
|
|
1189
|
+
TokenKind["KEY_DOUBLE_QUOTE_STRING"] = "TOKEN_KEY_DOUBLE_QUOTE_STRING";
|
|
1190
|
+
TokenKind["KEY_SINGLE_QUOTE_STRING"] = "TOKEN_KEY_SINGLE_QUOTE_STRING";
|
|
1184
1191
|
TokenKind["KEYS"] = "TOKEN_KEYS";
|
|
1192
|
+
TokenKind["KEYS_FILTER"] = "TOKEN_KEYS_FILTER";
|
|
1185
1193
|
TokenKind["LBRACKET"] = "TOKEN_LBRACKET";
|
|
1186
1194
|
TokenKind["LE"] = "TOKEN_LE";
|
|
1187
1195
|
TokenKind["LG"] = "TOKEN_LG";
|
|
@@ -1262,6 +1270,7 @@ const indexPattern = /-?\d+/y;
|
|
|
1262
1270
|
const intPattern = /-?[0-9]+/y;
|
|
1263
1271
|
const namePattern = /[\u0080-\uFFFFa-zA-Z_][\u0080-\uFFFFa-zA-Z0-9_-]*/y;
|
|
1264
1272
|
const whitespace = new Set([" ", "\n", "\t", "\r"]);
|
|
1273
|
+
const nameFirstPattern = /[\u0080-\uFFFFa-zA-Z_]/; // don't set sticky bit
|
|
1265
1274
|
|
|
1266
1275
|
/**
|
|
1267
1276
|
* JSONPath lexical scanner.
|
|
@@ -1334,6 +1343,11 @@ class Lexer {
|
|
|
1334
1343
|
if (ch) this.backup();
|
|
1335
1344
|
return ch;
|
|
1336
1345
|
}
|
|
1346
|
+
peekMatch(pattern) {
|
|
1347
|
+
const ch = this.next();
|
|
1348
|
+
if (ch) this.backup();
|
|
1349
|
+
return pattern.test(ch);
|
|
1350
|
+
}
|
|
1337
1351
|
accept(valid) {
|
|
1338
1352
|
const ch = this.next();
|
|
1339
1353
|
if (valid.has(ch)) return true;
|
|
@@ -1463,10 +1477,28 @@ function lexDescendantSelection(l) {
|
|
|
1463
1477
|
l.emit(TokenKind.NAME);
|
|
1464
1478
|
return lexSegment;
|
|
1465
1479
|
}
|
|
1466
|
-
if (!l.environment.strict
|
|
1467
|
-
//
|
|
1468
|
-
|
|
1469
|
-
|
|
1480
|
+
if (!l.environment.strict) {
|
|
1481
|
+
// We're effectively disabling the _key selector_ and _keys filter selector_ if a
|
|
1482
|
+
// custom _keys selector_ is set.
|
|
1483
|
+
if (l.environment.keysPattern.source === "~" && l.peek() === "~") {
|
|
1484
|
+
l.next();
|
|
1485
|
+
if (l.peekMatch(nameFirstPattern)) {
|
|
1486
|
+
// Non-standard key selector
|
|
1487
|
+
l.ignore(); // ignore ~
|
|
1488
|
+
l.acceptMatchRun(namePattern);
|
|
1489
|
+
l.emit(TokenKind.KEY);
|
|
1490
|
+
return lexSegment;
|
|
1491
|
+
} else {
|
|
1492
|
+
// Non-standard keys selector
|
|
1493
|
+
l.emit(TokenKind.KEYS);
|
|
1494
|
+
return lexSegment;
|
|
1495
|
+
}
|
|
1496
|
+
} else if (l.acceptMatchRun(l.environment.keysPattern)) {
|
|
1497
|
+
// NOTE: A custom keys pattern does not play well with other non-standard key selectors.
|
|
1498
|
+
// We leave this here for backwards compatibility.
|
|
1499
|
+
l.emit(TokenKind.KEYS);
|
|
1500
|
+
return lexSegment;
|
|
1501
|
+
}
|
|
1470
1502
|
}
|
|
1471
1503
|
const ch = l.next();
|
|
1472
1504
|
switch (ch) {
|
|
@@ -1491,9 +1523,28 @@ function lexDotSelector(l) {
|
|
|
1491
1523
|
l.error("unexpected whitespace after dot");
|
|
1492
1524
|
return null;
|
|
1493
1525
|
}
|
|
1494
|
-
if (!l.environment.strict
|
|
1495
|
-
|
|
1496
|
-
|
|
1526
|
+
if (!l.environment.strict) {
|
|
1527
|
+
// We're effectively disabling the _key selector_ and _keys filter selector_ if a
|
|
1528
|
+
// custom _keys selector_ is set.
|
|
1529
|
+
if (l.environment.keysPattern.source === "~" && l.peek() === "~") {
|
|
1530
|
+
l.next();
|
|
1531
|
+
if (l.peekMatch(nameFirstPattern)) {
|
|
1532
|
+
// Non-standard key selector
|
|
1533
|
+
l.ignore(); // ignore ~
|
|
1534
|
+
l.acceptMatchRun(namePattern);
|
|
1535
|
+
l.emit(TokenKind.KEY);
|
|
1536
|
+
return lexSegment;
|
|
1537
|
+
} else {
|
|
1538
|
+
// Non-standard keys selector
|
|
1539
|
+
l.emit(TokenKind.KEYS);
|
|
1540
|
+
return lexSegment;
|
|
1541
|
+
}
|
|
1542
|
+
} else if (l.acceptMatchRun(l.environment.keysPattern)) {
|
|
1543
|
+
// NOTE: A custom keys pattern does not play well with other non-standard key selectors.
|
|
1544
|
+
// We leave this here for backwards compatibility.
|
|
1545
|
+
l.emit(TokenKind.KEYS);
|
|
1546
|
+
return lexSegment;
|
|
1547
|
+
}
|
|
1497
1548
|
}
|
|
1498
1549
|
if (l.acceptMatchRun(namePattern)) {
|
|
1499
1550
|
l.emit(TokenKind.NAME);
|
|
@@ -1516,8 +1567,25 @@ function lexInsideBracketedSelection(l) {
|
|
|
1516
1567
|
continue;
|
|
1517
1568
|
}
|
|
1518
1569
|
if (!l.environment.strict && l.acceptMatchRun(l.environment.keysPattern)) {
|
|
1519
|
-
l.
|
|
1520
|
-
|
|
1570
|
+
switch (l.peek()) {
|
|
1571
|
+
case "'":
|
|
1572
|
+
l.ignore(); // ~
|
|
1573
|
+
l.next();
|
|
1574
|
+
return lexSingleQuoteKeyString(l);
|
|
1575
|
+
case '"':
|
|
1576
|
+
l.ignore(); // ~
|
|
1577
|
+
l.next();
|
|
1578
|
+
return lexDoubleQuoteKeyString(l);
|
|
1579
|
+
case "?":
|
|
1580
|
+
l.ignore(); // ~
|
|
1581
|
+
l.next();
|
|
1582
|
+
l.emit(TokenKind.KEYS_FILTER);
|
|
1583
|
+
l.filterLevel += 1;
|
|
1584
|
+
return lexInsideFilter;
|
|
1585
|
+
default:
|
|
1586
|
+
l.emit(TokenKind.KEYS);
|
|
1587
|
+
continue;
|
|
1588
|
+
}
|
|
1521
1589
|
}
|
|
1522
1590
|
const ch = l.next();
|
|
1523
1591
|
switch (ch) {
|
|
@@ -1604,7 +1672,7 @@ function lexInsideFilter(l) {
|
|
|
1604
1672
|
l.emit(TokenKind.CURRENT);
|
|
1605
1673
|
return lexSegment;
|
|
1606
1674
|
case "#":
|
|
1607
|
-
l.emit(TokenKind.
|
|
1675
|
+
l.emit(TokenKind.CURRENT_KEY);
|
|
1608
1676
|
return lexSegment;
|
|
1609
1677
|
case ".":
|
|
1610
1678
|
l.backup();
|
|
@@ -1704,8 +1772,7 @@ function lexInsideFilter(l) {
|
|
|
1704
1772
|
* @param state - The state function to return control to.
|
|
1705
1773
|
* @returns String tokenizing state function.
|
|
1706
1774
|
*/
|
|
1707
|
-
function makeLexString(quote, state) {
|
|
1708
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
1775
|
+
function makeLexString(quote, state, token_kind) {
|
|
1709
1776
|
function _lexString(l) {
|
|
1710
1777
|
l.ignore();
|
|
1711
1778
|
if (l.peek() === quote) {
|
|
@@ -1731,7 +1798,7 @@ function makeLexString(quote, state) {
|
|
|
1731
1798
|
}
|
|
1732
1799
|
if (ch === quote) {
|
|
1733
1800
|
l.backup();
|
|
1734
|
-
l.emit(
|
|
1801
|
+
l.emit(token_kind);
|
|
1735
1802
|
l.next();
|
|
1736
1803
|
l.ignore();
|
|
1737
1804
|
return state;
|
|
@@ -1740,10 +1807,12 @@ function makeLexString(quote, state) {
|
|
|
1740
1807
|
}
|
|
1741
1808
|
return _lexString;
|
|
1742
1809
|
}
|
|
1743
|
-
const lexSingleQuoteStringInsideBracketSelection = makeLexString("'", lexInsideBracketedSelection);
|
|
1744
|
-
const lexDoubleQuoteStringInsideBracketSelection = makeLexString('"', lexInsideBracketedSelection);
|
|
1745
|
-
const lexSingleQuoteStringInsideFilterExpression = makeLexString("'", lexInsideFilter);
|
|
1746
|
-
const lexDoubleQuoteStringInsideFilterExpression = makeLexString('"', lexInsideFilter);
|
|
1810
|
+
const lexSingleQuoteStringInsideBracketSelection = makeLexString("'", lexInsideBracketedSelection, TokenKind.SINGLE_QUOTE_STRING);
|
|
1811
|
+
const lexDoubleQuoteStringInsideBracketSelection = makeLexString('"', lexInsideBracketedSelection, TokenKind.DOUBLE_QUOTE_STRING);
|
|
1812
|
+
const lexSingleQuoteStringInsideFilterExpression = makeLexString("'", lexInsideFilter, TokenKind.SINGLE_QUOTE_STRING);
|
|
1813
|
+
const lexDoubleQuoteStringInsideFilterExpression = makeLexString('"', lexInsideFilter, TokenKind.DOUBLE_QUOTE_STRING);
|
|
1814
|
+
const lexSingleQuoteKeyString = makeLexString("'", lexInsideBracketedSelection, TokenKind.KEY_SINGLE_QUOTE_STRING);
|
|
1815
|
+
const lexDoubleQuoteKeyString = makeLexString('"', lexInsideBracketedSelection, TokenKind.KEY_DOUBLE_QUOTE_STRING);
|
|
1747
1816
|
|
|
1748
1817
|
/**
|
|
1749
1818
|
* Base class for all JSONPath segments and selectors.
|
|
@@ -2392,6 +2461,38 @@ class CurrentKey extends FilterExpression {
|
|
|
2392
2461
|
}
|
|
2393
2462
|
}
|
|
2394
2463
|
|
|
2464
|
+
class KeySelector extends JSONPathSelector {
|
|
2465
|
+
constructor(environment, token, key) {
|
|
2466
|
+
let shorthand = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
2467
|
+
super(environment, token);
|
|
2468
|
+
this.environment = environment;
|
|
2469
|
+
this.token = token;
|
|
2470
|
+
this.key = key;
|
|
2471
|
+
this.shorthand = shorthand;
|
|
2472
|
+
}
|
|
2473
|
+
resolve(nodes) {
|
|
2474
|
+
const rv = [];
|
|
2475
|
+
for (const node of nodes) {
|
|
2476
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2477
|
+
if (isObject(node.value) && hasStringKey(node.value, this.key)) {
|
|
2478
|
+
rv.push(new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root));
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
return rv;
|
|
2482
|
+
}
|
|
2483
|
+
*lazyResolve(nodes) {
|
|
2484
|
+
for (const node of nodes) {
|
|
2485
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2486
|
+
if (isObject(node.value) && hasStringKey(node.value, this.key)) {
|
|
2487
|
+
yield new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root);
|
|
2488
|
+
}
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
toString() {
|
|
2492
|
+
return this.shorthand ? `[~'${this.key.replaceAll("'", "\\'")}']` : `~'${this.key.replaceAll("'", "\\'")}'`;
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
|
|
2395
2496
|
/**
|
|
2396
2497
|
* Object property name selector or array index selector.
|
|
2397
2498
|
*/
|
|
@@ -2408,10 +2509,8 @@ class KeysSelector extends JSONPathSelector {
|
|
|
2408
2509
|
for (const node of nodes) {
|
|
2409
2510
|
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2410
2511
|
if (isObject(node.value)) {
|
|
2411
|
-
let i = 0;
|
|
2412
2512
|
for (const [key, _] of this.environment.entries(node.value)) {
|
|
2413
|
-
rv.push(new JSONPathNode(key, node.location.concat(
|
|
2414
|
-
i++;
|
|
2513
|
+
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
2415
2514
|
}
|
|
2416
2515
|
}
|
|
2417
2516
|
}
|
|
@@ -2421,10 +2520,8 @@ class KeysSelector extends JSONPathSelector {
|
|
|
2421
2520
|
for (const node of nodes) {
|
|
2422
2521
|
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2423
2522
|
if (isObject(node.value)) {
|
|
2424
|
-
let i = 0;
|
|
2425
2523
|
for (const [key, _] of this.environment.entries(node.value)) {
|
|
2426
|
-
yield new JSONPathNode(key, node.location.concat(
|
|
2427
|
-
i++;
|
|
2524
|
+
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
2428
2525
|
}
|
|
2429
2526
|
}
|
|
2430
2527
|
}
|
|
@@ -2433,6 +2530,56 @@ class KeysSelector extends JSONPathSelector {
|
|
|
2433
2530
|
return this.shorthand ? "[~]" : "~";
|
|
2434
2531
|
}
|
|
2435
2532
|
}
|
|
2533
|
+
class KeysFilterSelector extends JSONPathSelector {
|
|
2534
|
+
constructor(environment, token, expression) {
|
|
2535
|
+
super(environment, token);
|
|
2536
|
+
this.environment = environment;
|
|
2537
|
+
this.token = token;
|
|
2538
|
+
this.expression = expression;
|
|
2539
|
+
}
|
|
2540
|
+
resolve(nodes) {
|
|
2541
|
+
const rv = [];
|
|
2542
|
+
for (const node of nodes) {
|
|
2543
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2544
|
+
if (isObject(node.value)) {
|
|
2545
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
2546
|
+
const filterContext = {
|
|
2547
|
+
environment: this.environment,
|
|
2548
|
+
currentValue: value,
|
|
2549
|
+
rootValue: node.root,
|
|
2550
|
+
currentKey: key
|
|
2551
|
+
};
|
|
2552
|
+
if (this.expression.evaluate(filterContext)) {
|
|
2553
|
+
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
return rv;
|
|
2559
|
+
}
|
|
2560
|
+
*lazyResolve(nodes) {
|
|
2561
|
+
for (const node of nodes) {
|
|
2562
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2563
|
+
if (isObject(node.value)) {
|
|
2564
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
2565
|
+
const filterContext = {
|
|
2566
|
+
environment: this.environment,
|
|
2567
|
+
currentValue: value,
|
|
2568
|
+
rootValue: node.root,
|
|
2569
|
+
lazy: true,
|
|
2570
|
+
currentKey: key
|
|
2571
|
+
};
|
|
2572
|
+
if (this.expression.evaluate(filterContext)) {
|
|
2573
|
+
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
2574
|
+
}
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
toString() {
|
|
2580
|
+
return `~?${this.expression.toString()}`;
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2436
2583
|
|
|
2437
2584
|
const PRECEDENCE_LOWEST = 1;
|
|
2438
2585
|
const PRECEDENCE_LOGICAL_OR = 4;
|
|
@@ -2449,7 +2596,7 @@ const COMPARISON_OPERATORS = new Set(["==", ">=", ">", "<=", "<", "!="]);
|
|
|
2449
2596
|
class Parser {
|
|
2450
2597
|
constructor(environment) {
|
|
2451
2598
|
this.environment = environment;
|
|
2452
|
-
this.tokenMap = new Map([[TokenKind.FALSE, this.parseBoolean], [TokenKind.NUMBER, this.parseNumber], [TokenKind.LPAREN, this.parseGroupedExpression], [TokenKind.NOT, this.parsePrefixExpression], [TokenKind.NULL, this.parseNull], [TokenKind.ROOT, this.parseRootQuery], [TokenKind.CURRENT, this.parseRelativeQuery], [TokenKind.SINGLE_QUOTE_STRING, this.parseString], [TokenKind.DOUBLE_QUOTE_STRING, this.parseString], [TokenKind.TRUE, this.parseBoolean], [TokenKind.FUNCTION, this.parseFunction], [TokenKind.
|
|
2599
|
+
this.tokenMap = new Map([[TokenKind.FALSE, this.parseBoolean], [TokenKind.NUMBER, this.parseNumber], [TokenKind.LPAREN, this.parseGroupedExpression], [TokenKind.NOT, this.parsePrefixExpression], [TokenKind.NULL, this.parseNull], [TokenKind.ROOT, this.parseRootQuery], [TokenKind.CURRENT, this.parseRelativeQuery], [TokenKind.SINGLE_QUOTE_STRING, this.parseString], [TokenKind.DOUBLE_QUOTE_STRING, this.parseString], [TokenKind.TRUE, this.parseBoolean], [TokenKind.FUNCTION, this.parseFunction], [TokenKind.CURRENT_KEY, this.parseCurrentKey]]);
|
|
2453
2600
|
}
|
|
2454
2601
|
parse(stream) {
|
|
2455
2602
|
if (stream.current.kind === TokenKind.ROOT) stream.next();
|
|
@@ -2481,6 +2628,8 @@ class Parser {
|
|
|
2481
2628
|
return new NameSelector(this.environment, stream.current, stream.current.value, true);
|
|
2482
2629
|
case TokenKind.WILD:
|
|
2483
2630
|
return new WildcardSelector(this.environment, stream.current, true);
|
|
2631
|
+
case TokenKind.KEY:
|
|
2632
|
+
return new KeySelector(this.environment, stream.current, stream.current.value, true);
|
|
2484
2633
|
case TokenKind.KEYS:
|
|
2485
2634
|
return new KeysSelector(this.environment, stream.current, true);
|
|
2486
2635
|
case TokenKind.DDOT:
|
|
@@ -2576,6 +2725,13 @@ class Parser {
|
|
|
2576
2725
|
case TokenKind.WILD:
|
|
2577
2726
|
items.push(new WildcardSelector(this.environment, stream.current));
|
|
2578
2727
|
break;
|
|
2728
|
+
case TokenKind.KEY_SINGLE_QUOTE_STRING:
|
|
2729
|
+
case TokenKind.KEY_DOUBLE_QUOTE_STRING:
|
|
2730
|
+
items.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current, true), false));
|
|
2731
|
+
break;
|
|
2732
|
+
case TokenKind.KEYS_FILTER:
|
|
2733
|
+
items.push(this.parseFilter(stream, true));
|
|
2734
|
+
break;
|
|
2579
2735
|
case TokenKind.KEYS:
|
|
2580
2736
|
items.push(new KeysSelector(this.environment, stream.current));
|
|
2581
2737
|
break;
|
|
@@ -2596,6 +2752,7 @@ class Parser {
|
|
|
2596
2752
|
return new BracketedSelection(this.environment, token, items);
|
|
2597
2753
|
}
|
|
2598
2754
|
parseFilter(stream) {
|
|
2755
|
+
let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
2599
2756
|
const tok = stream.next();
|
|
2600
2757
|
const expr = this.parseFilterExpression(stream);
|
|
2601
2758
|
if (expr instanceof FunctionExtension) {
|
|
@@ -2604,7 +2761,7 @@ class Parser {
|
|
|
2604
2761
|
throw new JSONPathTypeError(`result of ${expr.name}() must be compared`, expr.token);
|
|
2605
2762
|
}
|
|
2606
2763
|
}
|
|
2607
|
-
return new FilterSelector(this.environment, tok, new LogicalExpression(tok, expr));
|
|
2764
|
+
return keys ? new KeysFilterSelector(this.environment, tok, new LogicalExpression(tok, expr)) : new FilterSelector(this.environment, tok, new LogicalExpression(tok, expr));
|
|
2608
2765
|
}
|
|
2609
2766
|
parseBoolean(stream) {
|
|
2610
2767
|
if (stream.current.kind === TokenKind.FALSE) return new BooleanLiteral(stream.current, false);
|
|
@@ -3032,6 +3189,7 @@ var index$1 = /*#__PURE__*/Object.freeze({
|
|
|
3032
3189
|
JSONPathRecursionLimitError: JSONPathRecursionLimitError,
|
|
3033
3190
|
JSONPathSyntaxError: JSONPathSyntaxError,
|
|
3034
3191
|
JSONPathTypeError: JSONPathTypeError,
|
|
3192
|
+
KEY_MARK: KEY_MARK,
|
|
3035
3193
|
Nothing: Nothing,
|
|
3036
3194
|
Token: Token,
|
|
3037
3195
|
TokenKind: TokenKind,
|
|
@@ -3524,6 +3682,6 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
3524
3682
|
apply: apply
|
|
3525
3683
|
});
|
|
3526
3684
|
|
|
3527
|
-
const version = "1.
|
|
3685
|
+
const version = "1.3.0";
|
|
3528
3686
|
|
|
3529
3687
|
export { DEFAULT_ENVIRONMENT, FunctionExpressionType, JSONPatch, JSONPatchError, JSONPatchTestFailure, JSONPath, JSONPathEnvironment, JSONPathError, JSONPathIndexError, JSONPathLexerError, JSONPathNode, JSONPathNodeList, 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 };
|