Files
pikasTech-HWLAB/internal/cloud/workbench-command-proxy.ts
T

39 lines
2.0 KiB
TypeScript

import { readBody, sendJson } from "./server-http-utils.ts";
export function workbenchTemporalProxyEnabled(env: Record<string, string | undefined> = process.env) {
return Boolean(String(env.HWLAB_WORKBENCH_API_URL ?? "").trim());
}
export function workbenchActivityDispatchRequested(request: any) {
return String(request.headers?.["x-workbench-activity-dispatch"] ?? "").trim() === "1";
}
export async function proxyWorkbenchCommandHttp(request: any, response: any, options: any, route: string) {
const baseUrl = String(options.env?.HWLAB_WORKBENCH_API_URL ?? "").trim();
if (!baseUrl) throw Object.assign(new Error("HWLAB_WORKBENCH_API_URL is required"), { code: "workbench_api_url_required" });
let bodyText = request.method === "GET" || request.method === "HEAD" ? "" : await readBody(request, options.bodyLimitBytes);
if (route === "/v1/workbench/commands") {
const command = JSON.parse(bodyText || "{}");
if (!command || typeof command !== "object" || Array.isArray(command)) throw Object.assign(new Error("Workbench command must be a JSON object"), { code: "invalid_json" });
if (command.operation !== "health") command.actor = { id: String(options.actor?.id ?? ""), role: String(options.actor?.role ?? "user") };
bodyText = JSON.stringify(command);
}
const headers: Record<string, string> = {
authorization: String(options.env?.WORKBENCH_CLOUD_API_AUTHORIZATION ?? ""),
"content-type": "application/json",
"x-hwlab-actor-id": String(options.actor?.id ?? ""),
"x-hwlab-actor-role": String(options.actor?.role ?? "user")
};
const upstream = await (options.fetchImpl ?? fetch)(`${baseUrl.replace(/\/$/u, "")}${route}`, {
method: request.method,
headers,
body: bodyText || undefined
});
const payload = await upstream.json().catch(() => null);
if (!payload || typeof payload !== "object") {
sendJson(response, 502, { ok: false, error: { code: "workbench_api_invalid_json", message: `Workbench API returned invalid JSON (${upstream.status})` } });
return;
}
sendJson(response, upstream.status, payload);
}