135 lines
4.6 KiB
TypeScript
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),
|
|
};
|