Files
arbiter/dashboard/src/api/client.ts

46 lines
1.1 KiB
TypeScript

const API_BASE_URL = import.meta.env.VITE_API_URL || '';
export class ApiError extends Error {
status: number;
constructor(status: number, message: string) {
super(message);
this.name = 'ApiError';
this.status = status;
}
}
export async function apiRequest<T>(
endpoint: string,
options: RequestInit = {},
): Promise<T> {
const url = `${API_BASE_URL}${endpoint}`;
const response = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
...options.headers,
},
});
if (!response.ok) {
const message = await response.text().catch(() => 'Request failed');
throw new ApiError(response.status, message);
}
return response.json();
}
export function buildQueryString(
params: Record<string, string | number | boolean | undefined>,
): string {
const filtered = Object.entries(params).filter(
([, value]) => value !== undefined,
);
if (filtered.length === 0) return '';
return '?' + new URLSearchParams(
filtered.map(([key, value]) => [key, String(value)]),
).toString();
}