120 lines
2.8 KiB
TypeScript
120 lines
2.8 KiB
TypeScript
import { createClient } from "@/lib/supabase/client";
|
|
import type { ApiError } from "@/lib/types";
|
|
|
|
class ApiClient {
|
|
private baseUrl = "/api";
|
|
|
|
private async getHeaders(): Promise<HeadersInit> {
|
|
const supabase = createClient();
|
|
const {
|
|
data: { session },
|
|
} = await supabase.auth.getSession();
|
|
|
|
const headers: HeadersInit = {
|
|
"Content-Type": "application/json",
|
|
};
|
|
|
|
if (session?.access_token) {
|
|
headers["Authorization"] = `Bearer ${session.access_token}`;
|
|
}
|
|
|
|
const tenantId = typeof window !== "undefined"
|
|
? localStorage.getItem("kanzlai_tenant_id")
|
|
: null;
|
|
if (tenantId) {
|
|
headers["X-Tenant-ID"] = tenantId;
|
|
}
|
|
|
|
return headers;
|
|
}
|
|
|
|
private async request<T>(
|
|
path: string,
|
|
options: RequestInit = {},
|
|
): Promise<T> {
|
|
const headers = await this.getHeaders();
|
|
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
...options,
|
|
headers: { ...headers, ...options.headers },
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const body = await res.json().catch(() => ({}));
|
|
const err: ApiError = {
|
|
error: body.error || res.statusText,
|
|
status: res.status,
|
|
};
|
|
throw err;
|
|
}
|
|
|
|
if (res.status === 204) return undefined as T;
|
|
return res.json();
|
|
}
|
|
|
|
get<T>(path: string) {
|
|
return this.request<T>(path, { method: "GET" });
|
|
}
|
|
|
|
post<T>(path: string, body?: unknown) {
|
|
return this.request<T>(path, {
|
|
method: "POST",
|
|
body: body ? JSON.stringify(body) : undefined,
|
|
});
|
|
}
|
|
|
|
put<T>(path: string, body?: unknown) {
|
|
return this.request<T>(path, {
|
|
method: "PUT",
|
|
body: body ? JSON.stringify(body) : undefined,
|
|
});
|
|
}
|
|
|
|
patch<T>(path: string, body?: unknown) {
|
|
return this.request<T>(path, {
|
|
method: "PATCH",
|
|
body: body ? JSON.stringify(body) : undefined,
|
|
});
|
|
}
|
|
|
|
delete<T>(path: string) {
|
|
return this.request<T>(path, { method: "DELETE" });
|
|
}
|
|
|
|
async postFormData<T>(path: string, formData: FormData): Promise<T> {
|
|
const supabase = createClient();
|
|
const {
|
|
data: { session },
|
|
} = await supabase.auth.getSession();
|
|
|
|
const headers: HeadersInit = {};
|
|
if (session?.access_token) {
|
|
headers["Authorization"] = `Bearer ${session.access_token}`;
|
|
}
|
|
const tenantId = typeof window !== "undefined"
|
|
? localStorage.getItem("kanzlai_tenant_id")
|
|
: null;
|
|
if (tenantId) {
|
|
headers["X-Tenant-ID"] = tenantId;
|
|
}
|
|
|
|
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
method: "POST",
|
|
headers,
|
|
body: formData,
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const body = await res.json().catch(() => ({}));
|
|
const err: ApiError = {
|
|
error: body.error || res.statusText,
|
|
status: res.status,
|
|
};
|
|
throw err;
|
|
}
|
|
|
|
return res.json();
|
|
}
|
|
}
|
|
|
|
export const api = new ApiClient();
|