import { apiFetch } from '@/lib/api'; import type { VulnerabilityDetail } from '@/types/security'; /** * Every vulnerability row for a scan, paging past the API's per-request cap * (the backend clamps a single page to 1000 rows). The detail table renders * only a capped page, so the CSV export relies on this to make good on its * "complete list" promise for scans with thousands of findings. Unfiltered by * severity on purpose: the CSV is the full record, not the current view. A * short page also ends the loop, so an over-reported `total` cannot spin it. */ export async function fetchAllScanVulnerabilities( scanId: number, ): Promise { const all: VulnerabilityDetail[] = []; const pageSize = 1000; for (let offset = 0; ; offset += pageSize) { const res = await apiFetch( `/security/scans/${scanId}/vulnerabilities?limit=${pageSize}&offset=${offset}`, ); if (!res.ok) throw new Error('Failed to fetch the full vulnerability list'); const data = await res.json(); const items: VulnerabilityDetail[] = Array.isArray(data.items) ? data.items : []; all.push(...items); if (items.length < pageSize || all.length >= (data.total ?? all.length)) break; } return all; }