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

@qentrah/sdk

v3.0.0-beta.31

Published

Isomorphic TypeScript client and codegen CLI for the Qentrah CMS interface.

Readme

@qentrah/sdk

Documentation · Install guide

Isomorphic TypeScript client and codegen CLI for the Qentrah CMS interface.

These guides describe the published 3.0.0-beta.29 package. The examples use the APIs and files in that release; beta packages should be kept on matching versions.

Documentation

Install and verify

Before you start

  • node: >=18.0.0.

Use a project with a package.json. Check the runtime and package manager:

node --version
npm --version

Install the documented version

npm install @qentrah/[email protected]

Confirm the installation

npm ls @qentrah/sdk

The output should show @qentrah/[email protected]. Commit the lockfile so another developer installs the same dependency tree.

Quick start

import { createClient } from '@qentrah/sdk'

const qentrah = createClient({
  url: 'https://cms.example.com',
  apiKey: process.env.QENTRAH_API_KEY,
})

const { data, meta } = await qentrah.content.list({
  limit: 20,
  status: 'published',
})

Authenticate with JWT credentials when an API key is not available:

const qentrah = createClient({ url: 'https://cms.example.com' })
await qentrah.auth.login({ email: '[email protected]', password: 'secret' })

Expected result

A configured client sends requests to your running CMS. Replace cms.example.com with your own server; installation does not start or deploy a CMS.

Read and write content

Typed collections

const { data } = await qentrah.collection('articles').list({ limit: 10 })

for await (const document of qentrah.documents.iterate({ type: 'articles' })) {
  console.log(document.id)
}

Generate TypeScript types

Code generation

npx @qentrah/[email protected] codegen \
  --url https://cms.example.com \
  --api-key "$QENTRAH_API_KEY" \
  --out src/qentrah.d.ts

Expected result

The CLI writes the generated declarations to the --out path. Run it against a reachable CMS with permission to read the collection schema. Import the resulting types in your application and regenerate them when schemas change. Use the scoped package command above so npx resolves the documented SDK rather than a similarly named package.

Configure authentication

Use a server-side API key

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

const cms = createClient({
  url: "https://cms.example.com",
  apiKey: process.env.QENTRAH_API_KEY,
});
const health = await cms.system.health();

The API key is an application secret. Keep privileged keys in server code. The client also accepts token, optional tenant, custom headers, and an injected fetch function.

Sign in with credentials

const cms = createClient({ url: "https://cms.example.com" });
const session = await cms.auth.login({
  email: "[email protected]",
  password: suppliedPassword,
});

suppliedPassword is application input, not a hard-coded sample password. Login returns a token and user record. The client’s auth resource updates its authentication state; your application owns secure persistence and session lifetime.

Replace client credentials

cms.setToken(savedToken);
cms.setApiKey(serverApiKey);

Resource operations may also accept a per-request RequestAuth object containing apiKey or token. Apply server permissions as well as UI restrictions.

Sign out

await cms.auth.logout();

Clear the corresponding application session and cached privileged data according to your host application’s authentication design.

Query content and iterate documents

List published content

const { data, meta } = await cms.content.list({
  limit: 20,
  offset: 0,
  status: "published",
  sort: "updated_at",
  dir: "desc",
});

cms is a client created with createClient. Content lists return data plus meta. Field projection, include options, and where filters use the server’s collection contract.

Create and update a record

const { data: article } = await cms.content.create({
  collectionId: "articles",
  title: "Hello",
  status: "draft",
  data: { body: "First draft" },
});
await cms.content.update(article.id, { title: "Updated draft" });

Use a collection id that exists in your CMS. Fields must satisfy its schema. Test writes on disposable records and retain ids for later updates.

Iterate the documents API

for await (const document of cms.documents.iterate({
  type: "articles",
  locale: "en",
  limit: 20,
})) {
  console.log(document.id);
}

Documents use keyset pagination with {updatedAt, id} cursors, rather than the content API’s offsets. Do not mix the pagination contracts. The iterator advances document pages until the server reports no next cursor.

API and exports

Package identity

| Field | Value | | --- | --- | | Package | @qentrah/sdk | | Version inspected | 3.0.0-beta.29 | | License | MIT | | Module type | module |

Public import paths

| Import path | Published target | | --- | --- | | @qentrah/sdk | ./dist/index.d.ts | | @qentrah/sdk/package.json | ./package.json |

CLI entry points

  • qentrah-sdk → dist/cli.cjs.

Client resources

createClient returns content, collections, collection(name), documents, media, auth, system, setToken, and setApiKey.

Client options

url is required. Optional fields are apiKey, token, tenant, fetch, and headers. Inject fetch for testing or a host-specific fetch implementation.

List contracts

Content list options include limit, offset, status, sort, dir, fields, include, where, and resolveVariables. Document lists require type and optionally accept locale, limit, cursor, sort, dir, filter, and facet. Content returns {data, meta}; documents return {data, nextCursor}.

Timestamp helpers

Use secondsToDate for document timestamps and msToDate for content timestamps. The two APIs use different timestamp units. QentrahError aliases the exported SonicError; both refer to the same error implementation.

Inspect the original release

Open the versioned npm page or download its published archive. The archive includes the actual executable files and declarations used to write these guides.

Troubleshooting

Check the installed version

npm ls @qentrah/sdk

Compare the installed version with the version noted in this guide. Inspect your lockfile before changing dependencies; prerelease behavior may differ between versions.

Import or module errors

Use only public import paths listed in API and exports. Avoid importing guessed paths inside dist. ESM-only packages require an ESM-aware application. Install declared peer dependencies in the consuming application.

Error handling

import { QentrahError } from '@qentrah/sdk'

try {
  await qentrah.content.create({ collectionId: 'articles', title: 'Hello' })
} catch (error) {
  if (error instanceof QentrahError) {
    console.error(error.status, error.code, error.message)
  }
}

401 or 403 responses

Verify the client’s token or API key and the server permissions for the requested collection. Do not place administrative API keys in a browser bundle. Public browser access should use the authentication contract provided by your CMS deployment.

Unexpected list shape or timestamps

Use the documented resource’s response shape. Do not treat a documents keyset cursor like a content offset, or document timestamps as milliseconds.

Release documentation

Documentation checked against the previously published package artifact. This documentation-only release preserves executable files and dependencies.