store/resources/js/lib/api.ts

52 lines
1.7 KiB
TypeScript

function getXsrfToken(): string {
const match = document.cookie
.split('; ')
.find((row) => row.startsWith('XSRF-TOKEN='));
return match ? decodeURIComponent(match.split('=')[1] ?? '') : '';
}
export async function apiFetch<T>(url: string, options: RequestInit = {}): Promise<T> {
const response = await fetch(url, {
...options,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-XSRF-TOKEN': getXsrfToken(),
'X-Requested-With': 'XMLHttpRequest',
...options.headers,
},
credentials: 'same-origin',
});
const contentType = response.headers.get('content-type') ?? '';
const isJson = contentType.includes('application/json');
if (!response.ok) {
if (isJson) {
const error = (await response.json().catch(() => ({}))) as {
message?: string;
errors?: Record<string, string[]>;
};
const firstValidationError = error.errors
? Object.values(error.errors).flat()[0]
: undefined;
throw new Error(firstValidationError ?? error.message ?? 'Permintaan gagal diproses.');
}
if (response.status === 401 || response.status === 419) {
throw new Error('Sesi Anda telah berakhir. Silakan muat ulang halaman dan coba lagi.');
}
throw new Error(`Permintaan gagal diproses (HTTP ${response.status}).`);
}
if (!isJson) {
throw new Error('Server mengembalikan respons yang tidak valid. Silakan muat ulang halaman.');
}
return response.json() as Promise<T>;
}