json-p3 0.2.0 → 0.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/README.md +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/json-p3.cjs.js +288 -59
- package/dist/json-p3.esm.js +288 -60
- package/dist/json-p3.iife.js +288 -59
- 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 +35 -10
- package/dist/path/index.d.ts +18 -0
- package/dist/path/node.d.ts +1 -4
- package/dist/path/parse.d.ts +4 -0
- package/dist/path/path.d.ts +6 -0
- package/dist/path/selectors.d.ts +25 -9
- 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 0.
|
|
2
|
+
* json-p3 version 0.3.0
|
|
3
3
|
* https://github.com/jg-rp/json-p3
|
|
4
4
|
*
|
|
5
5
|
* MIT License
|
|
@@ -643,10 +643,6 @@ var index$3 = /*#__PURE__*/Object.freeze({
|
|
|
643
643
|
* The pair of a JSON value and its location found in the target JSON value.
|
|
644
644
|
*/
|
|
645
645
|
class JSONPathNode {
|
|
646
|
-
/**
|
|
647
|
-
* The normalized path to this node in the target JSON value.
|
|
648
|
-
*/
|
|
649
|
-
|
|
650
646
|
/**
|
|
651
647
|
* @param value - The JSON value found at _location_.
|
|
652
648
|
* @param location - The parts of a normalized path to _value_.
|
|
@@ -656,9 +652,12 @@ class JSONPathNode {
|
|
|
656
652
|
this.value = value;
|
|
657
653
|
this.location = location;
|
|
658
654
|
this.root = root;
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
655
|
+
}
|
|
656
|
+
get path() {
|
|
657
|
+
return (
|
|
658
|
+
// eslint-disable-next-line prefer-template
|
|
659
|
+
"$" + this.location.map(s => isString(s) ? `['${s}']` : `[${s}]`).join("")
|
|
660
|
+
);
|
|
662
661
|
}
|
|
663
662
|
|
|
664
663
|
/**
|
|
@@ -910,7 +909,7 @@ class JSONPathQuery extends FilterExpression {
|
|
|
910
909
|
}
|
|
911
910
|
class RelativeQuery extends JSONPathQuery {
|
|
912
911
|
evaluate(context) {
|
|
913
|
-
return this.path.query(context.currentValue);
|
|
912
|
+
return context.lazy ? new JSONPathNodeList(Array.from(this.path.lazyQuery(context.currentValue))) : this.path.query(context.currentValue);
|
|
914
913
|
}
|
|
915
914
|
toString() {
|
|
916
915
|
return `@${this.path.toString().slice(1)}`;
|
|
@@ -918,7 +917,7 @@ class RelativeQuery extends JSONPathQuery {
|
|
|
918
917
|
}
|
|
919
918
|
class RootQuery extends JSONPathQuery {
|
|
920
919
|
evaluate(context) {
|
|
921
|
-
return this.path.query(context.rootValue);
|
|
920
|
+
return context.lazy ? new JSONPathNodeList(Array.from(this.path.lazyQuery(context.rootValue))) : this.path.query(context.rootValue);
|
|
922
921
|
}
|
|
923
922
|
toString() {
|
|
924
923
|
return this.path.toString();
|
|
@@ -1720,6 +1719,10 @@ class JSONPathSelector {
|
|
|
1720
1719
|
this.token = token;
|
|
1721
1720
|
}
|
|
1722
1721
|
|
|
1722
|
+
/**
|
|
1723
|
+
* @param nodes - Nodes matched by preceding selectors.
|
|
1724
|
+
*/
|
|
1725
|
+
|
|
1723
1726
|
/**
|
|
1724
1727
|
* @param nodes - Nodes matched by preceding selectors.
|
|
1725
1728
|
*/
|
|
@@ -1747,7 +1750,14 @@ class NameSelector extends JSONPathSelector {
|
|
|
1747
1750
|
rv.push(new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root));
|
|
1748
1751
|
}
|
|
1749
1752
|
}
|
|
1750
|
-
return
|
|
1753
|
+
return rv;
|
|
1754
|
+
}
|
|
1755
|
+
*lazyResolve(nodes) {
|
|
1756
|
+
for (const node of nodes) {
|
|
1757
|
+
if (hasStringKey(node.value, this.name)) {
|
|
1758
|
+
yield new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1751
1761
|
}
|
|
1752
1762
|
toString() {
|
|
1753
1763
|
return this.shorthand ? `['${this.name}']` : `'${this.name}'`;
|
|
@@ -1777,7 +1787,17 @@ class IndexSelector extends JSONPathSelector {
|
|
|
1777
1787
|
}
|
|
1778
1788
|
}
|
|
1779
1789
|
}
|
|
1780
|
-
return
|
|
1790
|
+
return rv;
|
|
1791
|
+
}
|
|
1792
|
+
*lazyResolve(nodes) {
|
|
1793
|
+
for (const node of nodes) {
|
|
1794
|
+
if (isArray(node.value)) {
|
|
1795
|
+
const normIndex = this.normalizedIndex(node.value.length);
|
|
1796
|
+
if (normIndex in node.value) {
|
|
1797
|
+
yield new JSONPathNode(node.value[normIndex], node.location.concat(normIndex), node.root);
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1781
1801
|
}
|
|
1782
1802
|
toString() {
|
|
1783
1803
|
return String(this.index);
|
|
@@ -1805,7 +1825,15 @@ class SliceSelector extends JSONPathSelector {
|
|
|
1805
1825
|
rv.push(new JSONPathNode(value, node.location.concat(i), node.root));
|
|
1806
1826
|
}
|
|
1807
1827
|
}
|
|
1808
|
-
return
|
|
1828
|
+
return rv;
|
|
1829
|
+
}
|
|
1830
|
+
*lazyResolve(nodes) {
|
|
1831
|
+
for (const node of nodes) {
|
|
1832
|
+
if (!isArray(node.value)) continue;
|
|
1833
|
+
for (const [i, value] of this.slice(node.value, this.start, this.stop, this.step)) {
|
|
1834
|
+
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1809
1837
|
}
|
|
1810
1838
|
toString() {
|
|
1811
1839
|
const start = this.start ? this.start : "";
|
|
@@ -1888,22 +1916,92 @@ class WildcardSelector extends JSONPathSelector {
|
|
|
1888
1916
|
}
|
|
1889
1917
|
}
|
|
1890
1918
|
}
|
|
1891
|
-
return
|
|
1919
|
+
return rv;
|
|
1920
|
+
}
|
|
1921
|
+
*lazyResolve(nodes) {
|
|
1922
|
+
for (const node of nodes) {
|
|
1923
|
+
if (node.value instanceof String) continue;
|
|
1924
|
+
if (isArray(node.value)) {
|
|
1925
|
+
for (let i = 0; i < node.value.length; i++) {
|
|
1926
|
+
yield new JSONPathNode(node.value[i], node.location.concat(i), node.root);
|
|
1927
|
+
}
|
|
1928
|
+
} else if (isObject(node.value)) {
|
|
1929
|
+
for (const [key, value] of Object.entries(node.value)) {
|
|
1930
|
+
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1892
1934
|
}
|
|
1893
1935
|
toString() {
|
|
1894
1936
|
return this.shorthand ? "[*]" : "*";
|
|
1895
1937
|
}
|
|
1896
1938
|
}
|
|
1897
1939
|
class RecursiveDescentSegment extends JSONPathSelector {
|
|
1940
|
+
constructor(environment, token, selector) {
|
|
1941
|
+
super(environment, token);
|
|
1942
|
+
this.environment = environment;
|
|
1943
|
+
this.token = token;
|
|
1944
|
+
this.selector = selector;
|
|
1945
|
+
}
|
|
1898
1946
|
resolve(nodes) {
|
|
1899
1947
|
const rv = [];
|
|
1900
1948
|
for (const node of nodes) {
|
|
1901
|
-
rv.push(node
|
|
1949
|
+
rv.push(node);
|
|
1950
|
+
for (const _node of this.visit(node)) {
|
|
1951
|
+
rv.push(_node);
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
return this.selector.resolve(rv);
|
|
1955
|
+
}
|
|
1956
|
+
*lazyResolve(nodes) {
|
|
1957
|
+
yield* this.selector.lazyResolve(this._lazyResolve(nodes));
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1960
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
1961
|
+
*_lazyResolve(nodes) {
|
|
1962
|
+
for (const _node of nodes) {
|
|
1963
|
+
const stack = [{
|
|
1964
|
+
node: _node,
|
|
1965
|
+
depth: 0
|
|
1966
|
+
}];
|
|
1967
|
+
yield _node;
|
|
1968
|
+
while (stack.length) {
|
|
1969
|
+
const {
|
|
1970
|
+
node: currentNode,
|
|
1971
|
+
depth
|
|
1972
|
+
} = stack.pop();
|
|
1973
|
+
if (depth >= this.environment.maxRecursionDepth) {
|
|
1974
|
+
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
1975
|
+
}
|
|
1976
|
+
if (currentNode.value instanceof String) continue;
|
|
1977
|
+
if (isArray(currentNode.value)) {
|
|
1978
|
+
for (let i = 0; i < currentNode.value.length; i++) {
|
|
1979
|
+
const __node = new JSONPathNode(currentNode.value[i], currentNode.location.concat(i), currentNode.root);
|
|
1980
|
+
yield __node;
|
|
1981
|
+
if (isObject(__node.value)) {
|
|
1982
|
+
stack.push({
|
|
1983
|
+
node: __node,
|
|
1984
|
+
depth: depth + 1
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
} else if (isObject(currentNode.value)) {
|
|
1989
|
+
for (const [key, value] of Object.entries(currentNode.value)) {
|
|
1990
|
+
const __node = new JSONPathNode(value, currentNode.location.concat(key), currentNode.root);
|
|
1991
|
+
yield __node;
|
|
1992
|
+
if (isObject(__node.value)) {
|
|
1993
|
+
stack.push({
|
|
1994
|
+
node: __node,
|
|
1995
|
+
depth: depth + 1
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
1902
2001
|
}
|
|
1903
|
-
return new JSONPathNodeList(rv);
|
|
1904
2002
|
}
|
|
1905
2003
|
toString() {
|
|
1906
|
-
return
|
|
2004
|
+
return `..${this.selector.toString()}`;
|
|
1907
2005
|
}
|
|
1908
2006
|
visit(node) {
|
|
1909
2007
|
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
@@ -1911,19 +2009,25 @@ class RecursiveDescentSegment extends JSONPathSelector {
|
|
|
1911
2009
|
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
1912
2010
|
}
|
|
1913
2011
|
const rv = [];
|
|
1914
|
-
if (node.value instanceof String) return
|
|
2012
|
+
if (node.value instanceof String) return rv;
|
|
1915
2013
|
if (isArray(node.value)) {
|
|
1916
2014
|
for (let i = 0; i < node.value.length; i++) {
|
|
1917
2015
|
const _node = new JSONPathNode(node.value[i], node.location.concat(i), node.root);
|
|
1918
|
-
rv.push(_node
|
|
2016
|
+
rv.push(_node);
|
|
2017
|
+
for (const __node of this.visit(_node, depth + 1)) {
|
|
2018
|
+
rv.push(__node);
|
|
2019
|
+
}
|
|
1919
2020
|
}
|
|
1920
2021
|
} else if (isObject(node.value)) {
|
|
1921
2022
|
for (const [key, value] of Object.entries(node.value)) {
|
|
1922
2023
|
const _node = new JSONPathNode(value, node.location.concat(key), node.root);
|
|
1923
|
-
rv.push(_node
|
|
2024
|
+
rv.push(_node);
|
|
2025
|
+
for (const __node of this.visit(_node, depth + 1)) {
|
|
2026
|
+
rv.push(__node);
|
|
2027
|
+
}
|
|
1924
2028
|
}
|
|
1925
2029
|
}
|
|
1926
|
-
return
|
|
2030
|
+
return rv;
|
|
1927
2031
|
}
|
|
1928
2032
|
}
|
|
1929
2033
|
class FilterSelector extends JSONPathSelector {
|
|
@@ -1964,7 +2068,40 @@ class FilterSelector extends JSONPathSelector {
|
|
|
1964
2068
|
}
|
|
1965
2069
|
}
|
|
1966
2070
|
}
|
|
1967
|
-
return
|
|
2071
|
+
return rv;
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
2075
|
+
*lazyResolve(nodes) {
|
|
2076
|
+
for (const node of nodes) {
|
|
2077
|
+
if (node.value instanceof String) continue;
|
|
2078
|
+
if (isArray(node.value)) {
|
|
2079
|
+
for (let i = 0; i < node.value.length; i++) {
|
|
2080
|
+
const value = node.value[i];
|
|
2081
|
+
const filterContext = {
|
|
2082
|
+
environment: this.environment,
|
|
2083
|
+
currentValue: value,
|
|
2084
|
+
rootValue: node.root,
|
|
2085
|
+
lazy: true
|
|
2086
|
+
};
|
|
2087
|
+
if (this.expression.evaluate(filterContext)) {
|
|
2088
|
+
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
} else if (isObject(node.value)) {
|
|
2092
|
+
for (const [key, value] of Object.entries(node.value)) {
|
|
2093
|
+
const filterContext = {
|
|
2094
|
+
environment: this.environment,
|
|
2095
|
+
currentValue: value,
|
|
2096
|
+
rootValue: node.root,
|
|
2097
|
+
lazy: true
|
|
2098
|
+
};
|
|
2099
|
+
if (this.expression.evaluate(filterContext)) {
|
|
2100
|
+
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
1968
2105
|
}
|
|
1969
2106
|
toString() {
|
|
1970
2107
|
return `?${this.expression.toString()}`;
|
|
@@ -1981,10 +2118,19 @@ class BracketedSelection extends JSONPathSelector {
|
|
|
1981
2118
|
const rv = [];
|
|
1982
2119
|
for (const node of nodes) {
|
|
1983
2120
|
for (const item of this.items) {
|
|
1984
|
-
|
|
2121
|
+
for (const _node of item.resolve([node])) {
|
|
2122
|
+
rv.push(_node);
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
return rv;
|
|
2127
|
+
}
|
|
2128
|
+
*lazyResolve(nodes) {
|
|
2129
|
+
for (const node of nodes) {
|
|
2130
|
+
for (const item of this.items) {
|
|
2131
|
+
yield* item.lazyResolve([node]);
|
|
1985
2132
|
}
|
|
1986
2133
|
}
|
|
1987
|
-
return new JSONPathNodeList(rv);
|
|
1988
2134
|
}
|
|
1989
2135
|
toString() {
|
|
1990
2136
|
return `[${this.items.map(itm => itm.toString()).join(", ")}]`;
|
|
@@ -2023,10 +2169,23 @@ class JSONPath {
|
|
|
2023
2169
|
* @returns
|
|
2024
2170
|
*/
|
|
2025
2171
|
query(value) {
|
|
2026
|
-
let nodes =
|
|
2172
|
+
let nodes = [new JSONPathNode(value, [], value)];
|
|
2027
2173
|
for (const selector of this.selectors) {
|
|
2028
2174
|
nodes = selector.resolve(nodes);
|
|
2029
2175
|
}
|
|
2176
|
+
return new JSONPathNodeList(nodes);
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
/**
|
|
2180
|
+
*
|
|
2181
|
+
* @param value -
|
|
2182
|
+
* @returns
|
|
2183
|
+
*/
|
|
2184
|
+
lazyQuery(value) {
|
|
2185
|
+
let nodes = [new JSONPathNode(value, [], value)][Symbol.iterator]();
|
|
2186
|
+
for (const selector of this.selectors) {
|
|
2187
|
+
nodes = selector.lazyResolve(nodes);
|
|
2188
|
+
}
|
|
2030
2189
|
return nodes;
|
|
2031
2190
|
}
|
|
2032
2191
|
|
|
@@ -2039,7 +2198,10 @@ class JSONPath {
|
|
|
2039
2198
|
* there are no matches.
|
|
2040
2199
|
*/
|
|
2041
2200
|
match(value) {
|
|
2042
|
-
|
|
2201
|
+
const it = this.lazyQuery(value);
|
|
2202
|
+
const rv = it.next();
|
|
2203
|
+
if (rv.done) return undefined;
|
|
2204
|
+
return rv.value;
|
|
2043
2205
|
}
|
|
2044
2206
|
|
|
2045
2207
|
/**
|
|
@@ -2059,13 +2221,17 @@ class JSONPath {
|
|
|
2059
2221
|
}
|
|
2060
2222
|
|
|
2061
2223
|
const PRECEDENCE_LOWEST = 1;
|
|
2062
|
-
const PRECEDENCE_LOGICALRIGHT = 3;
|
|
2063
2224
|
const PRECEDENCE_LOGICAL_AND = 4;
|
|
2064
2225
|
const PRECEDENCE_LOGICAL_OR = 5;
|
|
2065
2226
|
const PRECEDENCE_COMPARISON = 6;
|
|
2066
|
-
const
|
|
2227
|
+
const PRECEDENCE_PREFIX = 7;
|
|
2228
|
+
const PRECEDENCES = new Map([[TokenKind.AND, PRECEDENCE_LOGICAL_AND], [TokenKind.EQ, PRECEDENCE_COMPARISON], [TokenKind.GE, PRECEDENCE_COMPARISON], [TokenKind.GT, PRECEDENCE_COMPARISON], [TokenKind.LE, PRECEDENCE_COMPARISON], [TokenKind.LT, PRECEDENCE_COMPARISON], [TokenKind.NE, PRECEDENCE_COMPARISON], [TokenKind.NOT, PRECEDENCE_PREFIX], [TokenKind.OR, PRECEDENCE_LOGICAL_OR], [TokenKind.RPAREN, PRECEDENCE_LOWEST]]);
|
|
2067
2229
|
const BINARY_OPERATORS = new Map([[TokenKind.AND, "&&"], [TokenKind.EQ, "=="], [TokenKind.GE, ">="], [TokenKind.GT, ">"], [TokenKind.LE, "<="], [TokenKind.LT, "<"], [TokenKind.NE, "!="], [TokenKind.OR, "||"]]);
|
|
2068
2230
|
const COMPARISON_OPERATORS = new Set(["==", ">=", ">", "<=", "<", "!="]);
|
|
2231
|
+
|
|
2232
|
+
/**
|
|
2233
|
+
* JSONPath token stream parser.
|
|
2234
|
+
*/
|
|
2069
2235
|
class Parser {
|
|
2070
2236
|
constructor(environment) {
|
|
2071
2237
|
this.environment = environment;
|
|
@@ -2082,30 +2248,41 @@ class Parser {
|
|
|
2082
2248
|
parsePath(stream) {
|
|
2083
2249
|
let inFilter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
2084
2250
|
const selectors = [];
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
break;
|
|
2093
|
-
case TokenKind.DDOT:
|
|
2094
|
-
selectors.push(new RecursiveDescentSegment(this.environment, stream.current));
|
|
2095
|
-
break;
|
|
2096
|
-
case TokenKind.LBRACKET:
|
|
2097
|
-
selectors.push(this.parseBracketedSelection(stream));
|
|
2098
|
-
break;
|
|
2099
|
-
default:
|
|
2100
|
-
if (inFilter) {
|
|
2101
|
-
stream.backup();
|
|
2102
|
-
}
|
|
2103
|
-
break loop;
|
|
2251
|
+
for (;;) {
|
|
2252
|
+
const selector = this.parseSegment(stream);
|
|
2253
|
+
if (!selector) {
|
|
2254
|
+
if (inFilter) {
|
|
2255
|
+
stream.backup();
|
|
2256
|
+
}
|
|
2257
|
+
break;
|
|
2104
2258
|
}
|
|
2259
|
+
selectors.push(selector);
|
|
2105
2260
|
stream.next();
|
|
2106
2261
|
}
|
|
2107
2262
|
return selectors;
|
|
2108
2263
|
}
|
|
2264
|
+
parseSegment(stream) {
|
|
2265
|
+
switch (stream.current.kind) {
|
|
2266
|
+
case TokenKind.NAME:
|
|
2267
|
+
return new NameSelector(this.environment, stream.current, stream.current.value, true);
|
|
2268
|
+
case TokenKind.WILD:
|
|
2269
|
+
return new WildcardSelector(this.environment, stream.current, true);
|
|
2270
|
+
case TokenKind.DDOT:
|
|
2271
|
+
{
|
|
2272
|
+
const segmentToken = stream.current;
|
|
2273
|
+
stream.next();
|
|
2274
|
+
const selector = this.parseSegment(stream);
|
|
2275
|
+
if (!selector) {
|
|
2276
|
+
throw new JSONPathSyntaxError("bald descendant segment", stream.current);
|
|
2277
|
+
}
|
|
2278
|
+
return new RecursiveDescentSegment(this.environment, segmentToken, selector);
|
|
2279
|
+
}
|
|
2280
|
+
case TokenKind.LBRACKET:
|
|
2281
|
+
return this.parseBracketedSelection(stream);
|
|
2282
|
+
default:
|
|
2283
|
+
return null;
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2109
2286
|
parseIndex(stream) {
|
|
2110
2287
|
if (stream.current.value.length > 1 && stream.current.value.startsWith("0") || stream.current.value.startsWith("-0")) {
|
|
2111
2288
|
throw new JSONPathSyntaxError("leading zero in index selector", stream.current);
|
|
@@ -2226,7 +2403,7 @@ class Parser {
|
|
|
2226
2403
|
parsePrefixExpression(stream) {
|
|
2227
2404
|
stream.expect(TokenKind.NOT);
|
|
2228
2405
|
stream.next();
|
|
2229
|
-
return new PrefixExpression(stream.current, "!", this.parseFilterExpression(stream,
|
|
2406
|
+
return new PrefixExpression(stream.current, "!", this.parseFilterExpression(stream, PRECEDENCE_PREFIX));
|
|
2230
2407
|
}
|
|
2231
2408
|
parseInfixExpression(stream, left) {
|
|
2232
2409
|
const tok = stream.next();
|
|
@@ -2348,7 +2525,10 @@ class Parser {
|
|
|
2348
2525
|
*/
|
|
2349
2526
|
|
|
2350
2527
|
/**
|
|
2528
|
+
* A configuration object from which JSONPath queries can be evaluated.
|
|
2351
2529
|
*
|
|
2530
|
+
* An environment is where you'd register custom function extensions or set
|
|
2531
|
+
* the maximum recursion depth limit, for example.
|
|
2352
2532
|
*/
|
|
2353
2533
|
class JSONPathEnvironment {
|
|
2354
2534
|
/**
|
|
@@ -2381,8 +2561,7 @@ class JSONPathEnvironment {
|
|
|
2381
2561
|
*/
|
|
2382
2562
|
functionRegister = new Map();
|
|
2383
2563
|
/**
|
|
2384
|
-
*
|
|
2385
|
-
* @param options -
|
|
2564
|
+
* @param options - Environment configuration options.
|
|
2386
2565
|
*/
|
|
2387
2566
|
constructor() {
|
|
2388
2567
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
@@ -2395,9 +2574,8 @@ class JSONPathEnvironment {
|
|
|
2395
2574
|
}
|
|
2396
2575
|
|
|
2397
2576
|
/**
|
|
2398
|
-
*
|
|
2399
|
-
* @
|
|
2400
|
-
* @returns
|
|
2577
|
+
* @param path - A JSONPath query to parse.
|
|
2578
|
+
* @returns A new {@link JSONPath} object, bound to this environment.
|
|
2401
2579
|
*/
|
|
2402
2580
|
compile(path) {
|
|
2403
2581
|
return new JSONPath(this, this.parser.parse(new TokenStream(tokenize(path))));
|
|
@@ -2405,14 +2583,28 @@ class JSONPathEnvironment {
|
|
|
2405
2583
|
|
|
2406
2584
|
/**
|
|
2407
2585
|
*
|
|
2408
|
-
* @param path -
|
|
2409
|
-
* @param value -
|
|
2410
|
-
* @returns
|
|
2586
|
+
* @param path - A JSONPath query to parse and evaluate against _value_.
|
|
2587
|
+
* @param value - Data to which _path_ will be applied.
|
|
2588
|
+
* @returns The {@link JSONPathNodeList} resulting from applying _path_
|
|
2589
|
+
* to _value_.
|
|
2411
2590
|
*/
|
|
2412
2591
|
query(path, value) {
|
|
2413
2592
|
return this.compile(path).query(value);
|
|
2414
2593
|
}
|
|
2415
2594
|
|
|
2595
|
+
/**
|
|
2596
|
+
* A lazy version of {@link query} which is faster and more memory
|
|
2597
|
+
* efficient when querying some large datasets.
|
|
2598
|
+
*
|
|
2599
|
+
* @param path - A JSONPath query to parse and evaluate against _value_.
|
|
2600
|
+
* @param value - Data to which _path_ will be applied.
|
|
2601
|
+
* @returns A sequence of {@link JSONPathNode} objects resulting from
|
|
2602
|
+
* applying _path_ to _value_.
|
|
2603
|
+
*/
|
|
2604
|
+
lazyQuery(path, value) {
|
|
2605
|
+
return this.compile(path).lazyQuery(value);
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2416
2608
|
/**
|
|
2417
2609
|
* Return a {@link JSONPathNode} instance for the first object found in
|
|
2418
2610
|
* _value_ matching _path_.
|
|
@@ -2425,6 +2617,11 @@ class JSONPathEnvironment {
|
|
|
2425
2617
|
match(path, value) {
|
|
2426
2618
|
return this.compile(path).match(value);
|
|
2427
2619
|
}
|
|
2620
|
+
|
|
2621
|
+
/**
|
|
2622
|
+
* A hook for setting up the function register. You are encouraged to
|
|
2623
|
+
* override this method in classes extending `JSONPathEnvironment`.
|
|
2624
|
+
*/
|
|
2428
2625
|
setupFilterFunctions() {
|
|
2429
2626
|
this.functionRegister.set("count", new Count());
|
|
2430
2627
|
this.functionRegister.set("length", new Length());
|
|
@@ -2434,9 +2631,18 @@ class JSONPathEnvironment {
|
|
|
2434
2631
|
}
|
|
2435
2632
|
|
|
2436
2633
|
/**
|
|
2634
|
+
* Check the well-typedness of a function's arguments at compile-time.
|
|
2635
|
+
*
|
|
2636
|
+
* This method is called by the {@link Parser} when parsing function calls.
|
|
2637
|
+
* It is expected to throw a {@link JSONPathTypeError} if the function's
|
|
2638
|
+
* parameters are not well-typed.
|
|
2639
|
+
*
|
|
2640
|
+
* Override this if you want to deviate from the JSONPath Spec's function
|
|
2641
|
+
* extension type system.
|
|
2437
2642
|
*
|
|
2438
|
-
* @param token -
|
|
2439
|
-
*
|
|
2643
|
+
* @param token - The {@link Token} starting the function call. `Token.value`
|
|
2644
|
+
* will contain the name of the function.
|
|
2645
|
+
* @param args - One {@link FilterExpression} for each argument.
|
|
2440
2646
|
*/
|
|
2441
2647
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
2442
2648
|
checkWellTypedness(token, args) {
|
|
@@ -2503,6 +2709,27 @@ function query(path, value) {
|
|
|
2503
2709
|
return DEFAULT_ENVIRONMENT.query(path, value);
|
|
2504
2710
|
}
|
|
2505
2711
|
|
|
2712
|
+
/**
|
|
2713
|
+
* Lazily query JSON value _value_ with JSONPath expression _path_.
|
|
2714
|
+
* Lazy queries can be faster and more memory efficient when querying
|
|
2715
|
+
* large datasets, especially when using recursive decent selectors.
|
|
2716
|
+
*
|
|
2717
|
+
* @param path - A JSONPath expression/query.
|
|
2718
|
+
* @param value - The JSON-like value the JSONPath query is applied to.
|
|
2719
|
+
* @returns A sequence of {@link JSONPathNode} objects resulting from
|
|
2720
|
+
* applying _path_ to _value_.
|
|
2721
|
+
*
|
|
2722
|
+
* @throws {@link JSONPathSyntaxError}
|
|
2723
|
+
* If the path does not conform to standard syntax.
|
|
2724
|
+
*
|
|
2725
|
+
* @throws {@link JSONPathTypeError}
|
|
2726
|
+
* If filter function arguments are invalid, or filter expression are
|
|
2727
|
+
* used in an invalid way.
|
|
2728
|
+
*/
|
|
2729
|
+
function lazyQuery(path, value) {
|
|
2730
|
+
return DEFAULT_ENVIRONMENT.lazyQuery(path, value);
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2506
2733
|
/**
|
|
2507
2734
|
* Compile JSONPath _path_ for later use.
|
|
2508
2735
|
* @param path - A JSONPath expression/query.
|
|
@@ -2552,6 +2779,7 @@ var index$1 = /*#__PURE__*/Object.freeze({
|
|
|
2552
2779
|
compile: compile,
|
|
2553
2780
|
expressions: expression,
|
|
2554
2781
|
functions: index$2,
|
|
2782
|
+
lazyQuery: lazyQuery,
|
|
2555
2783
|
match: match,
|
|
2556
2784
|
query: query,
|
|
2557
2785
|
selectors: selectors
|
|
@@ -3037,6 +3265,6 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
3037
3265
|
apply: apply
|
|
3038
3266
|
});
|
|
3039
3267
|
|
|
3040
|
-
const version = "0.
|
|
3268
|
+
const version = "0.3.0";
|
|
3041
3269
|
|
|
3042
|
-
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, query, resolve, version };
|
|
3270
|
+
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 };
|