import { goto } from '$app/navigation'; import { auth } from '$lib/stores/auth.js'; import { config } from '$lib/stores/config.js'; /** * Get the API URL from runtime config * Falls back to build-time env var if runtime config not available * @returns {string} */ function getApiUrl() { const runtimeUrl = config.getApiUrl(); return runtimeUrl || import.meta.env.VITE_API_URL || ''; } /** * Base API client with JWT handling * @param {string} endpoint - API endpoint (without base URL) * @param {Object} options - Fetch options * @returns {Promise} - JSON response */ export async function apiClient(endpoint, options = {}) { // Get token from store let token = null; auth.subscribe((authState) => { token = authState.token; })(); // Build headers const headers = { 'Content-Type': 'application/json', ...options.headers, }; // Add Authorization header if token exists if (token) { headers['Authorization'] = `Bearer ${token}`; } // Build full URL using runtime config const url = `${getApiUrl()}${endpoint}`; try { const response = await fetch(url, { ...options, headers, }); // Handle 401 Unauthorized if (response.status === 401) { auth.logout(); goto('/login'); throw new Error('Unauthorized'); } // Handle other errors if (!response.ok) { const error = await response.json().catch(() => ({ message: 'An error occurred' })); throw new Error(error.message || `HTTP error! status: ${response.status}`); } // Parse JSON response return await response.json(); } catch (error) { console.error('API Error:', error); throw error; } } /** * GET request helper * @param {string} endpoint * @param {Object} options */ export function get(endpoint, options = {}) { return apiClient(endpoint, { ...options, method: 'GET' }); } /** * POST request helper * @param {string} endpoint * @param {Object} body * @param {Object} options */ export function post(endpoint, body, options = {}) { return apiClient(endpoint, { ...options, method: 'POST', body: JSON.stringify(body), }); } /** * PUT request helper * @param {string} endpoint * @param {Object} body * @param {Object} options */ export function put(endpoint, body, options = {}) { return apiClient(endpoint, { ...options, method: 'PUT', body: JSON.stringify(body), }); } /** * PATCH request helper * @param {string} endpoint * @param {Object} body * @param {Object} options */ export function patch(endpoint, body, options = {}) { return apiClient(endpoint, { ...options, method: 'PATCH', body: JSON.stringify(body), }); } /** * DELETE request helper * @param {string} endpoint * @param {Object} options */ export function del(endpoint, options = {}) { return apiClient(endpoint, { ...options, method: 'DELETE' }); }