export type ServerStatus = "pending" | "active" | "offline"; export type KeySource = "uploaded" | "generated"; export interface Server { id: string; server_id: string; hostname: string; ip_address: string; os_info: string; status: ServerStatus; last_seen: string; created_at: string; } export interface Key { id: string; key_id: string; label: string; public_key: string; fingerprint: string; source: KeySource; generated_by_server_id?: string; created_at: string; assigned_count?: number; } export interface Assignment { id: string; key_id: string; server_id: string; assigned_at: string; revoked_at: string | null; } export interface NewServerResponse { server_id: string; pre_reg_token: string; install_command: string; } export interface KeyWithAssignments extends Key { assignments: (Assignment & { server: Server })[]; } export interface ServerWithKeys extends Server { keys: (Assignment & { key: Key })[]; } class ApiError extends Error { constructor( public status: number, message: string ) { super(message); this.name = "ApiError"; } } async function request(path: string, options?: RequestInit): Promise { const res = await fetch(`/api${path}`, { headers: { "Content-Type": "application/json", ...options?.headers, }, ...options, }); if (!res.ok) { const text = await res.text().catch(() => res.statusText); throw new ApiError(res.status, text || `HTTP ${res.status}`); } if (res.status === 204) { return undefined as T; } return res.json(); } export const api = { // Servers listServers(): Promise { return request("/servers"); }, getServer(serverId: string): Promise { return request(`/servers/${serverId}`); }, createServer(): Promise { return request("/servers/new", { method: "POST" }); }, deleteServer(serverId: string): Promise { return request(`/servers/${serverId}`, { method: "DELETE" }); }, generateKeyForServer(serverId: string): Promise<{ key_id: string }> { return request<{ key_id: string }>(`/servers/${serverId}/generate-key`, { method: "POST", }); }, // Keys listKeys(): Promise { return request("/keys"); }, getKey(keyId: string): Promise { return request(`/keys/${keyId}`); }, uploadKey(label: string, public_key: string): Promise { return request("/keys", { method: "POST", body: JSON.stringify({ label, public_key }), }); }, deleteKey(keyId: string): Promise { return request(`/keys/${keyId}`, { method: "DELETE" }); }, // Assignments assignKey(keyId: string, serverId: string): Promise { return request(`/keys/${keyId}/assign`, { method: "POST", body: JSON.stringify({ server_id: serverId }), }); }, revokeKey(keyId: string, serverId: string): Promise { return request(`/keys/${keyId}/assign/${serverId}`, { method: "DELETE", }); }, };