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

cohost-client

v0.2.5

Published

TypeScript SDK for the Cohost API — auto-generated from OpenAPI spec

Readme

cohost-client

TypeScript SDK for the Cohost External API. Fully typed API client auto-generated from the OpenAPI spec using Orval.

Features

  • Fully typed request/response types generated from OpenAPI spec
  • Works in both browser and Node.js (18+)
  • Two auth modes: API Key (backend) and JWT Bearer (frontend)
  • Self-updating — regenerate types and functions with npm run generate
  • Zero runtime dependencies (uses native fetch)

Installation

npm install cohost-client

The Auth Architecture

The Cohost API uses two distinct auth mechanisms:

| Endpoint group | Auth required | Who calls it | |---|---|---| | /api/v1/external/* | X-API-Key header | Your server only | | /api/v1/checkout/*, /api/v1/bookings/my, /api/v1/auth/me | Bearer <JWT> | Your frontend |

Never expose your API key in client-side code. Environment variables prefixed with NEXT_PUBLIC_, VITE_, REACT_APP_, etc. get bundled into your JS and are readable by anyone in DevTools. Keep the key in unprefixed server-only env vars.

The intended flow:

Browser                  Your Server               Cohost API
  │                           │                        │
  │── POST /auth/login ───────►│                        │
  │                           │── customerLogin...() ─►│  (X-API-Key)
  │                           │◄── { access_token } ───│
  │◄── { access_token } ──────│                        │
  │                           │                        │
  │  setBearerToken(token)    │                        │
  │── getListings...() ───────────────────────────────►│  (Bearer JWT)

Quick Start

Server-side (API key)

// lib/cohost-server.ts — never import from a 'use client' component
import {
  configureClient,
  getListingsApiV1ExternalListingsGet,
} from "cohost-client";

configureClient({
  apiKey: process.env.COHOST_API_KEY, // no NEXT_PUBLIC_ prefix
});

export async function fetchListings() {
  const res = await getListingsApiV1ExternalListingsGet();
  return res.data;
}

After login (JWT)

import {
  configureClient,
  customerLoginApiV1ExternalCustomersLoginPost,
  setBearerToken,
  getListingsApiV1ExternalListingsGet,
} from "cohost-client";

configureClient({ apiKey: "cohost_api_xxx" });

const login = await customerLoginApiV1ExternalCustomersLoginPost({
  email: "[email protected]",
  password: "…",
});
setBearerToken(login.data.access_token);

const listings = await getListingsApiV1ExternalListingsGet();

Configuration

configureClient(options)

Call once at startup (or per request in server code). All generated functions use this global config.

import { configureClient } from "cohost-client";

configureClient({
  baseUrl: "https://v2-staging.api.cohost.ai",
  apiKey: process.env.COHOST_API_KEY,
  bearerToken: "eyJhbGciOi...", // optional pre-set JWT
  customFetch: myFetch, // optional — see below
  onRequest: (url, init) => init,
  onResponseError: (response, url) => {},
});

Auth headers

  • If apiKey is set → every request gets X-API-Key (unless already present).
  • If bearerToken is set (via configureClient or setBearerToken) → Authorization: Bearer … is added.

JWT persistence (localStorage, cookies, etc.) is your responsibility — read the token and call setBearerToken when your app loads or after login.

setBearerToken / setApiKey

Update credentials at runtime without re-calling configureClient.

Custom fetch implementation

By default the SDK uses the global fetch. Pass customFetch to replace it with any compatible transport — useful for Angular, testing, or custom middleware.

Angular (HttpClient)

Angular's HttpClient returns Observables rather than Promise<Response>, so wrap it to match the fetch signature:

import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { firstValueFrom } from "rxjs";
import { configureClient } from "cohost-client";

@Injectable({ providedIn: "root" })
export class CohostService {
  constructor(private http: HttpClient) {
    configureClient({
      apiKey: "cohost_api_xxx",
      customFetch: (url, init) =>
        firstValueFrom(
          this.http.request(
            new Request(url, init)
          )
        ),
    });
  }
}

Testing (mock fetch)

import { configureClient } from "cohost-client";

configureClient({
  customFetch: async (url, init) => {
    return new Response(JSON.stringify({ data: "mocked" }), {
      status: 200,
      headers: { "Content-Type": "application/json" },
    });
  },
});

Node.js (custom agent, proxies, etc.)

import { configureClient } from "cohost-client";
import { fetch, Agent } from "undici";

configureClient({
  customFetch: (url, init) =>
    fetch(url, {
      ...init,
      dispatcher: new Agent({ connect: { timeout: 10_000 } }),
    }) as Promise<Response>,
});

Error Handling

Non-2xx responses throw CohostApiError with status, statusText, body, and url:

import {
  CohostApiError,
  listCustomersApiV1ExternalCustomersGet,
} from "cohost-client";

try {
  await listCustomersApiV1ExternalCustomersGet();
} catch (error) {
  if (error instanceof CohostApiError) {
    console.error(error.status, error.body);
  }
}

Successful responses are { data, status, headers } (Orval fetch client shape). Inspect status on the returned object if you need to branch on 200 vs 201, etc.

API Reference (generated)

Function names follow the OpenAPI operationIds. Import from cohost-client — they are grouped in modules by tag: customers, bookings, listings, reference.

Customers (./generated/customers re-exported)

| Function | Description | |---|---| | customerLoginApiV1ExternalCustomersLoginPost | Customer login | | registerCustomerApiV1ExternalCustomersRegisterPost | Register customer | | listCustomersApiV1ExternalCustomersGet | List customers | | getCustomerApiV1ExternalCustomersUserIdGet | Get customer | | updateCustomerApiV1ExternalCustomersUserIdPatch | Update customer | | removeCustomerFromTeamApiV1ExternalCustomersUserIdTeamsTeamIdDelete | Remove from team | | resendVerificationApiV1ExternalCustomersUserIdResendVerificationPost | Resend verification | | checkCustomerEmailVerificationApiV1ExternalCustomersUserIdEmailVerificationGet | Email verification status |

Listings

| Function | Description | |---|---| | getListingsApiV1ExternalListingsGet | List listings | | getListingDetailApiV1ExternalListingsListingIdGet | Detail by ID | | getListingDetailBySlugApiV1ExternalListingsSlugSlugGet | Detail by slug | | getListingAvailabilityApiV1ExternalListingsListingIdAvailabilityGet | Availability by ID | | getListingAvailabilityBySlugApiV1ExternalListingsSlugSlugAvailabilityGet | Availability by slug |

Bookings

| Function | Description | |---|---| | previewExternalBookingApiV1ExternalBookingsPreviewPost | Preview pricing | | createExternalBookingApiV1ExternalBookingsPost | Create booking | | listExternalBookingsApiV1ExternalBookingsGet | List bookings | | getExternalBookingDetailApiV1ExternalBookingsBookingIdGet | Booking detail |

Reference

| Function | Description | |---|---| | getCatalogsApiV1ExternalCatalogsGet | Catalogs | | getAmenitiesApiV1ExternalAmenitiesGet | Amenities | | listCountriesApiV1ExternalLocationsCountriesGet | Countries | | listProvincesApiV1ExternalLocationsCountryCodeProvincesGet | Provinces |

Request/response types live under export * from "./generated/schemas" — import named types from cohost-client (e.g. CustomerLoginRequest).

Updating the SDK

When the Cohost API spec changes, regenerate the client:

# Fetch latest spec and regenerate all types + functions
npm run generate

# Or step by step:
npm run generate:fetch   # Download latest OpenAPI spec
npm run generate:clean   # Remove old generated code
npm run generate:orval   # Regenerate TypeScript client

# Then rebuild
npm run build:only

The full npm run build command runs the entire pipeline: fetch spec → generate code → bundle.

CI/CD Auto-Update

You can set up a scheduled CI job to auto-detect API changes:

# .github/workflows/update-sdk.yml
name: Update SDK
on:
  schedule:
    - cron: "0 */6 * * *"  # Every 6 hours
  workflow_dispatch:

jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npm run generate
      - run: npm run build:only
      - uses: peter-evans/create-pull-request@v6
        with:
          title: "chore: update SDK from latest API spec"
          commit-message: "chore: regenerate SDK from latest OpenAPI spec"
          branch: auto-update-sdk

Development

# Install dependencies
npm install

# Generate client from OpenAPI spec
npm run generate

# Build library
npm run build:only

# Full pipeline (generate + build)
npm run build

# Type check
npm run typecheck

# Watch mode
npm run dev

Architecture

src/
├── fetcher.ts           # configureClient + mutator used by Orval-generated functions
├── index.ts             # Barrel exports
└── generated/           # Auto-generated by Orval (do not edit)
    ├── customers/
    ├── bookings/
    ├── listings/
    ├── reference/
    └── schemas/

Compatibility

Runtime environments

The SDK uses only standard Web APIs (fetch, Headers, Request, Response) with no runtime dependencies, so it runs anywhere these are natively available:

| Environment | Min version | Notes | |---|---|---| | Node.js | 18.0.0+ | Native fetch added in Node 18 | | Bun | Any stable | Native fetch supported | | Deno | Any stable | Native fetch supported | | Cloudflare Workers | — | Fully supported | | Vercel Edge / Netlify Edge | — | Fully supported | | Modern browsers | — | All evergreen browsers |

Node 16 and below are not supported — they do not have native fetch.

Module formats

The package ships both formats so it works regardless of your project setup:

| Format | File | Use case | |---|---|---| | ESM | dist/index.mjs | import in modern projects, bundlers, Vite, Next.js | | CJS | dist/index.cjs | require() in older Node.js setups |

TypeScript declarations are included for both formats (.d.mts / .d.cts).

Frontend frameworks

The SDK is framework-agnostic and works with any frontend framework out of the box:

| Framework | Works | Notes | |---|---|---| | React / Next.js / Remix | ✓ | Wrap calls in @tanstack/react-query or swr for loading/caching | | Vue / Nuxt | ✓ | Wrap in a composable or use vue-query | | Svelte / SvelteKit | ✓ | Use in load functions or stores | | Solid.js | ✓ | Use with createResource | | Astro | ✓ | Use in .astro frontmatter or API routes | | Angular | ✓ | Wrap in an @Injectable service; plug in HttpClient via customFetch | | Plain JS/TS | ✓ | No framework required |

The SDK does not ship framework-specific hooks or bindings. This keeps it lean and lets you integrate it with whichever data-fetching layer your app already uses.

TypeScript

TypeScript 5.0+ is recommended. The generated types use modern TypeScript features. Older versions may work but are not tested.

License

MIT