const baseUrl = import.meta.env.VITE_API_URL ?? 'http://localhost:3000'; export class ApiError extends Error { constructor( readonly status: number, message: string, ) { super(message); this.name = 'ApiError'; } } type ApiOptions = RequestInit & { token?: string; }; export function getApiToken(): string | null { return localStorage.getItem('montime_access_token'); } export async function api(path: string, options: ApiOptions = {}): Promise { const token = options.token ?? getApiToken() ?? undefined; const headers: Record = { 'Content-Type': 'application/json', ...(options.headers as Record | undefined), }; if (token) { headers.Authorization = `Bearer ${token}`; } const { token: _token, ...fetchOptions } = options; const res = await fetch(`${baseUrl}${path}`, { ...fetchOptions, headers, }); if (!res.ok) { const body = (await res.json().catch(() => null)) as | { message?: string | string[] } | null; let msg: string; if (Array.isArray(body?.message)) { const lines = body.message.map(String); const timeErrors = lines.filter((l) => /startTime|endTime/.test(l) && /regular expression|HH:mm/i.test(l), ); msg = timeErrors.length > 0 ? 'فرمت ساعت نامعتبر است. لطفاً دوباره بازه را اضافه و ذخیره کنید.' : lines.join(' · '); } else { msg = body?.message ?? res.statusText; } throw new ApiError(res.status, msg); } if (res.status === 204) { return undefined as T; } return res.json() as Promise; }