import { fetchJson, type ApiRequestOptions } from "../client"; import { getBackendConfig } from "@/lib/config"; import type { SystemInfo, DiskUsageResponse, DatabaseStats, SnapshotInfo, LogFileInfo, LogTailResponse, UpdatesResponse, JobAcceptResponse, } from "@/lib/types/system"; const SYSTEM_BASE = "/api/v1/system"; // --- Info --------------------------------------------------------------- export function fetchSystemInfo(options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/info`, options); } // --- Disk usage --------------------------------------------------------- export function fetchDiskUsage(options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/disk-usage`, options); } export function refreshDiskUsage(options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/disk-usage/refresh`, { ...options, init: { method: "POST", ...(options?.init ?? {}) }, }); } export function openDataFolder(options?: ApiRequestOptions): Promise<{ path: string }> { return fetchJson<{ path: string }>(`${SYSTEM_BASE}/disk-usage/open`, { ...options, init: { method: "POST", ...(options?.init ?? {}) }, }); } // --- Database ----------------------------------------------------------- export function fetchDatabaseStats(options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/database`, options); } export function vacuumDatabase(options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/database/vacuum`, { ...options, init: { method: "POST", ...(options?.init ?? {}) }, }); } export function optimizeDatabase(options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/database/optimize`, { ...options, init: { method: "POST", ...(options?.init ?? {}) }, }); } export function resetDatabase( confirm: string, options?: ApiRequestOptions, ): Promise { return fetchJson(`${SYSTEM_BASE}/database/reset`, { ...options, init: { method: "POST", body: JSON.stringify({ confirm }), ...(options?.init ?? {}) }, }); } // --- Backups ------------------------------------------------------------ export async function fetchBackups(options?: ApiRequestOptions): Promise { const res = await fetchJson<{ snapshots: SnapshotInfo[] }>(`${SYSTEM_BASE}/backups`, options); return res.snapshots ?? []; } export function createBackup(options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/backups`, { ...options, init: { method: "POST", ...(options?.init ?? {}) }, }); } export function restoreBackup( name: string, confirm: string, options?: ApiRequestOptions, ): Promise { return fetchJson( `${SYSTEM_BASE}/backups/${encodeURIComponent(name)}/restore`, { ...options, init: { method: "POST", body: JSON.stringify({ confirm }), ...(options?.init ?? {}) }, }, ); } export function deleteBackup(name: string, options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/backups/${encodeURIComponent(name)}`, { ...options, init: { method: "DELETE", ...(options?.init ?? {}) }, }); } /** * Builds an absolute URL for downloading a snapshot. Snapshot downloads stream * binary data, so they cannot reuse fetchJson — they are typically wired into * or window.open(). */ export function buildBackupDownloadUrl(name: string, baseUrl?: string): string { const root = baseUrl ?? getBackendConfig().apiBaseUrl; return `${root}${SYSTEM_BASE}/backups/${encodeURIComponent(name)}/download`; } // --- Logs --------------------------------------------------------------- export async function fetchLogFiles(options?: ApiRequestOptions): Promise { const res = await fetchJson<{ files: LogFileInfo[] }>(`${SYSTEM_BASE}/logs`, options); return res.files ?? []; } export function fetchLogTail(n = 1000, options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/logs/tail?n=${encodeURIComponent(String(n))}`, { cache: "no-store", ...options, }); } export function buildLogDownloadUrl(name: string, baseUrl?: string): string { const root = baseUrl ?? getBackendConfig().apiBaseUrl; return `${root}${SYSTEM_BASE}/logs/${encodeURIComponent(name)}/download`; } // --- Jobs --------------------------------------------------------------- export function fetchSystemJob( jobId: string, options?: ApiRequestOptions, ): Promise { return fetchJson( `${SYSTEM_BASE}/jobs/${encodeURIComponent(jobId)}`, { cache: "no-store", ...options }, ); } // --- Updates ------------------------------------------------------------ export function fetchUpdates(options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/updates`, options); } export function checkUpdates(options?: ApiRequestOptions): Promise { return fetchJson(`${SYSTEM_BASE}/updates/check`, { ...options, init: { method: "POST", ...(options?.init ?? {}) }, }); } export function applyUpdate( confirm = "UPDATE", options?: ApiRequestOptions, ): Promise { return fetchJson(`${SYSTEM_BASE}/updates/apply`, { ...options, // Spread caller init first so the required method/body can't be overridden. init: { ...(options?.init ?? {}), method: "POST", body: JSON.stringify({ confirm }) }, }); }