Files
peakskills/clients/base/http-client.ts
2025-08-24 22:03:15 +02:00

70 lines
1.7 KiB
TypeScript

export abstract class BaseHttpClient {
protected baseUrl: string;
constructor() {
this.baseUrl = process.env.NEXT_PUBLIC_API_URL || "/api/";
}
protected async request<T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> {
const url = `${this.baseUrl}${endpoint}`;
const defaultOptions: RequestInit = {
credentials: "same-origin",
headers: {
"Content-Type": "application/json",
...options.headers,
},
...options,
};
try {
const response = await fetch(url, defaultOptions);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
// Handle empty responses
if (
response.status === 204 ||
response.headers.get("content-length") === "0"
) {
return {} as T;
}
return await response.json();
} catch (error) {
console.error(`Request failed for ${endpoint}:`, error);
throw error;
}
}
protected async get<T>(endpoint: string): Promise<T> {
return this.request<T>(endpoint);
}
protected async post<T>(endpoint: string, data?: any): Promise<T> {
return this.request<T>(endpoint, {
method: "POST",
body: data ? JSON.stringify(data) : undefined,
});
}
protected async put<T>(endpoint: string, data?: any): Promise<T> {
return this.request<T>(endpoint, {
method: "PUT",
body: data ? JSON.stringify(data) : undefined,
});
}
protected async delete<T>(endpoint: string, data?: any): Promise<T> {
return this.request<T>(endpoint, {
method: "DELETE",
body: data ? JSON.stringify(data) : undefined,
});
}
}