/** * Binary data reader tuned for decoding the Postgres wire protocol. * * @see https://github.com/brianc/node-postgres/blob/54eb0fa216aaccd727765641e7d1cf5da2bc483d/packages/pg-protocol/src/buffer-reader.ts */ declare class BufferReader { private offset; private buffer; private decoder; constructor(offset?: number); setBuffer(buffer: Uint8Array, offset?: number): void; int16(): number; byte(): number; int32(): number; string(length: number): string; cstring(): string; bytes(length: number): Uint8Array; } /** * binary data BufferWriter tuned for encoding binary specific to the postgres binary protocol * * @see https://github.com/brianc/node-postgres/blob/54eb0fa216aaccd727765641e7d1cf5da2bc483d/packages/pg-protocol/src/buffer- BufferWriter.ts */ declare class BufferWriter { private size; private buffer; private offset; private headerPosition; private encoder; constructor(size?: number); private ensure; addInt32(num: number): BufferWriter; addInt16(num: number): BufferWriter; addCString(string: string): BufferWriter; addString(string?: string): BufferWriter; add(otherBuffer: Uint8Array): BufferWriter; private join; flush(code?: number): Uint8Array; } type ClientParameters = { user: string; [key: string]: string; }; type TlsInfo = { serverName?: string; clientCertificate?: Uint8Array; }; declare const ServerStep: { readonly AwaitingInitialMessage: "AwaitingInitialMessage"; readonly PerformingAuthentication: "PerformingAuthentication"; readonly ReadyForQuery: "ReadyForQuery"; }; type ServerStep = (typeof ServerStep)[keyof typeof ServerStep]; type ConnectionState = { hasStarted: boolean; isAuthenticated: boolean; clientParams?: ClientParameters; tlsInfo?: TlsInfo; step: ServerStep; }; declare const tlsUpgradeSignal: unique symbol; declare const closeSignal: unique symbol; type TlsUpgradeSignal = typeof tlsUpgradeSignal; type CloseSignal = typeof closeSignal; type ConnectionSignal = TlsUpgradeSignal | CloseSignal; interface AuthFlow { createInitialAuthMessage(): Uint8Array | undefined; handleClientMessage(message: BufferSource): AsyncGenerator; isCompleted: boolean; } declare abstract class BaseAuthFlow implements AuthFlow { protected reader: BufferReader; protected writer: BufferWriter; protected connectionState: ConnectionState; constructor(params: { reader: BufferReader; writer: BufferWriter; connectionState: ConnectionState; }); abstract createInitialAuthMessage(): Uint8Array | undefined; abstract handleClientMessage(message: BufferSource): AsyncGenerator; abstract get isCompleted(): boolean; } type CertAuthOptions = { method: 'cert'; validateCredentials?: (credentials: { username: string; certificate: Uint8Array; }, connectionState: ConnectionState) => boolean | Promise; }; type Md5AuthOptions = { method: 'md5'; validateCredentials?: (credentials: { username: string; preHashedPassword: string; salt: Uint8Array; hashedPassword: string; }, connectionState: ConnectionState) => boolean | Promise; getPreHashedPassword: (credentials: { username: string; }, connectionState: ConnectionState) => string | Promise; }; declare class Md5AuthFlow extends BaseAuthFlow { private auth; private username; private salt; private completed; constructor(params: { auth: Md5AuthOptions; username: string; reader: BufferReader; writer: BufferWriter; connectionState: ConnectionState; }); handleClientMessage(message: Uint8Array): AsyncGenerator; createInitialAuthMessage(): Uint8Array; get isCompleted(): boolean; /** * Creates the authentication response. * * @see https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-FLOW-START-UP */ private createAuthenticationMD5Password; } /** * Hashes a password using Postgres' nested MD5 algorithm. * * @see https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-FLOW-START-UP */ declare function hashPreHashedPassword(preHashedPassword: string, salt: Uint8Array): Promise; /** * Computes the MD5 hash of the given value. */ declare function md5(value: string | Uint8Array): Promise; /** * Generates a random 4-byte salt for MD5 hashing. */ declare function generateMd5Salt(): Uint8Array; declare function createPreHashedPassword(username: string, password: string): Promise; type ClearTextPassword = string; type PasswordAuthOptions = { method: 'password'; validateCredentials?: (credentials: { username: string; password: string; clearTextPassword: ClearTextPassword; }, connectionState: ConnectionState) => boolean | Promise; getClearTextPassword: (params: { username: string; }, connectionState: ConnectionState) => ClearTextPassword | Promise; }; declare class SaslMechanism { writer: BufferWriter; constructor(params: { writer: BufferWriter; }); createAuthenticationSASL(): Uint8Array; createAuthenticationSASLContinue(message: string): Uint8Array; createAuthenticationSASLFinal(message: string): Uint8Array; } type ScramSha256Data = { salt: string; iterations: number; storedKey: string; serverKey: string; }; type ScramSha256AuthOptions = { method: 'scram-sha-256'; validateCredentials?: (params: { authMessage: string; clientProof: string; username: string; scramSha256Data: ScramSha256Data; }, connectionState: ConnectionState) => boolean | Promise; getScramSha256Data: (params: { username: string; }, connectionState: ConnectionState) => ScramSha256Data | Promise; }; /** * Creates scram-sha-256 data for password authentication. * @see https://www.postgresql.org/docs/current/sasl-authentication.html */ declare function createScramSha256Data(password: string, iterations?: number): Promise; /** * Verifies a scram-sha-256 password using the provided parameters. * @see https://www.postgresql.org/docs/current/sasl-authentication.html */ declare function verifyScramSha256Password(params: { authMessage: string; clientProof: string; storedKey: string; }): Promise; declare const ScramSha256Step: { readonly Initial: "Initial"; readonly ServerFirstMessage: "ServerFirstMessage"; readonly ServerFinalMessage: "ServerFinalMessage"; readonly Completed: "Completed"; }; type ScramSha256Step = (typeof ScramSha256Step)[keyof typeof ScramSha256Step]; declare class ScramSha256AuthFlow extends SaslMechanism implements AuthFlow { auth: ScramSha256AuthOptions & { validateCredentials: NonNullable; }; username: string; clientFirstMessageBare?: string; serverFirstMessage?: string; serverNonce?: string; step: ScramSha256Step; reader: BufferReader; scramSha256Data?: ScramSha256Data; connectionState: ConnectionState; constructor(params: { auth: ScramSha256AuthOptions; username: string; reader: BufferReader; writer: BufferWriter; connectionState: ConnectionState; }); /** * Get the scram-sha-256 data for the username. * This function is cached to always return the same data as we are generating random values in createScramSha256Data. */ getScramSha256Data(params: { username: string; }): Promise; createInitialAuthMessage(): Uint8Array; handleClientMessage(message: BufferSource): AsyncGenerator; handleClientFirstMessage(message: BufferSource): AsyncGenerator; createServerFirstMessage(clientFirstMessage: string): Promise; handleClientFinalMessage(message: BufferSource): AsyncGenerator; get isCompleted(): boolean; createServerFinalMessage(message: BufferSource): Promise; } type TrustAuthOptions = { method: 'trust'; }; type AuthOptions = TrustAuthOptions | PasswordAuthOptions | Md5AuthOptions | ScramSha256AuthOptions | CertAuthOptions; /** * Handles buffering of messages for a connection */ declare class MessageBuffer { private buffer; private bufferLength; private bufferOffset; /** * Merges a new buffer into the existing buffer * * @see https://github.com/brianc/node-postgres/blob/54eb0fa216aaccd727765641e7d1cf5da2bc483d/packages/pg-protocol/src/parser.ts#L121-L152 */ mergeBuffer(newData: Uint8Array): void; /** * Processes incoming data by buffering it and parsing messages. * * @see https://github.com/brianc/node-postgres/blob/54eb0fa216aaccd727765641e7d1cf5da2bc483d/packages/pg-protocol/src/parser.ts#L91-L119 */ processMessages(hasStarted: boolean): AsyncGenerator; } declare function getMessages(data: Uint8Array): Generator; interface DuplexStream { readable: ReadableStream; writable: WritableStream; } /** * A passthrough `DuplexStream` that buffers data to support * asynchronous reads and writes. */ declare class BufferedStream implements DuplexStream { readable: ReadableStream; writable: WritableStream; constructor(); } /** * Creates a pair of linked duplex streams. * * The returned duplex streams are interconnected such that writing to the * writable stream of one duplex will result in the data appearing on the * readable stream of the other duplex, and vice versa. This can be useful * for simulating a bidirectional communication channel or virtual socket. */ declare function createDuplexPair(): [DuplexStream, DuplexStream]; /** * Creates a virtual server that can accept multiple duplex stream connections. * * The server allows clients to connect via a `connect()` method, returning a * `DuplexStream` representing the client side of the connection. The server * side of each connection can be accessed by reading from the stream returned * by the `listen()` method. * * This is useful for simulating network servers, testing bidirectional * communication channels, or creating virtual sockets where data flow * can be controlled and observed. * * @returns An object containing `connect()` to initiate a connection and * `listen()` to retrieve the server side of the connections. */ declare function createVirtualServer(): { listen: () => ReadableStream>; connect: () => Promise>; }; /** * Converts a `ReadableStream` to an `AsyncIterator`. * * Note that `ReadableStream` is supposed to implement `AsyncIterable` * already, but this isn't true for all environments today (eg. Safari). * * Use this method as a ponyfill. */ declare function toAsyncIterator(readable: ReadableStream, options?: { preventCancel?: boolean; }): AsyncIterableIterator; type TlsOptions = { key: ArrayBuffer; cert: ArrayBuffer; ca?: ArrayBuffer; passphrase?: string; }; type TlsOptionsCallback = (serverName?: string) => TlsOptions | Promise; type PostgresConnectionOptions = { /** * The server version to send to the frontend. */ serverVersion?: string | ((state: ConnectionState) => string | Promise); /** * The authentication mode for the server. */ auth?: AuthOptions; /** * TLS options for when clients send an SSLRequest. */ tls?: TlsOptions | TlsOptionsCallback; /** * Callback after the connection has been upgraded to TLS. * * Includes `state` which holds connection information gathered so far like `tlsInfo`. * * This will be called before the startup message is received from the frontend * (if TLS is being used) so is a good place to establish proxy connections if desired. */ onTlsUpgrade?(state: ConnectionState): void | Promise; /** * Callback after the initial startup message has been received from the frontend. * * Includes `state` which holds connection information gathered so far like `clientInfo`. * * This is called after the connection is upgraded to TLS (if TLS is being used) * but before authentication messages are sent to the frontend. * */ onStartup?(state: ConnectionState): void | Promise; /** * Callback after a successful authentication has completed. * * Includes `state` which holds connection information gathered so far. */ onAuthenticated?(state: ConnectionState): void | Promise; /** * Callback for every message received from the frontend. * Use this as an escape hatch to manually handle raw message data. * * Includes `state` which holds connection information gathered so far and * can be used to understand where the protocol is at in its lifecycle. * * Callback can optionally return raw `Uint8Array` response data that will * be sent back to the client. It can also return multiple `Uint8Array` * responses via an `Iterable` or `AsyncIterable`. * This means you can turn this hook into a generator function to * asynchronously stream responses back to the client. * * **Warning:** By managing the message yourself (returning data), you bypass further * processing by the `PostgresConnection` which means some state may not be collected * and hooks won't be called depending on where the protocol is at in its lifecycle. * If you wish to hook into messages without bypassing further processing, do not return * any data from this callback. */ onMessage?(data: Uint8Array, state: ConnectionState): MessageResponse | Promise; /** * Callback for every frontend query message. * Use this to implement query handling. * * If left `undefined`, an error will be sent to the frontend * indicating that queries aren't implemented. * * TODO: change return signature to be more developer-friendly * and then translate to wire protocol. */ onQuery?(query: string, state: ConnectionState): Uint8Array | Promise; }; /** * Platform-specific adapters for handling features like TLS upgrades. * * Some platform helpers like `fromNodeSocket()` will implement these * for you. */ type PostgresConnectionAdapters = { /** * Implements the TLS upgrade logic for the stream. */ upgradeTls?(duplex: DuplexStream, options: TlsOptions | TlsOptionsCallback, requestCert?: boolean): Promise<{ duplex: DuplexStream; tlsInfo: TlsInfo; }>; }; type MessageResponse = undefined | Uint8Array | Iterable | AsyncIterable; declare class PostgresConnection { duplex: DuplexStream; adapters: PostgresConnectionAdapters; private step; options: PostgresConnectionOptions & { auth: NonNullable; }; authFlow?: AuthFlow; hasStarted: boolean; isAuthenticated: boolean; detached: boolean; bufferWriter: BufferWriter; bufferReader: BufferReader; clientParams?: ClientParameters; tlsInfo?: TlsInfo; messageBuffer: MessageBuffer; streamWriter?: WritableStreamDefaultWriter; constructor(duplex: DuplexStream, options?: PostgresConnectionOptions, adapters?: PostgresConnectionAdapters); get state(): ConnectionState; init(duplex: DuplexStream): Promise; /** * Detaches the `PostgresConnection` from the stream. * After calling this, data will no longer be buffered * and all processing will halt. * * Useful when proxying. You can detach at a certain point * (like TLS upgrade) to prevent further buffering/processing * when your goal is to pipe future messages downstream. */ detach(): Promise>; processData(duplex: DuplexStream): Promise; handleClientMessage(message: Uint8Array): AsyncGenerator; handleSslRequest(): AsyncGenerator; handleStartupMessage(message: BufferSource): AsyncGenerator; handleAuthenticationMessage(message: BufferSource): AsyncGenerator; private handleRegularMessage; /** * Checks if the given message is a valid SSL request. * * @see https://www.postgresql.org/docs/current/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-SSLREQUEST */ private isSslRequest; /** * Checks if the given message is a valid StartupMessage. * * @see https://www.postgresql.org/docs/current/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-STARTUPMESSAGE */ private isStartupMessage; /** * Completes authentication by forwarding the appropriate messages * to the frontend. */ completeAuthentication(): AsyncGenerator; /** * Parses a startup message from the frontend. * * @see https://www.postgresql.org/docs/current/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-STARTUPMESSAGE */ readStartupMessage(): { majorVersion: number; minorVersion: number; parameters: Record; }; /** * Parses a query message from the frontend. * * @see https://www.postgresql.org/docs/current/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-QUERY */ readQuery(): { query: string; }; /** * Creates an "AuthenticationOk" message. * * @see https://www.postgresql.org/docs/current/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONOK */ createAuthenticationOk(): Uint8Array; /** * Creates a "ParameterStatus" message. * Informs the frontend about the current setting of backend parameters. * * @see https://www.postgresql.org/docs/current/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-PARAMETERSTATUS * @see https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-ASYNC */ createParameterStatus(name: string, value: string): Uint8Array; /** * Creates a "ReadyForQuery" message. * * @see https://www.postgresql.org/docs/current/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-READYFORQUERY */ createReadyForQuery(transactionStatus?: 'idle' | 'transaction' | 'error'): Uint8Array; createAuthenticationFailedError(): Uint8Array; } export { BufferedStream as B, type ClientParameters as C, type DuplexStream as D, type MessageResponse as M, PostgresConnection as P, ServerStep as S, type TlsOptions as T, type TlsOptionsCallback as a, type PostgresConnectionOptions as b, type PostgresConnectionAdapters as c, type TlsInfo as d, type ConnectionState as e, type ScramSha256Data as f, type ScramSha256AuthOptions as g, createScramSha256Data as h, ScramSha256AuthFlow as i, type Md5AuthOptions as j, Md5AuthFlow as k, hashPreHashedPassword as l, md5 as m, generateMd5Salt as n, createPreHashedPassword as o, createDuplexPair as p, createVirtualServer as q, MessageBuffer as r, getMessages as s, toAsyncIterator as t, tlsUpgradeSignal as u, verifyScramSha256Password as v, closeSignal as w, type TlsUpgradeSignal as x, type CloseSignal as y, type ConnectionSignal as z };