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