import { notifyAuthCleared } from './authSessionManager' import { AUTH_TOKEN_KEY } from './authConstants' const API_URL = (import.meta.env.VITE_API_URL ?? '').replace(/\/$/, '') const API_LABEL = API_URL || 'same-origin /api' export class ApiRequestError extends Error { status: number | null constructor(message: string, status: number | null = null) { super(message) this.name = 'ApiRequestError' this.status = status } } function getAuthToken() { if (typeof window === 'undefined') return null return window.localStorage.getItem(AUTH_TOKEN_KEY) } function clearAuthToken() { if (typeof window === 'undefined') return window.localStorage.removeItem(AUTH_TOKEN_KEY) notifyAuthCleared() } async function parseError(response: Response, path: string) { const error = await response.text().catch(() => '') const message = extractErrorMessage(error) || `API request failed for ${path}` throw new ApiRequestError(message, response.status) } function extractErrorMessage(error: string) { if (!error.trim()) return '' try { const parsed = JSON.parse(error) as { message?: unknown; title?: unknown; detail?: unknown } const message = parsed.message ?? parsed.detail ?? parsed.title return typeof message === 'string' ? message : error } catch { return error } } export async function requestJson( path: string, options: RequestInit = {}, ): Promise { const token = getAuthToken() const headers = new Headers(options.headers) if (token) { headers.set('Authorization', `Bearer ${token}`) } const response = await fetch(`${API_URL}${path}`, { ...options, headers, }).catch(() => { throw new ApiRequestError(`API nicht erreichbar (${API_LABEL}). Bitte Backend starten.`) }) if (!response.ok) { if (response.status === 401 || response.status === 403) { clearAuthToken() } await parseError(response, path) } return response.json() as Promise }