import { computed, readonly, ref } from 'vue'; import { useNotification } from '~/composables/useNotification'; import type { DiagnosticCheck, DiagnosticsResponse } from '~/types/diagnostics'; import { parse_api_error, parse_api_response, request } from '~/utils'; const diagnostics = ref(null); const isLoading = ref(false); const lastError = ref(null); const throwInstead = ref(false); const groupedChecks = computed>>(() => { return (diagnostics.value?.checks ?? []).reduce>>( (acc, check) => { if (!acc[check.group]) { acc[check.group] = []; } acc[check.group]?.push(check); return acc; }, {}, ); }); const groupOrder = computed>(() => Object.keys(groupedChecks.value)); const readJson = async (response: Response): Promise => { try { return await response.clone().json(); } catch { return null; } }; const ensureSuccess = async (response: Response): Promise => { if (response.ok) { return; } const payload = await readJson(response); throw new Error(await parse_api_error(payload)); }; const handleError = (error: unknown): void => { const message = error instanceof Error ? error.message : 'Failed to load diagnostics.'; lastError.value = message; useNotification().error(message); }; const loadDiagnostics = async (force: boolean = false): Promise => { if (isLoading.value) { return diagnostics.value; } if (diagnostics.value && !force) { return diagnostics.value; } isLoading.value = true; lastError.value = null; try { const response = await request(`/api/system/diagnostics${force ? '?refresh=1' : ''}`); await ensureSuccess(response); diagnostics.value = await parse_api_response(response.json()); return diagnostics.value; } catch (error) { handleError(error); if (throwInstead.value) { throw error; } return null; } finally { isLoading.value = false; } }; const clearError = (): void => { lastError.value = null; }; const __resetForTesting = (): void => { diagnostics.value = null; isLoading.value = false; lastError.value = null; throwInstead.value = false; }; export const useDiagnostics = () => ({ diagnostics: readonly(diagnostics), isLoading: readonly(isLoading), lastError: readonly(lastError), groupedChecks, groupOrder, loadDiagnostics, clearError, throwInstead, __resetForTesting, });