json-p3 1.2.1 → 1.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.
- package/dist/json-p3.cjs.js +290 -50
- package/dist/json-p3.esm.js +290 -50
- package/dist/json-p3.iife.js +290 -50
- 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/functions/match.d.ts +1 -0
- package/dist/path/functions/search.d.ts +1 -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.iife.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* json-p3 version 1.
|
|
2
|
+
* json-p3 version 1.3.1
|
|
3
3
|
* https://github.com/jg-rp/json-p3
|
|
4
4
|
*
|
|
5
5
|
* MIT License
|
|
@@ -642,6 +642,24 @@ var json_p3 = (function (exports) {
|
|
|
642
642
|
resolve: resolve
|
|
643
643
|
});
|
|
644
644
|
|
|
645
|
+
const Nothing = Symbol.for("jsonpath.nothing");
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* ValueType for JSONPath function expression tye system.
|
|
649
|
+
*/
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Object passed to FilterExpression.evaluate().
|
|
653
|
+
*/
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* A type predicate for an object with a string property.
|
|
657
|
+
*/
|
|
658
|
+
function hasStringKey(value, key) {
|
|
659
|
+
return isObject(value) && Object.hasOwn(value, key);
|
|
660
|
+
}
|
|
661
|
+
const KEY_MARK = "\x02";
|
|
662
|
+
|
|
645
663
|
/**
|
|
646
664
|
* The pair of a JSON value and its location found in the target JSON value.
|
|
647
665
|
*/
|
|
@@ -659,7 +677,7 @@ var json_p3 = (function (exports) {
|
|
|
659
677
|
get path() {
|
|
660
678
|
return (
|
|
661
679
|
// eslint-disable-next-line prefer-template
|
|
662
|
-
"$" + this.location.map(s => isString(s) ?
|
|
680
|
+
"$" + this.location.map(s => isString(s) ? this.decode_name_location(s) : `[${s}]`).join("")
|
|
663
681
|
);
|
|
664
682
|
}
|
|
665
683
|
|
|
@@ -672,6 +690,9 @@ var json_p3 = (function (exports) {
|
|
|
672
690
|
}
|
|
673
691
|
return new JSONPointer(JSONPointer.encode(this.location.map(String)));
|
|
674
692
|
}
|
|
693
|
+
decode_name_location(name) {
|
|
694
|
+
return name.startsWith(KEY_MARK) ? `[~'${name.slice(1).replaceAll("'", "\\'")}']` : `['${name.replaceAll("'", "\\'")}']`;
|
|
695
|
+
}
|
|
675
696
|
}
|
|
676
697
|
|
|
677
698
|
/**
|
|
@@ -751,23 +772,6 @@ var json_p3 = (function (exports) {
|
|
|
751
772
|
}
|
|
752
773
|
}
|
|
753
774
|
|
|
754
|
-
const Nothing = Symbol.for("jsonpath.nothing");
|
|
755
|
-
|
|
756
|
-
/**
|
|
757
|
-
* ValueType for JSONPath function expression tye system.
|
|
758
|
-
*/
|
|
759
|
-
|
|
760
|
-
/**
|
|
761
|
-
* Object passed to FilterExpression.evaluate().
|
|
762
|
-
*/
|
|
763
|
-
|
|
764
|
-
/**
|
|
765
|
-
* A type predicate for an object with a string property.
|
|
766
|
-
*/
|
|
767
|
-
function hasStringKey(value, key) {
|
|
768
|
-
return isObject(value) && Object.hasOwn(value, key);
|
|
769
|
-
}
|
|
770
|
-
|
|
771
775
|
/**
|
|
772
776
|
* Base class for all filter expressions.
|
|
773
777
|
*/
|
|
@@ -1113,9 +1117,53 @@ var json_p3 = (function (exports) {
|
|
|
1113
1117
|
}
|
|
1114
1118
|
fullMatch(pattern) {
|
|
1115
1119
|
const parts = [];
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1120
|
+
let nonCaptureGroup = false;
|
|
1121
|
+
if (!pattern.startsWith("^") && !pattern.startsWith("^(")) {
|
|
1122
|
+
nonCaptureGroup = true;
|
|
1123
|
+
parts.push("^(?:");
|
|
1124
|
+
}
|
|
1125
|
+
parts.push(this.mapRegexp(pattern));
|
|
1126
|
+
if (nonCaptureGroup && !pattern.endsWith("$") && !pattern.endsWith(")$")) {
|
|
1127
|
+
parts.push(")$");
|
|
1128
|
+
}
|
|
1129
|
+
return parts.join("");
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// See https://datatracker.ietf.org/doc/html/rfc9485#name-ecmascript-regexps
|
|
1133
|
+
mapRegexp(pattern) {
|
|
1134
|
+
let escaped = false;
|
|
1135
|
+
let charClass = false;
|
|
1136
|
+
const parts = [];
|
|
1137
|
+
for (const ch of pattern) {
|
|
1138
|
+
switch (ch) {
|
|
1139
|
+
case ".":
|
|
1140
|
+
if (!escaped && !charClass) {
|
|
1141
|
+
parts.push("(?:(?![\r\n])\\P{Cs}|\\p{Cs}\\p{Cs})");
|
|
1142
|
+
} else {
|
|
1143
|
+
parts.push(ch);
|
|
1144
|
+
escaped = false;
|
|
1145
|
+
}
|
|
1146
|
+
break;
|
|
1147
|
+
case "\\":
|
|
1148
|
+
escaped = true;
|
|
1149
|
+
parts.push(ch);
|
|
1150
|
+
break;
|
|
1151
|
+
case "[":
|
|
1152
|
+
charClass = true;
|
|
1153
|
+
escaped = false;
|
|
1154
|
+
parts.push(ch);
|
|
1155
|
+
break;
|
|
1156
|
+
case "]":
|
|
1157
|
+
charClass = false;
|
|
1158
|
+
escaped = false;
|
|
1159
|
+
parts.push(ch);
|
|
1160
|
+
break;
|
|
1161
|
+
default:
|
|
1162
|
+
escaped = false;
|
|
1163
|
+
parts.push(ch);
|
|
1164
|
+
break;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1119
1167
|
return parts.join("");
|
|
1120
1168
|
}
|
|
1121
1169
|
}
|
|
@@ -1144,7 +1192,7 @@ var json_p3 = (function (exports) {
|
|
|
1144
1192
|
}
|
|
1145
1193
|
}
|
|
1146
1194
|
try {
|
|
1147
|
-
const re = new RegExp(pattern, "u");
|
|
1195
|
+
const re = new RegExp(this.mapRegexp(pattern), "u");
|
|
1148
1196
|
if (this.cacheSize > 0) this.#cache.set(pattern, re);
|
|
1149
1197
|
return !!s.match(re);
|
|
1150
1198
|
} catch (error) {
|
|
@@ -1152,6 +1200,44 @@ var json_p3 = (function (exports) {
|
|
|
1152
1200
|
return false;
|
|
1153
1201
|
}
|
|
1154
1202
|
}
|
|
1203
|
+
|
|
1204
|
+
// See https://datatracker.ietf.org/doc/html/rfc9485#name-ecmascript-regexps
|
|
1205
|
+
mapRegexp(pattern) {
|
|
1206
|
+
let escaped = false;
|
|
1207
|
+
let charClass = false;
|
|
1208
|
+
const parts = [];
|
|
1209
|
+
for (const ch of pattern) {
|
|
1210
|
+
switch (ch) {
|
|
1211
|
+
case ".":
|
|
1212
|
+
if (!escaped && !charClass) {
|
|
1213
|
+
parts.push("(?:(?![\r\n])\\P{Cs}|\\p{Cs}\\p{Cs})");
|
|
1214
|
+
} else {
|
|
1215
|
+
parts.push(ch);
|
|
1216
|
+
escaped = false;
|
|
1217
|
+
}
|
|
1218
|
+
break;
|
|
1219
|
+
case "\\":
|
|
1220
|
+
escaped = true;
|
|
1221
|
+
parts.push(ch);
|
|
1222
|
+
break;
|
|
1223
|
+
case "[":
|
|
1224
|
+
charClass = true;
|
|
1225
|
+
escaped = false;
|
|
1226
|
+
parts.push(ch);
|
|
1227
|
+
break;
|
|
1228
|
+
case "]":
|
|
1229
|
+
charClass = false;
|
|
1230
|
+
escaped = false;
|
|
1231
|
+
parts.push(ch);
|
|
1232
|
+
break;
|
|
1233
|
+
default:
|
|
1234
|
+
escaped = false;
|
|
1235
|
+
parts.push(ch);
|
|
1236
|
+
break;
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
return parts.join("");
|
|
1240
|
+
}
|
|
1155
1241
|
}
|
|
1156
1242
|
|
|
1157
1243
|
class Value {
|
|
@@ -1170,7 +1256,8 @@ var json_p3 = (function (exports) {
|
|
|
1170
1256
|
TokenKind["AND"] = "TOKEN_AND";
|
|
1171
1257
|
TokenKind["COLON"] = "TOKEN_COLON";
|
|
1172
1258
|
TokenKind["COMMA"] = "TOKEN_COMMA";
|
|
1173
|
-
TokenKind["CURRENT"] = "
|
|
1259
|
+
TokenKind["CURRENT"] = "TOKEN_CURRENT_VALUE";
|
|
1260
|
+
TokenKind["CURRENT_KEY"] = "TOKEN_CURRENT_KEY";
|
|
1174
1261
|
TokenKind["DDOT"] = "TOKEN_DDOT";
|
|
1175
1262
|
TokenKind["DOT"] = "TOKEN_DOT";
|
|
1176
1263
|
TokenKind["DOUBLE_QUOTE_STRING"] = "TOKEN_DOUBLE_QUOTE_STRING";
|
|
@@ -1184,7 +1271,10 @@ var json_p3 = (function (exports) {
|
|
|
1184
1271
|
TokenKind["GT"] = "TOKEN_GT";
|
|
1185
1272
|
TokenKind["INDEX"] = "TOKEN_INDEX";
|
|
1186
1273
|
TokenKind["KEY"] = "TOKEN_KEY";
|
|
1274
|
+
TokenKind["KEY_DOUBLE_QUOTE_STRING"] = "TOKEN_KEY_DOUBLE_QUOTE_STRING";
|
|
1275
|
+
TokenKind["KEY_SINGLE_QUOTE_STRING"] = "TOKEN_KEY_SINGLE_QUOTE_STRING";
|
|
1187
1276
|
TokenKind["KEYS"] = "TOKEN_KEYS";
|
|
1277
|
+
TokenKind["KEYS_FILTER"] = "TOKEN_KEYS_FILTER";
|
|
1188
1278
|
TokenKind["LBRACKET"] = "TOKEN_LBRACKET";
|
|
1189
1279
|
TokenKind["LE"] = "TOKEN_LE";
|
|
1190
1280
|
TokenKind["LG"] = "TOKEN_LG";
|
|
@@ -1265,6 +1355,7 @@ var json_p3 = (function (exports) {
|
|
|
1265
1355
|
const intPattern = /-?[0-9]+/y;
|
|
1266
1356
|
const namePattern = /[\u0080-\uFFFFa-zA-Z_][\u0080-\uFFFFa-zA-Z0-9_-]*/y;
|
|
1267
1357
|
const whitespace = new Set([" ", "\n", "\t", "\r"]);
|
|
1358
|
+
const nameFirstPattern = /[\u0080-\uFFFFa-zA-Z_]/; // don't set sticky bit
|
|
1268
1359
|
|
|
1269
1360
|
/**
|
|
1270
1361
|
* JSONPath lexical scanner.
|
|
@@ -1337,6 +1428,11 @@ var json_p3 = (function (exports) {
|
|
|
1337
1428
|
if (ch) this.backup();
|
|
1338
1429
|
return ch;
|
|
1339
1430
|
}
|
|
1431
|
+
peekMatch(pattern) {
|
|
1432
|
+
const ch = this.next();
|
|
1433
|
+
if (ch) this.backup();
|
|
1434
|
+
return pattern.test(ch);
|
|
1435
|
+
}
|
|
1340
1436
|
accept(valid) {
|
|
1341
1437
|
const ch = this.next();
|
|
1342
1438
|
if (valid.has(ch)) return true;
|
|
@@ -1466,10 +1562,28 @@ var json_p3 = (function (exports) {
|
|
|
1466
1562
|
l.emit(TokenKind.NAME);
|
|
1467
1563
|
return lexSegment;
|
|
1468
1564
|
}
|
|
1469
|
-
if (!l.environment.strict
|
|
1470
|
-
//
|
|
1471
|
-
|
|
1472
|
-
|
|
1565
|
+
if (!l.environment.strict) {
|
|
1566
|
+
// We're effectively disabling the _key selector_ and _keys filter selector_ if a
|
|
1567
|
+
// custom _keys selector_ is set.
|
|
1568
|
+
if (l.environment.keysPattern.source === "~" && l.peek() === "~") {
|
|
1569
|
+
l.next();
|
|
1570
|
+
if (l.peekMatch(nameFirstPattern)) {
|
|
1571
|
+
// Non-standard key selector
|
|
1572
|
+
l.ignore(); // ignore ~
|
|
1573
|
+
l.acceptMatchRun(namePattern);
|
|
1574
|
+
l.emit(TokenKind.KEY);
|
|
1575
|
+
return lexSegment;
|
|
1576
|
+
} else {
|
|
1577
|
+
// Non-standard keys selector
|
|
1578
|
+
l.emit(TokenKind.KEYS);
|
|
1579
|
+
return lexSegment;
|
|
1580
|
+
}
|
|
1581
|
+
} else if (l.acceptMatchRun(l.environment.keysPattern)) {
|
|
1582
|
+
// NOTE: A custom keys pattern does not play well with other non-standard key selectors.
|
|
1583
|
+
// We leave this here for backwards compatibility.
|
|
1584
|
+
l.emit(TokenKind.KEYS);
|
|
1585
|
+
return lexSegment;
|
|
1586
|
+
}
|
|
1473
1587
|
}
|
|
1474
1588
|
const ch = l.next();
|
|
1475
1589
|
switch (ch) {
|
|
@@ -1494,9 +1608,28 @@ var json_p3 = (function (exports) {
|
|
|
1494
1608
|
l.error("unexpected whitespace after dot");
|
|
1495
1609
|
return null;
|
|
1496
1610
|
}
|
|
1497
|
-
if (!l.environment.strict
|
|
1498
|
-
|
|
1499
|
-
|
|
1611
|
+
if (!l.environment.strict) {
|
|
1612
|
+
// We're effectively disabling the _key selector_ and _keys filter selector_ if a
|
|
1613
|
+
// custom _keys selector_ is set.
|
|
1614
|
+
if (l.environment.keysPattern.source === "~" && l.peek() === "~") {
|
|
1615
|
+
l.next();
|
|
1616
|
+
if (l.peekMatch(nameFirstPattern)) {
|
|
1617
|
+
// Non-standard key selector
|
|
1618
|
+
l.ignore(); // ignore ~
|
|
1619
|
+
l.acceptMatchRun(namePattern);
|
|
1620
|
+
l.emit(TokenKind.KEY);
|
|
1621
|
+
return lexSegment;
|
|
1622
|
+
} else {
|
|
1623
|
+
// Non-standard keys selector
|
|
1624
|
+
l.emit(TokenKind.KEYS);
|
|
1625
|
+
return lexSegment;
|
|
1626
|
+
}
|
|
1627
|
+
} else if (l.acceptMatchRun(l.environment.keysPattern)) {
|
|
1628
|
+
// NOTE: A custom keys pattern does not play well with other non-standard key selectors.
|
|
1629
|
+
// We leave this here for backwards compatibility.
|
|
1630
|
+
l.emit(TokenKind.KEYS);
|
|
1631
|
+
return lexSegment;
|
|
1632
|
+
}
|
|
1500
1633
|
}
|
|
1501
1634
|
if (l.acceptMatchRun(namePattern)) {
|
|
1502
1635
|
l.emit(TokenKind.NAME);
|
|
@@ -1519,8 +1652,25 @@ var json_p3 = (function (exports) {
|
|
|
1519
1652
|
continue;
|
|
1520
1653
|
}
|
|
1521
1654
|
if (!l.environment.strict && l.acceptMatchRun(l.environment.keysPattern)) {
|
|
1522
|
-
|
|
1523
|
-
|
|
1655
|
+
// FIXME: fall back to legacy behavior if keysPattern is not the default
|
|
1656
|
+
switch (l.peek()) {
|
|
1657
|
+
case "'":
|
|
1658
|
+
l.ignore(); // ~
|
|
1659
|
+
l.next();
|
|
1660
|
+
return lexSingleQuoteKeyString(l);
|
|
1661
|
+
case '"':
|
|
1662
|
+
l.ignore(); // ~
|
|
1663
|
+
l.next();
|
|
1664
|
+
return lexDoubleQuoteKeyString(l);
|
|
1665
|
+
case "?":
|
|
1666
|
+
l.next();
|
|
1667
|
+
l.emit(TokenKind.KEYS_FILTER);
|
|
1668
|
+
l.filterLevel += 1;
|
|
1669
|
+
return lexInsideFilter;
|
|
1670
|
+
default:
|
|
1671
|
+
l.emit(TokenKind.KEYS);
|
|
1672
|
+
continue;
|
|
1673
|
+
}
|
|
1524
1674
|
}
|
|
1525
1675
|
const ch = l.next();
|
|
1526
1676
|
switch (ch) {
|
|
@@ -1607,7 +1757,7 @@ var json_p3 = (function (exports) {
|
|
|
1607
1757
|
l.emit(TokenKind.CURRENT);
|
|
1608
1758
|
return lexSegment;
|
|
1609
1759
|
case "#":
|
|
1610
|
-
l.emit(TokenKind.
|
|
1760
|
+
l.emit(TokenKind.CURRENT_KEY);
|
|
1611
1761
|
return lexSegment;
|
|
1612
1762
|
case ".":
|
|
1613
1763
|
l.backup();
|
|
@@ -1707,8 +1857,7 @@ var json_p3 = (function (exports) {
|
|
|
1707
1857
|
* @param state - The state function to return control to.
|
|
1708
1858
|
* @returns String tokenizing state function.
|
|
1709
1859
|
*/
|
|
1710
|
-
function makeLexString(quote, state) {
|
|
1711
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
1860
|
+
function makeLexString(quote, state, token_kind) {
|
|
1712
1861
|
function _lexString(l) {
|
|
1713
1862
|
l.ignore();
|
|
1714
1863
|
if (l.peek() === quote) {
|
|
@@ -1734,7 +1883,7 @@ var json_p3 = (function (exports) {
|
|
|
1734
1883
|
}
|
|
1735
1884
|
if (ch === quote) {
|
|
1736
1885
|
l.backup();
|
|
1737
|
-
l.emit(
|
|
1886
|
+
l.emit(token_kind);
|
|
1738
1887
|
l.next();
|
|
1739
1888
|
l.ignore();
|
|
1740
1889
|
return state;
|
|
@@ -1743,10 +1892,12 @@ var json_p3 = (function (exports) {
|
|
|
1743
1892
|
}
|
|
1744
1893
|
return _lexString;
|
|
1745
1894
|
}
|
|
1746
|
-
const lexSingleQuoteStringInsideBracketSelection = makeLexString("'", lexInsideBracketedSelection);
|
|
1747
|
-
const lexDoubleQuoteStringInsideBracketSelection = makeLexString('"', lexInsideBracketedSelection);
|
|
1748
|
-
const lexSingleQuoteStringInsideFilterExpression = makeLexString("'", lexInsideFilter);
|
|
1749
|
-
const lexDoubleQuoteStringInsideFilterExpression = makeLexString('"', lexInsideFilter);
|
|
1895
|
+
const lexSingleQuoteStringInsideBracketSelection = makeLexString("'", lexInsideBracketedSelection, TokenKind.SINGLE_QUOTE_STRING);
|
|
1896
|
+
const lexDoubleQuoteStringInsideBracketSelection = makeLexString('"', lexInsideBracketedSelection, TokenKind.DOUBLE_QUOTE_STRING);
|
|
1897
|
+
const lexSingleQuoteStringInsideFilterExpression = makeLexString("'", lexInsideFilter, TokenKind.SINGLE_QUOTE_STRING);
|
|
1898
|
+
const lexDoubleQuoteStringInsideFilterExpression = makeLexString('"', lexInsideFilter, TokenKind.DOUBLE_QUOTE_STRING);
|
|
1899
|
+
const lexSingleQuoteKeyString = makeLexString("'", lexInsideBracketedSelection, TokenKind.KEY_SINGLE_QUOTE_STRING);
|
|
1900
|
+
const lexDoubleQuoteKeyString = makeLexString('"', lexInsideBracketedSelection, TokenKind.KEY_DOUBLE_QUOTE_STRING);
|
|
1750
1901
|
|
|
1751
1902
|
/**
|
|
1752
1903
|
* Base class for all JSONPath segments and selectors.
|
|
@@ -2395,6 +2546,38 @@ var json_p3 = (function (exports) {
|
|
|
2395
2546
|
}
|
|
2396
2547
|
}
|
|
2397
2548
|
|
|
2549
|
+
class KeySelector extends JSONPathSelector {
|
|
2550
|
+
constructor(environment, token, key) {
|
|
2551
|
+
let shorthand = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
2552
|
+
super(environment, token);
|
|
2553
|
+
this.environment = environment;
|
|
2554
|
+
this.token = token;
|
|
2555
|
+
this.key = key;
|
|
2556
|
+
this.shorthand = shorthand;
|
|
2557
|
+
}
|
|
2558
|
+
resolve(nodes) {
|
|
2559
|
+
const rv = [];
|
|
2560
|
+
for (const node of nodes) {
|
|
2561
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2562
|
+
if (isObject(node.value) && hasStringKey(node.value, this.key)) {
|
|
2563
|
+
rv.push(new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root));
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
return rv;
|
|
2567
|
+
}
|
|
2568
|
+
*lazyResolve(nodes) {
|
|
2569
|
+
for (const node of nodes) {
|
|
2570
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2571
|
+
if (isObject(node.value) && hasStringKey(node.value, this.key)) {
|
|
2572
|
+
yield new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root);
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
}
|
|
2576
|
+
toString() {
|
|
2577
|
+
return this.shorthand ? `[~'${this.key.replaceAll("'", "\\'")}']` : `~'${this.key.replaceAll("'", "\\'")}'`;
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2398
2581
|
/**
|
|
2399
2582
|
* Object property name selector or array index selector.
|
|
2400
2583
|
*/
|
|
@@ -2411,10 +2594,8 @@ var json_p3 = (function (exports) {
|
|
|
2411
2594
|
for (const node of nodes) {
|
|
2412
2595
|
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2413
2596
|
if (isObject(node.value)) {
|
|
2414
|
-
let i = 0;
|
|
2415
2597
|
for (const [key, _] of this.environment.entries(node.value)) {
|
|
2416
|
-
rv.push(new JSONPathNode(key, node.location.concat(
|
|
2417
|
-
i++;
|
|
2598
|
+
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
2418
2599
|
}
|
|
2419
2600
|
}
|
|
2420
2601
|
}
|
|
@@ -2424,10 +2605,8 @@ var json_p3 = (function (exports) {
|
|
|
2424
2605
|
for (const node of nodes) {
|
|
2425
2606
|
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2426
2607
|
if (isObject(node.value)) {
|
|
2427
|
-
let i = 0;
|
|
2428
2608
|
for (const [key, _] of this.environment.entries(node.value)) {
|
|
2429
|
-
yield new JSONPathNode(key, node.location.concat(
|
|
2430
|
-
i++;
|
|
2609
|
+
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
2431
2610
|
}
|
|
2432
2611
|
}
|
|
2433
2612
|
}
|
|
@@ -2436,6 +2615,56 @@ var json_p3 = (function (exports) {
|
|
|
2436
2615
|
return this.shorthand ? "[~]" : "~";
|
|
2437
2616
|
}
|
|
2438
2617
|
}
|
|
2618
|
+
class KeysFilterSelector extends JSONPathSelector {
|
|
2619
|
+
constructor(environment, token, expression) {
|
|
2620
|
+
super(environment, token);
|
|
2621
|
+
this.environment = environment;
|
|
2622
|
+
this.token = token;
|
|
2623
|
+
this.expression = expression;
|
|
2624
|
+
}
|
|
2625
|
+
resolve(nodes) {
|
|
2626
|
+
const rv = [];
|
|
2627
|
+
for (const node of nodes) {
|
|
2628
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2629
|
+
if (isObject(node.value)) {
|
|
2630
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
2631
|
+
const filterContext = {
|
|
2632
|
+
environment: this.environment,
|
|
2633
|
+
currentValue: value,
|
|
2634
|
+
rootValue: node.root,
|
|
2635
|
+
currentKey: key
|
|
2636
|
+
};
|
|
2637
|
+
if (this.expression.evaluate(filterContext)) {
|
|
2638
|
+
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
return rv;
|
|
2644
|
+
}
|
|
2645
|
+
*lazyResolve(nodes) {
|
|
2646
|
+
for (const node of nodes) {
|
|
2647
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2648
|
+
if (isObject(node.value)) {
|
|
2649
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
2650
|
+
const filterContext = {
|
|
2651
|
+
environment: this.environment,
|
|
2652
|
+
currentValue: value,
|
|
2653
|
+
rootValue: node.root,
|
|
2654
|
+
lazy: true,
|
|
2655
|
+
currentKey: key
|
|
2656
|
+
};
|
|
2657
|
+
if (this.expression.evaluate(filterContext)) {
|
|
2658
|
+
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
toString() {
|
|
2665
|
+
return `~?${this.expression.toString()}`;
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2439
2668
|
|
|
2440
2669
|
const PRECEDENCE_LOWEST = 1;
|
|
2441
2670
|
const PRECEDENCE_LOGICAL_OR = 4;
|
|
@@ -2452,7 +2681,7 @@ var json_p3 = (function (exports) {
|
|
|
2452
2681
|
class Parser {
|
|
2453
2682
|
constructor(environment) {
|
|
2454
2683
|
this.environment = environment;
|
|
2455
|
-
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.
|
|
2684
|
+
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]]);
|
|
2456
2685
|
}
|
|
2457
2686
|
parse(stream) {
|
|
2458
2687
|
if (stream.current.kind === TokenKind.ROOT) stream.next();
|
|
@@ -2484,6 +2713,8 @@ var json_p3 = (function (exports) {
|
|
|
2484
2713
|
return new NameSelector(this.environment, stream.current, stream.current.value, true);
|
|
2485
2714
|
case TokenKind.WILD:
|
|
2486
2715
|
return new WildcardSelector(this.environment, stream.current, true);
|
|
2716
|
+
case TokenKind.KEY:
|
|
2717
|
+
return new KeySelector(this.environment, stream.current, stream.current.value, true);
|
|
2487
2718
|
case TokenKind.KEYS:
|
|
2488
2719
|
return new KeysSelector(this.environment, stream.current, true);
|
|
2489
2720
|
case TokenKind.DDOT:
|
|
@@ -2579,6 +2810,13 @@ var json_p3 = (function (exports) {
|
|
|
2579
2810
|
case TokenKind.WILD:
|
|
2580
2811
|
items.push(new WildcardSelector(this.environment, stream.current));
|
|
2581
2812
|
break;
|
|
2813
|
+
case TokenKind.KEY_SINGLE_QUOTE_STRING:
|
|
2814
|
+
case TokenKind.KEY_DOUBLE_QUOTE_STRING:
|
|
2815
|
+
items.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current, true), false));
|
|
2816
|
+
break;
|
|
2817
|
+
case TokenKind.KEYS_FILTER:
|
|
2818
|
+
items.push(this.parseFilter(stream, true));
|
|
2819
|
+
break;
|
|
2582
2820
|
case TokenKind.KEYS:
|
|
2583
2821
|
items.push(new KeysSelector(this.environment, stream.current));
|
|
2584
2822
|
break;
|
|
@@ -2599,6 +2837,7 @@ var json_p3 = (function (exports) {
|
|
|
2599
2837
|
return new BracketedSelection(this.environment, token, items);
|
|
2600
2838
|
}
|
|
2601
2839
|
parseFilter(stream) {
|
|
2840
|
+
let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
2602
2841
|
const tok = stream.next();
|
|
2603
2842
|
const expr = this.parseFilterExpression(stream);
|
|
2604
2843
|
if (expr instanceof FunctionExtension) {
|
|
@@ -2607,7 +2846,7 @@ var json_p3 = (function (exports) {
|
|
|
2607
2846
|
throw new JSONPathTypeError(`result of ${expr.name}() must be compared`, expr.token);
|
|
2608
2847
|
}
|
|
2609
2848
|
}
|
|
2610
|
-
return new FilterSelector(this.environment, tok, new LogicalExpression(tok, expr));
|
|
2849
|
+
return keys ? new KeysFilterSelector(this.environment, tok, new LogicalExpression(tok, expr)) : new FilterSelector(this.environment, tok, new LogicalExpression(tok, expr));
|
|
2611
2850
|
}
|
|
2612
2851
|
parseBoolean(stream) {
|
|
2613
2852
|
if (stream.current.kind === TokenKind.FALSE) return new BooleanLiteral(stream.current, false);
|
|
@@ -3035,6 +3274,7 @@ var json_p3 = (function (exports) {
|
|
|
3035
3274
|
JSONPathRecursionLimitError: JSONPathRecursionLimitError,
|
|
3036
3275
|
JSONPathSyntaxError: JSONPathSyntaxError,
|
|
3037
3276
|
JSONPathTypeError: JSONPathTypeError,
|
|
3277
|
+
KEY_MARK: KEY_MARK,
|
|
3038
3278
|
Nothing: Nothing,
|
|
3039
3279
|
Token: Token,
|
|
3040
3280
|
TokenKind: TokenKind,
|
|
@@ -3527,7 +3767,7 @@ var json_p3 = (function (exports) {
|
|
|
3527
3767
|
apply: apply
|
|
3528
3768
|
});
|
|
3529
3769
|
|
|
3530
|
-
const version = "1.
|
|
3770
|
+
const version = "1.3.1";
|
|
3531
3771
|
|
|
3532
3772
|
exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT;
|
|
3533
3773
|
exports.FunctionExpressionType = FunctionExpressionType;
|