import axios from "axios";
import { Dependency, OSVQuery, OSVResponseItem, SocketResponse, OSVVulnerability } from "./types";
/**
* Query OSV.dev Batch API
*/
export async function checkOSVBatch(packages: Dependency[]): Promise<(OSVResponseItem | null)[]> {
try {
// Deduplicate queries logic could be here, but assumed handled by caller or batch robustness
const chunkSize = 500;
const allResults: (OSVResponseItem | null)[] = [];
for (let i = 0; i < packages.length; i += chunkSize) {
const chunk = packages.slice(i, i + chunkSize);
const queries: OSVQuery[] = chunk.map((p) => ({
package: { name: p.name, ecosystem: "npm" },
version: p.version,
}));
const response = await axios.post<{ results: (OSVResponseItem | null)[] }>("https://api.osv.dev/v1/querybatch", { queries });
if (response.data.results) {
allResults.push(...response.data.results);
} else {
allResults.push(...Array.from({ length: chunk.length }).fill(null) as null[]);
}
}
return allResults;
} catch (error) {
const msg = error instanceof Error ? error.message : String(error);
console.error("Error querying OSV.dev:", msg);
// Fallback: treat as no info found rather than crashing, but strictly this is an error state
return Array.from({ length: packages.length }).fill(null) as null[];
}
}
/**
* Query Socket.dev (Single Package)
*/
export async function checkSocket(name: string, version: string): Promise<SocketResponse | null> {
try {
const response = await axios.get<SocketResponse>(
`https://api.socket.dev/v0/package/npm/${name}/${version}`
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
if (error.response?.status === 404) {
// Package not found on Socket.dev, treat as "no info" (safeish)
return null;
}
console.warn(`[Socket.dev] API Error for ${name}@${version}: ${error.message}`);
} else {
console.warn(`[Socket.dev] Unknown Error for ${name}@${version}:`, error);
}
return null;
}
}
/**
* Query OSV.dev by ID
*/
export async function getVulnDetails(id: string): Promise<OSVVulnerability | null> {
try {
const response = await axios.get<OSVVulnerability>(`https://api.osv.dev/v1/vulns/${id}`);
return response.data;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 404) {
return null;
}
console.error(`Error fetching details for ${id}:`, error);
return null;
}
}
/**
* Query OSV.dev by List of IDs (Batch)
*/
export async function getVulnDetailsBatch(ids: string[]): Promise<(OSVVulnerability | null)[]> {
// OSV API doesn't have a by-ID batch endpoint, so we run in parallel.
return Promise.all(ids.map(id => getVulnDetails(id)));
}