import { apiRequest, ApiError } from './api-client'; import { moduleSchema, type Module } from './schemas'; /** Typsichere API-Funktionen für die Modul-Verwaltung. */ export async function fetchModules(): Promise { const response = await apiRequest<{ modules: unknown[] }>('/api/v1/modules'); return response.modules.map((module) => moduleSchema.parse(module)); } export async function installModule(file: File): Promise { const formData = new FormData(); formData.append('package', file); const headers: Record = {}; const csrfToken = readCsrfToken(); if (csrfToken) { headers['X-CSRF-Token'] = csrfToken; } const response = await fetch('/api/v1/modules/install', { method: 'POST', headers, credentials: 'same-origin', body: formData, }); if (!response.ok) { let message = 'Installation fehlgeschlagen'; let details: Record | undefined; try { const errorBody = (await response.json()) as { message?: string | string[]; details?: Record; }; if (typeof errorBody.message === 'string') { message = errorBody.message; } else if (Array.isArray(errorBody.message)) { message = errorBody.message.join(', '); } details = errorBody.details; } catch { // Kein JSON in der Antwort – Standardmeldung verwenden. } throw new ApiError(response.status, message, details); } const response_ = (await response.json()) as { module: unknown }; return moduleSchema.parse(response_.module); } export async function startModule(id: string): Promise { const response = await apiRequest<{ module: unknown }>(`/api/v1/modules/${id}/start`, { method: 'POST', }); return moduleSchema.parse(response.module); } export async function stopModule(id: string): Promise { const response = await apiRequest<{ module: unknown }>(`/api/v1/modules/${id}/stop`, { method: 'POST', }); return moduleSchema.parse(response.module); } export async function restartModule(id: string): Promise { const response = await apiRequest<{ module: unknown }>(`/api/v1/modules/${id}/restart`, { method: 'POST', }); return moduleSchema.parse(response.module); } export async function setModuleEnabled(id: string, enabled: boolean): Promise { const response = await apiRequest<{ module: unknown }>(`/api/v1/modules/${id}/enabled`, { method: 'PATCH', body: { enabled }, }); return moduleSchema.parse(response.module); } export async function removeModule(id: string): Promise { await apiRequest(`/api/v1/modules/${id}`, { method: 'DELETE' }); } export async function checkModuleHealth( id: string, ): Promise<{ healthy: boolean; latencyMs: number; detail: string }> { return apiRequest(`/api/v1/modules/${id}/health`); } /** Liest das CSRF-Token aus dem nicht-HttpOnly-Cookie. */ function readCsrfToken(): string | null { for (const part of document.cookie.split(';')) { const [name, ...value] = part.trim().split('='); if (name === 'mpm_csrf') { return decodeURIComponent(value.join('=')); } } return null; }