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

@bims-ad/tdm-client

v0.1.2

Published

TypeScript client for the Broadcom Test Data Manager (TDM) REST API — typed clients for all 13 servlet services, plus an auth-refreshing session, correct pagination, and job-domain helpers.

Readme

@bims-ad/tdm-client

TypeScript clients for the Broadcom Test Data Manager REST API, generated from the OpenAPI 3.1 specs in swagger/.

Shape

The thirteen TDM specs are thirteen servlet context roots on one host (job-engine/TDMJobService, publish/TDMPublisherService, …). They share an origin and a JWT but each needs its own base URL. Two specs declaring POST /api/ca/v1/jobs are therefore different URLs, not a conflict.

createTdmClients() takes the origin and returns one configured client per service. Pass it into any generated operation:

import { createTdmClients, jobEngine } from '@bims-ad/tdm-client';

const tdm = createTdmClients({
  origin: 'https://tdm.example.com:8443',
  token,
  insecureTls: true, // lab hosts ship self-signed / expired certs
});

const jobs = await jobEngine.getAllJobs({ client: tdm.jobEngine, query: { size: 50 } });

Auth: core owns /user/login and issues the JWT the other twelve consume. Use setTdmToken(tdm, token) to swap it on already-built clients.

Domain layer

Above the raw generated clients sits a thin hand-written domain layer that encodes the operational knowledge the generated types can't (auth lifecycle, the endpoint gotchas). Prefer it over wiring auth yourself.

createTdmSession — auth that stays fresh

For anything long-running (a monitor, a poller), use a session instead of a one-shot login. It takes credentials, logs in, and keeps the JWT current — proactively before the ~24h expiry and reactively on a 401 — so your calls never fail on a stale token. The clients it exposes always carry a valid token; you never rebuild them.

import { createTdmSession, jobEngine } from '@bims-ad/tdm-client';

const session = await createTdmSession({
  origin: 'https://tdm.example.com:8443',
  username, password,
  insecureTls: true,
});

while (running) {
  await session.ensureFresh(); // no-op until the token nears expiry, then re-logs-in
  const { data } = await jobEngine.getAllJobs({ client: session.clients.jobEngine });
  // ...
}

loginToTdm() (returning a TdmLoginResult) remains available for the one-shot case, but createTdmSession is the right default for a live integration. See the JSDoc on TdmSession for the full contract.

paginate() — correct list paging

TDM list endpoints are 1-indexed (page=0 aliases page 1) and can repeat a record across pages. paginate() encodes that once: give it a fetchPage(page, size) adapter and a keyOf, and it handles 1-indexing, dedup, and the stop conditions for any list endpoint. See its JSDoc for the shape.

createJobsApi() + job helpers

Job-domain operations and field semantics, so you don't re-derive the model's traps. createJobsApi(session.clients) gives recent(), get() (the singular /job/{id}), and children() (the plural /jobs/{id}). Pure helpers encode what the generated types can't:

import { createJobsApi, isTerminal, statusOf, jobFilter } from '@bims-ad/tdm-client';

const jobs = createJobsApi(session.clients);
const recent = await jobs.recent({ total: 500, q: jobFilter({ origin: 'flow_origin' }) });
const done = recent.filter(isTerminal);           // terminal = status, NOT endTimeL

Key rule baked in: terminality is decided by status, never by endTimeL — a job cancelled before it started has no endTimeL; one cancelled mid-run has one. See jobs.ts JSDoc for isTerminal, durationMs, queueLatencyMs, wasCancelledBeforeStart, and the singular/plural endpoint distinction.

Generated code

src/generated/ is gitignored. It is produced by tools/generate-clients.mjs via the generate-clients Nx target, which build, typecheck, test, and lint all dependsOn — so a fresh clone materializes it on the first command. Never edit it; the next run overwrites it.

Regenerate explicitly:

bun run generate:clients

Why axios, not fetch

@hey-api/client-axios, not client-fetch, because TDM hosts commonly present self-signed or expired certificates and may sit behind a proxy. There is no single fetch code path that handles that on both Node and Bun:

| Approach | Node 24 | Bun 1.3 | |---|---|---| | fetch + tls: {} | not an API | works | | fetch + undici Agent | UND_ERR_INVALID_ARG | ignored | | undici.fetch + Agent | works | fails | | axios + httpsAgent | works | works |

axios gives per-instance TLS and proxy control on both runtimes. The alternative — NODE_TLS_REJECT_UNAUTHORIZED=0 — disables verification process-wide, which is the wrong scope for one bad certificate.

Known deviation

exactOptionalPropertyTypes is false in tsconfig.lib.json, against the workspace default. hey-api's output cannot satisfy it and the files are machine-written. Scoped to this project; everything else inherits true.