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

@okeav/idp-core-postgres

v0.1.1

Published

PostgreSQL storage adapter for @okeav/idp-core.

Downloads

26

Readme

@okeav/idp-core-postgres

A PostgreSQL storage adapter for @okeav/idp-core — implements all 8 storage repository interfaces (users, sessions, OAuth2 authorization codes/clients/consents, verification tokens, service keys, WebAuthn credentials) against a plain relational schema, using nothing but pg (no ORM).

Install

npm install @okeav/idp-core-postgres pg

Usage

@okeav/idp-core doesn't know this package exists — you wire it in yourself via config.storage.factory, a small seam idp-core exposes specifically so non-Mongo adapters can plug in without idp-core ever importing them:

import { initIdentityProvider } from '@okeav/idp-core';
import { createPostgresStorage, runMigrations } from '@okeav/idp-core-postgres';
import pg from 'pg';

// Run once, at deploy time — NOT automatically by createPostgresStorage().
const migrationPool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
await runMigrations(migrationPool);
await migrationPool.end();

await initIdentityProvider({
  issuer: 'https://idp.example.com',
  // No config.mongo at all — storage.factory replaces it entirely.
  storage: {
    factory: (resolvedConfig, emailDeps) =>
      createPostgresStorage({ pool: { connectionString: process.env.DATABASE_URL } }, emailDeps),
  },
  signingKeys: { keys: { /* ... */ } },
  security: { emailHashPepper: '...', tokenHashSecret: '...' },
  // ...everything else is identical to the Mongo-backed quickstart.
});

Migrations

Raw .sql files under src/migrations/sql/, applied in order by runMigrations(pool), tracked in an idp_schema_migrations table. Not run automatically by createPostgresStorage() — call it explicitly at your own deploy/startup step (concurrent DDL from multiple instances booting at once is a real risk otherwise). createPostgresStorage() does a cheap read-only check on startup that the expected migrations have actually been applied, and throws an actionable error if not; set config.skipMigrationCheck: true to skip that round trip (e.g. a CI job reusing a known-good database).

Schema notes

  • Primary keys are application-generated UUIDs (crypto.randomUUID()) — no pgcrypto/uuid-ossp extension required, since some managed Postgres hosts restrict CREATE EXTENSION.
  • Two of idp-core's Mongo-shaped embedded arrays became real join tables here, since they're looked up by more than "give me the whole document": idp_user_external_providers (SSO-linked identities, looked up by provider+providerId) and idp_user_recovery_codes (MFA recovery codes, consumed by positional index — reconstructed in position order).
  • idp_oauth_clients.client_secret_hash has no database-level "hide by default" — every query lists its columns explicitly and only includes the secret hash when asked ({ includeSecret: true }). Don't change any repository query to SELECT *.
  • Unlike MongoDB, Postgres has no native TTL index — pruneExpired() on sessions/authorization-codes/verification-tokens is a real delete here, not a no-op. Schedule it yourself (cron/interval); idp-core never calls it automatically.
  • createSessionForLogin (the composite write every login flow uses) runs as a real Postgres transaction — a single checked-out client, explicit BEGIN/COMMIT/ROLLBACK. Unlike the Mongo adapter, there's no deployment-topology gate to worry about (no replica-set requirement) — plain Postgres has supported multi-statement transactions unconditionally, always.

Testing

The test suite uses @electric-sql/pglite + @electric-sql/pglite-socket — a real, WASM-compiled Postgres running in-process, exposed over a genuine wire-protocol TCP socket, so repository code runs against an entirely unmodified pg.Pool. No Docker/container is required to run npm test.

npm test

What this package does not do

  • No connection pooling tuning beyond whatever you pass in config.pool (a plain pg.Pool config).
  • No automatic migrations, no automatic pruneExpired() scheduling — both are your app's responsibility.
  • No RBAC/authorization decisioning — same as idp-core itself; this package only implements storage.

License

MIT © Okeav