Files
huskies/frontend/src/api/gateway.ts
T

65 lines
1.7 KiB
TypeScript

/// Gateway API client — used when running in gateway mode.
///
/// The gateway mode is detected by checking `GET /gateway/mode`. If it returns
/// `{ "mode": "gateway" }` the frontend switches to the gateway UI.
export interface JoinedAgent {
id: string;
label: string;
address: string;
registered_at: number;
}
export interface GenerateTokenResponse {
token: string;
}
export interface ServerMode {
mode: "gateway" | "standard";
}
async function gatewayRequest<T>(
path: string,
options: RequestInit = {},
): Promise<T> {
const res = await fetch(path, {
headers: { "Content-Type": "application/json", ...(options.headers ?? {}) },
...options,
});
if (!res.ok) {
const text = await res.text();
throw new Error(text || `Request failed (${res.status})`);
}
// DELETE /gateway/agents/:id returns 204 No Content.
if (res.status === 204) {
return undefined as unknown as T;
}
return res.json() as Promise<T>;
}
export const gatewayApi = {
/// Returns `{ mode: "gateway" }` if this server is a gateway, otherwise rejects.
getServerMode(): Promise<ServerMode> {
return gatewayRequest<ServerMode>("/gateway/mode");
},
/// Generate a one-time join token for a new build agent.
generateToken(): Promise<GenerateTokenResponse> {
return gatewayRequest<GenerateTokenResponse>("/gateway/tokens", {
method: "POST",
});
},
/// List all build agents that have registered with this gateway.
listAgents(): Promise<JoinedAgent[]> {
return gatewayRequest<JoinedAgent[]>("/gateway/agents");
},
/// Remove a registered build agent by its ID.
removeAgent(id: string): Promise<void> {
return gatewayRequest<void>(`/gateway/agents/${id}`, {
method: "DELETE",
});
},
};