json-p3 1.3.4 → 2.0.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/index.d.ts +1 -1
- package/dist/json-p3.cjs.js +347 -411
- package/dist/json-p3.esm.js +347 -411
- package/dist/json-p3.iife.js +347 -411
- 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 +4 -4
- package/dist/path/expression.d.ts +6 -6
- package/dist/path/extra/selectors.d.ts +8 -10
- package/dist/path/index.d.ts +5 -3
- package/dist/path/lru_cache.d.ts +1 -1
- package/dist/path/parse.d.ts +6 -5
- package/dist/path/path.d.ts +5 -5
- package/dist/path/segments.d.ts +38 -0
- package/dist/path/selectors.d.ts +16 -41
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -25
package/dist/json-p3.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* json-p3 version
|
|
2
|
+
* json-p3 version 2.0.0
|
|
3
3
|
* https://github.com/jg-rp/json-p3
|
|
4
4
|
*
|
|
5
5
|
* MIT License
|
|
@@ -919,14 +919,14 @@ class LogicalExpression extends FilterExpression {
|
|
|
919
919
|
/**
|
|
920
920
|
* Base class for relative and absolute JSONPath query expressions.
|
|
921
921
|
*/
|
|
922
|
-
class
|
|
922
|
+
class FilterQuery extends FilterExpression {
|
|
923
923
|
constructor(token, path) {
|
|
924
924
|
super(token);
|
|
925
925
|
this.token = token;
|
|
926
926
|
this.path = path;
|
|
927
927
|
}
|
|
928
928
|
}
|
|
929
|
-
class RelativeQuery extends
|
|
929
|
+
class RelativeQuery extends FilterQuery {
|
|
930
930
|
evaluate(context) {
|
|
931
931
|
return context.lazy ? new JSONPathNodeList(Array.from(this.path.lazyQuery(context.currentValue))) : this.path.query(context.currentValue);
|
|
932
932
|
}
|
|
@@ -934,7 +934,7 @@ class RelativeQuery extends JSONPathQuery {
|
|
|
934
934
|
return `@${this.path.toString().slice(1)}`;
|
|
935
935
|
}
|
|
936
936
|
}
|
|
937
|
-
class RootQuery extends
|
|
937
|
+
class RootQuery extends FilterQuery {
|
|
938
938
|
evaluate(context) {
|
|
939
939
|
return context.lazy ? new JSONPathNodeList(Array.from(this.path.lazyQuery(context.rootValue))) : this.path.query(context.rootValue);
|
|
940
940
|
}
|
|
@@ -1028,9 +1028,9 @@ var expression = /*#__PURE__*/Object.freeze({
|
|
|
1028
1028
|
BooleanLiteral: BooleanLiteral,
|
|
1029
1029
|
FilterExpression: FilterExpression,
|
|
1030
1030
|
FilterExpressionLiteral: FilterExpressionLiteral,
|
|
1031
|
+
FilterQuery: FilterQuery,
|
|
1031
1032
|
FunctionExtension: FunctionExtension,
|
|
1032
1033
|
InfixExpression: InfixExpression,
|
|
1033
|
-
JSONPathQuery: JSONPathQuery,
|
|
1034
1034
|
LogicalExpression: LogicalExpression,
|
|
1035
1035
|
NullLiteral: NullLiteral,
|
|
1036
1036
|
NumberLiteral: NumberLiteral,
|
|
@@ -1042,16 +1042,16 @@ var expression = /*#__PURE__*/Object.freeze({
|
|
|
1042
1042
|
});
|
|
1043
1043
|
|
|
1044
1044
|
class Count {
|
|
1045
|
-
argTypes = [FunctionExpressionType.NodesType];
|
|
1046
|
-
returnType = FunctionExpressionType.ValueType;
|
|
1045
|
+
argTypes = (() => [FunctionExpressionType.NodesType])();
|
|
1046
|
+
returnType = (() => FunctionExpressionType.ValueType)();
|
|
1047
1047
|
call(nodes) {
|
|
1048
1048
|
return nodes.length;
|
|
1049
1049
|
}
|
|
1050
1050
|
}
|
|
1051
1051
|
|
|
1052
1052
|
class Length {
|
|
1053
|
-
argTypes = [FunctionExpressionType.ValueType];
|
|
1054
|
-
returnType = FunctionExpressionType.ValueType;
|
|
1053
|
+
argTypes = (() => [FunctionExpressionType.ValueType])();
|
|
1054
|
+
returnType = (() => FunctionExpressionType.ValueType)();
|
|
1055
1055
|
call(value) {
|
|
1056
1056
|
if (isArray(value) || isString(value)) return value.length;
|
|
1057
1057
|
if (isObject(value)) return Object.keys(value).length;
|
|
@@ -1085,7 +1085,10 @@ class LRUCache extends Map {
|
|
|
1085
1085
|
if (this.has(key)) {
|
|
1086
1086
|
this.delete(key);
|
|
1087
1087
|
} else if (this.size >= this.maxSize) {
|
|
1088
|
-
this.
|
|
1088
|
+
const first = this.first();
|
|
1089
|
+
if (first !== undefined) {
|
|
1090
|
+
this.delete(first);
|
|
1091
|
+
}
|
|
1089
1092
|
}
|
|
1090
1093
|
return super.set(key, value);
|
|
1091
1094
|
}
|
|
@@ -2344,8 +2347,8 @@ var check_1 = {
|
|
|
2344
2347
|
var check$1 = check_1.check;
|
|
2345
2348
|
|
|
2346
2349
|
class Match {
|
|
2347
|
-
argTypes = [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType];
|
|
2348
|
-
returnType = FunctionExpressionType.LogicalType;
|
|
2350
|
+
argTypes = (() => [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType])();
|
|
2351
|
+
returnType = (() => FunctionExpressionType.LogicalType)();
|
|
2349
2352
|
#cache;
|
|
2350
2353
|
constructor() {
|
|
2351
2354
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
@@ -2402,8 +2405,8 @@ class Match {
|
|
|
2402
2405
|
}
|
|
2403
2406
|
|
|
2404
2407
|
class Search {
|
|
2405
|
-
argTypes = [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType];
|
|
2406
|
-
returnType = FunctionExpressionType.LogicalType;
|
|
2408
|
+
argTypes = (() => [FunctionExpressionType.ValueType, FunctionExpressionType.ValueType])();
|
|
2409
|
+
returnType = (() => FunctionExpressionType.LogicalType)();
|
|
2407
2410
|
#cache;
|
|
2408
2411
|
constructor() {
|
|
2409
2412
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
@@ -2451,8 +2454,8 @@ class Search {
|
|
|
2451
2454
|
}
|
|
2452
2455
|
|
|
2453
2456
|
class Value {
|
|
2454
|
-
argTypes = [FunctionExpressionType.NodesType];
|
|
2455
|
-
returnType = FunctionExpressionType.ValueType;
|
|
2457
|
+
argTypes = (() => [FunctionExpressionType.NodesType])();
|
|
2458
|
+
returnType = (() => FunctionExpressionType.ValueType)();
|
|
2456
2459
|
call(nodes) {
|
|
2457
2460
|
if (nodes.length === 1) return nodes.nodes[0].value;
|
|
2458
2461
|
return Nothing;
|
|
@@ -3128,11 +3131,11 @@ class JSONPathSelector {
|
|
|
3128
3131
|
}
|
|
3129
3132
|
|
|
3130
3133
|
/**
|
|
3131
|
-
* @param
|
|
3134
|
+
* @param node - Nodes matched by preceding selectors.
|
|
3132
3135
|
*/
|
|
3133
3136
|
|
|
3134
3137
|
/**
|
|
3135
|
-
* @param
|
|
3138
|
+
* @param node - Nodes matched by preceding selectors.
|
|
3136
3139
|
*/
|
|
3137
3140
|
|
|
3138
3141
|
/**
|
|
@@ -3144,31 +3147,26 @@ class JSONPathSelector {
|
|
|
3144
3147
|
* Shorthand and quoted name selector.
|
|
3145
3148
|
*/
|
|
3146
3149
|
class NameSelector extends JSONPathSelector {
|
|
3147
|
-
constructor(environment, token, name
|
|
3150
|
+
constructor(environment, token, name) {
|
|
3148
3151
|
super(environment, token);
|
|
3149
3152
|
this.environment = environment;
|
|
3150
3153
|
this.token = token;
|
|
3151
3154
|
this.name = name;
|
|
3152
|
-
this.shorthand = shorthand;
|
|
3153
3155
|
}
|
|
3154
|
-
resolve(
|
|
3156
|
+
resolve(node) {
|
|
3155
3157
|
const rv = [];
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
rv.push(new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root));
|
|
3159
|
-
}
|
|
3158
|
+
if (!isArray(node.value) && hasStringKey(node.value, this.name)) {
|
|
3159
|
+
rv.push(new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root));
|
|
3160
3160
|
}
|
|
3161
3161
|
return rv;
|
|
3162
3162
|
}
|
|
3163
|
-
*lazyResolve(
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
yield new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root);
|
|
3167
|
-
}
|
|
3163
|
+
*lazyResolve(node) {
|
|
3164
|
+
if (!isArray(node.value) && hasStringKey(node.value, this.name)) {
|
|
3165
|
+
yield new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root);
|
|
3168
3166
|
}
|
|
3169
3167
|
}
|
|
3170
3168
|
toString() {
|
|
3171
|
-
return
|
|
3169
|
+
return `'${this.name}'`;
|
|
3172
3170
|
}
|
|
3173
3171
|
}
|
|
3174
3172
|
|
|
@@ -3185,25 +3183,21 @@ class IndexSelector extends JSONPathSelector {
|
|
|
3185
3183
|
throw new JSONPathIndexError("index out of range", this.token);
|
|
3186
3184
|
}
|
|
3187
3185
|
}
|
|
3188
|
-
resolve(
|
|
3186
|
+
resolve(node) {
|
|
3189
3187
|
const rv = [];
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
rv.push(new JSONPathNode(node.value[normIndex], node.location.concat(normIndex), node.root));
|
|
3195
|
-
}
|
|
3188
|
+
if (isArray(node.value)) {
|
|
3189
|
+
const normIndex = this.normalizedIndex(node.value.length);
|
|
3190
|
+
if (normIndex in node.value) {
|
|
3191
|
+
rv.push(new JSONPathNode(node.value[normIndex], node.location.concat(normIndex), node.root));
|
|
3196
3192
|
}
|
|
3197
3193
|
}
|
|
3198
3194
|
return rv;
|
|
3199
3195
|
}
|
|
3200
|
-
*lazyResolve(
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
yield new JSONPathNode(node.value[normIndex], node.location.concat(normIndex), node.root);
|
|
3206
|
-
}
|
|
3196
|
+
*lazyResolve(node) {
|
|
3197
|
+
if (isArray(node.value)) {
|
|
3198
|
+
const normIndex = this.normalizedIndex(node.value.length);
|
|
3199
|
+
if (normIndex in node.value) {
|
|
3200
|
+
yield new JSONPathNode(node.value[normIndex], node.location.concat(normIndex), node.root);
|
|
3207
3201
|
}
|
|
3208
3202
|
}
|
|
3209
3203
|
}
|
|
@@ -3225,19 +3219,16 @@ class SliceSelector extends JSONPathSelector {
|
|
|
3225
3219
|
this.step = step;
|
|
3226
3220
|
this.checkRange(start, stop, step);
|
|
3227
3221
|
}
|
|
3228
|
-
resolve(
|
|
3222
|
+
resolve(node) {
|
|
3229
3223
|
const rv = [];
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
rv.push(new JSONPathNode(value, node.location.concat(i), node.root));
|
|
3234
|
-
}
|
|
3224
|
+
if (!isArray(node.value)) return rv;
|
|
3225
|
+
for (const [i, value] of this.slice(node.value, this.start, this.stop, this.step)) {
|
|
3226
|
+
rv.push(new JSONPathNode(value, node.location.concat(i), node.root));
|
|
3235
3227
|
}
|
|
3236
3228
|
return rv;
|
|
3237
3229
|
}
|
|
3238
|
-
*lazyResolve(
|
|
3239
|
-
|
|
3240
|
-
if (!isArray(node.value)) continue;
|
|
3230
|
+
*lazyResolve(node) {
|
|
3231
|
+
if (isArray(node.value)) {
|
|
3241
3232
|
for (const [i, value] of this.lazySlice(node.value, this.start, this.stop, this.step)) {
|
|
3242
3233
|
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
3243
3234
|
}
|
|
@@ -3343,281 +3334,175 @@ class SliceSelector extends JSONPathSelector {
|
|
|
3343
3334
|
}
|
|
3344
3335
|
class WildcardSelector extends JSONPathSelector {
|
|
3345
3336
|
constructor(environment, token) {
|
|
3346
|
-
let shorthand = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
3347
3337
|
super(environment, token);
|
|
3348
3338
|
this.environment = environment;
|
|
3349
3339
|
this.token = token;
|
|
3350
|
-
this.shorthand = shorthand;
|
|
3351
3340
|
}
|
|
3352
|
-
resolve(
|
|
3341
|
+
resolve(node) {
|
|
3353
3342
|
const rv = [];
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
3363
|
-
}
|
|
3343
|
+
if (node.value instanceof String) return rv;
|
|
3344
|
+
if (isArray(node.value)) {
|
|
3345
|
+
for (let i = 0; i < node.value.length; i++) {
|
|
3346
|
+
rv.push(new JSONPathNode(node.value[i], node.location.concat(i), node.root));
|
|
3347
|
+
}
|
|
3348
|
+
} else if (isObject(node.value)) {
|
|
3349
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3350
|
+
rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
3364
3351
|
}
|
|
3365
3352
|
}
|
|
3366
3353
|
return rv;
|
|
3367
3354
|
}
|
|
3368
|
-
*lazyResolve(
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3377
|
-
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
3378
|
-
}
|
|
3355
|
+
*lazyResolve(node) {
|
|
3356
|
+
if (isArray(node.value)) {
|
|
3357
|
+
for (let i = 0; i < node.value.length; i++) {
|
|
3358
|
+
yield new JSONPathNode(node.value[i], node.location.concat(i), node.root);
|
|
3359
|
+
}
|
|
3360
|
+
} else if (isObject(node.value) && !isString(node.value)) {
|
|
3361
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3362
|
+
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
3379
3363
|
}
|
|
3380
3364
|
}
|
|
3381
3365
|
}
|
|
3382
3366
|
toString() {
|
|
3383
|
-
return
|
|
3367
|
+
return "*";
|
|
3384
3368
|
}
|
|
3385
3369
|
}
|
|
3386
|
-
class
|
|
3387
|
-
constructor(environment, token,
|
|
3370
|
+
class FilterSelector extends JSONPathSelector {
|
|
3371
|
+
constructor(environment, token, expression) {
|
|
3388
3372
|
super(environment, token);
|
|
3389
3373
|
this.environment = environment;
|
|
3390
3374
|
this.token = token;
|
|
3391
|
-
this.
|
|
3392
|
-
}
|
|
3393
|
-
resolve(nodes) {
|
|
3394
|
-
const rv = [];
|
|
3395
|
-
if (this.environment.nondeterministic) {
|
|
3396
|
-
for (const root of nodes) {
|
|
3397
|
-
for (const node of this.nondeterministicVisitor(root)) {
|
|
3398
|
-
rv.push(node);
|
|
3399
|
-
}
|
|
3400
|
-
}
|
|
3401
|
-
} else {
|
|
3402
|
-
for (const node of nodes) {
|
|
3403
|
-
rv.push(node);
|
|
3404
|
-
for (const _node of this.visitor(node)) {
|
|
3405
|
-
rv.push(_node);
|
|
3406
|
-
}
|
|
3407
|
-
}
|
|
3408
|
-
}
|
|
3409
|
-
return this.selector.resolve(rv);
|
|
3410
|
-
}
|
|
3411
|
-
*lazyResolve(nodes) {
|
|
3412
|
-
yield* this.selector.lazyResolve(this._lazyResolve(nodes));
|
|
3413
|
-
}
|
|
3414
|
-
|
|
3415
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
3416
|
-
*_lazyResolve(nodes) {
|
|
3417
|
-
for (const _node of nodes) {
|
|
3418
|
-
const stack = [{
|
|
3419
|
-
node: _node,
|
|
3420
|
-
depth: 0
|
|
3421
|
-
}];
|
|
3422
|
-
yield _node;
|
|
3423
|
-
while (stack.length) {
|
|
3424
|
-
const {
|
|
3425
|
-
node: currentNode,
|
|
3426
|
-
depth
|
|
3427
|
-
} = stack.pop();
|
|
3428
|
-
if (depth >= this.environment.maxRecursionDepth) {
|
|
3429
|
-
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
3430
|
-
}
|
|
3431
|
-
if (currentNode.value instanceof String) continue;
|
|
3432
|
-
if (isArray(currentNode.value)) {
|
|
3433
|
-
for (let i = 0; i < currentNode.value.length; i++) {
|
|
3434
|
-
const __node = new JSONPathNode(currentNode.value[i], currentNode.location.concat(i), currentNode.root);
|
|
3435
|
-
yield __node;
|
|
3436
|
-
if (isObject(__node.value)) {
|
|
3437
|
-
stack.push({
|
|
3438
|
-
node: __node,
|
|
3439
|
-
depth: depth + 1
|
|
3440
|
-
});
|
|
3441
|
-
}
|
|
3442
|
-
}
|
|
3443
|
-
} else if (isObject(currentNode.value)) {
|
|
3444
|
-
for (const [key, value] of this.environment.entries(currentNode.value)) {
|
|
3445
|
-
const __node = new JSONPathNode(value, currentNode.location.concat(key), currentNode.root);
|
|
3446
|
-
yield __node;
|
|
3447
|
-
if (isObject(__node.value)) {
|
|
3448
|
-
stack.push({
|
|
3449
|
-
node: __node,
|
|
3450
|
-
depth: depth + 1
|
|
3451
|
-
});
|
|
3452
|
-
}
|
|
3453
|
-
}
|
|
3454
|
-
}
|
|
3455
|
-
}
|
|
3456
|
-
}
|
|
3457
|
-
}
|
|
3458
|
-
toString() {
|
|
3459
|
-
return `..${this.selector.toString()}`;
|
|
3375
|
+
this.expression = expression;
|
|
3460
3376
|
}
|
|
3461
|
-
|
|
3462
|
-
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
3463
|
-
if (depth >= this.environment.maxRecursionDepth) {
|
|
3464
|
-
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
3465
|
-
}
|
|
3377
|
+
resolve(node) {
|
|
3466
3378
|
const rv = [];
|
|
3467
3379
|
if (node.value instanceof String) return rv;
|
|
3468
3380
|
if (isArray(node.value)) {
|
|
3469
3381
|
for (let i = 0; i < node.value.length; i++) {
|
|
3470
|
-
const
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3382
|
+
const value = node.value[i];
|
|
3383
|
+
const filterContext = {
|
|
3384
|
+
environment: this.environment,
|
|
3385
|
+
currentValue: value,
|
|
3386
|
+
rootValue: node.root,
|
|
3387
|
+
currentKey: i
|
|
3388
|
+
};
|
|
3389
|
+
if (this.expression.evaluate(filterContext)) {
|
|
3390
|
+
rv.push(new JSONPathNode(value, node.location.concat(i), node.root));
|
|
3474
3391
|
}
|
|
3475
3392
|
}
|
|
3476
3393
|
} else if (isObject(node.value)) {
|
|
3477
3394
|
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3478
|
-
const
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
}
|
|
3487
|
-
nondeterministicVisitor(root) {
|
|
3488
|
-
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
3489
|
-
const rv = [root];
|
|
3490
|
-
let queue = this.nondeterministicChildren(root).map(node => [node, depth]);
|
|
3491
|
-
while (queue.length) {
|
|
3492
|
-
const [node, _depth] = queue.shift();
|
|
3493
|
-
rv.push(node);
|
|
3494
|
-
if (_depth >= this.environment.maxRecursionDepth) {
|
|
3495
|
-
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
3496
|
-
}
|
|
3497
|
-
|
|
3498
|
-
// Visit child nodes now or queue them for later?
|
|
3499
|
-
const visitChildren = Math.random() < 0.5;
|
|
3500
|
-
for (const child of this.nondeterministicChildren(node)) {
|
|
3501
|
-
if (visitChildren) {
|
|
3502
|
-
rv.push(child);
|
|
3503
|
-
const grandchildren = this.nondeterministicChildren(child).map(n => [n, _depth + 2]);
|
|
3504
|
-
queue = interleave(queue, grandchildren);
|
|
3505
|
-
} else {
|
|
3506
|
-
queue.push([child, _depth + 1]);
|
|
3395
|
+
const filterContext = {
|
|
3396
|
+
environment: this.environment,
|
|
3397
|
+
currentValue: value,
|
|
3398
|
+
rootValue: node.root,
|
|
3399
|
+
currentKey: key
|
|
3400
|
+
};
|
|
3401
|
+
if (this.expression.evaluate(filterContext)) {
|
|
3402
|
+
rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
3507
3403
|
}
|
|
3508
3404
|
}
|
|
3509
3405
|
}
|
|
3510
3406
|
return rv;
|
|
3511
3407
|
}
|
|
3512
|
-
|
|
3513
|
-
const _rv = [];
|
|
3514
|
-
if (node.value instanceof String) return _rv;
|
|
3408
|
+
*lazyResolve(node) {
|
|
3515
3409
|
if (isArray(node.value)) {
|
|
3516
3410
|
for (let i = 0; i < node.value.length; i++) {
|
|
3517
|
-
|
|
3411
|
+
const value = node.value[i];
|
|
3412
|
+
const filterContext = {
|
|
3413
|
+
environment: this.environment,
|
|
3414
|
+
currentValue: value,
|
|
3415
|
+
rootValue: node.root,
|
|
3416
|
+
lazy: true,
|
|
3417
|
+
currentKey: i
|
|
3418
|
+
};
|
|
3419
|
+
if (this.expression.evaluate(filterContext)) {
|
|
3420
|
+
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
3421
|
+
}
|
|
3518
3422
|
}
|
|
3519
|
-
} else if (isObject(node.value)) {
|
|
3423
|
+
} else if (isObject(node.value) && !isString(node.value)) {
|
|
3520
3424
|
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3521
|
-
|
|
3425
|
+
const filterContext = {
|
|
3426
|
+
environment: this.environment,
|
|
3427
|
+
currentValue: value,
|
|
3428
|
+
rootValue: node.root,
|
|
3429
|
+
lazy: true,
|
|
3430
|
+
currentKey: key
|
|
3431
|
+
};
|
|
3432
|
+
if (this.expression.evaluate(filterContext)) {
|
|
3433
|
+
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
3434
|
+
}
|
|
3522
3435
|
}
|
|
3523
3436
|
}
|
|
3524
|
-
|
|
3437
|
+
}
|
|
3438
|
+
toString() {
|
|
3439
|
+
return `?${this.expression.toString()}`;
|
|
3525
3440
|
}
|
|
3526
3441
|
}
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3442
|
+
|
|
3443
|
+
var selectors = /*#__PURE__*/Object.freeze({
|
|
3444
|
+
__proto__: null,
|
|
3445
|
+
FilterSelector: FilterSelector,
|
|
3446
|
+
IndexSelector: IndexSelector,
|
|
3447
|
+
JSONPathSelector: JSONPathSelector,
|
|
3448
|
+
NameSelector: NameSelector,
|
|
3449
|
+
SliceSelector: SliceSelector,
|
|
3450
|
+
WildcardSelector: WildcardSelector
|
|
3451
|
+
});
|
|
3452
|
+
|
|
3453
|
+
/** Base class for all JSONPath segments. Both shorthand and bracketed. */
|
|
3454
|
+
class JSONPathSegment {
|
|
3455
|
+
constructor(environment, token, selectors) {
|
|
3530
3456
|
this.environment = environment;
|
|
3531
3457
|
this.token = token;
|
|
3532
|
-
this.
|
|
3458
|
+
this.selectors = selectors;
|
|
3533
3459
|
}
|
|
3534
3460
|
|
|
3535
|
-
|
|
3461
|
+
/**
|
|
3462
|
+
* @param nodes - Nodes matched by preceding segments.
|
|
3463
|
+
*/
|
|
3464
|
+
|
|
3465
|
+
/**
|
|
3466
|
+
* @param nodes - Nodes matched by preceding segments.
|
|
3467
|
+
*/
|
|
3468
|
+
|
|
3469
|
+
/**
|
|
3470
|
+
* Return a canonical string representation of this segment.
|
|
3471
|
+
*/
|
|
3472
|
+
}
|
|
3473
|
+
|
|
3474
|
+
/** The child selection segment. */
|
|
3475
|
+
class ChildSegment extends JSONPathSegment {
|
|
3536
3476
|
resolve(nodes) {
|
|
3537
3477
|
const rv = [];
|
|
3538
3478
|
for (const node of nodes) {
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
for (let i = 0; i < node.value.length; i++) {
|
|
3542
|
-
const value = node.value[i];
|
|
3543
|
-
const filterContext = {
|
|
3544
|
-
environment: this.environment,
|
|
3545
|
-
currentValue: value,
|
|
3546
|
-
rootValue: node.root,
|
|
3547
|
-
currentKey: i
|
|
3548
|
-
};
|
|
3549
|
-
if (this.expression.evaluate(filterContext)) {
|
|
3550
|
-
rv.push(new JSONPathNode(value, node.location.concat(i), node.root));
|
|
3551
|
-
}
|
|
3552
|
-
}
|
|
3553
|
-
} else if (isObject(node.value)) {
|
|
3554
|
-
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3555
|
-
const filterContext = {
|
|
3556
|
-
environment: this.environment,
|
|
3557
|
-
currentValue: value,
|
|
3558
|
-
rootValue: node.root,
|
|
3559
|
-
currentKey: key
|
|
3560
|
-
};
|
|
3561
|
-
if (this.expression.evaluate(filterContext)) {
|
|
3562
|
-
rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
3563
|
-
}
|
|
3564
|
-
}
|
|
3479
|
+
for (const selector of this.selectors) {
|
|
3480
|
+
rv.push(...selector.resolve(node));
|
|
3565
3481
|
}
|
|
3566
3482
|
}
|
|
3567
3483
|
return rv;
|
|
3568
3484
|
}
|
|
3569
|
-
|
|
3570
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
3571
3485
|
*lazyResolve(nodes) {
|
|
3572
3486
|
for (const node of nodes) {
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
for (let i = 0; i < node.value.length; i++) {
|
|
3576
|
-
const value = node.value[i];
|
|
3577
|
-
const filterContext = {
|
|
3578
|
-
environment: this.environment,
|
|
3579
|
-
currentValue: value,
|
|
3580
|
-
rootValue: node.root,
|
|
3581
|
-
lazy: true,
|
|
3582
|
-
currentKey: i
|
|
3583
|
-
};
|
|
3584
|
-
if (this.expression.evaluate(filterContext)) {
|
|
3585
|
-
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
3586
|
-
}
|
|
3587
|
-
}
|
|
3588
|
-
} else if (isObject(node.value)) {
|
|
3589
|
-
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3590
|
-
const filterContext = {
|
|
3591
|
-
environment: this.environment,
|
|
3592
|
-
currentValue: value,
|
|
3593
|
-
rootValue: node.root,
|
|
3594
|
-
lazy: true,
|
|
3595
|
-
currentKey: key
|
|
3596
|
-
};
|
|
3597
|
-
if (this.expression.evaluate(filterContext)) {
|
|
3598
|
-
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
3599
|
-
}
|
|
3600
|
-
}
|
|
3487
|
+
for (const selector of this.selectors) {
|
|
3488
|
+
yield* selector.resolve(node);
|
|
3601
3489
|
}
|
|
3602
3490
|
}
|
|
3603
3491
|
}
|
|
3604
3492
|
toString() {
|
|
3605
|
-
return
|
|
3493
|
+
return `[${this.selectors.map(s => s.toString()).join(", ")}]`;
|
|
3606
3494
|
}
|
|
3607
3495
|
}
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
this.environment = environment;
|
|
3612
|
-
this.token = token;
|
|
3613
|
-
this.items = items;
|
|
3614
|
-
}
|
|
3496
|
+
|
|
3497
|
+
/** The recursive descent segment. */
|
|
3498
|
+
class DescendantSegment extends JSONPathSegment {
|
|
3615
3499
|
resolve(nodes) {
|
|
3616
3500
|
const rv = [];
|
|
3501
|
+
const visitor = (this.environment.nondeterministic ? this.nondeterministicVisit : this.visit).bind(this);
|
|
3617
3502
|
for (const node of nodes) {
|
|
3618
|
-
for (const
|
|
3619
|
-
for (const
|
|
3620
|
-
rv.push(_node);
|
|
3503
|
+
for (const _node of visitor(node)) {
|
|
3504
|
+
for (const selector of this.selectors) {
|
|
3505
|
+
rv.push(...selector.resolve(_node));
|
|
3621
3506
|
}
|
|
3622
3507
|
}
|
|
3623
3508
|
}
|
|
@@ -3625,13 +3510,75 @@ class BracketedSelection extends JSONPathSelector {
|
|
|
3625
3510
|
}
|
|
3626
3511
|
*lazyResolve(nodes) {
|
|
3627
3512
|
for (const node of nodes) {
|
|
3628
|
-
for (const
|
|
3629
|
-
|
|
3513
|
+
for (const _node of this.visit(node)) {
|
|
3514
|
+
for (const selector of this.selectors) {
|
|
3515
|
+
yield* selector.resolve(_node);
|
|
3516
|
+
}
|
|
3630
3517
|
}
|
|
3631
3518
|
}
|
|
3632
3519
|
}
|
|
3633
3520
|
toString() {
|
|
3634
|
-
return
|
|
3521
|
+
return `..[${this.selectors.map(s => s.toString()).join(", ")}]`;
|
|
3522
|
+
}
|
|
3523
|
+
visit(node) {
|
|
3524
|
+
var _this = this;
|
|
3525
|
+
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
3526
|
+
return function* () {
|
|
3527
|
+
if (depth >= _this.environment.maxRecursionDepth) {
|
|
3528
|
+
throw new JSONPathRecursionLimitError("recursion limit reached", _this.token);
|
|
3529
|
+
}
|
|
3530
|
+
yield node;
|
|
3531
|
+
if (isArray(node.value)) {
|
|
3532
|
+
for (let i = 0; i < node.value.length; i++) {
|
|
3533
|
+
const _node = new JSONPathNode(node.value[i], node.location.concat(i), node.root);
|
|
3534
|
+
yield* _this.visit(_node, depth + 1);
|
|
3535
|
+
}
|
|
3536
|
+
} else if (isObject(node.value)) {
|
|
3537
|
+
for (const [key, value] of _this.environment.entries(node.value)) {
|
|
3538
|
+
const _node = new JSONPathNode(value, node.location.concat(key), node.root);
|
|
3539
|
+
yield* _this.visit(_node, depth + 1);
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
}();
|
|
3543
|
+
}
|
|
3544
|
+
nondeterministicVisit(root) {
|
|
3545
|
+
var _this2 = this;
|
|
3546
|
+
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
3547
|
+
return function* () {
|
|
3548
|
+
let queue = Array.from(_this2.nondeterministicChildren(root)).map(node => [node, depth]);
|
|
3549
|
+
yield root;
|
|
3550
|
+
while (queue.length) {
|
|
3551
|
+
const [node, _depth] = queue.shift();
|
|
3552
|
+
yield node;
|
|
3553
|
+
if (_depth >= _this2.environment.maxRecursionDepth) {
|
|
3554
|
+
throw new JSONPathRecursionLimitError("recursion limit reached", _this2.token);
|
|
3555
|
+
}
|
|
3556
|
+
|
|
3557
|
+
// Visit child nodes now or queue them for later?
|
|
3558
|
+
const visitChildren = Math.random() < 0.5;
|
|
3559
|
+
for (const child of _this2.nondeterministicChildren(node)) {
|
|
3560
|
+
if (visitChildren) {
|
|
3561
|
+
yield child;
|
|
3562
|
+
const grandchildren = Array.from(_this2.nondeterministicChildren(child)).map(n => [n, _depth + 2]);
|
|
3563
|
+
queue = interleave(queue, grandchildren);
|
|
3564
|
+
} else {
|
|
3565
|
+
queue.push([child, _depth + 1]);
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
}();
|
|
3570
|
+
}
|
|
3571
|
+
*nondeterministicChildren(node) {
|
|
3572
|
+
if (isString(node.value)) return;
|
|
3573
|
+
if (isArray(node.value)) {
|
|
3574
|
+
for (let i = 0; i < node.value.length; i++) {
|
|
3575
|
+
yield new JSONPathNode(node.value[i], node.location.concat(i), node.root);
|
|
3576
|
+
}
|
|
3577
|
+
} else if (isObject(node.value)) {
|
|
3578
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3579
|
+
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3635
3582
|
}
|
|
3636
3583
|
}
|
|
3637
3584
|
|
|
@@ -3670,30 +3617,18 @@ function shuffle(entries) {
|
|
|
3670
3617
|
return entries;
|
|
3671
3618
|
}
|
|
3672
3619
|
|
|
3673
|
-
var selectors = /*#__PURE__*/Object.freeze({
|
|
3674
|
-
__proto__: null,
|
|
3675
|
-
BracketedSelection: BracketedSelection,
|
|
3676
|
-
FilterSelector: FilterSelector,
|
|
3677
|
-
IndexSelector: IndexSelector,
|
|
3678
|
-
JSONPathSelector: JSONPathSelector,
|
|
3679
|
-
NameSelector: NameSelector,
|
|
3680
|
-
RecursiveDescentSegment: RecursiveDescentSegment,
|
|
3681
|
-
SliceSelector: SliceSelector,
|
|
3682
|
-
WildcardSelector: WildcardSelector
|
|
3683
|
-
});
|
|
3684
|
-
|
|
3685
3620
|
/**
|
|
3686
3621
|
*
|
|
3687
3622
|
*/
|
|
3688
|
-
class
|
|
3623
|
+
class JSONPathQuery {
|
|
3689
3624
|
/**
|
|
3690
3625
|
*
|
|
3691
3626
|
* @param environment -
|
|
3692
|
-
* @param
|
|
3627
|
+
* @param segments -
|
|
3693
3628
|
*/
|
|
3694
|
-
constructor(environment,
|
|
3629
|
+
constructor(environment, segments) {
|
|
3695
3630
|
this.environment = environment;
|
|
3696
|
-
this.
|
|
3631
|
+
this.segments = segments;
|
|
3697
3632
|
}
|
|
3698
3633
|
|
|
3699
3634
|
/**
|
|
@@ -3703,8 +3638,8 @@ class JSONPath {
|
|
|
3703
3638
|
*/
|
|
3704
3639
|
query(value) {
|
|
3705
3640
|
let nodes = [new JSONPathNode(value, [], value)];
|
|
3706
|
-
for (const
|
|
3707
|
-
nodes =
|
|
3641
|
+
for (const segment of this.segments) {
|
|
3642
|
+
nodes = segment.resolve(nodes);
|
|
3708
3643
|
}
|
|
3709
3644
|
return new JSONPathNodeList(nodes);
|
|
3710
3645
|
}
|
|
@@ -3716,8 +3651,8 @@ class JSONPath {
|
|
|
3716
3651
|
*/
|
|
3717
3652
|
lazyQuery(value) {
|
|
3718
3653
|
let nodes = [new JSONPathNode(value, [], value)][Symbol.iterator]();
|
|
3719
|
-
for (const
|
|
3720
|
-
nodes =
|
|
3654
|
+
for (const segment of this.segments) {
|
|
3655
|
+
nodes = segment.lazyResolve(nodes);
|
|
3721
3656
|
}
|
|
3722
3657
|
return nodes;
|
|
3723
3658
|
}
|
|
@@ -3741,12 +3676,14 @@ class JSONPath {
|
|
|
3741
3676
|
*
|
|
3742
3677
|
*/
|
|
3743
3678
|
toString() {
|
|
3744
|
-
return `$${this.
|
|
3679
|
+
return `$${this.segments.map(s => s.toString()).join("")}`;
|
|
3745
3680
|
}
|
|
3746
3681
|
singularQuery() {
|
|
3747
|
-
for (const
|
|
3748
|
-
if (
|
|
3749
|
-
if (
|
|
3682
|
+
for (const segment of this.segments) {
|
|
3683
|
+
if (segment instanceof DescendantSegment) return false;
|
|
3684
|
+
if (segment.selectors.length === 1 && (segment.selectors[0] instanceof NameSelector || segment.selectors[0] instanceof IndexSelector)) {
|
|
3685
|
+
continue;
|
|
3686
|
+
}
|
|
3750
3687
|
return false;
|
|
3751
3688
|
}
|
|
3752
3689
|
return true;
|
|
@@ -3764,33 +3701,26 @@ class CurrentKey extends FilterExpression {
|
|
|
3764
3701
|
|
|
3765
3702
|
class KeySelector extends JSONPathSelector {
|
|
3766
3703
|
constructor(environment, token, key) {
|
|
3767
|
-
let shorthand = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
3768
3704
|
super(environment, token);
|
|
3769
3705
|
this.environment = environment;
|
|
3770
3706
|
this.token = token;
|
|
3771
3707
|
this.key = key;
|
|
3772
|
-
this.shorthand = shorthand;
|
|
3773
3708
|
}
|
|
3774
|
-
resolve(
|
|
3709
|
+
resolve(node) {
|
|
3775
3710
|
const rv = [];
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
rv.push(new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root));
|
|
3780
|
-
}
|
|
3711
|
+
if (node.value instanceof String || isArray(node.value)) return rv;
|
|
3712
|
+
if (isObject(node.value) && hasStringKey(node.value, this.key)) {
|
|
3713
|
+
rv.push(new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root));
|
|
3781
3714
|
}
|
|
3782
3715
|
return rv;
|
|
3783
3716
|
}
|
|
3784
|
-
*lazyResolve(
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
if (isObject(node.value) && hasStringKey(node.value, this.key)) {
|
|
3788
|
-
yield new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root);
|
|
3789
|
-
}
|
|
3717
|
+
*lazyResolve(node) {
|
|
3718
|
+
if (!isString(node.value) && isObject(node.value) && hasStringKey(node.value, this.key)) {
|
|
3719
|
+
yield new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root);
|
|
3790
3720
|
}
|
|
3791
3721
|
}
|
|
3792
3722
|
toString() {
|
|
3793
|
-
return
|
|
3723
|
+
return `~'${this.key.replaceAll("'", "\\'")}'`;
|
|
3794
3724
|
}
|
|
3795
3725
|
}
|
|
3796
3726
|
|
|
@@ -3799,36 +3729,29 @@ class KeySelector extends JSONPathSelector {
|
|
|
3799
3729
|
*/
|
|
3800
3730
|
class KeysSelector extends JSONPathSelector {
|
|
3801
3731
|
constructor(environment, token) {
|
|
3802
|
-
let shorthand = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
3803
3732
|
super(environment, token);
|
|
3804
3733
|
this.environment = environment;
|
|
3805
3734
|
this.token = token;
|
|
3806
|
-
this.shorthand = shorthand;
|
|
3807
3735
|
}
|
|
3808
|
-
resolve(
|
|
3736
|
+
resolve(node) {
|
|
3809
3737
|
const rv = [];
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
3815
|
-
}
|
|
3738
|
+
if (node.value instanceof String || isArray(node.value)) return rv;
|
|
3739
|
+
if (isObject(node.value)) {
|
|
3740
|
+
for (const [key, _] of this.environment.entries(node.value)) {
|
|
3741
|
+
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
3816
3742
|
}
|
|
3817
3743
|
}
|
|
3818
3744
|
return rv;
|
|
3819
3745
|
}
|
|
3820
|
-
*lazyResolve(
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
for (const [key, _] of this.environment.entries(node.value)) {
|
|
3825
|
-
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
3826
|
-
}
|
|
3746
|
+
*lazyResolve(node) {
|
|
3747
|
+
if (isObject(node.value) && !isString(node.value) && !isArray(node.value)) {
|
|
3748
|
+
for (const [key, _] of this.environment.entries(node.value)) {
|
|
3749
|
+
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
3827
3750
|
}
|
|
3828
3751
|
}
|
|
3829
3752
|
}
|
|
3830
3753
|
toString() {
|
|
3831
|
-
return
|
|
3754
|
+
return "~";
|
|
3832
3755
|
}
|
|
3833
3756
|
}
|
|
3834
3757
|
class KeysFilterSelector extends JSONPathSelector {
|
|
@@ -3838,41 +3761,37 @@ class KeysFilterSelector extends JSONPathSelector {
|
|
|
3838
3761
|
this.token = token;
|
|
3839
3762
|
this.expression = expression;
|
|
3840
3763
|
}
|
|
3841
|
-
resolve(
|
|
3764
|
+
resolve(node) {
|
|
3842
3765
|
const rv = [];
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
3855
|
-
}
|
|
3766
|
+
if (node.value instanceof String || isArray(node.value)) return rv;
|
|
3767
|
+
if (isObject(node.value)) {
|
|
3768
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3769
|
+
const filterContext = {
|
|
3770
|
+
environment: this.environment,
|
|
3771
|
+
currentValue: value,
|
|
3772
|
+
rootValue: node.root,
|
|
3773
|
+
currentKey: key
|
|
3774
|
+
};
|
|
3775
|
+
if (this.expression.evaluate(filterContext)) {
|
|
3776
|
+
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
3856
3777
|
}
|
|
3857
3778
|
}
|
|
3858
3779
|
}
|
|
3859
3780
|
return rv;
|
|
3860
3781
|
}
|
|
3861
|
-
*lazyResolve(
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
3875
|
-
}
|
|
3782
|
+
*lazyResolve(node) {
|
|
3783
|
+
if (node.value instanceof String || isArray(node.value)) return;
|
|
3784
|
+
if (isObject(node.value)) {
|
|
3785
|
+
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3786
|
+
const filterContext = {
|
|
3787
|
+
environment: this.environment,
|
|
3788
|
+
currentValue: value,
|
|
3789
|
+
rootValue: node.root,
|
|
3790
|
+
lazy: true,
|
|
3791
|
+
currentKey: key
|
|
3792
|
+
};
|
|
3793
|
+
if (this.expression.evaluate(filterContext)) {
|
|
3794
|
+
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
3876
3795
|
}
|
|
3877
3796
|
}
|
|
3878
3797
|
}
|
|
@@ -3901,52 +3820,59 @@ class Parser {
|
|
|
3901
3820
|
}
|
|
3902
3821
|
parse(stream) {
|
|
3903
3822
|
if (stream.current.kind === TokenKind.ROOT) stream.next();
|
|
3904
|
-
const
|
|
3823
|
+
const segments = this.parseQuery(stream);
|
|
3905
3824
|
if (stream.current.kind !== TokenKind.EOF) {
|
|
3906
3825
|
throw new JSONPathSyntaxError(`unexpected token '${stream.current.kind}'`, stream.current);
|
|
3907
3826
|
}
|
|
3908
|
-
return
|
|
3827
|
+
return segments;
|
|
3909
3828
|
}
|
|
3910
|
-
|
|
3829
|
+
parseQuery(stream) {
|
|
3911
3830
|
let inFilter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
3912
|
-
const
|
|
3913
|
-
for (;;) {
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3831
|
+
const segments = [];
|
|
3832
|
+
loop: for (;;) {
|
|
3833
|
+
switch (stream.current.kind) {
|
|
3834
|
+
case TokenKind.DDOT:
|
|
3835
|
+
{
|
|
3836
|
+
const token = stream.next();
|
|
3837
|
+
const selectors = this.parseSelectors(stream);
|
|
3838
|
+
segments.push(new DescendantSegment(this.environment, token, selectors));
|
|
3839
|
+
break;
|
|
3840
|
+
}
|
|
3841
|
+
case TokenKind.LBRACKET:
|
|
3842
|
+
case TokenKind.KEY:
|
|
3843
|
+
case TokenKind.KEYS:
|
|
3844
|
+
case TokenKind.NAME:
|
|
3845
|
+
case TokenKind.WILD:
|
|
3846
|
+
{
|
|
3847
|
+
const token = stream.current;
|
|
3848
|
+
const selectors = this.parseSelectors(stream);
|
|
3849
|
+
segments.push(new ChildSegment(this.environment, token, selectors));
|
|
3850
|
+
break;
|
|
3851
|
+
}
|
|
3852
|
+
default:
|
|
3853
|
+
{
|
|
3854
|
+
if (inFilter) stream.backup();
|
|
3855
|
+
break loop;
|
|
3856
|
+
}
|
|
3920
3857
|
}
|
|
3921
|
-
selectors.push(selector);
|
|
3922
3858
|
stream.next();
|
|
3923
3859
|
}
|
|
3924
|
-
return
|
|
3860
|
+
return segments;
|
|
3925
3861
|
}
|
|
3926
|
-
|
|
3862
|
+
parseSelectors(stream) {
|
|
3927
3863
|
switch (stream.current.kind) {
|
|
3928
3864
|
case TokenKind.NAME:
|
|
3929
|
-
return new NameSelector(this.environment, stream.current, stream.current.value
|
|
3865
|
+
return [new NameSelector(this.environment, stream.current, stream.current.value)];
|
|
3930
3866
|
case TokenKind.WILD:
|
|
3931
|
-
return new WildcardSelector(this.environment, stream.current
|
|
3867
|
+
return [new WildcardSelector(this.environment, stream.current)];
|
|
3932
3868
|
case TokenKind.KEY:
|
|
3933
|
-
return new KeySelector(this.environment, stream.current, stream.current.value
|
|
3869
|
+
return [new KeySelector(this.environment, stream.current, stream.current.value)];
|
|
3934
3870
|
case TokenKind.KEYS:
|
|
3935
|
-
return new KeysSelector(this.environment, stream.current
|
|
3936
|
-
case TokenKind.DDOT:
|
|
3937
|
-
{
|
|
3938
|
-
const segmentToken = stream.current;
|
|
3939
|
-
stream.next();
|
|
3940
|
-
const selector = this.parseSegment(stream);
|
|
3941
|
-
if (!selector) {
|
|
3942
|
-
throw new JSONPathSyntaxError("bald descendant segment", stream.current);
|
|
3943
|
-
}
|
|
3944
|
-
return new RecursiveDescentSegment(this.environment, segmentToken, selector);
|
|
3945
|
-
}
|
|
3871
|
+
return [new KeysSelector(this.environment, stream.current)];
|
|
3946
3872
|
case TokenKind.LBRACKET:
|
|
3947
3873
|
return this.parseBracketedSelection(stream);
|
|
3948
3874
|
default:
|
|
3949
|
-
return
|
|
3875
|
+
return [];
|
|
3950
3876
|
}
|
|
3951
3877
|
}
|
|
3952
3878
|
parseIndex(stream) {
|
|
@@ -4003,38 +3929,38 @@ class Parser {
|
|
|
4003
3929
|
}
|
|
4004
3930
|
parseBracketedSelection(stream) {
|
|
4005
3931
|
const token = stream.next();
|
|
4006
|
-
const
|
|
3932
|
+
const selectors = [];
|
|
4007
3933
|
while (stream.current.kind !== TokenKind.RBRACKET) {
|
|
4008
3934
|
switch (stream.current.kind) {
|
|
4009
3935
|
case TokenKind.SINGLE_QUOTE_STRING:
|
|
4010
3936
|
case TokenKind.DOUBLE_QUOTE_STRING:
|
|
4011
|
-
|
|
3937
|
+
selectors.push(new NameSelector(this.environment, stream.current, this.decodeString(stream.current)));
|
|
4012
3938
|
break;
|
|
4013
3939
|
case TokenKind.FILTER:
|
|
4014
|
-
|
|
3940
|
+
selectors.push(this.parseFilter(stream));
|
|
4015
3941
|
break;
|
|
4016
3942
|
case TokenKind.INDEX:
|
|
4017
3943
|
if (stream.peek.kind === TokenKind.COLON) {
|
|
4018
|
-
|
|
3944
|
+
selectors.push(this.parseSlice(stream));
|
|
4019
3945
|
} else {
|
|
4020
|
-
|
|
3946
|
+
selectors.push(this.parseIndex(stream));
|
|
4021
3947
|
}
|
|
4022
3948
|
break;
|
|
4023
3949
|
case TokenKind.COLON:
|
|
4024
|
-
|
|
3950
|
+
selectors.push(this.parseSlice(stream));
|
|
4025
3951
|
break;
|
|
4026
3952
|
case TokenKind.WILD:
|
|
4027
|
-
|
|
3953
|
+
selectors.push(new WildcardSelector(this.environment, stream.current));
|
|
4028
3954
|
break;
|
|
4029
3955
|
case TokenKind.KEY_SINGLE_QUOTE_STRING:
|
|
4030
3956
|
case TokenKind.KEY_DOUBLE_QUOTE_STRING:
|
|
4031
|
-
|
|
3957
|
+
selectors.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current)));
|
|
4032
3958
|
break;
|
|
4033
3959
|
case TokenKind.KEYS_FILTER:
|
|
4034
|
-
|
|
3960
|
+
selectors.push(this.parseFilter(stream, true));
|
|
4035
3961
|
break;
|
|
4036
3962
|
case TokenKind.KEYS:
|
|
4037
|
-
|
|
3963
|
+
selectors.push(new KeysSelector(this.environment, stream.current));
|
|
4038
3964
|
break;
|
|
4039
3965
|
case TokenKind.EOF:
|
|
4040
3966
|
throw new JSONPathSyntaxError("unexpected end of query", stream.current);
|
|
@@ -4048,10 +3974,10 @@ class Parser {
|
|
|
4048
3974
|
}
|
|
4049
3975
|
stream.next();
|
|
4050
3976
|
}
|
|
4051
|
-
if (!
|
|
3977
|
+
if (!selectors.length) {
|
|
4052
3978
|
throw new JSONPathSyntaxError("empty bracketed segment", token);
|
|
4053
3979
|
}
|
|
4054
|
-
return
|
|
3980
|
+
return selectors;
|
|
4055
3981
|
}
|
|
4056
3982
|
parseFilter(stream) {
|
|
4057
3983
|
let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
@@ -4131,11 +4057,11 @@ class Parser {
|
|
|
4131
4057
|
}
|
|
4132
4058
|
parseRootQuery(stream) {
|
|
4133
4059
|
const tok = stream.next();
|
|
4134
|
-
return new RootQuery(tok, new
|
|
4060
|
+
return new RootQuery(tok, new JSONPathQuery(this.environment, this.parseQuery(stream, true)));
|
|
4135
4061
|
}
|
|
4136
4062
|
parseRelativeQuery(stream) {
|
|
4137
4063
|
const tok = stream.next();
|
|
4138
|
-
return new RelativeQuery(tok, new
|
|
4064
|
+
return new RelativeQuery(tok, new JSONPathQuery(this.environment, this.parseQuery(stream, true)));
|
|
4139
4065
|
}
|
|
4140
4066
|
parseCurrentKey(stream) {
|
|
4141
4067
|
return new CurrentKey(stream.current);
|
|
@@ -4419,7 +4345,7 @@ class JSONPathEnvironment {
|
|
|
4419
4345
|
* A map of function names to objects implementing the {@link FilterFunction}
|
|
4420
4346
|
* interface. You are free to set or delete custom filter functions directly.
|
|
4421
4347
|
*/
|
|
4422
|
-
functionRegister = new Map();
|
|
4348
|
+
functionRegister = (() => new Map())();
|
|
4423
4349
|
/**
|
|
4424
4350
|
* @param options - Environment configuration options.
|
|
4425
4351
|
*/
|
|
@@ -4437,10 +4363,10 @@ class JSONPathEnvironment {
|
|
|
4437
4363
|
|
|
4438
4364
|
/**
|
|
4439
4365
|
* @param path - A JSONPath query to parse.
|
|
4440
|
-
* @returns A new {@link
|
|
4366
|
+
* @returns A new {@link JSONPathQuery} object, bound to this environment.
|
|
4441
4367
|
*/
|
|
4442
4368
|
compile(path) {
|
|
4443
|
-
return new
|
|
4369
|
+
return new JSONPathQuery(this, this.parser.parse(new TokenStream(tokenize(this, path))));
|
|
4444
4370
|
}
|
|
4445
4371
|
|
|
4446
4372
|
/**
|
|
@@ -4495,7 +4421,7 @@ class JSONPathEnvironment {
|
|
|
4495
4421
|
/**
|
|
4496
4422
|
* Check the well-typedness of a function's arguments at compile-time.
|
|
4497
4423
|
*
|
|
4498
|
-
* This method is called by the
|
|
4424
|
+
* This method is called by the parser when parsing function calls.
|
|
4499
4425
|
* It is expected to throw a {@link JSONPathTypeError} if the function's
|
|
4500
4426
|
* parameters are not well-typed.
|
|
4501
4427
|
*
|
|
@@ -4522,17 +4448,17 @@ class JSONPathEnvironment {
|
|
|
4522
4448
|
for (const [typ, arg, idx] of func.argTypes.map((t, i) => [t, args[i], i])) {
|
|
4523
4449
|
switch (typ) {
|
|
4524
4450
|
case FunctionExpressionType.ValueType:
|
|
4525
|
-
if (!(arg instanceof FilterExpressionLiteral || arg instanceof CurrentKey || arg instanceof
|
|
4451
|
+
if (!(arg instanceof FilterExpressionLiteral || arg instanceof CurrentKey || arg instanceof FilterQuery && arg.path.singularQuery() || arg instanceof FunctionExtension && this.functionRegister.get(arg.name)?.returnType === FunctionExpressionType.ValueType)) {
|
|
4526
4452
|
throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of ValueType`, arg.token);
|
|
4527
4453
|
}
|
|
4528
4454
|
break;
|
|
4529
4455
|
case FunctionExpressionType.LogicalType:
|
|
4530
|
-
if (!(arg instanceof
|
|
4456
|
+
if (!(arg instanceof FilterQuery || arg instanceof InfixExpression)) {
|
|
4531
4457
|
throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of LogicalType`, arg.token);
|
|
4532
4458
|
}
|
|
4533
4459
|
break;
|
|
4534
4460
|
case FunctionExpressionType.NodesType:
|
|
4535
|
-
if (!(arg instanceof
|
|
4461
|
+
if (!(arg instanceof FilterQuery || arg instanceof FunctionExtension && this.functionRegister.get(arg.name)?.returnType === FunctionExpressionType.NodesType)) {
|
|
4536
4462
|
throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of NodesType`, arg.token);
|
|
4537
4463
|
}
|
|
4538
4464
|
}
|
|
@@ -4648,14 +4574,16 @@ var index$1 = /*#__PURE__*/Object.freeze({
|
|
|
4648
4574
|
__proto__: null,
|
|
4649
4575
|
DEFAULT_ENVIRONMENT: DEFAULT_ENVIRONMENT,
|
|
4650
4576
|
FunctionExpressionType: FunctionExpressionType,
|
|
4651
|
-
JSONPath: JSONPath,
|
|
4652
4577
|
JSONPathEnvironment: JSONPathEnvironment,
|
|
4653
4578
|
JSONPathError: JSONPathError,
|
|
4654
4579
|
JSONPathIndexError: JSONPathIndexError,
|
|
4655
4580
|
JSONPathLexerError: JSONPathLexerError,
|
|
4656
4581
|
JSONPathNode: JSONPathNode,
|
|
4657
4582
|
JSONPathNodeList: JSONPathNodeList,
|
|
4583
|
+
JSONPathQuery: JSONPathQuery,
|
|
4658
4584
|
JSONPathRecursionLimitError: JSONPathRecursionLimitError,
|
|
4585
|
+
JSONPathSegment: JSONPathSegment,
|
|
4586
|
+
JSONPathSelector: JSONPathSelector,
|
|
4659
4587
|
JSONPathSyntaxError: JSONPathSyntaxError,
|
|
4660
4588
|
JSONPathTypeError: JSONPathTypeError,
|
|
4661
4589
|
KEY_MARK: KEY_MARK,
|
|
@@ -4862,7 +4790,11 @@ class OpMove {
|
|
|
4862
4790
|
throw new JSONPatchError(`unexpected operation on 'undefined' (${this.name}:${index})`);
|
|
4863
4791
|
}
|
|
4864
4792
|
if (isArray(destParent)) {
|
|
4865
|
-
|
|
4793
|
+
if (destTarget === "-") {
|
|
4794
|
+
destParent.push(sourceObj);
|
|
4795
|
+
} else {
|
|
4796
|
+
destParent.splice(Number(destTarget), 0, sourceObj);
|
|
4797
|
+
}
|
|
4866
4798
|
} else if (isObject(destParent)) {
|
|
4867
4799
|
destParent[destTarget] = sourceObj;
|
|
4868
4800
|
} else {
|
|
@@ -4904,11 +4836,15 @@ class OpCopy {
|
|
|
4904
4836
|
throw new JSONPatchError(`unexpected operation on 'undefined' (${this.name}:${index})`);
|
|
4905
4837
|
}
|
|
4906
4838
|
if (isArray(destParent)) {
|
|
4907
|
-
|
|
4839
|
+
if (destTarget === "-") {
|
|
4840
|
+
destParent.push(this.deepCopy(sourceObj));
|
|
4841
|
+
} else {
|
|
4842
|
+
destParent.splice(Number(destTarget), 0, this.deepCopy(sourceObj));
|
|
4843
|
+
}
|
|
4908
4844
|
} else if (isObject(destParent)) {
|
|
4909
4845
|
destParent[destTarget] = this.deepCopy(sourceObj);
|
|
4910
4846
|
} else {
|
|
4911
|
-
throw new JSONPatchError(`unexpected operation on '${typeof
|
|
4847
|
+
throw new JSONPatchError(`unexpected operation on '${typeof destParent}' (${this.name}:${index})`);
|
|
4912
4848
|
}
|
|
4913
4849
|
return value;
|
|
4914
4850
|
}
|
|
@@ -5151,20 +5087,20 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
5151
5087
|
apply: apply
|
|
5152
5088
|
});
|
|
5153
5089
|
|
|
5154
|
-
const version = "
|
|
5090
|
+
const version = "2.0.0";
|
|
5155
5091
|
|
|
5156
5092
|
exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT;
|
|
5157
5093
|
exports.FunctionExpressionType = FunctionExpressionType;
|
|
5158
5094
|
exports.JSONPatch = JSONPatch;
|
|
5159
5095
|
exports.JSONPatchError = JSONPatchError;
|
|
5160
5096
|
exports.JSONPatchTestFailure = JSONPatchTestFailure;
|
|
5161
|
-
exports.JSONPath = JSONPath;
|
|
5162
5097
|
exports.JSONPathEnvironment = JSONPathEnvironment;
|
|
5163
5098
|
exports.JSONPathError = JSONPathError;
|
|
5164
5099
|
exports.JSONPathIndexError = JSONPathIndexError;
|
|
5165
5100
|
exports.JSONPathLexerError = JSONPathLexerError;
|
|
5166
5101
|
exports.JSONPathNode = JSONPathNode;
|
|
5167
5102
|
exports.JSONPathNodeList = JSONPathNodeList;
|
|
5103
|
+
exports.JSONPathQuery = JSONPathQuery;
|
|
5168
5104
|
exports.JSONPathRecursionLimitError = JSONPathRecursionLimitError;
|
|
5169
5105
|
exports.JSONPathSyntaxError = JSONPathSyntaxError;
|
|
5170
5106
|
exports.JSONPathTypeError = JSONPathTypeError;
|