@art-ws/db-context
v2.0.42
Published
db-context
Readme
@art-ws/db-context
Lightweight PostgreSQL database context utilities for TypeScript/Node ESM. Provides a small abstraction over pg with pooled connections, typed query helpers, and simple model helpers (select/insert/update/upsert/delete) without hiding SQL.
Installation
pnpm add @art-ws/db-contextWhat you get
DbContextBase: thin orchestrator that hands out models and queries using a shared client factory.DbModel<T>: convenience CRUD helpers for a table with paging/order-by and upsert support; still SQL-first.PgPoolsBase: cachedpgconnection pools with idle eviction.PgDbClient/PgDbQuery: promise-like query wrapper with.single(),.first(),.last(),.exec()helpers.- Type parsers: installs numeric/date/array parsers for
pgbuilt-ins.
Quick start
import { MemoryCacheBase } from "@art-ws/common"
import { DbContextBase, DbModel } from "@art-ws/db-context/db-context"
import { PgPoolsBase } from "@art-ws/db-context/pg"
import { PgDbClient } from "@art-ws/db-context/pg-db-client"
import { PgDbQuery } from "@art-ws/db-context/pg-db-client"
// 1) Configure pooled connections
const pools = new PgPoolsBase(new MemoryCacheBase({}), /* timeToIdle ms */ 60_000)
const dbClientFactory = async () =>
new PgDbClient(() => pools.acquire({
PGHOST: "localhost",
PGDATABASE: "app",
PGUSER: "postgres",
PGPASSWORD: "postgres",
PGPORT: 5432,
}))
// 2) Wire DbContext with a query factory
const dbContext = new DbContextBase<{ users: UsersModel }>(
dbClientFactory,
PgDbQuery.FACTORY
)
// 3) Define a model
type User = { id: number; email: string; name: string }
class UsersModel extends DbModel<User> {
constructor(ctx: DbContextBase<any>) {
super(ctx, {
table: "users",
columns: [
{ name: "id", isPrimaryKey: true },
{ name: "email" },
{ name: "name" },
],
})
}
}
// 4) Register the model factory
dbContext["users"] = new UsersModel(dbContext) as any
// 5) Run queries
const all = await dbContext.getDbModel<UsersModel>("users").findAll({ limit: 50 })
const inserted = await dbContext.getDbModel<UsersModel>("users").insert({ email: "[email protected]", name: "Ann" }).single()Core pieces
DbContextBasekeeps a sharedDbClient(lazy) and a map of factories for models.DbModel<T>offersfindAll,findById,findBy,insert,update,upsert,del, andselecthelpers. All returnDbQuery<T>so you can chain.single(),.first(),.exec(), or await as a Promise for rows.PgPoolsBasecachespgpools by connection key;timeToIdlecontrols eviction and callspool.end()when evicted.PgDbClientwraps aPoolClient, supportsdispose()(releases client).PgDbQueryis the default query implementation for PostgreSQL.
Notes & tips
- The library is SQL-first; write SQL strings directly. Helpers only reduce boilerplate.
- Uses ESM (
"type": "module") and NodeNext-friendly exports. Import with explicit.jspaths if your TS config requires it. - Type parsers for numeric/date/array types are installed on import of
pg-db-client. DbQueryimplementsPromiseLike, soawait querygives rows;.single()throws if row count != 1.timeToIdleshould roughly match your DB idle timeout to avoid leaked pools.
Minimal API reference
DbContextBase(dbClientFactory, dbQueryFactory)getDbModel<T>(name: string): TgetDbQuery<T>({ name, sql, params }): DbQuery<T>dispose()releases the underlying client
DbModel<T>(dbContext, meta)findAll(opts?),findById(id),findBy(values, opts?),insert(values),update(values, where?),upsert(values, { unique }),del(values)
PgPoolsBase(cache, timeToIdleMs)acquire(options: PgConnectionOptions): Promise<PoolClient>
PgDbClient(pgClientFactory)getUnderlying(),dispose(),cancel()
PgDbQuery.FACTORY(args)builds aDbQueryforpg
Testing
Tests are disabled in this package (pnpm test is a no-op). You can still write vitest suites in your consumer project.
License
UNLICENSED (see package.json).
