vanta-auditor-tui
Version:
Beautiful terminal UI for exporting Vanta audit evidence with ZIP support and progress tracking
125 lines • 5.51 kB
JavaScript
export async function gatherEvidenceItems(sdk, auditId, verbose = false, onProgress) {
const items = [];
// Verbose logging handled by caller
try {
// Step 1: Get all evidence items for the audit
onProgress?.({
phase: 'discovering',
current: 0,
total: 0,
message: 'Discovering evidence items...'
});
let cursor = undefined;
const allEvidence = [];
for (let page = 0; page < 100; page++) {
// Page fetching in progress
const response = await sdk.audits.listEvidence({
auditId,
pageSize: 100,
pageCursor: cursor
});
const evidenceList = response?.results?.data || [];
allEvidence.push(...evidenceList);
onProgress?.({
phase: 'discovering',
current: allEvidence.length,
total: allEvidence.length,
message: `Found ${allEvidence.length} evidence items...`
});
// Evidence items collected from page
// Check for next page
const pageInfo = response?.results?.pageInfo;
if (pageInfo?.hasNextPage && pageInfo?.endCursor) {
cursor = pageInfo.endCursor;
}
else {
break;
}
}
// All evidence items discovered
// Step 2: For each evidence item, get its download URLs
for (let i = 0; i < allEvidence.length; i++) {
const evidence = allEvidence[i];
onProgress?.({
phase: 'processing',
current: i + 1,
total: allEvidence.length,
message: `Processing ${evidence.name || 'evidence'}...`
});
// Processing evidence item
try {
// Use getEvidenceUrls with the evidence ID
const urlsResponse = await sdk.audits.getEvidenceUrls({
auditId,
auditEvidenceId: evidence.id,
pageSize: 100
});
const urls = urlsResponse?.results?.data || [];
// URLs retrieved for evidence
// Add each URL to our items list
for (const urlItem of urls) {
if (urlItem.url && urlItem.isDownloadable !== false) {
// Ensure we have a proper filename with extension
let fileName = urlItem.filename || urlItem.id || evidence.name || 'document';
// If the filename doesn't have an extension, try to infer one
if (!fileName.includes('.')) {
// Try to infer from the URL or evidence type
const urlLower = urlItem.url?.toLowerCase() || '';
if (urlLower.includes('.pdf')) {
fileName += '.pdf';
}
else if (urlLower.includes('.json') || urlItem.id?.endsWith('.json')) {
fileName += '.json';
}
else if (urlLower.includes('.docx')) {
fileName += '.docx';
}
else if (urlLower.includes('.xlsx')) {
fileName += '.xlsx';
}
else if (urlLower.includes('.png') || urlLower.includes('.jpg') || urlLower.includes('.jpeg')) {
fileName += '.png';
}
else if (evidence.name?.toLowerCase().includes('policy') ||
evidence.name?.toLowerCase().includes('handbook') ||
evidence.name?.toLowerCase().includes('procedure') ||
evidence.name?.toLowerCase().includes('agreement') ||
evidence.name?.toLowerCase().includes('document')) {
fileName += '.pdf'; // Most likely PDF for policy documents
}
else {
fileName += '.pdf'; // Default to PDF for documents
}
}
items.push({
downloadUrl: urlItem.url,
fileName: fileName,
evidenceKey: evidence.id
});
// URL added to download list
}
}
}
catch (error) {
// Some evidence items might not have URLs, that's okay
if (verbose) {
const errorMsg = error instanceof Error ? error.message : String(error);
// Evidence URLs not available - continuing
}
}
}
onProgress?.({
phase: 'complete',
current: items.length,
total: items.length,
message: 'Evidence discovery complete'
});
// Evidence gathering complete
}
catch (error) {
// Error will be propagated to caller
throw error;
}
return items;
}
//# sourceMappingURL=evidenceGatherer.js.map