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

@happy-technologies/connector-core

v0.3.0

Published

Shared connector substrate for Happy Technologies products: manifest/descriptor schema, a generic registry, config validation, and an OAuth/credential substrate. Domain-agnostic; products supply their own connector contract, crypto, and storage.

Readme

@happy-technologies/connector-core

The shared connector substrate for Happy Technologies products. It provides the parts of a connector platform that are identical across products, and nothing that is specific to one:

  • Manifest / descriptor schema (ConnectorDescriptor): the single source of truth for a connector's metadata, driving config validation, the catalog, and the registration form.
  • A generic ConnectorRegistry<T>: register connectors, look them up, list the catalog, validate config. Replaces closed enums and DB CHECK constraints.
  • Descriptor-driven config validation, including a guard that rejects credential-shaped keys on the non-secret config path.
  • An OAuth and credential substrate (OAuthSubstrate): the authorization-code flow, token refresh, and encrypted token storage, behind injected interfaces.
  • An optional document-connector contract (SourceConnector) for products that ingest documents.

Design boundary

This package owns metadata, registry mechanics, validation, and auth orchestration. It does not own:

  • Product domain logic (compiling to artifacts, reconciling to CIs).
  • Crypto. You inject a SecretCipher.
  • Storage. You inject a CredentialStore and optionally an OAuthStateStore.
  • A specific OAuth library. You inject per-provider OAuthClient instances.

This is the seam that lets the auth backend be swapped later (for example to a self-hosted Nango) without touching connector code.

Wiring the OAuth substrate with Arctic

Arctic (arcticjs.dev, MIT) provides typed OAuth 2.0 clients for Microsoft Entra ID, Google, Atlassian, GitHub, Slack, and more. Arctic's token object exposes methods (accessToken()), so wrap each client to the OAuthClient shape this package expects:

import * as arctic from "arctic";
import { OAuthSubstrate, type OAuthClient } from "@happy-technologies/connector-core";

function wrap(provider: {
  createAuthorizationURL: (state: string, codeVerifier: string, scopes: string[]) => URL;
  validateAuthorizationCode: (code: string, codeVerifier: string) => Promise<arctic.OAuth2Tokens>;
  refreshAccessToken: (refreshToken: string, scopes?: string[]) => Promise<arctic.OAuth2Tokens>;
}): OAuthClient {
  const toTokens = (t: arctic.OAuth2Tokens) => ({
    accessToken: t.accessToken(),
    refreshToken: t.hasRefreshToken() ? t.refreshToken() : undefined,
    accessTokenExpiresAt: t.accessTokenExpiresAt(),
  });
  return {
    createAuthorizationURL: (state, verifier, scopes) =>
      provider.createAuthorizationURL(state, verifier, scopes),
    validateAuthorizationCode: async (code, verifier) =>
      toTokens(await provider.validateAuthorizationCode(code, verifier)),
    refreshAccessToken: async (refreshToken, scopes) =>
      toTokens(await provider.refreshAccessToken(refreshToken, scopes)),
  };
}

const google = new arctic.Google(clientId, clientSecret, redirectUri);

const oauth = new OAuthSubstrate({
  clients: new Map([["google", wrap(google)]]),
  credentials: myCredentialStore, // backed by your DB + envelope crypto
  cipher: myEnvelopeCipher,        // encryptSecret / decryptSecret
});

// In a fetch path:
const cred = await oauth.resolve(sourceId);
const res = await fetch(url, { headers: cred.headers });

For client-credentials / app-only grants (Microsoft Graph app-only, ServiceNow service accounts), implement OAuthClient directly over a token endpoint, or use openid-client.

Scripts

  • bun test runs the unit suite.
  • bun run type-check runs tsc --noEmit.
  • bun run build emits dist/ with declarations.
  • bun run check:no-em-dash enforces the org content rule.

Status

v0.1: substrate core (descriptor, registry, validation, auth, document contract) with tests. Consumed first by Happy Knowledge; HappyCMDB's existing framework migrates onto the same manifest schema over time.