@jmespath-community/jmespath 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -8
- package/dist/cli.cjs +2816 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +2 -0
- package/dist/cli.mjs +857 -244
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +849 -268
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +86 -34
- package/dist/index.d.ts +86 -34
- package/dist/index.esm.js +850 -242
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +5 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/index.mjs +850 -242
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +852 -273
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +5 -1
- package/dist/index.umd.min.js.map +1 -1
- package/package.json +41 -6
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,82 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// src/utils/ast.ts
|
|
4
|
+
var CHILD_PROPS = ["left", "right", "condition", "child", "operand", "trueExpr", "falseExpr", "expression"];
|
|
5
|
+
function pushChildren(node, stack) {
|
|
6
|
+
const n = node;
|
|
7
|
+
for (const prop of CHILD_PROPS) {
|
|
8
|
+
const val = n[prop];
|
|
9
|
+
if (val && typeof val === "object" && "type" in val) {
|
|
10
|
+
stack.push(val);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (Array.isArray(n.children)) {
|
|
14
|
+
for (const item of n.children) {
|
|
15
|
+
if (!item) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
stack.push(item);
|
|
19
|
+
if (item.type === "KeyValuePair" && item.value) {
|
|
20
|
+
stack.push(item.value);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(n.bindings)) {
|
|
25
|
+
for (const item of n.bindings) {
|
|
26
|
+
if (!item) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
stack.push(item);
|
|
30
|
+
if (item.reference) {
|
|
31
|
+
stack.push(item.reference);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function forEachNode(root, visitor) {
|
|
37
|
+
const stack = [root];
|
|
38
|
+
while (stack.length > 0) {
|
|
39
|
+
const current = stack.pop();
|
|
40
|
+
if (!current) {
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
if (visitor(current) === false) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
pushChildren(current, stack);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function countNodes(root) {
|
|
50
|
+
let count = 0;
|
|
51
|
+
forEachNode(root, () => {
|
|
52
|
+
count += 1;
|
|
53
|
+
return true;
|
|
54
|
+
});
|
|
55
|
+
return count;
|
|
56
|
+
}
|
|
57
|
+
function findDisallowedFunction(root, options) {
|
|
58
|
+
const { allowedFunctions, disallowedFunctions } = options;
|
|
59
|
+
if (!allowedFunctions && !disallowedFunctions) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
let violation = null;
|
|
63
|
+
forEachNode(root, (node) => {
|
|
64
|
+
if (node.type !== "Function") {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const name = node.name;
|
|
68
|
+
if (allowedFunctions && !allowedFunctions.includes(name)) {
|
|
69
|
+
violation = `Function '${name}' is not allowed`;
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
if (disallowedFunctions && disallowedFunctions.includes(name)) {
|
|
73
|
+
violation = `Function '${name}' is disallowed`;
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
});
|
|
78
|
+
return violation;
|
|
79
|
+
}
|
|
4
80
|
|
|
5
81
|
// src/utils/index.ts
|
|
6
82
|
var isObject = (obj) => {
|
|
@@ -51,9 +127,6 @@ var isFalse = (obj) => {
|
|
|
51
127
|
if (Array.isArray(obj)) {
|
|
52
128
|
return obj.length === 0;
|
|
53
129
|
}
|
|
54
|
-
if (obj === null) {
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
130
|
return Object.keys(obj).length === 0;
|
|
58
131
|
}
|
|
59
132
|
return false;
|
|
@@ -98,111 +171,28 @@ var notZero = (n) => {
|
|
|
98
171
|
};
|
|
99
172
|
var add = (left, right) => {
|
|
100
173
|
ensureNumbers(left, right);
|
|
101
|
-
|
|
102
|
-
return result;
|
|
174
|
+
return left + right;
|
|
103
175
|
};
|
|
104
176
|
var sub = (left, right) => {
|
|
105
177
|
ensureNumbers(left, right);
|
|
106
|
-
|
|
107
|
-
return result;
|
|
178
|
+
return left - right;
|
|
108
179
|
};
|
|
109
180
|
var mul = (left, right) => {
|
|
110
181
|
ensureNumbers(left, right);
|
|
111
|
-
|
|
112
|
-
return result;
|
|
182
|
+
return left * right;
|
|
113
183
|
};
|
|
114
184
|
var divide = (left, right) => {
|
|
115
185
|
ensureNumbers(left, right);
|
|
116
|
-
|
|
117
|
-
return result;
|
|
186
|
+
return left / notZero(right);
|
|
118
187
|
};
|
|
119
188
|
var div = (left, right) => {
|
|
120
189
|
ensureNumbers(left, right);
|
|
121
|
-
|
|
122
|
-
return result;
|
|
190
|
+
return Math.floor(left / notZero(right));
|
|
123
191
|
};
|
|
124
192
|
var mod = (left, right) => {
|
|
125
193
|
ensureNumbers(left, right);
|
|
126
|
-
|
|
127
|
-
return result;
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
// src/utils/strings.ts
|
|
131
|
-
var findFirst = (subject, sub2, start, end) => {
|
|
132
|
-
if (!subject || !sub2) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
start = Math.max(ensureInteger(start = start || 0), 0);
|
|
136
|
-
end = Math.min(ensureInteger(end = end || subject.length), subject.length);
|
|
137
|
-
const offset = subject.slice(start, end).indexOf(sub2);
|
|
138
|
-
return offset === -1 ? null : offset + start;
|
|
139
|
-
};
|
|
140
|
-
var findLast = (subject, sub2, start, end) => {
|
|
141
|
-
if (!subject || !sub2) {
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
start = Math.max(ensureInteger(start = start || 0), 0);
|
|
145
|
-
end = Math.min(ensureInteger(end = end || subject.length), subject.length);
|
|
146
|
-
const offset = subject.slice(start, end).lastIndexOf(sub2);
|
|
147
|
-
const result = offset === -1 ? null : offset + start;
|
|
148
|
-
return result;
|
|
149
|
-
};
|
|
150
|
-
var lower = (subject) => subject.toLowerCase();
|
|
151
|
-
var ensurePadFuncParams = (name, width, padding) => {
|
|
152
|
-
padding = padding || " ";
|
|
153
|
-
if (padding.length > 1) {
|
|
154
|
-
throw new Error(`invalid value, ${name} expects its 'pad' parameter to be a valid string with a single codepoint`);
|
|
155
|
-
}
|
|
156
|
-
ensurePositiveInteger(width);
|
|
157
|
-
return padding;
|
|
158
|
-
};
|
|
159
|
-
var padLeft = (subject, width, padding) => {
|
|
160
|
-
padding = ensurePadFuncParams("pad_left", width, padding);
|
|
161
|
-
return subject && subject.padStart(width, padding) || "";
|
|
162
|
-
};
|
|
163
|
-
var padRight = (subject, width, padding) => {
|
|
164
|
-
padding = ensurePadFuncParams("pad_right", width, padding);
|
|
165
|
-
return subject && subject.padEnd(width, padding) || "";
|
|
166
|
-
};
|
|
167
|
-
var replace = (subject, string, by, count) => {
|
|
168
|
-
if (count === 0) {
|
|
169
|
-
return subject;
|
|
170
|
-
}
|
|
171
|
-
if (!count) {
|
|
172
|
-
return subject.split(string).join(by);
|
|
173
|
-
}
|
|
174
|
-
ensurePositiveInteger(count);
|
|
175
|
-
[...Array(count).keys()].map(() => subject = subject.replace(string, by));
|
|
176
|
-
return subject;
|
|
177
|
-
};
|
|
178
|
-
var split = (subject, search2, count) => {
|
|
179
|
-
if (subject.length == 0 && search2.length === 0) {
|
|
180
|
-
return [];
|
|
181
|
-
}
|
|
182
|
-
if (count === null || count === void 0) {
|
|
183
|
-
return subject.split(search2);
|
|
184
|
-
}
|
|
185
|
-
ensurePositiveInteger(count);
|
|
186
|
-
if (count === 0) {
|
|
187
|
-
return [subject];
|
|
188
|
-
}
|
|
189
|
-
const split2 = subject.split(search2);
|
|
190
|
-
return [...split2.slice(0, count), split2.slice(count).join(search2)];
|
|
191
|
-
};
|
|
192
|
-
var trim = (subject, chars) => {
|
|
193
|
-
return trimLeft(trimRight(subject, chars), chars);
|
|
194
|
-
};
|
|
195
|
-
var trimLeft = (subject, chars) => {
|
|
196
|
-
return trimImpl(subject, (list) => new RegExp(`^[${list}]*(.*?)`), chars);
|
|
197
|
-
};
|
|
198
|
-
var trimRight = (subject, chars) => {
|
|
199
|
-
return trimImpl(subject, (list) => new RegExp(`(.*?)[${list}]*$`), chars);
|
|
200
|
-
};
|
|
201
|
-
var trimImpl = (subject, regExper, chars) => {
|
|
202
|
-
const pattern = chars ? chars.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&") : "\\s\x85";
|
|
203
|
-
return subject.replace(regExper(pattern), "$1");
|
|
194
|
+
return left % right;
|
|
204
195
|
};
|
|
205
|
-
var upper = (subject) => subject.toUpperCase();
|
|
206
196
|
|
|
207
197
|
// src/Lexer.ts
|
|
208
198
|
var basicTokens = {
|
|
@@ -383,7 +373,7 @@ var StreamLexer = class {
|
|
|
383
373
|
}
|
|
384
374
|
this._current += 1;
|
|
385
375
|
const literal = stream.slice(start + 1, this._current - 1);
|
|
386
|
-
return replace(
|
|
376
|
+
return literal.replace(/\\(['\\])/g, "$1");
|
|
387
377
|
}
|
|
388
378
|
consumeNumber(stream) {
|
|
389
379
|
const start = this._current;
|
|
@@ -548,14 +538,25 @@ var bindingPower = {
|
|
|
548
538
|
var TokenParser = class _TokenParser {
|
|
549
539
|
index = 0;
|
|
550
540
|
tokens = [];
|
|
541
|
+
depth = 0;
|
|
542
|
+
maxDepth;
|
|
543
|
+
nodeCount = 0;
|
|
544
|
+
maxNodes;
|
|
551
545
|
parse(expression, options) {
|
|
552
546
|
this.loadTokens(expression, options || { enable_legacy_literals: false });
|
|
553
547
|
this.index = 0;
|
|
548
|
+
this.depth = 0;
|
|
549
|
+
this.nodeCount = 0;
|
|
550
|
+
this.maxDepth = options?.maxDepth;
|
|
551
|
+
this.maxNodes = options?.maxNodes;
|
|
554
552
|
const ast = this.expression(0);
|
|
555
553
|
if (this.lookahead(0) !== "EOF" /* TOK_EOF */) {
|
|
556
554
|
const token = this.lookaheadToken(0);
|
|
557
555
|
this.errorToken(token, `Syntax error: unexpected token type: ${token.type}, value: ${token.value}`);
|
|
558
556
|
}
|
|
557
|
+
if (this.maxNodes !== void 0 && countNodes(ast) > this.maxNodes) {
|
|
558
|
+
throw new Error(`Expression exceeds maximum allowed node count of ${this.maxNodes}`);
|
|
559
|
+
}
|
|
559
560
|
return ast;
|
|
560
561
|
}
|
|
561
562
|
loadTokens(expression, options) {
|
|
@@ -563,16 +564,32 @@ var TokenParser = class _TokenParser {
|
|
|
563
564
|
this.tokens.push({ type: "EOF" /* TOK_EOF */, value: "", start: expression.length });
|
|
564
565
|
}
|
|
565
566
|
expression(rbp) {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
567
|
+
if (this.maxDepth !== void 0 && this.depth >= this.maxDepth) {
|
|
568
|
+
throw new Error(`Expression exceeds maximum allowed depth of ${this.maxDepth}`);
|
|
569
|
+
}
|
|
570
|
+
this.depth += 1;
|
|
571
|
+
this.trackNode();
|
|
572
|
+
try {
|
|
573
|
+
const leftToken = this.lookaheadToken(0);
|
|
571
574
|
this.advance();
|
|
572
|
-
left = this.
|
|
573
|
-
currentTokenType = this.lookahead(0);
|
|
575
|
+
let left = this.nud(leftToken);
|
|
576
|
+
let currentTokenType = this.lookahead(0);
|
|
577
|
+
while (rbp < bindingPower[currentTokenType]) {
|
|
578
|
+
this.trackNode();
|
|
579
|
+
this.advance();
|
|
580
|
+
left = this.led(currentTokenType, left);
|
|
581
|
+
currentTokenType = this.lookahead(0);
|
|
582
|
+
}
|
|
583
|
+
return left;
|
|
584
|
+
} finally {
|
|
585
|
+
this.depth -= 1;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
trackNode() {
|
|
589
|
+
this.nodeCount += 1;
|
|
590
|
+
if (this.maxNodes !== void 0 && this.nodeCount > this.maxNodes) {
|
|
591
|
+
throw new Error(`Expression exceeds maximum allowed node count of ${this.maxNodes}`);
|
|
574
592
|
}
|
|
575
|
-
return left;
|
|
576
593
|
}
|
|
577
594
|
lookahead(offset) {
|
|
578
595
|
return this.tokens[this.index + offset].type;
|
|
@@ -799,9 +816,13 @@ var TokenParser = class _TokenParser {
|
|
|
799
816
|
right
|
|
800
817
|
};
|
|
801
818
|
if (right.type === "Slice") {
|
|
819
|
+
const rhs = this.parseProjectionRHS(bindingPower.Star);
|
|
820
|
+
if (rhs.type === "Identity") {
|
|
821
|
+
return indexExpr;
|
|
822
|
+
}
|
|
802
823
|
return {
|
|
803
824
|
left: indexExpr,
|
|
804
|
-
right:
|
|
825
|
+
right: rhs,
|
|
805
826
|
type: "Projection"
|
|
806
827
|
};
|
|
807
828
|
}
|
|
@@ -961,6 +982,83 @@ var TokenParser = class _TokenParser {
|
|
|
961
982
|
var Parser = new TokenParser();
|
|
962
983
|
var Parser_default = Parser;
|
|
963
984
|
|
|
985
|
+
// src/utils/strings.ts
|
|
986
|
+
var findFirst = (subject, sub2, start, end) => {
|
|
987
|
+
if (!subject || !sub2) {
|
|
988
|
+
return null;
|
|
989
|
+
}
|
|
990
|
+
const s = Math.max(ensureInteger(start ?? 0), 0);
|
|
991
|
+
const e = Math.min(ensureInteger(end ?? subject.length), subject.length);
|
|
992
|
+
const offset = subject.slice(s, e).indexOf(sub2);
|
|
993
|
+
return offset === -1 ? null : offset + s;
|
|
994
|
+
};
|
|
995
|
+
var findLast = (subject, sub2, start, end) => {
|
|
996
|
+
if (!subject || !sub2) {
|
|
997
|
+
return null;
|
|
998
|
+
}
|
|
999
|
+
const s = Math.max(ensureInteger(start ?? 0), 0);
|
|
1000
|
+
const e = Math.min(ensureInteger(end ?? subject.length), subject.length);
|
|
1001
|
+
const offset = subject.slice(s, e).lastIndexOf(sub2);
|
|
1002
|
+
return offset === -1 ? null : offset + s;
|
|
1003
|
+
};
|
|
1004
|
+
var lower = (subject) => subject.toLowerCase();
|
|
1005
|
+
var ensurePadFuncParams = (name, width, padding = " ") => {
|
|
1006
|
+
if (padding.length > 1) {
|
|
1007
|
+
throw new Error(`invalid value, ${name} expects its 'pad' parameter to be a valid string with a single codepoint`);
|
|
1008
|
+
}
|
|
1009
|
+
ensurePositiveInteger(width);
|
|
1010
|
+
return padding;
|
|
1011
|
+
};
|
|
1012
|
+
var padLeft = (subject, width, padding) => {
|
|
1013
|
+
padding = ensurePadFuncParams("pad_left", width, padding);
|
|
1014
|
+
return subject && subject.padStart(width, padding) || "";
|
|
1015
|
+
};
|
|
1016
|
+
var padRight = (subject, width, padding) => {
|
|
1017
|
+
padding = ensurePadFuncParams("pad_right", width, padding);
|
|
1018
|
+
return subject && subject.padEnd(width, padding) || "";
|
|
1019
|
+
};
|
|
1020
|
+
var replace = (subject, string, by, count) => {
|
|
1021
|
+
if (count === 0) {
|
|
1022
|
+
return subject;
|
|
1023
|
+
}
|
|
1024
|
+
if (!count) {
|
|
1025
|
+
return subject.split(string).join(by);
|
|
1026
|
+
}
|
|
1027
|
+
ensurePositiveInteger(count);
|
|
1028
|
+
while (count-- > 0 && subject.includes(string)) {
|
|
1029
|
+
subject = subject.replace(string, by);
|
|
1030
|
+
}
|
|
1031
|
+
return subject;
|
|
1032
|
+
};
|
|
1033
|
+
var split = (subject, search2, count) => {
|
|
1034
|
+
if (subject.length == 0 && search2.length === 0) {
|
|
1035
|
+
return [];
|
|
1036
|
+
}
|
|
1037
|
+
if (count === null || count === void 0) {
|
|
1038
|
+
return subject.split(search2);
|
|
1039
|
+
}
|
|
1040
|
+
ensurePositiveInteger(count);
|
|
1041
|
+
if (count === 0) {
|
|
1042
|
+
return [subject];
|
|
1043
|
+
}
|
|
1044
|
+
const split2 = subject.split(search2);
|
|
1045
|
+
return [...split2.slice(0, count), split2.slice(count).join(search2)];
|
|
1046
|
+
};
|
|
1047
|
+
var trim = (subject, chars) => {
|
|
1048
|
+
return trimLeft(trimRight(subject, chars), chars);
|
|
1049
|
+
};
|
|
1050
|
+
var trimLeft = (subject, chars) => {
|
|
1051
|
+
return trimImpl(subject, (list) => new RegExp(`^[${list}]*(.*?)`), chars);
|
|
1052
|
+
};
|
|
1053
|
+
var trimRight = (subject, chars) => {
|
|
1054
|
+
return trimImpl(subject, (list) => new RegExp(`(.*?)[${list}]*$`), chars);
|
|
1055
|
+
};
|
|
1056
|
+
var trimImpl = (subject, regExper, chars) => {
|
|
1057
|
+
const pattern = chars ? chars.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&") : "\\s\x85";
|
|
1058
|
+
return subject.replace(regExper(pattern), "$1");
|
|
1059
|
+
};
|
|
1060
|
+
var upper = (subject) => subject.toUpperCase();
|
|
1061
|
+
|
|
964
1062
|
// src/utils/text.ts
|
|
965
1063
|
var Text = class _Text {
|
|
966
1064
|
_text;
|
|
@@ -971,7 +1069,11 @@ var Text = class _Text {
|
|
|
971
1069
|
return this._text;
|
|
972
1070
|
}
|
|
973
1071
|
get length() {
|
|
974
|
-
|
|
1072
|
+
let count = 0;
|
|
1073
|
+
for (const _ of this._text) {
|
|
1074
|
+
count += 1;
|
|
1075
|
+
}
|
|
1076
|
+
return count;
|
|
975
1077
|
}
|
|
976
1078
|
compareTo(other) {
|
|
977
1079
|
return _Text.compare(this, new _Text(other));
|
|
@@ -1006,6 +1108,12 @@ var Text = class _Text {
|
|
|
1006
1108
|
var createMathFunction = (mathFn) => ([value]) => mathFn(value);
|
|
1007
1109
|
var createStringFunction = (stringFn) => ([subject]) => stringFn(subject);
|
|
1008
1110
|
var createObjectFunction = (objFn) => ([obj]) => objFn(obj);
|
|
1111
|
+
var ARRAY_SUBTYPES = {
|
|
1112
|
+
[8 /* TYPE_ARRAY_NUMBER */]: 0 /* TYPE_NUMBER */,
|
|
1113
|
+
[10 /* TYPE_ARRAY_OBJECT */]: 4 /* TYPE_OBJECT */,
|
|
1114
|
+
[9 /* TYPE_ARRAY_STRING */]: 2 /* TYPE_STRING */,
|
|
1115
|
+
[11 /* TYPE_ARRAY_ARRAY */]: 3 /* TYPE_ARRAY */
|
|
1116
|
+
};
|
|
1009
1117
|
var Runtime = class {
|
|
1010
1118
|
_interpreter;
|
|
1011
1119
|
_functionTable;
|
|
@@ -1323,34 +1431,18 @@ var Runtime = class {
|
|
|
1323
1431
|
if (expected === 1 /* TYPE_ANY */) {
|
|
1324
1432
|
return true;
|
|
1325
1433
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
if (actual === 3 /* TYPE_ARRAY */) {
|
|
1331
|
-
let subtype;
|
|
1332
|
-
if (expected === 8 /* TYPE_ARRAY_NUMBER */) {
|
|
1333
|
-
subtype = 0 /* TYPE_NUMBER */;
|
|
1334
|
-
} else if (expected === 10 /* TYPE_ARRAY_OBJECT */) {
|
|
1335
|
-
subtype = 4 /* TYPE_OBJECT */;
|
|
1336
|
-
} else if (expected === 9 /* TYPE_ARRAY_STRING */) {
|
|
1337
|
-
subtype = 2 /* TYPE_STRING */;
|
|
1338
|
-
} else if (expected === 11 /* TYPE_ARRAY_ARRAY */) {
|
|
1339
|
-
subtype = 3 /* TYPE_ARRAY */;
|
|
1340
|
-
}
|
|
1341
|
-
const array = argValue;
|
|
1342
|
-
for (let i = 0; i < array.length; i += 1) {
|
|
1343
|
-
const typeName = this.getTypeName(array[i]);
|
|
1344
|
-
if (typeName !== void 0 && subtype !== void 0 && !this.typeMatches(typeName, subtype, array[i])) {
|
|
1345
|
-
return false;
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
return true;
|
|
1434
|
+
const subtype = ARRAY_SUBTYPES[expected];
|
|
1435
|
+
if (subtype !== void 0) {
|
|
1436
|
+
if (actual !== 3 /* TYPE_ARRAY */) {
|
|
1437
|
+
return false;
|
|
1349
1438
|
}
|
|
1350
|
-
|
|
1351
|
-
return
|
|
1439
|
+
const array = argValue;
|
|
1440
|
+
return array.every((item) => {
|
|
1441
|
+
const typeName = this.getTypeName(item);
|
|
1442
|
+
return typeName === void 0 || this.typeMatches(typeName, subtype, item);
|
|
1443
|
+
});
|
|
1352
1444
|
}
|
|
1353
|
-
return
|
|
1445
|
+
return actual === expected;
|
|
1354
1446
|
}
|
|
1355
1447
|
getTypeName(obj) {
|
|
1356
1448
|
if (obj === null) {
|
|
@@ -1414,9 +1506,8 @@ var Runtime = class {
|
|
|
1414
1506
|
}
|
|
1415
1507
|
return null;
|
|
1416
1508
|
};
|
|
1417
|
-
functionEndsWith = (
|
|
1418
|
-
|
|
1419
|
-
return searchStr.includes(suffix, searchStr.length - suffix.length);
|
|
1509
|
+
functionEndsWith = ([searchStr, suffix]) => {
|
|
1510
|
+
return searchStr.endsWith(suffix);
|
|
1420
1511
|
};
|
|
1421
1512
|
functionFindFirst = this.createFindFunction(findFirst);
|
|
1422
1513
|
functionFindLast = this.createFindFunction(findLast);
|
|
@@ -1430,21 +1521,24 @@ var Runtime = class {
|
|
|
1430
1521
|
};
|
|
1431
1522
|
}
|
|
1432
1523
|
functionFromItems = ([array]) => {
|
|
1433
|
-
|
|
1434
|
-
if (pair.length
|
|
1524
|
+
for (const pair of array) {
|
|
1525
|
+
if (pair.length !== 2 || typeof pair[0] !== "string") {
|
|
1435
1526
|
throw new Error("invalid value, each array must contain two elements, a pair of string and value");
|
|
1436
1527
|
}
|
|
1437
|
-
}
|
|
1528
|
+
}
|
|
1438
1529
|
return Object.fromEntries(array);
|
|
1439
1530
|
};
|
|
1440
1531
|
functionGroupBy = ([array, exprefNode]) => {
|
|
1441
1532
|
const keyFunction = this.createKeyFunction(exprefNode, [2 /* TYPE_STRING */]);
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
const
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1533
|
+
const groups = {};
|
|
1534
|
+
for (const item of array) {
|
|
1535
|
+
const key = keyFunction(item);
|
|
1536
|
+
if (!groups[key]) {
|
|
1537
|
+
groups[key] = [];
|
|
1538
|
+
}
|
|
1539
|
+
groups[key].push(item);
|
|
1540
|
+
}
|
|
1541
|
+
return groups;
|
|
1448
1542
|
};
|
|
1449
1543
|
functionItems = ([inputValue]) => {
|
|
1450
1544
|
return Object.entries(inputValue);
|
|
@@ -1507,12 +1601,7 @@ var Runtime = class {
|
|
|
1507
1601
|
return maxRecord || null;
|
|
1508
1602
|
};
|
|
1509
1603
|
functionMerge = (resolvedArgs) => {
|
|
1510
|
-
|
|
1511
|
-
for (let i = 0; i < resolvedArgs.length; i += 1) {
|
|
1512
|
-
const current = resolvedArgs[i];
|
|
1513
|
-
merged = Object.assign(merged, current);
|
|
1514
|
-
}
|
|
1515
|
-
return merged;
|
|
1604
|
+
return Object.assign({}, ...resolvedArgs);
|
|
1516
1605
|
};
|
|
1517
1606
|
functionMin = ([inputValue]) => {
|
|
1518
1607
|
if (!inputValue.length) {
|
|
@@ -1548,12 +1637,7 @@ var Runtime = class {
|
|
|
1548
1637
|
return minRecord || null;
|
|
1549
1638
|
};
|
|
1550
1639
|
functionNotNull = (resolvedArgs) => {
|
|
1551
|
-
|
|
1552
|
-
if (this.getTypeName(resolvedArgs[i]) !== 7 /* TYPE_NULL */) {
|
|
1553
|
-
return resolvedArgs[i];
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
return null;
|
|
1640
|
+
return resolvedArgs.find((arg) => arg !== null) ?? null;
|
|
1557
1641
|
};
|
|
1558
1642
|
functionPadLeft = this.createPadFunction(padLeft);
|
|
1559
1643
|
functionPadRight = this.createPadFunction(padRight);
|
|
@@ -1581,12 +1665,12 @@ var Runtime = class {
|
|
|
1581
1665
|
if (typeName === 2 /* TYPE_STRING */) {
|
|
1582
1666
|
return new Text(inputValue).reverse();
|
|
1583
1667
|
}
|
|
1584
|
-
const reversedArray = inputValue
|
|
1668
|
+
const reversedArray = [...inputValue];
|
|
1585
1669
|
reversedArray.reverse();
|
|
1586
1670
|
return reversedArray;
|
|
1587
1671
|
};
|
|
1588
1672
|
functionSort = ([inputValue]) => {
|
|
1589
|
-
if (inputValue.length
|
|
1673
|
+
if (inputValue.length <= 1) {
|
|
1590
1674
|
return inputValue;
|
|
1591
1675
|
}
|
|
1592
1676
|
if (typeof inputValue[0] === "string") {
|
|
@@ -1595,8 +1679,8 @@ var Runtime = class {
|
|
|
1595
1679
|
return [...inputValue].sort();
|
|
1596
1680
|
};
|
|
1597
1681
|
functionSortBy = (resolvedArgs) => {
|
|
1598
|
-
const sortedArray = resolvedArgs[0]
|
|
1599
|
-
if (sortedArray.length
|
|
1682
|
+
const sortedArray = [...resolvedArgs[0]];
|
|
1683
|
+
if (sortedArray.length <= 1) {
|
|
1600
1684
|
return sortedArray;
|
|
1601
1685
|
}
|
|
1602
1686
|
const interpreter = this._interpreter;
|
|
@@ -1631,10 +1715,7 @@ var Runtime = class {
|
|
|
1631
1715
|
return inputValue.reduce((x, y) => x + y, 0);
|
|
1632
1716
|
};
|
|
1633
1717
|
functionToArray = ([inputValue]) => {
|
|
1634
|
-
|
|
1635
|
-
return inputValue;
|
|
1636
|
-
}
|
|
1637
|
-
return [inputValue];
|
|
1718
|
+
return Array.isArray(inputValue) ? inputValue : [inputValue];
|
|
1638
1719
|
};
|
|
1639
1720
|
functionToNumber = ([inputValue]) => {
|
|
1640
1721
|
const typeName = this.getTypeName(inputValue);
|
|
@@ -1651,10 +1732,7 @@ var Runtime = class {
|
|
|
1651
1732
|
return null;
|
|
1652
1733
|
};
|
|
1653
1734
|
functionToString = ([inputValue]) => {
|
|
1654
|
-
|
|
1655
|
-
return inputValue;
|
|
1656
|
-
}
|
|
1657
|
-
return JSON.stringify(inputValue);
|
|
1735
|
+
return typeof inputValue === "string" ? inputValue : JSON.stringify(inputValue);
|
|
1658
1736
|
};
|
|
1659
1737
|
functionTrim = this.createTrimFunction(trim);
|
|
1660
1738
|
functionTrimLeft = this.createTrimFunction(trimLeft);
|
|
@@ -1667,27 +1745,16 @@ var Runtime = class {
|
|
|
1667
1745
|
};
|
|
1668
1746
|
}
|
|
1669
1747
|
functionType = ([inputValue]) => {
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
return "string";
|
|
1675
|
-
case 3 /* TYPE_ARRAY */:
|
|
1676
|
-
return "array";
|
|
1677
|
-
case 4 /* TYPE_OBJECT */:
|
|
1678
|
-
return "object";
|
|
1679
|
-
case 5 /* TYPE_BOOLEAN */:
|
|
1680
|
-
return "boolean";
|
|
1681
|
-
case 7 /* TYPE_NULL */:
|
|
1682
|
-
return "null";
|
|
1683
|
-
default:
|
|
1684
|
-
throw new Error("invalid-type");
|
|
1748
|
+
const type = this.getTypeName(inputValue);
|
|
1749
|
+
const name = type !== void 0 ? this.TYPE_NAME_TABLE[type] : void 0;
|
|
1750
|
+
if (!name) {
|
|
1751
|
+
throw new Error("invalid-type");
|
|
1685
1752
|
}
|
|
1753
|
+
return name;
|
|
1686
1754
|
};
|
|
1687
1755
|
functionZip = (array) => {
|
|
1688
1756
|
const length = Math.min(...array.map((arr) => arr.length));
|
|
1689
|
-
|
|
1690
|
-
return result;
|
|
1757
|
+
return Array.from({ length }, (_, index) => array.map((arr) => arr[index]));
|
|
1691
1758
|
};
|
|
1692
1759
|
};
|
|
1693
1760
|
|
|
@@ -1721,23 +1788,108 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
1721
1788
|
runtime;
|
|
1722
1789
|
_rootValue = null;
|
|
1723
1790
|
_scope;
|
|
1724
|
-
|
|
1791
|
+
_options;
|
|
1792
|
+
_depth = 0;
|
|
1793
|
+
_deadline = 0;
|
|
1794
|
+
constructor(options) {
|
|
1725
1795
|
this.runtime = new Runtime(this);
|
|
1726
1796
|
this._scope = new ScopeChain();
|
|
1797
|
+
if (options) {
|
|
1798
|
+
this._options = options;
|
|
1799
|
+
this._deadline = options.timeoutMs !== void 0 ? Date.now() + options.timeoutMs : 0;
|
|
1800
|
+
}
|
|
1727
1801
|
}
|
|
1728
1802
|
withScope(scope) {
|
|
1729
|
-
const interpreter = new _TreeInterpreter();
|
|
1803
|
+
const interpreter = new _TreeInterpreter(this._options);
|
|
1730
1804
|
interpreter.runtime._functionTable = this.runtime._functionTable;
|
|
1731
1805
|
interpreter._rootValue = this._rootValue;
|
|
1732
1806
|
interpreter._scope = this._scope.withScope(scope);
|
|
1807
|
+
interpreter._depth = this._depth;
|
|
1808
|
+
interpreter._deadline = this._deadline;
|
|
1733
1809
|
return interpreter;
|
|
1734
1810
|
}
|
|
1735
|
-
search(node, value) {
|
|
1811
|
+
search(node, value, options) {
|
|
1812
|
+
if (options?.maxNodes !== void 0 && countNodes(node) > options.maxNodes) {
|
|
1813
|
+
throw new Error(`Expression exceeds maximum allowed node count of ${options.maxNodes}`);
|
|
1814
|
+
}
|
|
1736
1815
|
this._rootValue = value;
|
|
1737
1816
|
this._scope = emptyScopeChain;
|
|
1738
|
-
|
|
1817
|
+
this._options = options;
|
|
1818
|
+
this._depth = 0;
|
|
1819
|
+
this._deadline = options?.timeoutMs !== void 0 ? Date.now() + options.timeoutMs : 0;
|
|
1820
|
+
const result = this.visit(node, value);
|
|
1821
|
+
this.checkOutputSize(result);
|
|
1822
|
+
return result;
|
|
1823
|
+
}
|
|
1824
|
+
checkOutputSize(val) {
|
|
1825
|
+
const max = this._options?.maxOutputSize;
|
|
1826
|
+
if (max === void 0 || val == null) {
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
const size = Array.isArray(val) || typeof val === "string" ? val.length : typeof val === "object" ? Object.keys(val).length : 0;
|
|
1830
|
+
if (size > max) {
|
|
1831
|
+
throw new Error(`Output size exceeds maximum allowed size of ${max}`);
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
collect(target, item) {
|
|
1835
|
+
target.push(item);
|
|
1836
|
+
if (this._options?.maxOutputSize !== void 0 && target.length > this._options.maxOutputSize) {
|
|
1837
|
+
throw new Error(`Output size exceeds maximum allowed size of ${this._options.maxOutputSize}`);
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
evaluateProjectionItems(items, right) {
|
|
1841
|
+
const collected = [];
|
|
1842
|
+
if (right.type === "Field") {
|
|
1843
|
+
const key = right.name;
|
|
1844
|
+
for (let i = 0; i < items.length; i++) {
|
|
1845
|
+
if (this._deadline > 0 && Date.now() >= this._deadline) {
|
|
1846
|
+
throw new Error(`Query execution timed out after ${this._options?.timeoutMs}ms`);
|
|
1847
|
+
}
|
|
1848
|
+
const elem = items[i];
|
|
1849
|
+
if (!elem || typeof elem !== "object" || Array.isArray(elem)) {
|
|
1850
|
+
continue;
|
|
1851
|
+
}
|
|
1852
|
+
const val = elem[key];
|
|
1853
|
+
if (val !== void 0 && val !== null) {
|
|
1854
|
+
this.collect(collected, val);
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
return collected;
|
|
1858
|
+
}
|
|
1859
|
+
if (right.type === "Identity") {
|
|
1860
|
+
for (let i = 0; i < items.length; i++) {
|
|
1861
|
+
const elem = items[i];
|
|
1862
|
+
if (elem !== null) {
|
|
1863
|
+
this.collect(collected, elem);
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
return collected;
|
|
1867
|
+
}
|
|
1868
|
+
for (const elem of items) {
|
|
1869
|
+
const current = this.visit(right, elem);
|
|
1870
|
+
if (current !== null) {
|
|
1871
|
+
this.collect(collected, current);
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
return collected;
|
|
1739
1875
|
}
|
|
1740
1876
|
visit(node, value) {
|
|
1877
|
+
if (this._options) {
|
|
1878
|
+
if (this._options.maxDepth !== void 0 && this._depth >= this._options.maxDepth) {
|
|
1879
|
+
throw new Error(`Evaluation exceeds maximum allowed depth of ${this._options.maxDepth}`);
|
|
1880
|
+
}
|
|
1881
|
+
if (this._deadline > 0 && Date.now() >= this._deadline) {
|
|
1882
|
+
throw new Error(`Query execution timed out after ${this._options.timeoutMs}ms`);
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
this._depth += 1;
|
|
1886
|
+
try {
|
|
1887
|
+
return this.evaluateNode(node, value);
|
|
1888
|
+
} finally {
|
|
1889
|
+
this._depth -= 1;
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
evaluateNode(node, value) {
|
|
1741
1893
|
switch (node.type) {
|
|
1742
1894
|
case "Ternary": {
|
|
1743
1895
|
const condition = this.visit(node.condition, value);
|
|
@@ -1753,16 +1905,11 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
1753
1905
|
}
|
|
1754
1906
|
return value[identifier] ?? null;
|
|
1755
1907
|
case "LetExpression": {
|
|
1756
|
-
const
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
...scope,
|
|
1762
|
-
...reference
|
|
1763
|
-
};
|
|
1764
|
-
});
|
|
1765
|
-
return this.withScope(scope).visit(expression, value);
|
|
1908
|
+
const scope = {};
|
|
1909
|
+
for (const binding of node.bindings) {
|
|
1910
|
+
Object.assign(scope, this.visit(binding, value));
|
|
1911
|
+
}
|
|
1912
|
+
return this.withScope(scope).visit(node.expression, value);
|
|
1766
1913
|
}
|
|
1767
1914
|
case "Binding": {
|
|
1768
1915
|
const { variable, reference } = node;
|
|
@@ -1794,51 +1941,27 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
1794
1941
|
return null;
|
|
1795
1942
|
}
|
|
1796
1943
|
const { start, stop, step } = this.computeSliceParams(value.length, node);
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
return this.slice(value, start, stop, step);
|
|
1803
|
-
}
|
|
1944
|
+
const target = typeof value === "string" ? [...value] : value;
|
|
1945
|
+
const sliced = this.slice(target, start, stop, step);
|
|
1946
|
+
const res = typeof value === "string" ? sliced.join("") : sliced;
|
|
1947
|
+
this.checkOutputSize(res);
|
|
1948
|
+
return res;
|
|
1804
1949
|
}
|
|
1805
1950
|
case "Projection": {
|
|
1806
1951
|
const { left, right } = node;
|
|
1807
|
-
|
|
1808
|
-
if (left.type === "IndexExpression" && left.right.type === "Slice") {
|
|
1809
|
-
allowString = true;
|
|
1810
|
-
}
|
|
1952
|
+
const allowString = left.type === "IndexExpression" && left.right.type === "Slice";
|
|
1811
1953
|
const base = this.visit(left, value);
|
|
1812
1954
|
if (allowString && typeof base === "string") {
|
|
1813
1955
|
return this.visit(right, base);
|
|
1814
1956
|
}
|
|
1815
|
-
|
|
1816
|
-
return null;
|
|
1817
|
-
}
|
|
1818
|
-
const collected = [];
|
|
1819
|
-
for (const elem of base) {
|
|
1820
|
-
const current = this.visit(right, elem);
|
|
1821
|
-
if (current !== null) {
|
|
1822
|
-
collected.push(current);
|
|
1823
|
-
}
|
|
1824
|
-
}
|
|
1825
|
-
return collected;
|
|
1957
|
+
return Array.isArray(base) ? this.evaluateProjectionItems(base, right) : null;
|
|
1826
1958
|
}
|
|
1827
1959
|
case "ValueProjection": {
|
|
1828
|
-
const
|
|
1829
|
-
const base = this.visit(left, value);
|
|
1960
|
+
const base = this.visit(node.left, value);
|
|
1830
1961
|
if (base === null || typeof base !== "object" || Array.isArray(base)) {
|
|
1831
1962
|
return null;
|
|
1832
1963
|
}
|
|
1833
|
-
|
|
1834
|
-
const values = Object.values(base);
|
|
1835
|
-
for (const elem of values) {
|
|
1836
|
-
const current = this.visit(right, elem);
|
|
1837
|
-
if (current !== null) {
|
|
1838
|
-
collected.push(current);
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
return collected;
|
|
1964
|
+
return this.evaluateProjectionItems(Object.values(base), node.right);
|
|
1842
1965
|
}
|
|
1843
1966
|
case "FilterProjection": {
|
|
1844
1967
|
const { left, right, condition } = node;
|
|
@@ -1847,14 +1970,42 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
1847
1970
|
return null;
|
|
1848
1971
|
}
|
|
1849
1972
|
const results = [];
|
|
1973
|
+
if (right.type === "Field") {
|
|
1974
|
+
const key = right.name;
|
|
1975
|
+
for (let i = 0; i < base.length; i++) {
|
|
1976
|
+
const elem = base[i];
|
|
1977
|
+
if (isFalse(this.visit(condition, elem))) {
|
|
1978
|
+
continue;
|
|
1979
|
+
}
|
|
1980
|
+
if (!elem || typeof elem !== "object" || Array.isArray(elem)) {
|
|
1981
|
+
continue;
|
|
1982
|
+
}
|
|
1983
|
+
const val = elem[key];
|
|
1984
|
+
if (val !== void 0 && val !== null) {
|
|
1985
|
+
this.collect(results, val);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
return results;
|
|
1989
|
+
}
|
|
1990
|
+
if (right.type === "Identity") {
|
|
1991
|
+
for (let i = 0; i < base.length; i++) {
|
|
1992
|
+
const elem = base[i];
|
|
1993
|
+
if (isFalse(this.visit(condition, elem))) {
|
|
1994
|
+
continue;
|
|
1995
|
+
}
|
|
1996
|
+
if (elem !== null) {
|
|
1997
|
+
this.collect(results, elem);
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
return results;
|
|
2001
|
+
}
|
|
1850
2002
|
for (const elem of base) {
|
|
1851
|
-
|
|
1852
|
-
if (isFalse(matched)) {
|
|
2003
|
+
if (isFalse(this.visit(condition, elem))) {
|
|
1853
2004
|
continue;
|
|
1854
2005
|
}
|
|
1855
2006
|
const result = this.visit(right, elem);
|
|
1856
2007
|
if (result !== null) {
|
|
1857
|
-
|
|
2008
|
+
this.collect(results, result);
|
|
1858
2009
|
}
|
|
1859
2010
|
}
|
|
1860
2011
|
return results;
|
|
@@ -1918,7 +2069,9 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
1918
2069
|
}
|
|
1919
2070
|
case "Flatten": {
|
|
1920
2071
|
const original = this.visit(node.child, value);
|
|
1921
|
-
|
|
2072
|
+
const res = Array.isArray(original) ? original.flat() : null;
|
|
2073
|
+
this.checkOutputSize(res);
|
|
2074
|
+
return res;
|
|
1922
2075
|
}
|
|
1923
2076
|
case "Root":
|
|
1924
2077
|
return this._rootValue;
|
|
@@ -1927,6 +2080,7 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
1927
2080
|
for (const child of node.children) {
|
|
1928
2081
|
collected.push(this.visit(child, value));
|
|
1929
2082
|
}
|
|
2083
|
+
this.checkOutputSize(collected);
|
|
1930
2084
|
return collected;
|
|
1931
2085
|
}
|
|
1932
2086
|
case "MultiSelectHash": {
|
|
@@ -1934,6 +2088,7 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
1934
2088
|
for (const child of node.children) {
|
|
1935
2089
|
collected[child.name] = this.visit(child.value, value);
|
|
1936
2090
|
}
|
|
2091
|
+
this.checkOutputSize(collected);
|
|
1937
2092
|
return collected;
|
|
1938
2093
|
}
|
|
1939
2094
|
case "OrExpression": {
|
|
@@ -1957,11 +2112,19 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
1957
2112
|
case "Pipe":
|
|
1958
2113
|
return this.visit(node.right, this.visit(node.left, value));
|
|
1959
2114
|
case "Function": {
|
|
2115
|
+
if (this._options?.allowedFunctions && !this._options.allowedFunctions.includes(node.name)) {
|
|
2116
|
+
throw new Error(`Function '${node.name}' is not allowed`);
|
|
2117
|
+
}
|
|
2118
|
+
if (this._options?.disallowedFunctions && this._options.disallowedFunctions.includes(node.name)) {
|
|
2119
|
+
throw new Error(`Function '${node.name}' is disallowed`);
|
|
2120
|
+
}
|
|
1960
2121
|
const args = [];
|
|
1961
2122
|
for (const child of node.children) {
|
|
1962
2123
|
args.push(this.visit(child, value));
|
|
1963
2124
|
}
|
|
1964
|
-
|
|
2125
|
+
const res = this.runtime.callFunction(node.name, args);
|
|
2126
|
+
this.checkOutputSize(res);
|
|
2127
|
+
return res;
|
|
1965
2128
|
}
|
|
1966
2129
|
case "ExpressionReference":
|
|
1967
2130
|
return {
|
|
@@ -1999,14 +2162,19 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
1999
2162
|
return nextActualValue;
|
|
2000
2163
|
}
|
|
2001
2164
|
slice(collection, start, end, step) {
|
|
2002
|
-
|
|
2165
|
+
if (step === 1) {
|
|
2166
|
+
return collection.slice(start, end);
|
|
2167
|
+
}
|
|
2168
|
+
const len = Math.ceil(Math.abs(start - end) / Math.abs(step));
|
|
2169
|
+
const result = new Array(len);
|
|
2170
|
+
let idx = 0;
|
|
2003
2171
|
if (step > 0) {
|
|
2004
2172
|
for (let i = start; i < end; i += step) {
|
|
2005
|
-
result
|
|
2173
|
+
result[idx++] = collection[i];
|
|
2006
2174
|
}
|
|
2007
2175
|
} else {
|
|
2008
2176
|
for (let i = start; i > end; i += step) {
|
|
2009
|
-
result
|
|
2177
|
+
result[idx++] = collection[i];
|
|
2010
2178
|
}
|
|
2011
2179
|
}
|
|
2012
2180
|
return result;
|
|
@@ -2015,6 +2183,391 @@ var TreeInterpreter = class _TreeInterpreter {
|
|
|
2015
2183
|
var TreeInterpreterInstance = new TreeInterpreter();
|
|
2016
2184
|
var TreeInterpreter_default = TreeInterpreterInstance;
|
|
2017
2185
|
|
|
2186
|
+
// src/Stream.ts
|
|
2187
|
+
async function* toAsyncIterable(source) {
|
|
2188
|
+
if (source == null) {
|
|
2189
|
+
return;
|
|
2190
|
+
}
|
|
2191
|
+
if (typeof source !== "object" && typeof source !== "function") {
|
|
2192
|
+
throw new TypeError("Invalid stream source: expected AsyncIterable, Iterable, or ReadableStream");
|
|
2193
|
+
}
|
|
2194
|
+
if (Symbol.asyncIterator in source) {
|
|
2195
|
+
for await (const chunk of source) {
|
|
2196
|
+
yield chunk;
|
|
2197
|
+
}
|
|
2198
|
+
return;
|
|
2199
|
+
}
|
|
2200
|
+
if (typeof source.getReader === "function") {
|
|
2201
|
+
const reader = source.getReader();
|
|
2202
|
+
try {
|
|
2203
|
+
while (true) {
|
|
2204
|
+
const { done, value } = await reader.read();
|
|
2205
|
+
if (done) {
|
|
2206
|
+
break;
|
|
2207
|
+
}
|
|
2208
|
+
yield value;
|
|
2209
|
+
}
|
|
2210
|
+
} finally {
|
|
2211
|
+
reader.releaseLock();
|
|
2212
|
+
}
|
|
2213
|
+
return;
|
|
2214
|
+
}
|
|
2215
|
+
if (Symbol.iterator in source) {
|
|
2216
|
+
for (const chunk of source) {
|
|
2217
|
+
yield chunk;
|
|
2218
|
+
}
|
|
2219
|
+
return;
|
|
2220
|
+
}
|
|
2221
|
+
throw new TypeError("Invalid stream source: expected AsyncIterable, Iterable, or ReadableStream");
|
|
2222
|
+
}
|
|
2223
|
+
function parseItem(str, parseJson) {
|
|
2224
|
+
if (parseJson === true) {
|
|
2225
|
+
return JSON.parse(str);
|
|
2226
|
+
}
|
|
2227
|
+
if (parseJson === "auto") {
|
|
2228
|
+
try {
|
|
2229
|
+
return JSON.parse(str);
|
|
2230
|
+
} catch {
|
|
2231
|
+
return str;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
return str;
|
|
2235
|
+
}
|
|
2236
|
+
async function* normalizeSource(source, options) {
|
|
2237
|
+
const parseJson = options?.parseJson ?? "auto";
|
|
2238
|
+
const flatten = options?.flattenChunks ?? true;
|
|
2239
|
+
let buffer = "";
|
|
2240
|
+
const textDecoder = typeof TextDecoder !== "undefined" ? new TextDecoder() : null;
|
|
2241
|
+
for await (const chunk of toAsyncIterable(source)) {
|
|
2242
|
+
if (chunk instanceof Uint8Array && textDecoder) {
|
|
2243
|
+
buffer += textDecoder.decode(chunk, { stream: true });
|
|
2244
|
+
if (buffer.includes("\n")) {
|
|
2245
|
+
const lines = buffer.split("\n");
|
|
2246
|
+
buffer = lines.pop() ?? "";
|
|
2247
|
+
for (const line of lines) {
|
|
2248
|
+
const trimmed = line.trim();
|
|
2249
|
+
if (trimmed) {
|
|
2250
|
+
yield parseItem(trimmed, parseJson);
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
} else if (typeof chunk === "string") {
|
|
2255
|
+
if (parseJson === false) {
|
|
2256
|
+
yield chunk;
|
|
2257
|
+
} else {
|
|
2258
|
+
buffer += chunk;
|
|
2259
|
+
if (buffer.includes("\n")) {
|
|
2260
|
+
const lines = buffer.split("\n");
|
|
2261
|
+
buffer = lines.pop() ?? "";
|
|
2262
|
+
for (const line of lines) {
|
|
2263
|
+
const trimmed = line.trim();
|
|
2264
|
+
if (trimmed) {
|
|
2265
|
+
yield parseItem(trimmed, parseJson);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
} else if (flatten && Array.isArray(chunk)) {
|
|
2271
|
+
if (buffer.trim()) {
|
|
2272
|
+
yield parseItem(buffer.trim(), parseJson);
|
|
2273
|
+
buffer = "";
|
|
2274
|
+
}
|
|
2275
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
2276
|
+
yield chunk[i];
|
|
2277
|
+
}
|
|
2278
|
+
} else {
|
|
2279
|
+
if (buffer.trim()) {
|
|
2280
|
+
yield parseItem(buffer.trim(), parseJson);
|
|
2281
|
+
buffer = "";
|
|
2282
|
+
}
|
|
2283
|
+
yield chunk;
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
if (textDecoder && buffer) {
|
|
2287
|
+
buffer += textDecoder.decode();
|
|
2288
|
+
}
|
|
2289
|
+
if (buffer.trim()) {
|
|
2290
|
+
yield parseItem(buffer.trim(), parseJson);
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
function isStreamableNode(node) {
|
|
2294
|
+
switch (node.type) {
|
|
2295
|
+
case "Projection":
|
|
2296
|
+
if (node.left.type === "Identity" || node.left.type === "Current") {
|
|
2297
|
+
return true;
|
|
2298
|
+
}
|
|
2299
|
+
if (node.left.type === "IndexExpression" && node.left.right.type === "Slice") {
|
|
2300
|
+
const slice = node.left.right;
|
|
2301
|
+
return (slice.start === null || slice.start >= 0) && (slice.stop === null || slice.stop >= 0) && (slice.step === null || slice.step > 0);
|
|
2302
|
+
}
|
|
2303
|
+
return false;
|
|
2304
|
+
case "FilterProjection":
|
|
2305
|
+
return node.left.type === "Identity" || node.left.type === "Current";
|
|
2306
|
+
case "IndexExpression":
|
|
2307
|
+
if (node.right.type === "Slice" && (node.left.type === "Identity" || node.left.type === "Current")) {
|
|
2308
|
+
const slice = node.right;
|
|
2309
|
+
return (slice.start === null || slice.start >= 0) && (slice.stop === null || slice.stop >= 0) && (slice.step === null || slice.step > 0);
|
|
2310
|
+
}
|
|
2311
|
+
return true;
|
|
2312
|
+
case "Field":
|
|
2313
|
+
case "Identity":
|
|
2314
|
+
case "Current":
|
|
2315
|
+
case "Subexpression":
|
|
2316
|
+
case "MultiSelectHash":
|
|
2317
|
+
case "MultiSelectList":
|
|
2318
|
+
case "Ternary":
|
|
2319
|
+
case "Comparator":
|
|
2320
|
+
case "Arithmetic":
|
|
2321
|
+
case "NotExpression":
|
|
2322
|
+
return true;
|
|
2323
|
+
case "Pipe":
|
|
2324
|
+
return isStreamableNode(node.left) && isStreamableNode(node.right);
|
|
2325
|
+
default:
|
|
2326
|
+
return false;
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
async function* evaluateStreamNode(source, node, interpreter, options) {
|
|
2330
|
+
const deadline = options?.timeoutMs !== void 0 ? Date.now() + options.timeoutMs : 0;
|
|
2331
|
+
function checkDeadline() {
|
|
2332
|
+
if (deadline > 0 && Date.now() >= deadline) {
|
|
2333
|
+
throw new Error(`Query execution timed out after ${options?.timeoutMs}ms`);
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
switch (node.type) {
|
|
2337
|
+
case "Projection": {
|
|
2338
|
+
const { left, right } = node;
|
|
2339
|
+
let streamSource = source;
|
|
2340
|
+
if (left.type === "IndexExpression" && left.right.type === "Slice") {
|
|
2341
|
+
streamSource = evaluateStreamNode(source, left, interpreter, options);
|
|
2342
|
+
}
|
|
2343
|
+
if (right.type === "Identity" || right.type === "Current") {
|
|
2344
|
+
for await (const item of streamSource) {
|
|
2345
|
+
checkDeadline();
|
|
2346
|
+
if (item !== null && item !== void 0) {
|
|
2347
|
+
yield item;
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
if (right.type === "Field") {
|
|
2353
|
+
const key = right.name;
|
|
2354
|
+
for await (const item of streamSource) {
|
|
2355
|
+
checkDeadline();
|
|
2356
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
2357
|
+
const val = item[key];
|
|
2358
|
+
if (val !== void 0 && val !== null) {
|
|
2359
|
+
yield val;
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
return;
|
|
2364
|
+
}
|
|
2365
|
+
for await (const item of streamSource) {
|
|
2366
|
+
checkDeadline();
|
|
2367
|
+
const res = interpreter.visit(right, item);
|
|
2368
|
+
if (res !== null && res !== void 0) {
|
|
2369
|
+
yield res;
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
case "IndexExpression": {
|
|
2375
|
+
if (node.right.type === "Slice" && (node.left.type === "Identity" || node.left.type === "Current")) {
|
|
2376
|
+
const slice = node.right;
|
|
2377
|
+
const start = slice.start ?? 0;
|
|
2378
|
+
const stop = slice.stop ?? Infinity;
|
|
2379
|
+
const step = slice.step ?? 1;
|
|
2380
|
+
if (start >= 0 && stop >= 0 && step > 0) {
|
|
2381
|
+
let index = 0;
|
|
2382
|
+
for await (const item of source) {
|
|
2383
|
+
checkDeadline();
|
|
2384
|
+
if (index >= stop) {
|
|
2385
|
+
break;
|
|
2386
|
+
}
|
|
2387
|
+
if (index >= start && (index - start) % step === 0) {
|
|
2388
|
+
yield item;
|
|
2389
|
+
}
|
|
2390
|
+
index++;
|
|
2391
|
+
if (index >= stop) {
|
|
2392
|
+
break;
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
return;
|
|
2396
|
+
}
|
|
2397
|
+
const collected = [];
|
|
2398
|
+
for await (const item of source) {
|
|
2399
|
+
checkDeadline();
|
|
2400
|
+
collected.push(item);
|
|
2401
|
+
if (options?.maxOutputSize !== void 0 && collected.length > options.maxOutputSize) {
|
|
2402
|
+
throw new Error(`Output size exceeds maximum allowed size of ${options.maxOutputSize}`);
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
const result = interpreter.search(node, collected, options);
|
|
2406
|
+
if (Array.isArray(result)) {
|
|
2407
|
+
for (const item of result) {
|
|
2408
|
+
yield item;
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
return;
|
|
2412
|
+
}
|
|
2413
|
+
for await (const item of source) {
|
|
2414
|
+
checkDeadline();
|
|
2415
|
+
const res = interpreter.visit(node, item);
|
|
2416
|
+
if (res !== null && res !== void 0) {
|
|
2417
|
+
yield res;
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
return;
|
|
2421
|
+
}
|
|
2422
|
+
case "FilterProjection": {
|
|
2423
|
+
const { condition, right } = node;
|
|
2424
|
+
if (right.type === "Identity" || right.type === "Current") {
|
|
2425
|
+
for await (const item of source) {
|
|
2426
|
+
checkDeadline();
|
|
2427
|
+
if (!isFalse(interpreter.visit(condition, item))) {
|
|
2428
|
+
yield item;
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
if (right.type === "Field") {
|
|
2434
|
+
const key = right.name;
|
|
2435
|
+
for await (const item of source) {
|
|
2436
|
+
checkDeadline();
|
|
2437
|
+
if (!isFalse(interpreter.visit(condition, item))) {
|
|
2438
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
2439
|
+
const val = item[key];
|
|
2440
|
+
if (val !== void 0 && val !== null) {
|
|
2441
|
+
yield val;
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2448
|
+
for await (const item of source) {
|
|
2449
|
+
checkDeadline();
|
|
2450
|
+
if (!isFalse(interpreter.visit(condition, item))) {
|
|
2451
|
+
const res = interpreter.visit(right, item);
|
|
2452
|
+
if (res !== null && res !== void 0) {
|
|
2453
|
+
yield res;
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
}
|
|
2457
|
+
return;
|
|
2458
|
+
}
|
|
2459
|
+
case "Pipe": {
|
|
2460
|
+
const leftStream = evaluateStreamNode(source, node.left, interpreter, options);
|
|
2461
|
+
if (isStreamableNode(node.right)) {
|
|
2462
|
+
for await (const res of evaluateStreamNode(leftStream, node.right, interpreter, options)) {
|
|
2463
|
+
yield res;
|
|
2464
|
+
}
|
|
2465
|
+
} else {
|
|
2466
|
+
const collected = [];
|
|
2467
|
+
for await (const item of leftStream) {
|
|
2468
|
+
checkDeadline();
|
|
2469
|
+
collected.push(item);
|
|
2470
|
+
if (options?.maxOutputSize !== void 0 && collected.length > options.maxOutputSize) {
|
|
2471
|
+
throw new Error(`Output size exceeds maximum allowed size of ${options.maxOutputSize}`);
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
const result = interpreter.search(node.right, collected, options);
|
|
2475
|
+
if (result !== null && result !== void 0) {
|
|
2476
|
+
yield result;
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
return;
|
|
2480
|
+
}
|
|
2481
|
+
case "Identity":
|
|
2482
|
+
case "Current": {
|
|
2483
|
+
for await (const item of source) {
|
|
2484
|
+
checkDeadline();
|
|
2485
|
+
yield item;
|
|
2486
|
+
}
|
|
2487
|
+
return;
|
|
2488
|
+
}
|
|
2489
|
+
case "Field": {
|
|
2490
|
+
const key = node.name;
|
|
2491
|
+
for await (const item of source) {
|
|
2492
|
+
checkDeadline();
|
|
2493
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
2494
|
+
const val = item[key];
|
|
2495
|
+
if (val !== void 0 && val !== null) {
|
|
2496
|
+
yield val;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
return;
|
|
2501
|
+
}
|
|
2502
|
+
default: {
|
|
2503
|
+
if (isStreamableNode(node)) {
|
|
2504
|
+
for await (const item of source) {
|
|
2505
|
+
checkDeadline();
|
|
2506
|
+
const res = interpreter.visit(node, item);
|
|
2507
|
+
if (res !== null && res !== void 0) {
|
|
2508
|
+
yield res;
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
return;
|
|
2512
|
+
}
|
|
2513
|
+
const collected = [];
|
|
2514
|
+
for await (const item of source) {
|
|
2515
|
+
checkDeadline();
|
|
2516
|
+
collected.push(item);
|
|
2517
|
+
if (options?.maxOutputSize !== void 0 && collected.length > options.maxOutputSize) {
|
|
2518
|
+
throw new Error(`Output size exceeds maximum allowed size of ${options.maxOutputSize}`);
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
const result = interpreter.search(node, collected, options);
|
|
2522
|
+
if (result !== null && result !== void 0) {
|
|
2523
|
+
yield result;
|
|
2524
|
+
}
|
|
2525
|
+
return;
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2529
|
+
function isExpressionNode(val) {
|
|
2530
|
+
return typeof val === "object" && val !== null && "type" in val && typeof val.type === "string" && !(Symbol.iterator in val) && !(Symbol.asyncIterator in val);
|
|
2531
|
+
}
|
|
2532
|
+
async function* searchStream(sourceOrExpression, expressionOrSource, options) {
|
|
2533
|
+
let expression;
|
|
2534
|
+
let source;
|
|
2535
|
+
if (typeof sourceOrExpression === "string" || isExpressionNode(sourceOrExpression)) {
|
|
2536
|
+
expression = sourceOrExpression;
|
|
2537
|
+
source = expressionOrSource;
|
|
2538
|
+
} else {
|
|
2539
|
+
source = sourceOrExpression;
|
|
2540
|
+
expression = expressionOrSource;
|
|
2541
|
+
}
|
|
2542
|
+
if (typeof expression !== "string" && !isExpressionNode(expression)) {
|
|
2543
|
+
throw new TypeError("Expression must be a string or AST ExpressionNode");
|
|
2544
|
+
}
|
|
2545
|
+
const ast = typeof expression === "string" ? Parser_default.parse(expression, options) : expression;
|
|
2546
|
+
if (options) {
|
|
2547
|
+
const fnError = findDisallowedFunction(ast, options);
|
|
2548
|
+
if (fnError) {
|
|
2549
|
+
throw new Error(fnError);
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
const interpreter = new TreeInterpreter(options);
|
|
2553
|
+
interpreter.runtime._functionTable = TreeInterpreterInstance.runtime._functionTable;
|
|
2554
|
+
const items = normalizeSource(source, options);
|
|
2555
|
+
const results = evaluateStreamNode(items, ast, interpreter, options);
|
|
2556
|
+
const limit = options?.limit;
|
|
2557
|
+
const maxOutputSize = options?.maxOutputSize;
|
|
2558
|
+
let count = 0;
|
|
2559
|
+
for await (const result of results) {
|
|
2560
|
+
yield result;
|
|
2561
|
+
count++;
|
|
2562
|
+
if (limit !== void 0 && count >= limit) {
|
|
2563
|
+
break;
|
|
2564
|
+
}
|
|
2565
|
+
if (maxOutputSize !== void 0 && count > maxOutputSize) {
|
|
2566
|
+
throw new Error(`Output size exceeds maximum allowed size of ${maxOutputSize}`);
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2018
2571
|
// src/index.ts
|
|
2019
2572
|
var TYPE_ANY = 1 /* TYPE_ANY */;
|
|
2020
2573
|
var TYPE_ARRAY = 3 /* TYPE_ARRAY */;
|
|
@@ -2029,8 +2582,37 @@ var TYPE_NUMBER = 0 /* TYPE_NUMBER */;
|
|
|
2029
2582
|
var TYPE_OBJECT = 4 /* TYPE_OBJECT */;
|
|
2030
2583
|
var TYPE_STRING = 2 /* TYPE_STRING */;
|
|
2031
2584
|
function compile(expression, options) {
|
|
2585
|
+
return Parser_default.parse(expression, options);
|
|
2586
|
+
}
|
|
2587
|
+
function compileQuery(expression, options) {
|
|
2032
2588
|
const nodeTree = Parser_default.parse(expression, options);
|
|
2033
|
-
|
|
2589
|
+
const fn = function(data) {
|
|
2590
|
+
return TreeInterpreter_default.search(nodeTree, data, options);
|
|
2591
|
+
};
|
|
2592
|
+
fn.search = (data) => TreeInterpreter_default.search(nodeTree, data, options);
|
|
2593
|
+
fn.searchStream = (source, streamOptions) => searchStream(source, nodeTree, { ...options, ...streamOptions });
|
|
2594
|
+
fn.ast = nodeTree;
|
|
2595
|
+
return fn;
|
|
2596
|
+
}
|
|
2597
|
+
function validate(expression, options) {
|
|
2598
|
+
if (typeof expression !== "string") {
|
|
2599
|
+
return { valid: false, error: "Expression must be a string" };
|
|
2600
|
+
}
|
|
2601
|
+
try {
|
|
2602
|
+
const ast = Parser_default.parse(expression, options);
|
|
2603
|
+
if (options) {
|
|
2604
|
+
const fnError = findDisallowedFunction(ast, options);
|
|
2605
|
+
if (fnError) {
|
|
2606
|
+
return { valid: false, error: fnError };
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
return { valid: true, ast };
|
|
2610
|
+
} catch (err) {
|
|
2611
|
+
return {
|
|
2612
|
+
valid: false,
|
|
2613
|
+
error: err instanceof Error ? err.message : String(err)
|
|
2614
|
+
};
|
|
2615
|
+
}
|
|
2034
2616
|
}
|
|
2035
2617
|
function tokenize(expression, options) {
|
|
2036
2618
|
return Lexer_default.tokenize(expression, options);
|
|
@@ -2056,9 +2638,26 @@ var getCustomFunctions = () => {
|
|
|
2056
2638
|
var clearCustomFunctions = () => {
|
|
2057
2639
|
TreeInterpreter_default.runtime.clearCustomFunctions();
|
|
2058
2640
|
};
|
|
2641
|
+
var MAX_CACHE_SIZE = 1e3;
|
|
2642
|
+
var astCache = /* @__PURE__ */ new Map();
|
|
2059
2643
|
function search(data, expression, options) {
|
|
2060
|
-
|
|
2061
|
-
|
|
2644
|
+
let nodeTree;
|
|
2645
|
+
if (!options) {
|
|
2646
|
+
nodeTree = astCache.get(expression);
|
|
2647
|
+
if (!nodeTree) {
|
|
2648
|
+
nodeTree = Parser_default.parse(expression);
|
|
2649
|
+
if (astCache.size >= MAX_CACHE_SIZE) {
|
|
2650
|
+
const firstKey = astCache.keys().next().value;
|
|
2651
|
+
if (firstKey !== void 0) {
|
|
2652
|
+
astCache.delete(firstKey);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
astCache.set(expression, nodeTree);
|
|
2656
|
+
}
|
|
2657
|
+
} else {
|
|
2658
|
+
nodeTree = Parser_default.parse(expression, options);
|
|
2659
|
+
}
|
|
2660
|
+
return TreeInterpreter_default.search(nodeTree, data, options);
|
|
2062
2661
|
}
|
|
2063
2662
|
function Scope() {
|
|
2064
2663
|
return new ScopeChain();
|
|
@@ -2066,6 +2665,9 @@ function Scope() {
|
|
|
2066
2665
|
var TreeInterpreter2 = TreeInterpreter_default;
|
|
2067
2666
|
var jmespath = {
|
|
2068
2667
|
compile,
|
|
2668
|
+
compileQuery,
|
|
2669
|
+
searchStream,
|
|
2670
|
+
validate,
|
|
2069
2671
|
registerFunction,
|
|
2070
2672
|
register,
|
|
2071
2673
|
unregisterFunction,
|
|
@@ -2085,34 +2687,13 @@ var jmespath = {
|
|
|
2085
2687
|
TYPE_NULL,
|
|
2086
2688
|
TYPE_NUMBER,
|
|
2087
2689
|
TYPE_OBJECT,
|
|
2088
|
-
TYPE_STRING
|
|
2690
|
+
TYPE_STRING,
|
|
2691
|
+
TYPE_ARRAY_ARRAY,
|
|
2692
|
+
TYPE_ARRAY_OBJECT,
|
|
2693
|
+
Scope
|
|
2089
2694
|
};
|
|
2695
|
+
var index_default = jmespath;
|
|
2090
2696
|
|
|
2091
|
-
exports
|
|
2092
|
-
exports.TYPE_ANY = TYPE_ANY;
|
|
2093
|
-
exports.TYPE_ARRAY = TYPE_ARRAY;
|
|
2094
|
-
exports.TYPE_ARRAY_ARRAY = TYPE_ARRAY_ARRAY;
|
|
2095
|
-
exports.TYPE_ARRAY_NUMBER = TYPE_ARRAY_NUMBER;
|
|
2096
|
-
exports.TYPE_ARRAY_OBJECT = TYPE_ARRAY_OBJECT;
|
|
2097
|
-
exports.TYPE_ARRAY_STRING = TYPE_ARRAY_STRING;
|
|
2098
|
-
exports.TYPE_BOOLEAN = TYPE_BOOLEAN;
|
|
2099
|
-
exports.TYPE_EXPREF = TYPE_EXPREF;
|
|
2100
|
-
exports.TYPE_NULL = TYPE_NULL;
|
|
2101
|
-
exports.TYPE_NUMBER = TYPE_NUMBER;
|
|
2102
|
-
exports.TYPE_OBJECT = TYPE_OBJECT;
|
|
2103
|
-
exports.TYPE_STRING = TYPE_STRING;
|
|
2104
|
-
exports.TreeInterpreter = TreeInterpreter2;
|
|
2105
|
-
exports.clearCustomFunctions = clearCustomFunctions;
|
|
2106
|
-
exports.compile = compile;
|
|
2107
|
-
exports.default = jmespath;
|
|
2108
|
-
exports.getCustomFunctions = getCustomFunctions;
|
|
2109
|
-
exports.getRegisteredFunctions = getRegisteredFunctions;
|
|
2110
|
-
exports.isRegistered = isRegistered;
|
|
2111
|
-
exports.jmespath = jmespath;
|
|
2112
|
-
exports.register = register;
|
|
2113
|
-
exports.registerFunction = registerFunction;
|
|
2114
|
-
exports.search = search;
|
|
2115
|
-
exports.tokenize = tokenize;
|
|
2116
|
-
exports.unregisterFunction = unregisterFunction;
|
|
2697
|
+
module.exports = index_default;
|
|
2117
2698
|
//# sourceMappingURL=index.cjs.map
|
|
2118
2699
|
//# sourceMappingURL=index.cjs.map
|