ai-voicebot/client/src/api-client.ts

135 lines
4.6 KiB
TypeScript

// TypeScript API client for AI Voicebot server
import { components } from './api-types';
// Re-export commonly used types from the generated schema
export type LobbyModel = components['schemas']['LobbyModel'];
export type LobbyListItem = components['schemas']['LobbyListItem'];
export type LobbyCreateData = components['schemas']['LobbyCreateData'];
export type NamePasswordRecord = components['schemas']['NamePasswordRecord'];
// Type aliases for API methods
export type AdminNamesResponse = components['schemas']['AdminNamesResponse'];
export type AdminActionResponse = components['schemas']['AdminActionResponse'];
export type AdminSetPassword = components['schemas']['AdminSetPassword'];
export type AdminClearPassword = components['schemas']['AdminClearPassword'];
export type HealthResponse = components['schemas']['HealthResponse'];
export type LobbiesResponse = components['schemas']['LobbiesResponse'];
export type SessionResponse = components['schemas']['SessionResponse'];
export type LobbyCreateRequest = components['schemas']['LobbyCreateRequest'];
export type LobbyCreateResponse = components['schemas']['LobbyCreateResponse'];
export class ApiError extends Error {
constructor(
public status: number,
public statusText: string,
public data?: any
) {
super(`HTTP ${status}: ${statusText}`);
this.name = 'ApiError';
}
}
export class ApiClient {
private baseURL: string;
private defaultHeaders: Record<string, string>;
constructor(baseURL?: string) {
this.baseURL = baseURL || process.env.REACT_APP_API_URL || 'http://localhost:8001';
this.defaultHeaders = {};
}
private async request<T>(path: string, options: {
method: string;
body?: any;
params?: Record<string, string>;
}): Promise<T> {
const url = new URL(path, this.baseURL);
if (options.params) {
Object.entries(options.params).forEach(([key, value]) => {
url.searchParams.append(key, value);
});
}
const requestInit: RequestInit = {
method: options.method,
headers: {
'Content-Type': 'application/json',
...this.defaultHeaders,
},
};
if (options.body && options.method !== 'GET') {
requestInit.body = JSON.stringify(options.body);
}
const response = await fetch(url.toString(), requestInit);
if (!response.ok) {
let errorData;
try {
errorData = await response.json();
} catch {
errorData = await response.text();
}
throw new ApiError(response.status, response.statusText, errorData);
}
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
return response.json();
}
return response.text() as unknown as T;
}
// Admin API methods
async adminListNames(): Promise<AdminNamesResponse> {
return this.request<AdminNamesResponse>('/ai-voicebot/api/admin/names', { method: 'GET' });
}
async adminSetPassword(data: AdminSetPassword): Promise<AdminActionResponse> {
return this.request<AdminActionResponse>('/ai-voicebot/api/admin/set_password', { method: 'POST', body: data });
}
async adminClearPassword(data: AdminClearPassword): Promise<AdminActionResponse> {
return this.request<AdminActionResponse>('/ai-voicebot/api/admin/clear_password', { method: 'POST', body: data });
}
// Health check
async healthCheck(): Promise<HealthResponse> {
return this.request<HealthResponse>('/ai-voicebot/api/health', { method: 'GET' });
}
// Session methods
async getSession(): Promise<SessionResponse> {
return this.request<SessionResponse>('/ai-voicebot/api/session', { method: 'GET' });
}
// Lobby methods
async getLobbies(): Promise<LobbiesResponse> {
return this.request<LobbiesResponse>('/ai-voicebot/api/lobby', { method: 'GET' });
}
async createLobby(sessionId: string, data: LobbyCreateRequest): Promise<LobbyCreateResponse> {
return this.request<LobbyCreateResponse>(`/ai-voicebot/api/lobby/${sessionId}`, { method: 'POST', body: data });
}
}
// Default client instance
export const apiClient = new ApiClient();
// Convenience API namespaces
export const adminApi = {
listNames: () => apiClient.adminListNames(),
setPassword: (data: AdminSetPassword) => apiClient.adminSetPassword(data),
clearPassword: (data: AdminClearPassword) => apiClient.adminClearPassword(data),
};
export const healthApi = { check: () => apiClient.healthCheck() };
export const lobbiesApi = { getAll: () => apiClient.getLobbies() };
export const sessionsApi = {
getCurrent: () => apiClient.getSession(),
createLobby: (sessionId: string, data: LobbyCreateRequest) => apiClient.createLobby(sessionId, data),
};