feature/sidebar #8

Merged
ilia merged 50 commits from feature/sidebar into main 2026-01-03 10:56:23 +00:00
Showing only changes of commit 6041ffd954 - Show all commits

61
src/shared/api/api.ts Normal file
View File

@@ -0,0 +1,61 @@
import type { ApiResponse } from '$shared/types/common';
export class ApiError extends Error {
constructor(
public status: number,
message: string,
public response?: Response,
) {
super(message);
this.name = 'ApiError';
}
}
async function request<T>(
url: string,
options?: RequestInit,
): Promise<ApiResponse<T>> {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
...options,
});
if (!response.ok) {
throw new ApiError(
response.status,
`Request failed: ${response.statusText}`,
response,
);
}
const data = await response.json() as T;
return {
data,
status: response.status,
};
}
export const api = {
get: <T>(url: string, options?: RequestInit) => request<T>(url, { ...options, method: 'GET' }),
post: <T>(url: string, body?: unknown, options?: RequestInit) =>
request<T>(url, {
...options,
method: 'POST',
body: JSON.stringify(body),
}),
put: <T>(url: string, body?: unknown, options?: RequestInit) =>
request<T>(url, {
...options,
method: 'PUT',
body: JSON.stringify(body),
}),
delete: <T>(url: string, options?: RequestInit) =>
request<T>(url, { ...options, method: 'DELETE' }),
};