postgrejs 3.11.1 → 3.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/connection/bind-param.d.ts +21 -0
- package/connection/bind-param.js +21 -0
- package/connection/connection.d.ts +136 -0
- package/connection/connection.js +132 -5
- package/connection/copy-stream.d.ts +2 -0
- package/connection/copy-stream.js +2 -0
- package/connection/cursor.d.ts +67 -5
- package/connection/cursor.js +88 -15
- package/connection/intl-connection.d.ts +22 -0
- package/connection/intl-connection.js +107 -17
- package/connection/large-object.d.ts +18 -0
- package/connection/large-object.js +17 -0
- package/connection/logical-replication.d.ts +15 -0
- package/connection/logical-replication.js +6 -0
- package/connection/pool.d.ts +80 -0
- package/connection/pool.js +82 -9
- package/connection/portal.d.ts +37 -0
- package/connection/portal.js +29 -0
- package/connection/prepared-statement.d.ts +109 -0
- package/connection/prepared-statement.js +150 -7
- package/constants.d.ts +18 -0
- package/constants.js +18 -0
- package/data-type-map.d.ts +38 -0
- package/data-type-map.js +38 -0
- package/data-types/bit-type.d.ts +4 -0
- package/data-types/bit-type.js +4 -0
- package/data-types/bool-type.d.ts +2 -0
- package/data-types/bool-type.js +2 -0
- package/data-types/box-type.d.ts +2 -0
- package/data-types/box-type.js +2 -0
- package/data-types/bytea-type.d.ts +2 -0
- package/data-types/bytea-type.js +2 -0
- package/data-types/char-type.d.ts +2 -0
- package/data-types/char-type.js +2 -0
- package/data-types/circle-type.d.ts +2 -0
- package/data-types/circle-type.js +2 -0
- package/data-types/date-type.d.ts +2 -0
- package/data-types/date-type.js +2 -0
- package/data-types/float4-type.d.ts +2 -0
- package/data-types/float4-type.js +2 -0
- package/data-types/float8-type.d.ts +2 -0
- package/data-types/float8-type.js +2 -0
- package/data-types/inet-type.d.ts +4 -0
- package/data-types/inet-type.js +4 -0
- package/data-types/int2-type.d.ts +2 -0
- package/data-types/int2-type.js +3 -1
- package/data-types/int2-vector-type.d.ts +2 -0
- package/data-types/int2-vector-type.js +2 -0
- package/data-types/int4-type.d.ts +2 -0
- package/data-types/int4-type.js +3 -1
- package/data-types/int8-type.d.ts +2 -0
- package/data-types/int8-type.js +4 -2
- package/data-types/interval-type.d.ts +9 -0
- package/data-types/interval-type.js +9 -0
- package/data-types/json-type.d.ts +2 -0
- package/data-types/json-type.js +2 -0
- package/data-types/jsonb-type.d.ts +2 -0
- package/data-types/jsonb-type.js +2 -0
- package/data-types/jsonpath-type.d.ts +2 -0
- package/data-types/jsonpath-type.js +2 -0
- package/data-types/line-type.d.ts +2 -0
- package/data-types/line-type.js +2 -0
- package/data-types/lseg-type.d.ts +2 -0
- package/data-types/lseg-type.js +2 -0
- package/data-types/macaddr-type.d.ts +4 -0
- package/data-types/macaddr-type.js +4 -0
- package/data-types/money-type.d.ts +1 -0
- package/data-types/money-type.js +17 -10
- package/data-types/numeric-type.d.ts +2 -0
- package/data-types/numeric-type.js +2 -0
- package/data-types/oid-type.d.ts +2 -0
- package/data-types/oid-type.js +3 -1
- package/data-types/oid-vector-type.d.ts +1 -0
- package/data-types/oid-vector-type.js +1 -0
- package/data-types/path-type.d.ts +4 -0
- package/data-types/path-type.js +4 -0
- package/data-types/pg-lsn-type.d.ts +2 -0
- package/data-types/pg-lsn-type.js +2 -0
- package/data-types/point-type.d.ts +2 -0
- package/data-types/point-type.js +2 -0
- package/data-types/range-type.d.ts +4 -0
- package/data-types/range-type.js +4 -0
- package/data-types/snapshot-type.d.ts +4 -0
- package/data-types/snapshot-type.js +4 -0
- package/data-types/tid-type.d.ts +2 -0
- package/data-types/tid-type.js +2 -0
- package/data-types/time-type.d.ts +2 -0
- package/data-types/time-type.js +2 -0
- package/data-types/timestamp-type.d.ts +2 -0
- package/data-types/timestamp-type.js +2 -0
- package/data-types/timestamptz-type.d.ts +2 -0
- package/data-types/timestamptz-type.js +2 -0
- package/data-types/timetz-type.d.ts +2 -0
- package/data-types/timetz-type.js +2 -0
- package/data-types/tsvector-type.d.ts +4 -0
- package/data-types/tsvector-type.js +4 -0
- package/data-types/uuid-type.d.ts +2 -0
- package/data-types/uuid-type.js +2 -0
- package/data-types/varchar-type.d.ts +2 -0
- package/data-types/varchar-type.js +2 -0
- package/data-types/xid-type.d.ts +6 -0
- package/data-types/xid-type.js +8 -1
- package/interfaces/command-result.d.ts +7 -0
- package/interfaces/copy-from-rows-options.d.ts +4 -0
- package/interfaces/data-mapping-options.d.ts +6 -0
- package/interfaces/data-type.d.ts +37 -0
- package/interfaces/database-connection-params.d.ts +31 -0
- package/interfaces/field-info.d.ts +8 -0
- package/interfaces/function-call-options.d.ts +1 -0
- package/interfaces/function-call-result.d.ts +6 -0
- package/interfaces/pipeline-request.d.ts +2 -0
- package/interfaces/query-options.d.ts +7 -0
- package/interfaces/query-result.d.ts +7 -0
- package/interfaces/script-execute-options.d.ts +4 -0
- package/interfaces/script-result.d.ts +1 -0
- package/interfaces/statement-prepare-options.d.ts +1 -0
- package/package.json +5 -5
- package/protocol/backend.d.ts +6 -0
- package/protocol/backend.js +35 -5
- package/protocol/cert-signature.d.ts +8 -0
- package/protocol/cert-signature.js +8 -0
- package/protocol/database-error.d.ts +8 -0
- package/protocol/database-error.js +8 -0
- package/protocol/frontend.d.ts +16 -0
- package/protocol/frontend.js +13 -6
- package/protocol/pg-socket.d.ts +10 -0
- package/protocol/pg-socket.js +14 -7
- package/protocol/pgoutput.d.ts +15 -0
- package/protocol/pgoutput.js +7 -0
- package/protocol/protocol.d.ts +50 -2
- package/protocol/protocol.js +17 -1
- package/protocol/sasl.d.ts +22 -0
- package/protocol/sasl.js +21 -0
- package/protocol/smart-buffer.d.ts +4 -0
- package/safe-event-emitter.d.ts +7 -0
- package/safe-event-emitter.js +7 -0
- package/types.d.ts +21 -0
- package/util/array-calculatedim.d.ts +10 -0
- package/util/array-calculatedim.js +10 -0
- package/util/assert-integer.d.ts +40 -25
- package/util/assert-integer.js +97 -32
- package/util/bigint-methods.d.ts +7 -0
- package/util/bigint-methods.js +9 -0
- package/util/config-from-env.d.ts +10 -0
- package/util/config-from-env.js +10 -0
- package/util/connection-config.d.ts +17 -0
- package/util/connection-config.js +17 -0
- package/util/copy-from-rows.d.ts +12 -0
- package/util/copy-from-rows.js +9 -0
- package/util/decimal-as-string.d.ts +6 -0
- package/util/decimal-as-string.js +6 -0
- package/util/decode-binaryarray.d.ts +9 -0
- package/util/decode-binaryarray.js +9 -0
- package/util/escape-literal.d.ts +11 -0
- package/util/escape-literal.js +13 -0
- package/util/fast-parseint.d.ts +14 -0
- package/util/fast-parseint.js +14 -0
- package/util/format-datetime.d.ts +26 -0
- package/util/format-datetime.js +26 -0
- package/util/get-parsers.d.ts +9 -0
- package/util/get-parsers.js +9 -0
- package/util/hex-text.d.ts +13 -21
- package/util/hex-text.js +24 -21
- package/util/local-date.d.ts +2 -41
- package/util/local-date.js +39 -41
- package/util/parse-array.d.ts +8 -0
- package/util/parse-array.js +8 -0
- package/util/parse-bytea.d.ts +15 -0
- package/util/parse-bytea.js +15 -0
- package/util/parse-datetime.d.ts +26 -0
- package/util/parse-datetime.js +26 -0
- package/util/parse-row.d.ts +23 -2
- package/util/parse-row.js +56 -36
- package/util/parse-time.d.ts +10 -0
- package/util/parse-time.js +10 -0
- package/util/resolve-column-formats.d.ts +1 -0
- package/util/row-decoder.d.ts +32 -0
- package/util/row-decoder.js +22 -0
- package/util/stringify-arrayliteral.d.ts +33 -0
- package/util/stringify-arrayliteral.js +242 -7
- package/util/stringify-for-sql.d.ts +17 -0
- package/util/stringify-for-sql.js +17 -0
- package/util/unspecified-param.d.ts +26 -2
- package/util/unspecified-param.js +26 -2
- package/util/wrap-row-description.d.ts +10 -0
- package/util/wrap-row-description.js +10 -0
- package/CHANGELOG.md +0 -1426
|
@@ -9,4 +9,12 @@
|
|
|
9
9
|
* signatureAlgorithm and signatureValue, so this skips the first and reads
|
|
10
10
|
* the OID out of the second.
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* The hash a certificate was signed with, for `tls-server-end-point`
|
|
14
|
+
* channel binding.
|
|
15
|
+
*
|
|
16
|
+
* @param der The server's certificate, as DER.
|
|
17
|
+
* @returns The Node digest name to bind with - SHA-256 where the
|
|
18
|
+
* signature's own hash is MD5 or SHA-1, as the RFC requires.
|
|
19
|
+
*/
|
|
12
20
|
export declare function signatureHashOfCertificate(der: Buffer): string;
|
|
@@ -79,6 +79,14 @@ const PSS_HASHES = {
|
|
|
79
79
|
'2.16.840.1.101.3.4.2.2': 'sha384',
|
|
80
80
|
'2.16.840.1.101.3.4.2.3': 'sha512',
|
|
81
81
|
};
|
|
82
|
+
/**
|
|
83
|
+
* The hash a certificate was signed with, for `tls-server-end-point`
|
|
84
|
+
* channel binding.
|
|
85
|
+
*
|
|
86
|
+
* @param der The server's certificate, as DER.
|
|
87
|
+
* @returns The Node digest name to bind with - SHA-256 where the
|
|
88
|
+
* signature's own hash is MD5 or SHA-1, as the RFC requires.
|
|
89
|
+
*/
|
|
82
90
|
export function signatureHashOfCertificate(der) {
|
|
83
91
|
let index = expectSequence(der, 0).index; // Certificate
|
|
84
92
|
const tbs = readLength(der, index + 1); // tbsCertificate's own header
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { BatchCommandResult } from '../interfaces/batch-result.js';
|
|
2
2
|
import { Protocol } from './protocol.js';
|
|
3
|
+
/**
|
|
4
|
+
* An error the server reported, with every field it sent.
|
|
5
|
+
*
|
|
6
|
+
* `code` is the five-character SQLSTATE and is the thing to branch on -
|
|
7
|
+
* `23505` for a unique violation, `40P01` for a deadlock - since the
|
|
8
|
+
* message is localized and may be reworded between releases. `detail`,
|
|
9
|
+
* `hint`, `position` and the rest are there when the server sent them.
|
|
10
|
+
*/
|
|
3
11
|
export declare class DatabaseError extends Error {
|
|
4
12
|
/**
|
|
5
13
|
* Which entry of a multi-statement submission the server rejected -
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { Protocol } from './protocol.js';
|
|
2
|
+
/**
|
|
3
|
+
* An error the server reported, with every field it sent.
|
|
4
|
+
*
|
|
5
|
+
* `code` is the five-character SQLSTATE and is the thing to branch on -
|
|
6
|
+
* `23505` for a unique violation, `40P01` for a deadlock - since the
|
|
7
|
+
* message is localized and may be reworded between releases. `detail`,
|
|
8
|
+
* `hint`, `position` and the rest are there when the server sent them.
|
|
9
|
+
*/
|
|
2
10
|
export class DatabaseError extends Error {
|
|
3
11
|
/**
|
|
4
12
|
* Which entry of a multi-statement submission the server rejected -
|
package/protocol/frontend.d.ts
CHANGED
|
@@ -4,15 +4,20 @@ import type { Maybe, OID } from '../types.js';
|
|
|
4
4
|
import { Protocol } from './protocol.js';
|
|
5
5
|
import type { SASL } from './sasl.js';
|
|
6
6
|
import { type SmartBufferConfig } from './smart-buffer.js';
|
|
7
|
+
/** How a `Frontend` builds its messages - the buffer it writes them into. */
|
|
7
8
|
export interface FrontendOptions {
|
|
9
|
+
/** The send buffer's own configuration. */
|
|
8
10
|
buffer?: SmartBufferConfig;
|
|
9
11
|
}
|
|
12
|
+
/** What each message the client sends is built from. */
|
|
10
13
|
export declare namespace Frontend {
|
|
14
|
+
/** The startup packet: who is connecting, to what, and any session settings to carry with it. */
|
|
11
15
|
interface StartupMessageArgs {
|
|
12
16
|
user: string;
|
|
13
17
|
database: string;
|
|
14
18
|
[index: string]: string;
|
|
15
19
|
}
|
|
20
|
+
/** A Bind: which statement, which portal, the parameters and the formats to read the result in. */
|
|
16
21
|
interface BindMessageArgs {
|
|
17
22
|
typeMap: DataTypeMap;
|
|
18
23
|
statement?: string;
|
|
@@ -28,19 +33,23 @@ export declare namespace Frontend {
|
|
|
28
33
|
*/
|
|
29
34
|
columnFormat?: Protocol.DataFormat | Protocol.DataFormat[];
|
|
30
35
|
}
|
|
36
|
+
/** A Parse: the SQL, the name to give it, and any parameter types to declare. */
|
|
31
37
|
interface ParseMessageArgs {
|
|
32
38
|
statement?: string;
|
|
33
39
|
sql: string;
|
|
34
40
|
paramTypes?: Maybe<OID>[];
|
|
35
41
|
}
|
|
42
|
+
/** A Describe: of a statement (`S`) or of a portal (`P`). */
|
|
36
43
|
interface DescribeMessageArgs {
|
|
37
44
|
type: 'P' | 'S';
|
|
38
45
|
name?: string;
|
|
39
46
|
}
|
|
47
|
+
/** An Execute: which portal, and how many rows to stop at. */
|
|
40
48
|
interface ExecuteMessageArgs {
|
|
41
49
|
portal?: string;
|
|
42
50
|
fetchCount?: number;
|
|
43
51
|
}
|
|
52
|
+
/** A Close: of a statement (`S`) or of a portal (`P`). */
|
|
44
53
|
interface CloseMessageArgs {
|
|
45
54
|
type: 'P' | 'S';
|
|
46
55
|
name?: string;
|
|
@@ -69,6 +78,13 @@ export declare namespace Frontend {
|
|
|
69
78
|
resultFormat?: Protocol.DataFormat;
|
|
70
79
|
}
|
|
71
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Builds the client's messages, into one buffer it keeps and reuses.
|
|
83
|
+
*
|
|
84
|
+
* Each method returns the bytes of one message; the socket writes them,
|
|
85
|
+
* often several at a time so a statement costs one round trip rather
|
|
86
|
+
* than one per message.
|
|
87
|
+
*/
|
|
72
88
|
export declare class Frontend {
|
|
73
89
|
private _io;
|
|
74
90
|
constructor(options?: FrontendOptions);
|
package/protocol/frontend.js
CHANGED
|
@@ -3,7 +3,7 @@ import { DataTypeMap } from '../data-type-map.js';
|
|
|
3
3
|
import { arrayLeaf } from '../util/array-leaf.js';
|
|
4
4
|
import { encodeBinaryArray } from '../util/encode-binaryarray.js';
|
|
5
5
|
import { formatDateParam } from '../util/format-datetime.js';
|
|
6
|
-
import {
|
|
6
|
+
import { writeArrayLiteral } from '../util/stringify-arrayliteral.js';
|
|
7
7
|
import { Protocol } from './protocol.js';
|
|
8
8
|
import { SmartBuffer } from './smart-buffer.js';
|
|
9
9
|
const DataFormat = Protocol.DataFormat;
|
|
@@ -35,6 +35,13 @@ const StaticCopyDoneBuffer = Buffer.from([
|
|
|
35
35
|
0x00,
|
|
36
36
|
0x04,
|
|
37
37
|
]);
|
|
38
|
+
/**
|
|
39
|
+
* Builds the client's messages, into one buffer it keeps and reuses.
|
|
40
|
+
*
|
|
41
|
+
* Each method returns the bytes of one message; the socket writes them,
|
|
42
|
+
* often several at a time so a statement costs one round trip rather
|
|
43
|
+
* than one per message.
|
|
44
|
+
*/
|
|
38
45
|
export class Frontend {
|
|
39
46
|
_io;
|
|
40
47
|
constructor(options) {
|
|
@@ -182,10 +189,10 @@ export class Frontend {
|
|
|
182
189
|
io.buffer.writeInt32BE(io.size - dataOffset, dataOffset - 4); // Update length
|
|
183
190
|
}
|
|
184
191
|
else if (typeof dt.encodeText === 'function') {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
192
|
+
if (dt.elementsOID)
|
|
193
|
+
writeArrayLiteral(io, v, queryOptions, dt.encodeText);
|
|
194
|
+
else
|
|
195
|
+
io.writeLString(dt.encodeText(v, queryOptions), 'utf8');
|
|
189
196
|
}
|
|
190
197
|
}
|
|
191
198
|
else if (v instanceof Date) {
|
|
@@ -201,7 +208,7 @@ export class Frontend {
|
|
|
201
208
|
// takes the element type from the column. `'' + v` would hand
|
|
202
209
|
// it `a,b`, which is not one - the elements have to be quoted
|
|
203
210
|
// and the braces written, and a nested array needs its own.
|
|
204
|
-
io
|
|
211
|
+
writeArrayLiteral(io, v, queryOptions, arrayLeaf(v) instanceof Date ? formatDateParam : undefined);
|
|
205
212
|
}
|
|
206
213
|
else if (Buffer.isBuffer(v)) {
|
|
207
214
|
// Set param format to binary
|
package/protocol/pg-socket.d.ts
CHANGED
|
@@ -6,10 +6,20 @@ import { SafeEventEmitter } from '../safe-event-emitter.js';
|
|
|
6
6
|
import type { Callback, Maybe } from '../types.js';
|
|
7
7
|
import { Frontend } from './frontend.js';
|
|
8
8
|
import { Protocol } from './protocol.js';
|
|
9
|
+
/**
|
|
10
|
+
* What a sender registers to receive the messages its statement
|
|
11
|
+
* provokes, until it calls `done`.
|
|
12
|
+
*/
|
|
9
13
|
export type CaptureCallback = (code: Protocol.BackendMessageCode, msg: any, done: (err: Maybe<Error>, result?: any) => void) => void | Promise<void>;
|
|
14
|
+
/** A socket-level failure, with the code the platform gave it. */
|
|
10
15
|
export interface SocketError extends Error {
|
|
11
16
|
code: string;
|
|
12
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* The connected socket: the handshake, the authentication, TLS where it
|
|
20
|
+
* is asked for, and a queue that pairs each response with whoever sent
|
|
21
|
+
* the statement that caused it.
|
|
22
|
+
*/
|
|
13
23
|
export declare class PgSocket extends SafeEventEmitter {
|
|
14
24
|
options: ConnectionConfiguration;
|
|
15
25
|
private _state;
|
package/protocol/pg-socket.js
CHANGED
|
@@ -15,6 +15,11 @@ import { Protocol } from './protocol.js';
|
|
|
15
15
|
import { SASL } from './sasl.js';
|
|
16
16
|
const DEFAULT_PORT_NUMBER = 5432;
|
|
17
17
|
const COMMAND_RESULT_PATTERN = /^([^\d]+)(?: (\d+)(?: (\d+))?)?$/;
|
|
18
|
+
/**
|
|
19
|
+
* The connected socket: the handshake, the authentication, TLS where it
|
|
20
|
+
* is asked for, and a queue that pairs each response with whoever sent
|
|
21
|
+
* the statement that caused it.
|
|
22
|
+
*/
|
|
18
23
|
export class PgSocket extends SafeEventEmitter {
|
|
19
24
|
options;
|
|
20
25
|
_state = ConnectionState.CLOSED;
|
|
@@ -588,13 +593,15 @@ export class PgSocket extends SafeEventEmitter {
|
|
|
588
593
|
this.sendQueryMessage('select pg_catalog.pg_is_in_recovery()::text as a,' +
|
|
589
594
|
" current_setting('transaction_read_only') as b", (code, msg, done) => {
|
|
590
595
|
if (code === Protocol.BackendMessageCode.DataRow) {
|
|
591
|
-
// Two text columns, each length-prefixed
|
|
592
|
-
|
|
593
|
-
const
|
|
594
|
-
const
|
|
595
|
-
const
|
|
596
|
-
const
|
|
597
|
-
const
|
|
596
|
+
// Two text columns, each length-prefixed, read where the row
|
|
597
|
+
// already sits in the read buffer.
|
|
598
|
+
const buffer = msg.buffer;
|
|
599
|
+
const start = msg.offset;
|
|
600
|
+
const aLen = buffer.readInt32BE(start);
|
|
601
|
+
const a = buffer.toString('utf8', start + 4, start + 4 + aLen);
|
|
602
|
+
const bOffset = start + 4 + aLen;
|
|
603
|
+
const bLen = buffer.readInt32BE(bOffset);
|
|
604
|
+
const b = buffer.toString('utf8', bOffset + 4, bOffset + 4 + bLen);
|
|
598
605
|
this._standbyState = { standby: a === 'true', readOnly: b === 'on' };
|
|
599
606
|
}
|
|
600
607
|
else if (code === Protocol.BackendMessageCode.ReadyForQuery) {
|
package/protocol/pgoutput.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BufferReader } from './buffer-reader.js';
|
|
2
|
+
/** One column of a replicated table, as the stream declared it. */
|
|
2
3
|
export interface PgOutputColumn {
|
|
3
4
|
name: string;
|
|
4
5
|
dataTypeId: number;
|
|
@@ -6,6 +7,12 @@ export interface PgOutputColumn {
|
|
|
6
7
|
/** Part of the replica identity, so it can identify a row on its own. */
|
|
7
8
|
isKey: boolean;
|
|
8
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* A replicated table, declared once and then referred to by id.
|
|
12
|
+
*
|
|
13
|
+
* The stream sends this before the first change to that table and not
|
|
14
|
+
* again, so a decoder has to remember it.
|
|
15
|
+
*/
|
|
9
16
|
export interface PgOutputRelation {
|
|
10
17
|
relationId: number;
|
|
11
18
|
schema: string;
|
|
@@ -13,6 +20,7 @@ export interface PgOutputRelation {
|
|
|
13
20
|
replicaIdentity: string;
|
|
14
21
|
columns: PgOutputColumn[];
|
|
15
22
|
}
|
|
23
|
+
/** Any message the `pgoutput` plugin sends, decoded. */
|
|
16
24
|
export type PgOutputMessage = {
|
|
17
25
|
kind: 'begin';
|
|
18
26
|
finalLsn: bigint;
|
|
@@ -66,6 +74,13 @@ export type PgOutputMessage = {
|
|
|
66
74
|
* from the map entirely - which is not the same as being null.
|
|
67
75
|
*/
|
|
68
76
|
export type TupleValues = Record<string, string | null>;
|
|
77
|
+
/**
|
|
78
|
+
* Reads the `pgoutput` logical replication stream.
|
|
79
|
+
*
|
|
80
|
+
* Keeps the relations the stream declares, so each change can be
|
|
81
|
+
* reported with the table and column names it belongs to rather than
|
|
82
|
+
* the ids the wire uses.
|
|
83
|
+
*/
|
|
69
84
|
export declare class PgOutputDecoder {
|
|
70
85
|
protected readonly _relations: Map<number, PgOutputRelation>;
|
|
71
86
|
decode(data: Buffer): PgOutputMessage;
|
package/protocol/pgoutput.js
CHANGED
|
@@ -10,6 +10,13 @@ import { BufferReader } from './buffer-reader.js';
|
|
|
10
10
|
*/
|
|
11
11
|
/** Microseconds since 2000-01-01, which is how this protocol tells time. */
|
|
12
12
|
const PG_EPOCH_MS = Date.UTC(2000, 0, 1);
|
|
13
|
+
/**
|
|
14
|
+
* Reads the `pgoutput` logical replication stream.
|
|
15
|
+
*
|
|
16
|
+
* Keeps the relations the stream declares, so each change can be
|
|
17
|
+
* reported with the table and column names it belongs to rather than
|
|
18
|
+
* the ids the wire uses.
|
|
19
|
+
*/
|
|
13
20
|
export class PgOutputDecoder {
|
|
14
21
|
_relations = new Map();
|
|
15
22
|
decode(data) {
|
package/protocol/protocol.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire protocol itself: the message codes, the shapes each message
|
|
3
|
+
* carries, and the version numbers the handshake negotiates.
|
|
4
|
+
*
|
|
5
|
+
* These are PostgreSQL's own definitions, named as the documentation
|
|
6
|
+
* names them - nothing here is this client's invention, and a reader
|
|
7
|
+
* comparing it against the protocol pages should find the two line up.
|
|
8
|
+
*/
|
|
1
9
|
export declare namespace Protocol {
|
|
10
|
+
/** The protocol major version, which has been 3 since PostgreSQL 7.4. */
|
|
2
11
|
const VERSION_MAJOR = 3;
|
|
12
|
+
/** The minor version a connection asks for by default. */
|
|
3
13
|
const VERSION_MINOR = 0;
|
|
4
14
|
/**
|
|
5
15
|
* Minor version 3.2 (PostgreSQL 18+) differs from 3.0 only in that
|
|
@@ -11,6 +21,7 @@ export declare namespace Protocol {
|
|
|
11
21
|
* never a connection-breaking choice, only ever a possible no-op.
|
|
12
22
|
*/
|
|
13
23
|
const VERSION_MINOR_LONG_CANCEL_KEY = 2;
|
|
24
|
+
/** The first byte of each message the server sends. */
|
|
14
25
|
enum BackendMessageCode {
|
|
15
26
|
Authentication = 82,// R
|
|
16
27
|
BackendKeyData = 75,// K
|
|
@@ -37,6 +48,7 @@ export declare namespace Protocol {
|
|
|
37
48
|
ReadyForQuery = 90,// Z
|
|
38
49
|
RowDescription = 84
|
|
39
50
|
}
|
|
51
|
+
/** The first byte of each message the client sends. */
|
|
40
52
|
enum FrontendMessageCode {
|
|
41
53
|
Bind = 66,// B
|
|
42
54
|
Close = 67,// C
|
|
@@ -53,6 +65,7 @@ export declare namespace Protocol {
|
|
|
53
65
|
Sync = 83,// S
|
|
54
66
|
Terminate = 88
|
|
55
67
|
}
|
|
68
|
+
/** Which authentication the server asked for, by name rather than by its number. */
|
|
56
69
|
enum AuthenticationMessageKind {
|
|
57
70
|
KerberosV5 = "KerberosV5",
|
|
58
71
|
CleartextPassword = "CleartextPassword",
|
|
@@ -65,48 +78,64 @@ export declare namespace Protocol {
|
|
|
65
78
|
SASLContinue = "SASLContinue",
|
|
66
79
|
SASLFinal = "SASLFinal"
|
|
67
80
|
}
|
|
81
|
+
/** How a value travels: as the text the server prints, or in its binary form. */
|
|
68
82
|
enum DataFormat {
|
|
83
|
+
/** The type's own text, as `::text` would render it. */
|
|
69
84
|
text = 0,
|
|
85
|
+
/** The type's binary form - fewer bytes, and no text to parse. */
|
|
70
86
|
binary = 1
|
|
71
87
|
}
|
|
88
|
+
/** What every Authentication message carries: which kind it is. */
|
|
72
89
|
interface AuthenticationRequiredMessage {
|
|
90
|
+
/** The authentication the server is asking for. */
|
|
73
91
|
kind: AuthenticationMessageKind;
|
|
74
92
|
}
|
|
93
|
+
/** Kerberos V5 authentication is required - not implemented by this client, nor by any modern server. */
|
|
75
94
|
interface AuthenticationKerberosV5Message extends AuthenticationRequiredMessage {
|
|
76
95
|
kind: AuthenticationMessageKind.KerberosV5;
|
|
77
96
|
}
|
|
97
|
+
/** The server wants the password as it is, which only a trusted transport should be asked for. */
|
|
78
98
|
interface AuthenticationCleartextPasswordMessage extends AuthenticationRequiredMessage {
|
|
79
99
|
kind: AuthenticationMessageKind.CleartextPassword;
|
|
80
100
|
}
|
|
101
|
+
/** The server wants the password MD5-hashed with the salt it sent. */
|
|
81
102
|
interface AuthenticationMD5PasswordMessage extends AuthenticationRequiredMessage {
|
|
82
103
|
kind: AuthenticationMessageKind.MD5Password;
|
|
83
104
|
salt: Buffer;
|
|
84
105
|
}
|
|
106
|
+
/** SCM credential authentication, which only ever applied to some unix sockets. */
|
|
85
107
|
interface AuthenticationSCMCredentialMessage extends AuthenticationRequiredMessage {
|
|
86
108
|
kind: AuthenticationMessageKind.SCMCredential;
|
|
87
109
|
}
|
|
110
|
+
/** GSSAPI authentication is required. */
|
|
88
111
|
interface AuthenticationGSSMessage extends AuthenticationRequiredMessage {
|
|
89
112
|
kind: AuthenticationMessageKind.GSS;
|
|
90
113
|
}
|
|
114
|
+
/** SSPI authentication is required - the Windows spelling of GSSAPI. */
|
|
91
115
|
interface AuthenticationSSPIMessage extends AuthenticationRequiredMessage {
|
|
92
116
|
kind: AuthenticationMessageKind.SSPI;
|
|
93
117
|
}
|
|
118
|
+
/** One more round of GSSAPI/SSPI data. */
|
|
94
119
|
interface AuthenticationGSSContinueMessage extends AuthenticationRequiredMessage {
|
|
95
120
|
kind: AuthenticationMessageKind.GSSContinue;
|
|
96
121
|
data: Buffer;
|
|
97
122
|
}
|
|
123
|
+
/** SASL authentication is required; the message names which mechanisms the server offers. */
|
|
98
124
|
interface AuthenticationSASLMessage extends AuthenticationRequiredMessage {
|
|
99
125
|
kind: AuthenticationMessageKind.SASL;
|
|
100
126
|
mechanisms: string[];
|
|
101
127
|
}
|
|
128
|
+
/** The server's half of the SCRAM exchange in progress. */
|
|
102
129
|
interface AuthenticationSASLContinueMessage extends AuthenticationRequiredMessage {
|
|
103
130
|
kind: AuthenticationMessageKind.SASLContinue;
|
|
104
131
|
data: string;
|
|
105
132
|
}
|
|
133
|
+
/** The server's final SCRAM message, which proves it knew the password too. */
|
|
106
134
|
interface AuthenticationSASLFinalMessage extends AuthenticationRequiredMessage {
|
|
107
135
|
kind: AuthenticationMessageKind.SASLFinal;
|
|
108
136
|
data: string;
|
|
109
137
|
}
|
|
138
|
+
/** The process id and secret key a cancel request has to carry, sent once at startup. */
|
|
110
139
|
interface BackendKeyDataMessage {
|
|
111
140
|
processID: number;
|
|
112
141
|
/**
|
|
@@ -118,25 +147,36 @@ export declare namespace Protocol {
|
|
|
118
147
|
*/
|
|
119
148
|
secretKey: Buffer;
|
|
120
149
|
}
|
|
150
|
+
/** One statement finished: its tag, and what the tag reports. */
|
|
121
151
|
interface CommandCompleteMessage {
|
|
122
152
|
command: string;
|
|
123
153
|
oid?: number;
|
|
124
154
|
rowCount?: number;
|
|
125
155
|
}
|
|
156
|
+
/** One chunk of a copy in either direction. */
|
|
126
157
|
interface CopyDataMessage {
|
|
127
158
|
data: Buffer;
|
|
128
159
|
}
|
|
160
|
+
/** A copy is starting: which format it is in, and per column. */
|
|
129
161
|
interface CopyResponseMessage {
|
|
130
162
|
overallFormat: DataFormat;
|
|
131
163
|
columnCount: number;
|
|
132
164
|
columnFormats?: DataFormat[];
|
|
133
165
|
}
|
|
166
|
+
/** The DataRow message body, kept for its name; `DataRowMessage` is the shape actually used. */
|
|
134
167
|
interface DataRow {
|
|
135
168
|
}
|
|
169
|
+
/** One row, still as the bytes it arrived in - the values are read out of `data` by the column parsers. */
|
|
136
170
|
interface DataRowMessage {
|
|
137
171
|
columnCount: number;
|
|
138
|
-
|
|
139
|
-
|
|
172
|
+
/** The read buffer the row's values sit in. */
|
|
173
|
+
buffer: Buffer;
|
|
174
|
+
/** Where they start in it. */
|
|
175
|
+
offset: number;
|
|
176
|
+
/** How many bytes they run for. */
|
|
177
|
+
len: number;
|
|
178
|
+
}
|
|
179
|
+
/** An error or a notice, with every field the server chose to send. `code` is the SQLSTATE and is the part to branch on. */
|
|
140
180
|
interface ErrorResponseMessage {
|
|
141
181
|
severity?: string;
|
|
142
182
|
code?: string;
|
|
@@ -156,15 +196,18 @@ export declare namespace Protocol {
|
|
|
156
196
|
line?: string;
|
|
157
197
|
routine?: string;
|
|
158
198
|
}
|
|
199
|
+
/** A `NOTIFY` arriving: which channel, what payload, and which backend sent it. */
|
|
159
200
|
interface NotificationResponseMessage {
|
|
160
201
|
processId: number;
|
|
161
202
|
channel: string;
|
|
162
203
|
payload: string;
|
|
163
204
|
}
|
|
205
|
+
/** A fast-path function's return value, undecoded - the protocol says nothing about its type. */
|
|
164
206
|
interface FunctionCallResponseMessage {
|
|
165
207
|
/** `null` when the function returned SQL NULL. */
|
|
166
208
|
result: Buffer | null;
|
|
167
209
|
}
|
|
210
|
+
/** The server does not speak the minor version that was asked for, and names the highest it does. */
|
|
168
211
|
interface NegotiateProtocolVersionMessage {
|
|
169
212
|
/** Newest minor protocol version the server supports. */
|
|
170
213
|
supportedVersionMinor: number;
|
|
@@ -175,17 +218,21 @@ export declare namespace Protocol {
|
|
|
175
218
|
*/
|
|
176
219
|
unrecognizedOptions: string[];
|
|
177
220
|
}
|
|
221
|
+
/** What the server resolved each parameter of a prepared statement to. */
|
|
178
222
|
interface ParameterDescriptionMessage {
|
|
179
223
|
parameterCount: number;
|
|
180
224
|
parameterIds: number[];
|
|
181
225
|
}
|
|
226
|
+
/** A session setting the server reports, at startup and whenever it changes. */
|
|
182
227
|
interface ParameterStatusMessage {
|
|
183
228
|
name: string;
|
|
184
229
|
value: string;
|
|
185
230
|
}
|
|
231
|
+
/** The server is ready for the next statement, and says whether a transaction is open. */
|
|
186
232
|
interface ReadyForQueryMessage {
|
|
187
233
|
status: string;
|
|
188
234
|
}
|
|
235
|
+
/** One column of a result, as the server describes it. */
|
|
189
236
|
interface RowDescription {
|
|
190
237
|
fieldName: string;
|
|
191
238
|
tableId: number;
|
|
@@ -195,6 +242,7 @@ export declare namespace Protocol {
|
|
|
195
242
|
modifier?: number;
|
|
196
243
|
format: DataFormat;
|
|
197
244
|
}
|
|
245
|
+
/** The columns a statement will return, sent before its rows. */
|
|
198
246
|
interface RowDescriptionMessage {
|
|
199
247
|
fields: RowDescription[];
|
|
200
248
|
}
|
package/protocol/protocol.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire protocol itself: the message codes, the shapes each message
|
|
3
|
+
* carries, and the version numbers the handshake negotiates.
|
|
4
|
+
*
|
|
5
|
+
* These are PostgreSQL's own definitions, named as the documentation
|
|
6
|
+
* names them - nothing here is this client's invention, and a reader
|
|
7
|
+
* comparing it against the protocol pages should find the two line up.
|
|
8
|
+
*/
|
|
1
9
|
export var Protocol;
|
|
2
10
|
(function (Protocol) {
|
|
11
|
+
/** The protocol major version, which has been 3 since PostgreSQL 7.4. */
|
|
3
12
|
Protocol.VERSION_MAJOR = 3;
|
|
13
|
+
/** The minor version a connection asks for by default. */
|
|
4
14
|
Protocol.VERSION_MINOR = 0;
|
|
5
15
|
/**
|
|
6
16
|
* Minor version 3.2 (PostgreSQL 18+) differs from 3.0 only in that
|
|
@@ -12,7 +22,8 @@ export var Protocol;
|
|
|
12
22
|
* never a connection-breaking choice, only ever a possible no-op.
|
|
13
23
|
*/
|
|
14
24
|
Protocol.VERSION_MINOR_LONG_CANCEL_KEY = 2;
|
|
15
|
-
|
|
25
|
+
/** The first byte of each message the server sends. */
|
|
26
|
+
/* https://www.postgresql.org/docs/9.3/protocol-message-formats.html */
|
|
16
27
|
let BackendMessageCode;
|
|
17
28
|
(function (BackendMessageCode) {
|
|
18
29
|
BackendMessageCode[BackendMessageCode["Authentication"] = 82] = "Authentication";
|
|
@@ -40,6 +51,7 @@ export var Protocol;
|
|
|
40
51
|
BackendMessageCode[BackendMessageCode["ReadyForQuery"] = 90] = "ReadyForQuery";
|
|
41
52
|
BackendMessageCode[BackendMessageCode["RowDescription"] = 84] = "RowDescription";
|
|
42
53
|
})(BackendMessageCode = Protocol.BackendMessageCode || (Protocol.BackendMessageCode = {}));
|
|
54
|
+
/** The first byte of each message the client sends. */
|
|
43
55
|
let FrontendMessageCode;
|
|
44
56
|
(function (FrontendMessageCode) {
|
|
45
57
|
FrontendMessageCode[FrontendMessageCode["Bind"] = 66] = "Bind";
|
|
@@ -57,6 +69,7 @@ export var Protocol;
|
|
|
57
69
|
FrontendMessageCode[FrontendMessageCode["Sync"] = 83] = "Sync";
|
|
58
70
|
FrontendMessageCode[FrontendMessageCode["Terminate"] = 88] = "Terminate";
|
|
59
71
|
})(FrontendMessageCode = Protocol.FrontendMessageCode || (Protocol.FrontendMessageCode = {}));
|
|
72
|
+
/** Which authentication the server asked for, by name rather than by its number. */
|
|
60
73
|
let AuthenticationMessageKind;
|
|
61
74
|
(function (AuthenticationMessageKind) {
|
|
62
75
|
AuthenticationMessageKind["KerberosV5"] = "KerberosV5";
|
|
@@ -70,9 +83,12 @@ export var Protocol;
|
|
|
70
83
|
AuthenticationMessageKind["SASLContinue"] = "SASLContinue";
|
|
71
84
|
AuthenticationMessageKind["SASLFinal"] = "SASLFinal";
|
|
72
85
|
})(AuthenticationMessageKind = Protocol.AuthenticationMessageKind || (Protocol.AuthenticationMessageKind = {}));
|
|
86
|
+
/** How a value travels: as the text the server prints, or in its binary form. */
|
|
73
87
|
let DataFormat;
|
|
74
88
|
(function (DataFormat) {
|
|
89
|
+
/** The type's own text, as `::text` would render it. */
|
|
75
90
|
DataFormat[DataFormat["text"] = 0] = "text";
|
|
91
|
+
/** The type's binary form - fewer bytes, and no text to parse. */
|
|
76
92
|
DataFormat[DataFormat["binary"] = 1] = "binary";
|
|
77
93
|
})(DataFormat = Protocol.DataFormat || (Protocol.DataFormat = {}));
|
|
78
94
|
})(Protocol || (Protocol = {}));
|
package/protocol/sasl.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SCRAM-SHA-256, and the channel binding that ties it to the TLS
|
|
3
|
+
* connection underneath.
|
|
4
|
+
*/
|
|
1
5
|
export declare namespace SASL {
|
|
6
|
+
/** One exchange in progress: what was sent, and what is needed to check the reply. */
|
|
2
7
|
interface Session {
|
|
3
8
|
username: string;
|
|
4
9
|
mechanism: string;
|
|
@@ -18,6 +23,23 @@ export declare namespace SASL {
|
|
|
18
23
|
* is what tells the server a stripped -PLUS offer would be an attack.
|
|
19
24
|
*/
|
|
20
25
|
function createSession(username: string, mechanism: string, bindingData?: Buffer, supportsBinding?: boolean): Session;
|
|
26
|
+
/**
|
|
27
|
+
* Answers the server's first SCRAM message.
|
|
28
|
+
*
|
|
29
|
+
* @param session The session started for this connection.
|
|
30
|
+
* @param password The password to prove knowledge of.
|
|
31
|
+
* @param serverData The server's message.
|
|
32
|
+
* @param channelBinding The binding data, when the mechanism uses it.
|
|
33
|
+
*/
|
|
21
34
|
function continueSession(session: Session, password: string, data: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Checks the server's final message, which is what proves the server
|
|
37
|
+
* knew the password too.
|
|
38
|
+
*
|
|
39
|
+
* @param session The session in progress.
|
|
40
|
+
* @param data The server's final message.
|
|
41
|
+
* @throws Error When the signature does not match, meaning the server
|
|
42
|
+
* is not the one it claims to be.
|
|
43
|
+
*/
|
|
22
44
|
function finalizeSession(session: Session, data: string): void;
|
|
23
45
|
}
|
package/protocol/sasl.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
|
+
/**
|
|
3
|
+
* SCRAM-SHA-256, and the channel binding that ties it to the TLS
|
|
4
|
+
* connection underneath.
|
|
5
|
+
*/
|
|
2
6
|
export var SASL;
|
|
3
7
|
(function (SASL) {
|
|
4
8
|
const CLIENT_KEY = 'Client Key';
|
|
@@ -37,6 +41,14 @@ export var SASL;
|
|
|
37
41
|
};
|
|
38
42
|
}
|
|
39
43
|
SASL.createSession = createSession;
|
|
44
|
+
/**
|
|
45
|
+
* Answers the server's first SCRAM message.
|
|
46
|
+
*
|
|
47
|
+
* @param session The session started for this connection.
|
|
48
|
+
* @param password The password to prove knowledge of.
|
|
49
|
+
* @param serverData The server's message.
|
|
50
|
+
* @param channelBinding The binding data, when the mechanism uses it.
|
|
51
|
+
*/
|
|
40
52
|
function continueSession(session, password, data) {
|
|
41
53
|
const s = data.toString();
|
|
42
54
|
const items = s.split(',');
|
|
@@ -91,6 +103,15 @@ export var SASL;
|
|
|
91
103
|
clientFinalMessageWithoutProof + ',p=' + clientProof;
|
|
92
104
|
}
|
|
93
105
|
SASL.continueSession = continueSession;
|
|
106
|
+
/**
|
|
107
|
+
* Checks the server's final message, which is what proves the server
|
|
108
|
+
* knew the password too.
|
|
109
|
+
*
|
|
110
|
+
* @param session The session in progress.
|
|
111
|
+
* @param data The server's final message.
|
|
112
|
+
* @throws Error When the signature does not match, meaning the server
|
|
113
|
+
* is not the one it claims to be.
|
|
114
|
+
*/
|
|
94
115
|
function finalizeSession(session, data) {
|
|
95
116
|
let serverSignature = '';
|
|
96
117
|
const arr = data.split(',');
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { FlexyBuffer } from 'flexy-buffer';
|
|
2
|
+
/** How a `SmartBuffer` grows, how far, and when it gives the pages back. */
|
|
2
3
|
export interface SmartBufferConfig {
|
|
4
|
+
/** Bytes added at a time when it has to grow. */
|
|
3
5
|
pageSize?: number;
|
|
6
|
+
/** The most it may ever hold. */
|
|
4
7
|
maxLength?: number;
|
|
8
|
+
/** Idle milliseconds before the grown capacity is released. */
|
|
5
9
|
houseKeepMs?: number;
|
|
6
10
|
}
|
|
7
11
|
/**
|
package/safe-event-emitter.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
+
/**
|
|
3
|
+
* An `EventEmitter` whose listeners cannot take the process down.
|
|
4
|
+
*
|
|
5
|
+
* A listener that throws would otherwise escape into whatever was
|
|
6
|
+
* emitting - the socket's own data handler, more often than not - and
|
|
7
|
+
* an `error` event with nobody listening would throw by definition.
|
|
8
|
+
*/
|
|
2
9
|
export declare class SafeEventEmitter extends EventEmitter {
|
|
3
10
|
emit(event: string | symbol, ...args: any[]): boolean;
|
|
4
11
|
}
|
package/safe-event-emitter.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
+
/**
|
|
3
|
+
* An `EventEmitter` whose listeners cannot take the process down.
|
|
4
|
+
*
|
|
5
|
+
* A listener that throws would otherwise escape into whatever was
|
|
6
|
+
* emitting - the socket's own data handler, more often than not - and
|
|
7
|
+
* an `error` event with nobody listening would throw by definition.
|
|
8
|
+
*/
|
|
2
9
|
export class SafeEventEmitter extends EventEmitter {
|
|
3
10
|
emit(event, ...args) {
|
|
4
11
|
try {
|