Patchlightdocs

Use the SDK

Submit reviews, start scans and triage findings from TypeScript, with a client that has zero runtime dependencies.

Install

npm install --save-dev @patchlight/sdk

Needs Node.js 18.17 or newer. The package has no runtime dependencies and stays that way, so CI installs stay small.

Authenticate

Create an API key on the API Keys page of the dashboard. It is shown once.

import { createClient } from "@patchlight/sdk";

const client = createClient({ apiKey: process.env.PATCHLIGHT_API_KEY! });

A key belongs to the workspace that was active when you created it. It bills that workspace's balance and files reviews under it. Revoking a key takes effect within about a minute.

The client talks to https://api.patchlight.dev. Override it with the baseUrl option or the PATCHLIGHT_BASE_URL environment variable.

Review a diff

review.ts
const { id } = await client.createReview({
  repo: "acme/checkout-service",   // any name, groups reviews in the dashboard
  diff: myUnifiedDiff,             // unified diff text, from git or anywhere else
});

// Polls until the review settles. Throws if it fails, is skipped or times out.
const review = await client.waitForReview(id);
console.log(review.summary);

const { findings } = await client.getReviewFindings(id);
for (const f of findings) {
  console.log(`[${f.severity}] ${f.title} at ${f.filePath}:${f.line}`);
}

Only repo and diff are required. Passing the contents of the changed files makes the review noticeably better:

await client.createReview({
  repo: "acme/checkout-service",
  diff: myUnifiedDiff,
  files: { "src/payment.ts": paymentSource },
  ref: "9f2c1ab",        // the reviewed commit
  baseRef: "main",       // what the diff is against
  title: "Add 3DS fallback",
});

A review is billed from the workspace balance. When the balance is too low, the submit fails with insufficient_funds.

Scan a repository

A scan reads a whole repository. It needs a repository connected through the GitHub App, because the scanner clones it itself.

const repos = await client.listRepos();
const repo = repos.find((r) => r.fullName === "acme/checkout-service")!;

const { id } = await client.startScan(repo.id);
await client.waitForScan(id);

const { findings } = await client.getScanFindings(id);

One scan per repository runs at a time, and scans are billed per token. To scan a local checkout instead, use the CLI.

Triage findings

const findings = await client.listFindings();

for (const f of findings.filter((f) => f.category === "style")) {
  await client.updateFinding(f.id, "dismissed");
}

updateFinding takes review and scan finding ids alike, so you never need to check which kind you hold.

Every method, option and error code is in the SDK client reference.

On this page