@probitas/client-sql-postgres

PostgreSQL client for Probitas scenario testing framework.

This package provides a PostgreSQL client designed for integration testing, with transaction support and LISTEN/NOTIFY capabilities.

Features

  • Query Execution: Parameterized queries with type-safe results
  • Transactions: Full transaction support with isolation levels
  • LISTEN/NOTIFY: Real-time notifications for async testing
  • COPY Protocol: High-performance bulk data loading
  • Connection Pooling: Configurable pool with idle timeout
  • Resource Management: Implements AsyncDisposable for proper cleanup

Installation

deno add jsr:@probitas/client-sql-postgres

Quick Start

import { createPostgresClient } from "@probitas/client-sql-postgres";

const client = await createPostgresClient({
  url: "postgres://user:pass@localhost:5432/mydb",
});

// Query with parameters
const result = await client.query<{ id: number; name: string }>(
  "SELECT id, name FROM users WHERE active = $1",
  [true]
);
console.log(result.rows);

// Get first row
const user = await client.queryOne<{ id: number; name: string }>(
  "SELECT * FROM users WHERE id = $1",
  [1]
);

await client.close();

Transactions

import { createPostgresClient } from "@probitas/client-sql-postgres";
import type { SqlTransaction } from "@probitas/client-sql";

const client = await createPostgresClient({
  url: "postgres://localhost:5432/testdb",
});

await client.transaction(async (tx: SqlTransaction) => {
  await tx.query("INSERT INTO accounts (id, balance) VALUES ($1, $2)", [1, 100]);
  await tx.query("INSERT INTO accounts (id, balance) VALUES ($1, $2)", [2, 200]);
  // Automatically committed if no error, rolled back on exception
}, { isolationLevel: "serializable" });

await client.close();

LISTEN/NOTIFY

import { createPostgresClient } from "@probitas/client-sql-postgres";

const client = await createPostgresClient({
  url: "postgres://localhost:5432/testdb",
});

// Listen for notifications
const listener = await client.listen("events");
for await (const notification of listener) {
  console.log("Received:", notification.payload);
  break;
}

// Send notification
await client.notify("events", JSON.stringify({ type: "created", id: 123 }));

await client.close();

Using with using Statement

import { createPostgresClient } from "@probitas/client-sql-postgres";

await using client = await createPostgresClient({
  url: "postgres://localhost:5432/testdb",
});

const result = await client.query("SELECT 1 as n");
// Client automatically closed when block exits
PackageDescription
`@probitas/client-sql`Common SQL types and utilities
`@probitas/client-sql-mysql`MySQL client
`@probitas/client-sql-sqlite`SQLite client
`@probitas/client-sql-duckdb`DuckDB client

Installation

deno add jsr:@probitas/client-sql-postgres

Classes

class

#ConstraintError

class ConstraintError extends SqlError
ExtendsSqlError

Error thrown when a constraint violation occurs.

NameDescription
name
kind
constraint
Constructor
new ConstraintError(
  message: string,
  constraint: string,
  options?: SqlErrorOptions,
)
Properties
  • readonlynamestring
  • readonlykind"constraint"
  • readonlyconstraintstring
class

#DeadlockError

class DeadlockError extends SqlError
ExtendsSqlError

Error thrown when a deadlock is detected.

NameDescription
name
kind
Constructor
new DeadlockError(message: string, options?: SqlErrorOptions)
Properties
  • readonlynamestring
  • readonlykind"deadlock"
class

#PostgresTransaction

class PostgresTransaction implements SqlTransaction
ImplementsSqlTransaction

PostgreSQL transaction implementation.

Wraps a postgres.js reserved connection to provide transaction semantics.

NameDescription
query()Execute a query within the transaction.
queryOne()Execute a query and return the first row or undefined.
commit()Commit the transaction.
rollback()Rollback the transaction.
Constructor
new PostgresTransaction(sql: postgres.ReservedSql)

Creates a new PostgresTransaction.

Methods
query(): unknown

Execute a query within the transaction.

queryOne(): unknown

Execute a query and return the first row or undefined.

commit(): unknown

Commit the transaction.

rollback(): unknown

Rollback the transaction.

class

#QuerySyntaxError

class QuerySyntaxError extends SqlError
ExtendsSqlError

Error thrown when a SQL query has syntax errors.

NameDescription
name
kind
Constructor
new QuerySyntaxError(message: string, options?: SqlErrorOptions)
Properties
  • readonlynamestring
  • readonlykind"query"
class

#SqlConnectionError

class SqlConnectionError extends SqlError
ExtendsSqlError

Error thrown when a connection or network-level error occurs.

This includes:

  • Connection refused (server not running)
  • Authentication failure
  • Connection timeout
  • Pool exhaustion
  • TLS handshake failure
  • DNS resolution failure
NameDescription
name
kind
Constructor
new SqlConnectionError(message: string, options?: SqlErrorOptions)
Properties
  • readonlynamestring
  • readonlykind"connection"
class

#SqlError

class SqlError extends ClientError

Base error class for SQL-specific errors. Extends ClientError with SQL-specific properties.

NameDescription
name
kind
sqlState
Constructor
new SqlError(message: string, kind: SqlErrorKind, options?: SqlErrorOptions)
Properties
  • readonlynamestring
  • readonlykindSqlErrorKind
  • readonlysqlStatestring | null

Interfaces

interface

#PostgresClient

interface PostgresClient extends AsyncDisposable

PostgreSQL client interface.

NameDescription
configThe client configuration.
dialectThe database dialect.
query()Execute a SQL query.
queryOne()Execute a query and return the first row or undefined.
transaction()Execute a function within a transaction.
copyFrom()Copy data from an iterable into a table using PostgreSQL COPY protocol.
copyTo()Copy data from a query result using PostgreSQL COPY protocol.
listen()Listen for notifications on a channel.
notify()Send a notification on a channel.
close()Close the client and release all connections.
Properties
  • readonlyconfigPostgresClientConfig

    The client configuration.

  • readonlydialect"postgres"

    The database dialect.

Methods
query<T = Record<string, any>>(
  sql: string,
  params?: unknown[],
  options?: SqlQueryOptions,
): Promise<SqlQueryResult<T>>

Execute a SQL query.

Parameters
  • sqlstring
    • SQL query string
  • params?unknown[]
    • Optional query parameters
    • Optional query options
queryOne<T = Record<string, any>>(
  sql: string,
  params?: unknown[],
  options?: SqlQueryOptions,
): Promise<T | undefined>

Execute a query and return the first row or undefined.

Parameters
  • sqlstring
    • SQL query string
  • params?unknown[]
    • Optional query parameters
    • Optional query options
transaction<T>(
  fn: (tx: SqlTransaction) => unknown,
  options?: SqlTransactionOptions,
): Promise<T>

Execute a function within a transaction.

The transaction is automatically committed if the function completes successfully, or rolled back if the function throws an error.

Parameters
copyFrom(table: string, data: AsyncIterable<unknown[]>): Promise<number>

Copy data from an iterable into a table using PostgreSQL COPY protocol.

Parameters
  • tablestring
    • Target table name
  • dataAsyncIterable<unknown[]>
    • Async iterable of row arrays
copyTo(query: string): AsyncIterable<unknown[]>

Copy data from a query result using PostgreSQL COPY protocol.

Parameters
  • querystring
    • SQL query to copy from
listen(channel: string): AsyncIterable<PostgresNotification>

Listen for notifications on a channel.

Parameters
  • channelstring
    • Channel name to listen on
notify(channel: string, payload?: string): Promise<void>

Send a notification on a channel.

Parameters
  • channelstring
    • Channel name
  • payload?string
    • Optional notification payload
close(): Promise<void>

Close the client and release all connections.

interface

#PostgresClientConfig

interface PostgresClientConfig extends CommonOptions

Configuration for creating a PostgreSQL client.

NameDescription
urlConnection URL string or configuration object.
poolPool configuration
applicationNameApplication name for PostgreSQL connection
throwOnErrorWhether to throw an error for query failures.
Properties
  • readonlyurlstring | PostgresConnectionConfig

    Connection URL string or configuration object.

  • readonlypool?PostgresPoolConfig

    Pool configuration

  • readonlyapplicationName?string

    Application name for PostgreSQL connection

  • readonlythrowOnError?boolean

    Whether to throw an error for query failures. When false, failures are returned as SqlQueryResultError or SqlQueryResultFailure. Can be overridden per-query via SqlQueryOptions.

interface

#PostgresConnectionConfig

interface PostgresConnectionConfig extends CommonConnectionConfig

PostgreSQL connection configuration.

Extends CommonConnectionConfig with PostgreSQL-specific options.

NameDescription
databaseDatabase name to connect to.
sslSSL/TLS configuration.
Properties
  • readonlydatabase?string

    Database name to connect to.

  • readonlyssl?boolean | PostgresSslConfig

    SSL/TLS configuration.

interface

#PostgresErrorLike

interface PostgresErrorLike

PostgreSQL error structure from the driver.

NameDescription
message
code
constraint
Properties
  • readonlymessagestring
  • readonlycode?string
  • readonlyconstraint?string
interface

#PostgresNotification

interface PostgresNotification

PostgreSQL LISTEN/NOTIFY notification.

NameDescription
channelChannel name
payloadNotification payload
processIdProcess ID of the notifying backend
Properties
  • readonlychannelstring

    Channel name

  • readonlypayloadstring

    Notification payload

  • readonlyprocessIdnumber

    Process ID of the notifying backend

interface

#PostgresPoolConfig

interface PostgresPoolConfig

Pool configuration for PostgreSQL.

NameDescription
maxMaximum number of connections in the pool
idleTimeoutIdle timeout in milliseconds before closing unused connections
connectTimeoutConnection timeout in milliseconds
Properties
  • readonlymax?number

    Maximum number of connections in the pool

  • readonlyidleTimeout?number

    Idle timeout in milliseconds before closing unused connections

  • readonlyconnectTimeout?number

    Connection timeout in milliseconds

interface

#PostgresSslConfig

interface PostgresSslConfig

SSL/TLS configuration for PostgreSQL connection.

NameDescription
rejectUnauthorizedWhether to reject unauthorized certificates.
caCA certificate(s) for verification.
certClient certificate for mutual TLS.
keyClient private key for mutual TLS.
Properties
  • readonlyrejectUnauthorized?boolean

    Whether to reject unauthorized certificates.

  • readonlyca?string

    CA certificate(s) for verification.

  • readonlycert?string

    Client certificate for mutual TLS.

  • readonlykey?string

    Client private key for mutual TLS.

interface

#SqlErrorOptions

interface SqlErrorOptions extends ErrorOptions

Options for SqlError constructor.

NameDescription
sqlStateSQL State code (e.g., "23505" for unique violation)
Properties
  • readonlysqlState?string

    SQL State code (e.g., "23505" for unique violation)

interface

#SqlQueryOptions

interface SqlQueryOptions extends CommonOptions

Options for individual SQL queries.

NameDescription
throwOnErrorWhether to throw an error for query failures.
Properties
  • readonlythrowOnError?boolean

    Whether to throw an error for query failures. When false, failures are returned as SqlQueryResultError or SqlQueryResultFailure.

interface

#SqlQueryResultError

interface SqlQueryResultError<T = any> extends SqlQueryResultBase<T>

SQL query result for query errors (syntax errors, constraint violations, etc.).

Server received and processed the query, but it failed due to a SQL error.

NameDescription
processedServer processed the query.
okQuery failed.
errorError describing the SQL error.
rowsEmpty rows for failed queries.
rowCountZero affected rows for failed queries.
lastInsertIdNo lastInsertId for failed queries.
warningsNo warnings for failed queries.
Properties
  • readonlyprocessedtrue

    Server processed the query.

  • readonlyokfalse

    Query failed.

  • readonlyerrorSqlError

    Error describing the SQL error.

  • readonlyrowsreadonly never[]

    Empty rows for failed queries.

  • readonlyrowCount0

    Zero affected rows for failed queries.

  • readonlylastInsertIdnull

    No lastInsertId for failed queries.

  • readonlywarningsnull

    No warnings for failed queries.

interface

#SqlQueryResultFailure

interface SqlQueryResultFailure<T = any> extends SqlQueryResultBase<T>

SQL query result for connection failures (network errors, timeouts, etc.).

Query could not be processed by the server (connection refused, timeout, pool exhausted, authentication failure, etc.).

NameDescription
processedServer did not process the query.
okQuery failed.
errorError describing the failure.
rowsNo rows (query didn't reach server).
rowCountNo row count (query didn't reach server).
lastInsertIdNo lastInsertId (query didn't reach server).
warningsNo warnings (query didn't reach server).
Properties
  • readonlyprocessedfalse

    Server did not process the query.

  • readonlyokfalse

    Query failed.

  • readonlyerrorSqlFailureError

    Error describing the failure.

  • readonlyrowsnull

    No rows (query didn't reach server).

  • readonlyrowCountnull

    No row count (query didn't reach server).

  • readonlylastInsertIdnull

    No lastInsertId (query didn't reach server).

  • readonlywarningsnull

    No warnings (query didn't reach server).

interface

#SqlQueryResultSuccess

interface SqlQueryResultSuccess<T = any> extends SqlQueryResultBase<T>

SQL query result for successful queries.

The query was executed successfully and returned results.

NameDescription
processedServer processed the query.
okQuery succeeded.
errorNo error for successful queries.
rowsQuery result rows.
rowCountNumber of affected rows.
lastInsertIdLast inserted ID (for INSERT statements).
warningsWarning messages from the database.
Properties
  • readonlyprocessedtrue

    Server processed the query.

  • readonlyoktrue

    Query succeeded.

  • readonlyerrornull

    No error for successful queries.

  • readonlyrowsreadonly T[]

    Query result rows.

  • readonlyrowCountnumber

    Number of affected rows.

  • readonlylastInsertIdbigint | string | null

    Last inserted ID (for INSERT statements).

  • readonlywarningsunknown | null

    Warning messages from the database.

interface

#SqlQueryResultSuccessParams

interface SqlQueryResultSuccessParams<T = any>

Parameters for creating a SqlQueryResultSuccess.

NameDescription
rowsThe result rows
rowCountNumber of affected rows (for INSERT/UPDATE/DELETE)
durationQuery execution duration in milliseconds
lastInsertIdLast inserted ID (for INSERT statements)
warningsWarning messages from the database
Properties
  • readonlyrowsreadonly T[]

    The result rows

  • readonlyrowCountnumber

    Number of affected rows (for INSERT/UPDATE/DELETE)

  • readonlydurationnumber

    Query execution duration in milliseconds

  • readonlylastInsertId?bigint | string

    Last inserted ID (for INSERT statements)

  • readonlywarnings?readonly string[]

    Warning messages from the database

interface

#SqlTransaction

interface SqlTransaction

SQL transaction interface. Implementations should provide actual database-specific transaction handling.

NameDescription
query()Execute a query within the transaction.
queryOne()Execute a query and return the first row or undefined.
commit()Commit the transaction.
rollback()Rollback the transaction.
Methods
query<T = Record<string, any>>(
  sql: string,
  params?: unknown[],
  options?: SqlQueryOptions,
): Promise<SqlQueryResult<T>>

Execute a query within the transaction.

Parameters
  • sqlstring
    • SQL query string
  • params?unknown[]
    • Optional query parameters
    • Optional query options
queryOne<T = Record<string, any>>(
  sql: string,
  params?: unknown[],
  options?: SqlQueryOptions,
): Promise<T | undefined>

Execute a query and return the first row or undefined.

Parameters
  • sqlstring
    • SQL query string
  • params?unknown[]
    • Optional query parameters
    • Optional query options
commit(): Promise<void>

Commit the transaction.

rollback(): Promise<void>

Rollback the transaction.

interface

#SqlTransactionOptions

interface SqlTransactionOptions

Options for starting a transaction.

NameDescription
isolationLevelIsolation level for the transaction
Properties

Functions

function

#createPostgresClient

async function createPostgresClient(
  config: PostgresClientConfig,
): Promise<PostgresClient>

Create a new PostgreSQL client instance.

The client provides connection pooling, parameterized queries, transaction support, and PostgreSQL-specific features like COPY and LISTEN/NOTIFY.

Parameters
Returns

Promise<PostgresClient> — A promise resolving to a new PostgreSQL client instance

Examples

Using URL string

import { createPostgresClient } from "@probitas/client-sql-postgres";

const client = await createPostgresClient({
  url: "postgres://user:pass@localhost:5432/mydb",
});

const result = await client.query("SELECT * FROM users WHERE id = $1", [1]);
if (result.ok) {
  console.log(result.rows[0]);
}

await client.close();

Using connection config object

import { createPostgresClient } from "@probitas/client-sql-postgres";

const client = await createPostgresClient({
  url: {
    host: "localhost",
    port: 5432,
    database: "mydb",
    username: "user",
    password: "pass",
  },
  pool: { max: 10 },
  applicationName: "my-app",
});

await client.close();

Transaction with auto-commit/rollback

import { createPostgresClient } from "@probitas/client-sql-postgres";
import type { SqlTransaction } from "@probitas/client-sql";

const client = await createPostgresClient({
  url: "postgres://localhost:5432/mydb",
});

const user = await client.transaction(async (tx: SqlTransaction) => {
  await tx.query("INSERT INTO users (name) VALUES ($1)", ["John"]);
  return await tx.queryOne("SELECT * FROM users WHERE name = $1", ["John"]);
});

await client.close();

LISTEN/NOTIFY for real-time events

import { createPostgresClient } from "@probitas/client-sql-postgres";

const client = await createPostgresClient({
  url: "postgres://localhost:5432/mydb",
});

// Listen for notifications
for await (const notification of client.listen("user_events")) {
  console.log("Received:", notification.payload);
}

// In another session
await client.notify("user_events", JSON.stringify({ userId: 123 }));

await client.close();

Using await using for automatic cleanup

import { createPostgresClient } from "@probitas/client-sql-postgres";

await using client = await createPostgresClient({
  url: "postgres://localhost:5432/mydb",
});

const result = await client.query("SELECT 1");
// Client automatically closed when scope exits
function

#isConnectionError

function isConnectionError(error: PostgresErrorLike): boolean

Check if an error is a connection-level error based on SQLSTATE or error characteristics.

Parameters
function

#mapPostgresError

function mapPostgresError(error: PostgresErrorLike): SqlError

Maps a PostgreSQL error to the appropriate SqlError subclass.

Parameters
Returns

SqlError — Mapped SqlError or subclass

Types

type

#SqlErrorKind

type SqlErrorKind = "query" | "constraint" | "deadlock" | "connection" | "unknown"

SQL-specific error kinds.

type

#SqlFailureError

type SqlFailureError = SqlConnectionError | AbortError | TimeoutError

Error types that indicate the operation was not processed. These are errors that occur before the query reaches the SQL server.

type

#SqlIsolationLevel

type SqlIsolationLevel = "read_uncommitted" | "read_committed" | "repeatable_read" | "serializable"

Transaction isolation level.

type

#SqlOperationError

type SqlOperationError = QuerySyntaxError | ConstraintError | DeadlockError | SqlError

Error types that indicate an operation was processed by the server. These errors occur after the query reaches the SQL server.

type

#SqlQueryResult

type SqlQueryResult<T = any> = SqlQueryResultSuccess<T> | SqlQueryResultError<T> | SqlQueryResultFailure<T>

SQL query result union type representing all possible result states.

  • Success: processed: true, ok: true, error: null
  • Error: processed: true, ok: false, error: SqlError
  • Failure: processed: false, ok: false, error: SqlConnectionError
Search Documentation