poe-code 14.0.47 → 14.0.48

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.
@@ -22,7 +22,7 @@ import {
22
22
  resolveFsConfig,
23
23
  splitFrontmatter,
24
24
  withBrokenPipeGuard
25
- } from "./chunks/chunk-WQY27BRL.js";
25
+ } from "./chunks/chunk-6GXMEFMD.js";
26
26
  import {
27
27
  Budget,
28
28
  SandboxError,
@@ -34,7 +34,7 @@ import {
34
34
  replaceErrorStack,
35
35
  restore,
36
36
  run
37
- } from "./chunks/chunk-XC53RECY.js";
37
+ } from "./chunks/chunk-PCHV72VT.js";
38
38
  import "./chunks/chunk-UXMKEUH3.js";
39
39
  import "./chunks/chunk-5DYEOCT5.js";
40
40
  import "./chunks/chunk-4YIDX44G.js";
@@ -5,7 +5,7 @@ import {
5
5
  defineExtension,
6
6
  lint,
7
7
  run
8
- } from "./chunks/chunk-XC53RECY.js";
8
+ } from "./chunks/chunk-PCHV72VT.js";
9
9
  import "./chunks/chunk-4YIDX44G.js";
10
10
  export {
11
11
  Budget,
@@ -26,7 +26,7 @@ import {
26
26
  runWithSpawnUsageAccumulator,
27
27
  splitFrontmatter,
28
28
  supportsSpawnMode
29
- } from "./chunks/chunk-WQY27BRL.js";
29
+ } from "./chunks/chunk-6GXMEFMD.js";
30
30
  import {
31
31
  Budget,
32
32
  FileSnapshotBackend,
@@ -50,7 +50,7 @@ import {
50
50
  registerPendingHostCallPolicy,
51
51
  restore,
52
52
  run
53
- } from "./chunks/chunk-XC53RECY.js";
53
+ } from "./chunks/chunk-PCHV72VT.js";
54
54
  import "./chunks/chunk-UXMKEUH3.js";
55
55
  import "./chunks/chunk-5DYEOCT5.js";
56
56
  import "./chunks/chunk-4YIDX44G.js";
@@ -0,0 +1,3 @@
1
+ import type { Budget } from "./budget.js";
2
+ import { type SandboxCallContext, type SandboxClosure, type SandboxValue } from "./values.js";
3
+ export declare function invokeBuiltinClosure(closure: SandboxClosure, args: readonly SandboxValue[], budget: Budget, context: SandboxCallContext | undefined, thisValue: SandboxValue, construct?: boolean): Promise<SandboxValue>;
@@ -0,0 +1,24 @@
1
+ import { isSandboxPromise } from "./values.js";
2
+ export async function invokeBuiltinClosure(closure, args, budget, context, thisValue, construct = false) {
3
+ if (context?.invokeClosure !== undefined) {
4
+ return context.invokeClosure(closure, args, thisValue, construct);
5
+ }
6
+ const leaveCall = budget.enterCall();
7
+ try {
8
+ const invoke = construct ? closure.construct : closure.call;
9
+ if (invoke === undefined)
10
+ throw new TypeError("Value is not a constructor.");
11
+ const result = await invoke(args, {
12
+ ...context,
13
+ stack: context?.stack ?? [],
14
+ thisValue,
15
+ invokeClosure: (target, values, receiver, asConstructor) => invokeBuiltinClosure(target, values, budget, context, receiver, asConstructor)
16
+ });
17
+ if (isSandboxPromise(result))
18
+ await result.synchronousPrefix;
19
+ return result;
20
+ }
21
+ finally {
22
+ leaveCall();
23
+ }
24
+ }
@@ -1,4 +1,4 @@
1
- import type { Budget, CompileOwner } from "../budget.js";
1
+ import { type Budget, type CompileOwner } from "../budget.js";
2
2
  import { type SandboxClosure } from "../values.js";
3
3
  export type ObjectArrayGlobals = {
4
4
  Object: SandboxClosure;
@@ -1,13 +1,16 @@
1
- import { dateTime, isSandboxDate } from "../date.js";
1
+ import { isFatalSandboxError } from "../budget.js";
2
+ import { invokeBuiltinClosure } from "../builtin-call.js";
3
+ import { isCapturedException } from "../exceptions.js";
4
+ import { isSandboxDate } from "../date.js";
2
5
  import { getDatePrototype } from "./date.js";
3
6
  import { createObjectGlobal, hasOwnSandboxProperty } from "./object.js";
4
7
  import { getHostObjectKeys, isGuestHostObject } from "../host-capabilities.js";
5
8
  import { isFloat32Array } from "../float32.js";
6
9
  import { setSandboxProperty } from "../interpreter.js";
7
10
  import { getSandboxIterator } from "../iteration.js";
8
- import { sandboxString } from "../string-coercion.js";
9
- import { getSandboxPrototype, isGuestClosure, markDescriptorObject, materializeFunctionProperties, setSandboxPrototype } from "../object-model.js";
10
- import { allocateProducedSandboxValue, createSandboxClosure, deepCopyToSandbox, isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, isSandboxRegex, isSandboxSet, ownEnumerableSandboxEntries as getOwnEnumerableEntries } from "../values.js";
11
+ import { sandboxNumber, sandboxString } from "../string-coercion.js";
12
+ import { getSandboxDataProperty, getSandboxPrototype, isGuestClosure, markDescriptorObject, materializeFunctionProperties, setSandboxPrototype } from "../object-model.js";
13
+ import { allocateProducedSandboxValue, createSandboxClosure, deepCopyToSandbox, defineOwnDataProperty, isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, isSandboxRegex, isSandboxSet, ownEnumerableSandboxEntries as getOwnEnumerableEntries, reconcileCompiledValues } from "../values.js";
11
14
  export function createObjectArrayGlobals(options) {
12
15
  return {
13
16
  Object: createObjectGlobal({
@@ -165,7 +168,7 @@ export function createObjectArrayGlobals(options) {
165
168
  }),
166
169
  from: createSandboxClosure({
167
170
  sandbox: true,
168
- call: (args) => arrayFromSandboxValues(args, options.budget),
171
+ call: (args, context) => arrayFromSandboxValues(args, options.budget, context),
169
172
  name: "from"
170
173
  }),
171
174
  of: createSandboxClosure({
@@ -199,7 +202,7 @@ export function createObjectArrayGlobals(options) {
199
202
  }),
200
203
  Number: createSandboxClosure({
201
204
  sandbox: true,
202
- call: ([value]) => isSandboxDate(value) ? dateTime(value) : Number(value),
205
+ call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context),
203
206
  name: "Number",
204
207
  properties: {
205
208
  isFinite: createSandboxClosure({
@@ -365,45 +368,108 @@ function isAssignableSandboxTarget(value) {
365
368
  !isSandboxPromise(value) &&
366
369
  !isSandboxRegex(value));
367
370
  }
368
- async function arrayFromSandboxValues(args, budget) {
371
+ async function arrayFromSandboxValues(args, budget, context) {
369
372
  const [items, mapFn, thisValue] = args;
373
+ if (mapFn !== undefined && !isSandboxClosure(mapFn)) {
374
+ throw new TypeError("Array.from mapping callback must be a function.");
375
+ }
376
+ if (items === null || items === undefined) {
377
+ throw new TypeError("Array.from requires a non-null input.");
378
+ }
379
+ const read = (property) => context?.getProperty !== undefined
380
+ ? context.getProperty(items, property)
381
+ : getSandboxDataProperty(items, property, budget);
370
382
  const iterator = getSandboxIterator(items);
371
- if (isGuestHostObject(items) && iterator !== undefined) {
372
- if (mapFn !== undefined && !isSandboxClosure(mapFn))
373
- throw new TypeError("Array.from mapping callback must be a function.");
374
- const values = [];
375
- while (true) {
376
- const next = await iterator.next();
377
- if (next.done)
378
- break;
379
- budget.allocateArrayLength(values.length + 1);
380
- const value = mapFn === undefined
381
- ? next.value
382
- : await mapFn.call([next.value, values.length], { stack: [], thisValue });
383
- if (isSandboxPromise(value) && value.synchronousPrefix !== undefined)
384
- await value.synchronousPrefix;
385
- values.push(value);
383
+ const constructor = context?.thisValue;
384
+ let result;
385
+ let currentValue;
386
+ let failure;
387
+ let estimatedDataSize = 0;
388
+ const retained = {};
389
+ budget.setRetainedValues(retained, () => [items, mapFn, constructor, result, currentValue, failure]);
390
+ const checkData = (growth = 0, force = false) => {
391
+ const limit = budget.limits.dataSize;
392
+ if (limit === undefined)
393
+ return;
394
+ estimatedDataSize = Math.max(estimatedDataSize, budget.currentDataSize) + growth;
395
+ // Primitive writes have bounded growth; changed graphs require an exact check.
396
+ if (!force && estimatedDataSize <= limit)
397
+ return;
398
+ if (context?.reconcileData !== undefined)
399
+ context.reconcileData(result);
400
+ else
401
+ reconcileCompiledValues(budget, [], context?.compilation);
402
+ estimatedDataSize = budget.currentDataSize;
403
+ };
404
+ const closeOnThrow = async (error) => {
405
+ failure = isCapturedException(error) ? error.reason : error;
406
+ try {
407
+ await iterator?.return?.();
386
408
  }
387
- return allocateProducedSandboxValue(values, budget);
388
- }
389
- const values = iterator === undefined
390
- ? Reflect.apply(Array.from, Array, [items])
391
- : await collectIteratorValues(iterator);
392
- if (mapFn === undefined || !isSandboxClosure(mapFn)) {
393
- if (mapFn !== undefined) {
394
- throw new TypeError("Array.from mapping callback must be a function.");
409
+ catch (closeError) {
410
+ if (!isFatalSandboxError(error) && isFatalSandboxError(closeError))
411
+ throw closeError;
395
412
  }
396
- return budgetSandboxValue(values, budget);
397
- }
398
- const mappedValues = [];
399
- for (const [index, value] of values.entries()) {
400
- const result = await mapFn.call([value, index], { stack: [], thisValue });
401
- if (isSandboxPromise(result) && result.synchronousPrefix !== undefined) {
402
- await result.synchronousPrefix;
413
+ throw error;
414
+ };
415
+ try {
416
+ let length = 0;
417
+ if (iterator === undefined) {
418
+ const number = await sandboxNumber(read("length"), budget, context);
419
+ length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
403
420
  }
404
- mappedValues.push(result);
421
+ result = isSandboxClosure(constructor) && constructor.construct !== undefined
422
+ ? await invokeBuiltinClosure(constructor, iterator === undefined ? [length] : [], budget, context, undefined, true)
423
+ : createArrayFromConstructorArgs([length], budget);
424
+ checkData(0, true);
425
+ let index = 0;
426
+ while (iterator !== undefined || index < length) {
427
+ try {
428
+ budget.visitNode();
429
+ if (iterator !== undefined && index >= Number.MAX_SAFE_INTEGER)
430
+ throw new TypeError("Array.from input is too long.");
431
+ }
432
+ catch (error) {
433
+ await closeOnThrow(error);
434
+ }
435
+ if (iterator !== undefined) {
436
+ const next = await iterator.next();
437
+ if (typeof next !== "object" || next === null)
438
+ throw new TypeError("Iterator result must be an object.");
439
+ if (next.done)
440
+ break;
441
+ currentValue = next.value;
442
+ }
443
+ else {
444
+ currentValue = read(index);
445
+ }
446
+ try {
447
+ if (Array.isArray(result))
448
+ budget.allocateArrayLength(index + 1);
449
+ if (mapFn !== undefined)
450
+ currentValue = await invokeBuiltinClosure(mapFn, [currentValue, index], budget, context, thisValue);
451
+ const key = String(index);
452
+ const growth = key.length + 1 +
453
+ (Array.isArray(result) ? Math.max(0, index + 1 - result.length) : 0) +
454
+ (typeof currentValue === "string" ? currentValue.length : 0);
455
+ const graphChanged = (typeof currentValue === "object" && currentValue !== null) || isSandboxClosure(result);
456
+ budget.visitNode();
457
+ defineOwnDataProperty(objectProperties(result, true), key, currentValue);
458
+ currentValue = undefined;
459
+ checkData(growth, graphChanged);
460
+ }
461
+ catch (error) {
462
+ await closeOnThrow(error);
463
+ }
464
+ index += 1;
465
+ }
466
+ setSandboxProperty(result, "length", index, budget);
467
+ checkData(0, true);
468
+ return allocateProducedSandboxValue(result, budget);
469
+ }
470
+ finally {
471
+ budget.setRetainedValues(retained, undefined);
405
472
  }
406
- return budgetSandboxValue(mappedValues, budget);
407
473
  }
408
474
  function createArrayFromConstructorArgs(args, budget) {
409
475
  if (args.length !== 1) {
@@ -417,15 +483,12 @@ function createArrayFromConstructorArgs(args, budget) {
417
483
  throw new RangeError("Invalid array length.");
418
484
  }
419
485
  budget.allocateArrayLength(lengthOrValue);
420
- return new Array(lengthOrValue);
421
- }
422
- async function collectIteratorValues(iterator) {
423
- const values = [];
424
- while (true) {
425
- const result = await iterator.next();
426
- if (result.done)
427
- return values;
428
- values.push(result.value);
486
+ const release = budget.provisionDataUsage(lengthOrValue + 1);
487
+ try {
488
+ return new Array(lengthOrValue);
489
+ }
490
+ finally {
491
+ release();
429
492
  }
430
493
  }
431
494
  function getOwnEnumerableKeys(value) {
@@ -231,7 +231,7 @@ async function evaluateNode(node, context) {
231
231
  }
232
232
  }
233
233
  function reconcileDataBudget(budget, stats, scope, transient, compilation, parent) {
234
- reconcileCompiledValues(budget, [...scope.retainedValues(), ...budget.retainedValues(), transient], compilation, parent, [transient]);
234
+ reconcileCompiledValues(budget, [...scope.retainedValues(), transient], compilation, parent, [transient]);
235
235
  stats.currentDataSize = budget.currentDataSize;
236
236
  stats.peakDataSize = budget.peakDataSize;
237
237
  }
@@ -2127,7 +2127,9 @@ function createCoercionContext(context) {
2127
2127
  stack: context.callStack,
2128
2128
  thisValue: undefined,
2129
2129
  compilation: context.compilation,
2130
- invokeClosure: (closure, args, thisValue) => invokeSandboxClosure(closure, args, context, context.callStack, undefined, thisValue)
2130
+ getProperty: (value, property) => getPropertyValue(value, property, context),
2131
+ reconcileData: value => reconcileDataBudget(context.budget, context.stats, context.scope, value, context.compilation, context.compilation?.parent),
2132
+ invokeClosure: (closure, args, thisValue, construct) => invokeSandboxClosure(closure, args, context, context.callStack, undefined, thisValue, construct)
2131
2133
  };
2132
2134
  }
2133
2135
  function hasSandboxProperty(value, key, context) {
@@ -2518,7 +2520,9 @@ async function invokeSandboxClosure(callee, args, context, stack, span, thisValu
2518
2520
  stack,
2519
2521
  thisValue,
2520
2522
  compilation: context.compilation,
2521
- invokeClosure: (closure, argumentsList, receiver) => invokeSandboxClosure(closure, argumentsList, context, stack, span, receiver),
2523
+ getProperty: (value, property) => getPropertyValue(value, property, context),
2524
+ reconcileData: (value) => reconcileDataBudget(context.budget, context.stats, context.scope, value, context.compilation, context.compilation?.parent),
2525
+ invokeClosure: (closure, argumentsList, receiver, asConstructor) => invokeSandboxClosure(closure, argumentsList, context, stack, span, receiver, asConstructor),
2522
2526
  ...(span === undefined ? {} : { span })
2523
2527
  }
2524
2528
  ]);
@@ -1,3 +1,4 @@
1
1
  import type { Budget } from "./budget.js";
2
2
  import { type SandboxCallContext, type SandboxValue } from "./values.js";
3
+ export declare function sandboxNumber(value: SandboxValue, budget: Budget, context?: SandboxCallContext): number | Promise<number>;
3
4
  export declare function sandboxString(value: SandboxValue, budget: Budget, context?: SandboxCallContext, joining?: Set<object>): string | Promise<string>;
@@ -1,5 +1,6 @@
1
1
  import { sandboxErrorTypes } from "../error/shape.js";
2
- import { dateString, isSandboxDate } from "./date.js";
2
+ import { dateString, dateTime, isSandboxDate } from "./date.js";
3
+ import { invokeBuiltinClosure } from "./builtin-call.js";
3
4
  import { float32Storage, isFloat32Array } from "./float32.js";
4
5
  import { assertSandboxDataDepth } from "../graph-depth.js";
5
6
  import { isGuestHostObject } from "./host-capabilities.js";
@@ -7,55 +8,46 @@ import { getGuestFunctionProperties, getSandboxPrototype, hasExplicitSandboxProt
7
8
  import { getRegexMember } from "./methods/regex.js";
8
9
  import { isSandboxClosure, isSandboxPromise, isSandboxMap, isSandboxSet, isSandboxRegex, isSandboxGenerator } from "./values.js";
9
10
  const defaultStringHook = Symbol("defaultStringHook");
11
+ const defaultValueHook = Symbol("defaultValueHook");
12
+ export function sandboxNumber(value, budget, context) {
13
+ if (value === null || typeof value !== "object") {
14
+ if (typeof value === "function")
15
+ throw new TypeError("Expected a sandbox value.");
16
+ return Number(value);
17
+ }
18
+ return objectToPrimitive(value, budget, context, new Set(), "number").then(Number);
19
+ }
10
20
  export function sandboxString(value, budget, context, joining = new Set()) {
11
21
  if (value === null || typeof value !== "object") {
12
22
  if (typeof value === "function")
13
23
  throw new TypeError("Expected a sandbox value.");
14
24
  return budget.allocateString(String(value));
15
25
  }
16
- const invocation = context?.invokeClosure !== undefined
17
- ? context
18
- : {
19
- ...context,
20
- stack: context?.stack ?? [],
21
- thisValue: context?.thisValue,
22
- invokeClosure: async (closure, args, thisValue) => {
23
- const leaveCall = budget.enterCall();
24
- try {
25
- const result = closure.call(args, { ...invocation, thisValue });
26
- if (isSandboxPromise(result)) {
27
- await result.synchronousPrefix;
28
- return result;
29
- }
30
- return await result;
31
- }
32
- finally {
33
- leaveCall();
34
- }
35
- }
36
- };
37
- return stringifyObject(value, budget, invocation, joining);
26
+ return objectToPrimitive(value, budget, context, joining, "string")
27
+ .then(primitive => budget.allocateString(String(primitive)));
38
28
  }
39
- async function stringifyObject(value, budget, context, joining) {
29
+ async function objectToPrimitive(value, budget, context, joining, hint) {
40
30
  const leaveCall = budget.enterCall();
41
31
  try {
42
32
  budget.visitNode();
43
- for (const name of ["toString", "valueOf"]) {
33
+ for (const name of hint === "string" ? ["toString", "valueOf"] : ["valueOf", "toString"]) {
44
34
  const hook = conversionHook(value, name, budget);
45
35
  let result;
46
36
  if (hook === defaultStringHook) {
47
37
  result = await defaultToString(value, budget, context, joining);
48
38
  }
39
+ else if (hook === defaultValueHook) {
40
+ result = isSandboxDate(value) ? dateTime(value) : value;
41
+ }
49
42
  else {
50
43
  if (!isSandboxClosure(hook))
51
44
  continue;
52
- if (context?.invokeClosure === undefined) {
53
- throw new TypeError("String hooks require a sandbox call context.");
54
- }
55
- result = await context.invokeClosure(hook, [], value);
45
+ result = await invokeBuiltinClosure(hook, [], budget, context, value);
56
46
  }
57
47
  if (result === null || typeof result !== "object") {
58
- return sandboxString(result, budget, context, joining);
48
+ if (typeof result === "function")
49
+ throw new TypeError("Expected a sandbox value.");
50
+ return result;
59
51
  }
60
52
  }
61
53
  throw new TypeError("Cannot convert object to primitive value");
@@ -90,7 +82,7 @@ function conversionHook(value, name, budget) {
90
82
  const parent = getSandboxPrototype(current, budget);
91
83
  if (current === value &&
92
84
  (implicitBuiltin || (parent === null && !hasExplicitSandboxPrototype(value)))) {
93
- return name === "toString" ? defaultStringHook : undefined;
85
+ return name === "toString" ? defaultStringHook : defaultValueHook;
94
86
  }
95
87
  current = parent;
96
88
  if (current !== null) {
@@ -117,10 +109,7 @@ async function defaultToString(value, budget, context, joining) {
117
109
  const join = ownDataValue(value, "join");
118
110
  if (!isSandboxClosure(join))
119
111
  return isFloat32Array(value) ? "[object Float32Array]" : "[object Array]";
120
- if (context?.invokeClosure === undefined) {
121
- throw new TypeError("String hooks require a sandbox call context.");
122
- }
123
- return context.invokeClosure(join, [], value);
112
+ return invokeBuiltinClosure(join, [], budget, context, value);
124
113
  }
125
114
  if (joining.has(value))
126
115
  return "";
@@ -51,7 +51,9 @@ export type SandboxCallContext = {
51
51
  };
52
52
  readonly stack: readonly string[];
53
53
  readonly thisValue: SandboxValue;
54
- readonly invokeClosure?: (closure: SandboxClosure, args: readonly SandboxValue[], thisValue: SandboxValue) => Promise<SandboxValue>;
54
+ readonly getProperty?: (value: SandboxValue, property: string | number) => SandboxValue;
55
+ readonly reconcileData?: (value: SandboxValue) => void;
56
+ readonly invokeClosure?: (closure: SandboxClosure, args: readonly SandboxValue[], thisValue: SandboxValue, construct?: boolean) => Promise<SandboxValue>;
55
57
  };
56
58
  export type SandboxClosure = {
57
59
  readonly async?: true;