export interface JavaScriptResult { value: string; logs: string[]; durationMs: number; } const MAX_SOURCE_BYTES = 64 * 1024; const MAX_RESULT_CHARACTERS = 16 * 1024; const OPAQUE_WORKER_SOURCE = ` (() => { const send = self.postMessage.bind(self); const render = (value) => { if (typeof value === 'string') return value; try { return JSON.stringify(value); } catch { return String(value); } }; const blocked = () => Promise.reject(new Error('Network access is disabled in js_eval')); const hide = (target, key, value) => { try { Object.defineProperty(target, key, { value, writable: false, configurable: false }); } catch {} }; hide(self, 'fetch', blocked); hide(self, 'XMLHttpRequest', undefined); hide(self, 'WebSocket', undefined); hide(self, 'EventSource', undefined); hide(self, 'SharedWorker', undefined); hide(self, 'Worker', undefined); hide(self, 'BroadcastChannel', undefined); hide(self, 'importScripts', undefined); hide(self, 'indexedDB', undefined); hide(self, 'caches', undefined); hide(self.navigator, 'storage', undefined); hide(self, 'postMessage', undefined); hide(self, 'close', undefined); self.onmessage = async ({ data }) => { const logs = []; const capture = (...values) => logs.push(values.map(render).join(' ')); const console = { log: capture, info: capture, warn: capture, error: capture }; try { const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor; const execute = new AsyncFunction('console', '"use strict";\\n' + data.source); const value = await execute(console); send({ ok: true, value: render(value), logs }); } catch (error) { send({ ok: false, error: error?.message ?? String(error), logs }); } }; })(); `; function frameSource(channel: string): string { const policy = [ "default-src 'none'", "base-uri 'none'", "connect-src 'none'", "form-action 'none'", "frame-src 'none'", "img-src 'none'", "media-src 'none'", "object-src 'none'", "style-src 'none'", "script-src 'unsafe-inline' 'unsafe-eval' blob:", 'worker-src blob:', ].join('; '); return `