@poe-platform/safe-bash 0.1.439 → 0.1.441

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.
@@ -7205,6 +7205,57 @@ async function matchesPattern(pattern, value2, work) {
7205
7205
  reservation?.release();
7206
7206
  }
7207
7207
  }
7208
+ async function compilePatternBoundaries(pattern, work) {
7209
+ work.signal.throwIfAborted();
7210
+ const { patternTokens } = await tokens(pattern, work);
7211
+ return async (value2, shortest = false, suffix2 = false) => {
7212
+ let rowReservation;
7213
+ let resultReservation;
7214
+ try {
7215
+ const rowSize = patternTokens.length + 1;
7216
+ const resultSize = value2.length + 1;
7217
+ const initialized = stringCheckpoint(work, rowSize + resultSize);
7218
+ if (initialized) await initialized;
7219
+ rowReservation = work.allocation?.reserve(64 + rowSize * 8, 0);
7220
+ resultReservation = work.allocation?.reserve(64 + resultSize * 8, 0);
7221
+ const row = new Float64Array(rowSize).fill(-1);
7222
+ const ends = new Float64Array(resultSize).fill(-1);
7223
+ let position = value2.length;
7224
+ while (true) {
7225
+ const advanced = stringCheckpoint(work);
7226
+ if (advanced) await advanced;
7227
+ const point = position < value2.length ? value2.codePointAt(position) : void 0;
7228
+ let diagonal = row[patternTokens.length];
7229
+ row[patternTokens.length] = !suffix2 || position === value2.length ? position : -1;
7230
+ for (let index = patternTokens.length - 1; index >= 0; index--) {
7231
+ const pending = stringCheckpoint(work);
7232
+ if (pending) await pending;
7233
+ const previous = row[index];
7234
+ const token = patternTokens[index];
7235
+ if (token.kind === "star") {
7236
+ const skip = row[index + 1];
7237
+ const consume = point === void 0 ? -1 : previous;
7238
+ row[index] = skip < 0 ? consume : consume < 0 ? skip : shortest ? Math.min(skip, consume) : Math.max(skip, consume);
7239
+ } else {
7240
+ const accepts = point !== void 0 && (token.kind === "any" || (token.kind === "literal" ? token.value.codePointAt(0) === point : token.expression.test(String.fromCodePoint(point))));
7241
+ row[index] = accepts ? diagonal : -1;
7242
+ }
7243
+ diagonal = previous;
7244
+ }
7245
+ ends[position] = row[0];
7246
+ if (position === 0) break;
7247
+ position = previousCodePointOffset(value2, position);
7248
+ }
7249
+ work.signal.throwIfAborted();
7250
+ return ends;
7251
+ } catch (error) {
7252
+ resultReservation?.release();
7253
+ throw error;
7254
+ } finally {
7255
+ rowReservation?.release();
7256
+ }
7257
+ };
7258
+ }
7208
7259
  async function matchTokens(patternTokens, value2, work, start, end) {
7209
7260
  work.signal.throwIfAborted();
7210
7261
  let position = start;
@@ -16786,19 +16837,17 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
16786
16837
  scratch.reserve(patternUnits * 2, 0);
16787
16838
  const pattern = patternFields.join("");
16788
16839
  const size = (await scanString(text3, work)).count;
16789
- const matches3 = await compilePattern(pattern, work);
16790
- const match = async (start, end, length) => {
16791
- const pending = stringCheckpoint(work, length + 1);
16792
- if (pending) await pending;
16793
- return matches3(text3, start, end);
16794
- };
16840
+ const boundaries = await compilePatternBoundaries(pattern, work);
16795
16841
  const operator = part.operator;
16796
16842
  if (!operator.startsWith("/")) {
16797
16843
  const longest = operator.length === 2;
16798
16844
  const prefix3 = operator.startsWith("#");
16845
+ const ends2 = await boundaries(text3, !longest && prefix3, !prefix3);
16799
16846
  let boundary = longest === prefix3 ? text3.length : 0;
16800
16847
  for (let length = longest ? size : 0; longest ? length >= 0 : length <= size; length += longest ? -1 : 1) {
16801
- if (await match(prefix3 ? 0 : boundary, prefix3 ? boundary : text3.length, length)) {
16848
+ const pending = stringCheckpoint(work);
16849
+ if (pending) await pending;
16850
+ if (ends2[prefix3 ? 0 : boundary] === (prefix3 ? boundary : text3.length)) {
16802
16851
  const start = prefix3 ? boundary : 0;
16803
16852
  const end = prefix3 ? text3.length : boundary;
16804
16853
  scratch.reserve((end - start) * 2, 0);
@@ -16841,49 +16890,49 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
16841
16890
  retained?.release();
16842
16891
  retained = next;
16843
16892
  };
16893
+ const ends = await boundaries(text3, false, operator === "/%");
16844
16894
  let position = 0;
16845
- let positionIndex = 0;
16846
- while (positionIndex <= size) {
16895
+ while (position <= text3.length) {
16847
16896
  let found = false;
16848
- for (let start = position, startIndex2 = positionIndex; startIndex2 <= size; startIndex2++, start = nextCodePointOffset(text3, start)) {
16897
+ for (let start = position; start <= text3.length; start = nextCodePointOffset(text3, start)) {
16849
16898
  if (operator === "/#" && start !== 0) break;
16850
- for (let end = text3.length, endIndex = size; endIndex >= startIndex2; endIndex--, end = previousCodePointOffset(text3, end)) {
16851
- if (operator === "/%" && end !== text3.length) break;
16852
- if (!await match(start, end, endIndex - startIndex2)) continue;
16853
- await append(text3, position, start);
16854
- for (const replacement of replacements) {
16855
- if (replacement.quoted) await append(replacement.value);
16856
- else {
16857
- let fragment = 0;
16858
- for (let cursor = 0; cursor < replacement.value.length; cursor++) {
16859
- const pending = stringCheckpoint(work);
16860
- if (pending) await pending;
16861
- if (replacement.value[cursor] !== "&") continue;
16862
- await append(replacement.value, fragment, cursor);
16863
- await append(text3, start, end);
16864
- fragment = cursor + 1;
16865
- }
16866
- await append(replacement.value, fragment);
16899
+ const pending = stringCheckpoint(work);
16900
+ if (pending) await pending;
16901
+ const end = ends[start];
16902
+ if (end < 0) {
16903
+ if (start === text3.length) break;
16904
+ continue;
16905
+ }
16906
+ await append(text3, position, start);
16907
+ for (const replacement of replacements) {
16908
+ if (replacement.quoted) await append(replacement.value);
16909
+ else {
16910
+ let fragment = 0;
16911
+ for (let cursor = 0; cursor < replacement.value.length; cursor++) {
16912
+ const pending2 = stringCheckpoint(work);
16913
+ if (pending2) await pending2;
16914
+ if (replacement.value[cursor] !== "&") continue;
16915
+ await append(replacement.value, fragment, cursor);
16916
+ await append(text3, start, end);
16917
+ fragment = cursor + 1;
16867
16918
  }
16919
+ await append(replacement.value, fragment);
16868
16920
  }
16869
- position = end;
16870
- positionIndex = endIndex;
16871
- found = true;
16872
- if (operator !== "//" || end === text3.length) {
16873
- await append(text3, end);
16874
- return result2;
16875
- }
16876
- if (end === start) {
16877
- position = nextCodePointOffset(text3, end);
16878
- positionIndex++;
16879
- await append(text3, end, position);
16880
- }
16881
- break;
16882
16921
  }
16883
- if (found) break;
16922
+ position = end;
16923
+ found = true;
16924
+ if (operator !== "//" || end === text3.length) {
16925
+ await append(text3, end);
16926
+ return result2;
16927
+ }
16928
+ if (end === start) {
16929
+ position = nextCodePointOffset(text3, end);
16930
+ await append(text3, end, position);
16931
+ }
16932
+ break;
16884
16933
  }
16885
16934
  if (!found) {
16886
- if (positionIndex === 0) return text3;
16935
+ if (position === 0) return text3;
16887
16936
  await append(text3, position);
16888
16937
  break;
16889
16938
  }
@@ -24391,40 +24440,117 @@ async function* rawValues(sources2, budget, slurp) {
24391
24440
  yield buffer;
24392
24441
  }
24393
24442
  }
24394
- function stringify(value2, budget, pretty = false, maxBytes = budget.limits.maxValueBytes, limitName = "maxValueBytes") {
24443
+ function* quotedFragments(value2, budget) {
24444
+ yield { text: '"', bytes: 1 };
24445
+ let offset = 0;
24446
+ while (offset < value2.length) {
24447
+ const start = offset;
24448
+ const limit = Math.min(start + 32, value2.length);
24449
+ budget.step(limit - start);
24450
+ let bytes3 = 0;
24451
+ while (offset < limit) {
24452
+ const code = value2.charCodeAt(offset);
24453
+ if (code >= 55296 && code <= 56319 && offset + 1 === limit && limit < value2.length) break;
24454
+ if (code >= 55296 && code <= 56319 && offset + 1 < limit) {
24455
+ const next = value2.charCodeAt(offset + 1);
24456
+ if (next >= 56320 && next <= 57343) {
24457
+ bytes3 += 4;
24458
+ offset += 2;
24459
+ continue;
24460
+ }
24461
+ }
24462
+ if (code === 34 || code === 92 || code === 8 || code === 9 || code === 10 || code === 12 || code === 13) bytes3 += 2;
24463
+ else if (code < 32 || code >= 55296 && code <= 57343) bytes3 += 6;
24464
+ else bytes3 += code < 128 ? 1 : code < 2048 ? 2 : 3;
24465
+ offset++;
24466
+ }
24467
+ yield { value: value2, start, end: offset, bytes: bytes3, quoted: true };
24468
+ }
24469
+ yield { text: '"', bytes: 1 };
24470
+ }
24471
+ function renderJsonFragment(fragment, budget) {
24472
+ if ("text" in fragment) return fragment.text;
24473
+ budget.step(fragment.end - fragment.start);
24474
+ const text3 = fragment.value.slice(fragment.start, fragment.end);
24475
+ return fragment.quoted ? JSON.stringify(text3).slice(1, -1) : text3;
24476
+ }
24477
+ function* jsonFragments(value2, budget, pretty = false, depth = 0) {
24478
+ budget.step();
24479
+ if (depth > budget.limits.maxDepth) throw new JqLimitError("maxDepth");
24480
+ if (typeof value2 === "string") {
24481
+ yield* quotedFragments(value2, budget);
24482
+ return;
24483
+ }
24484
+ if (value2 === null || typeof value2 !== "object" || isNumber(value2)) {
24485
+ const text3 = scalarJson(value2, budget);
24486
+ for (let start = 0; start < text3.length; start += 32) {
24487
+ const end = Math.min(start + 32, text3.length);
24488
+ budget.step(end - start);
24489
+ yield { value: text3, start, end, bytes: end - start, quoted: false };
24490
+ }
24491
+ return;
24492
+ }
24493
+ if (depth + 1 > budget.limits.maxDepth) throw new JqLimitError("maxDepth");
24494
+ const array2 = Array.isArray(value2);
24495
+ if (array2) budget.collection(value2.length);
24496
+ yield { text: array2 ? "[" : "{", bytes: 1 };
24497
+ let count2 = 0;
24498
+ const keys = array2 ? value2.keys() : objectKeyIterator(value2);
24499
+ for (const key of keys) {
24500
+ budget.step();
24501
+ budget.collection(count2 + 1);
24502
+ if (count2++) yield { text: ",", bytes: 1 };
24503
+ if (pretty) {
24504
+ const bytes3 = 1 + 2 * (depth + 1);
24505
+ budget.step(bytes3);
24506
+ yield { text: `
24507
+ ${" ".repeat(depth + 1)}`, bytes: bytes3 };
24508
+ }
24509
+ if (!array2) {
24510
+ yield* quotedFragments(String(key), budget);
24511
+ yield { text: pretty ? ": " : ":", bytes: pretty ? 2 : 1 };
24512
+ }
24513
+ yield* jsonFragments(value2[key], budget, pretty, depth + 1);
24514
+ }
24515
+ if (pretty && count2) {
24516
+ const bytes3 = 1 + 2 * depth;
24517
+ budget.step(bytes3);
24518
+ yield { text: `
24519
+ ${" ".repeat(depth)}`, bytes: bytes3 };
24520
+ }
24521
+ yield { text: array2 ? "]" : "}", bytes: 1 };
24522
+ }
24523
+ async function measureValue(value2, budget, depth = 0, maxBytes = budget.limits.maxValueBytes) {
24524
+ await budget.tick(0);
24525
+ let bytes3 = 0;
24526
+ for (const fragment of jsonFragments(value2, budget, false, depth)) {
24527
+ await budget.tick(0);
24528
+ bytes3 += fragment.bytes;
24529
+ if (bytes3 > maxBytes) throw new JqLimitError("maxValueBytes");
24530
+ }
24531
+ return bytes3;
24532
+ }
24533
+ async function stringify(value2, budget, pretty = false, maxBytes = budget.limits.maxValueBytes, limitName = "maxValueBytes", asStringValue = false) {
24534
+ await budget.tick(0);
24395
24535
  const parts2 = [];
24396
24536
  let bytes3 = 0;
24397
- const append = (text3) => {
24398
- bytes3 += import_buffer.Buffer.byteLength(text3);
24537
+ let units = 0;
24538
+ let stringBytes = 2;
24539
+ for (const fragment of jsonFragments(value2, budget, pretty)) {
24540
+ await budget.tick(0);
24541
+ bytes3 += fragment.bytes;
24399
24542
  if (bytes3 > maxBytes) throw new JqLimitError(limitName);
24400
- parts2.push(text3);
24401
- };
24402
- const visit = (current, depth) => {
24403
- budget.step();
24404
- if (depth > budget.limits.maxDepth) throw new JqLimitError("maxDepth");
24405
- if (current === null || typeof current !== "object" || isNumber(current)) {
24406
- append(scalarJson(current, budget));
24407
- return;
24543
+ const text3 = renderJsonFragment(fragment, budget);
24544
+ if (asStringValue) {
24545
+ for (const encoded2 of quotedFragments(text3, budget)) stringBytes += encoded2.bytes;
24546
+ stringBytes -= 2;
24547
+ if (stringBytes > budget.limits.maxValueBytes) throw new JqLimitError("maxValueBytes");
24408
24548
  }
24409
- const keys = Array.isArray(current) ? Object.keys(current) : objectKeys(current);
24410
- const array2 = Array.isArray(current);
24411
- append(array2 ? "[" : "{");
24412
- for (let index = 0; index < keys.length; index++) {
24413
- if (index) append(",");
24414
- if (pretty) append(`
24415
- ${" ".repeat(depth + 1)}`);
24416
- const key = keys[index];
24417
- if (!array2) {
24418
- append(JSON.stringify(key));
24419
- append(pretty ? ": " : ":");
24420
- }
24421
- visit(current[key], depth + 1);
24422
- }
24423
- if (pretty && keys.length) append(`
24424
- ${" ".repeat(depth)}`);
24425
- append(array2 ? "]" : "}");
24426
- };
24427
- visit(value2, 0);
24549
+ budget.step();
24550
+ units += text3.length;
24551
+ parts2.push(text3);
24552
+ }
24553
+ await budget.tick(units);
24428
24554
  return parts2.join("");
24429
24555
  }
24430
24556
 
@@ -24501,8 +24627,19 @@ function type(value2) {
24501
24627
  return value2 === null ? "null" : isNumber(value2) ? "number" : Array.isArray(value2) ? "array" : typeof value2;
24502
24628
  }
24503
24629
  function describe(value2, budget) {
24504
- const bytes3 = import_buffer.Buffer.from(stringify(value2, budget));
24505
- const text3 = bytes3.length < 15 ? bytes3.toString() : `${bytes3.subarray(0, 11).toString()}...`;
24630
+ const parts2 = [];
24631
+ let length = 0;
24632
+ for (const fragment of jsonFragments(value2, budget)) {
24633
+ const text4 = renderJsonFragment(fragment, budget);
24634
+ budget.step(text4.length);
24635
+ const bytes4 = import_buffer.Buffer.from(text4);
24636
+ const retained = Math.min(15 - length, bytes4.length);
24637
+ parts2.push(bytes4.subarray(0, retained));
24638
+ length += retained;
24639
+ if (length === 15) break;
24640
+ }
24641
+ const bytes3 = import_buffer.Buffer.concat(parts2, length);
24642
+ const text3 = length < 15 ? bytes3.toString() : `${bytes3.subarray(0, 11).toString()}...`;
24506
24643
  return `${type(value2)} (${text3})`;
24507
24644
  }
24508
24645
  async function stringCompare(left, right, budget) {
@@ -24598,15 +24735,24 @@ function equal(left, right, budget) {
24598
24735
  }
24599
24736
  return false;
24600
24737
  }
24601
- function entries(value2, budget) {
24738
+ async function* entries(value2, budget) {
24739
+ budget.signal.throwIfAborted();
24602
24740
  if (Array.isArray(value2)) {
24603
24741
  budget.collection(value2.length);
24604
- return value2.map((item, index) => [index, item]);
24742
+ for (let index = 0; index < value2.length; index++) {
24743
+ await budget.tick(2);
24744
+ yield [index, value2[index]];
24745
+ }
24746
+ return;
24605
24747
  }
24606
24748
  if (isObject(value2)) {
24607
- const keys = objectKeys(value2);
24608
- budget.collection(keys.length);
24609
- return keys.map((key) => [key, value2[key]]);
24749
+ let count2 = 0;
24750
+ for (const key of objectKeyIterator(value2)) {
24751
+ await budget.tick(2);
24752
+ budget.collection(++count2);
24753
+ yield [key, value2[key]];
24754
+ }
24755
+ return;
24610
24756
  }
24611
24757
  throw new JqError(`Cannot iterate over ${describe(value2, budget)}`);
24612
24758
  }
@@ -24845,7 +24991,7 @@ var Interpreter = class _Interpreter {
24845
24991
  }
24846
24992
  return;
24847
24993
  case "iterate":
24848
- for await (const base of this.run(ast.base, input3)) for (const [, value2] of entries(base, this.budget)) {
24994
+ for await (const base of this.run(ast.base, input3)) for await (const [, value2] of entries(base, this.budget)) {
24849
24995
  await this.budget.tick();
24850
24996
  yield value2;
24851
24997
  }
@@ -24981,7 +25127,7 @@ var Interpreter = class _Interpreter {
24981
25127
  for await (const path of this.paths(ast.base, input3)) {
24982
25128
  let base = input3;
24983
25129
  for (const component of path) base = indexValue(base, component);
24984
- for (const [key] of entries(base, this.budget)) {
25130
+ for await (const [key] of entries(base, this.budget)) {
24985
25131
  await this.budget.tick();
24986
25132
  yield [...path, key];
24987
25133
  }
@@ -25102,24 +25248,66 @@ var Interpreter = class _Interpreter {
25102
25248
  if (input3 === null) yield 0;
25103
25249
  else if (isNumber(input3)) yield Math.abs(numberValue(input3));
25104
25250
  else if (typeof input3 === "string") {
25251
+ await budget.tick(input3.length);
25105
25252
  let length = 0;
25106
- for (const ignoredEntry of input3) length++;
25253
+ for (let offset = 0; offset < input3.length; length++) {
25254
+ if (length % 32 === 0) await budget.tick(0);
25255
+ offset += input3.codePointAt(offset) > 65535 ? 2 : 1;
25256
+ }
25107
25257
  yield length;
25108
25258
  } else if (Array.isArray(input3)) yield input3.length;
25109
- else if (isObject(input3)) yield objectKeys(input3).length;
25110
- else throw new JqError("boolean has no length");
25259
+ else if (isObject(input3)) {
25260
+ let length = 0;
25261
+ for (const key of objectKeyIterator(input3)) {
25262
+ await budget.tick();
25263
+ void key;
25264
+ length++;
25265
+ }
25266
+ yield length;
25267
+ } else throw new JqError("boolean has no length");
25111
25268
  return;
25112
25269
  }
25113
25270
  if (name2 === "keys" || name2 === "keys_unsorted") {
25114
- if (Array.isArray(input3)) yield input3.map((_, index) => index);
25115
- else if (isObject(input3)) yield name2 === "keys" ? await sortedKeys(input3, budget) : objectKeys(input3);
25116
- else throw new JqError("keys requires an object or array");
25271
+ let result2;
25272
+ if (Array.isArray(input3)) {
25273
+ budget.collection(input3.length);
25274
+ await budget.tick(input3.length);
25275
+ result2 = [];
25276
+ let bytes3 = 2;
25277
+ if (bytes3 > budget.limits.maxValueBytes) throw new JqLimitError("maxValueBytes");
25278
+ for (let index = 0; index < input3.length; index++) {
25279
+ await budget.tick();
25280
+ bytes3 += String(index).length + (index ? 1 : 0);
25281
+ if (bytes3 > budget.limits.maxValueBytes) throw new JqLimitError("maxValueBytes");
25282
+ result2.push(index);
25283
+ }
25284
+ } else if (isObject(input3)) {
25285
+ let bytes3 = 2;
25286
+ let count2 = 0;
25287
+ if (bytes3 > budget.limits.maxValueBytes) throw new JqLimitError("maxValueBytes");
25288
+ for (const key of objectKeyIterator(input3)) {
25289
+ await budget.tick();
25290
+ budget.collection(++count2);
25291
+ const separator = count2 > 1 ? 1 : 0;
25292
+ bytes3 += separator + await measureValue(key, budget, 1, budget.limits.maxValueBytes - bytes3 - separator);
25293
+ }
25294
+ if (name2 === "keys") result2 = await sortedKeys(input3, budget);
25295
+ else {
25296
+ result2 = [];
25297
+ for (const key of objectKeyIterator(input3)) {
25298
+ await budget.tick();
25299
+ budget.collection(result2.length + 1);
25300
+ result2.push(key);
25301
+ }
25302
+ }
25303
+ } else throw new JqError("keys requires an object or array");
25304
+ yield result2;
25117
25305
  return;
25118
25306
  }
25119
25307
  if (name2 === "map" || name2 === "map_values") {
25120
25308
  const result2 = name2 === "map_values" && isObject(input3) ? object() : [];
25121
25309
  let bytes3 = 2;
25122
- for (const [key, value2] of entries(input3, budget)) for await (const mapped of this.run(args[0], value2)) {
25310
+ for await (const [key, value2] of entries(input3, budget)) for await (const mapped of this.run(args[0], value2)) {
25123
25311
  bytes3 += budget.value(mapped) + 1 + (Array.isArray(result2) ? 0 : import_buffer.Buffer.byteLength(JSON.stringify(String(key))) + 1);
25124
25312
  if (bytes3 - 1 > budget.limits.maxValueBytes) throw new JqLimitError("maxValueBytes");
25125
25313
  if (Array.isArray(result2)) {
@@ -25161,7 +25349,7 @@ var Interpreter = class _Interpreter {
25161
25349
  if (bytes3 > budget.limits.maxValueBytes) throw new JqLimitError("maxValueBytes");
25162
25350
  result2 += text3;
25163
25351
  };
25164
- for (const [, item] of entries(input3, budget)) {
25352
+ for await (const [, item] of entries(input3, budget)) {
25165
25353
  await budget.tick();
25166
25354
  if (!first && separator !== null) {
25167
25355
  if (typeof separator !== "string") await binary("+", result2, separator, budget);
@@ -25170,7 +25358,7 @@ var Interpreter = class _Interpreter {
25170
25358
  }
25171
25359
  first = false;
25172
25360
  if (isObject(item) || Array.isArray(item)) await binary("+", result2, item, budget);
25173
- const text3 = item === null ? "" : typeof item === "string" ? item : stringify(item, budget);
25361
+ const text3 = item === null ? "" : typeof item === "string" ? item : await stringify(item, budget);
25174
25362
  append(text3, budget.value(text3));
25175
25363
  }
25176
25364
  budget.value(result2);
@@ -25228,9 +25416,10 @@ var Interpreter = class _Interpreter {
25228
25416
  return;
25229
25417
  }
25230
25418
  if (name2 === "tostring" || name2 === "tojson") {
25231
- const result2 = typeof input3 === "string" && name2 === "tostring" ? input3 : stringify(input3, budget);
25232
- budget.text(result2);
25233
- yield result2;
25419
+ if (typeof input3 === "string" && name2 === "tostring") {
25420
+ await measureValue(input3, budget);
25421
+ yield input3;
25422
+ } else yield await stringify(input3, budget, false, budget.limits.maxValueBytes, "maxValueBytes", true);
25234
25423
  return;
25235
25424
  }
25236
25425
  if (name2 === "tonumber" || name2 === "fromjson") {
@@ -25251,7 +25440,24 @@ var Interpreter = class _Interpreter {
25251
25440
  return;
25252
25441
  }
25253
25442
  if (name2 === "to_entries") {
25254
- yield entries(input3, budget).map(([key, value2]) => copyObject({ key, value: value2 }));
25443
+ if (Array.isArray(input3)) await budget.tick(input3.length);
25444
+ const result2 = [];
25445
+ let bytes3 = 2;
25446
+ if (bytes3 > budget.limits.maxValueBytes) throw new JqLimitError("maxValueBytes");
25447
+ for await (const [key, value2] of entries(input3, budget)) {
25448
+ budget.collection(result2.length + 1);
25449
+ budget.collection(2);
25450
+ const overhead = 17 + (result2.length ? 1 : 0);
25451
+ const keyBytes3 = await measureValue(key, budget, 2, budget.limits.maxValueBytes - bytes3 - overhead);
25452
+ const valueBytes = await measureValue(value2, budget, 2, budget.limits.maxValueBytes - bytes3 - overhead - keyBytes3);
25453
+ await budget.tick(4);
25454
+ bytes3 += overhead + keyBytes3 + valueBytes;
25455
+ const entry = object();
25456
+ put(entry, "key", key);
25457
+ put(entry, "value", value2);
25458
+ result2.push(entry);
25459
+ }
25460
+ yield result2;
25255
25461
  return;
25256
25462
  }
25257
25463
  if (name2 === "from_entries" || name2 === "with_entries") {
@@ -25259,7 +25465,7 @@ var Interpreter = class _Interpreter {
25259
25465
  if (name2 === "with_entries") {
25260
25466
  values = [];
25261
25467
  let bytes3 = 2;
25262
- for (const [key, value2] of entries(input3, budget)) for await (const mapped of this.run(args[0], copyObject({ key, value: value2 }))) {
25468
+ for await (const [key, value2] of entries(input3, budget)) for await (const mapped of this.run(args[0], copyObject({ key, value: value2 }))) {
25263
25469
  budget.collection(values.length + 1);
25264
25470
  bytes3 += budget.value(mapped) + (values.length ? 1 : 0);
25265
25471
  if (bytes3 > budget.limits.maxValueBytes) throw new JqLimitError("maxValueBytes");
@@ -25267,7 +25473,7 @@ var Interpreter = class _Interpreter {
25267
25473
  }
25268
25474
  }
25269
25475
  const result2 = object();
25270
- for (const [, entry] of entries(values, budget)) {
25476
+ for await (const [, entry] of entries(values, budget)) {
25271
25477
  await budget.tick();
25272
25478
  if (!isObject(entry)) throw new JqError(`Cannot index ${type(entry)} with string "key"`);
25273
25479
  const key = ["key", "Key", "name", "Name"].find((candidate) => Object.hasOwn(entry, candidate) && truth2(entry[candidate]));
@@ -25295,12 +25501,19 @@ var Interpreter = class _Interpreter {
25295
25501
  return;
25296
25502
  }
25297
25503
  if (!Array.isArray(input3)) {
25298
- if (name2 === "unique") entries(input3, budget);
25504
+ if (name2 === "unique" && !isObject(input3)) throw new JqError(`Cannot iterate over ${describe(input3, budget)}`);
25299
25505
  if (name2 === "sort") throw new JqError(`${describe(input3, budget)} cannot be sorted, as it is not an array`);
25300
25506
  throw new JqError(`${name2} requires an array`);
25301
25507
  }
25302
25508
  if (name2 === "reverse") {
25303
- yield [...input3].reverse();
25509
+ await budget.tick(input3.length);
25510
+ await measureValue(input3, budget);
25511
+ const result2 = [];
25512
+ for (let index = input3.length - 1; index >= 0; index--) {
25513
+ await budget.tick(0);
25514
+ result2.push(input3[index]);
25515
+ }
25516
+ yield result2;
25304
25517
  return;
25305
25518
  }
25306
25519
  if (name2 === "add") {
@@ -25901,7 +26114,7 @@ async function execute3(context2, limits) {
25901
26114
  if (++budget.results > limits.maxResults) throw new JqLimitError("maxResults");
25902
26115
  const remaining = limits.maxOutputBytes - budget.outputBytes;
25903
26116
  const suffix2 = options3.joinOutput ? "" : "\n";
25904
- const text3 = options3.raw && typeof result2 === "string" ? result2 : stringify(result2, budget, !options3.compact, Math.max(0, remaining - suffix2.length), "maxOutputBytes");
26117
+ const text3 = options3.raw && typeof result2 === "string" ? result2 : await stringify(result2, budget, !options3.compact, Math.max(0, remaining - suffix2.length), "maxOutputBytes");
25905
26118
  const bytes3 = import_buffer.Buffer.from(`${text3}${suffix2}`);
25906
26119
  if (bytes3.byteLength > remaining) throw new JqLimitError("maxOutputBytes");
25907
26120
  budget.outputBytes += bytes3.byteLength;