Eventos y SDK
SDK de JavaScript
Un cliente tipado y ligero para Node.js 18+, Deno y Bun. Sin dependencias: usa el fetch integrado y Web Crypto.
@scanverra/sdk está en versión preliminar y su interfaz aún puede cambiar. Cada llamada es una petición HTTP normal, así que las páginas de la API muestran cómo hacerlo sin él.Instalación
Crea un cliente y reutilízalo.
npm install @scanverra/sdk
import { Scanverra } from "@scanverra/sdk";
const scanverra = new Scanverra({
apiKey: process.env.SCANVERRA_API_KEY,
// baseUrl: "https://www.scanverra.com", // optional
// timeoutMs: 300_000, // optional, per request
});Ejecutar escaneos
scans.audit() y scans.repo() responden con el informe terminado. Los demás responden al instante con un id; wait() consulta hasta que el informe está listo y lanza un error si el escaneo falló.
// Answers with the finished report
const audit = await scanverra.scans.audit({ url: "https://example.com" });
// Answer with an id; wait() polls until the report is ready
const { scanId } = await scanverra.scans.security({ url: "https://example.com" });
const security = await scanverra.wait("security", scanId);
const { testId } = await scanverra.scans.browser({ url: "https://example.com" });
const browser = await scanverra.wait("browser", testId, { intervalMs: 5000 });
// Repo scans: owner and repo of a connected account
const repo = await scanverra.scans.repo({ owner: "acme", repo: "storefront", async: true });
const repoReport = await scanverra.wait("repo", repo.scanId);Leer propiedades
Puntuaciones, problemas unificados y próximos pasos de cada producto.
const { properties } = await scanverra.properties.list();
for (const p of properties) console.log(p.name, p.score, p.openTasks);
const detail = await scanverra.properties.get(properties[0].id);
const critical = detail.issues.filter((i) => i.severity === "critical");Suscribirse a eventos
Crea un REST hook para cualquier evento y comprueba la firma de cada envío con verifyWebhook. Rechaza los envíos de hace más de cinco minutos.
const hook = await scanverra.hooks.create({
event: "remediation.task_created",
url: "https://hooks.example.com/scanverra",
});
// Store hook.secret: it is shown only once.
// In your receiver, with the raw request body:
import { verifyWebhook } from "@scanverra/sdk";
const ok = await verifyWebhook({
secret: process.env.SCANVERRA_HOOK_SECRET,
body: rawBody,
timestamp: req.headers["x-scanverra-timestamp"],
signature: req.headers["x-scanverra-signature"],
});
if (!ok) return res.status(401).end();Errores
Cualquier fallo lanza ScanverraError con status, code, un message legible y el body de la respuesta. Si no llega respuesta, status es 0 y code es network_error o timeout.
import { ScanverraError } from "@scanverra/sdk";
try {
await scanverra.scans.audit({ url: "https://example.com" });
} catch (err) {
if (!(err instanceof ScanverraError)) throw err;
if (err.code === "SCAN_COOLDOWN") console.log("Try again later:", err.message);
else if (err.status === 0 || err.status >= 500) console.log("Retry with backoff:", err.code ?? err.status);
else throw err; // 4xx: fix the request (see /docs/errors)
}Referencia
| Campo | Descripción |
|---|---|
scans.audit(body)Promise<report>Opcional | Ejecuta una auditoría web y devuelve el informe. Con async: true recibes reportId al instante. |
scans.security(body)Promise<{ scanId }>Opcional | Inicia un escaneo de seguridad. |
scans.browser(body)Promise<{ testId }>Opcional | Inicia una auditoría de navegador. Con credentialId pruebas páginas tras un login. |
scans.seo(body)Promise<{ scanId }>Opcional | Inicia un análisis SEO. |
scans.repo(body)Promise<{ scanId }>Opcional | Escanea un repositorio conectado. |
results.<tool>(id)Promise<ScanResult>Opcional | Lee un escaneo por id: audit, security, browser, seo o repo. |
wait(tool, id, options?)Promise<ScanResult>Opcional | Consulta el método results de la herramienta hasta que termina el escaneo. Opciones: intervalMs (4000), timeoutMs (600000). |
properties.list() / get(id)Promise<...>Opcional | Lista las propiedades o lee una con sus problemas y próximos pasos. |
hooks.list() / create() / delete(id) / sample(event)Promise<...>Opcional | Gestiona los REST hooks. create() devuelve el secreto de firma una sola vez. |
verifyWebhook(input)Promise<boolean>Opcional | Comprueba X-Scanverra-Signature con el cuerpo sin procesar y la marca de tiempo. |