postgrejs 3.12.0 → 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.
Files changed (183) hide show
  1. package/connection/bind-param.d.ts +21 -0
  2. package/connection/bind-param.js +21 -0
  3. package/connection/connection.d.ts +136 -0
  4. package/connection/connection.js +132 -5
  5. package/connection/copy-stream.d.ts +2 -0
  6. package/connection/copy-stream.js +2 -0
  7. package/connection/cursor.d.ts +67 -5
  8. package/connection/cursor.js +88 -15
  9. package/connection/intl-connection.d.ts +14 -0
  10. package/connection/intl-connection.js +95 -15
  11. package/connection/large-object.d.ts +18 -0
  12. package/connection/large-object.js +17 -0
  13. package/connection/logical-replication.d.ts +15 -0
  14. package/connection/logical-replication.js +6 -0
  15. package/connection/pool.d.ts +80 -0
  16. package/connection/pool.js +82 -9
  17. package/connection/portal.d.ts +37 -0
  18. package/connection/portal.js +29 -0
  19. package/connection/prepared-statement.d.ts +68 -0
  20. package/connection/prepared-statement.js +71 -2
  21. package/constants.d.ts +18 -0
  22. package/constants.js +18 -0
  23. package/data-type-map.d.ts +38 -0
  24. package/data-type-map.js +38 -0
  25. package/data-types/bit-type.d.ts +4 -0
  26. package/data-types/bit-type.js +4 -0
  27. package/data-types/bool-type.d.ts +2 -0
  28. package/data-types/bool-type.js +2 -0
  29. package/data-types/box-type.d.ts +2 -0
  30. package/data-types/box-type.js +2 -0
  31. package/data-types/bytea-type.d.ts +2 -0
  32. package/data-types/bytea-type.js +2 -0
  33. package/data-types/char-type.d.ts +2 -0
  34. package/data-types/char-type.js +2 -0
  35. package/data-types/circle-type.d.ts +2 -0
  36. package/data-types/circle-type.js +2 -0
  37. package/data-types/date-type.d.ts +2 -0
  38. package/data-types/date-type.js +2 -0
  39. package/data-types/float4-type.d.ts +2 -0
  40. package/data-types/float4-type.js +2 -0
  41. package/data-types/float8-type.d.ts +2 -0
  42. package/data-types/float8-type.js +2 -0
  43. package/data-types/inet-type.d.ts +4 -0
  44. package/data-types/inet-type.js +4 -0
  45. package/data-types/int2-type.d.ts +2 -0
  46. package/data-types/int2-type.js +2 -0
  47. package/data-types/int2-vector-type.d.ts +2 -0
  48. package/data-types/int2-vector-type.js +2 -0
  49. package/data-types/int4-type.d.ts +2 -0
  50. package/data-types/int4-type.js +2 -0
  51. package/data-types/int8-type.d.ts +2 -0
  52. package/data-types/int8-type.js +2 -0
  53. package/data-types/interval-type.d.ts +9 -0
  54. package/data-types/interval-type.js +9 -0
  55. package/data-types/json-type.d.ts +2 -0
  56. package/data-types/json-type.js +2 -0
  57. package/data-types/jsonb-type.d.ts +2 -0
  58. package/data-types/jsonb-type.js +2 -0
  59. package/data-types/jsonpath-type.d.ts +2 -0
  60. package/data-types/jsonpath-type.js +2 -0
  61. package/data-types/line-type.d.ts +2 -0
  62. package/data-types/line-type.js +2 -0
  63. package/data-types/lseg-type.d.ts +2 -0
  64. package/data-types/lseg-type.js +2 -0
  65. package/data-types/macaddr-type.d.ts +4 -0
  66. package/data-types/macaddr-type.js +4 -0
  67. package/data-types/money-type.d.ts +1 -0
  68. package/data-types/money-type.js +17 -10
  69. package/data-types/numeric-type.d.ts +2 -0
  70. package/data-types/numeric-type.js +2 -0
  71. package/data-types/oid-type.d.ts +2 -0
  72. package/data-types/oid-type.js +2 -0
  73. package/data-types/oid-vector-type.d.ts +1 -0
  74. package/data-types/oid-vector-type.js +1 -0
  75. package/data-types/path-type.d.ts +4 -0
  76. package/data-types/path-type.js +4 -0
  77. package/data-types/pg-lsn-type.d.ts +2 -0
  78. package/data-types/pg-lsn-type.js +2 -0
  79. package/data-types/point-type.d.ts +2 -0
  80. package/data-types/point-type.js +2 -0
  81. package/data-types/range-type.d.ts +4 -0
  82. package/data-types/range-type.js +4 -0
  83. package/data-types/snapshot-type.d.ts +4 -0
  84. package/data-types/snapshot-type.js +4 -0
  85. package/data-types/tid-type.d.ts +2 -0
  86. package/data-types/tid-type.js +2 -0
  87. package/data-types/time-type.d.ts +2 -0
  88. package/data-types/time-type.js +2 -0
  89. package/data-types/timestamp-type.d.ts +2 -0
  90. package/data-types/timestamp-type.js +2 -0
  91. package/data-types/timestamptz-type.d.ts +2 -0
  92. package/data-types/timestamptz-type.js +2 -0
  93. package/data-types/timetz-type.d.ts +2 -0
  94. package/data-types/timetz-type.js +2 -0
  95. package/data-types/tsvector-type.d.ts +4 -0
  96. package/data-types/tsvector-type.js +4 -0
  97. package/data-types/uuid-type.d.ts +2 -0
  98. package/data-types/uuid-type.js +2 -0
  99. package/data-types/varchar-type.d.ts +2 -0
  100. package/data-types/varchar-type.js +2 -0
  101. package/data-types/xid-type.d.ts +6 -0
  102. package/data-types/xid-type.js +6 -0
  103. package/interfaces/command-result.d.ts +7 -0
  104. package/interfaces/copy-from-rows-options.d.ts +4 -0
  105. package/interfaces/data-mapping-options.d.ts +6 -0
  106. package/interfaces/data-type.d.ts +37 -0
  107. package/interfaces/database-connection-params.d.ts +31 -0
  108. package/interfaces/field-info.d.ts +8 -0
  109. package/interfaces/function-call-options.d.ts +1 -0
  110. package/interfaces/function-call-result.d.ts +6 -0
  111. package/interfaces/pipeline-request.d.ts +2 -0
  112. package/interfaces/query-options.d.ts +7 -0
  113. package/interfaces/query-result.d.ts +7 -0
  114. package/interfaces/script-execute-options.d.ts +4 -0
  115. package/interfaces/script-result.d.ts +1 -0
  116. package/interfaces/statement-prepare-options.d.ts +1 -0
  117. package/package.json +5 -5
  118. package/protocol/backend.d.ts +6 -0
  119. package/protocol/backend.js +35 -5
  120. package/protocol/cert-signature.d.ts +8 -0
  121. package/protocol/cert-signature.js +8 -0
  122. package/protocol/database-error.d.ts +8 -0
  123. package/protocol/database-error.js +8 -0
  124. package/protocol/frontend.d.ts +16 -0
  125. package/protocol/frontend.js +13 -6
  126. package/protocol/pg-socket.d.ts +10 -0
  127. package/protocol/pg-socket.js +14 -7
  128. package/protocol/pgoutput.d.ts +15 -0
  129. package/protocol/pgoutput.js +7 -0
  130. package/protocol/protocol.d.ts +50 -2
  131. package/protocol/protocol.js +17 -1
  132. package/protocol/sasl.d.ts +22 -0
  133. package/protocol/sasl.js +21 -0
  134. package/protocol/smart-buffer.d.ts +4 -0
  135. package/safe-event-emitter.d.ts +7 -0
  136. package/safe-event-emitter.js +7 -0
  137. package/types.d.ts +21 -0
  138. package/util/array-calculatedim.d.ts +10 -0
  139. package/util/array-calculatedim.js +10 -0
  140. package/util/bigint-methods.d.ts +7 -0
  141. package/util/bigint-methods.js +9 -0
  142. package/util/config-from-env.d.ts +10 -0
  143. package/util/config-from-env.js +10 -0
  144. package/util/connection-config.d.ts +17 -0
  145. package/util/connection-config.js +17 -0
  146. package/util/copy-from-rows.d.ts +12 -0
  147. package/util/copy-from-rows.js +9 -0
  148. package/util/decimal-as-string.d.ts +6 -0
  149. package/util/decimal-as-string.js +6 -0
  150. package/util/decode-binaryarray.d.ts +9 -0
  151. package/util/decode-binaryarray.js +9 -0
  152. package/util/escape-literal.d.ts +11 -0
  153. package/util/escape-literal.js +13 -0
  154. package/util/fast-parseint.d.ts +14 -0
  155. package/util/fast-parseint.js +14 -0
  156. package/util/format-datetime.d.ts +26 -0
  157. package/util/format-datetime.js +26 -0
  158. package/util/get-parsers.d.ts +9 -0
  159. package/util/get-parsers.js +9 -0
  160. package/util/hex-text.d.ts +13 -21
  161. package/util/hex-text.js +24 -21
  162. package/util/local-date.d.ts +2 -41
  163. package/util/local-date.js +39 -41
  164. package/util/parse-array.d.ts +8 -0
  165. package/util/parse-array.js +8 -0
  166. package/util/parse-bytea.d.ts +15 -0
  167. package/util/parse-bytea.js +15 -0
  168. package/util/parse-datetime.d.ts +26 -0
  169. package/util/parse-datetime.js +26 -0
  170. package/util/parse-row.d.ts +23 -2
  171. package/util/parse-row.js +56 -36
  172. package/util/parse-time.d.ts +10 -0
  173. package/util/parse-time.js +10 -0
  174. package/util/resolve-column-formats.d.ts +1 -0
  175. package/util/row-decoder.d.ts +32 -0
  176. package/util/row-decoder.js +22 -0
  177. package/util/stringify-arrayliteral.d.ts +33 -0
  178. package/util/stringify-arrayliteral.js +220 -20
  179. package/util/stringify-for-sql.d.ts +17 -0
  180. package/util/stringify-for-sql.js +17 -0
  181. package/util/wrap-row-description.d.ts +10 -0
  182. package/util/wrap-row-description.js +10 -0
  183. package/CHANGELOG.md +0 -1453
@@ -4,6 +4,14 @@ import type { SmartBufferConfig } from '../protocol/smart-buffer.js';
4
4
  import type { DebugLogger } from '../types.js';
5
5
  import type { DataMappingOptions } from './data-mapping-options.js';
6
6
  import type { QueryOptions } from './query-options.js';
7
+ /**
8
+ * Where the server is and how to log in.
9
+ *
10
+ * Every field is optional: what is left out is taken from the
11
+ * environment - `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE`
12
+ * and the rest, the same variables `psql` reads - and what neither
13
+ * gives falls back to PostgreSQL's own defaults.
14
+ */
7
15
  export interface DatabaseConnectionParams {
8
16
  /**
9
17
  * A whole connection string, as an alternative to the fields below -
@@ -15,11 +23,20 @@ export interface DatabaseConnectionParams {
15
23
  * by one that was left in the object.
16
24
  */
17
25
  connectionString?: string;
26
+ /** Host name, IP, or the directory of a unix socket. */
18
27
  host?: string;
28
+ /** Port the server listens on. */
19
29
  port?: number;
30
+ /** Role to connect as. */
20
31
  user?: string;
32
+ /**
33
+ * The password, or a function asked for one when the server wants it -
34
+ * which is where a rotating credential or a secret store goes.
35
+ */
21
36
  password?: string | (() => string | Promise<string>);
37
+ /** Database to connect to. */
22
38
  database?: string;
39
+ /** What this connection calls itself, shown in `pg_stat_activity`. */
23
40
  applicationName?: string;
24
41
  /**
25
42
  * Opens the connection in replication mode, which is what lets it run
@@ -155,8 +172,14 @@ export interface DatabaseConnectionParams {
155
172
  timing?: boolean;
156
173
  debugLogger?: DebugLogger;
157
174
  }
175
+ /**
176
+ * Which server in a list is acceptable, checked after connecting - the
177
+ * same values `libpq` takes, and how a client finds the primary.
178
+ */
158
179
  export type TargetSessionAttrs = 'read-write' | 'read-only' | 'primary' | 'standby' | 'prefer-standby';
180
+ /** Options passed down to the socket itself. */
159
181
  export interface SocketOptions {
182
+ /** Whether TCP keep-alive is turned on. */
160
183
  keepAlive?: boolean;
161
184
  }
162
185
  /**
@@ -169,6 +192,10 @@ export interface SocketOptions {
169
192
  * about - see `fetchAsString` in QueryOptions.
170
193
  */
171
194
  export type ConnectionMappingDefaults = DataMappingOptions & Pick<QueryOptions, 'objectRows' | 'rowDecoder' | 'typeMap' | 'columnFormat'>;
195
+ /**
196
+ * Everything a `Connection` can be given: where the server is, how to
197
+ * talk to it, and the defaults every statement on it inherits.
198
+ */
172
199
  export interface ConnectionConfiguration extends DatabaseConnectionParams, SocketOptions, ConnectionMappingDefaults {
173
200
  buffer?: SmartBufferConfig;
174
201
  /**
@@ -186,6 +213,10 @@ export interface ConnectionConfiguration extends DatabaseConnectionParams, Socke
186
213
  */
187
214
  pipeline?: boolean;
188
215
  }
216
+ /**
217
+ * A connection's configuration, plus how many of them to keep and how
218
+ * long an idle one lives.
219
+ */
189
220
  export interface PoolConfiguration extends ConnectionConfiguration, LPoolConfiguration {
190
221
  /**
191
222
  * How many of Pool.query()'s one-shot queries may share a single pooled
@@ -1,3 +1,11 @@
1
+ /**
2
+ * One column of a result, as the server described it and this client
3
+ * mapped it.
4
+ *
5
+ * The server's half - name, type OID, table and column - comes from the
6
+ * RowDescription; `jsType`, the element type of an array and the fixed
7
+ * size are what the type map made of it.
8
+ */
1
9
  export interface FieldInfo {
2
10
  /**
3
11
  * Name of the field
@@ -1,4 +1,5 @@
1
1
  import type { DataFormat } from '../constants.js';
2
+ /** How a `Connection.callFunction()` sends its arguments and reads back its result. */
2
3
  export interface FunctionCallOptions {
3
4
  /**
4
5
  * Format of each argument, applied positionally - omit for text (the
@@ -1,3 +1,9 @@
1
+ /**
2
+ * What a function call answered with, undecoded.
3
+ *
4
+ * The fast-call protocol says nothing about the return type, so the
5
+ * bytes are handed over as they arrived for the caller to read.
6
+ */
1
7
  export interface FunctionCallResult {
2
8
  /**
3
9
  * The function's return value, in the wire format requested via
@@ -5,7 +5,9 @@ import type { Maybe, OID } from '../types.js';
5
5
  * tagged templates without any conversion.
6
6
  */
7
7
  export interface PipelineRequest {
8
+ /** The statement text. */
8
9
  sql: string;
10
+ /** Its parameters, for `$1`, `$2` and so on. */
9
11
  params?: any[];
10
12
  /**
11
13
  * Parameter type OIDs for this statement. Per statement rather than per
@@ -3,6 +3,13 @@ import type { DataFormat } from '../constants.js';
3
3
  import type { DataTypeMap } from '../data-type-map.js';
4
4
  import type { RowDecoder } from '../util/row-decoder.js';
5
5
  import type { DataMappingOptions } from './data-mapping-options.js';
6
+ /**
7
+ * What `query()` and `execute()` take: the parameters, the shape of the
8
+ * rows, how much of the result to read, and how to stop.
9
+ *
10
+ * Everything a `DataMappingOptions` carries applies here too, and a value
11
+ * left out falls back to the connection's own setting.
12
+ */
6
13
  export interface QueryOptions extends DataMappingOptions {
7
14
  /**
8
15
  * Specifies weather execute query in auto-commit mode
@@ -1,5 +1,12 @@
1
1
  import type { Cursor } from '../connection/cursor.js';
2
2
  import type { CommandResult } from './command-result.js';
3
+ /**
4
+ * What `query()` answered with - a `CommandResult`, plus the cursor when
5
+ * one was asked for.
6
+ *
7
+ * With `cursor: true` the rows are read through `cursor` instead of
8
+ * `rows`, which stays empty.
9
+ */
3
10
  export interface QueryResult extends CommandResult {
4
11
  /**
5
12
  * Cursor instance
@@ -1,6 +1,10 @@
1
1
  import type { DataTypeMap } from '../data-type-map.js';
2
2
  import type { RowDecoder } from '../util/row-decoder.js';
3
3
  import type { DataMappingOptions } from './data-mapping-options.js';
4
+ /**
5
+ * What `execute()` takes for a script of several statements - how much of
6
+ * each result to keep, and how to read the rows it does.
7
+ */
4
8
  export interface ScriptExecuteOptions extends DataMappingOptions {
5
9
  /**
6
10
  * Specifies weather execute query in auto-commit mode
@@ -1,4 +1,5 @@
1
1
  import type { CommandResult } from './command-result.js';
2
+ /** What `execute()` answered with: one result per statement in the script. */
2
3
  export interface ScriptResult {
3
4
  /**
4
5
  * Array of command result for each sql command in the script
@@ -1,5 +1,6 @@
1
1
  import type { DataTypeMap } from '../data-type-map.js';
2
2
  import type { OID } from '../types.js';
3
+ /** What `prepare()` takes: the parameter types to declare, and which type map to read them with. */
3
4
  export interface StatementPrepareOptions {
4
5
  /**
5
6
  * Specifies data type for each parameter
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "postgrejs",
3
3
  "description": "Professional PostgreSQL client NodeJS",
4
- "version": "3.12.0",
4
+ "version": "3.12.1",
5
5
  "author": "Panates",
6
6
  "license": "BSD-3-Clause",
7
7
  "dependencies": {
8
- "@jsopen/objects": "^2.2.3",
8
+ "@jsopen/objects": "^2.3.4",
9
9
  "doublylinked": "^2.5.6",
10
- "flexy-buffer": "^1.1.0",
11
- "lightning-pool": "^4.12.0",
10
+ "flexy-buffer": "^1.1.1",
11
+ "lightning-pool": "^4.14.0",
12
12
  "power-tasks": "^1.14.2",
13
13
  "putil-promisify": "^1.10.1",
14
14
  "putil-varhelpers": "^1.7.0",
@@ -65,4 +65,4 @@
65
65
  "publishConfig": {
66
66
  "access": "public"
67
67
  }
68
- }
68
+ }
@@ -1,5 +1,11 @@
1
1
  import { Protocol } from './protocol.js';
2
2
  declare type ParseCallback = (code: Protocol.BackendMessageCode, data?: any) => void;
3
+ /**
4
+ * Reads the server's messages out of the bytes as they arrive.
5
+ *
6
+ * Keeps whatever a chunk left half-finished, so a message split across
7
+ * reads - or several in one read - comes out whole exactly once.
8
+ */
3
9
  export declare class Backend {
4
10
  private readonly _headerBuf;
5
11
  private _headerFilled;
@@ -22,6 +22,12 @@ const ErrorFieldTypes = {
22
22
  L: 'line',
23
23
  R: 'routine',
24
24
  };
25
+ /**
26
+ * Reads the server's messages out of the bytes as they arrive.
27
+ *
28
+ * Keeps whatever a chunk left half-finished, so a message split across
29
+ * reads - or several in one read - comes out whole exactly once.
30
+ */
25
31
  export class Backend {
26
32
  _headerBuf = Buffer.allocUnsafe(HEADER_LENGTH);
27
33
  _headerFilled = 0;
@@ -47,10 +53,17 @@ export class Backend {
47
53
  const bodyStart = pos + HEADER_LENGTH;
48
54
  const bodyEnd = bodyStart + (len - 4);
49
55
  if (bodyEnd <= dataLen) {
50
- const io = new BufferReader(data.subarray(bodyStart, bodyEnd));
51
- const parser = MessageParsers[code];
52
- const v = parser && parser(io, code, len);
53
- callback(code, v);
56
+ if (code === Protocol.BackendMessageCode.DataRow) {
57
+ // Straight out of the read buffer: no view of the body, no
58
+ // reader over it, and no view of the row's own bytes either.
59
+ callback(code, dataRowMessage(data, bodyStart, bodyEnd));
60
+ }
61
+ else {
62
+ const io = new BufferReader(data.subarray(bodyStart, bodyEnd));
63
+ const parser = MessageParsers[code];
64
+ const v = parser && parser(io, code, len);
65
+ callback(code, v);
66
+ }
54
67
  pos = bodyEnd;
55
68
  continue;
56
69
  }
@@ -206,10 +219,27 @@ function parseCopyResponse(io) {
206
219
  }
207
220
  return out;
208
221
  }
222
+ /**
223
+ * One row, pointing into the read buffer rather than copying out of it.
224
+ *
225
+ * A consumer that needs a `Buffer` of its own - a caller's RowDecoder,
226
+ * or a path that sets the row aside and reads it later - builds the view
227
+ * with `dataRowBytes()`. The decoders that read the row in place never
228
+ * do, which is the point.
229
+ */
230
+ function dataRowMessage(buffer, bodyStart, bodyEnd) {
231
+ const offset = bodyStart + 2;
232
+ return {
233
+ columnCount: buffer.readUInt16BE(bodyStart),
234
+ buffer,
235
+ offset,
236
+ len: bodyEnd - offset,
237
+ };
238
+ }
209
239
  function parseDataRow(io, code, len) {
210
240
  const columnCount = io.readUInt16BE();
211
241
  const data = io.readBytes(len - 6);
212
- return { columnCount, data };
242
+ return { columnCount, buffer: data, offset: 0, len: data.length };
213
243
  }
214
244
  function parseErrorResponse(io) {
215
245
  const out = {};
@@ -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 -
@@ -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);
@@ -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 { stringifyArrayLiteral } from '../util/stringify-arrayliteral.js';
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
- v = dt.elementsOID
186
- ? stringifyArrayLiteral(v, queryOptions, dt.encodeText)
187
- : dt.encodeText(v, queryOptions);
188
- io.writeLString(v, 'utf8');
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.writeLString(stringifyArrayLiteral(v, queryOptions, arrayLeaf(v) instanceof Date ? formatDateParam : undefined), 'utf8');
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
@@ -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;
@@ -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 within the row buffer.
592
- const data = msg.data;
593
- const aLen = data.readInt32BE(0);
594
- const a = data.toString('utf8', 4, 4 + aLen);
595
- const bOffset = 4 + aLen;
596
- const bLen = data.readInt32BE(bOffset);
597
- const b = data.toString('utf8', bOffset + 4, bOffset + 4 + bLen);
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) {
@@ -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;
@@ -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) {