@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/dist/index.umd.js CHANGED
@@ -1,10 +1,88 @@
1
- var jmespath = (function (exports) {
1
+ var jmespath = (function () {
2
2
  'use strict';
3
3
 
4
4
  var __defProp = Object.defineProperty;
5
5
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
6
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
7
 
8
+ // src/utils/ast.ts
9
+ var CHILD_PROPS = ["left", "right", "condition", "child", "operand", "trueExpr", "falseExpr", "expression"];
10
+ function pushChildren(node, stack) {
11
+ const n = node;
12
+ for (const prop of CHILD_PROPS) {
13
+ const val = n[prop];
14
+ if (val && typeof val === "object" && "type" in val) {
15
+ stack.push(val);
16
+ }
17
+ }
18
+ if (Array.isArray(n.children)) {
19
+ for (const item of n.children) {
20
+ if (!item) {
21
+ continue;
22
+ }
23
+ stack.push(item);
24
+ if (item.type === "KeyValuePair" && item.value) {
25
+ stack.push(item.value);
26
+ }
27
+ }
28
+ }
29
+ if (Array.isArray(n.bindings)) {
30
+ for (const item of n.bindings) {
31
+ if (!item) {
32
+ continue;
33
+ }
34
+ stack.push(item);
35
+ if (item.reference) {
36
+ stack.push(item.reference);
37
+ }
38
+ }
39
+ }
40
+ }
41
+ function forEachNode(root, visitor) {
42
+ const stack = [root];
43
+ while (stack.length > 0) {
44
+ const current = stack.pop();
45
+ if (!current) {
46
+ break;
47
+ }
48
+ if (visitor(current) === false) {
49
+ return;
50
+ }
51
+ pushChildren(current, stack);
52
+ }
53
+ }
54
+ function countNodes(root) {
55
+ let count = 0;
56
+ forEachNode(root, () => {
57
+ count += 1;
58
+ return true;
59
+ });
60
+ return count;
61
+ }
62
+ function findDisallowedFunction(root, options) {
63
+ const { allowedFunctions, disallowedFunctions } = options;
64
+ if (!allowedFunctions && !disallowedFunctions) {
65
+ return null;
66
+ }
67
+ let violation = null;
68
+ forEachNode(root, (node) => {
69
+ if (node.type !== "Function") {
70
+ return true;
71
+ }
72
+ const name = node.name;
73
+ if (allowedFunctions && !allowedFunctions.includes(name)) {
74
+ violation = `Function '${name}' is not allowed`;
75
+ return false;
76
+ }
77
+ if (disallowedFunctions && disallowedFunctions.includes(name)) {
78
+ violation = `Function '${name}' is disallowed`;
79
+ return false;
80
+ }
81
+ return true;
82
+ });
83
+ return violation;
84
+ }
85
+
8
86
  // src/utils/index.ts
9
87
  var isObject = (obj) => {
10
88
  return obj !== null && Object.prototype.toString.call(obj) === "[object Object]";
@@ -54,9 +132,6 @@ var jmespath = (function (exports) {
54
132
  if (Array.isArray(obj)) {
55
133
  return obj.length === 0;
56
134
  }
57
- if (obj === null) {
58
- return true;
59
- }
60
135
  return Object.keys(obj).length === 0;
61
136
  }
62
137
  return false;
@@ -101,112 +176,29 @@ var jmespath = (function (exports) {
101
176
  };
102
177
  var add = (left, right) => {
103
178
  ensureNumbers(left, right);
104
- const result = left + right;
105
- return result;
179
+ return left + right;
106
180
  };
107
181
  var sub = (left, right) => {
108
182
  ensureNumbers(left, right);
109
- const result = left - right;
110
- return result;
183
+ return left - right;
111
184
  };
112
185
  var mul = (left, right) => {
113
186
  ensureNumbers(left, right);
114
- const result = left * right;
115
- return result;
187
+ return left * right;
116
188
  };
117
189
  var divide = (left, right) => {
118
190
  ensureNumbers(left, right);
119
- const result = left / notZero(right);
120
- return result;
191
+ return left / notZero(right);
121
192
  };
122
193
  var div = (left, right) => {
123
194
  ensureNumbers(left, right);
124
- const result = Math.floor(left / notZero(right));
125
- return result;
195
+ return Math.floor(left / notZero(right));
126
196
  };
127
197
  var mod = (left, right) => {
128
198
  ensureNumbers(left, right);
129
- const result = left % right;
130
- return result;
199
+ return left % right;
131
200
  };
132
201
 
133
- // src/utils/strings.ts
134
- var findFirst = (subject, sub2, start, end) => {
135
- if (!subject || !sub2) {
136
- return null;
137
- }
138
- start = Math.max(ensureInteger(start = start || 0), 0);
139
- end = Math.min(ensureInteger(end = end || subject.length), subject.length);
140
- const offset = subject.slice(start, end).indexOf(sub2);
141
- return offset === -1 ? null : offset + start;
142
- };
143
- var findLast = (subject, sub2, start, end) => {
144
- if (!subject || !sub2) {
145
- return null;
146
- }
147
- start = Math.max(ensureInteger(start = start || 0), 0);
148
- end = Math.min(ensureInteger(end = end || subject.length), subject.length);
149
- const offset = subject.slice(start, end).lastIndexOf(sub2);
150
- const result = offset === -1 ? null : offset + start;
151
- return result;
152
- };
153
- var lower = (subject) => subject.toLowerCase();
154
- var ensurePadFuncParams = (name, width, padding) => {
155
- padding = padding || " ";
156
- if (padding.length > 1) {
157
- throw new Error(`invalid value, ${name} expects its 'pad' parameter to be a valid string with a single codepoint`);
158
- }
159
- ensurePositiveInteger(width);
160
- return padding;
161
- };
162
- var padLeft = (subject, width, padding) => {
163
- padding = ensurePadFuncParams("pad_left", width, padding);
164
- return subject && subject.padStart(width, padding) || "";
165
- };
166
- var padRight = (subject, width, padding) => {
167
- padding = ensurePadFuncParams("pad_right", width, padding);
168
- return subject && subject.padEnd(width, padding) || "";
169
- };
170
- var replace = (subject, string, by, count) => {
171
- if (count === 0) {
172
- return subject;
173
- }
174
- if (!count) {
175
- return subject.split(string).join(by);
176
- }
177
- ensurePositiveInteger(count);
178
- [...Array(count).keys()].map(() => subject = subject.replace(string, by));
179
- return subject;
180
- };
181
- var split = (subject, search2, count) => {
182
- if (subject.length == 0 && search2.length === 0) {
183
- return [];
184
- }
185
- if (count === null || count === void 0) {
186
- return subject.split(search2);
187
- }
188
- ensurePositiveInteger(count);
189
- if (count === 0) {
190
- return [subject];
191
- }
192
- const split2 = subject.split(search2);
193
- return [...split2.slice(0, count), split2.slice(count).join(search2)];
194
- };
195
- var trim = (subject, chars) => {
196
- return trimLeft(trimRight(subject, chars), chars);
197
- };
198
- var trimLeft = (subject, chars) => {
199
- return trimImpl(subject, (list) => new RegExp(`^[${list}]*(.*?)`), chars);
200
- };
201
- var trimRight = (subject, chars) => {
202
- return trimImpl(subject, (list) => new RegExp(`(.*?)[${list}]*$`), chars);
203
- };
204
- var trimImpl = (subject, regExper, chars) => {
205
- const pattern = chars ? chars.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&") : "\\s\x85";
206
- return subject.replace(regExper(pattern), "$1");
207
- };
208
- var upper = (subject) => subject.toUpperCase();
209
-
210
202
  // src/Lexer.ts
211
203
  var basicTokens = {
212
204
  "(": "Lparen" /* TOK_LPAREN */,
@@ -388,7 +380,7 @@ var jmespath = (function (exports) {
388
380
  }
389
381
  this._current += 1;
390
382
  const literal = stream.slice(start + 1, this._current - 1);
391
- return replace(replace(literal, `\\\\`, `\\`), `\\'`, `'`);
383
+ return literal.replace(/\\(['\\])/g, "$1");
392
384
  }
393
385
  consumeNumber(stream) {
394
386
  const start = this._current;
@@ -554,15 +546,26 @@ var jmespath = (function (exports) {
554
546
  constructor() {
555
547
  __publicField(this, "index", 0);
556
548
  __publicField(this, "tokens", []);
549
+ __publicField(this, "depth", 0);
550
+ __publicField(this, "maxDepth");
551
+ __publicField(this, "nodeCount", 0);
552
+ __publicField(this, "maxNodes");
557
553
  }
558
554
  parse(expression, options) {
559
555
  this.loadTokens(expression, options || { enable_legacy_literals: false });
560
556
  this.index = 0;
557
+ this.depth = 0;
558
+ this.nodeCount = 0;
559
+ this.maxDepth = options?.maxDepth;
560
+ this.maxNodes = options?.maxNodes;
561
561
  const ast = this.expression(0);
562
562
  if (this.lookahead(0) !== "EOF" /* TOK_EOF */) {
563
563
  const token = this.lookaheadToken(0);
564
564
  this.errorToken(token, `Syntax error: unexpected token type: ${token.type}, value: ${token.value}`);
565
565
  }
566
+ if (this.maxNodes !== void 0 && countNodes(ast) > this.maxNodes) {
567
+ throw new Error(`Expression exceeds maximum allowed node count of ${this.maxNodes}`);
568
+ }
566
569
  return ast;
567
570
  }
568
571
  loadTokens(expression, options) {
@@ -570,16 +573,32 @@ var jmespath = (function (exports) {
570
573
  this.tokens.push({ type: "EOF" /* TOK_EOF */, value: "", start: expression.length });
571
574
  }
572
575
  expression(rbp) {
573
- const leftToken = this.lookaheadToken(0);
574
- this.advance();
575
- let left = this.nud(leftToken);
576
- let currentTokenType = this.lookahead(0);
577
- while (rbp < bindingPower[currentTokenType]) {
576
+ if (this.maxDepth !== void 0 && this.depth >= this.maxDepth) {
577
+ throw new Error(`Expression exceeds maximum allowed depth of ${this.maxDepth}`);
578
+ }
579
+ this.depth += 1;
580
+ this.trackNode();
581
+ try {
582
+ const leftToken = this.lookaheadToken(0);
578
583
  this.advance();
579
- left = this.led(currentTokenType, left);
580
- currentTokenType = this.lookahead(0);
584
+ let left = this.nud(leftToken);
585
+ let currentTokenType = this.lookahead(0);
586
+ while (rbp < bindingPower[currentTokenType]) {
587
+ this.trackNode();
588
+ this.advance();
589
+ left = this.led(currentTokenType, left);
590
+ currentTokenType = this.lookahead(0);
591
+ }
592
+ return left;
593
+ } finally {
594
+ this.depth -= 1;
595
+ }
596
+ }
597
+ trackNode() {
598
+ this.nodeCount += 1;
599
+ if (this.maxNodes !== void 0 && this.nodeCount > this.maxNodes) {
600
+ throw new Error(`Expression exceeds maximum allowed node count of ${this.maxNodes}`);
581
601
  }
582
- return left;
583
602
  }
584
603
  lookahead(offset) {
585
604
  return this.tokens[this.index + offset].type;
@@ -806,9 +825,13 @@ var jmespath = (function (exports) {
806
825
  right
807
826
  };
808
827
  if (right.type === "Slice") {
828
+ const rhs = this.parseProjectionRHS(bindingPower.Star);
829
+ if (rhs.type === "Identity") {
830
+ return indexExpr;
831
+ }
809
832
  return {
810
833
  left: indexExpr,
811
- right: this.parseProjectionRHS(bindingPower.Star),
834
+ right: rhs,
812
835
  type: "Projection"
813
836
  };
814
837
  }
@@ -968,6 +991,83 @@ var jmespath = (function (exports) {
968
991
  var Parser = new TokenParser();
969
992
  var Parser_default = Parser;
970
993
 
994
+ // src/utils/strings.ts
995
+ var findFirst = (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).indexOf(sub2);
1002
+ return offset === -1 ? null : offset + s;
1003
+ };
1004
+ var findLast = (subject, sub2, start, end) => {
1005
+ if (!subject || !sub2) {
1006
+ return null;
1007
+ }
1008
+ const s = Math.max(ensureInteger(start ?? 0), 0);
1009
+ const e = Math.min(ensureInteger(end ?? subject.length), subject.length);
1010
+ const offset = subject.slice(s, e).lastIndexOf(sub2);
1011
+ return offset === -1 ? null : offset + s;
1012
+ };
1013
+ var lower = (subject) => subject.toLowerCase();
1014
+ var ensurePadFuncParams = (name, width, padding = " ") => {
1015
+ if (padding.length > 1) {
1016
+ throw new Error(`invalid value, ${name} expects its 'pad' parameter to be a valid string with a single codepoint`);
1017
+ }
1018
+ ensurePositiveInteger(width);
1019
+ return padding;
1020
+ };
1021
+ var padLeft = (subject, width, padding) => {
1022
+ padding = ensurePadFuncParams("pad_left", width, padding);
1023
+ return subject && subject.padStart(width, padding) || "";
1024
+ };
1025
+ var padRight = (subject, width, padding) => {
1026
+ padding = ensurePadFuncParams("pad_right", width, padding);
1027
+ return subject && subject.padEnd(width, padding) || "";
1028
+ };
1029
+ var replace = (subject, string, by, count) => {
1030
+ if (count === 0) {
1031
+ return subject;
1032
+ }
1033
+ if (!count) {
1034
+ return subject.split(string).join(by);
1035
+ }
1036
+ ensurePositiveInteger(count);
1037
+ while (count-- > 0 && subject.includes(string)) {
1038
+ subject = subject.replace(string, by);
1039
+ }
1040
+ return subject;
1041
+ };
1042
+ var split = (subject, search2, count) => {
1043
+ if (subject.length == 0 && search2.length === 0) {
1044
+ return [];
1045
+ }
1046
+ if (count === null || count === void 0) {
1047
+ return subject.split(search2);
1048
+ }
1049
+ ensurePositiveInteger(count);
1050
+ if (count === 0) {
1051
+ return [subject];
1052
+ }
1053
+ const split2 = subject.split(search2);
1054
+ return [...split2.slice(0, count), split2.slice(count).join(search2)];
1055
+ };
1056
+ var trim = (subject, chars) => {
1057
+ return trimLeft(trimRight(subject, chars), chars);
1058
+ };
1059
+ var trimLeft = (subject, chars) => {
1060
+ return trimImpl(subject, (list) => new RegExp(`^[${list}]*(.*?)`), chars);
1061
+ };
1062
+ var trimRight = (subject, chars) => {
1063
+ return trimImpl(subject, (list) => new RegExp(`(.*?)[${list}]*$`), chars);
1064
+ };
1065
+ var trimImpl = (subject, regExper, chars) => {
1066
+ const pattern = chars ? chars.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&") : "\\s\x85";
1067
+ return subject.replace(regExper(pattern), "$1");
1068
+ };
1069
+ var upper = (subject) => subject.toUpperCase();
1070
+
971
1071
  // src/utils/text.ts
972
1072
  var Text = class _Text {
973
1073
  constructor(text) {
@@ -978,7 +1078,11 @@ var jmespath = (function (exports) {
978
1078
  return this._text;
979
1079
  }
980
1080
  get length() {
981
- return this.codePoints.length;
1081
+ let count = 0;
1082
+ for (const _ of this._text) {
1083
+ count += 1;
1084
+ }
1085
+ return count;
982
1086
  }
983
1087
  compareTo(other) {
984
1088
  return _Text.compare(this, new _Text(other));
@@ -1013,6 +1117,12 @@ var jmespath = (function (exports) {
1013
1117
  var createMathFunction = (mathFn) => ([value]) => mathFn(value);
1014
1118
  var createStringFunction = (stringFn) => ([subject]) => stringFn(subject);
1015
1119
  var createObjectFunction = (objFn) => ([obj]) => objFn(obj);
1120
+ var ARRAY_SUBTYPES = {
1121
+ [8 /* TYPE_ARRAY_NUMBER */]: 0 /* TYPE_NUMBER */,
1122
+ [10 /* TYPE_ARRAY_OBJECT */]: 4 /* TYPE_OBJECT */,
1123
+ [9 /* TYPE_ARRAY_STRING */]: 2 /* TYPE_STRING */,
1124
+ [11 /* TYPE_ARRAY_ARRAY */]: 3 /* TYPE_ARRAY */
1125
+ };
1016
1126
  var Runtime = class {
1017
1127
  constructor(interpreter) {
1018
1128
  __publicField(this, "_interpreter");
@@ -1058,28 +1168,30 @@ var jmespath = (function (exports) {
1058
1168
  }
1059
1169
  return null;
1060
1170
  });
1061
- __publicField(this, "functionEndsWith", (resolvedArgs) => {
1062
- const [searchStr, suffix] = resolvedArgs;
1063
- return searchStr.includes(suffix, searchStr.length - suffix.length);
1171
+ __publicField(this, "functionEndsWith", ([searchStr, suffix]) => {
1172
+ return searchStr.endsWith(suffix);
1064
1173
  });
1065
1174
  __publicField(this, "functionFindFirst", this.createFindFunction(findFirst));
1066
1175
  __publicField(this, "functionFindLast", this.createFindFunction(findLast));
1067
1176
  __publicField(this, "functionFromItems", ([array]) => {
1068
- array.map((pair) => {
1069
- if (pair.length != 2 || typeof pair[0] !== "string") {
1177
+ for (const pair of array) {
1178
+ if (pair.length !== 2 || typeof pair[0] !== "string") {
1070
1179
  throw new Error("invalid value, each array must contain two elements, a pair of string and value");
1071
1180
  }
1072
- });
1181
+ }
1073
1182
  return Object.fromEntries(array);
1074
1183
  });
1075
1184
  __publicField(this, "functionGroupBy", ([array, exprefNode]) => {
1076
1185
  const keyFunction = this.createKeyFunction(exprefNode, [2 /* TYPE_STRING */]);
1077
- return array.reduce((acc, cur) => {
1078
- const k = keyFunction(cur ?? {});
1079
- const target = acc[k] = acc[k] || [];
1080
- target.push(cur);
1081
- return acc;
1082
- }, {});
1186
+ const groups = {};
1187
+ for (const item of array) {
1188
+ const key = keyFunction(item);
1189
+ if (!groups[key]) {
1190
+ groups[key] = [];
1191
+ }
1192
+ groups[key].push(item);
1193
+ }
1194
+ return groups;
1083
1195
  });
1084
1196
  __publicField(this, "functionItems", ([inputValue]) => {
1085
1197
  return Object.entries(inputValue);
@@ -1142,12 +1254,7 @@ var jmespath = (function (exports) {
1142
1254
  return maxRecord || null;
1143
1255
  });
1144
1256
  __publicField(this, "functionMerge", (resolvedArgs) => {
1145
- let merged = {};
1146
- for (let i = 0; i < resolvedArgs.length; i += 1) {
1147
- const current = resolvedArgs[i];
1148
- merged = Object.assign(merged, current);
1149
- }
1150
- return merged;
1257
+ return Object.assign({}, ...resolvedArgs);
1151
1258
  });
1152
1259
  __publicField(this, "functionMin", ([inputValue]) => {
1153
1260
  if (!inputValue.length) {
@@ -1183,12 +1290,7 @@ var jmespath = (function (exports) {
1183
1290
  return minRecord || null;
1184
1291
  });
1185
1292
  __publicField(this, "functionNotNull", (resolvedArgs) => {
1186
- for (let i = 0; i < resolvedArgs.length; i += 1) {
1187
- if (this.getTypeName(resolvedArgs[i]) !== 7 /* TYPE_NULL */) {
1188
- return resolvedArgs[i];
1189
- }
1190
- }
1191
- return null;
1293
+ return resolvedArgs.find((arg) => arg !== null) ?? null;
1192
1294
  });
1193
1295
  __publicField(this, "functionPadLeft", this.createPadFunction(padLeft));
1194
1296
  __publicField(this, "functionPadRight", this.createPadFunction(padRight));
@@ -1208,12 +1310,12 @@ var jmespath = (function (exports) {
1208
1310
  if (typeName === 2 /* TYPE_STRING */) {
1209
1311
  return new Text(inputValue).reverse();
1210
1312
  }
1211
- const reversedArray = inputValue.slice(0);
1313
+ const reversedArray = [...inputValue];
1212
1314
  reversedArray.reverse();
1213
1315
  return reversedArray;
1214
1316
  });
1215
1317
  __publicField(this, "functionSort", ([inputValue]) => {
1216
- if (inputValue.length == 0) {
1318
+ if (inputValue.length <= 1) {
1217
1319
  return inputValue;
1218
1320
  }
1219
1321
  if (typeof inputValue[0] === "string") {
@@ -1222,8 +1324,8 @@ var jmespath = (function (exports) {
1222
1324
  return [...inputValue].sort();
1223
1325
  });
1224
1326
  __publicField(this, "functionSortBy", (resolvedArgs) => {
1225
- const sortedArray = resolvedArgs[0].slice(0);
1226
- if (sortedArray.length === 0) {
1327
+ const sortedArray = [...resolvedArgs[0]];
1328
+ if (sortedArray.length <= 1) {
1227
1329
  return sortedArray;
1228
1330
  }
1229
1331
  const interpreter = this._interpreter;
@@ -1258,10 +1360,7 @@ var jmespath = (function (exports) {
1258
1360
  return inputValue.reduce((x, y) => x + y, 0);
1259
1361
  });
1260
1362
  __publicField(this, "functionToArray", ([inputValue]) => {
1261
- if (this.getTypeName(inputValue) === 3 /* TYPE_ARRAY */) {
1262
- return inputValue;
1263
- }
1264
- return [inputValue];
1363
+ return Array.isArray(inputValue) ? inputValue : [inputValue];
1265
1364
  });
1266
1365
  __publicField(this, "functionToNumber", ([inputValue]) => {
1267
1366
  const typeName = this.getTypeName(inputValue);
@@ -1278,36 +1377,22 @@ var jmespath = (function (exports) {
1278
1377
  return null;
1279
1378
  });
1280
1379
  __publicField(this, "functionToString", ([inputValue]) => {
1281
- if (this.getTypeName(inputValue) === 2 /* TYPE_STRING */) {
1282
- return inputValue;
1283
- }
1284
- return JSON.stringify(inputValue);
1380
+ return typeof inputValue === "string" ? inputValue : JSON.stringify(inputValue);
1285
1381
  });
1286
1382
  __publicField(this, "functionTrim", this.createTrimFunction(trim));
1287
1383
  __publicField(this, "functionTrimLeft", this.createTrimFunction(trimLeft));
1288
1384
  __publicField(this, "functionTrimRight", this.createTrimFunction(trimRight));
1289
1385
  __publicField(this, "functionType", ([inputValue]) => {
1290
- switch (this.getTypeName(inputValue)) {
1291
- case 0 /* TYPE_NUMBER */:
1292
- return "number";
1293
- case 2 /* TYPE_STRING */:
1294
- return "string";
1295
- case 3 /* TYPE_ARRAY */:
1296
- return "array";
1297
- case 4 /* TYPE_OBJECT */:
1298
- return "object";
1299
- case 5 /* TYPE_BOOLEAN */:
1300
- return "boolean";
1301
- case 7 /* TYPE_NULL */:
1302
- return "null";
1303
- default:
1304
- throw new Error("invalid-type");
1386
+ const type = this.getTypeName(inputValue);
1387
+ const name = type !== void 0 ? this.TYPE_NAME_TABLE[type] : void 0;
1388
+ if (!name) {
1389
+ throw new Error("invalid-type");
1305
1390
  }
1391
+ return name;
1306
1392
  });
1307
1393
  __publicField(this, "functionZip", (array) => {
1308
1394
  const length = Math.min(...array.map((arr) => arr.length));
1309
- const result = Array(length).fill(null).map((_, index) => array.map((arr) => arr[index]));
1310
- return result;
1395
+ return Array.from({ length }, (_, index) => array.map((arr) => arr[index]));
1311
1396
  });
1312
1397
  this._interpreter = interpreter;
1313
1398
  this._functionTable = this.buildFunctionTable();
@@ -1607,34 +1692,18 @@ var jmespath = (function (exports) {
1607
1692
  if (expected === 1 /* TYPE_ANY */) {
1608
1693
  return true;
1609
1694
  }
1610
- if (expected === 9 /* TYPE_ARRAY_STRING */ || expected === 8 /* TYPE_ARRAY_NUMBER */ || expected === 10 /* TYPE_ARRAY_OBJECT */ || expected === 11 /* TYPE_ARRAY_ARRAY */ || expected === 3 /* TYPE_ARRAY */) {
1611
- if (expected === 3 /* TYPE_ARRAY */) {
1612
- return actual === 3 /* TYPE_ARRAY */;
1613
- }
1614
- if (actual === 3 /* TYPE_ARRAY */) {
1615
- let subtype;
1616
- if (expected === 8 /* TYPE_ARRAY_NUMBER */) {
1617
- subtype = 0 /* TYPE_NUMBER */;
1618
- } else if (expected === 10 /* TYPE_ARRAY_OBJECT */) {
1619
- subtype = 4 /* TYPE_OBJECT */;
1620
- } else if (expected === 9 /* TYPE_ARRAY_STRING */) {
1621
- subtype = 2 /* TYPE_STRING */;
1622
- } else if (expected === 11 /* TYPE_ARRAY_ARRAY */) {
1623
- subtype = 3 /* TYPE_ARRAY */;
1624
- }
1625
- const array = argValue;
1626
- for (let i = 0; i < array.length; i += 1) {
1627
- const typeName = this.getTypeName(array[i]);
1628
- if (typeName !== void 0 && subtype !== void 0 && !this.typeMatches(typeName, subtype, array[i])) {
1629
- return false;
1630
- }
1631
- }
1632
- return true;
1695
+ const subtype = ARRAY_SUBTYPES[expected];
1696
+ if (subtype !== void 0) {
1697
+ if (actual !== 3 /* TYPE_ARRAY */) {
1698
+ return false;
1633
1699
  }
1634
- } else {
1635
- return actual === expected;
1700
+ const array = argValue;
1701
+ return array.every((item) => {
1702
+ const typeName = this.getTypeName(item);
1703
+ return typeName === void 0 || this.typeMatches(typeName, subtype, item);
1704
+ });
1636
1705
  }
1637
- return false;
1706
+ return actual === expected;
1638
1707
  }
1639
1708
  getTypeName(obj) {
1640
1709
  if (obj === null) {
@@ -1727,26 +1796,111 @@ var jmespath = (function (exports) {
1727
1796
  // src/TreeInterpreter.ts
1728
1797
  var emptyScopeChain = new ScopeChain();
1729
1798
  var TreeInterpreter = class _TreeInterpreter {
1730
- constructor() {
1799
+ constructor(options) {
1731
1800
  __publicField(this, "runtime");
1732
1801
  __publicField(this, "_rootValue", null);
1733
1802
  __publicField(this, "_scope");
1803
+ __publicField(this, "_options");
1804
+ __publicField(this, "_depth", 0);
1805
+ __publicField(this, "_deadline", 0);
1734
1806
  this.runtime = new Runtime(this);
1735
1807
  this._scope = new ScopeChain();
1808
+ if (options) {
1809
+ this._options = options;
1810
+ this._deadline = options.timeoutMs !== void 0 ? Date.now() + options.timeoutMs : 0;
1811
+ }
1736
1812
  }
1737
1813
  withScope(scope) {
1738
- const interpreter = new _TreeInterpreter();
1814
+ const interpreter = new _TreeInterpreter(this._options);
1739
1815
  interpreter.runtime._functionTable = this.runtime._functionTable;
1740
1816
  interpreter._rootValue = this._rootValue;
1741
1817
  interpreter._scope = this._scope.withScope(scope);
1818
+ interpreter._depth = this._depth;
1819
+ interpreter._deadline = this._deadline;
1742
1820
  return interpreter;
1743
1821
  }
1744
- search(node, value) {
1822
+ search(node, value, options) {
1823
+ if (options?.maxNodes !== void 0 && countNodes(node) > options.maxNodes) {
1824
+ throw new Error(`Expression exceeds maximum allowed node count of ${options.maxNodes}`);
1825
+ }
1745
1826
  this._rootValue = value;
1746
1827
  this._scope = emptyScopeChain;
1747
- return this.visit(node, value);
1828
+ this._options = options;
1829
+ this._depth = 0;
1830
+ this._deadline = options?.timeoutMs !== void 0 ? Date.now() + options.timeoutMs : 0;
1831
+ const result = this.visit(node, value);
1832
+ this.checkOutputSize(result);
1833
+ return result;
1834
+ }
1835
+ checkOutputSize(val) {
1836
+ const max = this._options?.maxOutputSize;
1837
+ if (max === void 0 || val == null) {
1838
+ return;
1839
+ }
1840
+ const size = Array.isArray(val) || typeof val === "string" ? val.length : typeof val === "object" ? Object.keys(val).length : 0;
1841
+ if (size > max) {
1842
+ throw new Error(`Output size exceeds maximum allowed size of ${max}`);
1843
+ }
1844
+ }
1845
+ collect(target, item) {
1846
+ target.push(item);
1847
+ if (this._options?.maxOutputSize !== void 0 && target.length > this._options.maxOutputSize) {
1848
+ throw new Error(`Output size exceeds maximum allowed size of ${this._options.maxOutputSize}`);
1849
+ }
1850
+ }
1851
+ evaluateProjectionItems(items, right) {
1852
+ const collected = [];
1853
+ if (right.type === "Field") {
1854
+ const key = right.name;
1855
+ for (let i = 0; i < items.length; i++) {
1856
+ if (this._deadline > 0 && Date.now() >= this._deadline) {
1857
+ throw new Error(`Query execution timed out after ${this._options?.timeoutMs}ms`);
1858
+ }
1859
+ const elem = items[i];
1860
+ if (!elem || typeof elem !== "object" || Array.isArray(elem)) {
1861
+ continue;
1862
+ }
1863
+ const val = elem[key];
1864
+ if (val !== void 0 && val !== null) {
1865
+ this.collect(collected, val);
1866
+ }
1867
+ }
1868
+ return collected;
1869
+ }
1870
+ if (right.type === "Identity") {
1871
+ for (let i = 0; i < items.length; i++) {
1872
+ const elem = items[i];
1873
+ if (elem !== null) {
1874
+ this.collect(collected, elem);
1875
+ }
1876
+ }
1877
+ return collected;
1878
+ }
1879
+ for (const elem of items) {
1880
+ const current = this.visit(right, elem);
1881
+ if (current !== null) {
1882
+ this.collect(collected, current);
1883
+ }
1884
+ }
1885
+ return collected;
1748
1886
  }
1749
1887
  visit(node, value) {
1888
+ if (this._options) {
1889
+ if (this._options.maxDepth !== void 0 && this._depth >= this._options.maxDepth) {
1890
+ throw new Error(`Evaluation exceeds maximum allowed depth of ${this._options.maxDepth}`);
1891
+ }
1892
+ if (this._deadline > 0 && Date.now() >= this._deadline) {
1893
+ throw new Error(`Query execution timed out after ${this._options.timeoutMs}ms`);
1894
+ }
1895
+ }
1896
+ this._depth += 1;
1897
+ try {
1898
+ return this.evaluateNode(node, value);
1899
+ } finally {
1900
+ this._depth -= 1;
1901
+ }
1902
+ }
1903
+ evaluateNode(node, value) {
1750
1904
  switch (node.type) {
1751
1905
  case "Ternary": {
1752
1906
  const condition = this.visit(node.condition, value);
@@ -1762,16 +1916,11 @@ var jmespath = (function (exports) {
1762
1916
  }
1763
1917
  return value[identifier] ?? null;
1764
1918
  case "LetExpression": {
1765
- const { bindings, expression } = node;
1766
- let scope = {};
1767
- bindings.forEach((binding) => {
1768
- const reference = this.visit(binding, value);
1769
- scope = {
1770
- ...scope,
1771
- ...reference
1772
- };
1773
- });
1774
- return this.withScope(scope).visit(expression, value);
1919
+ const scope = {};
1920
+ for (const binding of node.bindings) {
1921
+ Object.assign(scope, this.visit(binding, value));
1922
+ }
1923
+ return this.withScope(scope).visit(node.expression, value);
1775
1924
  }
1776
1925
  case "Binding": {
1777
1926
  const { variable, reference } = node;
@@ -1803,51 +1952,27 @@ var jmespath = (function (exports) {
1803
1952
  return null;
1804
1953
  }
1805
1954
  const { start, stop, step } = this.computeSliceParams(value.length, node);
1806
- if (typeof value === "string") {
1807
- const chars = [...value];
1808
- const sliced = this.slice(chars, start, stop, step);
1809
- return sliced.join("");
1810
- } else {
1811
- return this.slice(value, start, stop, step);
1812
- }
1955
+ const target = typeof value === "string" ? [...value] : value;
1956
+ const sliced = this.slice(target, start, stop, step);
1957
+ const res = typeof value === "string" ? sliced.join("") : sliced;
1958
+ this.checkOutputSize(res);
1959
+ return res;
1813
1960
  }
1814
1961
  case "Projection": {
1815
1962
  const { left, right } = node;
1816
- let allowString = false;
1817
- if (left.type === "IndexExpression" && left.right.type === "Slice") {
1818
- allowString = true;
1819
- }
1963
+ const allowString = left.type === "IndexExpression" && left.right.type === "Slice";
1820
1964
  const base = this.visit(left, value);
1821
1965
  if (allowString && typeof base === "string") {
1822
1966
  return this.visit(right, base);
1823
1967
  }
1824
- if (!Array.isArray(base)) {
1825
- return null;
1826
- }
1827
- const collected = [];
1828
- for (const elem of base) {
1829
- const current = this.visit(right, elem);
1830
- if (current !== null) {
1831
- collected.push(current);
1832
- }
1833
- }
1834
- return collected;
1968
+ return Array.isArray(base) ? this.evaluateProjectionItems(base, right) : null;
1835
1969
  }
1836
1970
  case "ValueProjection": {
1837
- const { left, right } = node;
1838
- const base = this.visit(left, value);
1971
+ const base = this.visit(node.left, value);
1839
1972
  if (base === null || typeof base !== "object" || Array.isArray(base)) {
1840
1973
  return null;
1841
1974
  }
1842
- const collected = [];
1843
- const values = Object.values(base);
1844
- for (const elem of values) {
1845
- const current = this.visit(right, elem);
1846
- if (current !== null) {
1847
- collected.push(current);
1848
- }
1849
- }
1850
- return collected;
1975
+ return this.evaluateProjectionItems(Object.values(base), node.right);
1851
1976
  }
1852
1977
  case "FilterProjection": {
1853
1978
  const { left, right, condition } = node;
@@ -1856,14 +1981,42 @@ var jmespath = (function (exports) {
1856
1981
  return null;
1857
1982
  }
1858
1983
  const results = [];
1984
+ if (right.type === "Field") {
1985
+ const key = right.name;
1986
+ for (let i = 0; i < base.length; i++) {
1987
+ const elem = base[i];
1988
+ if (isFalse(this.visit(condition, elem))) {
1989
+ continue;
1990
+ }
1991
+ if (!elem || typeof elem !== "object" || Array.isArray(elem)) {
1992
+ continue;
1993
+ }
1994
+ const val = elem[key];
1995
+ if (val !== void 0 && val !== null) {
1996
+ this.collect(results, val);
1997
+ }
1998
+ }
1999
+ return results;
2000
+ }
2001
+ if (right.type === "Identity") {
2002
+ for (let i = 0; i < base.length; i++) {
2003
+ const elem = base[i];
2004
+ if (isFalse(this.visit(condition, elem))) {
2005
+ continue;
2006
+ }
2007
+ if (elem !== null) {
2008
+ this.collect(results, elem);
2009
+ }
2010
+ }
2011
+ return results;
2012
+ }
1859
2013
  for (const elem of base) {
1860
- const matched = this.visit(condition, elem);
1861
- if (isFalse(matched)) {
2014
+ if (isFalse(this.visit(condition, elem))) {
1862
2015
  continue;
1863
2016
  }
1864
2017
  const result = this.visit(right, elem);
1865
2018
  if (result !== null) {
1866
- results.push(result);
2019
+ this.collect(results, result);
1867
2020
  }
1868
2021
  }
1869
2022
  return results;
@@ -1927,7 +2080,9 @@ var jmespath = (function (exports) {
1927
2080
  }
1928
2081
  case "Flatten": {
1929
2082
  const original = this.visit(node.child, value);
1930
- return Array.isArray(original) ? original.flat() : null;
2083
+ const res = Array.isArray(original) ? original.flat() : null;
2084
+ this.checkOutputSize(res);
2085
+ return res;
1931
2086
  }
1932
2087
  case "Root":
1933
2088
  return this._rootValue;
@@ -1936,6 +2091,7 @@ var jmespath = (function (exports) {
1936
2091
  for (const child of node.children) {
1937
2092
  collected.push(this.visit(child, value));
1938
2093
  }
2094
+ this.checkOutputSize(collected);
1939
2095
  return collected;
1940
2096
  }
1941
2097
  case "MultiSelectHash": {
@@ -1943,6 +2099,7 @@ var jmespath = (function (exports) {
1943
2099
  for (const child of node.children) {
1944
2100
  collected[child.name] = this.visit(child.value, value);
1945
2101
  }
2102
+ this.checkOutputSize(collected);
1946
2103
  return collected;
1947
2104
  }
1948
2105
  case "OrExpression": {
@@ -1966,11 +2123,19 @@ var jmespath = (function (exports) {
1966
2123
  case "Pipe":
1967
2124
  return this.visit(node.right, this.visit(node.left, value));
1968
2125
  case "Function": {
2126
+ if (this._options?.allowedFunctions && !this._options.allowedFunctions.includes(node.name)) {
2127
+ throw new Error(`Function '${node.name}' is not allowed`);
2128
+ }
2129
+ if (this._options?.disallowedFunctions && this._options.disallowedFunctions.includes(node.name)) {
2130
+ throw new Error(`Function '${node.name}' is disallowed`);
2131
+ }
1969
2132
  const args = [];
1970
2133
  for (const child of node.children) {
1971
2134
  args.push(this.visit(child, value));
1972
2135
  }
1973
- return this.runtime.callFunction(node.name, args);
2136
+ const res = this.runtime.callFunction(node.name, args);
2137
+ this.checkOutputSize(res);
2138
+ return res;
1974
2139
  }
1975
2140
  case "ExpressionReference":
1976
2141
  return {
@@ -2008,14 +2173,19 @@ var jmespath = (function (exports) {
2008
2173
  return nextActualValue;
2009
2174
  }
2010
2175
  slice(collection, start, end, step) {
2011
- const result = [];
2176
+ if (step === 1) {
2177
+ return collection.slice(start, end);
2178
+ }
2179
+ const len = Math.ceil(Math.abs(start - end) / Math.abs(step));
2180
+ const result = new Array(len);
2181
+ let idx = 0;
2012
2182
  if (step > 0) {
2013
2183
  for (let i = start; i < end; i += step) {
2014
- result.push(collection[i]);
2184
+ result[idx++] = collection[i];
2015
2185
  }
2016
2186
  } else {
2017
2187
  for (let i = start; i > end; i += step) {
2018
- result.push(collection[i]);
2188
+ result[idx++] = collection[i];
2019
2189
  }
2020
2190
  }
2021
2191
  return result;
@@ -2024,6 +2194,391 @@ var jmespath = (function (exports) {
2024
2194
  var TreeInterpreterInstance = new TreeInterpreter();
2025
2195
  var TreeInterpreter_default = TreeInterpreterInstance;
2026
2196
 
2197
+ // src/Stream.ts
2198
+ async function* toAsyncIterable(source) {
2199
+ if (source == null) {
2200
+ return;
2201
+ }
2202
+ if (typeof source !== "object" && typeof source !== "function") {
2203
+ throw new TypeError("Invalid stream source: expected AsyncIterable, Iterable, or ReadableStream");
2204
+ }
2205
+ if (Symbol.asyncIterator in source) {
2206
+ for await (const chunk of source) {
2207
+ yield chunk;
2208
+ }
2209
+ return;
2210
+ }
2211
+ if (typeof source.getReader === "function") {
2212
+ const reader = source.getReader();
2213
+ try {
2214
+ while (true) {
2215
+ const { done, value } = await reader.read();
2216
+ if (done) {
2217
+ break;
2218
+ }
2219
+ yield value;
2220
+ }
2221
+ } finally {
2222
+ reader.releaseLock();
2223
+ }
2224
+ return;
2225
+ }
2226
+ if (Symbol.iterator in source) {
2227
+ for (const chunk of source) {
2228
+ yield chunk;
2229
+ }
2230
+ return;
2231
+ }
2232
+ throw new TypeError("Invalid stream source: expected AsyncIterable, Iterable, or ReadableStream");
2233
+ }
2234
+ function parseItem(str, parseJson) {
2235
+ if (parseJson === true) {
2236
+ return JSON.parse(str);
2237
+ }
2238
+ if (parseJson === "auto") {
2239
+ try {
2240
+ return JSON.parse(str);
2241
+ } catch {
2242
+ return str;
2243
+ }
2244
+ }
2245
+ return str;
2246
+ }
2247
+ async function* normalizeSource(source, options) {
2248
+ const parseJson = options?.parseJson ?? "auto";
2249
+ const flatten = options?.flattenChunks ?? true;
2250
+ let buffer = "";
2251
+ const textDecoder = typeof TextDecoder !== "undefined" ? new TextDecoder() : null;
2252
+ for await (const chunk of toAsyncIterable(source)) {
2253
+ if (chunk instanceof Uint8Array && textDecoder) {
2254
+ buffer += textDecoder.decode(chunk, { stream: true });
2255
+ if (buffer.includes("\n")) {
2256
+ const lines = buffer.split("\n");
2257
+ buffer = lines.pop() ?? "";
2258
+ for (const line of lines) {
2259
+ const trimmed = line.trim();
2260
+ if (trimmed) {
2261
+ yield parseItem(trimmed, parseJson);
2262
+ }
2263
+ }
2264
+ }
2265
+ } else if (typeof chunk === "string") {
2266
+ if (parseJson === false) {
2267
+ yield chunk;
2268
+ } else {
2269
+ buffer += chunk;
2270
+ if (buffer.includes("\n")) {
2271
+ const lines = buffer.split("\n");
2272
+ buffer = lines.pop() ?? "";
2273
+ for (const line of lines) {
2274
+ const trimmed = line.trim();
2275
+ if (trimmed) {
2276
+ yield parseItem(trimmed, parseJson);
2277
+ }
2278
+ }
2279
+ }
2280
+ }
2281
+ } else if (flatten && Array.isArray(chunk)) {
2282
+ if (buffer.trim()) {
2283
+ yield parseItem(buffer.trim(), parseJson);
2284
+ buffer = "";
2285
+ }
2286
+ for (let i = 0; i < chunk.length; i++) {
2287
+ yield chunk[i];
2288
+ }
2289
+ } else {
2290
+ if (buffer.trim()) {
2291
+ yield parseItem(buffer.trim(), parseJson);
2292
+ buffer = "";
2293
+ }
2294
+ yield chunk;
2295
+ }
2296
+ }
2297
+ if (textDecoder && buffer) {
2298
+ buffer += textDecoder.decode();
2299
+ }
2300
+ if (buffer.trim()) {
2301
+ yield parseItem(buffer.trim(), parseJson);
2302
+ }
2303
+ }
2304
+ function isStreamableNode(node) {
2305
+ switch (node.type) {
2306
+ case "Projection":
2307
+ if (node.left.type === "Identity" || node.left.type === "Current") {
2308
+ return true;
2309
+ }
2310
+ if (node.left.type === "IndexExpression" && node.left.right.type === "Slice") {
2311
+ const slice = node.left.right;
2312
+ return (slice.start === null || slice.start >= 0) && (slice.stop === null || slice.stop >= 0) && (slice.step === null || slice.step > 0);
2313
+ }
2314
+ return false;
2315
+ case "FilterProjection":
2316
+ return node.left.type === "Identity" || node.left.type === "Current";
2317
+ case "IndexExpression":
2318
+ if (node.right.type === "Slice" && (node.left.type === "Identity" || node.left.type === "Current")) {
2319
+ const slice = node.right;
2320
+ return (slice.start === null || slice.start >= 0) && (slice.stop === null || slice.stop >= 0) && (slice.step === null || slice.step > 0);
2321
+ }
2322
+ return true;
2323
+ case "Field":
2324
+ case "Identity":
2325
+ case "Current":
2326
+ case "Subexpression":
2327
+ case "MultiSelectHash":
2328
+ case "MultiSelectList":
2329
+ case "Ternary":
2330
+ case "Comparator":
2331
+ case "Arithmetic":
2332
+ case "NotExpression":
2333
+ return true;
2334
+ case "Pipe":
2335
+ return isStreamableNode(node.left) && isStreamableNode(node.right);
2336
+ default:
2337
+ return false;
2338
+ }
2339
+ }
2340
+ async function* evaluateStreamNode(source, node, interpreter, options) {
2341
+ const deadline = options?.timeoutMs !== void 0 ? Date.now() + options.timeoutMs : 0;
2342
+ function checkDeadline() {
2343
+ if (deadline > 0 && Date.now() >= deadline) {
2344
+ throw new Error(`Query execution timed out after ${options?.timeoutMs}ms`);
2345
+ }
2346
+ }
2347
+ switch (node.type) {
2348
+ case "Projection": {
2349
+ const { left, right } = node;
2350
+ let streamSource = source;
2351
+ if (left.type === "IndexExpression" && left.right.type === "Slice") {
2352
+ streamSource = evaluateStreamNode(source, left, interpreter, options);
2353
+ }
2354
+ if (right.type === "Identity" || right.type === "Current") {
2355
+ for await (const item of streamSource) {
2356
+ checkDeadline();
2357
+ if (item !== null && item !== void 0) {
2358
+ yield item;
2359
+ }
2360
+ }
2361
+ return;
2362
+ }
2363
+ if (right.type === "Field") {
2364
+ const key = right.name;
2365
+ for await (const item of streamSource) {
2366
+ checkDeadline();
2367
+ if (item && typeof item === "object" && !Array.isArray(item)) {
2368
+ const val = item[key];
2369
+ if (val !== void 0 && val !== null) {
2370
+ yield val;
2371
+ }
2372
+ }
2373
+ }
2374
+ return;
2375
+ }
2376
+ for await (const item of streamSource) {
2377
+ checkDeadline();
2378
+ const res = interpreter.visit(right, item);
2379
+ if (res !== null && res !== void 0) {
2380
+ yield res;
2381
+ }
2382
+ }
2383
+ return;
2384
+ }
2385
+ case "IndexExpression": {
2386
+ if (node.right.type === "Slice" && (node.left.type === "Identity" || node.left.type === "Current")) {
2387
+ const slice = node.right;
2388
+ const start = slice.start ?? 0;
2389
+ const stop = slice.stop ?? Infinity;
2390
+ const step = slice.step ?? 1;
2391
+ if (start >= 0 && stop >= 0 && step > 0) {
2392
+ let index = 0;
2393
+ for await (const item of source) {
2394
+ checkDeadline();
2395
+ if (index >= stop) {
2396
+ break;
2397
+ }
2398
+ if (index >= start && (index - start) % step === 0) {
2399
+ yield item;
2400
+ }
2401
+ index++;
2402
+ if (index >= stop) {
2403
+ break;
2404
+ }
2405
+ }
2406
+ return;
2407
+ }
2408
+ const collected = [];
2409
+ for await (const item of source) {
2410
+ checkDeadline();
2411
+ collected.push(item);
2412
+ if (options?.maxOutputSize !== void 0 && collected.length > options.maxOutputSize) {
2413
+ throw new Error(`Output size exceeds maximum allowed size of ${options.maxOutputSize}`);
2414
+ }
2415
+ }
2416
+ const result = interpreter.search(node, collected, options);
2417
+ if (Array.isArray(result)) {
2418
+ for (const item of result) {
2419
+ yield item;
2420
+ }
2421
+ }
2422
+ return;
2423
+ }
2424
+ for await (const item of source) {
2425
+ checkDeadline();
2426
+ const res = interpreter.visit(node, item);
2427
+ if (res !== null && res !== void 0) {
2428
+ yield res;
2429
+ }
2430
+ }
2431
+ return;
2432
+ }
2433
+ case "FilterProjection": {
2434
+ const { condition, right } = node;
2435
+ if (right.type === "Identity" || right.type === "Current") {
2436
+ for await (const item of source) {
2437
+ checkDeadline();
2438
+ if (!isFalse(interpreter.visit(condition, item))) {
2439
+ yield item;
2440
+ }
2441
+ }
2442
+ return;
2443
+ }
2444
+ if (right.type === "Field") {
2445
+ const key = right.name;
2446
+ for await (const item of source) {
2447
+ checkDeadline();
2448
+ if (!isFalse(interpreter.visit(condition, item))) {
2449
+ if (item && typeof item === "object" && !Array.isArray(item)) {
2450
+ const val = item[key];
2451
+ if (val !== void 0 && val !== null) {
2452
+ yield val;
2453
+ }
2454
+ }
2455
+ }
2456
+ }
2457
+ return;
2458
+ }
2459
+ for await (const item of source) {
2460
+ checkDeadline();
2461
+ if (!isFalse(interpreter.visit(condition, item))) {
2462
+ const res = interpreter.visit(right, item);
2463
+ if (res !== null && res !== void 0) {
2464
+ yield res;
2465
+ }
2466
+ }
2467
+ }
2468
+ return;
2469
+ }
2470
+ case "Pipe": {
2471
+ const leftStream = evaluateStreamNode(source, node.left, interpreter, options);
2472
+ if (isStreamableNode(node.right)) {
2473
+ for await (const res of evaluateStreamNode(leftStream, node.right, interpreter, options)) {
2474
+ yield res;
2475
+ }
2476
+ } else {
2477
+ const collected = [];
2478
+ for await (const item of leftStream) {
2479
+ checkDeadline();
2480
+ collected.push(item);
2481
+ if (options?.maxOutputSize !== void 0 && collected.length > options.maxOutputSize) {
2482
+ throw new Error(`Output size exceeds maximum allowed size of ${options.maxOutputSize}`);
2483
+ }
2484
+ }
2485
+ const result = interpreter.search(node.right, collected, options);
2486
+ if (result !== null && result !== void 0) {
2487
+ yield result;
2488
+ }
2489
+ }
2490
+ return;
2491
+ }
2492
+ case "Identity":
2493
+ case "Current": {
2494
+ for await (const item of source) {
2495
+ checkDeadline();
2496
+ yield item;
2497
+ }
2498
+ return;
2499
+ }
2500
+ case "Field": {
2501
+ const key = node.name;
2502
+ for await (const item of source) {
2503
+ checkDeadline();
2504
+ if (item && typeof item === "object" && !Array.isArray(item)) {
2505
+ const val = item[key];
2506
+ if (val !== void 0 && val !== null) {
2507
+ yield val;
2508
+ }
2509
+ }
2510
+ }
2511
+ return;
2512
+ }
2513
+ default: {
2514
+ if (isStreamableNode(node)) {
2515
+ for await (const item of source) {
2516
+ checkDeadline();
2517
+ const res = interpreter.visit(node, item);
2518
+ if (res !== null && res !== void 0) {
2519
+ yield res;
2520
+ }
2521
+ }
2522
+ return;
2523
+ }
2524
+ const collected = [];
2525
+ for await (const item of source) {
2526
+ checkDeadline();
2527
+ collected.push(item);
2528
+ if (options?.maxOutputSize !== void 0 && collected.length > options.maxOutputSize) {
2529
+ throw new Error(`Output size exceeds maximum allowed size of ${options.maxOutputSize}`);
2530
+ }
2531
+ }
2532
+ const result = interpreter.search(node, collected, options);
2533
+ if (result !== null && result !== void 0) {
2534
+ yield result;
2535
+ }
2536
+ return;
2537
+ }
2538
+ }
2539
+ }
2540
+ function isExpressionNode(val) {
2541
+ return typeof val === "object" && val !== null && "type" in val && typeof val.type === "string" && !(Symbol.iterator in val) && !(Symbol.asyncIterator in val);
2542
+ }
2543
+ async function* searchStream(sourceOrExpression, expressionOrSource, options) {
2544
+ let expression;
2545
+ let source;
2546
+ if (typeof sourceOrExpression === "string" || isExpressionNode(sourceOrExpression)) {
2547
+ expression = sourceOrExpression;
2548
+ source = expressionOrSource;
2549
+ } else {
2550
+ source = sourceOrExpression;
2551
+ expression = expressionOrSource;
2552
+ }
2553
+ if (typeof expression !== "string" && !isExpressionNode(expression)) {
2554
+ throw new TypeError("Expression must be a string or AST ExpressionNode");
2555
+ }
2556
+ const ast = typeof expression === "string" ? Parser_default.parse(expression, options) : expression;
2557
+ if (options) {
2558
+ const fnError = findDisallowedFunction(ast, options);
2559
+ if (fnError) {
2560
+ throw new Error(fnError);
2561
+ }
2562
+ }
2563
+ const interpreter = new TreeInterpreter(options);
2564
+ interpreter.runtime._functionTable = TreeInterpreterInstance.runtime._functionTable;
2565
+ const items = normalizeSource(source, options);
2566
+ const results = evaluateStreamNode(items, ast, interpreter, options);
2567
+ const limit = options?.limit;
2568
+ const maxOutputSize = options?.maxOutputSize;
2569
+ let count = 0;
2570
+ for await (const result of results) {
2571
+ yield result;
2572
+ count++;
2573
+ if (limit !== void 0 && count >= limit) {
2574
+ break;
2575
+ }
2576
+ if (maxOutputSize !== void 0 && count > maxOutputSize) {
2577
+ throw new Error(`Output size exceeds maximum allowed size of ${maxOutputSize}`);
2578
+ }
2579
+ }
2580
+ }
2581
+
2027
2582
  // src/index.ts
2028
2583
  var TYPE_ANY = 1 /* TYPE_ANY */;
2029
2584
  var TYPE_ARRAY = 3 /* TYPE_ARRAY */;
@@ -2038,8 +2593,37 @@ var jmespath = (function (exports) {
2038
2593
  var TYPE_OBJECT = 4 /* TYPE_OBJECT */;
2039
2594
  var TYPE_STRING = 2 /* TYPE_STRING */;
2040
2595
  function compile(expression, options) {
2596
+ return Parser_default.parse(expression, options);
2597
+ }
2598
+ function compileQuery(expression, options) {
2041
2599
  const nodeTree = Parser_default.parse(expression, options);
2042
- return nodeTree;
2600
+ const fn = function(data) {
2601
+ return TreeInterpreter_default.search(nodeTree, data, options);
2602
+ };
2603
+ fn.search = (data) => TreeInterpreter_default.search(nodeTree, data, options);
2604
+ fn.searchStream = (source, streamOptions) => searchStream(source, nodeTree, { ...options, ...streamOptions });
2605
+ fn.ast = nodeTree;
2606
+ return fn;
2607
+ }
2608
+ function validate(expression, options) {
2609
+ if (typeof expression !== "string") {
2610
+ return { valid: false, error: "Expression must be a string" };
2611
+ }
2612
+ try {
2613
+ const ast = Parser_default.parse(expression, options);
2614
+ if (options) {
2615
+ const fnError = findDisallowedFunction(ast, options);
2616
+ if (fnError) {
2617
+ return { valid: false, error: fnError };
2618
+ }
2619
+ }
2620
+ return { valid: true, ast };
2621
+ } catch (err) {
2622
+ return {
2623
+ valid: false,
2624
+ error: err instanceof Error ? err.message : String(err)
2625
+ };
2626
+ }
2043
2627
  }
2044
2628
  function tokenize(expression, options) {
2045
2629
  return Lexer_default.tokenize(expression, options);
@@ -2065,9 +2649,26 @@ var jmespath = (function (exports) {
2065
2649
  var clearCustomFunctions = () => {
2066
2650
  TreeInterpreter_default.runtime.clearCustomFunctions();
2067
2651
  };
2652
+ var MAX_CACHE_SIZE = 1e3;
2653
+ var astCache = /* @__PURE__ */ new Map();
2068
2654
  function search(data, expression, options) {
2069
- const nodeTree = Parser_default.parse(expression, options);
2070
- return TreeInterpreter_default.search(nodeTree, data);
2655
+ let nodeTree;
2656
+ if (!options) {
2657
+ nodeTree = astCache.get(expression);
2658
+ if (!nodeTree) {
2659
+ nodeTree = Parser_default.parse(expression);
2660
+ if (astCache.size >= MAX_CACHE_SIZE) {
2661
+ const firstKey = astCache.keys().next().value;
2662
+ if (firstKey !== void 0) {
2663
+ astCache.delete(firstKey);
2664
+ }
2665
+ }
2666
+ astCache.set(expression, nodeTree);
2667
+ }
2668
+ } else {
2669
+ nodeTree = Parser_default.parse(expression, options);
2670
+ }
2671
+ return TreeInterpreter_default.search(nodeTree, data, options);
2071
2672
  }
2072
2673
  function Scope() {
2073
2674
  return new ScopeChain();
@@ -2075,6 +2676,9 @@ var jmespath = (function (exports) {
2075
2676
  var TreeInterpreter2 = TreeInterpreter_default;
2076
2677
  var jmespath = {
2077
2678
  compile,
2679
+ compileQuery,
2680
+ searchStream,
2681
+ validate,
2078
2682
  registerFunction,
2079
2683
  register,
2080
2684
  unregisterFunction,
@@ -2094,40 +2698,15 @@ var jmespath = (function (exports) {
2094
2698
  TYPE_NULL,
2095
2699
  TYPE_NUMBER,
2096
2700
  TYPE_OBJECT,
2097
- TYPE_STRING
2701
+ TYPE_STRING,
2702
+ TYPE_ARRAY_ARRAY,
2703
+ TYPE_ARRAY_OBJECT,
2704
+ Scope
2098
2705
  };
2706
+ var index_default = jmespath;
2099
2707
 
2100
- exports.Scope = Scope;
2101
- exports.TYPE_ANY = TYPE_ANY;
2102
- exports.TYPE_ARRAY = TYPE_ARRAY;
2103
- exports.TYPE_ARRAY_ARRAY = TYPE_ARRAY_ARRAY;
2104
- exports.TYPE_ARRAY_NUMBER = TYPE_ARRAY_NUMBER;
2105
- exports.TYPE_ARRAY_OBJECT = TYPE_ARRAY_OBJECT;
2106
- exports.TYPE_ARRAY_STRING = TYPE_ARRAY_STRING;
2107
- exports.TYPE_BOOLEAN = TYPE_BOOLEAN;
2108
- exports.TYPE_EXPREF = TYPE_EXPREF;
2109
- exports.TYPE_NULL = TYPE_NULL;
2110
- exports.TYPE_NUMBER = TYPE_NUMBER;
2111
- exports.TYPE_OBJECT = TYPE_OBJECT;
2112
- exports.TYPE_STRING = TYPE_STRING;
2113
- exports.TreeInterpreter = TreeInterpreter2;
2114
- exports.clearCustomFunctions = clearCustomFunctions;
2115
- exports.compile = compile;
2116
- exports.default = jmespath;
2117
- exports.getCustomFunctions = getCustomFunctions;
2118
- exports.getRegisteredFunctions = getRegisteredFunctions;
2119
- exports.isRegistered = isRegistered;
2120
- exports.jmespath = jmespath;
2121
- exports.register = register;
2122
- exports.registerFunction = registerFunction;
2123
- exports.search = search;
2124
- exports.tokenize = tokenize;
2125
- exports.unregisterFunction = unregisterFunction;
2126
-
2127
- Object.defineProperty(exports, '__esModule', { value: true });
2128
-
2129
- return exports;
2708
+ return index_default;
2130
2709
 
2131
- })({});
2710
+ })();
2132
2711
  //# sourceMappingURL=index.umd.js.map
2133
2712
  //# sourceMappingURL=index.umd.js.map