json-p3 1.3.5 → 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 +321 -396
- package/dist/json-p3.esm.js +321 -396
- package/dist/json-p3.iife.js +321 -396
- 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/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 +1 -1
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,
|
|
@@ -3131,11 +3131,11 @@ class JSONPathSelector {
|
|
|
3131
3131
|
}
|
|
3132
3132
|
|
|
3133
3133
|
/**
|
|
3134
|
-
* @param
|
|
3134
|
+
* @param node - Nodes matched by preceding selectors.
|
|
3135
3135
|
*/
|
|
3136
3136
|
|
|
3137
3137
|
/**
|
|
3138
|
-
* @param
|
|
3138
|
+
* @param node - Nodes matched by preceding selectors.
|
|
3139
3139
|
*/
|
|
3140
3140
|
|
|
3141
3141
|
/**
|
|
@@ -3147,31 +3147,26 @@ class JSONPathSelector {
|
|
|
3147
3147
|
* Shorthand and quoted name selector.
|
|
3148
3148
|
*/
|
|
3149
3149
|
class NameSelector extends JSONPathSelector {
|
|
3150
|
-
constructor(environment, token, name
|
|
3150
|
+
constructor(environment, token, name) {
|
|
3151
3151
|
super(environment, token);
|
|
3152
3152
|
this.environment = environment;
|
|
3153
3153
|
this.token = token;
|
|
3154
3154
|
this.name = name;
|
|
3155
|
-
this.shorthand = shorthand;
|
|
3156
3155
|
}
|
|
3157
|
-
resolve(
|
|
3156
|
+
resolve(node) {
|
|
3158
3157
|
const rv = [];
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
rv.push(new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root));
|
|
3162
|
-
}
|
|
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));
|
|
3163
3160
|
}
|
|
3164
3161
|
return rv;
|
|
3165
3162
|
}
|
|
3166
|
-
*lazyResolve(
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
yield new JSONPathNode(node.value[this.name], node.location.concat(this.name), node.root);
|
|
3170
|
-
}
|
|
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);
|
|
3171
3166
|
}
|
|
3172
3167
|
}
|
|
3173
3168
|
toString() {
|
|
3174
|
-
return
|
|
3169
|
+
return `'${this.name}'`;
|
|
3175
3170
|
}
|
|
3176
3171
|
}
|
|
3177
3172
|
|
|
@@ -3188,25 +3183,21 @@ class IndexSelector extends JSONPathSelector {
|
|
|
3188
3183
|
throw new JSONPathIndexError("index out of range", this.token);
|
|
3189
3184
|
}
|
|
3190
3185
|
}
|
|
3191
|
-
resolve(
|
|
3186
|
+
resolve(node) {
|
|
3192
3187
|
const rv = [];
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
rv.push(new JSONPathNode(node.value[normIndex], node.location.concat(normIndex), node.root));
|
|
3198
|
-
}
|
|
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));
|
|
3199
3192
|
}
|
|
3200
3193
|
}
|
|
3201
3194
|
return rv;
|
|
3202
3195
|
}
|
|
3203
|
-
*lazyResolve(
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
yield new JSONPathNode(node.value[normIndex], node.location.concat(normIndex), node.root);
|
|
3209
|
-
}
|
|
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);
|
|
3210
3201
|
}
|
|
3211
3202
|
}
|
|
3212
3203
|
}
|
|
@@ -3228,19 +3219,16 @@ class SliceSelector extends JSONPathSelector {
|
|
|
3228
3219
|
this.step = step;
|
|
3229
3220
|
this.checkRange(start, stop, step);
|
|
3230
3221
|
}
|
|
3231
|
-
resolve(
|
|
3222
|
+
resolve(node) {
|
|
3232
3223
|
const rv = [];
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
rv.push(new JSONPathNode(value, node.location.concat(i), node.root));
|
|
3237
|
-
}
|
|
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));
|
|
3238
3227
|
}
|
|
3239
3228
|
return rv;
|
|
3240
3229
|
}
|
|
3241
|
-
*lazyResolve(
|
|
3242
|
-
|
|
3243
|
-
if (!isArray(node.value)) continue;
|
|
3230
|
+
*lazyResolve(node) {
|
|
3231
|
+
if (isArray(node.value)) {
|
|
3244
3232
|
for (const [i, value] of this.lazySlice(node.value, this.start, this.stop, this.step)) {
|
|
3245
3233
|
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
3246
3234
|
}
|
|
@@ -3346,281 +3334,175 @@ class SliceSelector extends JSONPathSelector {
|
|
|
3346
3334
|
}
|
|
3347
3335
|
class WildcardSelector extends JSONPathSelector {
|
|
3348
3336
|
constructor(environment, token) {
|
|
3349
|
-
let shorthand = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
3350
3337
|
super(environment, token);
|
|
3351
3338
|
this.environment = environment;
|
|
3352
3339
|
this.token = token;
|
|
3353
|
-
this.shorthand = shorthand;
|
|
3354
3340
|
}
|
|
3355
|
-
resolve(
|
|
3341
|
+
resolve(node) {
|
|
3356
3342
|
const rv = [];
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
3366
|
-
}
|
|
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));
|
|
3367
3351
|
}
|
|
3368
3352
|
}
|
|
3369
3353
|
return rv;
|
|
3370
3354
|
}
|
|
3371
|
-
*lazyResolve(
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3380
|
-
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
3381
|
-
}
|
|
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);
|
|
3382
3363
|
}
|
|
3383
3364
|
}
|
|
3384
3365
|
}
|
|
3385
3366
|
toString() {
|
|
3386
|
-
return
|
|
3367
|
+
return "*";
|
|
3387
3368
|
}
|
|
3388
3369
|
}
|
|
3389
|
-
class
|
|
3390
|
-
constructor(environment, token,
|
|
3370
|
+
class FilterSelector extends JSONPathSelector {
|
|
3371
|
+
constructor(environment, token, expression) {
|
|
3391
3372
|
super(environment, token);
|
|
3392
3373
|
this.environment = environment;
|
|
3393
3374
|
this.token = token;
|
|
3394
|
-
this.
|
|
3395
|
-
}
|
|
3396
|
-
resolve(nodes) {
|
|
3397
|
-
const rv = [];
|
|
3398
|
-
if (this.environment.nondeterministic) {
|
|
3399
|
-
for (const root of nodes) {
|
|
3400
|
-
for (const node of this.nondeterministicVisitor(root)) {
|
|
3401
|
-
rv.push(node);
|
|
3402
|
-
}
|
|
3403
|
-
}
|
|
3404
|
-
} else {
|
|
3405
|
-
for (const node of nodes) {
|
|
3406
|
-
rv.push(node);
|
|
3407
|
-
for (const _node of this.visitor(node)) {
|
|
3408
|
-
rv.push(_node);
|
|
3409
|
-
}
|
|
3410
|
-
}
|
|
3411
|
-
}
|
|
3412
|
-
return this.selector.resolve(rv);
|
|
3413
|
-
}
|
|
3414
|
-
*lazyResolve(nodes) {
|
|
3415
|
-
yield* this.selector.lazyResolve(this._lazyResolve(nodes));
|
|
3416
|
-
}
|
|
3417
|
-
|
|
3418
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
3419
|
-
*_lazyResolve(nodes) {
|
|
3420
|
-
for (const _node of nodes) {
|
|
3421
|
-
const stack = [{
|
|
3422
|
-
node: _node,
|
|
3423
|
-
depth: 0
|
|
3424
|
-
}];
|
|
3425
|
-
yield _node;
|
|
3426
|
-
while (stack.length) {
|
|
3427
|
-
const {
|
|
3428
|
-
node: currentNode,
|
|
3429
|
-
depth
|
|
3430
|
-
} = stack.pop();
|
|
3431
|
-
if (depth >= this.environment.maxRecursionDepth) {
|
|
3432
|
-
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
3433
|
-
}
|
|
3434
|
-
if (currentNode.value instanceof String) continue;
|
|
3435
|
-
if (isArray(currentNode.value)) {
|
|
3436
|
-
for (let i = 0; i < currentNode.value.length; i++) {
|
|
3437
|
-
const __node = new JSONPathNode(currentNode.value[i], currentNode.location.concat(i), currentNode.root);
|
|
3438
|
-
yield __node;
|
|
3439
|
-
if (isObject(__node.value)) {
|
|
3440
|
-
stack.push({
|
|
3441
|
-
node: __node,
|
|
3442
|
-
depth: depth + 1
|
|
3443
|
-
});
|
|
3444
|
-
}
|
|
3445
|
-
}
|
|
3446
|
-
} else if (isObject(currentNode.value)) {
|
|
3447
|
-
for (const [key, value] of this.environment.entries(currentNode.value)) {
|
|
3448
|
-
const __node = new JSONPathNode(value, currentNode.location.concat(key), currentNode.root);
|
|
3449
|
-
yield __node;
|
|
3450
|
-
if (isObject(__node.value)) {
|
|
3451
|
-
stack.push({
|
|
3452
|
-
node: __node,
|
|
3453
|
-
depth: depth + 1
|
|
3454
|
-
});
|
|
3455
|
-
}
|
|
3456
|
-
}
|
|
3457
|
-
}
|
|
3458
|
-
}
|
|
3459
|
-
}
|
|
3460
|
-
}
|
|
3461
|
-
toString() {
|
|
3462
|
-
return `..${this.selector.toString()}`;
|
|
3375
|
+
this.expression = expression;
|
|
3463
3376
|
}
|
|
3464
|
-
|
|
3465
|
-
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
3466
|
-
if (depth >= this.environment.maxRecursionDepth) {
|
|
3467
|
-
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
3468
|
-
}
|
|
3377
|
+
resolve(node) {
|
|
3469
3378
|
const rv = [];
|
|
3470
3379
|
if (node.value instanceof String) return rv;
|
|
3471
3380
|
if (isArray(node.value)) {
|
|
3472
3381
|
for (let i = 0; i < node.value.length; i++) {
|
|
3473
|
-
const
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
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));
|
|
3477
3391
|
}
|
|
3478
3392
|
}
|
|
3479
3393
|
} else if (isObject(node.value)) {
|
|
3480
3394
|
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3481
|
-
const
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
}
|
|
3490
|
-
nondeterministicVisitor(root) {
|
|
3491
|
-
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
3492
|
-
const rv = [root];
|
|
3493
|
-
let queue = this.nondeterministicChildren(root).map(node => [node, depth]);
|
|
3494
|
-
while (queue.length) {
|
|
3495
|
-
const [node, _depth] = queue.shift();
|
|
3496
|
-
rv.push(node);
|
|
3497
|
-
if (_depth >= this.environment.maxRecursionDepth) {
|
|
3498
|
-
throw new JSONPathRecursionLimitError("recursion limit reached", this.token);
|
|
3499
|
-
}
|
|
3500
|
-
|
|
3501
|
-
// Visit child nodes now or queue them for later?
|
|
3502
|
-
const visitChildren = Math.random() < 0.5;
|
|
3503
|
-
for (const child of this.nondeterministicChildren(node)) {
|
|
3504
|
-
if (visitChildren) {
|
|
3505
|
-
rv.push(child);
|
|
3506
|
-
const grandchildren = this.nondeterministicChildren(child).map(n => [n, _depth + 2]);
|
|
3507
|
-
queue = interleave(queue, grandchildren);
|
|
3508
|
-
} else {
|
|
3509
|
-
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));
|
|
3510
3403
|
}
|
|
3511
3404
|
}
|
|
3512
3405
|
}
|
|
3513
3406
|
return rv;
|
|
3514
3407
|
}
|
|
3515
|
-
|
|
3516
|
-
const _rv = [];
|
|
3517
|
-
if (node.value instanceof String) return _rv;
|
|
3408
|
+
*lazyResolve(node) {
|
|
3518
3409
|
if (isArray(node.value)) {
|
|
3519
3410
|
for (let i = 0; i < node.value.length; i++) {
|
|
3520
|
-
|
|
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
|
+
}
|
|
3521
3422
|
}
|
|
3522
|
-
} else if (isObject(node.value)) {
|
|
3423
|
+
} else if (isObject(node.value) && !isString(node.value)) {
|
|
3523
3424
|
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3524
|
-
|
|
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
|
+
}
|
|
3525
3435
|
}
|
|
3526
3436
|
}
|
|
3527
|
-
|
|
3437
|
+
}
|
|
3438
|
+
toString() {
|
|
3439
|
+
return `?${this.expression.toString()}`;
|
|
3528
3440
|
}
|
|
3529
3441
|
}
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
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) {
|
|
3533
3456
|
this.environment = environment;
|
|
3534
3457
|
this.token = token;
|
|
3535
|
-
this.
|
|
3458
|
+
this.selectors = selectors;
|
|
3536
3459
|
}
|
|
3537
3460
|
|
|
3538
|
-
|
|
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 {
|
|
3539
3476
|
resolve(nodes) {
|
|
3540
3477
|
const rv = [];
|
|
3541
3478
|
for (const node of nodes) {
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
for (let i = 0; i < node.value.length; i++) {
|
|
3545
|
-
const value = node.value[i];
|
|
3546
|
-
const filterContext = {
|
|
3547
|
-
environment: this.environment,
|
|
3548
|
-
currentValue: value,
|
|
3549
|
-
rootValue: node.root,
|
|
3550
|
-
currentKey: i
|
|
3551
|
-
};
|
|
3552
|
-
if (this.expression.evaluate(filterContext)) {
|
|
3553
|
-
rv.push(new JSONPathNode(value, node.location.concat(i), node.root));
|
|
3554
|
-
}
|
|
3555
|
-
}
|
|
3556
|
-
} else if (isObject(node.value)) {
|
|
3557
|
-
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3558
|
-
const filterContext = {
|
|
3559
|
-
environment: this.environment,
|
|
3560
|
-
currentValue: value,
|
|
3561
|
-
rootValue: node.root,
|
|
3562
|
-
currentKey: key
|
|
3563
|
-
};
|
|
3564
|
-
if (this.expression.evaluate(filterContext)) {
|
|
3565
|
-
rv.push(new JSONPathNode(value, node.location.concat(key), node.root));
|
|
3566
|
-
}
|
|
3567
|
-
}
|
|
3479
|
+
for (const selector of this.selectors) {
|
|
3480
|
+
rv.push(...selector.resolve(node));
|
|
3568
3481
|
}
|
|
3569
3482
|
}
|
|
3570
3483
|
return rv;
|
|
3571
3484
|
}
|
|
3572
|
-
|
|
3573
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
3574
3485
|
*lazyResolve(nodes) {
|
|
3575
3486
|
for (const node of nodes) {
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
for (let i = 0; i < node.value.length; i++) {
|
|
3579
|
-
const value = node.value[i];
|
|
3580
|
-
const filterContext = {
|
|
3581
|
-
environment: this.environment,
|
|
3582
|
-
currentValue: value,
|
|
3583
|
-
rootValue: node.root,
|
|
3584
|
-
lazy: true,
|
|
3585
|
-
currentKey: i
|
|
3586
|
-
};
|
|
3587
|
-
if (this.expression.evaluate(filterContext)) {
|
|
3588
|
-
yield new JSONPathNode(value, node.location.concat(i), node.root);
|
|
3589
|
-
}
|
|
3590
|
-
}
|
|
3591
|
-
} else if (isObject(node.value)) {
|
|
3592
|
-
for (const [key, value] of this.environment.entries(node.value)) {
|
|
3593
|
-
const filterContext = {
|
|
3594
|
-
environment: this.environment,
|
|
3595
|
-
currentValue: value,
|
|
3596
|
-
rootValue: node.root,
|
|
3597
|
-
lazy: true,
|
|
3598
|
-
currentKey: key
|
|
3599
|
-
};
|
|
3600
|
-
if (this.expression.evaluate(filterContext)) {
|
|
3601
|
-
yield new JSONPathNode(value, node.location.concat(key), node.root);
|
|
3602
|
-
}
|
|
3603
|
-
}
|
|
3487
|
+
for (const selector of this.selectors) {
|
|
3488
|
+
yield* selector.resolve(node);
|
|
3604
3489
|
}
|
|
3605
3490
|
}
|
|
3606
3491
|
}
|
|
3607
3492
|
toString() {
|
|
3608
|
-
return
|
|
3493
|
+
return `[${this.selectors.map(s => s.toString()).join(", ")}]`;
|
|
3609
3494
|
}
|
|
3610
3495
|
}
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
this.environment = environment;
|
|
3615
|
-
this.token = token;
|
|
3616
|
-
this.items = items;
|
|
3617
|
-
}
|
|
3496
|
+
|
|
3497
|
+
/** The recursive descent segment. */
|
|
3498
|
+
class DescendantSegment extends JSONPathSegment {
|
|
3618
3499
|
resolve(nodes) {
|
|
3619
3500
|
const rv = [];
|
|
3501
|
+
const visitor = (this.environment.nondeterministic ? this.nondeterministicVisit : this.visit).bind(this);
|
|
3620
3502
|
for (const node of nodes) {
|
|
3621
|
-
for (const
|
|
3622
|
-
for (const
|
|
3623
|
-
rv.push(_node);
|
|
3503
|
+
for (const _node of visitor(node)) {
|
|
3504
|
+
for (const selector of this.selectors) {
|
|
3505
|
+
rv.push(...selector.resolve(_node));
|
|
3624
3506
|
}
|
|
3625
3507
|
}
|
|
3626
3508
|
}
|
|
@@ -3628,13 +3510,75 @@ class BracketedSelection extends JSONPathSelector {
|
|
|
3628
3510
|
}
|
|
3629
3511
|
*lazyResolve(nodes) {
|
|
3630
3512
|
for (const node of nodes) {
|
|
3631
|
-
for (const
|
|
3632
|
-
|
|
3513
|
+
for (const _node of this.visit(node)) {
|
|
3514
|
+
for (const selector of this.selectors) {
|
|
3515
|
+
yield* selector.resolve(_node);
|
|
3516
|
+
}
|
|
3633
3517
|
}
|
|
3634
3518
|
}
|
|
3635
3519
|
}
|
|
3636
3520
|
toString() {
|
|
3637
|
-
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
|
+
}
|
|
3638
3582
|
}
|
|
3639
3583
|
}
|
|
3640
3584
|
|
|
@@ -3673,30 +3617,18 @@ function shuffle(entries) {
|
|
|
3673
3617
|
return entries;
|
|
3674
3618
|
}
|
|
3675
3619
|
|
|
3676
|
-
var selectors = /*#__PURE__*/Object.freeze({
|
|
3677
|
-
__proto__: null,
|
|
3678
|
-
BracketedSelection: BracketedSelection,
|
|
3679
|
-
FilterSelector: FilterSelector,
|
|
3680
|
-
IndexSelector: IndexSelector,
|
|
3681
|
-
JSONPathSelector: JSONPathSelector,
|
|
3682
|
-
NameSelector: NameSelector,
|
|
3683
|
-
RecursiveDescentSegment: RecursiveDescentSegment,
|
|
3684
|
-
SliceSelector: SliceSelector,
|
|
3685
|
-
WildcardSelector: WildcardSelector
|
|
3686
|
-
});
|
|
3687
|
-
|
|
3688
3620
|
/**
|
|
3689
3621
|
*
|
|
3690
3622
|
*/
|
|
3691
|
-
class
|
|
3623
|
+
class JSONPathQuery {
|
|
3692
3624
|
/**
|
|
3693
3625
|
*
|
|
3694
3626
|
* @param environment -
|
|
3695
|
-
* @param
|
|
3627
|
+
* @param segments -
|
|
3696
3628
|
*/
|
|
3697
|
-
constructor(environment,
|
|
3629
|
+
constructor(environment, segments) {
|
|
3698
3630
|
this.environment = environment;
|
|
3699
|
-
this.
|
|
3631
|
+
this.segments = segments;
|
|
3700
3632
|
}
|
|
3701
3633
|
|
|
3702
3634
|
/**
|
|
@@ -3706,8 +3638,8 @@ class JSONPath {
|
|
|
3706
3638
|
*/
|
|
3707
3639
|
query(value) {
|
|
3708
3640
|
let nodes = [new JSONPathNode(value, [], value)];
|
|
3709
|
-
for (const
|
|
3710
|
-
nodes =
|
|
3641
|
+
for (const segment of this.segments) {
|
|
3642
|
+
nodes = segment.resolve(nodes);
|
|
3711
3643
|
}
|
|
3712
3644
|
return new JSONPathNodeList(nodes);
|
|
3713
3645
|
}
|
|
@@ -3719,8 +3651,8 @@ class JSONPath {
|
|
|
3719
3651
|
*/
|
|
3720
3652
|
lazyQuery(value) {
|
|
3721
3653
|
let nodes = [new JSONPathNode(value, [], value)][Symbol.iterator]();
|
|
3722
|
-
for (const
|
|
3723
|
-
nodes =
|
|
3654
|
+
for (const segment of this.segments) {
|
|
3655
|
+
nodes = segment.lazyResolve(nodes);
|
|
3724
3656
|
}
|
|
3725
3657
|
return nodes;
|
|
3726
3658
|
}
|
|
@@ -3744,12 +3676,14 @@ class JSONPath {
|
|
|
3744
3676
|
*
|
|
3745
3677
|
*/
|
|
3746
3678
|
toString() {
|
|
3747
|
-
return `$${this.
|
|
3679
|
+
return `$${this.segments.map(s => s.toString()).join("")}`;
|
|
3748
3680
|
}
|
|
3749
3681
|
singularQuery() {
|
|
3750
|
-
for (const
|
|
3751
|
-
if (
|
|
3752
|
-
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
|
+
}
|
|
3753
3687
|
return false;
|
|
3754
3688
|
}
|
|
3755
3689
|
return true;
|
|
@@ -3767,33 +3701,26 @@ class CurrentKey extends FilterExpression {
|
|
|
3767
3701
|
|
|
3768
3702
|
class KeySelector extends JSONPathSelector {
|
|
3769
3703
|
constructor(environment, token, key) {
|
|
3770
|
-
let shorthand = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
3771
3704
|
super(environment, token);
|
|
3772
3705
|
this.environment = environment;
|
|
3773
3706
|
this.token = token;
|
|
3774
3707
|
this.key = key;
|
|
3775
|
-
this.shorthand = shorthand;
|
|
3776
3708
|
}
|
|
3777
|
-
resolve(
|
|
3709
|
+
resolve(node) {
|
|
3778
3710
|
const rv = [];
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
rv.push(new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root));
|
|
3783
|
-
}
|
|
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));
|
|
3784
3714
|
}
|
|
3785
3715
|
return rv;
|
|
3786
3716
|
}
|
|
3787
|
-
*lazyResolve(
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
if (isObject(node.value) && hasStringKey(node.value, this.key)) {
|
|
3791
|
-
yield new JSONPathNode(this.key, node.location.concat(`${KEY_MARK}${this.key}`), node.root);
|
|
3792
|
-
}
|
|
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);
|
|
3793
3720
|
}
|
|
3794
3721
|
}
|
|
3795
3722
|
toString() {
|
|
3796
|
-
return
|
|
3723
|
+
return `~'${this.key.replaceAll("'", "\\'")}'`;
|
|
3797
3724
|
}
|
|
3798
3725
|
}
|
|
3799
3726
|
|
|
@@ -3802,36 +3729,29 @@ class KeySelector extends JSONPathSelector {
|
|
|
3802
3729
|
*/
|
|
3803
3730
|
class KeysSelector extends JSONPathSelector {
|
|
3804
3731
|
constructor(environment, token) {
|
|
3805
|
-
let shorthand = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
3806
3732
|
super(environment, token);
|
|
3807
3733
|
this.environment = environment;
|
|
3808
3734
|
this.token = token;
|
|
3809
|
-
this.shorthand = shorthand;
|
|
3810
3735
|
}
|
|
3811
|
-
resolve(
|
|
3736
|
+
resolve(node) {
|
|
3812
3737
|
const rv = [];
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
3818
|
-
}
|
|
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));
|
|
3819
3742
|
}
|
|
3820
3743
|
}
|
|
3821
3744
|
return rv;
|
|
3822
3745
|
}
|
|
3823
|
-
*lazyResolve(
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
for (const [key, _] of this.environment.entries(node.value)) {
|
|
3828
|
-
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
3829
|
-
}
|
|
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);
|
|
3830
3750
|
}
|
|
3831
3751
|
}
|
|
3832
3752
|
}
|
|
3833
3753
|
toString() {
|
|
3834
|
-
return
|
|
3754
|
+
return "~";
|
|
3835
3755
|
}
|
|
3836
3756
|
}
|
|
3837
3757
|
class KeysFilterSelector extends JSONPathSelector {
|
|
@@ -3841,41 +3761,37 @@ class KeysFilterSelector extends JSONPathSelector {
|
|
|
3841
3761
|
this.token = token;
|
|
3842
3762
|
this.expression = expression;
|
|
3843
3763
|
}
|
|
3844
|
-
resolve(
|
|
3764
|
+
resolve(node) {
|
|
3845
3765
|
const rv = [];
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
rv.push(new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root));
|
|
3858
|
-
}
|
|
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));
|
|
3859
3777
|
}
|
|
3860
3778
|
}
|
|
3861
3779
|
}
|
|
3862
3780
|
return rv;
|
|
3863
3781
|
}
|
|
3864
|
-
*lazyResolve(
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
yield new JSONPathNode(key, node.location.concat(`${KEY_MARK}${key}`), node.root);
|
|
3878
|
-
}
|
|
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);
|
|
3879
3795
|
}
|
|
3880
3796
|
}
|
|
3881
3797
|
}
|
|
@@ -3904,52 +3820,59 @@ class Parser {
|
|
|
3904
3820
|
}
|
|
3905
3821
|
parse(stream) {
|
|
3906
3822
|
if (stream.current.kind === TokenKind.ROOT) stream.next();
|
|
3907
|
-
const
|
|
3823
|
+
const segments = this.parseQuery(stream);
|
|
3908
3824
|
if (stream.current.kind !== TokenKind.EOF) {
|
|
3909
3825
|
throw new JSONPathSyntaxError(`unexpected token '${stream.current.kind}'`, stream.current);
|
|
3910
3826
|
}
|
|
3911
|
-
return
|
|
3827
|
+
return segments;
|
|
3912
3828
|
}
|
|
3913
|
-
|
|
3829
|
+
parseQuery(stream) {
|
|
3914
3830
|
let inFilter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
3915
|
-
const
|
|
3916
|
-
for (;;) {
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
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
|
+
}
|
|
3923
3857
|
}
|
|
3924
|
-
selectors.push(selector);
|
|
3925
3858
|
stream.next();
|
|
3926
3859
|
}
|
|
3927
|
-
return
|
|
3860
|
+
return segments;
|
|
3928
3861
|
}
|
|
3929
|
-
|
|
3862
|
+
parseSelectors(stream) {
|
|
3930
3863
|
switch (stream.current.kind) {
|
|
3931
3864
|
case TokenKind.NAME:
|
|
3932
|
-
return new NameSelector(this.environment, stream.current, stream.current.value
|
|
3865
|
+
return [new NameSelector(this.environment, stream.current, stream.current.value)];
|
|
3933
3866
|
case TokenKind.WILD:
|
|
3934
|
-
return new WildcardSelector(this.environment, stream.current
|
|
3867
|
+
return [new WildcardSelector(this.environment, stream.current)];
|
|
3935
3868
|
case TokenKind.KEY:
|
|
3936
|
-
return new KeySelector(this.environment, stream.current, stream.current.value
|
|
3869
|
+
return [new KeySelector(this.environment, stream.current, stream.current.value)];
|
|
3937
3870
|
case TokenKind.KEYS:
|
|
3938
|
-
return new KeysSelector(this.environment, stream.current
|
|
3939
|
-
case TokenKind.DDOT:
|
|
3940
|
-
{
|
|
3941
|
-
const segmentToken = stream.current;
|
|
3942
|
-
stream.next();
|
|
3943
|
-
const selector = this.parseSegment(stream);
|
|
3944
|
-
if (!selector) {
|
|
3945
|
-
throw new JSONPathSyntaxError("bald descendant segment", stream.current);
|
|
3946
|
-
}
|
|
3947
|
-
return new RecursiveDescentSegment(this.environment, segmentToken, selector);
|
|
3948
|
-
}
|
|
3871
|
+
return [new KeysSelector(this.environment, stream.current)];
|
|
3949
3872
|
case TokenKind.LBRACKET:
|
|
3950
3873
|
return this.parseBracketedSelection(stream);
|
|
3951
3874
|
default:
|
|
3952
|
-
return
|
|
3875
|
+
return [];
|
|
3953
3876
|
}
|
|
3954
3877
|
}
|
|
3955
3878
|
parseIndex(stream) {
|
|
@@ -4006,38 +3929,38 @@ class Parser {
|
|
|
4006
3929
|
}
|
|
4007
3930
|
parseBracketedSelection(stream) {
|
|
4008
3931
|
const token = stream.next();
|
|
4009
|
-
const
|
|
3932
|
+
const selectors = [];
|
|
4010
3933
|
while (stream.current.kind !== TokenKind.RBRACKET) {
|
|
4011
3934
|
switch (stream.current.kind) {
|
|
4012
3935
|
case TokenKind.SINGLE_QUOTE_STRING:
|
|
4013
3936
|
case TokenKind.DOUBLE_QUOTE_STRING:
|
|
4014
|
-
|
|
3937
|
+
selectors.push(new NameSelector(this.environment, stream.current, this.decodeString(stream.current)));
|
|
4015
3938
|
break;
|
|
4016
3939
|
case TokenKind.FILTER:
|
|
4017
|
-
|
|
3940
|
+
selectors.push(this.parseFilter(stream));
|
|
4018
3941
|
break;
|
|
4019
3942
|
case TokenKind.INDEX:
|
|
4020
3943
|
if (stream.peek.kind === TokenKind.COLON) {
|
|
4021
|
-
|
|
3944
|
+
selectors.push(this.parseSlice(stream));
|
|
4022
3945
|
} else {
|
|
4023
|
-
|
|
3946
|
+
selectors.push(this.parseIndex(stream));
|
|
4024
3947
|
}
|
|
4025
3948
|
break;
|
|
4026
3949
|
case TokenKind.COLON:
|
|
4027
|
-
|
|
3950
|
+
selectors.push(this.parseSlice(stream));
|
|
4028
3951
|
break;
|
|
4029
3952
|
case TokenKind.WILD:
|
|
4030
|
-
|
|
3953
|
+
selectors.push(new WildcardSelector(this.environment, stream.current));
|
|
4031
3954
|
break;
|
|
4032
3955
|
case TokenKind.KEY_SINGLE_QUOTE_STRING:
|
|
4033
3956
|
case TokenKind.KEY_DOUBLE_QUOTE_STRING:
|
|
4034
|
-
|
|
3957
|
+
selectors.push(new KeySelector(this.environment, stream.current, this.decodeString(stream.current)));
|
|
4035
3958
|
break;
|
|
4036
3959
|
case TokenKind.KEYS_FILTER:
|
|
4037
|
-
|
|
3960
|
+
selectors.push(this.parseFilter(stream, true));
|
|
4038
3961
|
break;
|
|
4039
3962
|
case TokenKind.KEYS:
|
|
4040
|
-
|
|
3963
|
+
selectors.push(new KeysSelector(this.environment, stream.current));
|
|
4041
3964
|
break;
|
|
4042
3965
|
case TokenKind.EOF:
|
|
4043
3966
|
throw new JSONPathSyntaxError("unexpected end of query", stream.current);
|
|
@@ -4051,10 +3974,10 @@ class Parser {
|
|
|
4051
3974
|
}
|
|
4052
3975
|
stream.next();
|
|
4053
3976
|
}
|
|
4054
|
-
if (!
|
|
3977
|
+
if (!selectors.length) {
|
|
4055
3978
|
throw new JSONPathSyntaxError("empty bracketed segment", token);
|
|
4056
3979
|
}
|
|
4057
|
-
return
|
|
3980
|
+
return selectors;
|
|
4058
3981
|
}
|
|
4059
3982
|
parseFilter(stream) {
|
|
4060
3983
|
let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
@@ -4134,11 +4057,11 @@ class Parser {
|
|
|
4134
4057
|
}
|
|
4135
4058
|
parseRootQuery(stream) {
|
|
4136
4059
|
const tok = stream.next();
|
|
4137
|
-
return new RootQuery(tok, new
|
|
4060
|
+
return new RootQuery(tok, new JSONPathQuery(this.environment, this.parseQuery(stream, true)));
|
|
4138
4061
|
}
|
|
4139
4062
|
parseRelativeQuery(stream) {
|
|
4140
4063
|
const tok = stream.next();
|
|
4141
|
-
return new RelativeQuery(tok, new
|
|
4064
|
+
return new RelativeQuery(tok, new JSONPathQuery(this.environment, this.parseQuery(stream, true)));
|
|
4142
4065
|
}
|
|
4143
4066
|
parseCurrentKey(stream) {
|
|
4144
4067
|
return new CurrentKey(stream.current);
|
|
@@ -4440,10 +4363,10 @@ class JSONPathEnvironment {
|
|
|
4440
4363
|
|
|
4441
4364
|
/**
|
|
4442
4365
|
* @param path - A JSONPath query to parse.
|
|
4443
|
-
* @returns A new {@link
|
|
4366
|
+
* @returns A new {@link JSONPathQuery} object, bound to this environment.
|
|
4444
4367
|
*/
|
|
4445
4368
|
compile(path) {
|
|
4446
|
-
return new
|
|
4369
|
+
return new JSONPathQuery(this, this.parser.parse(new TokenStream(tokenize(this, path))));
|
|
4447
4370
|
}
|
|
4448
4371
|
|
|
4449
4372
|
/**
|
|
@@ -4498,7 +4421,7 @@ class JSONPathEnvironment {
|
|
|
4498
4421
|
/**
|
|
4499
4422
|
* Check the well-typedness of a function's arguments at compile-time.
|
|
4500
4423
|
*
|
|
4501
|
-
* This method is called by the
|
|
4424
|
+
* This method is called by the parser when parsing function calls.
|
|
4502
4425
|
* It is expected to throw a {@link JSONPathTypeError} if the function's
|
|
4503
4426
|
* parameters are not well-typed.
|
|
4504
4427
|
*
|
|
@@ -4525,17 +4448,17 @@ class JSONPathEnvironment {
|
|
|
4525
4448
|
for (const [typ, arg, idx] of func.argTypes.map((t, i) => [t, args[i], i])) {
|
|
4526
4449
|
switch (typ) {
|
|
4527
4450
|
case FunctionExpressionType.ValueType:
|
|
4528
|
-
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)) {
|
|
4529
4452
|
throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of ValueType`, arg.token);
|
|
4530
4453
|
}
|
|
4531
4454
|
break;
|
|
4532
4455
|
case FunctionExpressionType.LogicalType:
|
|
4533
|
-
if (!(arg instanceof
|
|
4456
|
+
if (!(arg instanceof FilterQuery || arg instanceof InfixExpression)) {
|
|
4534
4457
|
throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of LogicalType`, arg.token);
|
|
4535
4458
|
}
|
|
4536
4459
|
break;
|
|
4537
4460
|
case FunctionExpressionType.NodesType:
|
|
4538
|
-
if (!(arg instanceof
|
|
4461
|
+
if (!(arg instanceof FilterQuery || arg instanceof FunctionExtension && this.functionRegister.get(arg.name)?.returnType === FunctionExpressionType.NodesType)) {
|
|
4539
4462
|
throw new JSONPathTypeError(`${token.value}() argument ${idx} must be of NodesType`, arg.token);
|
|
4540
4463
|
}
|
|
4541
4464
|
}
|
|
@@ -4651,14 +4574,16 @@ var index$1 = /*#__PURE__*/Object.freeze({
|
|
|
4651
4574
|
__proto__: null,
|
|
4652
4575
|
DEFAULT_ENVIRONMENT: DEFAULT_ENVIRONMENT,
|
|
4653
4576
|
FunctionExpressionType: FunctionExpressionType,
|
|
4654
|
-
JSONPath: JSONPath,
|
|
4655
4577
|
JSONPathEnvironment: JSONPathEnvironment,
|
|
4656
4578
|
JSONPathError: JSONPathError,
|
|
4657
4579
|
JSONPathIndexError: JSONPathIndexError,
|
|
4658
4580
|
JSONPathLexerError: JSONPathLexerError,
|
|
4659
4581
|
JSONPathNode: JSONPathNode,
|
|
4660
4582
|
JSONPathNodeList: JSONPathNodeList,
|
|
4583
|
+
JSONPathQuery: JSONPathQuery,
|
|
4661
4584
|
JSONPathRecursionLimitError: JSONPathRecursionLimitError,
|
|
4585
|
+
JSONPathSegment: JSONPathSegment,
|
|
4586
|
+
JSONPathSelector: JSONPathSelector,
|
|
4662
4587
|
JSONPathSyntaxError: JSONPathSyntaxError,
|
|
4663
4588
|
JSONPathTypeError: JSONPathTypeError,
|
|
4664
4589
|
KEY_MARK: KEY_MARK,
|
|
@@ -5162,20 +5087,20 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
5162
5087
|
apply: apply
|
|
5163
5088
|
});
|
|
5164
5089
|
|
|
5165
|
-
const version = "
|
|
5090
|
+
const version = "2.0.0";
|
|
5166
5091
|
|
|
5167
5092
|
exports.DEFAULT_ENVIRONMENT = DEFAULT_ENVIRONMENT;
|
|
5168
5093
|
exports.FunctionExpressionType = FunctionExpressionType;
|
|
5169
5094
|
exports.JSONPatch = JSONPatch;
|
|
5170
5095
|
exports.JSONPatchError = JSONPatchError;
|
|
5171
5096
|
exports.JSONPatchTestFailure = JSONPatchTestFailure;
|
|
5172
|
-
exports.JSONPath = JSONPath;
|
|
5173
5097
|
exports.JSONPathEnvironment = JSONPathEnvironment;
|
|
5174
5098
|
exports.JSONPathError = JSONPathError;
|
|
5175
5099
|
exports.JSONPathIndexError = JSONPathIndexError;
|
|
5176
5100
|
exports.JSONPathLexerError = JSONPathLexerError;
|
|
5177
5101
|
exports.JSONPathNode = JSONPathNode;
|
|
5178
5102
|
exports.JSONPathNodeList = JSONPathNodeList;
|
|
5103
|
+
exports.JSONPathQuery = JSONPathQuery;
|
|
5179
5104
|
exports.JSONPathRecursionLimitError = JSONPathRecursionLimitError;
|
|
5180
5105
|
exports.JSONPathSyntaxError = JSONPathSyntaxError;
|
|
5181
5106
|
exports.JSONPathTypeError = JSONPathTypeError;
|