poe-code 14.0.18 → 14.0.20

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-W6AHPZCN.js";
25
+ } from "./chunks/chunk-5XRQ3GNN.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-BW4SYRDC.js";
37
+ } from "./chunks/chunk-CZNLD2Z3.js";
38
38
  import "./chunks/chunk-7M2SJPSZ.js";
39
39
  import "./chunks/chunk-2QRYPKQQ.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-BW4SYRDC.js";
8
+ } from "./chunks/chunk-CZNLD2Z3.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-W6AHPZCN.js";
29
+ } from "./chunks/chunk-5XRQ3GNN.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-BW4SYRDC.js";
53
+ } from "./chunks/chunk-CZNLD2Z3.js";
54
54
  import "./chunks/chunk-7M2SJPSZ.js";
55
55
  import "./chunks/chunk-2QRYPKQQ.js";
56
56
  import "./chunks/chunk-4YIDX44G.js";
@@ -18,6 +18,9 @@ export type RealmOptions = {
18
18
  bindings?: Record<string, CallerInjectedBinding>;
19
19
  modules?: ModuleRegistry;
20
20
  extensions?: readonly SafeJSExtension[];
21
+ builtinOverrides?: {
22
+ console?: string;
23
+ };
21
24
  grants?: readonly string[];
22
25
  budget?: Budget;
23
26
  signal?: AbortSignal;
@@ -32,6 +32,7 @@ class RealmState {
32
32
  bridge;
33
33
  limits;
34
34
  extensions;
35
+ consoleExtension;
35
36
  cleanups = [];
36
37
  callbacks = new Map();
37
38
  pendingCallbacks = new Set();
@@ -91,6 +92,14 @@ class RealmState {
91
92
  const grants = new Set(readStringList(options.grants ?? [], "Realm grants"));
92
93
  for (const extension of this.extensions)
93
94
  getExtensionSetup(extension);
95
+ const overrides = readDataRecord(options.builtinOverrides === undefined ? {} : options.builtinOverrides, "Builtin overrides");
96
+ for (const [name, extensionName] of Object.entries(overrides)) {
97
+ if (name !== "console" || typeof extensionName !== "string" || extensionName.length === 0 || extensionName.length > 256)
98
+ throw new TypeError("Builtin overrides only supports console with a nonempty extension name.");
99
+ if (!this.extensions.some(extension => extension.manifest.name === extensionName && extension.manifest.globals?.includes(name)))
100
+ throw new TypeError("Console override requires a registered extension declaring console.");
101
+ this.consoleExtension = extensionName;
102
+ }
94
103
  this.budget = options.budget ?? new Budget({ maxCallDepth: 1000 });
95
104
  this.lease = this.budget.acquireCompileOwner(true);
96
105
  this.compilation = new CompileScope(this.lease.owner);
@@ -111,7 +120,10 @@ class RealmState {
111
120
  random: createReplayableRandom({ seed: options.randomSeed }).next
112
121
  });
113
122
  const names = new Set();
114
- const globals = new Set([...Object.keys(this.builtinBindings), ...Object.keys(this.globals)]);
123
+ const globals = new Set([
124
+ ...Object.keys(this.builtinBindings).filter(name => name !== "console" || this.consoleExtension === undefined),
125
+ ...Object.keys(this.globals)
126
+ ]);
115
127
  const modules = new Map(Object.entries(this.modules).map(([name, exports]) => [name, new Set(Object.keys(exports))]));
116
128
  for (const extension of this.extensions) {
117
129
  const manifest = extension.manifest;
@@ -123,6 +135,8 @@ class RealmState {
123
135
  throw new TypeError(`Missing grant '${capability}' for extension '${manifest.name}'.`);
124
136
  }
125
137
  for (const name of manifest.globals ?? []) {
138
+ if (name === "console" && this.consoleExtension !== undefined && manifest.name !== this.consoleExtension)
139
+ throw new TypeError(`Conflicting global 'console': replacement is authorized only for '${this.consoleExtension}'.`);
126
140
  if (globals.has(name))
127
141
  throw new TypeError(`Conflicting global '${name}'.`);
128
142
  globals.add(name);
@@ -539,6 +553,8 @@ class RealmState {
539
553
  const globals = readDataRecord(exports.globals ?? {}, "Extension globals");
540
554
  const modules = readModules(exports.modules);
541
555
  assertNames(Object.keys(globals), extension.manifest.globals ?? [], "global");
556
+ if (extension.manifest.name === this.consoleExtension && !this.hostObjects.has(globals.console))
557
+ throw new TypeError("Console replacement must be a host object created in this realm.");
542
558
  assertNames(Object.keys(modules), Object.keys(extension.manifest.modules ?? {}), "module");
543
559
  for (const [name, values] of Object.entries(modules)) {
544
560
  assertNames(Object.keys(values), extension.manifest.modules?.[name] ?? [], "module export");
@@ -794,6 +810,7 @@ function readRealmOptions(value, oneShot = false) {
794
810
  "bindings",
795
811
  "modules",
796
812
  "extensions",
813
+ "builtinOverrides",
797
814
  "grants",
798
815
  "budget",
799
816
  "signal",
@@ -14,6 +14,7 @@ import type { SnapshotBackend } from "./snapshot/backend.js";
14
14
  import { type ReplayData } from "./snapshot/replay-data.js";
15
15
  export type RunOptions = {
16
16
  extensions?: RealmOptions["extensions"];
17
+ builtinOverrides?: RealmOptions["builtinOverrides"];
17
18
  grants?: RealmOptions["grants"];
18
19
  limits?: RealmOptions["limits"];
19
20
  bindings?: Record<string, CallerInjectedBinding>;
@@ -39,7 +39,7 @@ export class UnhandledRejectionError extends Error {
39
39
  }
40
40
  const DEFAULT_MAX_CALL_DEPTH = 1_000;
41
41
  export function run(source, options = {}) {
42
- if (options.extensions !== undefined)
42
+ if (options.extensions !== undefined || options.builtinOverrides !== undefined)
43
43
  return runWithExtensions(source, options);
44
44
  const lifecycle = {
45
45
  hostCallbackDepth: 0,