import type { Pool, QueryResultRow } from "pg"; export interface QueryResult { rows: T[]; rowCount: number; } /** * Minimal executor contract. `pg.Pool` and `pg.PoolClient` both satisfy the * `query` method; the wrapper builds the rest on top so tests can substitute a * lightweight shim without pulling in a live Postgres. */ export interface PgExecutor { query(sql: string, params?: readonly unknown[]): Promise<{ rows: T[]; rowCount: number | null; }>; } export interface TypedQueryClient { query(sql: string, params?: readonly unknown[]): Promise>; many(sql: string, params?: readonly unknown[]): Promise; /** First row or `null`. Restored here after knowledge dropped it. */ get(sql: string, params?: readonly unknown[]): Promise; /** Exactly one row; throws if zero or more than one row is returned. */ one(sql: string, params?: readonly unknown[]): Promise; execute(sql: string, params?: readonly unknown[]): Promise; } /** Wrap any `PgExecutor` (a Pool, a PoolClient, or a test shim) with the typed vocabulary. */ export declare function wrapExecutor(executor: PgExecutor): TypedQueryClient; export interface PoolQueryClient extends TypedQueryClient { readonly pool: Pool; /** Run a callback inside a `BEGIN`/`COMMIT` transaction on a dedicated client. */ transaction(fn: (client: TypedQueryClient) => Promise): Promise; close(): Promise; } /** Build a `PoolQueryClient` around a live `pg.Pool`. */ export declare function createQueryClient(pool: Pool): PoolQueryClient;