json-p3 1.1.1 → 1.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.
- package/dist/json-p3.cjs.js +214 -39
- package/dist/json-p3.esm.js +214 -39
- package/dist/json-p3.iife.js +214 -39
- package/dist/json-p3.iife.min.js +1 -1
- package/dist/json-p3.iife.min.js.map +1 -1
- package/dist/path/environment.d.ts +18 -4
- package/dist/path/extra/expression.d.ts +6 -0
- package/dist/path/extra/index.d.ts +0 -0
- package/dist/path/extra/selectors.d.ts +16 -0
- package/dist/path/lex.d.ts +6 -3
- package/dist/path/parse.d.ts +2 -0
- package/dist/path/selectors.d.ts +3 -1
- package/dist/path/token.d.ts +2 -0
- 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.2.0
|
|
3
3
|
* https://github.com/jg-rp/json-p3
|
|
4
4
|
*
|
|
5
5
|
* MIT License
|
|
@@ -1183,6 +1183,8 @@ var json_p3 = (function (exports) {
|
|
|
1183
1183
|
TokenKind["GE"] = "TOKEN_GE";
|
|
1184
1184
|
TokenKind["GT"] = "TOKEN_GT";
|
|
1185
1185
|
TokenKind["INDEX"] = "TOKEN_INDEX";
|
|
1186
|
+
TokenKind["KEY"] = "TOKEN_KEY";
|
|
1187
|
+
TokenKind["KEYS"] = "TOKEN_KEYS";
|
|
1186
1188
|
TokenKind["LBRACKET"] = "TOKEN_LBRACKET";
|
|
1187
1189
|
TokenKind["LE"] = "TOKEN_LE";
|
|
1188
1190
|
TokenKind["LG"] = "TOKEN_LG";
|
|
@@ -1252,6 +1254,9 @@ var json_p3 = (function (exports) {
|
|
|
1252
1254
|
}
|
|
1253
1255
|
}
|
|
1254
1256
|
|
|
1257
|
+
/** A lexer that accepts additional, non-standard tokens. */
|
|
1258
|
+
|
|
1259
|
+
|
|
1255
1260
|
// These regular expressions are to be used with Lexer.acceptMatchRun(),
|
|
1256
1261
|
// which expects the sticky flag to be set.
|
|
1257
1262
|
const exponentPattern = /e[+-]?\d+/y;
|
|
@@ -1291,7 +1296,8 @@ var json_p3 = (function (exports) {
|
|
|
1291
1296
|
/**
|
|
1292
1297
|
* @param path - A JSONPath query.
|
|
1293
1298
|
*/
|
|
1294
|
-
constructor(path) {
|
|
1299
|
+
constructor(environment, path) {
|
|
1300
|
+
this.environment = environment;
|
|
1295
1301
|
this.path = path;
|
|
1296
1302
|
}
|
|
1297
1303
|
get pos() {
|
|
@@ -1391,8 +1397,8 @@ var json_p3 = (function (exports) {
|
|
|
1391
1397
|
* @returns A two-tuple containing a lexer for _path_ and an array to populate
|
|
1392
1398
|
* with tokens.
|
|
1393
1399
|
*/
|
|
1394
|
-
function lex(path) {
|
|
1395
|
-
const lexer = new Lexer(path);
|
|
1400
|
+
function lex(environment, path) {
|
|
1401
|
+
const lexer = new Lexer(environment, path);
|
|
1396
1402
|
return [lexer, lexer.tokens];
|
|
1397
1403
|
}
|
|
1398
1404
|
|
|
@@ -1401,8 +1407,8 @@ var json_p3 = (function (exports) {
|
|
|
1401
1407
|
* @param path - A JSONPath query.
|
|
1402
1408
|
* @returns Tokens to be parsed by the parser.
|
|
1403
1409
|
*/
|
|
1404
|
-
function tokenize(path) {
|
|
1405
|
-
const [lexer, tokens] = lex(path);
|
|
1410
|
+
function tokenize(environment, path) {
|
|
1411
|
+
const [lexer, tokens] = lex(environment, path);
|
|
1406
1412
|
lexer.run();
|
|
1407
1413
|
if (tokens.length && tokens[tokens.length - 1].kind === TokenKind.ERROR) {
|
|
1408
1414
|
throw new JSONPathSyntaxError(tokens[tokens.length - 1].value, tokens[tokens.length - 1]);
|
|
@@ -1455,6 +1461,16 @@ var json_p3 = (function (exports) {
|
|
|
1455
1461
|
* @returns -
|
|
1456
1462
|
*/
|
|
1457
1463
|
function lexDescendantSelection(l) {
|
|
1464
|
+
if (l.acceptMatchRun(namePattern)) {
|
|
1465
|
+
// Shorthand name
|
|
1466
|
+
l.emit(TokenKind.NAME);
|
|
1467
|
+
return lexSegment;
|
|
1468
|
+
}
|
|
1469
|
+
if (!l.environment.strict && l.acceptMatchRun(l.environment.keysPattern)) {
|
|
1470
|
+
// Non-standard keys selector
|
|
1471
|
+
l.emit(TokenKind.KEYS);
|
|
1472
|
+
return lexSegment;
|
|
1473
|
+
}
|
|
1458
1474
|
const ch = l.next();
|
|
1459
1475
|
switch (ch) {
|
|
1460
1476
|
case "":
|
|
@@ -1468,13 +1484,8 @@ var json_p3 = (function (exports) {
|
|
|
1468
1484
|
return lexInsideBracketedSelection;
|
|
1469
1485
|
default:
|
|
1470
1486
|
l.backup();
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
return lexSegment;
|
|
1474
|
-
} else {
|
|
1475
|
-
l.error(`unexpected descendent selection token '${ch}'`);
|
|
1476
|
-
return null;
|
|
1477
|
-
}
|
|
1487
|
+
l.error(`unexpected descendent selection token '${ch}'`);
|
|
1488
|
+
return null;
|
|
1478
1489
|
}
|
|
1479
1490
|
}
|
|
1480
1491
|
function lexDotSelector(l) {
|
|
@@ -1483,23 +1494,34 @@ var json_p3 = (function (exports) {
|
|
|
1483
1494
|
l.error("unexpected whitespace after dot");
|
|
1484
1495
|
return null;
|
|
1485
1496
|
}
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
l.emit(TokenKind.WILD);
|
|
1497
|
+
if (!l.environment.strict && l.acceptMatchRun(l.environment.keysPattern)) {
|
|
1498
|
+
l.emit(TokenKind.KEYS);
|
|
1489
1499
|
return lexSegment;
|
|
1490
1500
|
}
|
|
1491
|
-
l.backup();
|
|
1492
1501
|
if (l.acceptMatchRun(namePattern)) {
|
|
1493
1502
|
l.emit(TokenKind.NAME);
|
|
1494
1503
|
return lexSegment;
|
|
1495
|
-
} else {
|
|
1496
|
-
l.error(`unexpected shorthand selector '${ch}'`);
|
|
1497
|
-
return null;
|
|
1498
1504
|
}
|
|
1505
|
+
const ch = l.next();
|
|
1506
|
+
if (ch === "*") {
|
|
1507
|
+
l.emit(TokenKind.WILD);
|
|
1508
|
+
return lexSegment;
|
|
1509
|
+
}
|
|
1510
|
+
l.backup();
|
|
1511
|
+
l.error(`unexpected shorthand selector '${ch}'`);
|
|
1512
|
+
return null;
|
|
1499
1513
|
}
|
|
1500
1514
|
function lexInsideBracketedSelection(l) {
|
|
1501
1515
|
for (;;) {
|
|
1502
1516
|
l.ignoreWhitespace();
|
|
1517
|
+
if (l.acceptMatchRun(indexPattern)) {
|
|
1518
|
+
l.emit(TokenKind.INDEX);
|
|
1519
|
+
continue;
|
|
1520
|
+
}
|
|
1521
|
+
if (!l.environment.strict && l.acceptMatchRun(l.environment.keysPattern)) {
|
|
1522
|
+
l.emit(TokenKind.KEYS);
|
|
1523
|
+
continue;
|
|
1524
|
+
}
|
|
1503
1525
|
const ch = l.next();
|
|
1504
1526
|
switch (ch) {
|
|
1505
1527
|
case "]":
|
|
@@ -1528,10 +1550,6 @@ var json_p3 = (function (exports) {
|
|
|
1528
1550
|
return lexDoubleQuoteStringInsideBracketSelection;
|
|
1529
1551
|
default:
|
|
1530
1552
|
l.backup();
|
|
1531
|
-
if (l.acceptMatchRun(indexPattern)) {
|
|
1532
|
-
l.emit(TokenKind.INDEX);
|
|
1533
|
-
continue;
|
|
1534
|
-
}
|
|
1535
1553
|
l.error(`unexpected token '${ch}' in bracketed selection`);
|
|
1536
1554
|
return null;
|
|
1537
1555
|
}
|
|
@@ -1545,6 +1563,8 @@ var json_p3 = (function (exports) {
|
|
|
1545
1563
|
const ch = l.next();
|
|
1546
1564
|
switch (ch) {
|
|
1547
1565
|
case "":
|
|
1566
|
+
l.error("unclosed bracketed selection");
|
|
1567
|
+
return null;
|
|
1548
1568
|
case "]":
|
|
1549
1569
|
l.filterLevel -= 1;
|
|
1550
1570
|
if (l.parenStack.length === 1) {
|
|
@@ -1586,6 +1606,9 @@ var json_p3 = (function (exports) {
|
|
|
1586
1606
|
case "@":
|
|
1587
1607
|
l.emit(TokenKind.CURRENT);
|
|
1588
1608
|
return lexSegment;
|
|
1609
|
+
case "#":
|
|
1610
|
+
l.emit(TokenKind.KEY);
|
|
1611
|
+
return lexSegment;
|
|
1589
1612
|
case ".":
|
|
1590
1613
|
l.backup();
|
|
1591
1614
|
return lexSegment;
|
|
@@ -1963,12 +1986,22 @@ var json_p3 = (function (exports) {
|
|
|
1963
1986
|
}
|
|
1964
1987
|
resolve(nodes) {
|
|
1965
1988
|
const rv = [];
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1989
|
+
if (this.environment.nondeterministic) {
|
|
1990
|
+
for (const root of nodes) {
|
|
1991
|
+
for (const node of this.nondeterministicVisitor(root)) {
|
|
1992
|
+
rv.push(node);
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
} else {
|
|
1996
|
+
for (const node of nodes) {
|
|
1997
|
+
rv.push(node);
|
|
1998
|
+
for (const _node of this.visitor(node)) {
|
|
1999
|
+
rv.push(_node);
|
|
2000
|
+
}
|
|
1970
2001
|
}
|
|
1971
2002
|
}
|
|
2003
|
+
|
|
2004
|
+
// console.log(JSON.stringify(rv.map((n: any) => n.value)));
|
|
1972
2005
|
return this.selector.resolve(rv);
|
|
1973
2006
|
}
|
|
1974
2007
|
*lazyResolve(nodes) {
|
|
@@ -2021,7 +2054,7 @@ var json_p3 = (function (exports) {
|
|
|
2021
2054
|
toString() {
|
|
2022
2055
|
return `..${this.selector.toString()}`;
|
|
2023
2056
|
}
|
|
2024
|
-
|
|
2057
|
+
visitor(node) {
|
|
2025
2058
|
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
2026
2059
|
if (depth >= this.environment.maxRecursionDepth) {
|
|
2027
2060
|
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
@@ -2032,7 +2065,7 @@ var json_p3 = (function (exports) {
|
|
|
2032
2065
|
for (let i = 0; i < node.value.length; i++) {
|
|
2033
2066
|
const _node = new JSONPathNode(node.value[i], node.location.concat(i), node.root);
|
|
2034
2067
|
rv.push(_node);
|
|
2035
|
-
for (const __node of this.
|
|
2068
|
+
for (const __node of this.visitor(_node, depth + 1)) {
|
|
2036
2069
|
rv.push(__node);
|
|
2037
2070
|
}
|
|
2038
2071
|
}
|
|
@@ -2040,13 +2073,52 @@ var json_p3 = (function (exports) {
|
|
|
2040
2073
|
for (const [key, value] of this.environment.entries(node.value)) {
|
|
2041
2074
|
const _node = new JSONPathNode(value, node.location.concat(key), node.root);
|
|
2042
2075
|
rv.push(_node);
|
|
2043
|
-
for (const __node of this.
|
|
2076
|
+
for (const __node of this.visitor(_node, depth + 1)) {
|
|
2044
2077
|
rv.push(__node);
|
|
2045
2078
|
}
|
|
2046
2079
|
}
|
|
2047
2080
|
}
|
|
2048
2081
|
return rv;
|
|
2049
2082
|
}
|
|
2083
|
+
nondeterministicVisitor(root) {
|
|
2084
|
+
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
2085
|
+
const rv = [root];
|
|
2086
|
+
let queue = this.nondeterministicChildren(root).map(node => [node, depth]);
|
|
2087
|
+
while (queue.length) {
|
|
2088
|
+
const [node, _depth] = queue.shift();
|
|
2089
|
+
rv.push(node);
|
|
2090
|
+
if (_depth >= this.environment.maxRecursionDepth) {
|
|
2091
|
+
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
// Visit child nodes now or queue them for later?
|
|
2095
|
+
const visitChildren = Math.random() < 0.5;
|
|
2096
|
+
for (const child of this.nondeterministicChildren(node)) {
|
|
2097
|
+
if (visitChildren) {
|
|
2098
|
+
rv.push(child);
|
|
2099
|
+
const grandchildren = this.nondeterministicChildren(child).map(n => [n, _depth + 2]);
|
|
2100
|
+
queue = interleave(queue, grandchildren);
|
|
2101
|
+
} else {
|
|
2102
|
+
queue.push([child, _depth + 1]);
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
return rv;
|
|
2107
|
+
}
|
|
2108
|
+
nondeterministicChildren(node) {
|
|
2109
|
+
const _rv = [];
|
|
2110
|
+
if (node.value instanceof String) return _rv;
|
|
2111
|
+
if (isArray(node.value)) {
|
|
2112
|
+
for (let i = 0; i < node.value.length; i++) {
|
|
2113
|
+
_rv.push(new JSONPathNode(node.value[i], node.location.concat(i), node.root));
|
|
2114
|
+
}
|
|
2115
|
+
} else if (isObject(node.value)) {
|
|
2116
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
2117
|
+
_rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
return _rv;
|
|
2121
|
+
}
|
|
2050
2122
|
}
|
|
2051
2123
|
class FilterSelector extends JSONPathSelector {
|
|
2052
2124
|
constructor(environment, token, expression) {
|
|
@@ -2067,7 +2139,8 @@ var json_p3 = (function (exports) {
|
|
|
2067
2139
|
const filterContext = {
|
|
2068
2140
|
environment: this.environment,
|
|
2069
2141
|
currentValue: value,
|
|
2070
|
-
rootValue: node.root
|
|
2142
|
+
rootValue: node.root,
|
|
2143
|
+
currentKey: i
|
|
2071
2144
|
};
|
|
2072
2145
|
if (this.expression.evaluate(filterContext)) {
|
|
2073
2146
|
rv.push(new JSONPathNode(value, node.location.concat(i), node.root));
|
|
@@ -2078,7 +2151,8 @@ var json_p3 = (function (exports) {
|
|
|
2078
2151
|
const filterContext = {
|
|
2079
2152
|
environment: this.environment,
|
|
2080
2153
|
currentValue: value,
|
|
2081
|
-
rootValue: node.root
|
|
2154
|
+
rootValue: node.root,
|
|
2155
|
+
currentKey: key
|
|
2082
2156
|
};
|
|
2083
2157
|
if (this.expression.evaluate(filterContext)) {
|
|
2084
2158
|
rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
@@ -2100,7 +2174,8 @@ var json_p3 = (function (exports) {
|
|
|
2100
2174
|
environment: this.environment,
|
|
2101
2175
|
currentValue: value,
|
|
2102
2176
|
rootValue: node.root,
|
|
2103
|
-
lazy: true
|
|
2177
|
+
lazy: true,
|
|
2178
|
+
currentKey: i
|
|
2104
2179
|
};
|
|
2105
2180
|
if (this.expression.evaluate(filterContext)) {
|
|
2106
2181
|
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
@@ -2112,7 +2187,8 @@ var json_p3 = (function (exports) {
|
|
|
2112
2187
|
environment: this.environment,
|
|
2113
2188
|
currentValue: value,
|
|
2114
2189
|
rootValue: node.root,
|
|
2115
|
-
lazy: true
|
|
2190
|
+
lazy: true,
|
|
2191
|
+
currentKey: key
|
|
2116
2192
|
};
|
|
2117
2193
|
if (this.expression.evaluate(filterContext)) {
|
|
2118
2194
|
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
@@ -2155,6 +2231,41 @@ var json_p3 = (function (exports) {
|
|
|
2155
2231
|
}
|
|
2156
2232
|
}
|
|
2157
2233
|
|
|
2234
|
+
/**
|
|
2235
|
+
* Randomly interleave elements from two arrays while maintaining relative
|
|
2236
|
+
* order of each input array.
|
|
2237
|
+
*
|
|
2238
|
+
* If _arrayA_ is empty, _arrayB_ is returned, and vice versa.
|
|
2239
|
+
*/
|
|
2240
|
+
function interleave(arrayA, arrayB) {
|
|
2241
|
+
if (arrayA.length === 0) {
|
|
2242
|
+
return arrayB;
|
|
2243
|
+
}
|
|
2244
|
+
if (arrayB.length === 0) {
|
|
2245
|
+
return arrayA;
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
// An array of iterators
|
|
2249
|
+
const iterators = [];
|
|
2250
|
+
const itA = arrayA[Symbol.iterator]();
|
|
2251
|
+
const itB = arrayB[Symbol.iterator]();
|
|
2252
|
+
for (let i = 0; i < arrayA.length; i++) {
|
|
2253
|
+
iterators.push(itA);
|
|
2254
|
+
}
|
|
2255
|
+
for (let i = 0; i < arrayB.length; i++) {
|
|
2256
|
+
iterators.push(itB);
|
|
2257
|
+
}
|
|
2258
|
+
shuffle(iterators);
|
|
2259
|
+
return iterators.map(it => it.next().value);
|
|
2260
|
+
}
|
|
2261
|
+
function shuffle(entries) {
|
|
2262
|
+
for (let i = entries.length - 1; i > 0; i--) {
|
|
2263
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
2264
|
+
[entries[i], entries[j]] = [entries[j], entries[i]];
|
|
2265
|
+
}
|
|
2266
|
+
return entries;
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2158
2269
|
var selectors = /*#__PURE__*/Object.freeze({
|
|
2159
2270
|
__proto__: null,
|
|
2160
2271
|
BracketedSelection: BracketedSelection,
|
|
@@ -2238,6 +2349,57 @@ var json_p3 = (function (exports) {
|
|
|
2238
2349
|
}
|
|
2239
2350
|
}
|
|
2240
2351
|
|
|
2352
|
+
class CurrentKey extends FilterExpression {
|
|
2353
|
+
evaluate(context) {
|
|
2354
|
+
return context.currentKey ?? Nothing;
|
|
2355
|
+
}
|
|
2356
|
+
toString() {
|
|
2357
|
+
return "#";
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
|
|
2361
|
+
/**
|
|
2362
|
+
* Object property name selector or array index selector.
|
|
2363
|
+
*/
|
|
2364
|
+
class KeysSelector extends JSONPathSelector {
|
|
2365
|
+
constructor(environment, token) {
|
|
2366
|
+
let shorthand = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
2367
|
+
super(environment, token);
|
|
2368
|
+
this.environment = environment;
|
|
2369
|
+
this.token = token;
|
|
2370
|
+
this.shorthand = shorthand;
|
|
2371
|
+
}
|
|
2372
|
+
resolve(nodes) {
|
|
2373
|
+
const rv = [];
|
|
2374
|
+
for (const node of nodes) {
|
|
2375
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2376
|
+
if (isObject(node.value)) {
|
|
2377
|
+
let i = 0;
|
|
2378
|
+
for (const [key, _] of this.environment.entries(node.value)) {
|
|
2379
|
+
rv.push(new JSONPathNode(key, node.location.concat("[~]", `[${i}]`), node.root));
|
|
2380
|
+
i++;
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
return rv;
|
|
2385
|
+
}
|
|
2386
|
+
*lazyResolve(nodes) {
|
|
2387
|
+
for (const node of nodes) {
|
|
2388
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2389
|
+
if (isObject(node.value)) {
|
|
2390
|
+
let i = 0;
|
|
2391
|
+
for (const [key, _] of this.environment.entries(node.value)) {
|
|
2392
|
+
yield new JSONPathNode(key, node.location.concat("[~]", `[${i}]`), node.root);
|
|
2393
|
+
i++;
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
toString() {
|
|
2399
|
+
return this.shorthand ? "[~]" : "~";
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2241
2403
|
const PRECEDENCE_LOWEST = 1;
|
|
2242
2404
|
const PRECEDENCE_LOGICAL_OR = 4;
|
|
2243
2405
|
const PRECEDENCE_LOGICAL_AND = 5;
|
|
@@ -2253,7 +2415,7 @@ var json_p3 = (function (exports) {
|
|
|
2253
2415
|
class Parser {
|
|
2254
2416
|
constructor(environment) {
|
|
2255
2417
|
this.environment = environment;
|
|
2256
|
-
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]]);
|
|
2418
|
+
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.KEY, this.parseCurrentKey], [TokenKind.KEY, this.parseCurrentKey]]);
|
|
2257
2419
|
}
|
|
2258
2420
|
parse(stream) {
|
|
2259
2421
|
if (stream.current.kind === TokenKind.ROOT) stream.next();
|
|
@@ -2285,6 +2447,8 @@ var json_p3 = (function (exports) {
|
|
|
2285
2447
|
return new NameSelector(this.environment, stream.current, stream.current.value, true);
|
|
2286
2448
|
case TokenKind.WILD:
|
|
2287
2449
|
return new WildcardSelector(this.environment, stream.current, true);
|
|
2450
|
+
case TokenKind.KEYS:
|
|
2451
|
+
return new KeysSelector(this.environment, stream.current, true);
|
|
2288
2452
|
case TokenKind.DDOT:
|
|
2289
2453
|
{
|
|
2290
2454
|
const segmentToken = stream.current;
|
|
@@ -2378,6 +2542,9 @@ var json_p3 = (function (exports) {
|
|
|
2378
2542
|
case TokenKind.WILD:
|
|
2379
2543
|
items.push(new WildcardSelector(this.environment, stream.current));
|
|
2380
2544
|
break;
|
|
2545
|
+
case TokenKind.KEYS:
|
|
2546
|
+
items.push(new KeysSelector(this.environment, stream.current));
|
|
2547
|
+
break;
|
|
2381
2548
|
case TokenKind.EOF:
|
|
2382
2549
|
throw new JSONPathSyntaxError("unexpected end of query", stream.current);
|
|
2383
2550
|
default:
|
|
@@ -2458,6 +2625,9 @@ var json_p3 = (function (exports) {
|
|
|
2458
2625
|
const tok = stream.next();
|
|
2459
2626
|
return new RelativeQuery(tok, new JSONPath(this.environment, this.parsePath(stream, true)));
|
|
2460
2627
|
}
|
|
2628
|
+
parseCurrentKey(stream) {
|
|
2629
|
+
return new CurrentKey(stream.current);
|
|
2630
|
+
}
|
|
2461
2631
|
parseFunction(stream) {
|
|
2462
2632
|
const args = [];
|
|
2463
2633
|
const tok = stream.next();
|
|
@@ -2574,6 +2744,10 @@ var json_p3 = (function (exports) {
|
|
|
2574
2744
|
* If `true`, enable nondeterministic ordering when iterating JSON object data.
|
|
2575
2745
|
*/
|
|
2576
2746
|
|
|
2747
|
+
/**
|
|
2748
|
+
* The pattern to use for the non-standard _keys selector_.
|
|
2749
|
+
*/
|
|
2750
|
+
|
|
2577
2751
|
/**
|
|
2578
2752
|
* A map of function names to objects implementing the {@link FilterFunction}
|
|
2579
2753
|
* interface. You are free to set or delete custom filter functions directly.
|
|
@@ -2589,6 +2763,7 @@ var json_p3 = (function (exports) {
|
|
|
2589
2763
|
this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) - 1;
|
|
2590
2764
|
this.maxRecursionDepth = options.maxRecursionDepth ?? 50;
|
|
2591
2765
|
this.nondeterministic = options.nondeterministic ?? false;
|
|
2766
|
+
this.keysPattern = options.keysPattern ?? /~/y;
|
|
2592
2767
|
this.parser = new Parser(this);
|
|
2593
2768
|
this.setupFilterFunctions();
|
|
2594
2769
|
}
|
|
@@ -2598,7 +2773,7 @@ var json_p3 = (function (exports) {
|
|
|
2598
2773
|
* @returns A new {@link JSONPath} object, bound to this environment.
|
|
2599
2774
|
*/
|
|
2600
2775
|
compile(path) {
|
|
2601
|
-
return new JSONPath(this, this.parser.parse(new TokenStream(tokenize(path))));
|
|
2776
|
+
return new JSONPath(this, this.parser.parse(new TokenStream(tokenize(this, path))));
|
|
2602
2777
|
}
|
|
2603
2778
|
|
|
2604
2779
|
/**
|
|
@@ -2680,7 +2855,7 @@ var json_p3 = (function (exports) {
|
|
|
2680
2855
|
for (const [typ, arg, idx] of func.argTypes.map((t, i) => [t, args[i], i])) {
|
|
2681
2856
|
switch (typ) {
|
|
2682
2857
|
case FunctionExpressionType.ValueType:
|
|
2683
|
-
if (!(arg instanceof FilterExpressionLiteral || arg instanceof JSONPathQuery && arg.path.singularQuery() || arg instanceof FunctionExtension && this.functionRegister.get(arg.name)?.returnType === FunctionExpressionType.ValueType)) {
|
|
2858
|
+
if (!(arg instanceof FilterExpressionLiteral || arg instanceof CurrentKey || arg instanceof JSONPathQuery && arg.path.singularQuery() || arg instanceof FunctionExtension && this.functionRegister.get(arg.name)?.returnType === FunctionExpressionType.ValueType)) {
|
|
2684
2859
|
throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of ValueType`, arg.token);
|
|
2685
2860
|
}
|
|
2686
2861
|
break;
|
|
@@ -3308,7 +3483,7 @@ var json_p3 = (function (exports) {
|
|
|
3308
3483
|
apply: apply
|
|
3309
3484
|
});
|
|
3310
3485
|
|
|
3311
|
-
const version = "1.
|
|
3486
|
+
const version = "1.2.0";
|
|
3312
3487
|
|
|
3313
3488
|
exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT;
|
|
3314
3489
|
exports.FunctionExpressionType = FunctionExpressionType;
|