import { auth } from '$lib/stores/auth'; import { get } from 'svelte/store'; const API_BASE = '/api/v1'; interface RequestOptions extends RequestInit { params?: Record; } async function request(endpoint: string, options: RequestOptions = {}): Promise { const { params, ...init } = options; let url = `${API_BASE}${endpoint}`; if (params) { const filteredParams = Object.entries(params) .filter(([, value]) => value !== undefined && value !== null && value !== '') .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}); if (Object.keys(filteredParams).length > 0) { url += `?${new URLSearchParams(filteredParams).toString()}`; } } const authState = get(auth); const headers = new Headers(init.headers); if (authState.token) { headers.set('Authorization', `Bearer ${authState.token}`); } if (!headers.has('Content-Type')) { headers.set('Content-Type', 'application/json'); } headers.set('X-App', 'client'); const slug = get(auth)?.user?.tenant_slug || get(auth)?.user?.tenant_id || ''; headers.set('X-Tenant-Slug', slug); const response = await fetch(url, { ...init, credentials: 'include', headers }); if (response.status === 401) { if (typeof window !== 'undefined') { window.location.href = '/login'; } throw new Error('Unauthorized'); } if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.detail || `API error: ${response.statusText}`); } if (response.status === 204) { return {} as T; } return response.json(); } async function downloadFile(endpoint: string, filename: string): Promise { const authState = get(auth); const headers = new Headers(); if (authState.token) { headers.set('Authorization', `Bearer ${authState.token}`); } } headers.set('X-App', 'client'); const slug = get(auth)?.user?.tenant_slug || get(auth)?.user?.tenant_id || ''; headers.set('X-Tenant-Slug', slug); const response = await fetch(`${API_BASE}${endpoint}`, { method: 'GET', credentials: 'include', headers }); if (response.status === 401) { if (typeof window !== 'undefined') window.location.href = '/login'; throw new Error('Unauthorized'); } if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.detail || `Download error: ${response.statusText}`); } const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(url); } export const api = { get: (endpoint: string, params?: Record) => request(endpoint, { method: 'GET', params }), post: (endpoint: string, body?: any) => request(endpoint, { method: 'POST', body: body !== undefined ? JSON.stringify(body) : undefined }), put: (endpoint: string, body?: any) => request(endpoint, { method: 'PUT', body: body !== undefined ? JSON.stringify(body) : undefined }), patch: (endpoint: string, body?: any) => request(endpoint, { method: 'PATCH', body: body !== undefined ? JSON.stringify(body) : undefined }), delete: (endpoint: string) => request(endpoint, { method: 'DELETE' }), downloadFile: (endpoint: string, filename: string) => downloadFile(endpoint, filename) };