poe-code 14.0.41 → 14.0.42

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-L4NMOY6O.js";
25
+ } from "./chunks/chunk-IRDBTJYC.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-5J6BX3HD.js";
37
+ } from "./chunks/chunk-M4M56OCI.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-5J6BX3HD.js";
8
+ } from "./chunks/chunk-M4M56OCI.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-L4NMOY6O.js";
29
+ } from "./chunks/chunk-IRDBTJYC.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-5J6BX3HD.js";
53
+ } from "./chunks/chunk-M4M56OCI.js";
54
54
  import "./chunks/chunk-UXMKEUH3.js";
55
55
  import "./chunks/chunk-5DYEOCT5.js";
56
56
  import "./chunks/chunk-4YIDX44G.js";
@@ -29,6 +29,7 @@ type ExceptionContext = {
29
29
  budget: Budget;
30
30
  callStack: readonly string[];
31
31
  scope: Scope;
32
+ toPropertyKey?: (value: SandboxValue) => Promise<string>;
32
33
  };
33
34
  type EvaluateExceptionNode<TContext, TError> = (node: ParseResult, context: TContext) => Promise<EvaluationResult<TError>>;
34
35
  export declare function evaluateThrowStatement<TContext extends ExceptionContext, TError>(node: ThrowStatement, context: TContext, evaluateNode: EvaluateExceptionNode<TContext, TError>): Promise<EvaluationResult<TError>>;
@@ -3,6 +3,7 @@ import { SandboxError } from "./budget.js";
3
3
  import { HostCallResumabilityError } from "./host-call.js";
4
4
  import { withFatalPromiseCleanup } from "./promise-tracker.js";
5
5
  import { deepCopyToSandbox } from "./values.js";
6
+ import { toPropertyKey } from "./property-key.js";
6
7
  const capturedExceptionBrand = Symbol("CapturedException");
7
8
  export async function evaluateThrowStatement(node, context, evaluateNode) {
8
9
  const argument = await evaluateNode(node.argument, context);
@@ -389,12 +390,9 @@ async function resolvePatternPropertyKey(property, context, evaluateNode) {
389
390
  result: computedKey
390
391
  };
391
392
  }
392
- if (typeof computedKey.value !== "string" && typeof computedKey.value !== "number") {
393
- throw new TypeError("Computed catch binding keys must evaluate to a string or number.");
394
- }
395
393
  return {
396
394
  ok: true,
397
- value: computedKey.value
395
+ value: await (context.toPropertyKey?.(computedKey.value) ?? toPropertyKey(computedKey.value, context.budget, { stack: context.callStack, thisValue: undefined }))
398
396
  };
399
397
  }
400
398
  function getStaticPropertyKey(property) {
@@ -1,6 +1,6 @@
1
1
  import { promiseReplayContext } from "./promise-replay.js";
2
2
  import { deleteHostObjectMember, getHostObjectKeys, getHostObjectMember, hasHostObjectMember, isGuestHostObject, setHostObjectMember } from "./host-capabilities.js";
3
- import { sandboxString } from "./string-coercion.js";
3
+ import { toPropertyKey } from "./property-key.js";
4
4
  import { assertPromiseExecutionAllowed } from "./promise-tracker.js";
5
5
  import { SandboxJobQueue, runAsyncPrefix, suspendJob } from "./jobs.js";
6
6
  import { withCancellationSignal } from "./cancel.js";
@@ -444,7 +444,7 @@ async function evaluateBinaryExpression(node, context) {
444
444
  if (typeof right.value !== "object" || right.value === null) {
445
445
  throw new TypeError("Right-hand side of 'in' must be an object.");
446
446
  }
447
- leftValue = await toPropertyKey(leftValue, context);
447
+ leftValue = await toPropertyKey(leftValue, context.budget, createCoercionContext(context));
448
448
  }
449
449
  const value = applyBinaryOperator(node, leftValue, right.value, context);
450
450
  return {
@@ -535,7 +535,15 @@ async function evaluateMemberAssignmentExpression(node, context) {
535
535
  if (member.kind === "nullish") {
536
536
  throw new TypeError("Cannot assign properties of null or undefined.");
537
537
  }
538
- const current = node.operator === "=" ? undefined : getPropertyValue(member.object, member.property, context);
538
+ let property;
539
+ let current = undefined;
540
+ if (node.operator !== "=") {
541
+ if (member.object === null || member.object === undefined) {
542
+ throw new TypeError("Cannot assign properties of null or undefined.");
543
+ }
544
+ property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
545
+ current = getPropertyValue(member.object, property, context);
546
+ }
539
547
  if (node.operator === "&&=" && !isTruthy(current)) {
540
548
  return {
541
549
  kind: "normal",
@@ -567,7 +575,11 @@ async function evaluateMemberAssignmentExpression(node, context) {
567
575
  node.operator === "??="
568
576
  ? right.value
569
577
  : await applyCompoundAssignmentOperator(node.operator, current, right.value, context);
570
- setSandboxProperty(member.object, member.property, value, context.budget);
578
+ if (member.object === null || member.object === undefined) {
579
+ throw new TypeError("Cannot assign properties of null or undefined.");
580
+ }
581
+ property ??= await toPropertyKey(member.property, context.budget, createCoercionContext(context));
582
+ setSandboxProperty(member.object, property, value, context.budget);
571
583
  return {
572
584
  kind: "normal",
573
585
  hasValue: true,
@@ -1523,7 +1535,10 @@ async function evaluateThrowStatement(node, context) {
1523
1535
  return evaluateThrowStatementResult(node, context, evaluateNode);
1524
1536
  }
1525
1537
  async function evaluateTryStatement(node, context) {
1526
- return evaluateTryStatementResult(node, context, evaluateNode);
1538
+ return evaluateTryStatementResult(node, {
1539
+ ...context,
1540
+ toPropertyKey: (value) => toPropertyKey(value, context.budget, createCoercionContext(context))
1541
+ }, evaluateNode);
1527
1542
  }
1528
1543
  async function evaluateUnaryExpression(node, context) {
1529
1544
  if (node.operator === "delete") {
@@ -1566,8 +1581,8 @@ async function evaluateDeleteExpression(node, context) {
1566
1581
  if (member.kind === "completion") {
1567
1582
  return member.result;
1568
1583
  }
1569
- if (member.kind === "nullish") {
1570
- if (node.argument.optional) {
1584
+ if (member.kind === "nullish" || member.object === null || member.object === undefined) {
1585
+ if (member.kind === "nullish" && node.argument.optional) {
1571
1586
  return {
1572
1587
  kind: "normal",
1573
1588
  hasValue: true,
@@ -1579,7 +1594,8 @@ async function evaluateDeleteExpression(node, context) {
1579
1594
  if (!isIndexableSandboxValue(member.object)) {
1580
1595
  throw new TypeError("Unary operator 'delete' requires a sandbox object property.");
1581
1596
  }
1582
- const deleted = deleteSandboxProperty(member.object, member.property);
1597
+ const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
1598
+ const deleted = deleteSandboxProperty(member.object, property);
1583
1599
  return {
1584
1600
  kind: "normal",
1585
1601
  hasValue: true,
@@ -1623,12 +1639,13 @@ async function evaluateMemberUpdateExpression(node, context) {
1623
1639
  if (member.kind === "completion") {
1624
1640
  return member.result;
1625
1641
  }
1626
- if (member.kind === "nullish") {
1642
+ if (member.kind === "nullish" || member.object === null || member.object === undefined) {
1627
1643
  throw new TypeError("Cannot update properties of null or undefined.");
1628
1644
  }
1629
- const current = toNumber(await toNumericPrimitive(getPropertyValue(member.object, member.property, context), context));
1645
+ const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
1646
+ const current = toNumber(await toNumericPrimitive(getPropertyValue(member.object, property, context), context));
1630
1647
  const next = node.operator === "++" ? current + 1 : current - 1;
1631
- setSandboxProperty(member.object, member.property, next, context.budget);
1648
+ setSandboxProperty(member.object, property, next, context.budget);
1632
1649
  return {
1633
1650
  kind: "normal",
1634
1651
  hasValue: true,
@@ -1641,15 +1658,15 @@ async function evaluateMemberExpression(node, context) {
1641
1658
  return member;
1642
1659
  if (member.kind === "completion")
1643
1660
  return member.result;
1644
- if (member.kind === "nullish") {
1645
- if (node.optional)
1661
+ if (member.kind === "nullish" || member.object === null || member.object === undefined) {
1662
+ if (member.kind === "nullish" && node.optional)
1646
1663
  return { kind: "normal", hasValue: true, value: undefined };
1647
1664
  throw new TypeError("Cannot read properties of null or undefined.");
1648
1665
  }
1649
1666
  return {
1650
1667
  kind: "normal",
1651
1668
  hasValue: true,
1652
- value: getPropertyValue(member.object, member.property, context)
1669
+ value: getPropertyValue(member.object, await toPropertyKey(member.property, context.budget, createCoercionContext(context)), context)
1653
1670
  };
1654
1671
  }
1655
1672
  function getPropertyValue(target, property, context) {
@@ -1686,6 +1703,7 @@ export function createPatternContext(context, scope = context.scope, evaluate =
1686
1703
  const evaluationContext = { ...context, scope };
1687
1704
  return {
1688
1705
  evaluate: node => evaluate(node, evaluationContext),
1706
+ toPropertyKey: value => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
1689
1707
  getProperty: (value, key) => getPropertyValue(value, key, evaluationContext),
1690
1708
  setProperty: (target, key, value) => setSandboxProperty(target, key, value, context.budget)
1691
1709
  };
@@ -1773,24 +1791,10 @@ async function evaluateMemberAccess(node, context) {
1773
1791
  };
1774
1792
  }
1775
1793
  const property = node.computed
1776
- ? await evaluateMemberProperty(node.property, context)
1777
- : { ok: true, value: getStaticPropertyName(node.property) };
1778
- if (!property.ok) {
1779
- return property.result.kind === "error"
1780
- ? {
1781
- kind: "error",
1782
- error: property.result.error
1783
- }
1784
- : {
1785
- kind: "completion",
1786
- result: property.result
1787
- };
1788
- }
1789
- if (object.value === null || object.value === undefined) {
1790
- return {
1791
- kind: "nullish"
1792
- };
1793
- }
1794
+ ? await evaluateNode(node.property, context)
1795
+ : { kind: "normal", value: getStaticPropertyName(node.property) };
1796
+ if (property.kind !== "normal")
1797
+ return { kind: "completion", result: property };
1794
1798
  return {
1795
1799
  kind: "resolved",
1796
1800
  object: object.value,
@@ -1805,13 +1809,10 @@ async function evaluateMemberProperty(node, context) {
1805
1809
  result: property
1806
1810
  };
1807
1811
  }
1808
- if (typeof property.value === "string" || typeof property.value === "number") {
1809
- return {
1810
- ok: true,
1811
- value: property.value
1812
- };
1813
- }
1814
- throw new TypeError("Computed property access requires a string or number key.");
1812
+ return {
1813
+ ok: true,
1814
+ value: await toPropertyKey(property.value, context.budget, createCoercionContext(context))
1815
+ };
1815
1816
  }
1816
1817
  async function evaluateObjectPropertyKey(node, context) {
1817
1818
  if (!node.computed) {
@@ -1835,15 +1836,15 @@ async function evaluateMemberCallExpression(node, context) {
1835
1836
  if (node.callee.type !== "MemberExpression") {
1836
1837
  throw new TypeError("Expected member call expression.");
1837
1838
  }
1838
- const member = await evaluateMemberAccess(node.callee, context);
1839
- if (member.kind === "error") {
1840
- return member;
1839
+ const reference = await evaluateMemberAccess(node.callee, context);
1840
+ if (reference.kind === "error") {
1841
+ return reference;
1841
1842
  }
1842
- if (member.kind === "completion") {
1843
- return member.result;
1843
+ if (reference.kind === "completion") {
1844
+ return reference.result;
1844
1845
  }
1845
- if (member.kind === "nullish") {
1846
- if (node.optional || node.callee.optional) {
1846
+ if (reference.kind === "nullish" || reference.object === null || reference.object === undefined) {
1847
+ if (reference.kind === "nullish") {
1847
1848
  return {
1848
1849
  kind: "normal",
1849
1850
  hasValue: true,
@@ -1852,6 +1853,10 @@ async function evaluateMemberCallExpression(node, context) {
1852
1853
  }
1853
1854
  throw new TypeError("Cannot read properties of null or undefined.");
1854
1855
  }
1856
+ const member = {
1857
+ ...reference,
1858
+ property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
1859
+ };
1855
1860
  if (typeof member.object === "string" && isStringMethodName(member.property)) {
1856
1861
  return evaluateStringMethodCall(node, member.object, member.property, context);
1857
1862
  }
@@ -2124,25 +2129,13 @@ function applyBinaryOperator(node, left, right, context) {
2124
2129
  return hasSandboxProperty(right, left, context);
2125
2130
  }
2126
2131
  }
2127
- async function toPropertyKey(value, context) {
2128
- if (isPlainSandboxObject(value) && !isSandboxDate(value) && !isFloat32Array(value) &&
2129
- !isSandboxGenerator(value) && !isGuestHostObject(value)) {
2130
- for (const name of ["toString", "valueOf"]) {
2131
- const method = getMemberValue(value, name, context);
2132
- if (!isSandboxClosure(method))
2133
- continue;
2134
- const primitive = await invokeSandboxClosure(method, [], context, context.callStack, undefined, value);
2135
- if (primitive === null || typeof primitive !== "object") {
2136
- return context.budget.allocateString(String(primitive));
2137
- }
2138
- }
2139
- throw new TypeError("Cannot convert object to primitive value.");
2140
- }
2141
- return sandboxString(value, context.budget, {
2132
+ function createCoercionContext(context) {
2133
+ return {
2142
2134
  stack: context.callStack,
2143
2135
  thisValue: undefined,
2136
+ compilation: context.compilation,
2144
2137
  invokeClosure: (closure, args, thisValue) => invokeSandboxClosure(closure, args, context, context.callStack, undefined, thisValue)
2145
- });
2138
+ };
2146
2139
  }
2147
2140
  function hasSandboxProperty(value, key, context) {
2148
2141
  let current = value;
@@ -11,6 +11,7 @@ export type PatternTarget = {
11
11
  };
12
12
  export type PatternContext = {
13
13
  evaluate(node: ParseResult): Promise<AsyncEvaluationResult>;
14
+ toPropertyKey(value: SandboxValue): Promise<string>;
14
15
  getProperty(value: SandboxValue, key: string | number): SandboxValue;
15
16
  setProperty(target: SandboxValue, key: string | number, value: SandboxValue): void;
16
17
  };
@@ -90,19 +90,19 @@ async function bindMemberExpression(pattern, value, scope, context) {
90
90
  if (object.kind !== "normal") {
91
91
  return { ok: false, result: object };
92
92
  }
93
+ const property = pattern.computed
94
+ ? await context.evaluate(pattern.property)
95
+ : { kind: "normal", value: getStaticPropertyName(pattern.property) };
96
+ if (property.kind !== "normal") {
97
+ return { ok: false, result: property };
98
+ }
93
99
  if (object.value === null || object.value === undefined) {
94
100
  throw new TypeError("Cannot assign properties of null or undefined.");
95
101
  }
96
102
  if (!isIndexableValue(object.value)) {
97
103
  throw new TypeError("Assignment expressions require a sandbox object property.");
98
104
  }
99
- const property = pattern.computed
100
- ? await evaluateProperty(pattern.property, context)
101
- : { ok: true, value: getStaticPropertyName(pattern.property) };
102
- if (!property.ok) {
103
- return property;
104
- }
105
- context.setProperty(object.value, property.value, value);
105
+ context.setProperty(object.value, await context.toPropertyKey(property.value), value);
106
106
  return { ok: true };
107
107
  }
108
108
  async function evaluatePatternKey(property, context) {
@@ -115,10 +115,7 @@ async function evaluateProperty(property, context) {
115
115
  if (result.kind !== "normal") {
116
116
  return { ok: false, result };
117
117
  }
118
- if (typeof result.value !== "string" && typeof result.value !== "number") {
119
- throw new TypeError("Computed property access requires a string or number key.");
120
- }
121
- return { ok: true, value: result.value };
118
+ return { ok: true, value: await context.toPropertyKey(result.value) };
122
119
  }
123
120
  function getStaticPropertyName(property) {
124
121
  if (property.type === "Identifier") {
@@ -0,0 +1,3 @@
1
+ import type { Budget } from "./budget.js";
2
+ import { type SandboxCallContext, type SandboxValue } from "./values.js";
3
+ export declare function toPropertyKey(value: SandboxValue, budget: Budget, context: SandboxCallContext): Promise<string>;
@@ -0,0 +1,53 @@
1
+ import { isSandboxDate } from "./date.js";
2
+ import { isFloat32Array } from "./float32.js";
3
+ import { isGuestHostObject } from "./host-capabilities.js";
4
+ import { getSandboxDataProperty } from "./object-model.js";
5
+ import { sandboxString } from "./string-coercion.js";
6
+ import { isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, isSandboxRegex, isSandboxSet } from "./values.js";
7
+ export async function toPropertyKey(value, budget, context) {
8
+ if (typeof value === "string")
9
+ return value;
10
+ const invocation = context.invokeClosure === undefined
11
+ ? {
12
+ ...context,
13
+ invokeClosure: async (closure, args, thisValue) => {
14
+ const leaveCall = budget.enterCall();
15
+ try {
16
+ const result = closure.call(args, { ...invocation, thisValue });
17
+ if (isSandboxPromise(result)) {
18
+ await result.synchronousPrefix;
19
+ return result;
20
+ }
21
+ return await result;
22
+ }
23
+ finally {
24
+ leaveCall();
25
+ }
26
+ }
27
+ }
28
+ : context;
29
+ if (typeof value === "object" &&
30
+ value !== null &&
31
+ !Array.isArray(value) &&
32
+ !isSandboxClosure(value) &&
33
+ !isSandboxMap(value) &&
34
+ !isSandboxSet(value) &&
35
+ !isSandboxPromise(value) &&
36
+ !isSandboxRegex(value) &&
37
+ !isSandboxDate(value) &&
38
+ !isFloat32Array(value) &&
39
+ !isSandboxGenerator(value) &&
40
+ !isGuestHostObject(value)) {
41
+ for (const name of ["toString", "valueOf"]) {
42
+ const method = getSandboxDataProperty(value, name, budget);
43
+ if (!isSandboxClosure(method))
44
+ continue;
45
+ const primitive = await invocation.invokeClosure(method, [], value);
46
+ if (primitive === null || typeof primitive !== "object") {
47
+ return budget.allocateString(String(primitive));
48
+ }
49
+ }
50
+ throw new TypeError("Cannot convert object to primitive value.");
51
+ }
52
+ return sandboxString(value, budget, invocation);
53
+ }
@@ -1,5 +1,6 @@
1
1
  import { Budget, SandboxError } from "../interp/budget.js";
2
2
  import { executeAsyncFunction } from "../interp/async.js";
3
+ import { toPropertyKey } from "../interp/property-key.js";
3
4
  import { CompileScope } from "../interp/regex/compile-guard.js";
4
5
  import { decodeFloat32Storage } from "./float32array.js";
5
6
  import { restoreDateTime } from "../interp/date.js";
@@ -500,6 +501,7 @@ async function executeRestoredClosure(node, capturedScopeId, closure, args, this
500
501
  const rest = args.slice(index);
501
502
  state.budget.allocateArrayLength(rest.length);
502
503
  const binding = await bindPattern(param, rest, { kind: "let" }, scope, {
504
+ toPropertyKey: value => toPropertyKey(value, state.budget, { ...callContext, stack: callContext?.stack ?? [], thisValue, compilation }),
503
505
  getProperty: (value, key) => getSandboxDataProperty(value, key, state.budget),
504
506
  setProperty: (target, key, value) => setSandboxProperty(target, key, value, state.budget),
505
507
  evaluate: async (defaultNode) => {
@@ -530,6 +532,7 @@ async function executeRestoredClosure(node, capturedScopeId, closure, args, this
530
532
  break;
531
533
  }
532
534
  const binding = await bindPattern(param, args[index], { kind: "let" }, scope, {
535
+ toPropertyKey: value => toPropertyKey(value, state.budget, { ...callContext, stack: callContext?.stack ?? [], thisValue, compilation }),
533
536
  getProperty: (value, key) => getSandboxDataProperty(value, key, state.budget),
534
537
  setProperty: (target, key, value) => setSandboxProperty(target, key, value, state.budget),
535
538
  evaluate: async (defaultNode) => {