json-p3 1.1.1 → 1.2.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 +263 -44
- package/dist/json-p3.esm.js +263 -44
- package/dist/json-p3.iife.js +263 -44
- 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 +4 -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.1
|
|
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;
|
|
@@ -1764,7 +1787,7 @@ var json_p3 = (function (exports) {
|
|
|
1764
1787
|
resolve(nodes) {
|
|
1765
1788
|
const rv = [];
|
|
1766
1789
|
for (const node of nodes) {
|
|
1767
|
-
if (hasStringKey(node.value, this.name)) {
|
|
1790
|
+
if (!isArray(node.value) && hasStringKey(node.value, this.name)) {
|
|
1768
1791
|
rv.push(new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root));
|
|
1769
1792
|
}
|
|
1770
1793
|
}
|
|
@@ -1772,7 +1795,7 @@ var json_p3 = (function (exports) {
|
|
|
1772
1795
|
}
|
|
1773
1796
|
*lazyResolve(nodes) {
|
|
1774
1797
|
for (const node of nodes) {
|
|
1775
|
-
if (hasStringKey(node.value, this.name)) {
|
|
1798
|
+
if (!isArray(node.value) && hasStringKey(node.value, this.name)) {
|
|
1776
1799
|
yield new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root);
|
|
1777
1800
|
}
|
|
1778
1801
|
}
|
|
@@ -1848,7 +1871,7 @@ var json_p3 = (function (exports) {
|
|
|
1848
1871
|
*lazyResolve(nodes) {
|
|
1849
1872
|
for (const node of nodes) {
|
|
1850
1873
|
if (!isArray(node.value)) continue;
|
|
1851
|
-
for (const [i, value] of this.
|
|
1874
|
+
for (const [i, value] of this.lazySlice(node.value, this.start, this.stop, this.step)) {
|
|
1852
1875
|
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
1853
1876
|
}
|
|
1854
1877
|
}
|
|
@@ -1911,6 +1934,45 @@ var json_p3 = (function (exports) {
|
|
|
1911
1934
|
}
|
|
1912
1935
|
return slicedArray;
|
|
1913
1936
|
}
|
|
1937
|
+
|
|
1938
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
1939
|
+
*lazySlice(arr, start, stop, step) {
|
|
1940
|
+
if (!arr.length) return;
|
|
1941
|
+
|
|
1942
|
+
// Handle negative and undefined start values
|
|
1943
|
+
if (start === undefined || start === null) {
|
|
1944
|
+
start = step && step < 0 ? arr.length - 1 : 0;
|
|
1945
|
+
} else if (start < 0) {
|
|
1946
|
+
start = Math.max(arr.length + start, 0);
|
|
1947
|
+
} else {
|
|
1948
|
+
start = Math.min(start, arr.length - 1);
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
// Handle negative and undefined stop values
|
|
1952
|
+
if (stop === undefined || stop === null) {
|
|
1953
|
+
stop = step && step < 0 ? -1 : arr.length;
|
|
1954
|
+
} else if (stop < 0) {
|
|
1955
|
+
stop = Math.max(arr.length + stop, -1);
|
|
1956
|
+
} else {
|
|
1957
|
+
stop = Math.min(stop, arr.length);
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1960
|
+
// Perform the slice
|
|
1961
|
+
if (step === undefined) {
|
|
1962
|
+
// Default to a step of 1
|
|
1963
|
+
for (let i = start; i < stop; i += 1) {
|
|
1964
|
+
yield [i, arr[i]];
|
|
1965
|
+
}
|
|
1966
|
+
} else if (step > 0) {
|
|
1967
|
+
for (let i = start; i < stop; i += step) {
|
|
1968
|
+
yield [i, arr[i]];
|
|
1969
|
+
}
|
|
1970
|
+
} else if (step < 0) {
|
|
1971
|
+
for (let i = start; i > stop; i += step) {
|
|
1972
|
+
yield [i, arr[i]];
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1914
1976
|
}
|
|
1915
1977
|
class WildcardSelector extends JSONPathSelector {
|
|
1916
1978
|
constructor(environment, token) {
|
|
@@ -1963,10 +2025,18 @@ var json_p3 = (function (exports) {
|
|
|
1963
2025
|
}
|
|
1964
2026
|
resolve(nodes) {
|
|
1965
2027
|
const rv = [];
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
2028
|
+
if (this.environment.nondeterministic) {
|
|
2029
|
+
for (const root of nodes) {
|
|
2030
|
+
for (const node of this.nondeterministicVisitor(root)) {
|
|
2031
|
+
rv.push(node);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
} else {
|
|
2035
|
+
for (const node of nodes) {
|
|
2036
|
+
rv.push(node);
|
|
2037
|
+
for (const _node of this.visitor(node)) {
|
|
2038
|
+
rv.push(_node);
|
|
2039
|
+
}
|
|
1970
2040
|
}
|
|
1971
2041
|
}
|
|
1972
2042
|
return this.selector.resolve(rv);
|
|
@@ -2021,7 +2091,7 @@ var json_p3 = (function (exports) {
|
|
|
2021
2091
|
toString() {
|
|
2022
2092
|
return `..${this.selector.toString()}`;
|
|
2023
2093
|
}
|
|
2024
|
-
|
|
2094
|
+
visitor(node) {
|
|
2025
2095
|
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
2026
2096
|
if (depth >= this.environment.maxRecursionDepth) {
|
|
2027
2097
|
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
@@ -2032,7 +2102,7 @@ var json_p3 = (function (exports) {
|
|
|
2032
2102
|
for (let i = 0; i < node.value.length; i++) {
|
|
2033
2103
|
const _node = new JSONPathNode(node.value[i], node.location.concat(i), node.root);
|
|
2034
2104
|
rv.push(_node);
|
|
2035
|
-
for (const __node of this.
|
|
2105
|
+
for (const __node of this.visitor(_node, depth + 1)) {
|
|
2036
2106
|
rv.push(__node);
|
|
2037
2107
|
}
|
|
2038
2108
|
}
|
|
@@ -2040,13 +2110,52 @@ var json_p3 = (function (exports) {
|
|
|
2040
2110
|
for (const [key, value] of this.environment.entries(node.value)) {
|
|
2041
2111
|
const _node = new JSONPathNode(value, node.location.concat(key), node.root);
|
|
2042
2112
|
rv.push(_node);
|
|
2043
|
-
for (const __node of this.
|
|
2113
|
+
for (const __node of this.visitor(_node, depth + 1)) {
|
|
2044
2114
|
rv.push(__node);
|
|
2045
2115
|
}
|
|
2046
2116
|
}
|
|
2047
2117
|
}
|
|
2048
2118
|
return rv;
|
|
2049
2119
|
}
|
|
2120
|
+
nondeterministicVisitor(root) {
|
|
2121
|
+
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
2122
|
+
const rv = [root];
|
|
2123
|
+
let queue = this.nondeterministicChildren(root).map(node => [node, depth]);
|
|
2124
|
+
while (queue.length) {
|
|
2125
|
+
const [node, _depth] = queue.shift();
|
|
2126
|
+
rv.push(node);
|
|
2127
|
+
if (_depth >= this.environment.maxRecursionDepth) {
|
|
2128
|
+
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
// Visit child nodes now or queue them for later?
|
|
2132
|
+
const visitChildren = Math.random() < 0.5;
|
|
2133
|
+
for (const child of this.nondeterministicChildren(node)) {
|
|
2134
|
+
if (visitChildren) {
|
|
2135
|
+
rv.push(child);
|
|
2136
|
+
const grandchildren = this.nondeterministicChildren(child).map(n => [n, _depth + 2]);
|
|
2137
|
+
queue = interleave(queue, grandchildren);
|
|
2138
|
+
} else {
|
|
2139
|
+
queue.push([child, _depth + 1]);
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
return rv;
|
|
2144
|
+
}
|
|
2145
|
+
nondeterministicChildren(node) {
|
|
2146
|
+
const _rv = [];
|
|
2147
|
+
if (node.value instanceof String) return _rv;
|
|
2148
|
+
if (isArray(node.value)) {
|
|
2149
|
+
for (let i = 0; i < node.value.length; i++) {
|
|
2150
|
+
_rv.push(new JSONPathNode(node.value[i], node.location.concat(i), node.root));
|
|
2151
|
+
}
|
|
2152
|
+
} else if (isObject(node.value)) {
|
|
2153
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
2154
|
+
_rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
return _rv;
|
|
2158
|
+
}
|
|
2050
2159
|
}
|
|
2051
2160
|
class FilterSelector extends JSONPathSelector {
|
|
2052
2161
|
constructor(environment, token, expression) {
|
|
@@ -2067,7 +2176,8 @@ var json_p3 = (function (exports) {
|
|
|
2067
2176
|
const filterContext = {
|
|
2068
2177
|
environment: this.environment,
|
|
2069
2178
|
currentValue: value,
|
|
2070
|
-
rootValue: node.root
|
|
2179
|
+
rootValue: node.root,
|
|
2180
|
+
currentKey: i
|
|
2071
2181
|
};
|
|
2072
2182
|
if (this.expression.evaluate(filterContext)) {
|
|
2073
2183
|
rv.push(new JSONPathNode(value, node.location.concat(i), node.root));
|
|
@@ -2078,7 +2188,8 @@ var json_p3 = (function (exports) {
|
|
|
2078
2188
|
const filterContext = {
|
|
2079
2189
|
environment: this.environment,
|
|
2080
2190
|
currentValue: value,
|
|
2081
|
-
rootValue: node.root
|
|
2191
|
+
rootValue: node.root,
|
|
2192
|
+
currentKey: key
|
|
2082
2193
|
};
|
|
2083
2194
|
if (this.expression.evaluate(filterContext)) {
|
|
2084
2195
|
rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
@@ -2100,7 +2211,8 @@ var json_p3 = (function (exports) {
|
|
|
2100
2211
|
environment: this.environment,
|
|
2101
2212
|
currentValue: value,
|
|
2102
2213
|
rootValue: node.root,
|
|
2103
|
-
lazy: true
|
|
2214
|
+
lazy: true,
|
|
2215
|
+
currentKey: i
|
|
2104
2216
|
};
|
|
2105
2217
|
if (this.expression.evaluate(filterContext)) {
|
|
2106
2218
|
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
@@ -2112,7 +2224,8 @@ var json_p3 = (function (exports) {
|
|
|
2112
2224
|
environment: this.environment,
|
|
2113
2225
|
currentValue: value,
|
|
2114
2226
|
rootValue: node.root,
|
|
2115
|
-
lazy: true
|
|
2227
|
+
lazy: true,
|
|
2228
|
+
currentKey: key
|
|
2116
2229
|
};
|
|
2117
2230
|
if (this.expression.evaluate(filterContext)) {
|
|
2118
2231
|
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
@@ -2155,6 +2268,41 @@ var json_p3 = (function (exports) {
|
|
|
2155
2268
|
}
|
|
2156
2269
|
}
|
|
2157
2270
|
|
|
2271
|
+
/**
|
|
2272
|
+
* Randomly interleave elements from two arrays while maintaining relative
|
|
2273
|
+
* order of each input array.
|
|
2274
|
+
*
|
|
2275
|
+
* If _arrayA_ is empty, _arrayB_ is returned, and vice versa.
|
|
2276
|
+
*/
|
|
2277
|
+
function interleave(arrayA, arrayB) {
|
|
2278
|
+
if (arrayA.length === 0) {
|
|
2279
|
+
return arrayB;
|
|
2280
|
+
}
|
|
2281
|
+
if (arrayB.length === 0) {
|
|
2282
|
+
return arrayA;
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
// An array of iterators
|
|
2286
|
+
const iterators = [];
|
|
2287
|
+
const itA = arrayA[Symbol.iterator]();
|
|
2288
|
+
const itB = arrayB[Symbol.iterator]();
|
|
2289
|
+
for (let i = 0; i < arrayA.length; i++) {
|
|
2290
|
+
iterators.push(itA);
|
|
2291
|
+
}
|
|
2292
|
+
for (let i = 0; i < arrayB.length; i++) {
|
|
2293
|
+
iterators.push(itB);
|
|
2294
|
+
}
|
|
2295
|
+
shuffle(iterators);
|
|
2296
|
+
return iterators.map(it => it.next().value);
|
|
2297
|
+
}
|
|
2298
|
+
function shuffle(entries) {
|
|
2299
|
+
for (let i = entries.length - 1; i > 0; i--) {
|
|
2300
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
2301
|
+
[entries[i], entries[j]] = [entries[j], entries[i]];
|
|
2302
|
+
}
|
|
2303
|
+
return entries;
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2158
2306
|
var selectors = /*#__PURE__*/Object.freeze({
|
|
2159
2307
|
__proto__: null,
|
|
2160
2308
|
BracketedSelection: BracketedSelection,
|
|
@@ -2238,6 +2386,57 @@ var json_p3 = (function (exports) {
|
|
|
2238
2386
|
}
|
|
2239
2387
|
}
|
|
2240
2388
|
|
|
2389
|
+
class CurrentKey extends FilterExpression {
|
|
2390
|
+
evaluate(context) {
|
|
2391
|
+
return context.currentKey ?? Nothing;
|
|
2392
|
+
}
|
|
2393
|
+
toString() {
|
|
2394
|
+
return "#";
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
/**
|
|
2399
|
+
* Object property name selector or array index selector.
|
|
2400
|
+
*/
|
|
2401
|
+
class KeysSelector extends JSONPathSelector {
|
|
2402
|
+
constructor(environment, token) {
|
|
2403
|
+
let shorthand = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
2404
|
+
super(environment, token);
|
|
2405
|
+
this.environment = environment;
|
|
2406
|
+
this.token = token;
|
|
2407
|
+
this.shorthand = shorthand;
|
|
2408
|
+
}
|
|
2409
|
+
resolve(nodes) {
|
|
2410
|
+
const rv = [];
|
|
2411
|
+
for (const node of nodes) {
|
|
2412
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2413
|
+
if (isObject(node.value)) {
|
|
2414
|
+
let i = 0;
|
|
2415
|
+
for (const [key, _] of this.environment.entries(node.value)) {
|
|
2416
|
+
rv.push(new JSONPathNode(key, node.location.concat("[~]", `[${i}]`), node.root));
|
|
2417
|
+
i++;
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
return rv;
|
|
2422
|
+
}
|
|
2423
|
+
*lazyResolve(nodes) {
|
|
2424
|
+
for (const node of nodes) {
|
|
2425
|
+
if (node.value instanceof String || isArray(node.value)) continue;
|
|
2426
|
+
if (isObject(node.value)) {
|
|
2427
|
+
let i = 0;
|
|
2428
|
+
for (const [key, _] of this.environment.entries(node.value)) {
|
|
2429
|
+
yield new JSONPathNode(key, node.location.concat("[~]", `[${i}]`), node.root);
|
|
2430
|
+
i++;
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
toString() {
|
|
2436
|
+
return this.shorthand ? "[~]" : "~";
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2241
2440
|
const PRECEDENCE_LOWEST = 1;
|
|
2242
2441
|
const PRECEDENCE_LOGICAL_OR = 4;
|
|
2243
2442
|
const PRECEDENCE_LOGICAL_AND = 5;
|
|
@@ -2253,7 +2452,7 @@ var json_p3 = (function (exports) {
|
|
|
2253
2452
|
class Parser {
|
|
2254
2453
|
constructor(environment) {
|
|
2255
2454
|
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]]);
|
|
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.KEY, this.parseCurrentKey], [TokenKind.KEY, this.parseCurrentKey]]);
|
|
2257
2456
|
}
|
|
2258
2457
|
parse(stream) {
|
|
2259
2458
|
if (stream.current.kind === TokenKind.ROOT) stream.next();
|
|
@@ -2285,6 +2484,8 @@ var json_p3 = (function (exports) {
|
|
|
2285
2484
|
return new NameSelector(this.environment, stream.current, stream.current.value, true);
|
|
2286
2485
|
case TokenKind.WILD:
|
|
2287
2486
|
return new WildcardSelector(this.environment, stream.current, true);
|
|
2487
|
+
case TokenKind.KEYS:
|
|
2488
|
+
return new KeysSelector(this.environment, stream.current, true);
|
|
2288
2489
|
case TokenKind.DDOT:
|
|
2289
2490
|
{
|
|
2290
2491
|
const segmentToken = stream.current;
|
|
@@ -2378,6 +2579,9 @@ var json_p3 = (function (exports) {
|
|
|
2378
2579
|
case TokenKind.WILD:
|
|
2379
2580
|
items.push(new WildcardSelector(this.environment, stream.current));
|
|
2380
2581
|
break;
|
|
2582
|
+
case TokenKind.KEYS:
|
|
2583
|
+
items.push(new KeysSelector(this.environment, stream.current));
|
|
2584
|
+
break;
|
|
2381
2585
|
case TokenKind.EOF:
|
|
2382
2586
|
throw new JSONPathSyntaxError("unexpected end of query", stream.current);
|
|
2383
2587
|
default:
|
|
@@ -2438,13 +2642,20 @@ var json_p3 = (function (exports) {
|
|
|
2438
2642
|
return new InfixExpression(tok, left, operator, right);
|
|
2439
2643
|
}
|
|
2440
2644
|
parseGroupedExpression(stream) {
|
|
2441
|
-
stream.
|
|
2645
|
+
if (stream.peek.kind === TokenKind.RPAREN) {
|
|
2646
|
+
throw new JSONPathSyntaxError(`empty paren expression`, stream.current);
|
|
2647
|
+
}
|
|
2648
|
+
stream.next(); // eat open paren
|
|
2649
|
+
|
|
2442
2650
|
let expr = this.parseFilterExpression(stream);
|
|
2443
2651
|
stream.next();
|
|
2444
2652
|
while (stream.current.kind !== TokenKind.RPAREN) {
|
|
2445
2653
|
if (stream.current.kind === TokenKind.EOF) {
|
|
2446
2654
|
throw new JSONPathSyntaxError("unbalanced parentheses", stream.current);
|
|
2447
2655
|
}
|
|
2656
|
+
if (!BINARY_OPERATORS.has(stream.current.kind)) {
|
|
2657
|
+
throw new JSONPathSyntaxError(`expected an expression, found '${stream.current.value}'`, stream.current);
|
|
2658
|
+
}
|
|
2448
2659
|
expr = this.parseInfixExpression(stream, expr);
|
|
2449
2660
|
}
|
|
2450
2661
|
stream.expect(TokenKind.RPAREN);
|
|
@@ -2458,6 +2669,9 @@ var json_p3 = (function (exports) {
|
|
|
2458
2669
|
const tok = stream.next();
|
|
2459
2670
|
return new RelativeQuery(tok, new JSONPath(this.environment, this.parsePath(stream, true)));
|
|
2460
2671
|
}
|
|
2672
|
+
parseCurrentKey(stream) {
|
|
2673
|
+
return new CurrentKey(stream.current);
|
|
2674
|
+
}
|
|
2461
2675
|
parseFunction(stream) {
|
|
2462
2676
|
const args = [];
|
|
2463
2677
|
const tok = stream.next();
|
|
@@ -2497,7 +2711,7 @@ var json_p3 = (function (exports) {
|
|
|
2497
2711
|
msg = "end of expression";
|
|
2498
2712
|
break;
|
|
2499
2713
|
default:
|
|
2500
|
-
msg = `'${stream.current.value}`;
|
|
2714
|
+
msg = `'${stream.current.value}'`;
|
|
2501
2715
|
}
|
|
2502
2716
|
throw new JSONPathSyntaxError(`unexpected ${msg}`, stream.current);
|
|
2503
2717
|
}
|
|
@@ -2574,6 +2788,10 @@ var json_p3 = (function (exports) {
|
|
|
2574
2788
|
* If `true`, enable nondeterministic ordering when iterating JSON object data.
|
|
2575
2789
|
*/
|
|
2576
2790
|
|
|
2791
|
+
/**
|
|
2792
|
+
* The pattern to use for the non-standard _keys selector_.
|
|
2793
|
+
*/
|
|
2794
|
+
|
|
2577
2795
|
/**
|
|
2578
2796
|
* A map of function names to objects implementing the {@link FilterFunction}
|
|
2579
2797
|
* interface. You are free to set or delete custom filter functions directly.
|
|
@@ -2589,6 +2807,7 @@ var json_p3 = (function (exports) {
|
|
|
2589
2807
|
this.minIntIndex = options.maxIntIndex ?? -Math.pow(2, 53) - 1;
|
|
2590
2808
|
this.maxRecursionDepth = options.maxRecursionDepth ?? 50;
|
|
2591
2809
|
this.nondeterministic = options.nondeterministic ?? false;
|
|
2810
|
+
this.keysPattern = options.keysPattern ?? /~/y;
|
|
2592
2811
|
this.parser = new Parser(this);
|
|
2593
2812
|
this.setupFilterFunctions();
|
|
2594
2813
|
}
|
|
@@ -2598,7 +2817,7 @@ var json_p3 = (function (exports) {
|
|
|
2598
2817
|
* @returns A new {@link JSONPath} object, bound to this environment.
|
|
2599
2818
|
*/
|
|
2600
2819
|
compile(path) {
|
|
2601
|
-
return new JSONPath(this, this.parser.parse(new TokenStream(tokenize(path))));
|
|
2820
|
+
return new JSONPath(this, this.parser.parse(new TokenStream(tokenize(this, path))));
|
|
2602
2821
|
}
|
|
2603
2822
|
|
|
2604
2823
|
/**
|
|
@@ -2680,7 +2899,7 @@ var json_p3 = (function (exports) {
|
|
|
2680
2899
|
for (const [typ, arg, idx] of func.argTypes.map((t, i) => [t, args[i], i])) {
|
|
2681
2900
|
switch (typ) {
|
|
2682
2901
|
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)) {
|
|
2902
|
+
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
2903
|
throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of ValueType`, arg.token);
|
|
2685
2904
|
}
|
|
2686
2905
|
break;
|
|
@@ -3308,7 +3527,7 @@ var json_p3 = (function (exports) {
|
|
|
3308
3527
|
apply: apply
|
|
3309
3528
|
});
|
|
3310
3529
|
|
|
3311
|
-
const version = "1.
|
|
3530
|
+
const version = "1.2.1";
|
|
3312
3531
|
|
|
3313
3532
|
exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT;
|
|
3314
3533
|
exports.FunctionExpressionType = FunctionExpressionType;
|