import type { CapabilityEndpoint } from "../capabilities/http-client"; import type { ColineJobRunInfo } from "../define/types"; /** * Helpers shared by every execution path that hosts app handlers: the * external `createColineAppHandler`, and the test workspace. The hosted * Dynamic Worker bootstrap mirrors these in plain JavaScript. */ export function parseEndpointJson(body: string): T { try { return JSON.parse(body) as T; } catch { throw Object.assign(new Error("The request body is not valid JSON."), { code: "invalid_json", }); } } export function createJobRunInfo( endpoint: CapabilityEndpoint, job: { id: string; name: string; attempt: number; maxAttempts: number; enqueuedAt: string; checkpoint: unknown; }, ): ColineJobRunInfo { const post = async (operation: string, args: unknown[]) => { const fetchImpl = endpoint.fetchImpl ?? fetch; const response = await fetchImpl(endpoint.url, { method: "POST", headers: { "content-type": "application/json", authorization: `Bearer ${endpoint.token}`, }, body: JSON.stringify({ operation, args }), }); const parsed = (await response.json().catch(() => null)) as { error?: { code?: string; message?: string }; } | null; if (!response.ok || parsed?.error) { throw Object.assign(new Error(parsed?.error?.message ?? `${operation} failed.`), { code: parsed?.error?.code ?? "capability_error", }); } }; return { id: job.id, name: job.name, attempt: job.attempt, maxAttempts: job.maxAttempts, enqueuedAt: job.enqueuedAt, checkpoint: job.checkpoint ?? null, saveCheckpoint: (state) => post("jobs.checkpoint", [state]), progress: (value, message) => post("jobs.progress", [{ value, message: message ?? null }]), }; }