ShipTested

Library API

On this page

ESM, Node 20.19+ and Web API runtimes. Core has no import-time side effects or telemetry. Only OSV receives exact package names and versions. Optional AI is a separate import.

import { scan } from '@heysalad/shiptested';
const report = await scan({ lockfile: suppliedText }, {
  signal: controller.signal,
  onStage: event => renderStage(event),
});

Generated TypeScript declarations:

import { type Cache } from './osv.js';
import type { ScanReport } from './types.js';
export * from './types.js';
export { parseManifest } from './parser.js';
export { maskSecrets, scanFiles, verdict } from './scanner.js';
export { queryOsv, getAdvisory, MemoryCache, type Cache } from './osv.js';
export { advisoryMetadata, groupByPackage } from './advisory-metadata.js';
export type StageEvent = {
    stage: 'Lockfile' | 'Secrets' | 'OSV';
    status: 'running' | 'done' | 'failed';
    detail: string;
    durationMs: number;
};
export type Report = ScanReport;
export type ScanOptions = {
    onStage?: (event: StageEvent) => void;
    signal?: AbortSignal;
    osv?: {
        baseUrl?: string;
        cache?: Cache;
    }; /** Dependency injection for tests; URL allowlist remains enforced. */
    fetcher?: typeof fetch;
};
export declare function scan(input: {
    lockfile: string;
    filename?: string;
}, opts?: ScanOptions): Promise<Report>;

export type Dependency = {
    name: string;
    version: string;
    ecosystem: "npm" | "PyPI";
    path: string;
};
export type Evidence = {
    kind: "code" | "advisory" | "http";
    dependency?: Dependency;
    location: string;
    excerpt: string;
    url?: string;
    retrievedAt?: string;
};
export type Finding = {
    id: string;
    title: string;
    severity: "high" | "medium" | "low" | "review";
    severitySource?: string;
    cvss?: number;
    cvssVector?: string;
    fixedVersion?: string;
    description: string;
    action: string;
    evidence: Evidence[];
};
export type Check = {
    name: string;
    state: "complete" | "incomplete" | "snapshot" | "not-in-scope";
    detail: string;
};
export type Source = {
    id: string;
    package?: string;
    version?: string;
    matchedDependencies?: Dependency[];
    url: string;
    title: string;
    excerpt: string;
    retrievedAt: string;
    publishedAt?: string;
    extraction?: "extracted" | "search-only";
    classification?: "matched-advisory" | "watch";
};
export type Explanation = {
    findingId: string;
    explanation: string;
    basis?: "validated-selection" | "scanner-fallback";
};
export type ScanReport = {
    recording?: {
        recordedAt: string;
        model: string;
        region: string;
        commit: string;
        advisoryMetadataRetrievedAt?: string;
    };
    id: string;
    mode: "demo" | "live";
    createdAt: string;
    status: "Blocked" | "Review required" | "Checks passed" | "Incomplete";
    dependencies: Dependency[];
    findings: Finding[];
    checks: Check[];
    sources: Source[];
    explanations: Explanation[];
    durationMs: number;
    policy: string;
};
export type ScanInput = {
    mode: "demo" | "live";
    filename?: "package.json" | "package-lock.json" | "requirements.txt";
    content?: string;
    research?: boolean;
    projectId?: string;
};