poe-code 14.0.5 → 14.0.7
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.js +1604 -255
- package/dist/index.js.map +4 -4
- package/dist/metafile.json +1 -1
- package/package.json +1 -1
- package/packages/safe-js/dist/chunks/{chunk-B7H4ZL65.js → chunk-BWVASPJX.js} +2099 -783
- package/packages/safe-js/dist/chunks/chunk-BWVASPJX.js.map +7 -0
- package/packages/safe-js/dist/chunks/{chunk-7B7BKWVF.js → chunk-ETKM3KPA.js} +2 -2
- package/packages/safe-js/dist/cli.js +2 -2
- package/packages/safe-js/dist/core.d.ts +3 -0
- package/packages/safe-js/dist/core.js +5 -1
- package/packages/safe-js/dist/extensions.d.ts +44 -0
- package/packages/safe-js/dist/extensions.js +83 -0
- package/packages/safe-js/dist/index.d.ts +4 -1
- package/packages/safe-js/dist/index.js +6 -2
- package/packages/safe-js/dist/index.js.map +2 -2
- package/packages/safe-js/dist/interp/async.d.ts +1 -0
- package/packages/safe-js/dist/interp/date.d.ts +19 -0
- package/packages/safe-js/dist/interp/date.js +129 -0
- package/packages/safe-js/dist/interp/globals/console-json.js +5 -1
- package/packages/safe-js/dist/interp/globals/date.d.ts +10 -0
- package/packages/safe-js/dist/interp/globals/date.js +95 -0
- package/packages/safe-js/dist/interp/globals/object-array.d.ts +2 -1
- package/packages/safe-js/dist/interp/globals/object-array.js +15 -1
- package/packages/safe-js/dist/interp/globals.d.ts +34 -0
- package/packages/safe-js/dist/interp/globals.js +24 -0
- package/packages/safe-js/dist/interp/host-bridge.d.ts +18 -1
- package/packages/safe-js/dist/interp/host-bridge.js +39 -5
- package/packages/safe-js/dist/interp/host-call.js +4 -0
- package/packages/safe-js/dist/interp/host-capabilities.d.ts +50 -0
- package/packages/safe-js/dist/interp/host-capabilities.js +151 -0
- package/packages/safe-js/dist/interp/interpreter.d.ts +4 -0
- package/packages/safe-js/dist/interp/interpreter.js +41 -6
- package/packages/safe-js/dist/interp/object-model.js +7 -0
- package/packages/safe-js/dist/interp/string-coercion.js +3 -0
- package/packages/safe-js/dist/interp/values.d.ts +2 -1
- package/packages/safe-js/dist/interp/values.js +36 -0
- package/packages/safe-js/dist/lint/rules/known-globals.d.ts +1 -1
- package/packages/safe-js/dist/lint/rules/known-globals.js +1 -0
- package/packages/safe-js/dist/modules/registry.d.ts +3 -1
- package/packages/safe-js/dist/modules/registry.js +2 -1
- package/packages/safe-js/dist/parse/parser.js +4 -2
- package/packages/safe-js/dist/realm.d.ts +46 -0
- package/packages/safe-js/dist/realm.js +779 -0
- package/packages/safe-js/dist/run.d.ts +7 -1
- package/packages/safe-js/dist/run.js +6 -35
- package/packages/safe-js/dist/snapshot/dump-format.js +8 -3
- package/packages/safe-js/dist/snapshot/replay-data.d.ts +4 -1
- package/packages/safe-js/dist/snapshot/replay-data.js +11 -0
- package/packages/safe-js/dist/snapshot/restore.js +6 -0
- package/packages/safe-js/dist/snapshot/serialize.d.ts +5 -2
- package/packages/safe-js/dist/snapshot/serialize.js +8 -2
- package/packages/safe-js/dist/snapshot/validation.js +18 -1
- package/packages/safe-js/dist/chunks/chunk-B7H4ZL65.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-7B7BKWVF.js.map → chunk-ETKM3KPA.js.map} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { promiseReplayContext } from "./promise-replay.js";
|
|
2
|
+
import { getHostObjectKeys, getHostObjectMember, isGuestHostObject, setHostObjectMember } from "./host-capabilities.js";
|
|
2
3
|
import { assertPromiseExecutionAllowed } from "./promise-tracker.js";
|
|
3
|
-
import { SandboxJobQueue, suspendJob } from "./jobs.js";
|
|
4
|
+
import { SandboxJobQueue, runAsyncPrefix, suspendJob } from "./jobs.js";
|
|
4
5
|
import { withCancellationSignal } from "./cancel.js";
|
|
5
6
|
import { attachErrorSpan, formatErrorStack, readErrorSpan, replaceErrorStack } from "../error/shape.js";
|
|
6
7
|
import { evaluateArrowFunctionExpression, evaluateFunctionExpression, evaluateAwaitExpression, emitResumeBreakpoint, createInterpretedClosure, normalizeClosureResult } from "./async.js";
|
|
@@ -26,6 +27,8 @@ import { isSandboxErrorConstructorInstance } from "./globals/error.js";
|
|
|
26
27
|
import { isSandboxMapConstructor, isSandboxSetConstructor } from "./globals/collections.js";
|
|
27
28
|
import { getFloat32Member, isFloat32ArrayConstructor, setFloat32Member } from "./globals/float32array.js";
|
|
28
29
|
import { isFloat32Array } from "./float32.js";
|
|
30
|
+
import { dateString, dateTime, isSandboxDate } from "./date.js";
|
|
31
|
+
import { getDateMember, getDatePrototype, isDateConstructor } from "./globals/date.js";
|
|
29
32
|
import { createSandboxRegex, allocateProducedSandboxValue, isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, isSandboxRegex, isSandboxSet, reconcileCompiledValues } from "./values.js";
|
|
30
33
|
import { Scope } from "./scope.js";
|
|
31
34
|
import { hoistVarDeclarations } from "./var-hoist.js";
|
|
@@ -98,9 +101,10 @@ export async function interpret(node, options = {}) {
|
|
|
98
101
|
peakDataSize: { enumerable: false, value: 0, writable: true }
|
|
99
102
|
});
|
|
100
103
|
const activeLoopIterations = new Map();
|
|
101
|
-
const jobs = new SandboxJobQueue();
|
|
104
|
+
const jobs = options.jobs ?? new SandboxJobQueue();
|
|
102
105
|
hoistVarDeclarations(node, scope);
|
|
103
106
|
const context = {
|
|
107
|
+
assertActive: options.assertActive,
|
|
104
108
|
compilation,
|
|
105
109
|
budget,
|
|
106
110
|
callStack: [],
|
|
@@ -119,8 +123,9 @@ export async function interpret(node, options = {}) {
|
|
|
119
123
|
generatorYield: options.generatorYield,
|
|
120
124
|
resumeTarget: { nodeId: options.snapshot?.resumeNodeId }
|
|
121
125
|
};
|
|
122
|
-
const evaluation = await withCancellationSignal(options.signal, () => jobs.run(() => evaluateNode(node, context)));
|
|
123
|
-
|
|
126
|
+
const evaluation = await withCancellationSignal(options.signal, () => options.nested ? runAsyncPrefix(() => evaluateNode(node, context)) : jobs.run(() => evaluateNode(node, context)));
|
|
127
|
+
if (!options.nested)
|
|
128
|
+
await jobs.drain();
|
|
124
129
|
const snapshot = scope.snapshot();
|
|
125
130
|
reconcileDataBudget(budget, stats, scope, "hasValue" in evaluation && evaluation.hasValue ? evaluation.value : undefined, compilation, options.compilation);
|
|
126
131
|
if (evaluation.kind === "error") {
|
|
@@ -167,6 +172,7 @@ export async function interpret(node, options = {}) {
|
|
|
167
172
|
}
|
|
168
173
|
export { Scope } from "./scope.js";
|
|
169
174
|
async function evaluateNode(node, context) {
|
|
175
|
+
context.assertActive?.();
|
|
170
176
|
const replayWait = promiseReplayContext.getStore()?.beforeNode(node.nodeId);
|
|
171
177
|
if (replayWait !== undefined)
|
|
172
178
|
await suspendJob(replayWait);
|
|
@@ -1119,6 +1125,8 @@ function forInObject(value) {
|
|
|
1119
1125
|
return undefined;
|
|
1120
1126
|
}
|
|
1121
1127
|
function forInKeys(object, budget) {
|
|
1128
|
+
if (isGuestHostObject(object))
|
|
1129
|
+
return getHostObjectKeys(object);
|
|
1122
1130
|
const keys = [];
|
|
1123
1131
|
const seen = new Set();
|
|
1124
1132
|
let depth = 0;
|
|
@@ -1140,6 +1148,8 @@ function forInKeys(object, budget) {
|
|
|
1140
1148
|
return keys;
|
|
1141
1149
|
}
|
|
1142
1150
|
function hasForInProperty(object, key, budget) {
|
|
1151
|
+
if (isGuestHostObject(object))
|
|
1152
|
+
return getHostObjectKeys(object).includes(key);
|
|
1143
1153
|
let depth = 0;
|
|
1144
1154
|
for (let current = object; current !== null; current = getSandboxPrototype(current)) {
|
|
1145
1155
|
if (depth > 0)
|
|
@@ -1630,6 +1640,8 @@ async function evaluateMemberExpression(node, context) {
|
|
|
1630
1640
|
};
|
|
1631
1641
|
}
|
|
1632
1642
|
function getPropertyValue(target, property, context) {
|
|
1643
|
+
if (isGuestHostObject(target))
|
|
1644
|
+
return getHostObjectMember(target, String(property));
|
|
1633
1645
|
if (typeof target === "string")
|
|
1634
1646
|
return getStringMember(target, property, context.budget);
|
|
1635
1647
|
if (typeof target === "number")
|
|
@@ -1638,6 +1650,8 @@ function getPropertyValue(target, property, context) {
|
|
|
1638
1650
|
return undefined;
|
|
1639
1651
|
if (isFloat32Array(target))
|
|
1640
1652
|
return getFloat32Member(target, property, context.budget);
|
|
1653
|
+
if (isSandboxDate(target))
|
|
1654
|
+
return getDateMember(property, context.budget, context.compilation?.owner);
|
|
1641
1655
|
if (isSandboxMap(target))
|
|
1642
1656
|
return getMapMember(target, property, createMapMethodOptions(context));
|
|
1643
1657
|
if (isSandboxSet(target))
|
|
@@ -1854,6 +1868,9 @@ async function evaluateMemberCallExpression(node, context) {
|
|
|
1854
1868
|
if (isSandboxMap(member.object)) {
|
|
1855
1869
|
return evaluatePrimitiveMemberCall(node, "Map", member.property, getMapMember(member.object, member.property, createMapMethodOptions(context)), context);
|
|
1856
1870
|
}
|
|
1871
|
+
if (isSandboxDate(member.object)) {
|
|
1872
|
+
return evaluateResolvedCallExpression(node, getDateMember(member.property, context.budget, context.compilation?.owner), context, member.object);
|
|
1873
|
+
}
|
|
1857
1874
|
if (isFloat32Array(member.object)) {
|
|
1858
1875
|
return evaluateResolvedCallExpression(node, getFloat32Member(member.object, member.property, context.budget), context, member.object);
|
|
1859
1876
|
}
|
|
@@ -2066,6 +2083,8 @@ function applyBinaryOperator(node, left, right, context) {
|
|
|
2066
2083
|
}
|
|
2067
2084
|
if (isFloat32ArrayConstructor(right))
|
|
2068
2085
|
return isFloat32Array(left);
|
|
2086
|
+
if (isDateConstructor(right))
|
|
2087
|
+
return isSandboxDate(left) && getDatePrototype(left, context.budget, context.compilation?.owner) !== null;
|
|
2069
2088
|
if (isSandboxSetConstructor(right) && isSandboxSet(left)) {
|
|
2070
2089
|
return true;
|
|
2071
2090
|
}
|
|
@@ -2131,8 +2150,8 @@ function applyAdditionOperator(left, right, context) {
|
|
|
2131
2150
|
return toNumber(leftPrimitive) + toNumber(rightPrimitive);
|
|
2132
2151
|
}
|
|
2133
2152
|
function compareRelational(left, right, operator) {
|
|
2134
|
-
const leftPrimitive = toPrimitive(left);
|
|
2135
|
-
const rightPrimitive = toPrimitive(right);
|
|
2153
|
+
const leftPrimitive = isSandboxDate(left) ? dateTime(left) : toPrimitive(left);
|
|
2154
|
+
const rightPrimitive = isSandboxDate(right) ? dateTime(right) : toPrimitive(right);
|
|
2136
2155
|
if (typeof leftPrimitive === "string" && typeof rightPrimitive === "string") {
|
|
2137
2156
|
switch (operator) {
|
|
2138
2157
|
case "<":
|
|
@@ -2215,6 +2234,8 @@ function toPrimitive(value) {
|
|
|
2215
2234
|
return toString(value);
|
|
2216
2235
|
}
|
|
2217
2236
|
async function toNumericPrimitive(value, context) {
|
|
2237
|
+
if (isSandboxDate(value))
|
|
2238
|
+
return dateTime(value);
|
|
2218
2239
|
if (isPrimitiveCoercionType(getCoercionType(value))) {
|
|
2219
2240
|
return value;
|
|
2220
2241
|
}
|
|
@@ -2237,6 +2258,8 @@ async function toNumericPrimitive(value, context) {
|
|
|
2237
2258
|
return toString(value);
|
|
2238
2259
|
}
|
|
2239
2260
|
function toNumber(value) {
|
|
2261
|
+
if (isSandboxDate(value))
|
|
2262
|
+
return dateTime(value);
|
|
2240
2263
|
if (typeof value === "number") {
|
|
2241
2264
|
return value;
|
|
2242
2265
|
}
|
|
@@ -2255,6 +2278,8 @@ function toNumber(value) {
|
|
|
2255
2278
|
return toNumber(toPrimitive(value));
|
|
2256
2279
|
}
|
|
2257
2280
|
function toString(value) {
|
|
2281
|
+
if (isSandboxDate(value))
|
|
2282
|
+
return dateString(value);
|
|
2258
2283
|
if (Array.isArray(value)) {
|
|
2259
2284
|
return value
|
|
2260
2285
|
.map((entry) => (entry === null || entry === undefined ? "" : toString(entry)))
|
|
@@ -2284,6 +2309,8 @@ function isPlainSandboxObject(value) {
|
|
|
2284
2309
|
!isSandboxRegex(value));
|
|
2285
2310
|
}
|
|
2286
2311
|
function getMemberValue(target, property, context) {
|
|
2312
|
+
if (isGuestHostObject(target))
|
|
2313
|
+
return getHostObjectMember(target, String(property));
|
|
2287
2314
|
let current = target;
|
|
2288
2315
|
let depth = 0;
|
|
2289
2316
|
while (typeof current === "object" && current !== null) {
|
|
@@ -2311,6 +2338,12 @@ function getArrayMemberValue(target, property, context) {
|
|
|
2311
2338
|
return getArrayMember(target, property, createArrayMethodOptions(context));
|
|
2312
2339
|
}
|
|
2313
2340
|
export function setSandboxProperty(target, property, value, budget) {
|
|
2341
|
+
if (isSandboxDate(target))
|
|
2342
|
+
throw new TypeError("Date own properties are not supported.");
|
|
2343
|
+
if (isGuestHostObject(target)) {
|
|
2344
|
+
setHostObjectMember(target, String(property), value);
|
|
2345
|
+
return;
|
|
2346
|
+
}
|
|
2314
2347
|
const prototypeOwner = target;
|
|
2315
2348
|
if (isGuestClosure(target))
|
|
2316
2349
|
target = materializeFunctionProperties(target);
|
|
@@ -2359,6 +2392,8 @@ export function setSandboxProperty(target, property, value, budget) {
|
|
|
2359
2392
|
}
|
|
2360
2393
|
}
|
|
2361
2394
|
function deleteSandboxProperty(target, property) {
|
|
2395
|
+
if (isGuestHostObject(target))
|
|
2396
|
+
throw new TypeError("Live host properties cannot be deleted.");
|
|
2362
2397
|
if (isGuestClosure(target))
|
|
2363
2398
|
target = materializeFunctionProperties(target);
|
|
2364
2399
|
if (Array.isArray(target)) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assertSandboxDataDepth } from "../graph-depth.js";
|
|
2
|
+
import { getHostObjectMember, isGuestHostObject, isLiveCapability } from "./host-capabilities.js";
|
|
2
3
|
import { isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, isSandboxRegex, isSandboxSet } from "./values.js";
|
|
3
4
|
const guestClosures = new WeakSet();
|
|
4
5
|
const functionProperties = new WeakMap();
|
|
@@ -62,6 +63,8 @@ export function getSandboxDataProperty(value, key, budget) {
|
|
|
62
63
|
let current = value;
|
|
63
64
|
let depth = 0;
|
|
64
65
|
while (typeof current === "object" && current !== null) {
|
|
66
|
+
if (isGuestHostObject(current))
|
|
67
|
+
return getHostObjectMember(current, String(key));
|
|
65
68
|
if (isGuestClosure(current))
|
|
66
69
|
return getGuestFunctionProperty(current, String(key));
|
|
67
70
|
if (isSandboxClosure(current)) {
|
|
@@ -108,6 +111,8 @@ export function setSandboxPrototype(value, prototype, budget) {
|
|
|
108
111
|
prototypes.set(value, prototype);
|
|
109
112
|
}
|
|
110
113
|
function isPrototypeRecord(value) {
|
|
114
|
+
if (isGuestHostObject(value))
|
|
115
|
+
return false;
|
|
111
116
|
if (isSandboxClosure(value) ||
|
|
112
117
|
isSandboxGenerator(value) ||
|
|
113
118
|
isSandboxMap(value) ||
|
|
@@ -125,6 +130,8 @@ export function hasManagedDescriptors(value) {
|
|
|
125
130
|
return descriptorObjects.has(value);
|
|
126
131
|
}
|
|
127
132
|
export function hasGuestObjectState(value) {
|
|
133
|
+
if (isLiveCapability(value))
|
|
134
|
+
return true;
|
|
128
135
|
if (functionProperties.has(value) || prototypes.has(value))
|
|
129
136
|
return true;
|
|
130
137
|
return (descriptorObjects.has(value) &&
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
2
|
+
import { dateString, isSandboxDate } from "./date.js";
|
|
2
3
|
import { float32Storage, isFloat32Array } from "./float32.js";
|
|
3
4
|
import { isSandboxClosure, isSandboxPromise } from "./values.js";
|
|
4
5
|
export function sandboxString(value, budget, context, joining = new Set()) {
|
|
@@ -41,6 +42,8 @@ async function stringifyObject(value, budget, context, joining) {
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
async function defaultToString(value, budget, context, joining) {
|
|
45
|
+
if (isSandboxDate(value))
|
|
46
|
+
return budget.allocateString(dateString(value));
|
|
44
47
|
if (Array.isArray(value) || isFloat32Array(value)) {
|
|
45
48
|
if (Object.hasOwn(value, "join")) {
|
|
46
49
|
const join = ownDataValue(value, "join");
|
|
@@ -12,7 +12,7 @@ declare const sandboxRegexPattern: unique symbol;
|
|
|
12
12
|
declare const sandboxSetBrand: unique symbol;
|
|
13
13
|
declare const sandboxRetainedValues: unique symbol;
|
|
14
14
|
export type SandboxPrimitive = string | number | boolean | null | undefined;
|
|
15
|
-
export type SandboxValue = SandboxPrimitive | Float32Array | SandboxObject | SandboxArray | SandboxClosure | SandboxGenerator | SandboxMap | SandboxSet | SandboxPromise | SandboxRegex;
|
|
15
|
+
export type SandboxValue = SandboxPrimitive | Date | Float32Array | SandboxObject | SandboxArray | SandboxClosure | SandboxGenerator | SandboxMap | SandboxSet | SandboxPromise | SandboxRegex;
|
|
16
16
|
export type SandboxObject = {
|
|
17
17
|
[key: string]: SandboxValue;
|
|
18
18
|
};
|
|
@@ -86,6 +86,7 @@ export type SandboxGenerator = {
|
|
|
86
86
|
};
|
|
87
87
|
type CopyFromSandboxOptions = {
|
|
88
88
|
wrapClosure?: (value: SandboxClosure) => unknown;
|
|
89
|
+
unwrapHostObject?: (value: SandboxObject) => unknown;
|
|
89
90
|
compilation?: CompileScope;
|
|
90
91
|
};
|
|
91
92
|
export declare function createSandboxClosure(input: {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { bindOtelSpan, getBoundOtelSpan } from "../observability/otel.js";
|
|
2
|
+
import { copyNativeDate, exportDate, isSandboxDate } from "./date.js";
|
|
3
|
+
import { getHostObjectKeys, getHostObjectMember, isGuestHostObject, isLiveCapability } from "./host-capabilities.js";
|
|
2
4
|
import { types as nodeTypes } from "node:util";
|
|
3
5
|
import { CompileScope, RegexCompileGuard, regexCompiledData } from "./regex/compile-guard.js";
|
|
4
6
|
import { copyFloat32Storage, float32DataProperties, float32Storage, isFloat32Array } from "./float32.js";
|
|
@@ -70,6 +72,8 @@ export function createSandboxClosure(input) {
|
|
|
70
72
|
return Object.freeze(closure);
|
|
71
73
|
}
|
|
72
74
|
export function ownEnumerableSandboxEntries(value) {
|
|
75
|
+
if (isGuestHostObject(value))
|
|
76
|
+
return getHostObjectKeys(value).map(key => [key, getHostObjectMember(value, key)]);
|
|
73
77
|
if (value === null || value === undefined)
|
|
74
78
|
throw new TypeError("Cannot convert undefined or null to object.");
|
|
75
79
|
if (isGuestClosure(value))
|
|
@@ -222,6 +226,15 @@ export function measureSandboxData(values, options = {}) {
|
|
|
222
226
|
assertSandboxDataDepth(depth);
|
|
223
227
|
seen.add(value);
|
|
224
228
|
usage += 1;
|
|
229
|
+
if (isSandboxDate(value)) {
|
|
230
|
+
usage += 8;
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (isGuestHostObject(value)) {
|
|
234
|
+
for (const key of getHostObjectKeys(value))
|
|
235
|
+
usage += key.length + 1;
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
225
238
|
const prototype = getSandboxPrototype(value);
|
|
226
239
|
if (prototype !== null)
|
|
227
240
|
visit(prototype, depth + 1);
|
|
@@ -376,6 +389,8 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
376
389
|
if (isSandboxPrimitive(value)) {
|
|
377
390
|
return value;
|
|
378
391
|
}
|
|
392
|
+
if (isLiveCapability(value))
|
|
393
|
+
throw new TypeError("Live capabilities require their owning realm bridge.");
|
|
379
394
|
if (isSandboxClosure(value) ||
|
|
380
395
|
isSandboxGenerator(value) ||
|
|
381
396
|
isSandboxRegex(value) ||
|
|
@@ -425,6 +440,14 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
425
440
|
}
|
|
426
441
|
return sandboxPromise;
|
|
427
442
|
}
|
|
443
|
+
if (nodeTypes.isDate(value)) {
|
|
444
|
+
const existing = state.seen.get(value);
|
|
445
|
+
if (existing !== undefined)
|
|
446
|
+
return existing;
|
|
447
|
+
const copy = copyNativeDate(value);
|
|
448
|
+
state.seen.set(value, copy);
|
|
449
|
+
return copy;
|
|
450
|
+
}
|
|
428
451
|
if (isFloat32Array(value)) {
|
|
429
452
|
const existing = state.seen.get(value);
|
|
430
453
|
if (existing !== undefined)
|
|
@@ -508,6 +531,11 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
508
531
|
if (isSandboxPrimitive(value)) {
|
|
509
532
|
return value;
|
|
510
533
|
}
|
|
534
|
+
if (isGuestHostObject(value)) {
|
|
535
|
+
if (options.unwrapHostObject === undefined)
|
|
536
|
+
throw new TypeError("Live capabilities require their owning realm bridge.");
|
|
537
|
+
return options.unwrapHostObject(value);
|
|
538
|
+
}
|
|
511
539
|
if (nodeTypes.isProxy(value))
|
|
512
540
|
throw new TypeError("Unsupported proxy sandbox value.");
|
|
513
541
|
if (!isSandboxClosure(value) && hasGuestObjectState(value)) {
|
|
@@ -552,6 +580,14 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
552
580
|
Object.preventExtensions(copy);
|
|
553
581
|
return copy;
|
|
554
582
|
}
|
|
583
|
+
if (isSandboxDate(value)) {
|
|
584
|
+
const existing = state.seen.get(value);
|
|
585
|
+
if (existing !== undefined)
|
|
586
|
+
return existing;
|
|
587
|
+
const copy = exportDate(value);
|
|
588
|
+
state.seen.set(value, copy);
|
|
589
|
+
return copy;
|
|
590
|
+
}
|
|
555
591
|
if (isSandboxClosure(value)) {
|
|
556
592
|
if (options.wrapClosure === undefined) {
|
|
557
593
|
throw new TypeError("Sandbox closures cannot cross into host values without an explicit wrapper.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const KNOWN_RUNTIME_GLOBALS: readonly ["AggregateError", "Array", "Boolean", "Error", "Infinity", "isFinite", "isNaN", "JSON", "Map", "Float32Array", "Math", "NaN", "Number", "Object", "parseFloat", "parseInt", "Promise", "RangeError", "ReferenceError", "RegExp", "Set", "String", "structuredClone", "SyntaxError", "TypeError", "console"];
|
|
1
|
+
export declare const KNOWN_RUNTIME_GLOBALS: readonly ["AggregateError", "Array", "Boolean", "Date", "Error", "Infinity", "isFinite", "isNaN", "JSON", "Map", "Float32Array", "Math", "NaN", "Number", "Object", "parseFloat", "parseInt", "Promise", "RangeError", "ReferenceError", "RegExp", "Set", "String", "structuredClone", "SyntaxError", "TypeError", "console"];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Budget, CompileOwner } from "../interp/budget.js";
|
|
2
2
|
import type { HostCallJournal } from "../interp/host-call.js";
|
|
3
|
-
import { type CallerInjectedBinding } from "../interp/host-bridge.js";
|
|
3
|
+
import { type RealmBridge, type CallerInjectedBinding } from "../interp/host-bridge.js";
|
|
4
4
|
import type { SandboxValue } from "../interp/values.js";
|
|
5
5
|
import type { Module } from "../parse/parser.js";
|
|
6
6
|
export type ModuleExports = ReadonlyMap<string, CallerInjectedBinding> | Record<string, CallerInjectedBinding>;
|
|
@@ -9,6 +9,8 @@ export declare function createUnknownModuleMessage(moduleName: string, moduleNam
|
|
|
9
9
|
export declare function createUnknownExportMessage(moduleName: string, exportName: string, availableExports: readonly string[]): string;
|
|
10
10
|
export declare function resolveModuleImports(module: Module, modules: ModuleRegistry | undefined, options: {
|
|
11
11
|
budget: Budget;
|
|
12
|
+
realm?: RealmBridge;
|
|
13
|
+
wrappedModules?: Map<string, Record<string, SandboxValue>>;
|
|
12
14
|
compileOwner?: CompileOwner;
|
|
13
15
|
hostCalls?: HostCallJournal;
|
|
14
16
|
signal?: AbortSignal;
|
|
@@ -17,7 +17,7 @@ export function createUnknownExportMessage(moduleName, exportName, availableExpo
|
|
|
17
17
|
export function resolveModuleImports(module, modules, options) {
|
|
18
18
|
const registry = normalizeModuleRegistry(modules);
|
|
19
19
|
const bindings = createBindingRecord();
|
|
20
|
-
const wrappedModules = new Map();
|
|
20
|
+
const wrappedModules = options.wrappedModules ?? new Map();
|
|
21
21
|
for (const statement of module.body) {
|
|
22
22
|
if (statement.type !== "ImportDeclaration") {
|
|
23
23
|
continue;
|
|
@@ -36,6 +36,7 @@ function bindImportDeclaration(declaration, registry, wrappedModules, bindings,
|
|
|
36
36
|
}
|
|
37
37
|
const wrappedExports = wrappedModules.get(moduleName) ??
|
|
38
38
|
createBindingRecord(wrapCancelableBindings(wrapCallerInjectedBindings(Object.fromEntries(moduleExports), {
|
|
39
|
+
realm: options.realm,
|
|
39
40
|
budget: options.budget,
|
|
40
41
|
compileOwner: options.compileOwner,
|
|
41
42
|
hostCalls: options.hostCalls,
|
|
@@ -1832,8 +1832,10 @@ class Parser {
|
|
|
1832
1832
|
}
|
|
1833
1833
|
break;
|
|
1834
1834
|
}
|
|
1835
|
-
this.
|
|
1836
|
-
|
|
1835
|
+
const optional = this.consumePunctuator("?.");
|
|
1836
|
+
if (optional !== undefined)
|
|
1837
|
+
throw new DisallowedSyntaxError("new optional chain", optional.start);
|
|
1838
|
+
const args = this.consumePunctuator("(") === undefined ? [] : this.parseArguments();
|
|
1837
1839
|
const end = this.previousToken();
|
|
1838
1840
|
return {
|
|
1839
1841
|
node: {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Budget } from "./interp/budget.js";
|
|
2
|
+
import { type InterpreterResult } from "./interp/interpreter.js";
|
|
3
|
+
import { type CallerInjectedBinding } from "./interp/host-bridge.js";
|
|
4
|
+
import { type CallbackOptions, type SafeJSExtension } from "./extensions.js";
|
|
5
|
+
import { type ModuleRegistry } from "./modules/registry.js";
|
|
6
|
+
import type { ConsoleSink } from "./interp/globals/console-json.js";
|
|
7
|
+
import type { RunClock, RunOptions, RunResult } from "./run.js";
|
|
8
|
+
export type RealmLimits = {
|
|
9
|
+
extensions?: number;
|
|
10
|
+
hostObjects?: number;
|
|
11
|
+
callbacks?: number;
|
|
12
|
+
guestReferences?: number;
|
|
13
|
+
cleanups?: number;
|
|
14
|
+
nestedEvaluations?: number;
|
|
15
|
+
};
|
|
16
|
+
export type RealmOptions = {
|
|
17
|
+
clock?: RunClock;
|
|
18
|
+
bindings?: Record<string, CallerInjectedBinding>;
|
|
19
|
+
modules?: ModuleRegistry;
|
|
20
|
+
extensions?: readonly SafeJSExtension[];
|
|
21
|
+
grants?: readonly string[];
|
|
22
|
+
budget?: Budget;
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
sink?: ConsoleSink;
|
|
25
|
+
randomSeed?: number;
|
|
26
|
+
limits?: RealmLimits;
|
|
27
|
+
};
|
|
28
|
+
export type RealmResult = (Omit<Extract<InterpreterResult, {
|
|
29
|
+
ok: true;
|
|
30
|
+
}>, "snapshot" | "returnValue"> & {
|
|
31
|
+
returnValue?: unknown;
|
|
32
|
+
}) | Omit<Extract<InterpreterResult, {
|
|
33
|
+
ok: false;
|
|
34
|
+
}>, "snapshot">;
|
|
35
|
+
export type SafeJSRealm = {
|
|
36
|
+
readonly extensions: readonly SafeJSExtension["manifest"][];
|
|
37
|
+
evaluate(source: string, options?: {
|
|
38
|
+
filename?: string;
|
|
39
|
+
}): Promise<RealmResult>;
|
|
40
|
+
invokeCallback(callback: unknown, options?: CallbackOptions): Promise<unknown>;
|
|
41
|
+
releaseCallback(callback: unknown): void;
|
|
42
|
+
releaseGuestReference(reference: unknown): void;
|
|
43
|
+
close(): Promise<void>;
|
|
44
|
+
};
|
|
45
|
+
export declare function createRealm(options?: RealmOptions): SafeJSRealm;
|
|
46
|
+
export declare function runWithExtensions(source: string, options: RunOptions): Promise<RunResult>;
|