npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

blackduck-api-client

v1.0.1

Published

TypeScript client for the Black Duck REST API

Readme

Black Duck API Client

A zero-dependency TypeScript client for the Black Duck REST API (Software Composition Analysis).

CI npm license

Features

  • Full TypeScript — every request and response is fully typed
  • Read-only — covers all major GET endpoints for projects, BOM components, vulnerabilities, licenses, users, code locations, and policy rules
  • Chainable resourcesclient.project('id').version('id').components() pattern
  • Dual package — ships CJS + ESM, works in Node.js and browsers
  • Zero runtime dependencies — uses native fetch and URLSearchParams
  • Request events — hook into every HTTP request for logging and monitoring
  • Semantic versioning — automated releases via Conventional Commits

Installation

npm install blackduck-api-client

Quick Start

import { BlackDuckClient } from 'blackduck-api-client';

const client = new BlackDuckClient({
  apiUrl: 'https://blackduck.example.com',
  token: 'my-personal-access-token',
});

// List projects
const page = await client.projects({ limit: 10 });
console.log(page.totalCount, 'projects found');

// Get BOM components for a project version
const bom = await client.project('proj-uuid').version('ver-uuid').components();
for (const comp of bom.items) {
  console.log(comp.componentName, comp.policyStatus);
}

// Get vulnerable components only
const vulns = await client.project('proj-uuid').version('ver-uuid').vulnerableComponents();
const critical = vulns.items.filter(v =>
  v.vulnerabilityWithRemediation.severity === 'CRITICAL'
);

// Get the risk profile
const risk = await client.project('proj-uuid').version('ver-uuid').riskProfile();
console.log('High vulns:', risk.categories.VULNERABILITY?.HIGH);

// Search the Knowledge Base for a component
const results = await client.components({ q: 'log4j', limit: 5 });

// Get the current user
const me = await client.currentUser();
console.log(me.userName);

Authentication

The client uses API Token authentication (recommended for integrations):

const client = new BlackDuckClient({
  apiUrl: 'https://blackduck.example.com',
  token: 'my-personal-access-token',
  // Optional — defaults shown:
  apiPath: 'api',
});

To generate a personal access token, go to Black Duck → User menu → My Access Tokens.

The Authorization: token <api-token> header is sent automatically with every request.

API Reference

BlackDuckClient

The main client. All methods return Promises.

Projects

// List projects (paginated)
await client.projects({ q: 'name:my-app', limit: 25, offset: 0 });

// Get a single project (await directly or call .get())
const project = await client.project('proj-uuid');
const project = await client.project('proj-uuid').get();

// List project versions
await client.project('proj-uuid').versions({ limit: 10 });

// Navigate to a project version (await directly or chain)
const version = await client.project('proj-uuid').version('ver-uuid');

Project Versions (BOM, Risk, Policy)

// Bill of Materials — all components
await client.project('proj-uuid').version('ver-uuid').components({ limit: 100 });

// Vulnerable components only
await client.project('proj-uuid').version('ver-uuid').vulnerableComponents();

// Aggregated risk profile (VULNERABILITY, LICENSE, OPERATIONAL, ACTIVITY, VERSION)
await client.project('proj-uuid').version('ver-uuid').riskProfile();

// Overall policy status
await client.project('proj-uuid').version('ver-uuid').policyStatus();

Knowledge Base — Components

// Search KB components
await client.components({ q: 'log4j', limit: 10 });

// Get a component (await directly or chain)
const comp = await client.component('comp-uuid');

// List component versions
await client.component('comp-uuid').versions({ q: 'versionName:2.17' });

// Get a specific component version
await client.component('comp-uuid').version('ver-uuid');

Vulnerabilities

// List vulnerabilities
await client.vulnerabilities({ q: 'severity:CRITICAL', limit: 50 });

// Get a single vulnerability by CVE or BDSA ID
await client.vulnerability('CVE-2021-44228');
await client.vulnerability('BDSA-2021-3544');

Licenses

// List licenses
await client.licenses({ q: 'name:Apache', limit: 20 });

// Get a single license
await client.license('lic-uuid');

Users

// List users
await client.users({ q: 'userName:jdoe', limit: 10 });

// Get a single user by UUID
await client.user('user-uuid');

// Get the currently authenticated user
await client.currentUser();

Roles

// List all roles
await client.roles();

Notifications

// List notifications
await client.notifications({
  filter: 'notificationType:VULNERABILITY',
  startDate: '2024-01-01T00:00:00.000Z',
  endDate: '2024-12-31T23:59:59.999Z',
});

Code Locations (Scans)

// List code locations
await client.codeLocations({ q: 'name:my-repo', limit: 20 });

// Get a code location (await directly or chain)
const location = await client.codeLocation('loc-uuid');

// Get scan summaries for a code location
await client.codeLocation('loc-uuid').scanSummaries();

Policy Rules

// List policy rules
await client.policyRules({ limit: 50 });

// Get a single policy rule
await client.policyRule('rule-uuid');

Pagination

All list endpoints return a paged response:

interface BlackDuckPagedResponse<T> {
  totalCount: number;
  items: T[];
  _meta: BlackDuckMeta;
}

To iterate through all pages:

let offset = 0;
const limit = 100;
const allComponents: BlackDuckBomComponent[] = [];

while (true) {
  const page = await client
    .project('proj-uuid')
    .version('ver-uuid')
    .components({ offset, limit });

  allComponents.push(...page.items);
  if (allComponents.length >= page.totalCount) break;
  offset += limit;
}

Request Events

Subscribe to every HTTP request for logging, metrics, or debugging:

client.on('request', (event) => {
  console.log(`[${event.method}] ${event.url} — ${event.durationMs}ms (${event.statusCode})`);
  if (event.error) {
    console.error('Request failed:', event.error.message);
  }
});

Event payload:

| Field | Type | Description | |-------|------|-------------| | url | string | Full URL requested | | method | 'GET' | HTTP method | | startedAt | Date | Request start timestamp | | finishedAt | Date | Request end timestamp | | durationMs | number | Duration in milliseconds | | statusCode | number? | HTTP status code | | error | Error? | Error object if the request failed |

Error Handling

import { BlackDuckApiError } from 'blackduck-api-client';

try {
  await client.project('nonexistent-uuid');
} catch (err) {
  if (err instanceof BlackDuckApiError) {
    console.log(err.status);     // 404
    console.log(err.statusText); // 'Not Found'
    console.log(err.message);    // 'Black Duck API error: 404 Not Found'
  }
}

TypeScript Types

All domain types are exported:

import type {
  BlackDuckProject,
  BlackDuckProjectVersion,
  BlackDuckBomComponent,
  BlackDuckVulnerableBomComponent,
  BlackDuckVulnerabilityWithRemediation,
  BlackDuckRiskProfile,
  BlackDuckRiskCounts,
  BlackDuckPolicyStatus,
  BlackDuckComponent,
  BlackDuckComponentVersion,
  BlackDuckVulnerability,
  BlackDuckCvss2,
  BlackDuckCvss3,
  BlackDuckLicense,
  BlackDuckUser,
  BlackDuckRole,
  BlackDuckNotification,
  BlackDuckCodeLocation,
  BlackDuckScanSummary,
  BlackDuckPolicyRule,
  BlackDuckPagedResponse,
  BlackDuckMeta,
  // ... and many more
} from 'blackduck-api-client';

Contributing

See CONTRIBUTING.md for development guidelines.

License

MIT