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) { // Filtrar parĂ¡metros undefined y null const filteredParams = Object.entries(params) .filter(([key, value]) => value !== undefined && value !== null && value !== '') .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}); if (Object.keys(filteredParams).length > 0) { const searchParams = new URLSearchParams(filteredParams); url += `?${searchParams.toString()}`; } } const authState = get(auth); const token = authState.token || (typeof window !== 'undefined' ? localStorage.getItem('internal_auth_token') : null); // Resolve tenant_id from store or from the persisted user object in localStorage let tenantId = authState.user?.tenant_id ?? null; if (!tenantId && typeof window !== 'undefined') { try { const stored = localStorage.getItem('internal_auth_user'); if (stored) tenantId = JSON.parse(stored)?.tenant_id ?? null; } catch { /* ignore */ } } const headers = new Headers(init.headers); if (token) { headers.set('Authorization', `Bearer ${token}`); } if (tenantId && !headers.has('X-Tenant-ID')) { headers.set('X-Tenant-ID', tenantId); } if (!headers.has('Content-Type')) { headers.set('Content-Type', 'application/json'); } const response = await fetch(url, { ...init, headers }); if (response.status === 401) { // Token expired or invalid if (typeof window !== 'undefined') { localStorage.removeItem('internal_auth_token'); localStorage.removeItem('internal_auth_user'); 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}`); } // Handle empty responses (like 204 No Content) if (response.status === 204) { return {} as T; } return response.json(); } async function downloadFile(endpoint: string, filename: string): Promise { const authState = get(auth); const token = authState.token || (typeof window !== 'undefined' ? localStorage.getItem('internal_auth_token') : null); let tenantId = authState.user?.tenant_id ?? null; if (!tenantId && typeof window !== 'undefined') { try { const stored = localStorage.getItem('internal_auth_user'); if (stored) tenantId = JSON.parse(stored)?.tenant_id ?? null; } catch { /* ignore */ } } const headers = new Headers(); if (token) { headers.set('Authorization', `Bearer ${token}`); } if (tenantId) { headers.set('X-Tenant-ID', tenantId); } const response = await fetch(`${API_BASE}${endpoint}`, { method: 'GET', headers }); if (response.status === 401) { if (typeof window !== 'undefined') { localStorage.removeItem('internal_auth_token'); localStorage.removeItem('internal_auth_user'); 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}`); } // Crear blob y descargar 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: JSON.stringify(body) }), put: (endpoint: string, body: any) => request(endpoint, { method: 'PUT', body: JSON.stringify(body) }), patch: (endpoint: string, body: any) => request(endpoint, { method: 'PATCH', body: JSON.stringify(body) }), delete: (endpoint: string) => request(endpoint, { method: 'DELETE' }), downloadFile: (endpoint: string, filename: string) => downloadFile(endpoint, filename) };