2.9 KiB
factory/create-db-adapter — direct-surface adapter factory
(no submodules)
Purpose
createDbAdapter is the public entry point for host code that wants to wire
the @suaveplan/db engine adapters to the plugin
AdminDatabaseLike / TenantScopedDatabaseLike surfaces. It composes three
pieces from this package — the options validator, the engine registry, and
the tenant-scope wrapper — into a single callable that delegates engine
identity to the open DatabaseEngineRegistry.
The result object exposes:
admin— the unscopedAdminDatabaseLike(used by migrations and admin endpoints).scoped(tenantId)— produces a freshTenantScopedDatabaseLikewrapper over the same admin connection. The wrapper is stateless beyond the rewrite contract, so one admin connection can back many tenant scopes concurrently.close()— closes the underlying admin connection.
Features
- Options are parsed once at factory time; the rest of the API is typed
against the post-parse
DbAdapterOptions. - Engine lookup is delegated to
buildEngineAdapter, so any declaration-merged engine works automatically. - Tenant scoping config (
tenantColumn,autoInjectInserts) flows from the parsed options into everyscoped()call — no per-call repetition.
Usage: Basic
import { createDbAdapter } from "@suaveplan/api-db-adapter/adapter";
import { registerEngine } from "@suaveplan/api-db-adapter/engine-registry";
registerEngine("sqlite", buildSqliteEngineFactory());
const db = await createDbAdapter({ engine: "sqlite", url: ":memory:" });
const admin = db.admin;
const acme = db.scoped("acme" as TenantId);
const rows = await acme.query("SELECT * FROM users");
await db.close();
Usage: Advanced
const db = await createDbAdapter({
engine: "postgres",
url: "postgres://app@db.local/app",
tenantColumn: "org_id",
autoInjectInserts: false,
pool: { min: 2, max: 16, idleMs: 60_000 },
});
const tx = await db.scoped(tenantId).transaction!(async (tx) => {
await tx.execute(
"INSERT INTO invoices (id, org_id, amount) VALUES (?, ?, ?)",
["inv_1", tenantId, 100]
);
return await tx.query<{ id: string }[]>("SELECT id FROM invoices");
});
API Reference
createDbAdapter(input: DbAdapterOptionsInput): Promise<DbAdapter>.DbAdapter.admin: AdminDatabaseLike.DbAdapter.scoped(tenantId: TenantId): TenantScopedDatabaseLike.DbAdapter.close(): Promise<void>.
Implementation Notes
The factory does NOT register engines on import — it expects the host or a
downstream adapter package to populate the registry before the first call.
This shape keeps @suaveplan/api-db-adapter universally importable and
prevents engine deps from leaking into bundles that never use them. Errors
surface synchronously where possible (options validation, engine lookup);
engine handshake errors arrive as the promise rejection.