UsefulKey

Drizzle ORM

Use Drizzle ORM as the keystore backend.

Overview

  • Keystore backed by your Drizzle ORM models. This adapter does not run DDL; manage migrations in your app.
  • Expects a table with columns matching KeyRecord fields and helpers (e.g., eq) for where clauses.
  • metadata can be stored natively (JSON/JSONB) or as TEXT via metadataMode.

Usage

import { DrizzleKeyStore, usefulkey } from "betterkey";
import { drizzle } from "drizzle-orm/postgres-js"; // or mysql2 / better-sqlite3
import { pgTable, text, bigint, integer, jsonb } from "drizzle-orm/pg-core";
import { eq } from "drizzle-orm";

export const keys = pgTable("usefulkey_keys", {
  id: text("id").primaryKey(),
  userId: text("user_id"),
  prefix: text("prefix").notNull(),
  keyHash: text("key_hash").notNull().unique(),
  createdAt: bigint({ mode: "number" }).notNull(),
  expiresAt: bigint({ mode: "number" }),
  metadata: jsonb("metadata"), // for sqlite: use text(...) and set metadataMode: "text"
  usesRemaining: integer("uses_remaining"),
  revokedAt: bigint({ mode: "number" }),
});

const db = drizzle(/* your driver */);
const keyStore = new DrizzleKeyStore(db, {
  schema: keys,
  helpers: { eq },
  // metadataMode: "native" | "text" (default native)
});

const uk = usefulkey({ adapters: { keyStore } });

Options

  • schema (required): your Drizzle table with columns named id, userId, prefix, keyHash, createdAt, expiresAt, metadata, usesRemaining, revokedAt.
  • helpers.eq (required): pass eq from drizzle-orm.
  • metadataMode (optional):
    • "native" (default): store objects directly (use JSON/JSONB columns in pg/mysql).
    • "text": serialize metadata as text; use this for sqlite or when you prefer TEXT.

Migrations

  • This adapter does not run migrations. Create the table and indexes via your Drizzle migrations (unique on key_hash, index on user_id).