neonctl 2.27.1 → 2.29.0

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 (136) hide show
  1. package/README.md +35 -3
  2. package/dist/analytics.js +52 -34
  3. package/dist/api.js +643 -13
  4. package/dist/auth.js +50 -44
  5. package/dist/cli.js +8 -1
  6. package/dist/commands/auth.js +64 -51
  7. package/dist/commands/bootstrap.js +115 -157
  8. package/dist/commands/branches.js +160 -150
  9. package/dist/commands/bucket.js +183 -146
  10. package/dist/commands/checkout.js +51 -51
  11. package/dist/commands/config.js +228 -82
  12. package/dist/commands/connection_string.js +62 -62
  13. package/dist/commands/data_api.js +100 -101
  14. package/dist/commands/databases.js +29 -26
  15. package/dist/commands/deploy.js +12 -12
  16. package/dist/commands/dev.js +114 -114
  17. package/dist/commands/env.js +43 -43
  18. package/dist/commands/functions.js +101 -104
  19. package/dist/commands/index.js +27 -25
  20. package/dist/commands/init.js +23 -22
  21. package/dist/commands/ip_allow.js +29 -29
  22. package/dist/commands/link.js +232 -182
  23. package/dist/commands/neon_auth.js +385 -370
  24. package/dist/commands/operations.js +11 -11
  25. package/dist/commands/orgs.js +8 -8
  26. package/dist/commands/projects.js +103 -101
  27. package/dist/commands/psql.js +31 -31
  28. package/dist/commands/roles.js +27 -24
  29. package/dist/commands/schema_diff.js +25 -26
  30. package/dist/commands/set_context.js +17 -17
  31. package/dist/commands/status.js +40 -0
  32. package/dist/commands/user.js +5 -5
  33. package/dist/commands/vpc_endpoints.js +50 -50
  34. package/dist/config.js +7 -7
  35. package/dist/config_format.js +5 -5
  36. package/dist/context.js +37 -14
  37. package/dist/current_branch_fast_path.js +55 -0
  38. package/dist/dev/env.js +33 -33
  39. package/dist/dev/functions.js +4 -4
  40. package/dist/dev/inputs.js +6 -6
  41. package/dist/dev/runtime.js +25 -25
  42. package/dist/env.js +14 -14
  43. package/dist/env_file.js +13 -13
  44. package/dist/errors.js +68 -5
  45. package/dist/functions_api.js +10 -10
  46. package/dist/help.js +15 -15
  47. package/dist/index.js +110 -107
  48. package/dist/log.js +2 -2
  49. package/dist/parameters.gen.js +14 -14
  50. package/dist/pkg.js +5 -5
  51. package/dist/psql/cli.js +4 -2
  52. package/dist/psql/command/cmd_cond.js +61 -61
  53. package/dist/psql/command/cmd_connect.js +159 -154
  54. package/dist/psql/command/cmd_copy.js +107 -97
  55. package/dist/psql/command/cmd_describe.js +368 -363
  56. package/dist/psql/command/cmd_format.js +276 -263
  57. package/dist/psql/command/cmd_io.js +269 -263
  58. package/dist/psql/command/cmd_lo.js +74 -66
  59. package/dist/psql/command/cmd_meta.js +148 -148
  60. package/dist/psql/command/cmd_misc.js +17 -17
  61. package/dist/psql/command/cmd_pipeline.js +142 -135
  62. package/dist/psql/command/cmd_restrict.js +25 -25
  63. package/dist/psql/command/cmd_show.js +183 -168
  64. package/dist/psql/command/dispatch.js +26 -26
  65. package/dist/psql/command/shared.js +14 -14
  66. package/dist/psql/complete/filenames.js +16 -16
  67. package/dist/psql/complete/index.js +4 -4
  68. package/dist/psql/complete/matcher.js +33 -32
  69. package/dist/psql/complete/psqlVars.js +173 -173
  70. package/dist/psql/complete/queries.js +5 -3
  71. package/dist/psql/complete/rules.js +900 -863
  72. package/dist/psql/core/common.js +136 -133
  73. package/dist/psql/core/help.js +343 -343
  74. package/dist/psql/core/mainloop.js +160 -153
  75. package/dist/psql/core/prompt.js +126 -123
  76. package/dist/psql/core/settings.js +111 -111
  77. package/dist/psql/core/sqlHelp.js +150 -150
  78. package/dist/psql/core/startup.js +211 -205
  79. package/dist/psql/core/syncVars.js +14 -14
  80. package/dist/psql/core/variables.js +24 -24
  81. package/dist/psql/describe/formatters.js +302 -289
  82. package/dist/psql/describe/processNamePattern.js +28 -28
  83. package/dist/psql/describe/queries.js +656 -651
  84. package/dist/psql/index.js +436 -411
  85. package/dist/psql/io/history.js +36 -36
  86. package/dist/psql/io/input.js +15 -15
  87. package/dist/psql/io/lineEditor/buffer.js +27 -25
  88. package/dist/psql/io/lineEditor/complete.js +15 -15
  89. package/dist/psql/io/lineEditor/filename.js +22 -22
  90. package/dist/psql/io/lineEditor/index.js +65 -62
  91. package/dist/psql/io/lineEditor/keymap.js +325 -318
  92. package/dist/psql/io/lineEditor/vt100.js +60 -60
  93. package/dist/psql/io/pgpass.js +18 -18
  94. package/dist/psql/io/pgservice.js +14 -14
  95. package/dist/psql/io/psqlrc.js +46 -46
  96. package/dist/psql/print/aligned.js +175 -166
  97. package/dist/psql/print/asciidoc.js +51 -51
  98. package/dist/psql/print/crosstab.js +34 -31
  99. package/dist/psql/print/csv.js +25 -22
  100. package/dist/psql/print/html.js +54 -54
  101. package/dist/psql/print/json.js +12 -12
  102. package/dist/psql/print/latex.js +118 -118
  103. package/dist/psql/print/pager.js +28 -26
  104. package/dist/psql/print/troff.js +48 -48
  105. package/dist/psql/print/unaligned.js +15 -14
  106. package/dist/psql/print/units.js +17 -17
  107. package/dist/psql/scanner/slash.js +48 -46
  108. package/dist/psql/scanner/sql.js +88 -84
  109. package/dist/psql/scanner/stringutils.js +21 -17
  110. package/dist/psql/types/index.js +7 -7
  111. package/dist/psql/types/scanner.js +8 -8
  112. package/dist/psql/wire/connection.js +341 -327
  113. package/dist/psql/wire/copy.js +7 -7
  114. package/dist/psql/wire/pipeline.js +26 -24
  115. package/dist/psql/wire/protocol.js +102 -102
  116. package/dist/psql/wire/sasl.js +62 -62
  117. package/dist/psql/wire/tls.js +79 -73
  118. package/dist/storage_api.js +22 -23
  119. package/dist/test_utils/fixtures.js +74 -41
  120. package/dist/test_utils/oauth_server.js +5 -5
  121. package/dist/utils/api_enums.js +33 -0
  122. package/dist/utils/branch_notice.js +5 -5
  123. package/dist/utils/branch_picker.js +26 -26
  124. package/dist/utils/compute_units.js +4 -4
  125. package/dist/utils/enrichers.js +28 -16
  126. package/dist/utils/esbuild.js +28 -28
  127. package/dist/utils/formats.js +1 -1
  128. package/dist/utils/middlewares.js +3 -3
  129. package/dist/utils/package_manager.js +68 -0
  130. package/dist/utils/point_in_time.js +12 -12
  131. package/dist/utils/psql.js +30 -30
  132. package/dist/utils/string.js +2 -2
  133. package/dist/utils/ui.js +9 -9
  134. package/dist/utils/zip.js +1 -1
  135. package/dist/writer.js +17 -17
  136. package/package.json +10 -12
@@ -32,16 +32,16 @@
32
32
  * protocol.ts but the high-level path (parameterised `query()`, prepared
33
33
  * statements, pipeline) is WP-21. We throw clearly when called.
34
34
  */
35
- import * as dns from 'node:dns/promises';
36
- import * as net from 'node:net';
37
- import * as tls from 'node:tls';
38
- import { createHash } from 'node:crypto';
39
- import { Buffer } from 'node:buffer';
40
- import { Bind, CancelRequest, Close, CopyData, CopyDone, CopyFail, Describe, Execute, fieldsToNotice, MessageParser, Parse, PasswordMessage, Query, SASLInitialResponse, SASLResponse, StartupMessage, Sync, Terminate, } from './protocol.js';
41
- import { PipelineSession } from './pipeline.js';
42
- import { createScramClient } from './sasl.js';
43
- import { negotiateTls } from './tls.js';
44
- import { NoticeMultiplexer } from './notify.js';
35
+ import { Buffer } from "node:buffer";
36
+ import { createHash } from "node:crypto";
37
+ import * as dns from "node:dns/promises";
38
+ import * as net from "node:net";
39
+ import * as tls from "node:tls";
40
+ import { NoticeMultiplexer } from "./notify.js";
41
+ import { PipelineSession } from "./pipeline.js";
42
+ import { Bind, CancelRequest, Close, CopyData, CopyDone, CopyFail, Describe, Execute, fieldsToNotice, MessageParser, Parse, PasswordMessage, Query, SASLInitialResponse, SASLResponse, StartupMessage, Sync, Terminate, } from "./protocol.js";
43
+ import { createScramClient } from "./sasl.js";
44
+ import { negotiateTls } from "./tls.js";
45
45
  /**
46
46
  * Map a Notice-flavoured fields map into a `ConnectError` that includes a
47
47
  * recognizable `message` plus a `cause` slot for the raw record.
@@ -59,9 +59,9 @@ function fieldsToConnectError(fields) {
59
59
  */
60
60
  function pipelineAbortedError() {
61
61
  return {
62
- severity: 'ERROR',
63
- code: '',
64
- message: 'Pipeline aborted, command did not run',
62
+ severity: "ERROR",
63
+ code: "",
64
+ message: "Pipeline aborted, command did not run",
65
65
  pipelineAborted: true,
66
66
  };
67
67
  }
@@ -87,14 +87,14 @@ function parseServerVersion(value) {
87
87
  * the username; outer is salted. PG uses lowercase hex everywhere.
88
88
  */
89
89
  function md5AuthPayload(user, password, salt) {
90
- const inner = createHash('md5')
91
- .update(password + user, 'utf8')
92
- .digest('hex');
93
- const outer = createHash('md5')
94
- .update(inner, 'utf8')
90
+ const inner = createHash("md5")
91
+ .update(password + user, "utf8")
92
+ .digest("hex");
93
+ const outer = createHash("md5")
94
+ .update(inner, "utf8")
95
95
  .update(salt)
96
- .digest('hex');
97
- return 'md5' + outer;
96
+ .digest("hex");
97
+ return "md5" + outer;
98
98
  }
99
99
  /**
100
100
  * Fisher-Yates in-place shuffle of the candidate hosts list. Used by
@@ -124,11 +124,11 @@ function shuffleInPlace(arr, rng = Math.random) {
124
124
  * rather than handing the caller a half-broken connection.
125
125
  */
126
126
  async function checkSessionAttrs(conn, tsa) {
127
- if (tsa === undefined || tsa === 'any')
127
+ if (tsa === undefined || tsa === "any")
128
128
  return true;
129
129
  let inRecovery;
130
130
  try {
131
- const sets = await conn.execSimple('SELECT pg_is_in_recovery()');
131
+ const sets = await conn.execSimple("SELECT pg_is_in_recovery()");
132
132
  if (sets.length === 0 || sets[0].rows.length === 0) {
133
133
  return false;
134
134
  }
@@ -141,8 +141,8 @@ async function checkSessionAttrs(conn, tsa) {
141
141
  else if (raw === false) {
142
142
  inRecovery = false;
143
143
  }
144
- else if (typeof raw === 'string') {
145
- inRecovery = raw === 't' || raw.toLowerCase() === 'true';
144
+ else if (typeof raw === "string") {
145
+ inRecovery = raw === "t" || raw.toLowerCase() === "true";
146
146
  }
147
147
  else {
148
148
  return false;
@@ -152,11 +152,11 @@ async function checkSessionAttrs(conn, tsa) {
152
152
  return false;
153
153
  }
154
154
  switch (tsa) {
155
- case 'read-write':
156
- case 'primary':
155
+ case "read-write":
156
+ case "primary":
157
157
  return !inRecovery;
158
- case 'read-only':
159
- case 'standby':
158
+ case "read-only":
159
+ case "standby":
160
160
  return inRecovery;
161
161
  // 'prefer-standby' is unwrapped by the orchestrator into two passes
162
162
  // ('standby' then 'any'), so we never see it here. Fall through to
@@ -195,9 +195,9 @@ export class PgConnection {
195
195
  this.params = new Map();
196
196
  this.processId = 0;
197
197
  this.secretKey = 0;
198
- this.txStatus = 'I';
198
+ this.txStatus = "I";
199
199
  // -- Connection state machine
200
- this.state = 'auth';
200
+ this.state = "auth";
201
201
  this.pendingQuery = null;
202
202
  this.extDriver = null;
203
203
  /** True when `pipeline()` has handed out a PipelineSession (WP-21). */
@@ -285,17 +285,17 @@ export class PgConnection {
285
285
  this.opts = opts;
286
286
  this.channelBindingData = channelBindingData;
287
287
  this._password = opts.password ?? null;
288
- socket.on('data', (chunk) => {
288
+ socket.on("data", (chunk) => {
289
289
  this.onData(chunk);
290
290
  });
291
- socket.on('error', (err) => {
291
+ socket.on("error", (err) => {
292
292
  this.socketError = err;
293
293
  this.failPending(err);
294
294
  });
295
- socket.on('close', () => {
296
- if (this.state !== 'closed') {
297
- this.state = 'closed';
298
- this.failPending(this.socketError ?? new Error('Socket closed'));
295
+ socket.on("close", () => {
296
+ if (this.state !== "closed") {
297
+ this.state = "closed";
298
+ this.failPending(this.socketError ?? new Error("Socket closed"));
299
299
  }
300
300
  });
301
301
  }
@@ -342,20 +342,20 @@ export class PgConnection {
342
342
  // the candidate's `address`, and `host` (the user-typed name) is
343
343
  // preserved for SNI / `conn.host`. Only the single-host form carries a
344
344
  // `hostaddr`; libpq does not support a hostaddr-per-host list here.
345
- const candidates = opts.hostaddr !== undefined && opts.hostaddr !== ''
345
+ const candidates = opts.hostaddr !== undefined && opts.hostaddr !== ""
346
346
  ? seed.map((c) => ({
347
347
  host: c.host,
348
348
  address: opts.hostaddr,
349
349
  port: c.port,
350
350
  }))
351
351
  : await expandHostsViaDns(seed);
352
- if (opts.loadBalanceHosts === 'random') {
352
+ if (opts.loadBalanceHosts === "random") {
353
353
  shuffleInPlace(candidates, PgConnection._loadBalanceRng ?? Math.random);
354
354
  }
355
- const tsa = opts.targetSessionAttrs ?? 'any';
355
+ const tsa = opts.targetSessionAttrs ?? "any";
356
356
  // `prefer-standby` runs two passes: first 'standby', then 'any'. Every
357
357
  // other mode runs a single pass with the literal target.
358
- const passes = tsa === 'prefer-standby' ? ['standby', 'any'] : [tsa];
358
+ const passes = tsa === "prefer-standby" ? ["standby", "any"] : [tsa];
359
359
  let lastErr = null;
360
360
  for (const passTsa of passes) {
361
361
  for (const candidate of candidates) {
@@ -394,25 +394,25 @@ export class PgConnection {
394
394
  if (lastErr instanceof Error)
395
395
  throw lastErr;
396
396
  let message;
397
- if (typeof lastErr === 'object' &&
397
+ if (typeof lastErr === "object" &&
398
398
  lastErr !== null &&
399
- 'message' in lastErr &&
400
- typeof lastErr.message === 'string') {
399
+ "message" in lastErr &&
400
+ typeof lastErr.message === "string") {
401
401
  message = lastErr.message;
402
402
  }
403
- else if (typeof lastErr === 'string' ||
404
- typeof lastErr === 'number' ||
405
- typeof lastErr === 'boolean') {
403
+ else if (typeof lastErr === "string" ||
404
+ typeof lastErr === "number" ||
405
+ typeof lastErr === "boolean") {
406
406
  message = String(lastErr);
407
407
  }
408
408
  else {
409
- message = 'PgConnection.connect: unknown error';
409
+ message = "PgConnection.connect: unknown error";
410
410
  }
411
411
  const wrapped = new Error(message);
412
412
  wrapped.cause = lastErr;
413
413
  throw wrapped;
414
414
  }
415
- throw new Error('PgConnection.connect: no candidate hosts configured');
415
+ throw new Error("PgConnection.connect: no candidate hosts configured");
416
416
  }
417
417
  /**
418
418
  * Per-host connect attempt: open the socket, negotiate TLS, run the auth
@@ -432,9 +432,9 @@ export class PgConnection {
432
432
  // connections. We mirror the early rejection so a misconfigured caller
433
433
  // gets a clear diagnostic instead of a confused TLS handshake.
434
434
  if (isUnixSocketHost(opts.host) &&
435
- (opts.ssl === 'require' ||
436
- opts.ssl === 'verify-ca' ||
437
- opts.ssl === 'verify-full')) {
435
+ (opts.ssl === "require" ||
436
+ opts.ssl === "verify-ca" ||
437
+ opts.ssl === "verify-full")) {
438
438
  throw new Error(`sslmode=${opts.ssl} is not supported over Unix-domain sockets (host=${opts.host})`);
439
439
  }
440
440
  // libpq `requirepeer`: for Unix-domain sockets, libpq verifies the server
@@ -447,7 +447,7 @@ export class PgConnection {
447
447
  // connections ignore `requirepeer`, matching libpq.)
448
448
  if (isUnixSocketHost(opts.host) &&
449
449
  opts.requirepeer !== undefined &&
450
- opts.requirepeer !== '') {
450
+ opts.requirepeer !== "") {
451
451
  throw new Error(`requirepeer="${opts.requirepeer}" cannot be enforced: Node provides no ` +
452
452
  `Unix-domain socket peer-credential API; refusing to connect rather ` +
453
453
  `than skip the check`);
@@ -467,11 +467,11 @@ export class PgConnection {
467
467
  const servername = tlsServername(opts);
468
468
  const tlsConnectionOptions = {
469
469
  ...(servername !== undefined ? { servername } : {}),
470
- rejectUnauthorized: opts.ssl === 'verify-ca' || opts.ssl === 'verify-full',
470
+ rejectUnauthorized: opts.ssl === "verify-ca" || opts.ssl === "verify-full",
471
471
  // PG 17+ advertises ALPN for the 'postgresql' protocol; libpq sets
472
472
  // this so a future-proof TLS proxy can route on ALPN instead of
473
473
  // probing the wire. Always offer it — older servers ignore.
474
- ALPNProtocols: ['postgresql'],
474
+ ALPNProtocols: ["postgresql"],
475
475
  // Cipher preference is left to the runtime's TLS library. Our
476
476
  // ClientHello offers the byte-identical TLS-1.3 ciphersuite list and
477
477
  // order as libpq (AES-256-GCM, ChaCha20, AES-128-GCM), so the suite
@@ -483,7 +483,7 @@ export class PgConnection {
483
483
  // is TLS-1.2-only; `ciphersuites`/secureContext are ignored for the
484
484
  // client offer), so this is left as-is.
485
485
  };
486
- if (opts.ssl !== 'verify-full') {
486
+ if (opts.ssl !== "verify-full") {
487
487
  tlsConnectionOptions.checkServerIdentity = () => undefined;
488
488
  }
489
489
  else if (opts.sslsni === false) {
@@ -500,7 +500,7 @@ export class PgConnection {
500
500
  // prefer — instead of negotiating it just stays plain. We short-
501
501
  // circuit by passing 'disable' to negotiateTls; the caller's
502
502
  // requested sslmode is preserved on opts for error reporting.
503
- isUnixSocketHost(opts.host) ? 'disable' : opts.ssl, tlsConnectionOptions, {
503
+ isUnixSocketHost(opts.host) ? "disable" : opts.ssl, tlsConnectionOptions, {
504
504
  sslcert: opts.sslcert,
505
505
  sslkey: opts.sslkey,
506
506
  sslcertmode: opts.sslcertmode,
@@ -515,9 +515,9 @@ export class PgConnection {
515
515
  // sslmode 'disable' above) — direct SSL is a TCP-only concept. The
516
516
  // ALPN protocol is already on `tlsConnectionOptions` for both paths.
517
517
  isUnixSocketHost(opts.host)
518
- ? 'postgres'
519
- : (opts.sslnegotiation ?? 'postgres'));
520
- if (tlsResult.kind === 'tls') {
518
+ ? "postgres"
519
+ : (opts.sslnegotiation ?? "postgres"));
520
+ if (tlsResult.kind === "tls") {
521
521
  socket = tlsResult.socket;
522
522
  channelBindingData = tlsResult.channelBindingData;
523
523
  }
@@ -584,30 +584,32 @@ export class PgConnection {
584
584
  */
585
585
  getTlsInfo() {
586
586
  const s = this.socket;
587
- if (typeof s.getCipher !== 'function')
587
+ if (typeof s.getCipher !== "function")
588
588
  return null;
589
589
  try {
590
590
  const cipher = s.getCipher();
591
- const protocol = s.getProtocol?.() ?? cipher.version ?? 'unknown';
591
+ const protocol = s.getProtocol?.() ?? cipher.version ?? "unknown";
592
592
  if (!cipher.name)
593
593
  return null;
594
594
  // TLS compression has been disabled by every modern stack since CRIME
595
595
  // (2012); Node's TLS doesn't expose a compression accessor, so we
596
596
  // always report "off". libpq does the same.
597
- const compression = 'off';
597
+ const compression = "off";
598
598
  // Node exposes the negotiated ALPN protocol on TLSSocket.alpnProtocol
599
599
  // (string when negotiated, false when not). Postgres 17+ uses
600
600
  // 'postgresql' here.
601
601
  const alpnRaw = s
602
602
  .alpnProtocol;
603
- const alpn = typeof alpnRaw === 'string' && alpnRaw.length > 0 ? alpnRaw : null;
603
+ const alpn = typeof alpnRaw === "string" && alpnRaw.length > 0
604
+ ? alpnRaw
605
+ : null;
604
606
  return {
605
607
  protocol: String(protocol),
606
608
  cipher: cipher.standardName ?? cipher.name,
607
609
  standardName: cipher.standardName,
608
610
  compression,
609
611
  alpn,
610
- library: 'OpenSSL',
612
+ library: "OpenSSL",
611
613
  keyBits: sslKeyBitsFromCipher(cipher.standardName ?? cipher.name),
612
614
  };
613
615
  }
@@ -628,7 +630,7 @@ export class PgConnection {
628
630
  * - `gssapiUsed`: always `false` — we have no GSSAPI support.
629
631
  */
630
632
  getConnectionInfo() {
631
- const remote = this.opts.hostaddr !== undefined && this.opts.hostaddr !== ''
633
+ const remote = this.opts.hostaddr !== undefined && this.opts.hostaddr !== ""
632
634
  ? this.opts.hostaddr
633
635
  : (this.socket.remoteAddress ?? null);
634
636
  return {
@@ -657,7 +659,7 @@ export class PgConnection {
657
659
  if (params === undefined) {
658
660
  const sets = await this.execSimple(sql);
659
661
  if (sets.length === 0) {
660
- throw new Error('PgConnection.query: server returned no result sets');
662
+ throw new Error("PgConnection.query: server returned no result sets");
661
663
  }
662
664
  return sets[sets.length - 1];
663
665
  }
@@ -672,10 +674,10 @@ export class PgConnection {
672
674
  const descP = this.enqueueDescribePortalIntoNextExecute();
673
675
  const execP = this.enqueueExecute();
674
676
  const syncP = this.enqueueSync();
675
- this.socket.write(Parse('', sql, []));
676
- this.socket.write(Bind('', '', [], encoded, [0]));
677
- this.socket.write(Describe('P', ''));
678
- this.socket.write(Execute('', 0));
677
+ this.socket.write(Parse("", sql, []));
678
+ this.socket.write(Bind("", "", [], encoded, [0]));
679
+ this.socket.write(Describe("P", ""));
680
+ this.socket.write(Execute("", 0));
679
681
  this.socket.write(Sync());
680
682
  let firstErr = null;
681
683
  const cap = (e) => {
@@ -693,7 +695,7 @@ export class PgConnection {
693
695
  if (firstErr !== null)
694
696
  throw asThrowable(firstErr);
695
697
  if (result === null) {
696
- throw new Error('PgConnection.query: server returned no result');
698
+ throw new Error("PgConnection.query: server returned no result");
697
699
  }
698
700
  return result;
699
701
  }
@@ -708,7 +710,7 @@ export class PgConnection {
708
710
  notices: [],
709
711
  error: null,
710
712
  };
711
- this.state = 'in-query';
713
+ this.state = "in-query";
712
714
  this.socket.write(Query(sql));
713
715
  });
714
716
  }
@@ -720,7 +722,7 @@ export class PgConnection {
720
722
  const descP = this.enqueueDescribeStatement();
721
723
  const syncP = this.enqueueSync();
722
724
  this.socket.write(Parse(name, sql, oids));
723
- this.socket.write(Describe('S', name));
725
+ this.socket.write(Describe("S", name));
724
726
  this.socket.write(Sync());
725
727
  let firstErr = null;
726
728
  const cap = (e) => {
@@ -736,7 +738,7 @@ export class PgConnection {
736
738
  if (firstErr !== null)
737
739
  throw asThrowable(firstErr);
738
740
  if (descResult === null) {
739
- throw new Error('PgConnection.prepare: server returned no parameter description');
741
+ throw new Error("PgConnection.prepare: server returned no parameter description");
740
742
  }
741
743
  const { paramOids, fields } = descResult;
742
744
  // eslint-disable-next-line @typescript-eslint/no-this-alias
@@ -750,7 +752,7 @@ export class PgConnection {
750
752
  conn.startExtendedBatch();
751
753
  const bP = conn.enqueueBind();
752
754
  const sP = conn.enqueueSync();
753
- conn.socket.write(Bind('', name, paramFormats ?? [], encoded, [0]));
755
+ conn.socket.write(Bind("", name, paramFormats ?? [], encoded, [0]));
754
756
  conn.socket.write(Sync());
755
757
  let err = null;
756
758
  bP.catch((e) => {
@@ -772,7 +774,7 @@ export class PgConnection {
772
774
  conn.startExtendedBatch();
773
775
  const eP = conn.enqueueExecuteWithFields(fields);
774
776
  const sP = conn.enqueueSync();
775
- conn.socket.write(Execute('', maxRows ?? 0));
777
+ conn.socket.write(Execute("", maxRows ?? 0));
776
778
  conn.socket.write(Sync());
777
779
  let err = null;
778
780
  let rs = null;
@@ -789,7 +791,7 @@ export class PgConnection {
789
791
  if (err !== null)
790
792
  throw asThrowable(err);
791
793
  if (rs === null) {
792
- throw new Error('PgConnection.prepare.execute: server returned no result');
794
+ throw new Error("PgConnection.prepare.execute: server returned no result");
793
795
  }
794
796
  return rs;
795
797
  },
@@ -800,8 +802,8 @@ export class PgConnection {
800
802
  const bP = conn.enqueueBind();
801
803
  const eP = conn.enqueueExecuteWithFields(fields);
802
804
  const sP = conn.enqueueSync();
803
- conn.socket.write(Bind('', name, paramFormats ?? [], encoded, [0]));
804
- conn.socket.write(Execute('', maxRows ?? 0));
805
+ conn.socket.write(Bind("", name, paramFormats ?? [], encoded, [0]));
806
+ conn.socket.write(Execute("", maxRows ?? 0));
805
807
  conn.socket.write(Sync());
806
808
  let err = null;
807
809
  let rs = null;
@@ -822,7 +824,7 @@ export class PgConnection {
822
824
  if (err !== null)
823
825
  throw asThrowable(err);
824
826
  if (rs === null) {
825
- throw new Error('PgConnection.prepare.bindAndExecute: server returned no result');
827
+ throw new Error("PgConnection.prepare.bindAndExecute: server returned no result");
826
828
  }
827
829
  return rs;
828
830
  },
@@ -831,7 +833,7 @@ export class PgConnection {
831
833
  conn.startExtendedBatch();
832
834
  const cP = conn.enqueueClose();
833
835
  const sP = conn.enqueueSync();
834
- conn.socket.write(Close('S', name));
836
+ conn.socket.write(Close("S", name));
835
837
  conn.socket.write(Sync());
836
838
  let err = null;
837
839
  cP.catch((e) => {
@@ -859,7 +861,7 @@ export class PgConnection {
859
861
  this.startExtendedBatch();
860
862
  const cP = this.enqueueClose();
861
863
  const sP = this.enqueueSync();
862
- this.socket.write(Close('S', name));
864
+ this.socket.write(Close("S", name));
863
865
  this.socket.write(Sync());
864
866
  let err = null;
865
867
  cP.catch((e) => {
@@ -881,7 +883,7 @@ export class PgConnection {
881
883
  // (see handleCopyStartMessage) for any path that bypasses this check.
882
884
  if (this._extPipelineActive) {
883
885
  this.abortForCopyInPipeline();
884
- return Promise.reject(Object.assign(new Error('COPY in a pipeline is not supported, aborting connection'), { severity: 'FATAL' }));
886
+ return Promise.reject(Object.assign(new Error("COPY in a pipeline is not supported, aborting connection"), { severity: "FATAL" }));
885
887
  }
886
888
  // The driver waits in `in-query` state until CopyInResponse arrives — at
887
889
  // which point the protocol switches and we move to `in-copy-in`. The
@@ -900,7 +902,7 @@ export class PgConnection {
900
902
  resolve(this.makeCopyInStream());
901
903
  };
902
904
  this.copyStartReject = reject;
903
- this.state = 'in-query';
905
+ this.state = "in-query";
904
906
  this.socket.write(Query(sql));
905
907
  });
906
908
  }
@@ -908,7 +910,7 @@ export class PgConnection {
908
910
  this.ensureIdle();
909
911
  if (this._extPipelineActive) {
910
912
  this.abortForCopyInPipeline();
911
- return Promise.reject(Object.assign(new Error('COPY in a pipeline is not supported, aborting connection'), { severity: 'FATAL' }));
913
+ return Promise.reject(Object.assign(new Error("COPY in a pipeline is not supported, aborting connection"), { severity: "FATAL" }));
912
914
  }
913
915
  return new Promise((resolve, reject) => {
914
916
  this.copyOut = {
@@ -924,7 +926,7 @@ export class PgConnection {
924
926
  resolve(this.makeCopyOutStream());
925
927
  };
926
928
  this.copyStartReject = reject;
927
- this.state = 'in-query';
929
+ this.state = "in-query";
928
930
  this.socket.write(Query(sql));
929
931
  });
930
932
  }
@@ -956,10 +958,10 @@ export class PgConnection {
956
958
  // In-copy-in: send CopyFail on the live socket so the server returns
957
959
  // to ReadyForQuery cleanly. This is the same abort path the upstream
958
960
  // SIGINT handler in `copy.c::handleCopyIn` triggers via longjmp.
959
- if (this.state === 'in-copy-in' && this.copyIn && !this.copyIn.closed) {
961
+ if (this.state === "in-copy-in" && this.copyIn && !this.copyIn.closed) {
960
962
  this.copyIn.closed = true;
961
963
  try {
962
- this.socket.write(CopyFail('canceled by user'));
964
+ this.socket.write(CopyFail("canceled by user"));
963
965
  }
964
966
  catch {
965
967
  // Socket may have died — failPending() will surface that.
@@ -978,7 +980,7 @@ export class PgConnection {
978
980
  // Honour `hostaddr` on the cancel connection too: dial the fixed IP while
979
981
  // keeping the user-typed host for SNI / cert verification, mirroring the
980
982
  // primary connect path's `addressOverride`.
981
- const cancelSocket = await openSocket(this.opts, this.opts.hostaddr !== undefined && this.opts.hostaddr !== ''
983
+ const cancelSocket = await openSocket(this.opts, this.opts.hostaddr !== undefined && this.opts.hostaddr !== ""
982
984
  ? this.opts.hostaddr
983
985
  : undefined);
984
986
  let writeSocket = cancelSocket;
@@ -990,10 +992,11 @@ export class PgConnection {
990
992
  ...(cancelServername !== undefined
991
993
  ? { servername: cancelServername }
992
994
  : {}),
993
- rejectUnauthorized: this.opts.ssl === 'verify-ca' || this.opts.ssl === 'verify-full',
994
- ALPNProtocols: ['postgresql'],
995
+ rejectUnauthorized: this.opts.ssl === "verify-ca" ||
996
+ this.opts.ssl === "verify-full",
997
+ ALPNProtocols: ["postgresql"],
995
998
  };
996
- if (this.opts.ssl !== 'verify-full') {
999
+ if (this.opts.ssl !== "verify-full") {
997
1000
  cancelTlsOpts.checkServerIdentity = () => undefined;
998
1001
  }
999
1002
  else if (this.opts.sslsni === false) {
@@ -1003,7 +1006,7 @@ export class PgConnection {
1003
1006
  applyTlsProtocolVersionRange(cancelTlsOpts, this.opts);
1004
1007
  const t = await negotiateTls(cancelSocket,
1005
1008
  // Unix-domain socket: no TLS, regardless of caller's sslmode.
1006
- isUnixSocketHost(this.opts.host) ? 'disable' : this.opts.ssl, cancelTlsOpts, {
1009
+ isUnixSocketHost(this.opts.host) ? "disable" : this.opts.ssl, cancelTlsOpts, {
1007
1010
  sslcert: this.opts.sslcert,
1008
1011
  sslkey: this.opts.sslkey,
1009
1012
  sslcertmode: this.opts.sslcertmode,
@@ -1016,9 +1019,9 @@ export class PgConnection {
1016
1019
  // Mirror the primary connect path's negotiation mode so a server
1017
1020
  // configured for direct SSL also accepts the cancel connection.
1018
1021
  isUnixSocketHost(this.opts.host)
1019
- ? 'postgres'
1020
- : (this.opts.sslnegotiation ?? 'postgres'));
1021
- writeSocket = t.kind === 'tls' ? t.socket : t.socket;
1022
+ ? "postgres"
1023
+ : (this.opts.sslnegotiation ?? "postgres"));
1024
+ writeSocket = t.kind === "tls" ? t.socket : t.socket;
1022
1025
  await new Promise((resolve, reject) => {
1023
1026
  writeSocket.write(CancelRequest(this.processId, this.secretKey), (err) => {
1024
1027
  if (err)
@@ -1051,8 +1054,8 @@ export class PgConnection {
1051
1054
  // backslash, use the E'...' escape-string syntax so backslashes don't
1052
1055
  // depend on `standard_conforming_strings`.
1053
1056
  const doubled = value.replace(/'/g, "''");
1054
- if (value.includes('\\')) {
1055
- return "E'" + doubled.replace(/\\/g, '\\\\') + "'";
1057
+ if (value.includes("\\")) {
1058
+ return "E'" + doubled.replace(/\\/g, "\\\\") + "'";
1056
1059
  }
1057
1060
  return "'" + doubled + "'";
1058
1061
  }
@@ -1079,7 +1082,7 @@ export class PgConnection {
1079
1082
  return this.notify.onNotification(handler);
1080
1083
  }
1081
1084
  async close() {
1082
- if (this.state === 'closed')
1085
+ if (this.state === "closed")
1083
1086
  return;
1084
1087
  try {
1085
1088
  this.socket.write(Terminate());
@@ -1087,10 +1090,10 @@ export class PgConnection {
1087
1090
  catch {
1088
1091
  // socket may already be dead; we still want to mark closed
1089
1092
  }
1090
- this.state = 'closed';
1093
+ this.state = "closed";
1091
1094
  this.notify.clear();
1092
1095
  await new Promise((resolve) => {
1093
- this.socket.once('close', () => {
1096
+ this.socket.once("close", () => {
1094
1097
  resolve();
1095
1098
  });
1096
1099
  try {
@@ -1102,7 +1105,7 @@ export class PgConnection {
1102
1105
  });
1103
1106
  }
1104
1107
  isClosed() {
1105
- return this.state === 'closed';
1108
+ return this.state === "closed";
1106
1109
  }
1107
1110
  // -------------------------------------------------------------------------
1108
1111
  // Startup / auth state machine
@@ -1113,7 +1116,7 @@ export class PgConnection {
1113
1116
  user: this.opts.user,
1114
1117
  database: this.opts.database,
1115
1118
  // psql sends client_encoding=UTF8 by default; we follow.
1116
- client_encoding: this.opts.clientEncoding ?? 'UTF8',
1119
+ client_encoding: this.opts.clientEncoding ?? "UTF8",
1117
1120
  };
1118
1121
  if (this.opts.applicationName !== undefined) {
1119
1122
  params.application_name = this.opts.applicationName;
@@ -1156,15 +1159,16 @@ export class PgConnection {
1156
1159
  }
1157
1160
  handleAuthMessage(msg) {
1158
1161
  switch (msg.type) {
1159
- case 'AuthenticationOk': {
1162
+ case "AuthenticationOk": {
1160
1163
  // libpq parity: channel_binding=require demands that some prior
1161
1164
  // auth step actually negotiated channel binding. A bare
1162
1165
  // AuthenticationOk after no challenge ("trust") or after a cert
1163
1166
  // exchange ("cert" HBA, clientcert=verify-full) means no SCRAM
1164
1167
  // happened and we must refuse.
1165
- if (this.opts.channelBinding === 'require' &&
1166
- (this.scram === null || this.scram.mechanism !== 'SCRAM-SHA-256-PLUS')) {
1167
- this.failStartup(new Error('channel binding required, but server authenticated client without channel binding'));
1168
+ if (this.opts.channelBinding === "require" &&
1169
+ (this.scram === null ||
1170
+ this.scram.mechanism !== "SCRAM-SHA-256-PLUS")) {
1171
+ this.failStartup(new Error("channel binding required, but server authenticated client without channel binding"));
1168
1172
  return;
1169
1173
  }
1170
1174
  // Mutual-auth integrity: if a SCRAM exchange was started it MUST have
@@ -1172,45 +1176,45 @@ export class PgConnection {
1172
1176
  // verified). A server that sends SASLContinue then jumps to
1173
1177
  // AuthenticationOk never proves it knows the password (review #8).
1174
1178
  if (this.scram !== null && !this.saslFinalSeen) {
1175
- this.failStartup(new Error('server sent AuthenticationOk without completing SCRAM ' +
1176
- 'authentication (server signature not verified)'));
1179
+ this.failStartup(new Error("server sent AuthenticationOk without completing SCRAM " +
1180
+ "authentication (server signature not verified)"));
1177
1181
  return;
1178
1182
  }
1179
1183
  // require_auth=none allows trust auth; anything else is rejected
1180
1184
  // here. If a prior challenge was sent and validated, skip — that
1181
1185
  // method was already accepted by the check at its own branch.
1182
- if (!this.authChallengeSeen && !this.checkRequireAuth('none')) {
1186
+ if (!this.authChallengeSeen && !this.checkRequireAuth("none")) {
1183
1187
  return;
1184
1188
  }
1185
- this.state = 'await-ready';
1189
+ this.state = "await-ready";
1186
1190
  return;
1187
1191
  }
1188
- case 'AuthenticationCleartextPassword': {
1192
+ case "AuthenticationCleartextPassword": {
1189
1193
  this.authChallengeSeen = true;
1190
- if (this.opts.channelBinding === 'require') {
1194
+ if (this.opts.channelBinding === "require") {
1191
1195
  this.failStartup(new Error("channel binding required but not supported by server's authentication request"));
1192
1196
  return;
1193
1197
  }
1194
- if (!this.checkRequireAuth('password'))
1198
+ if (!this.checkRequireAuth("password"))
1195
1199
  return;
1196
1200
  if (this.opts.password === undefined) {
1197
- this.failStartup(new Error('Server requested cleartext password but no password was provided'));
1201
+ this.failStartup(new Error("Server requested cleartext password but no password was provided"));
1198
1202
  return;
1199
1203
  }
1200
1204
  this.passwordUsed = true;
1201
1205
  this.socket.write(PasswordMessage(this.opts.password));
1202
1206
  return;
1203
1207
  }
1204
- case 'AuthenticationMD5Password': {
1208
+ case "AuthenticationMD5Password": {
1205
1209
  this.authChallengeSeen = true;
1206
- if (this.opts.channelBinding === 'require') {
1210
+ if (this.opts.channelBinding === "require") {
1207
1211
  this.failStartup(new Error("channel binding required but not supported by server's authentication request"));
1208
1212
  return;
1209
1213
  }
1210
- if (!this.checkRequireAuth('md5'))
1214
+ if (!this.checkRequireAuth("md5"))
1211
1215
  return;
1212
1216
  if (this.opts.password === undefined) {
1213
- this.failStartup(new Error('Server requested MD5 password but no password was provided'));
1217
+ this.failStartup(new Error("Server requested MD5 password but no password was provided"));
1214
1218
  return;
1215
1219
  }
1216
1220
  const payload = md5AuthPayload(this.opts.user, this.opts.password, msg.salt);
@@ -1218,24 +1222,24 @@ export class PgConnection {
1218
1222
  this.socket.write(PasswordMessage(payload));
1219
1223
  return;
1220
1224
  }
1221
- case 'AuthenticationSASL': {
1225
+ case "AuthenticationSASL": {
1222
1226
  this.authChallengeSeen = true;
1223
1227
  if (this.opts.password === undefined) {
1224
- this.failStartup(new Error('Server requested SASL auth but no password was provided'));
1228
+ this.failStartup(new Error("Server requested SASL auth but no password was provided"));
1225
1229
  return;
1226
1230
  }
1227
- if (!this.checkRequireAuth('scram-sha-256'))
1231
+ if (!this.checkRequireAuth("scram-sha-256"))
1228
1232
  return;
1229
1233
  // channel_binding=require AND server didn't offer the PLUS
1230
1234
  // variant — refuse before the SASL handshake starts. The check
1231
1235
  // is split between here (no PLUS in the mechanism list) and
1232
1236
  // chooseMechanism's fallback (PLUS present but no binding data).
1233
- if (this.opts.channelBinding === 'require' &&
1234
- !msg.mechanisms.includes('SCRAM-SHA-256-PLUS')) {
1237
+ if (this.opts.channelBinding === "require" &&
1238
+ !msg.mechanisms.includes("SCRAM-SHA-256-PLUS")) {
1235
1239
  this.failStartup(new Error("channel binding required but not supported by server's authentication request"));
1236
1240
  return;
1237
1241
  }
1238
- if (this.opts.channelBinding === 'require' &&
1242
+ if (this.opts.channelBinding === "require" &&
1239
1243
  this.channelBindingData === null) {
1240
1244
  this.failStartup(new Error("channel binding required but not supported by server's authentication request"));
1241
1245
  return;
@@ -1246,9 +1250,9 @@ export class PgConnection {
1246
1250
  password: this.opts.password,
1247
1251
  mechanisms: msg.mechanisms,
1248
1252
  channelBinding: this.channelBindingData !== null &&
1249
- this.opts.channelBinding !== 'disable'
1253
+ this.opts.channelBinding !== "disable"
1250
1254
  ? {
1251
- type: 'tls-server-end-point',
1255
+ type: "tls-server-end-point",
1252
1256
  data: this.channelBindingData,
1253
1257
  }
1254
1258
  : undefined,
@@ -1262,9 +1266,9 @@ export class PgConnection {
1262
1266
  }
1263
1267
  return;
1264
1268
  }
1265
- case 'AuthenticationSASLContinue': {
1269
+ case "AuthenticationSASLContinue": {
1266
1270
  if (!this.scram) {
1267
- this.failStartup(new Error('Received AuthenticationSASLContinue without an active SCRAM client'));
1271
+ this.failStartup(new Error("Received AuthenticationSASLContinue without an active SCRAM client"));
1268
1272
  return;
1269
1273
  }
1270
1274
  try {
@@ -1276,9 +1280,9 @@ export class PgConnection {
1276
1280
  }
1277
1281
  return;
1278
1282
  }
1279
- case 'AuthenticationSASLFinal': {
1283
+ case "AuthenticationSASLFinal": {
1280
1284
  if (!this.scram) {
1281
- this.failStartup(new Error('Received AuthenticationSASLFinal without an active SCRAM client'));
1285
+ this.failStartup(new Error("Received AuthenticationSASLFinal without an active SCRAM client"));
1282
1286
  return;
1283
1287
  }
1284
1288
  try {
@@ -1290,10 +1294,10 @@ export class PgConnection {
1290
1294
  }
1291
1295
  return;
1292
1296
  }
1293
- case 'ErrorResponse':
1297
+ case "ErrorResponse":
1294
1298
  this.failStartup(fieldsToConnectError(msg.fields));
1295
1299
  return;
1296
- case 'NoticeResponse':
1300
+ case "NoticeResponse":
1297
1301
  this.notify.emit(fieldsToNotice(msg.fields));
1298
1302
  return;
1299
1303
  default:
@@ -1306,19 +1310,19 @@ export class PgConnection {
1306
1310
  }
1307
1311
  handleAwaitReady(msg) {
1308
1312
  switch (msg.type) {
1309
- case 'ParameterStatus':
1313
+ case "ParameterStatus":
1310
1314
  this.params.set(msg.name, msg.value);
1311
- if (msg.name === 'server_version') {
1315
+ if (msg.name === "server_version") {
1312
1316
  this.serverVersion = parseServerVersion(msg.value);
1313
1317
  }
1314
1318
  return;
1315
- case 'BackendKeyData':
1319
+ case "BackendKeyData":
1316
1320
  this.processId = msg.processId;
1317
1321
  this.secretKey = msg.secretKey;
1318
1322
  return;
1319
- case 'ReadyForQuery':
1323
+ case "ReadyForQuery":
1320
1324
  this.txStatus = msg.status;
1321
- this.state = 'idle';
1325
+ this.state = "idle";
1322
1326
  if (this.startupResolve) {
1323
1327
  const r = this.startupResolve;
1324
1328
  this.startupResolve = null;
@@ -1326,10 +1330,10 @@ export class PgConnection {
1326
1330
  r();
1327
1331
  }
1328
1332
  return;
1329
- case 'ErrorResponse':
1333
+ case "ErrorResponse":
1330
1334
  this.failStartup(fieldsToConnectError(msg.fields));
1331
1335
  return;
1332
- case 'NoticeResponse':
1336
+ case "NoticeResponse":
1333
1337
  this.notify.emit(fieldsToNotice(msg.fields));
1334
1338
  return;
1335
1339
  default:
@@ -1350,7 +1354,7 @@ export class PgConnection {
1350
1354
  catch {
1351
1355
  // ignore
1352
1356
  }
1353
- this.state = 'closed';
1357
+ this.state = "closed";
1354
1358
  }
1355
1359
  // -------------------------------------------------------------------------
1356
1360
  // COPY state machine (WP-16).
@@ -1370,17 +1374,19 @@ export class PgConnection {
1370
1374
  makeCopyInStream() {
1371
1375
  const driver = this.copyIn;
1372
1376
  if (!driver) {
1373
- throw new Error('PgConnection: makeCopyInStream called without driver');
1377
+ throw new Error("PgConnection: makeCopyInStream called without driver");
1374
1378
  }
1375
1379
  return {
1376
1380
  write: (chunk) => {
1377
- if (this.state === 'closed') {
1378
- return Promise.reject(new Error('Connection closed'));
1381
+ if (this.state === "closed") {
1382
+ return Promise.reject(new Error("Connection closed"));
1379
1383
  }
1380
1384
  if (driver.closed) {
1381
- return Promise.reject(new Error('CopyInStream already closed'));
1385
+ return Promise.reject(new Error("CopyInStream already closed"));
1382
1386
  }
1383
- const data = typeof chunk === 'string' ? Buffer.from(chunk, 'utf8') : chunk;
1387
+ const data = typeof chunk === "string"
1388
+ ? Buffer.from(chunk, "utf8")
1389
+ : chunk;
1384
1390
  return new Promise((resolve, reject) => {
1385
1391
  this.socket.write(CopyData(data), (err) => {
1386
1392
  if (err)
@@ -1392,7 +1398,7 @@ export class PgConnection {
1392
1398
  },
1393
1399
  end: () => {
1394
1400
  if (driver.closed) {
1395
- return Promise.reject(new Error('CopyInStream already closed'));
1401
+ return Promise.reject(new Error("CopyInStream already closed"));
1396
1402
  }
1397
1403
  driver.closed = true;
1398
1404
  return new Promise((resolve, reject) => {
@@ -1403,7 +1409,7 @@ export class PgConnection {
1403
1409
  },
1404
1410
  fail: (reason) => {
1405
1411
  if (driver.closed) {
1406
- return Promise.reject(new Error('CopyInStream already closed'));
1412
+ return Promise.reject(new Error("CopyInStream already closed"));
1407
1413
  }
1408
1414
  driver.closed = true;
1409
1415
  return new Promise((resolve, reject) => {
@@ -1422,11 +1428,11 @@ export class PgConnection {
1422
1428
  makeCopyOutStream() {
1423
1429
  const driver = this.copyOut;
1424
1430
  if (!driver) {
1425
- throw new Error('PgConnection: makeCopyOutStream called without driver');
1431
+ throw new Error("PgConnection: makeCopyOutStream called without driver");
1426
1432
  }
1427
1433
  // Capture the state-getter as a closure so the iterator can observe
1428
1434
  // connection close without holding a `this` alias (no-this-alias rule).
1429
- const isClosed = () => this.state === 'closed';
1435
+ const isClosed = () => this.state === "closed";
1430
1436
  // Resume reading once the buffered data drains — paired with the
1431
1437
  // pause() the CopyData handler applies at the high-water mark (#11).
1432
1438
  const resumeSocket = () => {
@@ -1451,14 +1457,15 @@ export class PgConnection {
1451
1457
  // wants a real Error. Wrap once before throwing.
1452
1458
  const ce = driver.error;
1453
1459
  const wrapped = new Error(ce.message);
1454
- wrapped.cause = ce;
1460
+ wrapped.cause =
1461
+ ce;
1455
1462
  throw wrapped;
1456
1463
  }
1457
1464
  if (driver.done) {
1458
1465
  return { value: undefined, done: true };
1459
1466
  }
1460
1467
  if (isClosed()) {
1461
- throw new Error('Connection closed mid-COPY-OUT');
1468
+ throw new Error("Connection closed mid-COPY-OUT");
1462
1469
  }
1463
1470
  await new Promise((resolve) => {
1464
1471
  driver.waker = resolve;
@@ -1476,7 +1483,10 @@ export class PgConnection {
1476
1483
  driver.queue.length = 0;
1477
1484
  driver.queuedBytes = 0;
1478
1485
  resumeSocket();
1479
- return Promise.resolve({ value: undefined, done: true });
1486
+ return Promise.resolve({
1487
+ value: undefined,
1488
+ done: true,
1489
+ });
1480
1490
  },
1481
1491
  };
1482
1492
  },
@@ -1489,7 +1499,7 @@ export class PgConnection {
1489
1499
  */
1490
1500
  handleCopyStartMessage(msg) {
1491
1501
  switch (msg.type) {
1492
- case 'CopyInResponse':
1502
+ case "CopyInResponse":
1493
1503
  // COPY-in-pipeline: libpq aborts the connection with this exact
1494
1504
  // diagnostic (matching upstream psql's behaviour). The `\copy`
1495
1505
  // command layer detects pipeline-active and fails fast before
@@ -1500,7 +1510,7 @@ export class PgConnection {
1500
1510
  return;
1501
1511
  }
1502
1512
  if (this.copyIn) {
1503
- this.state = 'in-copy-in';
1513
+ this.state = "in-copy-in";
1504
1514
  const r = this.copyStartResolve;
1505
1515
  this.copyStartResolve = null;
1506
1516
  this.copyStartReject = null;
@@ -1508,13 +1518,13 @@ export class PgConnection {
1508
1518
  r();
1509
1519
  }
1510
1520
  return;
1511
- case 'CopyOutResponse':
1521
+ case "CopyOutResponse":
1512
1522
  if (this._extPipelineActive) {
1513
1523
  this.abortForCopyInPipeline();
1514
1524
  return;
1515
1525
  }
1516
1526
  if (this.copyOut) {
1517
- this.state = 'in-copy-out';
1527
+ this.state = "in-copy-out";
1518
1528
  const r = this.copyStartResolve;
1519
1529
  this.copyStartResolve = null;
1520
1530
  this.copyStartReject = null;
@@ -1522,7 +1532,7 @@ export class PgConnection {
1522
1532
  r();
1523
1533
  }
1524
1534
  return;
1525
- case 'ErrorResponse': {
1535
+ case "ErrorResponse": {
1526
1536
  const err = fieldsToConnectError(msg.fields);
1527
1537
  if (this.copyIn) {
1528
1538
  if (this.copyStartReject)
@@ -1541,17 +1551,17 @@ export class PgConnection {
1541
1551
  // Stay in `in-query` until ReadyForQuery, then return to idle below.
1542
1552
  return;
1543
1553
  }
1544
- case 'ReadyForQuery':
1554
+ case "ReadyForQuery":
1545
1555
  // ReadyForQuery without a prior CopyXxxResponse means the server
1546
1556
  // immediately rejected the COPY (we surfaced the ErrorResponse just
1547
1557
  // above) — return to idle so the next command can fire.
1548
1558
  this.txStatus = msg.status;
1549
- this.state = 'idle';
1559
+ this.state = "idle";
1550
1560
  return;
1551
- case 'NoticeResponse':
1561
+ case "NoticeResponse":
1552
1562
  this.notify.emit(fieldsToNotice(msg.fields));
1553
1563
  return;
1554
- case 'ParameterStatus':
1564
+ case "ParameterStatus":
1555
1565
  this.params.set(msg.name, msg.value);
1556
1566
  return;
1557
1567
  default:
@@ -1568,22 +1578,22 @@ export class PgConnection {
1568
1578
  if (!driver)
1569
1579
  return;
1570
1580
  switch (msg.type) {
1571
- case 'CommandComplete':
1581
+ case "CommandComplete":
1572
1582
  driver.commandTag = msg.tag;
1573
1583
  this.lastCopyTag = msg.tag;
1574
1584
  return;
1575
- case 'ErrorResponse':
1585
+ case "ErrorResponse":
1576
1586
  driver.error = fieldsToConnectError(msg.fields);
1577
1587
  return;
1578
- case 'NoticeResponse':
1588
+ case "NoticeResponse":
1579
1589
  this.notify.emit(fieldsToNotice(msg.fields));
1580
1590
  return;
1581
- case 'ParameterStatus':
1591
+ case "ParameterStatus":
1582
1592
  this.params.set(msg.name, msg.value);
1583
1593
  return;
1584
- case 'ReadyForQuery':
1594
+ case "ReadyForQuery":
1585
1595
  this.txStatus = msg.status;
1586
- this.state = 'idle';
1596
+ this.state = "idle";
1587
1597
  this.copyIn = null;
1588
1598
  if (driver.error) {
1589
1599
  if (driver.rejectDone)
@@ -1597,7 +1607,7 @@ export class PgConnection {
1597
1607
  // Unknown messages mid-COPY-IN are protocol errors; record and let
1598
1608
  // the trailing ReadyForQuery flush the state.
1599
1609
  driver.error = {
1600
- severity: 'ERROR',
1610
+ severity: "ERROR",
1601
1611
  message: `Unexpected backend message during COPY IN: ${msg.type}`,
1602
1612
  };
1603
1613
  return;
@@ -1608,7 +1618,7 @@ export class PgConnection {
1608
1618
  if (!driver)
1609
1619
  return;
1610
1620
  switch (msg.type) {
1611
- case 'CopyData': {
1621
+ case "CopyData": {
1612
1622
  // Consumer broke early: drop instead of buffering (review item #11).
1613
1623
  if (driver.abandoned)
1614
1624
  return;
@@ -1627,27 +1637,27 @@ export class PgConnection {
1627
1637
  }
1628
1638
  return;
1629
1639
  }
1630
- case 'CopyDone':
1640
+ case "CopyDone":
1631
1641
  // Server signals it's done sending — we now expect CommandComplete +
1632
1642
  // ReadyForQuery. Stay in in-copy-out until ReadyForQuery; the queue
1633
1643
  // may still drain via the consumer.
1634
1644
  return;
1635
- case 'CommandComplete':
1645
+ case "CommandComplete":
1636
1646
  driver.commandTag = msg.tag;
1637
1647
  this.lastCopyTag = msg.tag;
1638
1648
  return;
1639
- case 'ErrorResponse':
1649
+ case "ErrorResponse":
1640
1650
  driver.error = fieldsToConnectError(msg.fields);
1641
1651
  return;
1642
- case 'NoticeResponse':
1652
+ case "NoticeResponse":
1643
1653
  this.notify.emit(fieldsToNotice(msg.fields));
1644
1654
  return;
1645
- case 'ParameterStatus':
1655
+ case "ParameterStatus":
1646
1656
  this.params.set(msg.name, msg.value);
1647
1657
  return;
1648
- case 'ReadyForQuery':
1658
+ case "ReadyForQuery":
1649
1659
  this.txStatus = msg.status;
1650
- this.state = 'idle';
1660
+ this.state = "idle";
1651
1661
  driver.done = true;
1652
1662
  this.copyOut = null;
1653
1663
  if (driver.waker) {
@@ -1658,7 +1668,7 @@ export class PgConnection {
1658
1668
  return;
1659
1669
  default:
1660
1670
  driver.error = {
1661
- severity: 'ERROR',
1671
+ severity: "ERROR",
1662
1672
  message: `Unexpected backend message during COPY OUT: ${msg.type}`,
1663
1673
  };
1664
1674
  if (driver.waker) {
@@ -1681,9 +1691,9 @@ export class PgConnection {
1681
1691
  return;
1682
1692
  }
1683
1693
  switch (msg.type) {
1684
- case 'RowDescription':
1694
+ case "RowDescription":
1685
1695
  q.current = {
1686
- command: '',
1696
+ command: "",
1687
1697
  rowCount: null,
1688
1698
  oid: null,
1689
1699
  fields: msg.fields,
@@ -1691,12 +1701,12 @@ export class PgConnection {
1691
1701
  notices: [],
1692
1702
  };
1693
1703
  return;
1694
- case 'DataRow': {
1704
+ case "DataRow": {
1695
1705
  if (!q.current) {
1696
1706
  // Server sent rows without a prior description — extremely rare
1697
1707
  // (only for some legacy COPY error paths). Treat as empty desc.
1698
1708
  q.current = {
1699
- command: '',
1709
+ command: "",
1700
1710
  rowCount: null,
1701
1711
  oid: null,
1702
1712
  fields: [],
@@ -1707,7 +1717,7 @@ export class PgConnection {
1707
1717
  q.current.rows.push(decodeDataRow(msg.values, q.current.fields));
1708
1718
  return;
1709
1719
  }
1710
- case 'CommandComplete': {
1720
+ case "CommandComplete": {
1711
1721
  const { command, rowCount, oid } = parseCommandTag(msg.tag);
1712
1722
  const set = q.current ?? {
1713
1723
  command,
@@ -1725,9 +1735,9 @@ export class PgConnection {
1725
1735
  q.current = null;
1726
1736
  return;
1727
1737
  }
1728
- case 'EmptyQueryResponse': {
1738
+ case "EmptyQueryResponse": {
1729
1739
  const set = {
1730
- command: '',
1740
+ command: "",
1731
1741
  rowCount: null,
1732
1742
  oid: null,
1733
1743
  fields: [],
@@ -1738,30 +1748,30 @@ export class PgConnection {
1738
1748
  q.current = null;
1739
1749
  return;
1740
1750
  }
1741
- case 'ParameterStatus':
1751
+ case "ParameterStatus":
1742
1752
  this.params.set(msg.name, msg.value);
1743
- if (msg.name === 'server_version') {
1753
+ if (msg.name === "server_version") {
1744
1754
  this.serverVersion = parseServerVersion(msg.value);
1745
1755
  }
1746
1756
  return;
1747
- case 'NoticeResponse': {
1757
+ case "NoticeResponse": {
1748
1758
  const notice = fieldsToNotice(msg.fields);
1749
1759
  q.notices.push(notice);
1750
1760
  this.notify.emit(notice);
1751
1761
  return;
1752
1762
  }
1753
- case 'NotificationResponse':
1763
+ case "NotificationResponse":
1754
1764
  this.notify.emitNotification(msg.channel, msg.payload, msg.processId);
1755
1765
  return;
1756
- case 'ErrorResponse': {
1766
+ case "ErrorResponse": {
1757
1767
  q.error = fieldsToConnectError(msg.fields);
1758
1768
  // Don't reject yet — ReadyForQuery will arrive shortly and we want
1759
1769
  // to drain queued NoticeResponse messages first.
1760
1770
  return;
1761
1771
  }
1762
- case 'ReadyForQuery': {
1772
+ case "ReadyForQuery": {
1763
1773
  this.txStatus = msg.status;
1764
- this.state = 'idle';
1774
+ this.state = "idle";
1765
1775
  this.pendingQuery = null;
1766
1776
  if (q.error) {
1767
1777
  // Mirror libpq's behaviour: the result list contains every
@@ -1772,8 +1782,7 @@ export class PgConnection {
1772
1782
  // (`executeAndPrint`) can render the pre-error rows in order
1773
1783
  // before printing the error itself.
1774
1784
  const err = asThrowable(q.error);
1775
- err.partialResults =
1776
- q.finished;
1785
+ err.partialResults = q.finished;
1777
1786
  q.reject(err);
1778
1787
  }
1779
1788
  else {
@@ -1781,7 +1790,7 @@ export class PgConnection {
1781
1790
  }
1782
1791
  return;
1783
1792
  }
1784
- case 'CopyInResponse': {
1793
+ case "CopyInResponse": {
1785
1794
  // PG 17 added pipeline + COPY support but libpq still rejects the
1786
1795
  // combination ("COPY in a pipeline is not supported, aborting
1787
1796
  // connection"). Upstream psql surfaces that diagnostic and tears down
@@ -1817,11 +1826,11 @@ export class PgConnection {
1817
1826
  return;
1818
1827
  }
1819
1828
  q.error = {
1820
- severity: 'ERROR',
1821
- message: 'COPY FROM STDIN not supported via execSimple — use \\copy or startCopyIn',
1829
+ severity: "ERROR",
1830
+ message: "COPY FROM STDIN not supported via execSimple — use \\copy or startCopyIn",
1822
1831
  };
1823
1832
  try {
1824
- this.socket.write(CopyFail('COPY FROM STDIN not driven by client'));
1833
+ this.socket.write(CopyFail("COPY FROM STDIN not driven by client"));
1825
1834
  }
1826
1835
  catch {
1827
1836
  // Write failures are surfaced via socket 'error' / 'close' handlers
@@ -1829,7 +1838,7 @@ export class PgConnection {
1829
1838
  }
1830
1839
  return;
1831
1840
  }
1832
- case 'CopyOutResponse': {
1841
+ case "CopyOutResponse": {
1833
1842
  if (this._extPipelineActive) {
1834
1843
  this.abortForCopyInPipeline();
1835
1844
  return;
@@ -1844,7 +1853,7 @@ export class PgConnection {
1844
1853
  // rendered yet (see hunk 5722-5730 in regress/psql).
1845
1854
  this.copyOutMidBatchActive = true;
1846
1855
  q.current = q.current ?? {
1847
- command: '',
1856
+ command: "",
1848
1857
  rowCount: null,
1849
1858
  oid: null,
1850
1859
  fields: [],
@@ -1854,7 +1863,7 @@ export class PgConnection {
1854
1863
  q.current.copyOutBytes = q.current.copyOutBytes ?? [];
1855
1864
  return;
1856
1865
  }
1857
- case 'CopyData': {
1866
+ case "CopyData": {
1858
1867
  // CopyData arrives during execSimple only when we're in the mid-batch
1859
1868
  // COPY-OUT phase (CopyOutResponse flipped the flag above). Stash the
1860
1869
  // payload on the current result's `copyOutBytes` so the caller can
@@ -1868,12 +1877,12 @@ export class PgConnection {
1868
1877
  return;
1869
1878
  }
1870
1879
  q.error = {
1871
- severity: 'ERROR',
1872
- message: 'Unexpected backend message during query: CopyData',
1880
+ severity: "ERROR",
1881
+ message: "Unexpected backend message during query: CopyData",
1873
1882
  };
1874
1883
  return;
1875
1884
  }
1876
- case 'CopyDone': {
1885
+ case "CopyDone": {
1877
1886
  // Server signals end of COPY-OUT data — next message will be
1878
1887
  // CommandComplete for the COPY statement, then the batch resumes.
1879
1888
  if (this.copyOutMidBatchActive) {
@@ -1881,12 +1890,12 @@ export class PgConnection {
1881
1890
  return;
1882
1891
  }
1883
1892
  q.error = {
1884
- severity: 'ERROR',
1885
- message: 'Unexpected backend message during query: CopyDone',
1893
+ severity: "ERROR",
1894
+ message: "Unexpected backend message during query: CopyDone",
1886
1895
  };
1887
1896
  return;
1888
1897
  }
1889
- case 'CopyBothResponse': {
1898
+ case "CopyBothResponse": {
1890
1899
  // Walsender (`replication=database` / `replication=true`) commands
1891
1900
  // such as `START_REPLICATION` transition the connection into a
1892
1901
  // CopyBoth streaming phase (WAL records flowing from server +
@@ -1897,9 +1906,9 @@ export class PgConnection {
1897
1906
  // message (matching the conformance assertion) and tear the socket
1898
1907
  // down so the next query / process exit is clean.
1899
1908
  const cbErr = {
1900
- severity: 'ERROR',
1901
- code: '0A000',
1902
- message: 'syntax error: unexpected CopyBothResponse from server (replication streaming is not supported by this client)',
1909
+ severity: "ERROR",
1910
+ code: "0A000",
1911
+ message: "syntax error: unexpected CopyBothResponse from server (replication streaming is not supported by this client)",
1903
1912
  };
1904
1913
  q.error = cbErr;
1905
1914
  q.reject(asThrowable(cbErr));
@@ -1911,14 +1920,14 @@ export class PgConnection {
1911
1920
  catch {
1912
1921
  // ignore
1913
1922
  }
1914
- this.state = 'closed';
1923
+ this.state = "closed";
1915
1924
  return;
1916
1925
  }
1917
1926
  default:
1918
1927
  // Unknown messages during a query are protocol errors but not fatal
1919
1928
  // for the connection — record them.
1920
1929
  q.error = {
1921
- severity: 'ERROR',
1930
+ severity: "ERROR",
1922
1931
  message: `Unexpected backend message during query: ${msg.type}`,
1923
1932
  };
1924
1933
  return;
@@ -1933,7 +1942,8 @@ export class PgConnection {
1933
1942
  messages = this.parser.feed(chunk);
1934
1943
  }
1935
1944
  catch (err) {
1936
- this.socketError = err instanceof Error ? err : new Error(String(err));
1945
+ this.socketError =
1946
+ err instanceof Error ? err : new Error(String(err));
1937
1947
  this.failPending(this.socketError);
1938
1948
  try {
1939
1949
  this.socket.destroy();
@@ -1941,39 +1951,39 @@ export class PgConnection {
1941
1951
  catch {
1942
1952
  // ignore
1943
1953
  }
1944
- this.state = 'closed';
1954
+ this.state = "closed";
1945
1955
  return;
1946
1956
  }
1947
1957
  for (const msg of messages) {
1948
1958
  this.dispatch(msg);
1949
- if (this.state === 'closed')
1959
+ if (this.state === "closed")
1950
1960
  break;
1951
1961
  }
1952
1962
  }
1953
1963
  dispatch(msg) {
1954
1964
  // Async backend messages always allowed. NotificationResponse can arrive
1955
1965
  // in *any* state since LISTEN payloads come in whenever a NOTIFY fires.
1956
- if (msg.type === 'NotificationResponse') {
1966
+ if (msg.type === "NotificationResponse") {
1957
1967
  this.notify.emitNotification(msg.channel, msg.payload, msg.processId);
1958
1968
  return;
1959
1969
  }
1960
1970
  switch (this.state) {
1961
- case 'auth':
1971
+ case "auth":
1962
1972
  this.handleAuthMessage(msg);
1963
1973
  return;
1964
- case 'await-ready':
1974
+ case "await-ready":
1965
1975
  this.handleAwaitReady(msg);
1966
1976
  return;
1967
- case 'idle':
1977
+ case "idle":
1968
1978
  // ParameterStatus changes can arrive asynchronously (SET).
1969
- if (msg.type === 'ParameterStatus') {
1979
+ if (msg.type === "ParameterStatus") {
1970
1980
  this.params.set(msg.name, msg.value);
1971
- if (msg.name === 'server_version') {
1981
+ if (msg.name === "server_version") {
1972
1982
  this.serverVersion = parseServerVersion(msg.value);
1973
1983
  }
1974
1984
  return;
1975
1985
  }
1976
- if (msg.type === 'NoticeResponse') {
1986
+ if (msg.type === "NoticeResponse") {
1977
1987
  this.notify.emit(fieldsToNotice(msg.fields));
1978
1988
  return;
1979
1989
  }
@@ -1986,21 +1996,21 @@ export class PgConnection {
1986
1996
  catch {
1987
1997
  // ignore
1988
1998
  }
1989
- this.state = 'closed';
1999
+ this.state = "closed";
1990
2000
  return;
1991
- case 'in-query':
2001
+ case "in-query":
1992
2002
  this.handleQueryMessage(msg);
1993
2003
  return;
1994
- case 'in-extended':
2004
+ case "in-extended":
1995
2005
  this.handleExtendedMessage(msg);
1996
2006
  return;
1997
- case 'in-copy-in':
2007
+ case "in-copy-in":
1998
2008
  this.handleCopyInMessage(msg);
1999
2009
  return;
2000
- case 'in-copy-out':
2010
+ case "in-copy-out":
2001
2011
  this.handleCopyOutMessage(msg);
2002
2012
  return;
2003
- case 'closed':
2013
+ case "closed":
2004
2014
  return;
2005
2015
  }
2006
2016
  }
@@ -2049,8 +2059,8 @@ export class PgConnection {
2049
2059
  this.copyOut = null;
2050
2060
  d.error =
2051
2061
  err instanceof Error
2052
- ? { severity: 'ERROR', message: err.message }
2053
- : { severity: 'ERROR', message: String(err) };
2062
+ ? { severity: "ERROR", message: err.message }
2063
+ : { severity: "ERROR", message: String(err) };
2054
2064
  if (d.waker) {
2055
2065
  const w = d.waker;
2056
2066
  d.waker = null;
@@ -2059,10 +2069,10 @@ export class PgConnection {
2059
2069
  }
2060
2070
  }
2061
2071
  ensureIdle() {
2062
- if (this.state === 'closed') {
2063
- throw new Error('PgConnection: connection is closed');
2072
+ if (this.state === "closed") {
2073
+ throw new Error("PgConnection: connection is closed");
2064
2074
  }
2065
- if (this.state !== 'idle' && this.state !== 'in-extended') {
2075
+ if (this.state !== "idle" && this.state !== "in-extended") {
2066
2076
  throw new Error(`PgConnection: cannot start query in state ${this.state}`);
2067
2077
  }
2068
2078
  }
@@ -2075,11 +2085,11 @@ export class PgConnection {
2075
2085
  // (Parse/Bind/Describe/Execute/Close/Sync) to the socket.
2076
2086
  // -------------------------------------------------------------------------
2077
2087
  startExtendedBatch() {
2078
- if (this.state === 'idle') {
2079
- this.state = 'in-extended';
2088
+ if (this.state === "idle") {
2089
+ this.state = "in-extended";
2080
2090
  this.extDriver = { queue: [], error: null };
2081
2091
  }
2082
- else if (this.state !== 'in-extended') {
2092
+ else if (this.state !== "in-extended") {
2083
2093
  throw new Error(`PgConnection: cannot start extended batch in state ${this.state}`);
2084
2094
  }
2085
2095
  else if (!this.extDriver) {
@@ -2091,21 +2101,21 @@ export class PgConnection {
2091
2101
  }
2092
2102
  enqueueParse() {
2093
2103
  return this.enqueueOp({
2094
- kind: 'parse',
2104
+ kind: "parse",
2095
2105
  resolve: () => undefined,
2096
2106
  reject: () => undefined,
2097
2107
  });
2098
2108
  }
2099
2109
  enqueueBind() {
2100
2110
  return this.enqueueOp({
2101
- kind: 'bind',
2111
+ kind: "bind",
2102
2112
  resolve: () => undefined,
2103
2113
  reject: () => undefined,
2104
2114
  });
2105
2115
  }
2106
2116
  enqueueDescribeStatement() {
2107
2117
  return this.enqueueOp({
2108
- kind: 'describeS',
2118
+ kind: "describeS",
2109
2119
  resolve: () => undefined,
2110
2120
  reject: () => undefined,
2111
2121
  paramOids: null,
@@ -2113,7 +2123,7 @@ export class PgConnection {
2113
2123
  }
2114
2124
  enqueueDescribePortal() {
2115
2125
  return this.enqueueOp({
2116
- kind: 'describeP',
2126
+ kind: "describeP",
2117
2127
  resolve: () => undefined,
2118
2128
  reject: () => undefined,
2119
2129
  });
@@ -2125,15 +2135,15 @@ export class PgConnection {
2125
2135
  enqueueDescribePortalIntoNextExecute() {
2126
2136
  const driver = this.extDriver;
2127
2137
  if (!driver) {
2128
- return Promise.reject(new Error('enqueueDescribePortalIntoNextExecute: not in extended state'));
2138
+ return Promise.reject(new Error("enqueueDescribePortalIntoNextExecute: not in extended state"));
2129
2139
  }
2130
2140
  return new Promise((resolve, reject) => {
2131
2141
  driver.queue.push({
2132
- kind: 'describeP',
2142
+ kind: "describeP",
2133
2143
  resolve: (v) => {
2134
2144
  const fields = v;
2135
2145
  for (const op of driver.queue) {
2136
- if (op.kind === 'execute' && op.fields === null) {
2146
+ if (op.kind === "execute" && op.fields === null) {
2137
2147
  op.fields = fields;
2138
2148
  break;
2139
2149
  }
@@ -2146,7 +2156,7 @@ export class PgConnection {
2146
2156
  }
2147
2157
  enqueueExecute() {
2148
2158
  return this.enqueueOp({
2149
- kind: 'execute',
2159
+ kind: "execute",
2150
2160
  resolve: () => undefined,
2151
2161
  reject: () => undefined,
2152
2162
  current: null,
@@ -2156,7 +2166,7 @@ export class PgConnection {
2156
2166
  }
2157
2167
  enqueueExecuteWithFields(fields) {
2158
2168
  return this.enqueueOp({
2159
- kind: 'execute',
2169
+ kind: "execute",
2160
2170
  resolve: () => undefined,
2161
2171
  reject: () => undefined,
2162
2172
  current: null,
@@ -2166,21 +2176,21 @@ export class PgConnection {
2166
2176
  }
2167
2177
  enqueueClose() {
2168
2178
  return this.enqueueOp({
2169
- kind: 'close',
2179
+ kind: "close",
2170
2180
  resolve: () => undefined,
2171
2181
  reject: () => undefined,
2172
2182
  });
2173
2183
  }
2174
2184
  enqueueSync() {
2175
2185
  return this.enqueueOp({
2176
- kind: 'sync',
2186
+ kind: "sync",
2177
2187
  resolve: () => undefined,
2178
2188
  reject: () => undefined,
2179
2189
  });
2180
2190
  }
2181
2191
  enqueueOp(opSkeleton) {
2182
2192
  if (!this.extDriver) {
2183
- return Promise.reject(new Error('enqueueOp: not in extended state'));
2193
+ return Promise.reject(new Error("enqueueOp: not in extended state"));
2184
2194
  }
2185
2195
  const driver = this.extDriver;
2186
2196
  return new Promise((resolve, reject) => {
@@ -2194,26 +2204,26 @@ export class PgConnection {
2194
2204
  const driver = this.extDriver;
2195
2205
  if (!driver)
2196
2206
  return;
2197
- if (msg.type === 'ParameterStatus') {
2207
+ if (msg.type === "ParameterStatus") {
2198
2208
  this.params.set(msg.name, msg.value);
2199
- if (msg.name === 'server_version') {
2209
+ if (msg.name === "server_version") {
2200
2210
  this.serverVersion = parseServerVersion(msg.value);
2201
2211
  }
2202
2212
  return;
2203
2213
  }
2204
- if (msg.type === 'NoticeResponse') {
2214
+ if (msg.type === "NoticeResponse") {
2205
2215
  const notice = fieldsToNotice(msg.fields);
2206
2216
  this.notify.emit(notice);
2207
2217
  const head = driver.queue[0];
2208
- if (head && head.kind === 'execute')
2218
+ if (head && head.kind === "execute")
2209
2219
  head.notices.push(notice);
2210
2220
  return;
2211
2221
  }
2212
- if (msg.type === 'NotificationResponse') {
2222
+ if (msg.type === "NotificationResponse") {
2213
2223
  this.notify.emitNotification(msg.channel, msg.payload, msg.processId);
2214
2224
  return;
2215
2225
  }
2216
- if (msg.type === 'ErrorResponse') {
2226
+ if (msg.type === "ErrorResponse") {
2217
2227
  driver.error = fieldsToConnectError(msg.fields);
2218
2228
  // Reject ALL queued non-sync ops eagerly. Upstream server semantics:
2219
2229
  // once a P/B/D/E op errors, the server skips every subsequent message
@@ -2231,7 +2241,7 @@ export class PgConnection {
2231
2241
  let first = true;
2232
2242
  while (driver.queue.length > 0) {
2233
2243
  const head = driver.queue[0];
2234
- if (head.kind === 'sync')
2244
+ if (head.kind === "sync")
2235
2245
  break;
2236
2246
  driver.queue.shift();
2237
2247
  if (first) {
@@ -2252,7 +2262,7 @@ export class PgConnection {
2252
2262
  // and tears the connection down. Mirror that so `\startpipeline +
2253
2263
  // COPY ...` surfaces the expected fatal error rather than hanging
2254
2264
  // on a response the extended driver doesn't know how to consume.
2255
- if (msg.type === 'CopyInResponse' || msg.type === 'CopyOutResponse') {
2265
+ if (msg.type === "CopyInResponse" || msg.type === "CopyOutResponse") {
2256
2266
  this.abortForCopyInPipeline();
2257
2267
  return;
2258
2268
  }
@@ -2269,7 +2279,7 @@ export class PgConnection {
2269
2279
  // `Pipeline aborted, command did not run` (no `ERROR:` prefix).
2270
2280
  while (driver.error !== null) {
2271
2281
  const head = driver.queue[0];
2272
- if (!head || head.kind === 'sync')
2282
+ if (!head || head.kind === "sync")
2273
2283
  break;
2274
2284
  driver.queue.shift();
2275
2285
  head.reject(pipelineAbortedError());
@@ -2280,39 +2290,40 @@ export class PgConnection {
2280
2290
  return;
2281
2291
  }
2282
2292
  switch (msg.type) {
2283
- case 'ParseComplete':
2284
- if (head.kind !== 'parse') {
2285
- this.protocolFail(new Error('ParseComplete arrived but head op is ' + head.kind));
2293
+ case "ParseComplete":
2294
+ if (head.kind !== "parse") {
2295
+ this.protocolFail(new Error("ParseComplete arrived but head op is " + head.kind));
2286
2296
  return;
2287
2297
  }
2288
2298
  driver.queue.shift();
2289
2299
  head.resolve(undefined);
2290
2300
  return;
2291
- case 'BindComplete':
2292
- if (head.kind !== 'bind') {
2293
- this.protocolFail(new Error('BindComplete arrived but head op is ' + head.kind));
2301
+ case "BindComplete":
2302
+ if (head.kind !== "bind") {
2303
+ this.protocolFail(new Error("BindComplete arrived but head op is " + head.kind));
2294
2304
  return;
2295
2305
  }
2296
2306
  driver.queue.shift();
2297
2307
  head.resolve(undefined);
2298
2308
  return;
2299
- case 'CloseComplete':
2300
- if (head.kind !== 'close') {
2301
- this.protocolFail(new Error('CloseComplete arrived but head op is ' + head.kind));
2309
+ case "CloseComplete":
2310
+ if (head.kind !== "close") {
2311
+ this.protocolFail(new Error("CloseComplete arrived but head op is " + head.kind));
2302
2312
  return;
2303
2313
  }
2304
2314
  driver.queue.shift();
2305
2315
  head.resolve(undefined);
2306
2316
  return;
2307
- case 'ParameterDescription':
2308
- if (head.kind !== 'describeS') {
2309
- this.protocolFail(new Error('ParameterDescription arrived but head op is ' + head.kind));
2317
+ case "ParameterDescription":
2318
+ if (head.kind !== "describeS") {
2319
+ this.protocolFail(new Error("ParameterDescription arrived but head op is " +
2320
+ head.kind));
2310
2321
  return;
2311
2322
  }
2312
2323
  head.paramOids = msg.oids;
2313
2324
  return;
2314
- case 'RowDescription':
2315
- if (head.kind === 'describeS') {
2325
+ case "RowDescription":
2326
+ if (head.kind === "describeS") {
2316
2327
  driver.queue.shift();
2317
2328
  head.resolve({
2318
2329
  paramOids: head.paramOids ?? [],
@@ -2320,14 +2331,14 @@ export class PgConnection {
2320
2331
  });
2321
2332
  return;
2322
2333
  }
2323
- if (head.kind === 'describeP') {
2334
+ if (head.kind === "describeP") {
2324
2335
  driver.queue.shift();
2325
2336
  head.resolve(msg.fields);
2326
2337
  return;
2327
2338
  }
2328
- if (head.kind === 'execute') {
2339
+ if (head.kind === "execute") {
2329
2340
  head.current = {
2330
- command: '',
2341
+ command: "",
2331
2342
  rowCount: null,
2332
2343
  oid: null,
2333
2344
  fields: msg.fields,
@@ -2337,30 +2348,33 @@ export class PgConnection {
2337
2348
  head.fields = msg.fields;
2338
2349
  return;
2339
2350
  }
2340
- this.protocolFail(new Error('Unexpected RowDescription at head op ' + head.kind));
2351
+ this.protocolFail(new Error("Unexpected RowDescription at head op " + head.kind));
2341
2352
  return;
2342
- case 'NoData':
2343
- if (head.kind === 'describeS') {
2353
+ case "NoData":
2354
+ if (head.kind === "describeS") {
2344
2355
  driver.queue.shift();
2345
- head.resolve({ paramOids: head.paramOids ?? [], fields: [] });
2356
+ head.resolve({
2357
+ paramOids: head.paramOids ?? [],
2358
+ fields: [],
2359
+ });
2346
2360
  return;
2347
2361
  }
2348
- if (head.kind === 'describeP') {
2362
+ if (head.kind === "describeP") {
2349
2363
  driver.queue.shift();
2350
2364
  head.resolve([]);
2351
2365
  return;
2352
2366
  }
2353
- this.protocolFail(new Error('Unexpected NoData at head op ' + head.kind));
2367
+ this.protocolFail(new Error("Unexpected NoData at head op " + head.kind));
2354
2368
  return;
2355
- case 'DataRow': {
2356
- if (head.kind !== 'execute') {
2357
- this.protocolFail(new Error('DataRow at head op ' + head.kind));
2369
+ case "DataRow": {
2370
+ if (head.kind !== "execute") {
2371
+ this.protocolFail(new Error("DataRow at head op " + head.kind));
2358
2372
  return;
2359
2373
  }
2360
2374
  const fields = head.fields ?? head.current?.fields ?? [];
2361
2375
  if (!head.current) {
2362
2376
  head.current = {
2363
- command: '',
2377
+ command: "",
2364
2378
  rowCount: null,
2365
2379
  oid: null,
2366
2380
  fields,
@@ -2371,9 +2385,9 @@ export class PgConnection {
2371
2385
  head.current.rows.push(decodeDataRow(msg.values, fields));
2372
2386
  return;
2373
2387
  }
2374
- case 'CommandComplete': {
2375
- if (head.kind !== 'execute') {
2376
- this.protocolFail(new Error('CommandComplete at head op ' + head.kind));
2388
+ case "CommandComplete": {
2389
+ if (head.kind !== "execute") {
2390
+ this.protocolFail(new Error("CommandComplete at head op " + head.kind));
2377
2391
  return;
2378
2392
  }
2379
2393
  const { command, rowCount, oid } = parseCommandTag(msg.tag);
@@ -2393,13 +2407,13 @@ export class PgConnection {
2393
2407
  head.resolve(set);
2394
2408
  return;
2395
2409
  }
2396
- case 'EmptyQueryResponse': {
2397
- if (head.kind !== 'execute') {
2398
- this.protocolFail(new Error('EmptyQueryResponse at head op ' + head.kind));
2410
+ case "EmptyQueryResponse": {
2411
+ if (head.kind !== "execute") {
2412
+ this.protocolFail(new Error("EmptyQueryResponse at head op " + head.kind));
2399
2413
  return;
2400
2414
  }
2401
2415
  const set = {
2402
- command: '',
2416
+ command: "",
2403
2417
  rowCount: null,
2404
2418
  oid: null,
2405
2419
  fields: [],
@@ -2410,13 +2424,13 @@ export class PgConnection {
2410
2424
  head.resolve(set);
2411
2425
  return;
2412
2426
  }
2413
- case 'PortalSuspended': {
2414
- if (head.kind !== 'execute') {
2415
- this.protocolFail(new Error('PortalSuspended at head op ' + head.kind));
2427
+ case "PortalSuspended": {
2428
+ if (head.kind !== "execute") {
2429
+ this.protocolFail(new Error("PortalSuspended at head op " + head.kind));
2416
2430
  return;
2417
2431
  }
2418
2432
  const set = head.current ?? {
2419
- command: '',
2433
+ command: "",
2420
2434
  rowCount: null,
2421
2435
  oid: null,
2422
2436
  fields: head.fields ?? [],
@@ -2428,10 +2442,10 @@ export class PgConnection {
2428
2442
  head.resolve(set);
2429
2443
  return;
2430
2444
  }
2431
- case 'ReadyForQuery': {
2445
+ case "ReadyForQuery": {
2432
2446
  this.txStatus = msg.status;
2433
- if (head.kind !== 'sync') {
2434
- this.protocolFail(new Error('ReadyForQuery but head op is ' + head.kind));
2447
+ if (head.kind !== "sync") {
2448
+ this.protocolFail(new Error("ReadyForQuery but head op is " + head.kind));
2435
2449
  return;
2436
2450
  }
2437
2451
  driver.queue.shift();
@@ -2444,7 +2458,7 @@ export class PgConnection {
2444
2458
  head.resolve(undefined);
2445
2459
  }
2446
2460
  if (driver.queue.length === 0 && !this._extPipelineActive) {
2447
- this.state = 'idle';
2461
+ this.state = "idle";
2448
2462
  this.extDriver = null;
2449
2463
  }
2450
2464
  return;
@@ -2463,7 +2477,7 @@ export class PgConnection {
2463
2477
  catch {
2464
2478
  // ignore
2465
2479
  }
2466
- this.state = 'closed';
2480
+ this.state = "closed";
2467
2481
  }
2468
2482
  /**
2469
2483
  * Abort the connection because the server replied with CopyInResponse /
@@ -2476,8 +2490,8 @@ export class PgConnection {
2476
2490
  */
2477
2491
  abortForCopyInPipeline() {
2478
2492
  const err = {
2479
- severity: 'FATAL',
2480
- message: 'COPY in a pipeline is not supported, aborting connection',
2493
+ severity: "FATAL",
2494
+ message: "COPY in a pipeline is not supported, aborting connection",
2481
2495
  };
2482
2496
  this.socketError = new Error(err.message);
2483
2497
  this.failPending(err);
@@ -2487,7 +2501,7 @@ export class PgConnection {
2487
2501
  catch {
2488
2502
  // ignore
2489
2503
  }
2490
- this.state = 'closed';
2504
+ this.state = "closed";
2491
2505
  }
2492
2506
  }
2493
2507
  // -------------------------------------------------------------------------
@@ -2522,7 +2536,7 @@ PgConnection._dnsLookupAll = null;
2522
2536
  * directory. libpq's rule: any value starting with `/` is a path.
2523
2537
  */
2524
2538
  export function isUnixSocketHost(host) {
2525
- return host.startsWith('/');
2539
+ return host.startsWith("/");
2526
2540
  }
2527
2541
  /**
2528
2542
  * Build the actual filesystem path Postgres listens on under a socket
@@ -2594,10 +2608,10 @@ async function expandHostsViaDns(seed) {
2594
2608
  */
2595
2609
  function toSecureVersion(value) {
2596
2610
  switch (value) {
2597
- case 'TLSv1':
2598
- case 'TLSv1.1':
2599
- case 'TLSv1.2':
2600
- case 'TLSv1.3':
2611
+ case "TLSv1":
2612
+ case "TLSv1.1":
2613
+ case "TLSv1.2":
2614
+ case "TLSv1.3":
2601
2615
  return value;
2602
2616
  default:
2603
2617
  return undefined;
@@ -2666,13 +2680,13 @@ export function keepAliveArgs(opts) {
2666
2680
  */
2667
2681
  export function sslKeyBitsFromCipher(name) {
2668
2682
  const upper = name.toUpperCase();
2669
- if (upper.includes('CHACHA20'))
2683
+ if (upper.includes("CHACHA20"))
2670
2684
  return 256;
2671
- if (upper.includes('AES_256') || upper.includes('AES256'))
2685
+ if (upper.includes("AES_256") || upper.includes("AES256"))
2672
2686
  return 256;
2673
- if (upper.includes('AES_128') || upper.includes('AES128'))
2687
+ if (upper.includes("AES_128") || upper.includes("AES128"))
2674
2688
  return 128;
2675
- if (upper.includes('AES_192') || upper.includes('AES192'))
2689
+ if (upper.includes("AES_192") || upper.includes("AES192"))
2676
2690
  return 192;
2677
2691
  const digits = /(\d{2,4})/.exec(upper);
2678
2692
  if (digits) {
@@ -2720,8 +2734,8 @@ addressOverride) {
2720
2734
  const cleanup = () => {
2721
2735
  if (timer)
2722
2736
  clearTimeout(timer);
2723
- socket.removeListener('error', onError);
2724
- socket.removeListener('connect', onConnect);
2737
+ socket.removeListener("error", onError);
2738
+ socket.removeListener("connect", onConnect);
2725
2739
  };
2726
2740
  const onError = (err) => {
2727
2741
  cleanup();
@@ -2731,8 +2745,8 @@ addressOverride) {
2731
2745
  cleanup();
2732
2746
  resolve(socket);
2733
2747
  };
2734
- socket.once('error', onError);
2735
- socket.once('connect', onConnect);
2748
+ socket.once("error", onError);
2749
+ socket.once("connect", onConnect);
2736
2750
  });
2737
2751
  }
2738
2752
  // ---------------------------------------------------------------------------
@@ -2753,7 +2767,7 @@ function decodeDataRow(values, fields) {
2753
2767
  continue;
2754
2768
  }
2755
2769
  const fmt = fields[i]?.format ?? 0;
2756
- out[i] = fmt === 1 ? v : v.toString('utf8');
2770
+ out[i] = fmt === 1 ? v : v.toString("utf8");
2757
2771
  }
2758
2772
  return out;
2759
2773
  }
@@ -2772,7 +2786,7 @@ function parseCommandTag(tag) {
2772
2786
  const insertMatch = /^INSERT (\d+) (\d+)$/.exec(trimmed);
2773
2787
  if (insertMatch) {
2774
2788
  return {
2775
- command: 'INSERT',
2789
+ command: "INSERT",
2776
2790
  oid: parseInt(insertMatch[1], 10),
2777
2791
  rowCount: parseInt(insertMatch[2], 10),
2778
2792
  };
@@ -2797,17 +2811,17 @@ export function encodeParams(values) {
2797
2811
  return null;
2798
2812
  if (Buffer.isBuffer(v))
2799
2813
  return v;
2800
- if (typeof v === 'string')
2814
+ if (typeof v === "string")
2801
2815
  return v;
2802
- if (typeof v === 'boolean')
2803
- return v ? 't' : 'f';
2804
- if (typeof v === 'number' || typeof v === 'bigint')
2816
+ if (typeof v === "boolean")
2817
+ return v ? "t" : "f";
2818
+ if (typeof v === "number" || typeof v === "bigint")
2805
2819
  return v.toString();
2806
2820
  try {
2807
2821
  return JSON.stringify(v);
2808
2822
  }
2809
2823
  catch {
2810
- return '';
2824
+ return "";
2811
2825
  }
2812
2826
  });
2813
2827
  }
@@ -2824,16 +2838,16 @@ export function encodeParams(values) {
2824
2838
  function asThrowable(v) {
2825
2839
  if (v instanceof Error)
2826
2840
  return v;
2827
- if (typeof v === 'object' &&
2841
+ if (typeof v === "object" &&
2828
2842
  v !== null &&
2829
- 'message' in v &&
2830
- typeof v.message === 'string') {
2843
+ "message" in v &&
2844
+ typeof v.message === "string") {
2831
2845
  const source = v;
2832
2846
  const err = new Error(source.message);
2833
2847
  // Copy every own enumerable field (severity, code, detail, hint, …) onto
2834
2848
  // the Error so structural consumers keep working.
2835
2849
  for (const key of Object.keys(source)) {
2836
- if (key === 'message')
2850
+ if (key === "message")
2837
2851
  continue;
2838
2852
  err[key] = source[key];
2839
2853
  }