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,10 +1,11 @@
|
|
|
1
|
+
import { type RealmOptions } from "./realm.js";
|
|
1
2
|
import { type ErrorSourceSpan } from "./error/shape.js";
|
|
2
3
|
import { type SourceSpan } from "./parse/parser.js";
|
|
3
4
|
import { type SafeJSSnapshot } from "./restore.js";
|
|
4
5
|
import { Budget } from "./interp/budget.js";
|
|
5
6
|
import { type PromiseReplaySnapshot } from "./interp/promise-replay.js";
|
|
6
7
|
import { type HostCallRecord, type HostCallReplay, type HostCallResumeProvider } from "./interp/host-call.js";
|
|
7
|
-
import {
|
|
8
|
+
import type { ConsoleSink } from "./interp/globals/console-json.js";
|
|
8
9
|
import { type CallerInjectedBinding } from "./interp/host-bridge.js";
|
|
9
10
|
import { type InterpreterResult, type LoopIterationSnapshot } from "./interp/interpreter.js";
|
|
10
11
|
import { type ModuleRegistry } from "./modules/registry.js";
|
|
@@ -12,6 +13,9 @@ import { type OtelSink } from "./observability/otel.js";
|
|
|
12
13
|
import type { SnapshotBackend } from "./snapshot/backend.js";
|
|
13
14
|
import { type ReplayData } from "./snapshot/replay-data.js";
|
|
14
15
|
export type RunOptions = {
|
|
16
|
+
extensions?: RealmOptions["extensions"];
|
|
17
|
+
grants?: RealmOptions["grants"];
|
|
18
|
+
limits?: RealmOptions["limits"];
|
|
15
19
|
bindings?: Record<string, CallerInjectedBinding>;
|
|
16
20
|
budget?: Budget;
|
|
17
21
|
clock?: RunClock;
|
|
@@ -59,6 +63,8 @@ export type RunClockSnapshot = {
|
|
|
59
63
|
next: number;
|
|
60
64
|
};
|
|
61
65
|
export type RunClock = {
|
|
66
|
+
now?: () => number;
|
|
67
|
+
restore?: (snapshot: RunClockSnapshot) => void;
|
|
62
68
|
snapshot: () => RunClockSnapshot | undefined;
|
|
63
69
|
};
|
|
64
70
|
export type RunRandom = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import { runWithExtensions } from "./realm.js";
|
|
2
3
|
import { hashParsedAst, hashSource } from "./parse/hash.js";
|
|
3
4
|
import { withRunResources } from "./interp/resources.js";
|
|
4
5
|
import { createReplayableRandom } from "./random.js";
|
|
@@ -12,17 +13,10 @@ import { wrapCancelableBindings } from "./interp/cancel.js";
|
|
|
12
13
|
import { enterSnapshotRun } from "./interp/running-state.js";
|
|
13
14
|
import { createSandboxPromiseRejectionTracker, observeSandboxPromise, withSandboxPromiseRejectionTracker } from "./interp/promise-tracker.js";
|
|
14
15
|
import { HostCallJournal } from "./interp/host-call.js";
|
|
15
|
-
import {
|
|
16
|
-
import { createCollectionGlobals } from "./interp/globals/collections.js";
|
|
17
|
-
import { createFloat32ArrayGlobal } from "./interp/globals/float32array.js";
|
|
18
|
-
import { createErrorGlobals } from "./interp/globals/error.js";
|
|
19
|
-
import { createMathGlobals } from "./interp/globals/math.js";
|
|
20
|
-
import { createRegexGlobals } from "./interp/globals/regex.js";
|
|
21
|
-
import { createMiscGlobals } from "./interp/globals/misc.js";
|
|
22
|
-
import { createObjectArrayGlobals } from "./interp/globals/object-array.js";
|
|
16
|
+
import { createBuiltinBindings } from "./interp/globals.js";
|
|
23
17
|
import { declareHostOperation, wrapCallerInjectedBindings } from "./interp/host-bridge.js";
|
|
24
18
|
import { interpret, Scope } from "./interp/interpreter.js";
|
|
25
|
-
import { consumeSettledHostCall
|
|
19
|
+
import { consumeSettledHostCall } from "./interp/promise.js";
|
|
26
20
|
import { deepCopyToSandbox, isSandboxClosure, isSandboxPromise, measureSandboxData, reconcileCompiledValues } from "./interp/values.js";
|
|
27
21
|
import { resolveModuleImports } from "./modules/registry.js";
|
|
28
22
|
import { activateOtelSink, getActiveOtelSpan, safeAddEvent } from "./observability/otel.js";
|
|
@@ -44,6 +38,8 @@ export class UnhandledRejectionError extends Error {
|
|
|
44
38
|
}
|
|
45
39
|
const DEFAULT_MAX_CALL_DEPTH = 1_000;
|
|
46
40
|
export function run(source, options = {}) {
|
|
41
|
+
if (options.extensions !== undefined)
|
|
42
|
+
return runWithExtensions(source, options);
|
|
47
43
|
const lifecycle = {
|
|
48
44
|
hostCallbackDepth: 0,
|
|
49
45
|
hostCallbackContext: new AsyncLocalStorage()
|
|
@@ -113,32 +109,7 @@ export function run(source, options = {}) {
|
|
|
113
109
|
signal: options.signal,
|
|
114
110
|
lifecycle
|
|
115
111
|
}));
|
|
116
|
-
const builtinBindings = {
|
|
117
|
-
...createConsoleJsonGlobals({
|
|
118
|
-
compileOwner: operation.owner,
|
|
119
|
-
budget,
|
|
120
|
-
hostCalls,
|
|
121
|
-
sink: options.sink
|
|
122
|
-
}),
|
|
123
|
-
...createCollectionGlobals({ budget }),
|
|
124
|
-
Float32Array: createFloat32ArrayGlobal(budget),
|
|
125
|
-
...createErrorGlobals({
|
|
126
|
-
budget
|
|
127
|
-
}),
|
|
128
|
-
...createMathGlobals({
|
|
129
|
-
random: random?.generator.next
|
|
130
|
-
}),
|
|
131
|
-
...createObjectArrayGlobals({
|
|
132
|
-
budget
|
|
133
|
-
}),
|
|
134
|
-
...createMiscGlobals({
|
|
135
|
-
budget
|
|
136
|
-
}),
|
|
137
|
-
...createPromiseGlobals({
|
|
138
|
-
budget
|
|
139
|
-
}),
|
|
140
|
-
...createRegexGlobals(operation.owner)
|
|
141
|
-
};
|
|
112
|
+
const builtinBindings = createBuiltinBindings({ compileOwner: operation.owner, budget, hostCalls, sink: options.sink, random: random?.generator.next, clock: options.clock });
|
|
142
113
|
const importMeta = convertInitialInput(() => deepCopyToSandbox(options.importMeta ?? {}));
|
|
143
114
|
if (restoredSnapshot?.migration !== undefined) {
|
|
144
115
|
if (Object.hasOwn(importMeta, "migration"))
|
|
@@ -8,6 +8,7 @@ import { serializeArguments } from "./arguments.js";
|
|
|
8
8
|
import { requiresArrayEntries, serializeArray } from "./arrays.js";
|
|
9
9
|
import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
|
|
10
10
|
import { encodeFloat32Storage } from "./float32array.js";
|
|
11
|
+
import { isSandboxDate, serializedDateTime } from "../interp/date.js";
|
|
11
12
|
const SKIP_VALUE = Symbol("SafeJS.skip-dump-value");
|
|
12
13
|
export function serializeSafeJSSnapshot(snapshot) {
|
|
13
14
|
const replayError = Object.getOwnPropertyDescriptor(snapshot, "replayError");
|
|
@@ -72,7 +73,7 @@ function serializeDumpValue(value, path, state) {
|
|
|
72
73
|
if (hasGuestObjectState(value)) {
|
|
73
74
|
throw new TypeError("Guest function properties and prototype links cannot be serialized.");
|
|
74
75
|
}
|
|
75
|
-
if (isFloat32Array(value))
|
|
76
|
+
if (isSandboxDate(value) || isFloat32Array(value))
|
|
76
77
|
return serializeHeapReference(value, path, state);
|
|
77
78
|
if (Array.isArray(value)) {
|
|
78
79
|
const reference = serializeHeapReference(value, path, state);
|
|
@@ -97,7 +98,10 @@ function serializeHeapReference(value, path, state) {
|
|
|
97
98
|
}
|
|
98
99
|
if (!state.serializedHeapIds.has(id)) {
|
|
99
100
|
state.serializedHeapIds.add(id);
|
|
100
|
-
if (
|
|
101
|
+
if (isSandboxDate(value)) {
|
|
102
|
+
state.heap[String(id)] = { kind: "date", time: serializedDateTime(value) };
|
|
103
|
+
}
|
|
104
|
+
else if (isFloat32Array(value)) {
|
|
101
105
|
const storage = encodeFloat32Storage(value, id, state.float32Buffers, (id) => ({
|
|
102
106
|
kind: "ref",
|
|
103
107
|
id
|
|
@@ -159,6 +163,7 @@ function indexHeapContainers(snapshot) {
|
|
|
159
163
|
for (const [value, stat] of stats.entries()) {
|
|
160
164
|
if (stat.count > 1 ||
|
|
161
165
|
stat.cyclic ||
|
|
166
|
+
isSandboxDate(value) ||
|
|
162
167
|
isFloat32Array(value) ||
|
|
163
168
|
(Array.isArray(value) && requiresArrayEntries(value)) ||
|
|
164
169
|
isSandboxArguments(value) ||
|
|
@@ -173,7 +178,7 @@ function collectContainerStats(value, stats, ancestors) {
|
|
|
173
178
|
if (value === null || typeof value !== "object") {
|
|
174
179
|
return;
|
|
175
180
|
}
|
|
176
|
-
if (!Array.isArray(value) && !isPlainObject(value) && !isFloat32Array(value)) {
|
|
181
|
+
if (!Array.isArray(value) && !isPlainObject(value) && !isFloat32Array(value) && !isSandboxDate(value)) {
|
|
177
182
|
return;
|
|
178
183
|
}
|
|
179
184
|
let stat = stats.get(value);
|
|
@@ -24,7 +24,10 @@ type Properties = Record<string, {
|
|
|
24
24
|
enumerable: boolean;
|
|
25
25
|
writable: boolean;
|
|
26
26
|
}>;
|
|
27
|
-
type DataNode =
|
|
27
|
+
type DataNode = {
|
|
28
|
+
kind: "date";
|
|
29
|
+
time: number | null;
|
|
30
|
+
} | (Float32Data<Atom> & {
|
|
28
31
|
properties: Properties;
|
|
29
32
|
extensible: boolean;
|
|
30
33
|
}) | {
|
|
@@ -3,6 +3,7 @@ import { hasGuestObjectState } from "../interp/object-model.js";
|
|
|
3
3
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
4
4
|
import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
|
|
5
5
|
import { decodeFloat32Storage, encodeFloat32Storage } from "./float32array.js";
|
|
6
|
+
import { isSandboxDate, restoreDateTime, serializedDateTime } from "../interp/date.js";
|
|
6
7
|
import { sandboxErrorNames, sandboxErrorTypes } from "../error/shape.js";
|
|
7
8
|
import { createSandboxArguments, createSandboxClosure, createSandboxMap, createSandboxRegex, createSandboxSet, isSandboxArguments, isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, isSandboxRegex, isSandboxSet } from "../interp/values.js";
|
|
8
9
|
import { serializeArguments } from "./arguments.js";
|
|
@@ -63,6 +64,9 @@ export function encodeReplayData(value, options = {}) {
|
|
|
63
64
|
properties: child(entry.properties, "properties")
|
|
64
65
|
};
|
|
65
66
|
}
|
|
67
|
+
else if (isSandboxDate(entry)) {
|
|
68
|
+
nodes[id] = { kind: "date", time: serializedDateTime(entry) };
|
|
69
|
+
}
|
|
66
70
|
else if (isFloat32Array(entry)) {
|
|
67
71
|
const storage = encodeFloat32Storage(entry, id, float32Buffers, (id) => ({
|
|
68
72
|
tag: "ref",
|
|
@@ -231,6 +235,13 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
231
235
|
options.onCapabilityRestored?.(capability, copy);
|
|
232
236
|
return copy;
|
|
233
237
|
}
|
|
238
|
+
if (kind === "date") {
|
|
239
|
+
if (Object.keys(node).length !== 2)
|
|
240
|
+
throw new TypeError("Invalid serialized Date fields.");
|
|
241
|
+
const result = restoreDateTime(own(node, "time"));
|
|
242
|
+
restored.set(id, result);
|
|
243
|
+
return result;
|
|
244
|
+
}
|
|
234
245
|
if (kind === "float32array") {
|
|
235
246
|
if (typeof node.extensible !== "boolean")
|
|
236
247
|
throw new TypeError("Invalid Float32Array extensibility.");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Budget, SandboxError } from "../interp/budget.js";
|
|
2
2
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
3
3
|
import { decodeFloat32Storage } from "./float32array.js";
|
|
4
|
+
import { restoreDateTime } from "../interp/date.js";
|
|
4
5
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
5
6
|
import { SnapshotMismatchError } from "../restore.js";
|
|
6
7
|
import { Scope, setSandboxProperty } from "../interp/interpreter.js";
|
|
@@ -339,6 +340,11 @@ function restoreHeapValue(id, state) {
|
|
|
339
340
|
if (serialized === undefined) {
|
|
340
341
|
throw new Error(`Snapshot references unknown heap value ${id}.`);
|
|
341
342
|
}
|
|
343
|
+
if (serialized.kind === "date") {
|
|
344
|
+
const value = restoreDateTime(serialized.time);
|
|
345
|
+
state.heapValueById.set(id, value);
|
|
346
|
+
return value;
|
|
347
|
+
}
|
|
342
348
|
if (serialized.kind === "float32array") {
|
|
343
349
|
const value = decodeFloat32Storage(serialized, (reference) => deserializeValue(reference, state));
|
|
344
350
|
state.heapValueById.set(id, value);
|
|
@@ -40,7 +40,10 @@ export type SerializedReferenceValue = {
|
|
|
40
40
|
kind: "ref";
|
|
41
41
|
id: number;
|
|
42
42
|
};
|
|
43
|
-
export type SerializedHeapValue =
|
|
43
|
+
export type SerializedHeapValue = {
|
|
44
|
+
kind: "date";
|
|
45
|
+
time: number | null;
|
|
46
|
+
} | (Float32Data<SerializedReferenceValue> & {
|
|
44
47
|
entries: Record<string, SerializedSnapshotValue>;
|
|
45
48
|
}) | SerializedArguments<SerializedSnapshotValue> | SerializedArray<SerializedSnapshotValue> | {
|
|
46
49
|
kind: "object";
|
|
@@ -72,7 +75,7 @@ export type RuntimePromiseValue = {
|
|
|
72
75
|
id: SnapshotId;
|
|
73
76
|
promise?: Promise<unknown>;
|
|
74
77
|
};
|
|
75
|
-
export type RuntimeSnapshotValue = Float32Array | boolean | null | number | string | undefined | RuntimeClosureValue | SandboxGenerator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
|
|
78
|
+
export type RuntimeSnapshotValue = Date | Float32Array | boolean | null | number | string | undefined | RuntimeClosureValue | SandboxGenerator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
|
|
76
79
|
[key: string]: RuntimeSnapshotValue;
|
|
77
80
|
};
|
|
78
81
|
export type RuntimeScopeFrame = {
|
|
@@ -6,6 +6,7 @@ import { serializeArguments } from "./arguments.js";
|
|
|
6
6
|
import { requiresArrayEntries, serializeArray } from "./arrays.js";
|
|
7
7
|
import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
|
|
8
8
|
import { encodeFloat32Storage } from "./float32array.js";
|
|
9
|
+
import { isSandboxDate, serializedDateTime } from "../interp/date.js";
|
|
9
10
|
import { isSandboxArguments, isSandboxGenerator, isSandboxMap, isSandboxRegex, isSandboxSet } from "../interp/values.js";
|
|
10
11
|
export class UnsnapshotableValueError extends Error {
|
|
11
12
|
path;
|
|
@@ -161,7 +162,7 @@ function serializeValue(value, path, state) {
|
|
|
161
162
|
if (isSandboxRegex(value)) {
|
|
162
163
|
return { kind: "regex", source: value.source, flags: value.flags, lastIndex: value.lastIndex };
|
|
163
164
|
}
|
|
164
|
-
if (isSandboxMap(value) || isSandboxSet(value) || isFloat32Array(value)) {
|
|
165
|
+
if (isSandboxDate(value) || isSandboxMap(value) || isSandboxSet(value) || isFloat32Array(value)) {
|
|
165
166
|
const reference = serializeHeapReference(value, path, state);
|
|
166
167
|
if (reference === undefined) {
|
|
167
168
|
throw new TypeError(`Cannot serialize collection without a heap reference at ${path}.`);
|
|
@@ -190,7 +191,10 @@ function serializeHeapReference(value, path, state) {
|
|
|
190
191
|
}
|
|
191
192
|
if (!state.serializedHeapIds.has(id)) {
|
|
192
193
|
state.serializedHeapIds.add(id);
|
|
193
|
-
if (
|
|
194
|
+
if (isSandboxDate(value)) {
|
|
195
|
+
state.heap[String(id)] = { kind: "date", time: serializedDateTime(value) };
|
|
196
|
+
}
|
|
197
|
+
else if (isFloat32Array(value)) {
|
|
194
198
|
const storage = encodeFloat32Storage(value, id, state.float32Buffers, (id) => ({
|
|
195
199
|
kind: "ref",
|
|
196
200
|
id
|
|
@@ -297,6 +301,7 @@ function indexHeapContainers(input) {
|
|
|
297
301
|
for (const [value, stat] of stats.entries()) {
|
|
298
302
|
if (stat.count > 1 ||
|
|
299
303
|
stat.cyclic ||
|
|
304
|
+
isSandboxDate(value) ||
|
|
300
305
|
isFloat32Array(value) ||
|
|
301
306
|
(Array.isArray(value) && requiresArrayEntries(value)) ||
|
|
302
307
|
sandboxErrorTypes.has(value) ||
|
|
@@ -319,6 +324,7 @@ function collectContainerStats(value, stats, ancestors) {
|
|
|
319
324
|
}
|
|
320
325
|
if (!Array.isArray(value) &&
|
|
321
326
|
!isPlainObject(value) &&
|
|
327
|
+
!isSandboxDate(value) &&
|
|
322
328
|
!isFloat32Array(value) &&
|
|
323
329
|
!isSandboxMap(value) &&
|
|
324
330
|
!isSandboxSet(value)) {
|
|
@@ -3,6 +3,7 @@ import { types } from "node:util";
|
|
|
3
3
|
import { DUMP_FORMAT_VERSION } from "./dump-format.js";
|
|
4
4
|
import { MAX_DATA_DEPTH } from "../graph-depth.js";
|
|
5
5
|
import { validateFloat32Storage } from "./float32array.js";
|
|
6
|
+
import { restoreDateTime } from "../interp/date.js";
|
|
6
7
|
import { hasGuestObjectState } from "../interp/object-model.js";
|
|
7
8
|
const DEFAULT_MAX_DEPTH = MAX_DATA_DEPTH;
|
|
8
9
|
const DEFAULT_MAX_ENTRIES = 100_000;
|
|
@@ -80,6 +81,10 @@ function validateDumpHeap(root, state) {
|
|
|
80
81
|
addUnique(heapIds, id, path);
|
|
81
82
|
const entry = requireRecord(value, path);
|
|
82
83
|
validateErrorType(entry, path);
|
|
84
|
+
if (entry.kind === "date") {
|
|
85
|
+
validateDateRecord(entry, path);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
83
88
|
if (entry.kind === "float32array") {
|
|
84
89
|
validateFloat32Storage(entry);
|
|
85
90
|
requireRecord(entry.entries, `${path}.entries`);
|
|
@@ -402,7 +407,7 @@ function validateGeneratorShape(record, path, state) {
|
|
|
402
407
|
function validateHeapValue(value, path, state) {
|
|
403
408
|
const record = requireRecord(value, path);
|
|
404
409
|
validateErrorType(record, path);
|
|
405
|
-
if (!["arguments", "array", "object", "map", "set", "float32array"].includes(String(record.kind)))
|
|
410
|
+
if (!["arguments", "array", "object", "map", "set", "float32array", "date"].includes(String(record.kind)))
|
|
406
411
|
fail("unknownTag", `${path}.kind`, "unknown heap tag");
|
|
407
412
|
validateValue(record, path, 1, state);
|
|
408
413
|
if (record.kind === "arguments")
|
|
@@ -411,6 +416,8 @@ function validateHeapValue(value, path, state) {
|
|
|
411
416
|
validateArrayHeap(record, path, state);
|
|
412
417
|
if (record.kind === "object")
|
|
413
418
|
requireRecord(record.entries, `${path}.entries`);
|
|
419
|
+
if (record.kind === "date")
|
|
420
|
+
validateDateRecord(record, path);
|
|
414
421
|
if (record.kind === "float32array") {
|
|
415
422
|
validateFloat32Storage(record);
|
|
416
423
|
requireRecord(record.entries, `${path}.entries`);
|
|
@@ -425,6 +432,16 @@ function validateHeapValue(value, path, state) {
|
|
|
425
432
|
if (record.kind === "set")
|
|
426
433
|
requireArray(record.values, `${path}.values`, state);
|
|
427
434
|
}
|
|
435
|
+
function validateDateRecord(record, path) {
|
|
436
|
+
if (Object.keys(record).length !== 2)
|
|
437
|
+
fail("invalidValue", path, "invalid Date fields");
|
|
438
|
+
try {
|
|
439
|
+
restoreDateTime(record.time);
|
|
440
|
+
}
|
|
441
|
+
catch {
|
|
442
|
+
fail("invalidValue", `${path}.time`, "invalid Date epoch");
|
|
443
|
+
}
|
|
444
|
+
}
|
|
428
445
|
function validateArrayHeap(record, path, state) {
|
|
429
446
|
if (Object.hasOwn(record, "items")) {
|
|
430
447
|
requireArray(record.items, `${path}.items`, state);
|