@steadybrew/postgresjs 4.5.0-rc1 → 4.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steadybrew/postgresjs",
3
- "version": "4.5.0-rc1",
3
+ "version": "4.5.1",
4
4
  "description": "PostgreSQL client for Node.js and Deno, independently maintained by Steady Brew",
5
5
  "type": "module",
6
6
  "module": "src/index.js",
@@ -32,10 +32,10 @@
32
32
  "build:deno": "node transpile.deno.js",
33
33
  "build:cf": "node transpile.cf.js",
34
34
  "test": "npm run test:startup && npm run test:esm && npm run test:cjs && npm run test:deno",
35
- "test:esm": "node tests-startup/run.js --integration && node tests/index.js",
35
+ "test:esm": "node tests-startup/run.js --integration && node tests/index.js && node tests-startup/run.js --reports",
36
36
  "test:startup": "node tests-startup/run.js",
37
37
  "test:tracing": "node tests-tracing/run.js",
38
- "test:cjs": "npm run build:cjs && node tests-startup/run.js --integration --cjs && cd cjs/tests && node index.js && cd ../../",
38
+ "test:cjs": "npm run build:cjs && node tests-startup/run.js --integration --cjs && cd cjs/tests && node index.js && cd ../../ && node tests-startup/run.js --reports --cjs",
39
39
  "test:deno": "npm run test:deno-socket && npm run build:deno && cd deno/tests && deno run --no-lock --allow-all --unsafely-ignore-certificate-errors index.js && cd ../../",
40
40
  "lint": "eslint src && eslint tests && eslint tests-startup --ext .js,.mjs",
41
41
  "prepare": "npm run build",
@@ -45,6 +45,7 @@
45
45
  },
46
46
  "files": [
47
47
  "/UNLICENSE",
48
+ "/docs/api.md",
48
49
  "/cf/src",
49
50
  "/cf/polyfills.js",
50
51
  "/cjs/src",
package/src/connection.js CHANGED
@@ -104,6 +104,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
104
104
  , hostIndex = 0
105
105
  , length = 0
106
106
  , rows = 0
107
+ , copyPaused = false
107
108
  , serverSignature = null
108
109
  , nextWriteTimer = null
109
110
  , incomings = null
@@ -462,6 +463,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
462
463
  query = results = errorResponse = chunk = nextWriteTimer = barrier = null
463
464
  result = new Result()
464
465
  rows = 0
466
+ copyPaused = false
465
467
  nonce = serverSignature = null
466
468
  }
467
469
 
@@ -684,6 +686,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
684
686
 
685
687
  function errored(err) {
686
688
  stream && (stream.destroy(err), stream = null)
689
+ resumeCopy()
687
690
  query && queryError(query, err)
688
691
  }
689
692
 
@@ -800,7 +803,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
800
803
  query.prepared && retryRoutines.has(errorResponse.routine) && delete statements[query.signature]
801
804
  query.retried
802
805
  ? errored(query.retried)
803
- : query.prepared && retryRoutines.has(errorResponse.routine) && query.owner === connection.owner && !barrier
806
+ : query.prepared && retryRoutines.has(errorResponse.routine) && query.owner === connection.owner && !barrier && !query.cancelled
804
807
  && (x[5] !== 69 || endsAbortedState.test(query.string))
805
808
  ? retry(query, errorResponse)
806
809
  : errored(errorResponse)
@@ -814,6 +817,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
814
817
 
815
818
  query = results = errorResponse = null
816
819
  result = new Result()
820
+ rows = 0
817
821
 
818
822
  dispatch('ready')
819
823
  }
@@ -1046,8 +1050,9 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
1046
1050
 
1047
1051
  function mismatchReason(x, xs) {
1048
1052
  return (
1053
+ (x === 'read-write' && xs.in_hot_standby === 'on' && 'is a standby') ||
1049
1054
  (x === 'read-write' && xs.default_transaction_read_only === 'on' && 'is read-only') ||
1050
- (x === 'read-only' && xs.default_transaction_read_only === 'off' && 'is read-write') ||
1055
+ (x === 'read-only' && xs.in_hot_standby === 'off' && xs.default_transaction_read_only === 'off' && 'is read-write') ||
1051
1056
  (x === 'primary' && xs.in_hot_standby === 'on' && 'is a standby') ||
1052
1057
  (x === 'standby' && xs.in_hot_standby === 'off' && 'is a primary') ||
1053
1058
  (x === 'prefer-standby' && xs.in_hot_standby === 'off' && standbyPass() && 'is a primary') ||
@@ -1146,7 +1151,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
1146
1151
 
1147
1152
  function CopyOutResponse() {
1148
1153
  stream = new Stream.Readable({
1149
- read() { socket.resume() }
1154
+ read() { copyPaused = false; socket.resume() }
1150
1155
  })
1151
1156
  query.resolve(stream)
1152
1157
  connection.owner && connection.owner.next()
@@ -1156,7 +1161,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
1156
1161
  function CopyBothResponse() {
1157
1162
  stream = new Stream.Duplex({
1158
1163
  autoDestroy: true,
1159
- read() { socket.resume() },
1164
+ read() { copyPaused = false; socket.resume() },
1160
1165
  /* c8 ignore next 11 */
1161
1166
  write(chunk, encoding, callback) {
1162
1167
  socket.write(b().d().raw(chunk).end(), callback)
@@ -1176,12 +1181,23 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
1176
1181
  }
1177
1182
 
1178
1183
  function CopyData(x) {
1179
- stream && (stream.push(x.subarray(5)) || socket.pause())
1184
+ if (stream && !stream.push(x.subarray(5))) {
1185
+ copyPaused = true
1186
+ socket.pause()
1187
+ }
1180
1188
  }
1181
1189
 
1182
1190
  function CopyDone() {
1183
1191
  stream && stream.push(null)
1184
1192
  stream = null
1193
+ resumeCopy()
1194
+ }
1195
+
1196
+ function resumeCopy() {
1197
+ if (copyPaused) {
1198
+ copyPaused = false
1199
+ socket.resume()
1200
+ }
1185
1201
  }
1186
1202
 
1187
1203
  function NoticeResponse(x) {
package/src/errors.js CHANGED
@@ -1,8 +1,8 @@
1
1
  export class PostgresError extends Error {
2
2
  constructor(x) {
3
- super(x.message)
3
+ super(typeof x === 'string' ? x : x.message)
4
4
  this.name = this.constructor.name
5
- Object.assign(this, x)
5
+ typeof x === 'string' || Object.assign(this, x)
6
6
  }
7
7
  }
8
8
 
package/src/index.js CHANGED
@@ -702,8 +702,8 @@ function parseOptions(a, b) {
702
702
  ...Object.entries(defaults).reduce(
703
703
  (acc, [k, d]) => {
704
704
  const value = k in o ? o[k] : k in query
705
- ? (query[k] === 'disable' || query[k] === 'false' ? false : query[k])
706
- : env['PG' + k.toUpperCase()] || d
705
+ ? off(query[k])
706
+ : env['PG' + k.toUpperCase()] ? off(env['PG' + k.toUpperCase()]) : d
707
707
  acc[k] = typeof value === 'string' && ints.includes(k)
708
708
  ? +value
709
709
  : value
@@ -736,6 +736,10 @@ function parseOptions(a, b) {
736
736
  return options
737
737
  }
738
738
 
739
+ function off(x) {
740
+ return x === 'disable' || x === 'false' ? false : x
741
+ }
742
+
739
743
  function tsa(o, url, env) {
740
744
  const x = o.target_session_attrs || url.searchParams.get('target_session_attrs') || env.PGTARGETSESSIONATTRS
741
745
  if (!x || ['read-write', 'read-only', 'primary', 'standby', 'prefer-standby'].includes(x))
package/src/query.js CHANGED
@@ -55,6 +55,7 @@ export class Query extends Promise {
55
55
  if (!this.canceller || this.settled)
56
56
  return Promise.resolve()
57
57
 
58
+ Promise.prototype.then.call(this, undefined, () => undefined)
58
59
  const cancelled = this.canceller(this)
59
60
  this.canceller = null
60
61
  cancelled.catch(() => undefined)
package/src/types.js CHANGED
@@ -346,14 +346,14 @@ function arrayParserLoop(s, x, parser, typarray) {
346
346
  export const toCamel = x => {
347
347
  let str = x[0]
348
348
  for (let i = 1; i < x.length; i++)
349
- str += x[i] === '_' ? x[++i].toUpperCase() : x[i]
349
+ str += x[i] === '_' && i + 1 < x.length ? x[++i].toUpperCase() : x[i]
350
350
  return str
351
351
  }
352
352
 
353
353
  export const toPascal = x => {
354
354
  let str = x[0].toUpperCase()
355
355
  for (let i = 1; i < x.length; i++)
356
- str += x[i] === '_' ? x[++i].toUpperCase() : x[i]
356
+ str += x[i] === '_' && i + 1 < x.length ? x[++i].toUpperCase() : x[i]
357
357
  return str
358
358
  }
359
359
 
package/types/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Readable, Writable } from 'node:stream'
1
+ import { Duplex, Readable, Writable } from 'node:stream'
2
2
 
3
3
  /**
4
4
  * Establish a connection to a PostgreSQL server.
@@ -45,6 +45,8 @@ interface BaseOptions<T extends Record<string, postgres.PostgresType>> {
45
45
  * @default false
46
46
  */
47
47
  ssl: 'require' | 'allow' | 'prefer' | 'verify-full' | boolean | object;
48
+ /** Set to 'direct' to start TLS immediately with ALPN instead of sending an SSLRequest first */
49
+ sslnegotiation: 'direct' | 'postgres' | null;
48
50
  /**
49
51
  * Max number of connections
50
52
  * @default 10
@@ -126,6 +128,8 @@ interface BaseOptions<T extends Record<string, postgres.PostgresType>> {
126
128
  backoff: boolean | ((attemptNum: number) => number);
127
129
  max_lifetime: number | null;
128
130
  keep_alive: number | null;
131
+ /** Function, sync or async, returning the socket-like duplex stream to connect through; it receives the parsed options */
132
+ socket?: (options: postgres.ParsedOptions) => Duplex | Promise<Duplex>;
129
133
  }
130
134
 
131
135
 
@@ -203,6 +207,8 @@ type Return<T, K extends readonly any[]> =
203
207
 
204
208
  declare namespace postgres {
205
209
  class PostgresError extends Error {
210
+ constructor(message: string);
211
+ constructor(fields: Partial<Omit<PostgresError, 'name' | 'stack' | 'cause'>>);
206
212
  name: 'PostgresError';
207
213
  severity_local: string;
208
214
  severity: string;