@steadybrew/postgresjs 4.4.1 → 4.5.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.
- package/README.md +271 -20
- package/cf/src/connection.js +62 -19
- package/cf/src/errors.js +2 -2
- package/cf/src/index.js +37 -9
- package/cf/src/query.js +4 -10
- package/cf/src/types.js +7 -2
- package/cjs/src/connection.js +62 -19
- package/cjs/src/errors.js +2 -2
- package/cjs/src/index.js +37 -9
- package/cjs/src/query.js +4 -10
- package/cjs/src/types.js +7 -2
- package/package.json +5 -4
- package/src/connection.js +62 -19
- package/src/errors.js +2 -2
- package/src/index.js +37 -9
- package/src/query.js +4 -10
- package/src/types.js +7 -2
- package/types/index.d.ts +37 -1
- package/types/package.json +1 -1
package/src/connection.js
CHANGED
|
@@ -4,7 +4,7 @@ import crypto from 'crypto'
|
|
|
4
4
|
import Stream from 'stream'
|
|
5
5
|
import { performance } from 'perf_hooks'
|
|
6
6
|
|
|
7
|
-
import { stringify, handleValue, addArrayType } from './types.js'
|
|
7
|
+
import { stringify, handleValue, addArrayType, clientSerialize } from './types.js'
|
|
8
8
|
import { Errors, callback } from './errors.js'
|
|
9
9
|
import Result from './result.js'
|
|
10
10
|
import Queue from './queue.js'
|
|
@@ -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
|
|
@@ -214,7 +215,10 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
214
215
|
const connection = {
|
|
215
216
|
queue: queues.closed,
|
|
216
217
|
idleTimer,
|
|
217
|
-
connect
|
|
218
|
+
// Sentry's hook wraps connect and reads the connection from this, so it must stay a method
|
|
219
|
+
connect(request) {
|
|
220
|
+
dispatch('acquire', request)
|
|
221
|
+
},
|
|
218
222
|
terminate: () => dispatch('terminate'),
|
|
219
223
|
execute,
|
|
220
224
|
release: () => dispatch('release'),
|
|
@@ -459,6 +463,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
459
463
|
query = results = errorResponse = chunk = nextWriteTimer = barrier = null
|
|
460
464
|
result = new Result()
|
|
461
465
|
rows = 0
|
|
466
|
+
copyPaused = false
|
|
462
467
|
nonce = serverSignature = null
|
|
463
468
|
}
|
|
464
469
|
|
|
@@ -538,7 +543,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
538
543
|
|
|
539
544
|
build(q)
|
|
540
545
|
const written = write(toBuffer(q))
|
|
541
|
-
if (q.describeFirst || q.cursorFn || mayCopy(q))
|
|
546
|
+
if (q.describeFirst || q.cursorFn || mayCopy(q) || (q.prepare && !q.prepared && !q.options.simple && q.parameters.length))
|
|
542
547
|
barrier = q
|
|
543
548
|
return written && accepting()
|
|
544
549
|
} catch (error) {
|
|
@@ -576,7 +581,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
576
581
|
|
|
577
582
|
function prepared(q) {
|
|
578
583
|
return Buffer.concat([
|
|
579
|
-
Bind(q
|
|
584
|
+
Bind(q),
|
|
580
585
|
q.cursorFn
|
|
581
586
|
? Execute('', q.cursorRows)
|
|
582
587
|
: ExecuteUnnamed
|
|
@@ -604,8 +609,11 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
604
609
|
q.signature = q.prepare && types + string
|
|
605
610
|
q.onlyDescribe && (delete statements[q.signature])
|
|
606
611
|
q.parameters = q.parameters || parameters
|
|
612
|
+
q.inferred = options.parameter_types === 'server' ? null : types.slice()
|
|
607
613
|
q.prepared = q.prepare && q.signature in statements
|
|
608
|
-
q.describeFirst = q.onlyDescribe || (
|
|
614
|
+
q.describeFirst = q.onlyDescribe || (!q.prepared && types.some((x, i) =>
|
|
615
|
+
!x && (options.parameter_types !== 'client' || Array.isArray(q.parameters[i]))
|
|
616
|
+
))
|
|
609
617
|
q.statement = q.prepared
|
|
610
618
|
? statements[q.signature]
|
|
611
619
|
: { string, types, name: q.prepare ? statementId + statementCount++ : '' }
|
|
@@ -678,6 +686,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
678
686
|
|
|
679
687
|
function errored(err) {
|
|
680
688
|
stream && (stream.destroy(err), stream = null)
|
|
689
|
+
resumeCopy()
|
|
681
690
|
query && queryError(query, err)
|
|
682
691
|
}
|
|
683
692
|
|
|
@@ -689,7 +698,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
689
698
|
err = new Error(err)
|
|
690
699
|
|
|
691
700
|
'query' in err || 'parameters' in err || Object.defineProperties(err, {
|
|
692
|
-
stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug },
|
|
701
|
+
stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug, writable: true, configurable: true },
|
|
693
702
|
query: { value: query.string, enumerable: options.debug },
|
|
694
703
|
parameters: { value: query.parameters, enumerable: options.debug },
|
|
695
704
|
args: { value: query.args, enumerable: options.debug },
|
|
@@ -794,7 +803,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
794
803
|
query.prepared && retryRoutines.has(errorResponse.routine) && delete statements[query.signature]
|
|
795
804
|
query.retried
|
|
796
805
|
? errored(query.retried)
|
|
797
|
-
: 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
|
|
798
807
|
&& (x[5] !== 69 || endsAbortedState.test(query.string))
|
|
799
808
|
? retry(query, errorResponse)
|
|
800
809
|
: errored(errorResponse)
|
|
@@ -808,6 +817,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
808
817
|
|
|
809
818
|
query = results = errorResponse = null
|
|
810
819
|
result = new Result()
|
|
820
|
+
rows = 0
|
|
811
821
|
|
|
812
822
|
dispatch('ready')
|
|
813
823
|
}
|
|
@@ -1040,8 +1050,9 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1040
1050
|
|
|
1041
1051
|
function mismatchReason(x, xs) {
|
|
1042
1052
|
return (
|
|
1053
|
+
(x === 'read-write' && xs.in_hot_standby === 'on' && 'is a standby') ||
|
|
1043
1054
|
(x === 'read-write' && xs.default_transaction_read_only === 'on' && 'is read-only') ||
|
|
1044
|
-
(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') ||
|
|
1045
1056
|
(x === 'primary' && xs.in_hot_standby === 'on' && 'is a standby') ||
|
|
1046
1057
|
(x === 'standby' && xs.in_hot_standby === 'off' && 'is a primary') ||
|
|
1047
1058
|
(x === 'prefer-standby' && xs.in_hot_standby === 'off' && standbyPass() && 'is a primary') ||
|
|
@@ -1140,7 +1151,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1140
1151
|
|
|
1141
1152
|
function CopyOutResponse() {
|
|
1142
1153
|
stream = new Stream.Readable({
|
|
1143
|
-
read() { socket.resume() }
|
|
1154
|
+
read() { copyPaused = false; socket.resume() }
|
|
1144
1155
|
})
|
|
1145
1156
|
query.resolve(stream)
|
|
1146
1157
|
connection.owner && connection.owner.next()
|
|
@@ -1150,7 +1161,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1150
1161
|
function CopyBothResponse() {
|
|
1151
1162
|
stream = new Stream.Duplex({
|
|
1152
1163
|
autoDestroy: true,
|
|
1153
|
-
read() { socket.resume() },
|
|
1164
|
+
read() { copyPaused = false; socket.resume() },
|
|
1154
1165
|
/* c8 ignore next 11 */
|
|
1155
1166
|
write(chunk, encoding, callback) {
|
|
1156
1167
|
socket.write(b().d().raw(chunk).end(), callback)
|
|
@@ -1170,12 +1181,23 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1170
1181
|
}
|
|
1171
1182
|
|
|
1172
1183
|
function CopyData(x) {
|
|
1173
|
-
stream &&
|
|
1184
|
+
if (stream && !stream.push(x.subarray(5))) {
|
|
1185
|
+
copyPaused = true
|
|
1186
|
+
socket.pause()
|
|
1187
|
+
}
|
|
1174
1188
|
}
|
|
1175
1189
|
|
|
1176
1190
|
function CopyDone() {
|
|
1177
1191
|
stream && stream.push(null)
|
|
1178
1192
|
stream = null
|
|
1193
|
+
resumeCopy()
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
function resumeCopy() {
|
|
1197
|
+
if (copyPaused) {
|
|
1198
|
+
copyPaused = false
|
|
1199
|
+
socket.resume()
|
|
1200
|
+
}
|
|
1179
1201
|
}
|
|
1180
1202
|
|
|
1181
1203
|
function NoticeResponse(x) {
|
|
@@ -1213,20 +1235,21 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1213
1235
|
}
|
|
1214
1236
|
|
|
1215
1237
|
/* Messages */
|
|
1216
|
-
function Bind(
|
|
1238
|
+
function Bind(q) {
|
|
1239
|
+
const differences = []
|
|
1217
1240
|
let prev
|
|
1218
1241
|
, type
|
|
1219
1242
|
|
|
1220
|
-
b().B().str(
|
|
1243
|
+
b().B().str((q.cursorName || '') + b.N).str(q.statement.name + b.N).i16(0).i16(q.parameters.length)
|
|
1221
1244
|
|
|
1222
|
-
parameters.forEach((x, i) => {
|
|
1245
|
+
q.parameters.forEach((x, i) => {
|
|
1223
1246
|
if (x === null)
|
|
1224
1247
|
return b.i32(0xFFFFFFFF)
|
|
1225
1248
|
|
|
1226
|
-
type = types[i]
|
|
1227
|
-
x =
|
|
1228
|
-
?
|
|
1229
|
-
: ''
|
|
1249
|
+
type = q.statement.types[i]
|
|
1250
|
+
x = !q.inferred || q.inferred[i] || Array.isArray(x)
|
|
1251
|
+
? serialize(x, type)
|
|
1252
|
+
: options.parameter_types === 'client' ? clientSerialize(x) : compare(x, type, i, differences)
|
|
1230
1253
|
|
|
1231
1254
|
prev = b.i
|
|
1232
1255
|
b.inc(4).str(x).i32(b.i - prev - 4, prev)
|
|
@@ -1234,7 +1257,27 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1234
1257
|
|
|
1235
1258
|
b.i16(0)
|
|
1236
1259
|
|
|
1237
|
-
|
|
1260
|
+
const message = b.end()
|
|
1261
|
+
differences.length && callback(options.ontypemismatch || console.warn, { query: q.string, parameters: differences }) // eslint-disable-line
|
|
1262
|
+
return message
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
function serialize(x, type) {
|
|
1266
|
+
return type in options.serializers
|
|
1267
|
+
? options.serializers[type](x)
|
|
1268
|
+
: '' + x
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
function compare(x, type, i, differences) {
|
|
1272
|
+
const serverText = serialize(x, type)
|
|
1273
|
+
let clientText
|
|
1274
|
+
try {
|
|
1275
|
+
clientText = clientSerialize(x)
|
|
1276
|
+
} catch (error) {
|
|
1277
|
+
clientText = error
|
|
1278
|
+
}
|
|
1279
|
+
serverText === clientText || differences.push({ position: i + 1, oid: type, typeof: typeof x, ...options.debug && { serverText, clientText } })
|
|
1280
|
+
return serverText
|
|
1238
1281
|
}
|
|
1239
1282
|
|
|
1240
1283
|
function Parse(str, parameters, types, name = '') {
|
package/src/errors.js
CHANGED
package/src/index.js
CHANGED
|
@@ -86,7 +86,8 @@ function Postgres(a, b) {
|
|
|
86
86
|
listen,
|
|
87
87
|
begin,
|
|
88
88
|
close,
|
|
89
|
-
end
|
|
89
|
+
end,
|
|
90
|
+
...Symbol.asyncDispose && { [Symbol.asyncDispose]: () => end() }
|
|
90
91
|
})
|
|
91
92
|
|
|
92
93
|
return sql
|
|
@@ -327,10 +328,17 @@ function Postgres(a, b) {
|
|
|
327
328
|
|
|
328
329
|
async function reserve() {
|
|
329
330
|
const l = await lease(false)
|
|
330
|
-
const sql = Sql(
|
|
331
|
+
const sql = Sql(handler)
|
|
331
332
|
sql.release = () => settle(l, Lease.Released)
|
|
333
|
+
Symbol.dispose && (sql[Symbol.dispose] = () => sql.release())
|
|
334
|
+
Symbol.asyncDispose && (sql[Symbol.asyncDispose] = async() => sql.release())
|
|
332
335
|
sql.stats = stats
|
|
333
336
|
return sql
|
|
337
|
+
|
|
338
|
+
// dd-trace starts query spans only inside function declarations named handler
|
|
339
|
+
function handler(q) {
|
|
340
|
+
send(l, q)
|
|
341
|
+
}
|
|
334
342
|
}
|
|
335
343
|
|
|
336
344
|
async function begin(options, fn) {
|
|
@@ -347,7 +355,7 @@ function Postgres(a, b) {
|
|
|
347
355
|
}
|
|
348
356
|
|
|
349
357
|
async function transaction() {
|
|
350
|
-
await Sql(
|
|
358
|
+
await Sql(handler).unsafe('begin ' + options.replace(/[^a-z ]/ig, ''), []).execute().catch(e => {
|
|
351
359
|
e instanceof PostgresError && settle(l, Lease.Released)
|
|
352
360
|
throw e
|
|
353
361
|
})
|
|
@@ -358,7 +366,7 @@ function Postgres(a, b) {
|
|
|
358
366
|
let result
|
|
359
367
|
l.state = Lease.Settling
|
|
360
368
|
try {
|
|
361
|
-
result = await statement(Sql(q =>
|
|
369
|
+
result = await statement(Sql(q => handler(q, Lease.Settling)))
|
|
362
370
|
} catch (e) {
|
|
363
371
|
settle(l, Lease.Discarded)
|
|
364
372
|
throw e
|
|
@@ -368,7 +376,7 @@ function Postgres(a, b) {
|
|
|
368
376
|
}
|
|
369
377
|
|
|
370
378
|
async function scope(fn, name) {
|
|
371
|
-
const sql = Sql(
|
|
379
|
+
const sql = Sql(track)
|
|
372
380
|
sql.savepoint = savepoint
|
|
373
381
|
sql.prepare = x => {
|
|
374
382
|
if (typeof x !== 'string' || !x || x.includes('\0'))
|
|
@@ -422,11 +430,16 @@ function Postgres(a, b) {
|
|
|
422
430
|
return scope(fn, 's' + savepoints++ + (name ? '_' + name : ''))
|
|
423
431
|
}
|
|
424
432
|
|
|
425
|
-
function
|
|
433
|
+
function track(q) {
|
|
426
434
|
q.catch(e => uncaughtError || (uncaughtError = e))
|
|
427
|
-
|
|
435
|
+
handler(q)
|
|
428
436
|
}
|
|
429
437
|
}
|
|
438
|
+
|
|
439
|
+
// dd-trace starts query spans only inside function declarations named handler
|
|
440
|
+
function handler(q, expected) {
|
|
441
|
+
send(l, q, expected)
|
|
442
|
+
}
|
|
430
443
|
}
|
|
431
444
|
|
|
432
445
|
function move(c, queue) {
|
|
@@ -674,6 +687,7 @@ function parseOptions(a, b) {
|
|
|
674
687
|
prepare : true,
|
|
675
688
|
debug : false,
|
|
676
689
|
fetch_types : true,
|
|
690
|
+
parameter_types : 'server',
|
|
677
691
|
publications : 'alltables',
|
|
678
692
|
target_session_attrs: null
|
|
679
693
|
}
|
|
@@ -688,8 +702,8 @@ function parseOptions(a, b) {
|
|
|
688
702
|
...Object.entries(defaults).reduce(
|
|
689
703
|
(acc, [k, d]) => {
|
|
690
704
|
const value = k in o ? o[k] : k in query
|
|
691
|
-
? (query[k]
|
|
692
|
-
: env['PG' + k.toUpperCase()]
|
|
705
|
+
? off(query[k])
|
|
706
|
+
: env['PG' + k.toUpperCase()] ? off(env['PG' + k.toUpperCase()]) : d
|
|
693
707
|
acc[k] = typeof value === 'string' && ints.includes(k)
|
|
694
708
|
? +value
|
|
695
709
|
: value
|
|
@@ -704,11 +718,13 @@ function parseOptions(a, b) {
|
|
|
704
718
|
},
|
|
705
719
|
types : o.types || {},
|
|
706
720
|
target_session_attrs: tsa(o, url, env),
|
|
721
|
+
parameter_types : parameterTypes(o, url, env),
|
|
707
722
|
onnotice : o.onnotice,
|
|
708
723
|
onnotify : o.onnotify,
|
|
709
724
|
onclose : o.onclose,
|
|
710
725
|
onidle : o.onidle,
|
|
711
726
|
onparameter : o.onparameter,
|
|
727
|
+
ontypemismatch : o.ontypemismatch,
|
|
712
728
|
socket : o.socket,
|
|
713
729
|
transform : parseTransform(o.transform || { undefined: undefined }),
|
|
714
730
|
parameters : {},
|
|
@@ -720,6 +736,10 @@ function parseOptions(a, b) {
|
|
|
720
736
|
return options
|
|
721
737
|
}
|
|
722
738
|
|
|
739
|
+
function off(x) {
|
|
740
|
+
return x === 'disable' || x === 'false' ? false : x
|
|
741
|
+
}
|
|
742
|
+
|
|
723
743
|
function tsa(o, url, env) {
|
|
724
744
|
const x = o.target_session_attrs || url.searchParams.get('target_session_attrs') || env.PGTARGETSESSIONATTRS
|
|
725
745
|
if (!x || ['read-write', 'read-only', 'primary', 'standby', 'prefer-standby'].includes(x))
|
|
@@ -728,6 +748,14 @@ function tsa(o, url, env) {
|
|
|
728
748
|
throw new Error('target_session_attrs ' + x + ' is not supported')
|
|
729
749
|
}
|
|
730
750
|
|
|
751
|
+
function parameterTypes(o, url, env) {
|
|
752
|
+
const x = o.parameter_types || url.searchParams.get('parameter_types') || env.PGPARAMETER_TYPES || 'server'
|
|
753
|
+
if (['server', 'client', 'warn'].includes(x))
|
|
754
|
+
return x
|
|
755
|
+
|
|
756
|
+
throw new Error('parameter_types ' + x + ' is not supported')
|
|
757
|
+
}
|
|
758
|
+
|
|
731
759
|
function max_lifetime() {
|
|
732
760
|
return 60 * (30 + Math.random() * 30)
|
|
733
761
|
}
|
package/src/query.js
CHANGED
|
@@ -23,16 +23,9 @@ export class Query extends Promise {
|
|
|
23
23
|
this.state = null
|
|
24
24
|
this.statement = null
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
resolve(x)
|
|
30
|
-
}
|
|
31
|
-
this.reject = x => {
|
|
32
|
-
this.active = false
|
|
33
|
-
this.settled = true
|
|
34
|
-
reject(x)
|
|
35
|
-
}
|
|
26
|
+
// dd-trace's load-time rewrite only accepts single-expression arrows here
|
|
27
|
+
this.resolve = x => (this.active = false, this.settled = true, resolve(x))
|
|
28
|
+
this.reject = x => (this.active = false, this.settled = true, reject(x))
|
|
36
29
|
|
|
37
30
|
this.active = false
|
|
38
31
|
this.settled = false
|
|
@@ -62,6 +55,7 @@ export class Query extends Promise {
|
|
|
62
55
|
if (!this.canceller || this.settled)
|
|
63
56
|
return Promise.resolve()
|
|
64
57
|
|
|
58
|
+
Promise.prototype.then.call(this, undefined, () => undefined)
|
|
65
59
|
const cancelled = this.canceller(this)
|
|
66
60
|
this.canceller = null
|
|
67
61
|
cancelled.catch(() => undefined)
|
package/src/types.js
CHANGED
|
@@ -248,6 +248,11 @@ export const inferType = function inferType(x) {
|
|
|
248
248
|
)
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
+
export function clientSerialize(x) {
|
|
252
|
+
const proto = typeof x === 'object' && Object.getPrototypeOf(x)
|
|
253
|
+
return proto === Object.prototype || proto === null ? JSON.stringify(x) : '' + x
|
|
254
|
+
}
|
|
255
|
+
|
|
251
256
|
const escapeBackslash = /\\/g
|
|
252
257
|
const escapeQuote = /"/g
|
|
253
258
|
|
|
@@ -341,14 +346,14 @@ function arrayParserLoop(s, x, parser, typarray) {
|
|
|
341
346
|
export const toCamel = x => {
|
|
342
347
|
let str = x[0]
|
|
343
348
|
for (let i = 1; i < x.length; i++)
|
|
344
|
-
str += x[i] === '_' ? x[++i].toUpperCase() : x[i]
|
|
349
|
+
str += x[i] === '_' && i + 1 < x.length ? x[++i].toUpperCase() : x[i]
|
|
345
350
|
return str
|
|
346
351
|
}
|
|
347
352
|
|
|
348
353
|
export const toPascal = x => {
|
|
349
354
|
let str = x[0].toUpperCase()
|
|
350
355
|
for (let i = 1; i < x.length; i++)
|
|
351
|
-
str += x[i] === '_' ? x[++i].toUpperCase() : x[i]
|
|
356
|
+
str += x[i] === '_' && i + 1 < x.length ? x[++i].toUpperCase() : x[i]
|
|
352
357
|
return str
|
|
353
358
|
}
|
|
354
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
|
|
@@ -110,6 +112,10 @@ interface BaseOptions<T extends Record<string, postgres.PostgresType>> {
|
|
|
110
112
|
* @default true
|
|
111
113
|
*/
|
|
112
114
|
fetch_types: boolean;
|
|
115
|
+
/** How values whose type cannot be told from the JavaScript value are serialized: 'server' (default) asks PostgreSQL for the placeholder's type first, 'client' sends their text for PostgreSQL to parse, 'warn' does the same as 'server' and reports values 'client' would send differently */
|
|
116
|
+
parameter_types: 'server' | 'client' | 'warn';
|
|
117
|
+
/** Called in parameter_types: 'warn' mode with each query whose values would be sent differently, console.warn by default; if it throws, the error is rethrown as an uncaught exception */
|
|
118
|
+
ontypemismatch: (report: postgres.TypeMismatchReport) => void;
|
|
113
119
|
/**
|
|
114
120
|
* Publications to subscribe to (only relevant when calling `sql.subscribe()`)
|
|
115
121
|
* @default 'alltables'
|
|
@@ -122,6 +128,8 @@ interface BaseOptions<T extends Record<string, postgres.PostgresType>> {
|
|
|
122
128
|
backoff: boolean | ((attemptNum: number) => number);
|
|
123
129
|
max_lifetime: number | null;
|
|
124
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>;
|
|
125
133
|
}
|
|
126
134
|
|
|
127
135
|
|
|
@@ -199,6 +207,8 @@ type Return<T, K extends readonly any[]> =
|
|
|
199
207
|
|
|
200
208
|
declare namespace postgres {
|
|
201
209
|
class PostgresError extends Error {
|
|
210
|
+
constructor(message: string);
|
|
211
|
+
constructor(fields: Partial<Omit<PostgresError, 'name' | 'stack' | 'cause'>>);
|
|
202
212
|
name: 'PostgresError';
|
|
203
213
|
severity_local: string;
|
|
204
214
|
severity: string;
|
|
@@ -411,6 +421,23 @@ declare namespace postgres {
|
|
|
411
421
|
};
|
|
412
422
|
}
|
|
413
423
|
|
|
424
|
+
interface TypeMismatchReport {
|
|
425
|
+
query: string;
|
|
426
|
+
parameters: TypeMismatch[];
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
interface TypeMismatch {
|
|
430
|
+
/** The `$n` number of the placeholder */
|
|
431
|
+
position: number;
|
|
432
|
+
/** The type OID PostgreSQL inferred for the placeholder */
|
|
433
|
+
oid: number;
|
|
434
|
+
typeof: string;
|
|
435
|
+
/** Only set when debug is enabled */
|
|
436
|
+
serverText?: string;
|
|
437
|
+
/** Only set when debug is enabled; the error is what the 'client' mode would throw */
|
|
438
|
+
clientText?: string | globalThis.Error;
|
|
439
|
+
}
|
|
440
|
+
|
|
414
441
|
interface Notice {
|
|
415
442
|
[field: string]: string;
|
|
416
443
|
}
|
|
@@ -742,6 +769,9 @@ declare namespace postgres {
|
|
|
742
769
|
|
|
743
770
|
end(options?: { timeout?: number | undefined } | undefined): Promise<void>;
|
|
744
771
|
|
|
772
|
+
/** Calls `end()` with no timeout when an `await using` scope exits */
|
|
773
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
774
|
+
|
|
745
775
|
listen(channel: string, onnotify: (value: string) => void, onlisten?: (() => void) | undefined): ListenRequest;
|
|
746
776
|
|
|
747
777
|
/** `onerror` receives replication connection errors and errors thrown while a change is decoded; such a change is skipped. */
|
|
@@ -767,6 +797,12 @@ declare namespace postgres {
|
|
|
767
797
|
|
|
768
798
|
interface ReservedSql<TTypes extends Record<string, unknown> = {}> extends Sql<TTypes> {
|
|
769
799
|
release(): void;
|
|
800
|
+
|
|
801
|
+
/** Calls `release()` when a `using` scope exits */
|
|
802
|
+
[Symbol.dispose](): void;
|
|
803
|
+
|
|
804
|
+
/** Calls `release()` when an `await using` scope exits */
|
|
805
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
770
806
|
}
|
|
771
807
|
}
|
|
772
808
|
|
package/types/package.json
CHANGED