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

@boomevents/sdk

v0.2.0

Published

TypeScript SDK for the BOOM Organizer Storefront and Organizer Management APIs — generated from OpenAPI, running on fetch

Downloads

48

Readme

🤘 BOOM SDK

TypeScript client for the BOOM Organizer APIs — the storefront your customers buy through, and the management API behind it.

Generated from the platform's OpenAPI documents, running on plain fetch, so it works the same in Astro, Next.js, Node, Deno, Bun and Cloudflare Workers.


Install

pnpm add @boomevents/sdk
# or: npm install @boomevents/sdk · yarn add @boomevents/sdk

Requires Node 18+ (or any runtime with a global fetch). No axios, no Node built-ins, no framework dependency.

60 seconds in

import { createStorefrontClient } from '@boomevents/sdk/storefront'

const boom = createStorefrontClient({
  apiKey: process.env.BOOM_API_KEY!,
})

const result = await boom.events.listEventsV1({
  currency: 'CZK', // required — see below
  lang: 'CS',
  pageSize: 20,
})

result.page // the events, each with its products
result.actual // current page index — 0-based
result.pages

You never call /auth/token yourself: the SDK exchanges your API key for a bearer token on the first request, keeps it, and swaps it for a fresh one if the platform answers 401. The organizer comes from the token too, so no call takes a tenant parameter.

boom.tenantId() // organizer the key belongs to, once a token has been issued

Management works the same way, against its own token endpoint:

import { createManagementClient } from '@boomevents/sdk/management'

const boom = createManagementClient({
  apiKey: process.env.BOOM_API_KEY!,
})

await boom.events.publishEventV1({
  eventId,
  publishRequest: { published: true },
})

Every request goes to https://platform.boomevents.org unless you say otherwise. baseUrl switches gateways, and it takes one of two known hosts rather than a free-form URL — the client sends your API key to whatever it names, so a typo must not be able to hand that key to somebody else:

import { BOOM_DEV_BASE_URL } from '@boomevents/sdk'

const boom = createStorefrontClient({ apiKey, baseUrl: BOOM_DEV_BASE_URL })

Reading it from the environment? asBoomBaseUrl narrows a string to a known gateway and returns null for anything else.

Always send currency

The storefront prices everything it returns, so the event endpoints need a currency even though the OpenAPI document lists the parameter among the optional ones. A call without it answers:

400 Bad Request
{"InvalidCurrency": ["Currency is not valid."]}

So pass it on every call that takes it — and mind the naming, which differs between list and detail:

await boom.events.listEventsV1({ currency: 'CZK', lang: 'CS' })
await boom.events.getEventByIdV1({ id, currencyCode: 'CZK', langCode: 'CS' })

The simplest approach is to bake it into your own data layer once, rather than remembering it at every call site:

const CURRENCY = 'CZK'
const LANG = 'CS'

export const listEvents = (params = {}) =>
  boom.events.listEventsV1({ currency: CURRENCY, lang: LANG, ...params })

Pagination is 0-based

The first page is pageNumber: 0, and actual reports the 0-based index of the page you got back. URLs are usually nicer 1-based, so convert at the boundary:

const result = await boom.events.listEventsV1({
  currency: 'CZK',
  pageNumber: uiPage - 1,
  pageSize: 20,
})

result.hasNextPage
result.hasPreviousPage

The envelope answers both questions itself, so there is no arithmetic to get wrong.

What's in the box

| Surface | Import | Covers | | -------------- | ---------------------------- | ------------------------------------------------------------------------------- | | Storefront | @boomevents/sdk/storefront | events (list, detail with products) · orders (direct order) · auth | | Management | @boomevents/sdk/management | events (CRUD, publish, visibility) · products (CRUD) · customers · auth | | Core | @boomevents/sdk | client options, error types, createBoomConfig, BOOM_BASE_URL |

Two OpenAPI documents, 7 API classes, 16 operations — see docs/api-surface.md.

Both clients are flat: one document per surface means boom.events.listEventsV1(), not a service-then-class hierarchy.

Why it feels different from raw generated code

The generated classes are exposed as-is — no domain facade to drift out of sync with the API. What sits around them is the thin layer you'd otherwise write in every project:

  • API key handling. Exchanged for a token once, reused, re-exchanged on 401. Concurrent calls share one exchange rather than stampeding the auth endpoint.
  • Real errors. Non-2xx throws BoomApiError with the body already parsed, plus validationErrors, status and isNotFound-style guards.
  • Retries with backoff. Idempotent methods only, honouring Retry-After, with full jitter.
  • Timeouts. Per attempt, composed with any AbortSignal you pass in.
  • Your fetch. Swap it out to add framework caching, tracing or mocks.

Keep the API key on a server

The key is long-lived and grants full access to the organizer's data — including placing orders. It belongs in an environment variable on a server, never in client-side JavaScript.

The bearer token it produces is short-lived, but it can place orders too, so it should not reach the browser either. Both framework guides show the shape that works: your own endpoint holds the key, the browser gets JSON. See docs/authentication.md.

For a storefront already built this way, see boom-frontend-sdk — a layer over this package with Next.js and Astro reference apps, the SDK confined to a single server-only workspace package, and a verify:no-leak step that scans the built client bundles for the key, the platform hostname and SDK internals.

Documentation

| | | | -------------------------------------------------- | ---------------------------------------------------- | | Getting started | Install, first call, client options in full | | Authentication | API keys, token exchange, where they may live | | Error handling | BoomApiError, validation errors, retries, timeouts | | Recipes | Listing, ordering, publishing, testing | | Next.js / Astro | Framework wiring | | API surface | Every API class and operation | | Regenerating | Pulling new endpoints from the platform specs | | Architecture | How the layers fit together, and why |

Working on the SDK

pnpm install
pnpm run generate    # pull both OpenAPI documents -> src/generated
pnpm run barrels     # rebuild the hand-facing surface over them
pnpm run typecheck
pnpm run test
pnpm run build

Both documents come from platform.boomevents.org/custom-openapi.

Tests

pnpm run test           # 95 tests, no network
pnpm run test:coverage
pnpm run smoke          # hits the platform — needs BOOM_API_KEY

The suite covers src/core, the hand-written layer where bugs would live, at ~98% statement coverage. Everything runs against an injected fetch, so it needs no credentials and no network.

| File | What it pins down | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | api-key.test.ts | Token exchanged once, shared between concurrent callers, key sent as a header only, failed exchange not cached | | fetcher.test.ts | Retries only idempotent methods, honours Retry-After, never replays a stream body, timeouts, signal composition, a caller's cancellation left intact | | errors.test.ts | BoomApiError fields and guards, body parsing that never throws | | middleware.test.ts | Auth header, 401 re-exchange (and when it must not fire), non-2xx becoming BoomApiError | | config.test.ts | Option defaults, middleware ordering, refusing a client with no way to authenticate | | client.integration.test.ts | The whole chain against a stubbed fetch, through the real generated clients | | version.test.ts | SDK_VERSION matches package.json, so the User-Agent never misreports a release |

License

MIT © BOOM Events s.r.o.