35 lines
1009 B
TypeScript
35 lines
1009 B
TypeScript
|
|
const API_BASE = (import.meta.env.VITE_AUTH_API_URL || '').replace(/\/$/, '') + '/api';
|
||
|
|
|
||
|
|
async function request<T>(path: string, options?: RequestInit): Promise<T> {
|
||
|
|
const token = localStorage.getItem('token');
|
||
|
|
const headers: Record<string, string> = {
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
||
|
|
};
|
||
|
|
|
||
|
|
const res = await fetch(`${API_BASE}${path}`, { ...options, headers });
|
||
|
|
|
||
|
|
if (res.status === 401) {
|
||
|
|
localStorage.removeItem('token');
|
||
|
|
window.location.href = '/login';
|
||
|
|
throw new Error('Unauthorized');
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!res.ok) {
|
||
|
|
const body = await res.text();
|
||
|
|
throw new Error(body || `HTTP ${res.status}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (res.status === 204 || res.headers.get('content-length') === '0') {
|
||
|
|
return undefined as T;
|
||
|
|
}
|
||
|
|
|
||
|
|
return res.json();
|
||
|
|
}
|
||
|
|
|
||
|
|
export const authApi = {
|
||
|
|
get: <T>(path: string) => request<T>(path),
|
||
|
|
post: <T>(path: string, body?: unknown) =>
|
||
|
|
request<T>(path, { method: 'POST', body: JSON.stringify(body) }),
|
||
|
|
};
|