/** * Build the ES module source that runs inside the dynamic Worker. * * The module exports a `WorkerEntrypoint` subclass with an `evaluate` * method that: * 1. Captures console output into `__logs`. * 2. Creates a recursive `tools` Proxy that dispatches calls via RPC. * 3. Executes the normalised user code with a `Promise.race` timeout. * 4. Returns `{ result, error?, logs }`. */ export const buildExecutorModule = (body: string, timeoutMs: number): string => [ 'import { WorkerEntrypoint } from "cloudflare:workers";', "", "export default class CodeExecutor extends WorkerEntrypoint {", " async evaluate(__dispatcher) {", " const __logs = [];", ' console.log = (...a) => { __logs.push(a.map(String).join(" ")); };', ' console.warn = (...a) => { __logs.push("[warn] " + a.map(String).join(" ")); };', ' console.error = (...a) => { __logs.push("[error] " + a.map(String).join(" ")); };', " const __serializeErrorValue = (value) => {", " if (value instanceof Error) {", " return {", " __type: 'Error',", " name: value.name,", " message: value.message,", " ...(typeof value.stack === 'string' && value.stack.length > 0 ? { stack: value.stack } : {}),", " };", " }", " if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {", " return value;", " }", " try {", " return JSON.parse(JSON.stringify(value));", " } catch {", " return String(value);", " }", " };", " const __renderMessage = (value) => {", " if (typeof value === 'string') return value;", " if (value && typeof value === 'object' && value.__type === 'Error' && typeof value.message === 'string') {", " return value.message;", " }", " if (value instanceof Error) return value.message;", " if (value && typeof value === 'object' && typeof value.message === 'string') return value.message;", " if (typeof value === 'undefined') return 'Unknown error';", " if (value && typeof value === 'object') {", " try {", " return JSON.stringify(value);", " } catch {", " return String(value);", " }", " }", " return String(value);", " };", " const __serializeThrownError = (err) => {", " const primary = __serializeErrorValue(err);", " return {", " kind: 'unknown',", " message: __renderMessage(primary),", " primary,", " failures: [],", " defects: [],", " interrupted: false,", " };", " };", "", " const __makeToolsProxy = (path = []) => new Proxy(() => undefined, {", " get(_target, prop) {", " if (prop === 'then' || typeof prop === 'symbol') return undefined;", " return __makeToolsProxy([...path, String(prop)]);", " },", " apply(_target, _thisArg, args) {", " const toolPath = path.join('.');", " if (!toolPath) throw new Error('Tool path missing in invocation');", " return __dispatcher.call(toolPath, JSON.stringify(args[0] ?? {})).then((raw) => {", " const data = JSON.parse(raw);", " if (!data.ok) {", " throw (data.error && data.error.primary !== null ? data.error.primary : data.error.message);", " }", " return data.result;", " });", " },", " });", " const tools = __makeToolsProxy();", "", " try {", " const result = await Promise.race([", " (async () => {", body, " })(),", " new Promise((_, reject) =>", ` setTimeout(() => reject(new Error("Execution timed out after ${timeoutMs}ms")), ${timeoutMs})`, " ),", " ]);", " return { result, logs: __logs };", " } catch (err) {", " return { result: undefined, error: __serializeThrownError(err), logs: __logs };", " }", " }", "}", ].join("\n");