import "server-only";
import { authenticateRunner, type RunnerIdentity } from "./runners";
/*
* The HTTP API that runners (public/vectrum-runner.mjs) talk to. Every request carries the runner's
* token as `Authorization: Bearer vrn_…`.
*
* POST /api/runner/claim { hostname, os, arch, version } → 200 { job } or 204 after waiting a while
* POST /api/runner/jobs/:id { steps?, logs?, status? } → { cancelled }
*/
export const json = (body: unknown, status = 200) => Response.json(body, { status, headers: { "Cache-Control": "no-store" } });
export async function runnerFromRequest(request: Request): Promise<RunnerIdentity | Response> {
const header = request.headers.get("authorization") ?? "";
const runner = header.startsWith("Bearer ") ? await authenticateRunner(header.slice(7).trim()) : null;
if (!runner) return json({ error: "Unknown or expired runner token. Register the runner again in Settings → Runners." }, 401);
return runner;
}
export async function readBody(request: Request) {
try {
const body: unknown = await request.json();
return typeof body === "object" && body !== null ? (body as Record<string, unknown>) : {};
} catch {
return {};
}
}