Files
weirsoe-party-protocol/frontend/src/api/client.ts

57 lines
1.5 KiB
TypeScript

import type { ApiResult, HealthResponse, SessionDetailResponse } from './types';
export interface ApiClient {
health(): Promise<ApiResult<HealthResponse>>;
getSession(code: string): Promise<ApiResult<SessionDetailResponse>>;
}
export function createApiClient(baseUrl = '', fetchImpl: typeof fetch = fetch): ApiClient {
async function request<T>(path: string): Promise<ApiResult<T>> {
let response: Response;
try {
response = await fetchImpl(`${baseUrl}${path}`, {
method: 'GET',
headers: { Accept: 'application/json' }
});
} catch {
return {
ok: false,
status: 0,
error: { kind: 'network', status: 0, message: 'Network error while contacting API' }
};
}
let payload: unknown;
try {
payload = await response.json();
} catch {
return {
ok: false,
status: response.status,
error: { kind: 'parse', status: response.status, message: 'Invalid JSON response from API' }
};
}
if (!response.ok) {
return {
ok: false,
status: response.status,
error: {
kind: 'http',
status: response.status,
message: `HTTP ${response.status}`,
payload
}
};
}
return { ok: true, status: response.status, data: payload as T };
}
return {
health: () => request<HealthResponse>('/healthz'),
getSession: (code: string) =>
request<SessionDetailResponse>(`/lobby/sessions/${encodeURIComponent(code.trim().toUpperCase())}`)
};
}