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