2026-04-14 12:02:17 +00:00
|
|
|
/// 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;
|
2026-04-14 12:25:12 +00:00
|
|
|
/// Project this agent is assigned to, if any.
|
|
|
|
|
assigned_project?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface GatewayProject {
|
|
|
|
|
name: string;
|
|
|
|
|
url: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface GatewayInfo {
|
|
|
|
|
active: string;
|
|
|
|
|
projects: GatewayProject[];
|
2026-04-14 12:02:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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",
|
|
|
|
|
});
|
|
|
|
|
},
|
2026-04-14 12:25:12 +00:00
|
|
|
|
|
|
|
|
/// Assign an agent to a project, or unassign it by passing null.
|
|
|
|
|
assignAgent(id: string, project: string | null): Promise<JoinedAgent> {
|
|
|
|
|
return gatewayRequest<JoinedAgent>(`/gateway/agents/${id}/assign`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: JSON.stringify({ project }),
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Get the list of registered projects from the gateway.
|
|
|
|
|
getGatewayInfo(): Promise<GatewayInfo> {
|
|
|
|
|
return gatewayRequest<GatewayInfo>("/api/gateway");
|
|
|
|
|
},
|
2026-04-14 12:02:17 +00:00
|
|
|
};
|