@immich/sql-tools 0.1.1 → 0.2.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/dist/index.js CHANGED
@@ -1,5 +1,3014 @@
1
+ import require$$0 from 'fs';
2
+ import os from 'os';
3
+ import net from 'net';
4
+ import tls from 'tls';
5
+ import crypto from 'crypto';
6
+ import Stream from 'stream';
7
+ import { performance as performance$1 } from 'perf_hooks';
1
8
  import { createHash } from 'node:crypto';
2
9
 
10
+ function getDefaultExportFromCjs (x) {
11
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
12
+ }
13
+
14
+ var pgConnectionString;
15
+ var hasRequiredPgConnectionString;
16
+
17
+ function requirePgConnectionString () {
18
+ if (hasRequiredPgConnectionString) return pgConnectionString;
19
+ hasRequiredPgConnectionString = 1;
20
+
21
+ //Parse method copied from https://github.com/brianc/node-postgres
22
+ //Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com)
23
+ //MIT License
24
+
25
+ //parses a connection string
26
+ function parse(str, options = {}) {
27
+ //unix socket
28
+ if (str.charAt(0) === '/') {
29
+ const config = str.split(' ');
30
+ return { host: config[0], database: config[1] }
31
+ }
32
+
33
+ // Check for empty host in URL
34
+
35
+ const config = {};
36
+ let result;
37
+ let dummyHost = false;
38
+ if (/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) {
39
+ // Ensure spaces are encoded as %20
40
+ str = encodeURI(str).replace(/%25(\d\d)/g, '%$1');
41
+ }
42
+
43
+ try {
44
+ try {
45
+ result = new URL(str, 'postgres://base');
46
+ } catch (e) {
47
+ // The URL is invalid so try again with a dummy host
48
+ result = new URL(str.replace('@/', '@___DUMMY___/'), 'postgres://base');
49
+ dummyHost = true;
50
+ }
51
+ } catch (err) {
52
+ // Remove the input from the error message to avoid leaking sensitive information
53
+ err.input && (err.input = '*****REDACTED*****');
54
+ throw err
55
+ }
56
+
57
+ // We'd like to use Object.fromEntries() here but Node.js 10 does not support it
58
+ for (const entry of result.searchParams.entries()) {
59
+ config[entry[0]] = entry[1];
60
+ }
61
+
62
+ config.user = config.user || decodeURIComponent(result.username);
63
+ config.password = config.password || decodeURIComponent(result.password);
64
+
65
+ if (result.protocol == 'socket:') {
66
+ config.host = decodeURI(result.pathname);
67
+ config.database = result.searchParams.get('db');
68
+ config.client_encoding = result.searchParams.get('encoding');
69
+ return config
70
+ }
71
+ const hostname = dummyHost ? '' : result.hostname;
72
+ if (!config.host) {
73
+ // Only set the host if there is no equivalent query param.
74
+ config.host = decodeURIComponent(hostname);
75
+ } else if (hostname && /^%2f/i.test(hostname)) {
76
+ // Only prepend the hostname to the pathname if it is not a URL encoded Unix socket host.
77
+ result.pathname = hostname + result.pathname;
78
+ }
79
+ if (!config.port) {
80
+ // Only set the port if there is no equivalent query param.
81
+ config.port = result.port;
82
+ }
83
+
84
+ const pathname = result.pathname.slice(1) || null;
85
+ config.database = pathname ? decodeURI(pathname) : null;
86
+
87
+ if (config.ssl === 'true' || config.ssl === '1') {
88
+ config.ssl = true;
89
+ }
90
+
91
+ if (config.ssl === '0') {
92
+ config.ssl = false;
93
+ }
94
+
95
+ if (config.sslcert || config.sslkey || config.sslrootcert || config.sslmode) {
96
+ config.ssl = {};
97
+ }
98
+
99
+ // Only try to load fs if we expect to read from the disk
100
+ const fs = config.sslcert || config.sslkey || config.sslrootcert ? require$$0 : null;
101
+
102
+ if (config.sslcert) {
103
+ config.ssl.cert = fs.readFileSync(config.sslcert).toString();
104
+ }
105
+
106
+ if (config.sslkey) {
107
+ config.ssl.key = fs.readFileSync(config.sslkey).toString();
108
+ }
109
+
110
+ if (config.sslrootcert) {
111
+ config.ssl.ca = fs.readFileSync(config.sslrootcert).toString();
112
+ }
113
+
114
+ if (options.useLibpqCompat && config.uselibpqcompat) {
115
+ throw new Error('Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.')
116
+ }
117
+
118
+ if (config.uselibpqcompat === 'true' || options.useLibpqCompat) {
119
+ switch (config.sslmode) {
120
+ case 'disable': {
121
+ config.ssl = false;
122
+ break
123
+ }
124
+ case 'prefer': {
125
+ config.ssl.rejectUnauthorized = false;
126
+ break
127
+ }
128
+ case 'require': {
129
+ if (config.sslrootcert) {
130
+ // If a root CA is specified, behavior of `sslmode=require` will be the same as that of `verify-ca`
131
+ config.ssl.checkServerIdentity = function () {};
132
+ } else {
133
+ config.ssl.rejectUnauthorized = false;
134
+ }
135
+ break
136
+ }
137
+ case 'verify-ca': {
138
+ if (!config.ssl.ca) {
139
+ throw new Error(
140
+ 'SECURITY WARNING: Using sslmode=verify-ca requires specifying a CA with sslrootcert. If a public CA is used, verify-ca allows connections to a server that somebody else may have registered with the CA, making you vulnerable to Man-in-the-Middle attacks. Either specify a custom CA certificate with sslrootcert parameter or use sslmode=verify-full for proper security.'
141
+ )
142
+ }
143
+ config.ssl.checkServerIdentity = function () {};
144
+ break
145
+ }
146
+ }
147
+ } else {
148
+ switch (config.sslmode) {
149
+ case 'disable': {
150
+ config.ssl = false;
151
+ break
152
+ }
153
+ case 'prefer':
154
+ case 'require':
155
+ case 'verify-ca':
156
+ case 'verify-full': {
157
+ if (config.sslmode !== 'verify-full') {
158
+ deprecatedSslModeWarning(config.sslmode);
159
+ }
160
+ break
161
+ }
162
+ case 'no-verify': {
163
+ config.ssl.rejectUnauthorized = false;
164
+ break
165
+ }
166
+ }
167
+ }
168
+
169
+ return config
170
+ }
171
+
172
+ // convert pg-connection-string ssl config to a ClientConfig.ConnectionOptions
173
+ function toConnectionOptions(sslConfig) {
174
+ const connectionOptions = Object.entries(sslConfig).reduce((c, [key, value]) => {
175
+ // we explicitly check for undefined and null instead of `if (value)` because some
176
+ // options accept falsy values. Example: `ssl.rejectUnauthorized = false`
177
+ if (value !== undefined && value !== null) {
178
+ c[key] = value;
179
+ }
180
+
181
+ return c
182
+ }, {});
183
+
184
+ return connectionOptions
185
+ }
186
+
187
+ // convert pg-connection-string config to a ClientConfig
188
+ function toClientConfig(config) {
189
+ const poolConfig = Object.entries(config).reduce((c, [key, value]) => {
190
+ if (key === 'ssl') {
191
+ const sslConfig = value;
192
+
193
+ if (typeof sslConfig === 'boolean') {
194
+ c[key] = sslConfig;
195
+ }
196
+
197
+ if (typeof sslConfig === 'object') {
198
+ c[key] = toConnectionOptions(sslConfig);
199
+ }
200
+ } else if (value !== undefined && value !== null) {
201
+ if (key === 'port') {
202
+ // when port is not specified, it is converted into an empty string
203
+ // we want to avoid NaN or empty string as a values in ClientConfig
204
+ if (value !== '') {
205
+ const v = parseInt(value, 10);
206
+ if (isNaN(v)) {
207
+ throw new Error(`Invalid ${key}: ${value}`)
208
+ }
209
+
210
+ c[key] = v;
211
+ }
212
+ } else {
213
+ c[key] = value;
214
+ }
215
+ }
216
+
217
+ return c
218
+ }, {});
219
+
220
+ return poolConfig
221
+ }
222
+
223
+ // parses a connection string into ClientConfig
224
+ function parseIntoClientConfig(str) {
225
+ return toClientConfig(parse(str))
226
+ }
227
+
228
+ function deprecatedSslModeWarning(sslmode) {
229
+ if (!deprecatedSslModeWarning.warned && typeof process !== 'undefined' && process.emitWarning) {
230
+ deprecatedSslModeWarning.warned = true;
231
+ process.emitWarning(`SECURITY WARNING: The SSL modes 'prefer', 'require', and 'verify-ca' are treated as aliases for 'verify-full'.
232
+ In the next major version (pg-connection-string v3.0.0 and pg v9.0.0), these modes will adopt standard libpq semantics, which have weaker security guarantees.
233
+
234
+ To prepare for this change:
235
+ - If you want the current behavior, explicitly use 'sslmode=verify-full'
236
+ - If you want libpq compatibility now, use 'uselibpqcompat=true&sslmode=${sslmode}'
237
+
238
+ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode definitions.`);
239
+ }
240
+ }
241
+
242
+ pgConnectionString = parse;
243
+
244
+ parse.parse = parse;
245
+ parse.toClientConfig = toClientConfig;
246
+ parse.parseIntoClientConfig = parseIntoClientConfig;
247
+ return pgConnectionString;
248
+ }
249
+
250
+ var pgConnectionStringExports = requirePgConnectionString();
251
+ const connectionString = /*@__PURE__*/getDefaultExportFromCjs(pgConnectionStringExports);
252
+
253
+ // ESM wrapper for pg-connection-string
254
+
255
+ // Re-export the parse function
256
+ connectionString.parse;
257
+ const parse$1 = connectionString.parse;
258
+ connectionString.toClientConfig;
259
+ connectionString.parseIntoClientConfig;
260
+
261
+ const originCache = new Map()
262
+ , originStackCache = new Map()
263
+ , originError = Symbol('OriginError');
264
+
265
+ const CLOSE = {};
266
+ class Query extends Promise {
267
+ constructor(strings, args, handler, canceller, options = {}) {
268
+ let resolve
269
+ , reject;
270
+
271
+ super((a, b) => {
272
+ resolve = a;
273
+ reject = b;
274
+ });
275
+
276
+ this.tagged = Array.isArray(strings.raw);
277
+ this.strings = strings;
278
+ this.args = args;
279
+ this.handler = handler;
280
+ this.canceller = canceller;
281
+ this.options = options;
282
+
283
+ this.state = null;
284
+ this.statement = null;
285
+
286
+ this.resolve = x => (this.active = false, resolve(x));
287
+ this.reject = x => (this.active = false, reject(x));
288
+
289
+ this.active = false;
290
+ this.cancelled = null;
291
+ this.executed = false;
292
+ this.signature = '';
293
+
294
+ this[originError] = this.handler.debug
295
+ ? new Error()
296
+ : this.tagged && cachedError(this.strings);
297
+ }
298
+
299
+ get origin() {
300
+ return (this.handler.debug
301
+ ? this[originError].stack
302
+ : this.tagged && originStackCache.has(this.strings)
303
+ ? originStackCache.get(this.strings)
304
+ : originStackCache.set(this.strings, this[originError].stack).get(this.strings)
305
+ ) || ''
306
+ }
307
+
308
+ static get [Symbol.species]() {
309
+ return Promise
310
+ }
311
+
312
+ cancel() {
313
+ return this.canceller && (this.canceller(this), this.canceller = null)
314
+ }
315
+
316
+ simple() {
317
+ this.options.simple = true;
318
+ this.options.prepare = false;
319
+ return this
320
+ }
321
+
322
+ async readable() {
323
+ this.simple();
324
+ this.streaming = true;
325
+ return this
326
+ }
327
+
328
+ async writable() {
329
+ this.simple();
330
+ this.streaming = true;
331
+ return this
332
+ }
333
+
334
+ cursor(rows = 1, fn) {
335
+ this.options.simple = false;
336
+ if (typeof rows === 'function') {
337
+ fn = rows;
338
+ rows = 1;
339
+ }
340
+
341
+ this.cursorRows = rows;
342
+
343
+ if (typeof fn === 'function')
344
+ return (this.cursorFn = fn, this)
345
+
346
+ let prev;
347
+ return {
348
+ [Symbol.asyncIterator]: () => ({
349
+ next: () => {
350
+ if (this.executed && !this.active)
351
+ return { done: true }
352
+
353
+ prev && prev();
354
+ const promise = new Promise((resolve, reject) => {
355
+ this.cursorFn = value => {
356
+ resolve({ value, done: false });
357
+ return new Promise(r => prev = r)
358
+ };
359
+ this.resolve = () => (this.active = false, resolve({ done: true }));
360
+ this.reject = x => (this.active = false, reject(x));
361
+ });
362
+ this.execute();
363
+ return promise
364
+ },
365
+ return() {
366
+ prev && prev(CLOSE);
367
+ return { done: true }
368
+ }
369
+ })
370
+ }
371
+ }
372
+
373
+ describe() {
374
+ this.options.simple = false;
375
+ this.onlyDescribe = this.options.prepare = true;
376
+ return this
377
+ }
378
+
379
+ stream() {
380
+ throw new Error('.stream has been renamed to .forEach')
381
+ }
382
+
383
+ forEach(fn) {
384
+ this.forEachFn = fn;
385
+ this.handle();
386
+ return this
387
+ }
388
+
389
+ raw() {
390
+ this.isRaw = true;
391
+ return this
392
+ }
393
+
394
+ values() {
395
+ this.isRaw = 'values';
396
+ return this
397
+ }
398
+
399
+ async handle() {
400
+ !this.executed && (this.executed = true) && await 1 && this.handler(this);
401
+ }
402
+
403
+ execute() {
404
+ this.handle();
405
+ return this
406
+ }
407
+
408
+ then() {
409
+ this.handle();
410
+ return super.then.apply(this, arguments)
411
+ }
412
+
413
+ catch() {
414
+ this.handle();
415
+ return super.catch.apply(this, arguments)
416
+ }
417
+
418
+ finally() {
419
+ this.handle();
420
+ return super.finally.apply(this, arguments)
421
+ }
422
+ }
423
+
424
+ function cachedError(xs) {
425
+ if (originCache.has(xs))
426
+ return originCache.get(xs)
427
+
428
+ const x = Error.stackTraceLimit;
429
+ Error.stackTraceLimit = 4;
430
+ originCache.set(xs, new Error());
431
+ Error.stackTraceLimit = x;
432
+ return originCache.get(xs)
433
+ }
434
+
435
+ class PostgresError extends Error {
436
+ constructor(x) {
437
+ super(x.message);
438
+ this.name = this.constructor.name;
439
+ Object.assign(this, x);
440
+ }
441
+ }
442
+
443
+ const Errors = {
444
+ connection,
445
+ postgres,
446
+ generic,
447
+ notSupported
448
+ };
449
+
450
+ function connection(x, options, socket) {
451
+ const { host, port } = socket || options;
452
+ const error = Object.assign(
453
+ new Error(('write ' + x + ' ' + (options.path || (host + ':' + port)))),
454
+ {
455
+ code: x,
456
+ errno: x,
457
+ address: options.path || host
458
+ }, options.path ? {} : { port: port }
459
+ );
460
+ Error.captureStackTrace(error, connection);
461
+ return error
462
+ }
463
+
464
+ function postgres(x) {
465
+ const error = new PostgresError(x);
466
+ Error.captureStackTrace(error, postgres);
467
+ return error
468
+ }
469
+
470
+ function generic(code, message) {
471
+ const error = Object.assign(new Error(code + ': ' + message), { code });
472
+ Error.captureStackTrace(error, generic);
473
+ return error
474
+ }
475
+
476
+ /* c8 ignore next 10 */
477
+ function notSupported(x) {
478
+ const error = Object.assign(
479
+ new Error(x + ' (B) is not supported'),
480
+ {
481
+ code: 'MESSAGE_NOT_SUPPORTED',
482
+ name: x
483
+ }
484
+ );
485
+ Error.captureStackTrace(error, notSupported);
486
+ return error
487
+ }
488
+
489
+ const types = {
490
+ string: {
491
+ to: 25,
492
+ from: null, // defaults to string
493
+ serialize: x => '' + x
494
+ },
495
+ number: {
496
+ to: 0,
497
+ from: [21, 23, 26, 700, 701],
498
+ serialize: x => '' + x,
499
+ parse: x => +x
500
+ },
501
+ json: {
502
+ to: 114,
503
+ from: [114, 3802],
504
+ serialize: x => JSON.stringify(x),
505
+ parse: x => JSON.parse(x)
506
+ },
507
+ boolean: {
508
+ to: 16,
509
+ from: 16,
510
+ serialize: x => x === true ? 't' : 'f',
511
+ parse: x => x === 't'
512
+ },
513
+ date: {
514
+ to: 1184,
515
+ from: [1082, 1114, 1184],
516
+ serialize: x => (x instanceof Date ? x : new Date(x)).toISOString(),
517
+ parse: x => new Date(x)
518
+ },
519
+ bytea: {
520
+ to: 17,
521
+ from: 17,
522
+ serialize: x => '\\x' + Buffer.from(x).toString('hex'),
523
+ parse: x => Buffer.from(x.slice(2), 'hex')
524
+ }
525
+ };
526
+
527
+ class NotTagged { then() { notTagged(); } catch() { notTagged(); } finally() { notTagged(); }}
528
+
529
+ class Identifier extends NotTagged {
530
+ constructor(value) {
531
+ super();
532
+ this.value = escapeIdentifier(value);
533
+ }
534
+ }
535
+
536
+ class Parameter extends NotTagged {
537
+ constructor(value, type, array) {
538
+ super();
539
+ this.value = value;
540
+ this.type = type;
541
+ this.array = array;
542
+ }
543
+ }
544
+
545
+ class Builder extends NotTagged {
546
+ constructor(first, rest) {
547
+ super();
548
+ this.first = first;
549
+ this.rest = rest;
550
+ }
551
+
552
+ build(before, parameters, types, options) {
553
+ const keyword = builders.map(([x, fn]) => ({ fn, i: before.search(x) })).sort((a, b) => a.i - b.i).pop();
554
+ return keyword.i === -1
555
+ ? escapeIdentifiers(this.first, options)
556
+ : keyword.fn(this.first, this.rest, parameters, types, options)
557
+ }
558
+ }
559
+
560
+ function handleValue(x, parameters, types, options) {
561
+ let value = x instanceof Parameter ? x.value : x;
562
+ if (value === undefined) {
563
+ x instanceof Parameter
564
+ ? x.value = options.transform.undefined
565
+ : value = x = options.transform.undefined;
566
+
567
+ if (value === undefined)
568
+ throw Errors.generic('UNDEFINED_VALUE', 'Undefined values are not allowed')
569
+ }
570
+
571
+ return '$' + (types.push(
572
+ x instanceof Parameter
573
+ ? (parameters.push(x.value), x.array
574
+ ? x.array[x.type || inferType(x.value)] || x.type || firstIsString(x.value)
575
+ : x.type
576
+ )
577
+ : (parameters.push(x), inferType(x))
578
+ ))
579
+ }
580
+
581
+ const defaultHandlers = typeHandlers(types);
582
+
583
+ function stringify(q, string, value, parameters, types, options) { // eslint-disable-line
584
+ for (let i = 1; i < q.strings.length; i++) {
585
+ string += (stringifyValue(string, value, parameters, types, options)) + q.strings[i];
586
+ value = q.args[i];
587
+ }
588
+
589
+ return string
590
+ }
591
+
592
+ function stringifyValue(string, value, parameters, types, o) {
593
+ return (
594
+ value instanceof Builder ? value.build(string, parameters, types, o) :
595
+ value instanceof Query ? fragment(value, parameters, types, o) :
596
+ value instanceof Identifier ? value.value :
597
+ value && value[0] instanceof Query ? value.reduce((acc, x) => acc + ' ' + fragment(x, parameters, types, o), '') :
598
+ handleValue(value, parameters, types, o)
599
+ )
600
+ }
601
+
602
+ function fragment(q, parameters, types, options) {
603
+ q.fragment = true;
604
+ return stringify(q, q.strings[0], q.args[0], parameters, types, options)
605
+ }
606
+
607
+ function valuesBuilder(first, parameters, types, columns, options) {
608
+ return first.map(row =>
609
+ '(' + columns.map(column =>
610
+ stringifyValue('values', row[column], parameters, types, options)
611
+ ).join(',') + ')'
612
+ ).join(',')
613
+ }
614
+
615
+ function values(first, rest, parameters, types, options) {
616
+ const multi = Array.isArray(first[0]);
617
+ const columns = rest.length ? rest.flat() : Object.keys(multi ? first[0] : first);
618
+ return valuesBuilder(multi ? first : [first], parameters, types, columns, options)
619
+ }
620
+
621
+ function select(first, rest, parameters, types, options) {
622
+ typeof first === 'string' && (first = [first].concat(rest));
623
+ if (Array.isArray(first))
624
+ return escapeIdentifiers(first, options)
625
+
626
+ let value;
627
+ const columns = rest.length ? rest.flat() : Object.keys(first);
628
+ return columns.map(x => {
629
+ value = first[x];
630
+ return (
631
+ value instanceof Query ? fragment(value, parameters, types, options) :
632
+ value instanceof Identifier ? value.value :
633
+ handleValue(value, parameters, types, options)
634
+ ) + ' as ' + escapeIdentifier(options.transform.column.to ? options.transform.column.to(x) : x)
635
+ }).join(',')
636
+ }
637
+
638
+ const builders = Object.entries({
639
+ values,
640
+ in: (...xs) => {
641
+ const x = values(...xs);
642
+ return x === '()' ? '(null)' : x
643
+ },
644
+ select,
645
+ as: select,
646
+ returning: select,
647
+ '\\(': select,
648
+
649
+ update(first, rest, parameters, types, options) {
650
+ return (rest.length ? rest.flat() : Object.keys(first)).map(x =>
651
+ escapeIdentifier(options.transform.column.to ? options.transform.column.to(x) : x) +
652
+ '=' + stringifyValue('values', first[x], parameters, types, options)
653
+ )
654
+ },
655
+
656
+ insert(first, rest, parameters, types, options) {
657
+ const columns = rest.length ? rest.flat() : Object.keys(Array.isArray(first) ? first[0] : first);
658
+ return '(' + escapeIdentifiers(columns, options) + ')values' +
659
+ valuesBuilder(Array.isArray(first) ? first : [first], parameters, types, columns, options)
660
+ }
661
+ }).map(([x, fn]) => ([new RegExp('((?:^|[\\s(])' + x + '(?:$|[\\s(]))(?![\\s\\S]*\\1)', 'i'), fn]));
662
+
663
+ function notTagged() {
664
+ throw Errors.generic('NOT_TAGGED_CALL', 'Query not called as a tagged template literal')
665
+ }
666
+
667
+ const serializers = defaultHandlers.serializers;
668
+ const parsers = defaultHandlers.parsers;
669
+
670
+ function firstIsString(x) {
671
+ if (Array.isArray(x))
672
+ return firstIsString(x[0])
673
+ return typeof x === 'string' ? 1009 : 0
674
+ }
675
+
676
+ const mergeUserTypes = function(types) {
677
+ const user = typeHandlers(types || {});
678
+ return {
679
+ serializers: Object.assign({}, serializers, user.serializers),
680
+ parsers: Object.assign({}, parsers, user.parsers)
681
+ }
682
+ };
683
+
684
+ function typeHandlers(types) {
685
+ return Object.keys(types).reduce((acc, k) => {
686
+ types[k].from && [].concat(types[k].from).forEach(x => acc.parsers[x] = types[k].parse);
687
+ if (types[k].serialize) {
688
+ acc.serializers[types[k].to] = types[k].serialize;
689
+ types[k].from && [].concat(types[k].from).forEach(x => acc.serializers[x] = types[k].serialize);
690
+ }
691
+ return acc
692
+ }, { parsers: {}, serializers: {} })
693
+ }
694
+
695
+ function escapeIdentifiers(xs, { transform: { column } }) {
696
+ return xs.map(x => escapeIdentifier(column.to ? column.to(x) : x)).join(',')
697
+ }
698
+
699
+ const escapeIdentifier = function escape(str) {
700
+ return '"' + str.replace(/"/g, '""').replace(/\./g, '"."') + '"'
701
+ };
702
+
703
+ const inferType = function inferType(x) {
704
+ return (
705
+ x instanceof Parameter ? x.type :
706
+ x instanceof Date ? 1184 :
707
+ x instanceof Uint8Array ? 17 :
708
+ (x === true || x === false) ? 16 :
709
+ typeof x === 'bigint' ? 20 :
710
+ Array.isArray(x) ? inferType(x[0]) :
711
+ 0
712
+ )
713
+ };
714
+
715
+ const escapeBackslash = /\\/g;
716
+ const escapeQuote = /"/g;
717
+
718
+ function arrayEscape(x) {
719
+ return x
720
+ .replace(escapeBackslash, '\\\\')
721
+ .replace(escapeQuote, '\\"')
722
+ }
723
+
724
+ const arraySerializer = function arraySerializer(xs, serializer, options, typarray) {
725
+ if (Array.isArray(xs) === false)
726
+ return xs
727
+
728
+ if (!xs.length)
729
+ return '{}'
730
+
731
+ const first = xs[0];
732
+ // Only _box (1020) has the ';' delimiter for arrays, all other types use the ',' delimiter
733
+ const delimiter = typarray === 1020 ? ';' : ',';
734
+
735
+ if (Array.isArray(first) && !first.type)
736
+ return '{' + xs.map(x => arraySerializer(x, serializer, options, typarray)).join(delimiter) + '}'
737
+
738
+ return '{' + xs.map(x => {
739
+ if (x === undefined) {
740
+ x = options.transform.undefined;
741
+ if (x === undefined)
742
+ throw Errors.generic('UNDEFINED_VALUE', 'Undefined values are not allowed')
743
+ }
744
+
745
+ return x === null
746
+ ? 'null'
747
+ : '"' + arrayEscape(serializer ? serializer(x.type ? x.value : x) : '' + x) + '"'
748
+ }).join(delimiter) + '}'
749
+ };
750
+
751
+ const arrayParserState = {
752
+ i: 0,
753
+ char: null,
754
+ str: '',
755
+ quoted: false,
756
+ last: 0
757
+ };
758
+
759
+ const arrayParser = function arrayParser(x, parser, typarray) {
760
+ arrayParserState.i = arrayParserState.last = 0;
761
+ return arrayParserLoop(arrayParserState, x, parser, typarray)
762
+ };
763
+
764
+ function arrayParserLoop(s, x, parser, typarray) {
765
+ const xs = [];
766
+ // Only _box (1020) has the ';' delimiter for arrays, all other types use the ',' delimiter
767
+ const delimiter = typarray === 1020 ? ';' : ',';
768
+ for (; s.i < x.length; s.i++) {
769
+ s.char = x[s.i];
770
+ if (s.quoted) {
771
+ if (s.char === '\\') {
772
+ s.str += x[++s.i];
773
+ } else if (s.char === '"') {
774
+ xs.push(parser ? parser(s.str) : s.str);
775
+ s.str = '';
776
+ s.quoted = x[s.i + 1] === '"';
777
+ s.last = s.i + 2;
778
+ } else {
779
+ s.str += s.char;
780
+ }
781
+ } else if (s.char === '"') {
782
+ s.quoted = true;
783
+ } else if (s.char === '{') {
784
+ s.last = ++s.i;
785
+ xs.push(arrayParserLoop(s, x, parser, typarray));
786
+ } else if (s.char === '}') {
787
+ s.quoted = false;
788
+ s.last < s.i && xs.push(parser ? parser(x.slice(s.last, s.i)) : x.slice(s.last, s.i));
789
+ s.last = s.i + 1;
790
+ break
791
+ } else if (s.char === delimiter && s.p !== '}' && s.p !== '"') {
792
+ xs.push(parser ? parser(x.slice(s.last, s.i)) : x.slice(s.last, s.i));
793
+ s.last = s.i + 1;
794
+ }
795
+ s.p = s.char;
796
+ }
797
+ s.last < s.i && xs.push(parser ? parser(x.slice(s.last, s.i + 1)) : x.slice(s.last, s.i + 1));
798
+ return xs
799
+ }
800
+
801
+ const toCamel = x => {
802
+ let str = x[0];
803
+ for (let i = 1; i < x.length; i++)
804
+ str += x[i] === '_' ? x[++i].toUpperCase() : x[i];
805
+ return str
806
+ };
807
+
808
+ const toPascal = x => {
809
+ let str = x[0].toUpperCase();
810
+ for (let i = 1; i < x.length; i++)
811
+ str += x[i] === '_' ? x[++i].toUpperCase() : x[i];
812
+ return str
813
+ };
814
+
815
+ const toKebab = x => x.replace(/_/g, '-');
816
+
817
+ const fromCamel = x => x.replace(/([A-Z])/g, '_$1').toLowerCase();
818
+ const fromPascal = x => (x.slice(0, 1) + x.slice(1).replace(/([A-Z])/g, '_$1')).toLowerCase();
819
+ const fromKebab = x => x.replace(/-/g, '_');
820
+
821
+ function createJsonTransform(fn) {
822
+ return function jsonTransform(x, column) {
823
+ return typeof x === 'object' && x !== null && (column.type === 114 || column.type === 3802)
824
+ ? Array.isArray(x)
825
+ ? x.map(x => jsonTransform(x, column))
826
+ : Object.entries(x).reduce((acc, [k, v]) => Object.assign(acc, { [fn(k)]: jsonTransform(v, column) }), {})
827
+ : x
828
+ }
829
+ }
830
+
831
+ toCamel.column = { from: toCamel };
832
+ toCamel.value = { from: createJsonTransform(toCamel) };
833
+ fromCamel.column = { to: fromCamel };
834
+
835
+ const camel = { ...toCamel };
836
+ camel.column.to = fromCamel;
837
+
838
+ toPascal.column = { from: toPascal };
839
+ toPascal.value = { from: createJsonTransform(toPascal) };
840
+ fromPascal.column = { to: fromPascal };
841
+
842
+ const pascal = { ...toPascal };
843
+ pascal.column.to = fromPascal;
844
+
845
+ toKebab.column = { from: toKebab };
846
+ toKebab.value = { from: createJsonTransform(toKebab) };
847
+ fromKebab.column = { to: fromKebab };
848
+
849
+ const kebab = { ...toKebab };
850
+ kebab.column.to = fromKebab;
851
+
852
+ class Result extends Array {
853
+ constructor() {
854
+ super();
855
+ Object.defineProperties(this, {
856
+ count: { value: null, writable: true },
857
+ state: { value: null, writable: true },
858
+ command: { value: null, writable: true },
859
+ columns: { value: null, writable: true },
860
+ statement: { value: null, writable: true }
861
+ });
862
+ }
863
+
864
+ static get [Symbol.species]() {
865
+ return Array
866
+ }
867
+ }
868
+
869
+ function Queue(initial = []) {
870
+ let xs = initial.slice();
871
+ let index = 0;
872
+
873
+ return {
874
+ get length() {
875
+ return xs.length - index
876
+ },
877
+ remove: (x) => {
878
+ const index = xs.indexOf(x);
879
+ return index === -1
880
+ ? null
881
+ : (xs.splice(index, 1), x)
882
+ },
883
+ push: (x) => (xs.push(x), x),
884
+ shift: () => {
885
+ const out = xs[index++];
886
+
887
+ if (index === xs.length) {
888
+ index = 0;
889
+ xs = [];
890
+ } else {
891
+ xs[index - 1] = undefined;
892
+ }
893
+
894
+ return out
895
+ }
896
+ }
897
+ }
898
+
899
+ const size = 256;
900
+ let buffer = Buffer.allocUnsafe(size);
901
+
902
+ const messages = 'BCcDdEFfHPpQSX'.split('').reduce((acc, x) => {
903
+ const v = x.charCodeAt(0);
904
+ acc[x] = () => {
905
+ buffer[0] = v;
906
+ b.i = 5;
907
+ return b
908
+ };
909
+ return acc
910
+ }, {});
911
+
912
+ const b = Object.assign(reset, messages, {
913
+ N: String.fromCharCode(0),
914
+ i: 0,
915
+ inc(x) {
916
+ b.i += x;
917
+ return b
918
+ },
919
+ str(x) {
920
+ const length = Buffer.byteLength(x);
921
+ fit(length);
922
+ b.i += buffer.write(x, b.i, length, 'utf8');
923
+ return b
924
+ },
925
+ i16(x) {
926
+ fit(2);
927
+ buffer.writeUInt16BE(x, b.i);
928
+ b.i += 2;
929
+ return b
930
+ },
931
+ i32(x, i) {
932
+ if (i || i === 0) {
933
+ buffer.writeUInt32BE(x, i);
934
+ return b
935
+ }
936
+ fit(4);
937
+ buffer.writeUInt32BE(x, b.i);
938
+ b.i += 4;
939
+ return b
940
+ },
941
+ z(x) {
942
+ fit(x);
943
+ buffer.fill(0, b.i, b.i + x);
944
+ b.i += x;
945
+ return b
946
+ },
947
+ raw(x) {
948
+ buffer = Buffer.concat([buffer.subarray(0, b.i), x]);
949
+ b.i = buffer.length;
950
+ return b
951
+ },
952
+ end(at = 1) {
953
+ buffer.writeUInt32BE(b.i - at, at);
954
+ const out = buffer.subarray(0, b.i);
955
+ b.i = 0;
956
+ buffer = Buffer.allocUnsafe(size);
957
+ return out
958
+ }
959
+ });
960
+
961
+ function fit(x) {
962
+ if (buffer.length - b.i < x) {
963
+ const prev = buffer
964
+ , length = prev.length;
965
+
966
+ buffer = Buffer.allocUnsafe(length + (length >> 1) + x);
967
+ prev.copy(buffer);
968
+ }
969
+ }
970
+
971
+ function reset() {
972
+ b.i = 0;
973
+ return b
974
+ }
975
+
976
+ let uid = 1;
977
+
978
+ const Sync = b().S().end()
979
+ , Flush = b().H().end()
980
+ , SSLRequest = b().i32(8).i32(80877103).end(8)
981
+ , ExecuteUnnamed = Buffer.concat([b().E().str(b.N).i32(0).end(), Sync])
982
+ , DescribeUnnamed = b().D().str('S').str(b.N).end()
983
+ , noop$2 = () => { /* noop */ };
984
+
985
+ const retryRoutines = new Set([
986
+ 'FetchPreparedStatement',
987
+ 'RevalidateCachedQuery',
988
+ 'transformAssignedExpr'
989
+ ]);
990
+
991
+ const errorFields = {
992
+ 83 : 'severity_local', // S
993
+ 86 : 'severity', // V
994
+ 67 : 'code', // C
995
+ 77 : 'message', // M
996
+ 68 : 'detail', // D
997
+ 72 : 'hint', // H
998
+ 80 : 'position', // P
999
+ 112 : 'internal_position', // p
1000
+ 113 : 'internal_query', // q
1001
+ 87 : 'where', // W
1002
+ 115 : 'schema_name', // s
1003
+ 116 : 'table_name', // t
1004
+ 99 : 'column_name', // c
1005
+ 100 : 'data type_name', // d
1006
+ 110 : 'constraint_name', // n
1007
+ 70 : 'file', // F
1008
+ 76 : 'line', // L
1009
+ 82 : 'routine' // R
1010
+ };
1011
+
1012
+ function Connection(options, queues = {}, { onopen = noop$2, onend = noop$2, onclose = noop$2 } = {}) {
1013
+ const {
1014
+ sslnegotiation,
1015
+ ssl,
1016
+ max,
1017
+ user,
1018
+ host,
1019
+ port,
1020
+ database,
1021
+ parsers,
1022
+ transform,
1023
+ onnotice,
1024
+ onnotify,
1025
+ onparameter,
1026
+ max_pipeline,
1027
+ keep_alive,
1028
+ backoff,
1029
+ target_session_attrs
1030
+ } = options;
1031
+
1032
+ const sent = Queue()
1033
+ , id = uid++
1034
+ , backend = { pid: null, secret: null }
1035
+ , idleTimer = timer(end, options.idle_timeout)
1036
+ , lifeTimer = timer(end, options.max_lifetime)
1037
+ , connectTimer = timer(connectTimedOut, options.connect_timeout);
1038
+
1039
+ let socket = null
1040
+ , cancelMessage
1041
+ , errorResponse = null
1042
+ , result = new Result()
1043
+ , incoming = Buffer.alloc(0)
1044
+ , needsTypes = options.fetch_types
1045
+ , backendParameters = {}
1046
+ , statements = {}
1047
+ , statementId = Math.random().toString(36).slice(2)
1048
+ , statementCount = 1
1049
+ , closedTime = 0
1050
+ , remaining = 0
1051
+ , hostIndex = 0
1052
+ , retries = 0
1053
+ , length = 0
1054
+ , delay = 0
1055
+ , rows = 0
1056
+ , serverSignature = null
1057
+ , nextWriteTimer = null
1058
+ , terminated = false
1059
+ , incomings = null
1060
+ , results = null
1061
+ , initial = null
1062
+ , ending = null
1063
+ , stream = null
1064
+ , chunk = null
1065
+ , ended = null
1066
+ , nonce = null
1067
+ , query = null
1068
+ , final = null;
1069
+
1070
+ const connection = {
1071
+ queue: queues.closed,
1072
+ idleTimer,
1073
+ connect(query) {
1074
+ initial = query;
1075
+ reconnect();
1076
+ },
1077
+ terminate,
1078
+ execute,
1079
+ cancel,
1080
+ end,
1081
+ count: 0,
1082
+ id
1083
+ };
1084
+
1085
+ queues.closed && queues.closed.push(connection);
1086
+
1087
+ return connection
1088
+
1089
+ async function createSocket() {
1090
+ let x;
1091
+ try {
1092
+ x = options.socket
1093
+ ? (await Promise.resolve(options.socket(options)))
1094
+ : new net.Socket();
1095
+ } catch (e) {
1096
+ error(e);
1097
+ return
1098
+ }
1099
+ x.on('error', error);
1100
+ x.on('close', closed);
1101
+ x.on('drain', drain);
1102
+ return x
1103
+ }
1104
+
1105
+ async function cancel({ pid, secret }, resolve, reject) {
1106
+ try {
1107
+ cancelMessage = b().i32(16).i32(80877102).i32(pid).i32(secret).end(16);
1108
+ await connect();
1109
+ socket.once('error', reject);
1110
+ socket.once('close', resolve);
1111
+ } catch (error) {
1112
+ reject(error);
1113
+ }
1114
+ }
1115
+
1116
+ function execute(q) {
1117
+ if (terminated)
1118
+ return queryError(q, Errors.connection('CONNECTION_DESTROYED', options))
1119
+
1120
+ if (stream)
1121
+ return queryError(q, Errors.generic('COPY_IN_PROGRESS', 'You cannot execute queries during copy'))
1122
+
1123
+ if (q.cancelled)
1124
+ return
1125
+
1126
+ try {
1127
+ q.state = backend;
1128
+ query
1129
+ ? sent.push(q)
1130
+ : (query = q, query.active = true);
1131
+
1132
+ build(q);
1133
+ return write(toBuffer(q))
1134
+ && !q.describeFirst
1135
+ && !q.cursorFn
1136
+ && sent.length < max_pipeline
1137
+ && (!q.options.onexecute || q.options.onexecute(connection))
1138
+ } catch (error) {
1139
+ sent.length === 0 && write(Sync);
1140
+ errored(error);
1141
+ return true
1142
+ }
1143
+ }
1144
+
1145
+ function toBuffer(q) {
1146
+ if (q.parameters.length >= 65534)
1147
+ throw Errors.generic('MAX_PARAMETERS_EXCEEDED', 'Max number of parameters (65534) exceeded')
1148
+
1149
+ return q.options.simple
1150
+ ? b().Q().str(q.statement.string + b.N).end()
1151
+ : q.describeFirst
1152
+ ? Buffer.concat([describe(q), Flush])
1153
+ : q.prepare
1154
+ ? q.prepared
1155
+ ? prepared(q)
1156
+ : Buffer.concat([describe(q), prepared(q)])
1157
+ : unnamed(q)
1158
+ }
1159
+
1160
+ function describe(q) {
1161
+ return Buffer.concat([
1162
+ Parse(q.statement.string, q.parameters, q.statement.types, q.statement.name),
1163
+ Describe('S', q.statement.name)
1164
+ ])
1165
+ }
1166
+
1167
+ function prepared(q) {
1168
+ return Buffer.concat([
1169
+ Bind(q.parameters, q.statement.types, q.statement.name, q.cursorName),
1170
+ q.cursorFn
1171
+ ? Execute('', q.cursorRows)
1172
+ : ExecuteUnnamed
1173
+ ])
1174
+ }
1175
+
1176
+ function unnamed(q) {
1177
+ return Buffer.concat([
1178
+ Parse(q.statement.string, q.parameters, q.statement.types),
1179
+ DescribeUnnamed,
1180
+ prepared(q)
1181
+ ])
1182
+ }
1183
+
1184
+ function build(q) {
1185
+ const parameters = []
1186
+ , types = [];
1187
+
1188
+ const string = stringify(q, q.strings[0], q.args[0], parameters, types, options);
1189
+
1190
+ !q.tagged && q.args.forEach(x => handleValue(x, parameters, types, options));
1191
+
1192
+ q.prepare = options.prepare && ('prepare' in q.options ? q.options.prepare : true);
1193
+ q.string = string;
1194
+ q.signature = q.prepare && types + string;
1195
+ q.onlyDescribe && (delete statements[q.signature]);
1196
+ q.parameters = q.parameters || parameters;
1197
+ q.prepared = q.prepare && q.signature in statements;
1198
+ q.describeFirst = q.onlyDescribe || (parameters.length && !q.prepared);
1199
+ q.statement = q.prepared
1200
+ ? statements[q.signature]
1201
+ : { string, types, name: q.prepare ? statementId + statementCount++ : '' };
1202
+
1203
+ typeof options.debug === 'function' && options.debug(id, string, parameters, types);
1204
+ }
1205
+
1206
+ function write(x, fn) {
1207
+ chunk = chunk ? Buffer.concat([chunk, x]) : Buffer.from(x);
1208
+ if (chunk.length >= 1024)
1209
+ return nextWrite(fn)
1210
+ nextWriteTimer === null && (nextWriteTimer = setImmediate(nextWrite));
1211
+ return true
1212
+ }
1213
+
1214
+ function nextWrite(fn) {
1215
+ const x = socket.write(chunk, fn);
1216
+ nextWriteTimer !== null && clearImmediate(nextWriteTimer);
1217
+ chunk = nextWriteTimer = null;
1218
+ return x
1219
+ }
1220
+
1221
+ function connectTimedOut() {
1222
+ errored(Errors.connection('CONNECT_TIMEOUT', options, socket));
1223
+ socket.destroy();
1224
+ }
1225
+
1226
+ async function secure() {
1227
+ if (sslnegotiation !== 'direct') {
1228
+ write(SSLRequest);
1229
+ const canSSL = await new Promise(r => socket.once('data', x => r(x[0] === 83))); // S
1230
+
1231
+ if (!canSSL && ssl === 'prefer')
1232
+ return connected()
1233
+ }
1234
+
1235
+ const options = {
1236
+ socket,
1237
+ servername: net.isIP(socket.host) ? undefined : socket.host
1238
+ };
1239
+
1240
+ if (sslnegotiation === 'direct')
1241
+ options.ALPNProtocols = ['postgresql'];
1242
+
1243
+ if (ssl === 'require' || ssl === 'allow' || ssl === 'prefer')
1244
+ options.rejectUnauthorized = false;
1245
+ else if (typeof ssl === 'object')
1246
+ Object.assign(options, ssl);
1247
+
1248
+ socket.removeAllListeners();
1249
+ socket = tls.connect(options);
1250
+ socket.on('secureConnect', connected);
1251
+ socket.on('error', error);
1252
+ socket.on('close', closed);
1253
+ socket.on('drain', drain);
1254
+ }
1255
+
1256
+ /* c8 ignore next 3 */
1257
+ function drain() {
1258
+ !query && onopen(connection);
1259
+ }
1260
+
1261
+ function data(x) {
1262
+ if (incomings) {
1263
+ incomings.push(x);
1264
+ remaining -= x.length;
1265
+ if (remaining > 0)
1266
+ return
1267
+ }
1268
+
1269
+ incoming = incomings
1270
+ ? Buffer.concat(incomings, length - remaining)
1271
+ : incoming.length === 0
1272
+ ? x
1273
+ : Buffer.concat([incoming, x], incoming.length + x.length);
1274
+
1275
+ while (incoming.length > 4) {
1276
+ length = incoming.readUInt32BE(1);
1277
+ if (length >= incoming.length) {
1278
+ remaining = length - incoming.length;
1279
+ incomings = [incoming];
1280
+ break
1281
+ }
1282
+
1283
+ try {
1284
+ handle(incoming.subarray(0, length + 1));
1285
+ } catch (e) {
1286
+ query && (query.cursorFn || query.describeFirst) && write(Sync);
1287
+ errored(e);
1288
+ }
1289
+ incoming = incoming.subarray(length + 1);
1290
+ remaining = 0;
1291
+ incomings = null;
1292
+ }
1293
+ }
1294
+
1295
+ async function connect() {
1296
+ terminated = false;
1297
+ backendParameters = {};
1298
+ socket || (socket = await createSocket());
1299
+
1300
+ if (!socket)
1301
+ return
1302
+
1303
+ connectTimer.start();
1304
+
1305
+ if (options.socket)
1306
+ return ssl ? secure() : connected()
1307
+
1308
+ socket.on('connect', ssl ? secure : connected);
1309
+
1310
+ if (options.path)
1311
+ return socket.connect(options.path)
1312
+
1313
+ socket.ssl = ssl;
1314
+ socket.connect(port[hostIndex], host[hostIndex]);
1315
+ socket.host = host[hostIndex];
1316
+ socket.port = port[hostIndex];
1317
+
1318
+ hostIndex = (hostIndex + 1) % port.length;
1319
+ }
1320
+
1321
+ function reconnect() {
1322
+ setTimeout(connect, closedTime ? Math.max(0, closedTime + delay - performance$1.now()) : 0);
1323
+ }
1324
+
1325
+ function connected() {
1326
+ try {
1327
+ statements = {};
1328
+ needsTypes = options.fetch_types;
1329
+ statementId = Math.random().toString(36).slice(2);
1330
+ statementCount = 1;
1331
+ lifeTimer.start();
1332
+ socket.on('data', data);
1333
+ keep_alive && socket.setKeepAlive && socket.setKeepAlive(true, 1000 * keep_alive);
1334
+ const s = StartupMessage();
1335
+ write(s);
1336
+ } catch (err) {
1337
+ error(err);
1338
+ }
1339
+ }
1340
+
1341
+ function error(err) {
1342
+ if (connection.queue === queues.connecting && options.host[retries + 1])
1343
+ return
1344
+
1345
+ errored(err);
1346
+ while (sent.length)
1347
+ queryError(sent.shift(), err);
1348
+ }
1349
+
1350
+ function errored(err) {
1351
+ stream && (stream.destroy(err), stream = null);
1352
+ query && queryError(query, err);
1353
+ initial && (queryError(initial, err), initial = null);
1354
+ }
1355
+
1356
+ function queryError(query, err) {
1357
+ if (query.reserve)
1358
+ return query.reject(err)
1359
+
1360
+ if (!err || typeof err !== 'object')
1361
+ err = new Error(err);
1362
+
1363
+ 'query' in err || 'parameters' in err || Object.defineProperties(err, {
1364
+ stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug },
1365
+ query: { value: query.string, enumerable: options.debug },
1366
+ parameters: { value: query.parameters, enumerable: options.debug },
1367
+ args: { value: query.args, enumerable: options.debug },
1368
+ types: { value: query.statement && query.statement.types, enumerable: options.debug }
1369
+ });
1370
+ query.reject(err);
1371
+ }
1372
+
1373
+ function end() {
1374
+ return ending || (
1375
+ !connection.reserved && onend(connection),
1376
+ !connection.reserved && !initial && !query && sent.length === 0
1377
+ ? (terminate(), new Promise(r => socket && socket.readyState !== 'closed' ? socket.once('close', r) : r()))
1378
+ : ending = new Promise(r => ended = r)
1379
+ )
1380
+ }
1381
+
1382
+ function terminate() {
1383
+ terminated = true;
1384
+ if (stream || query || initial || sent.length)
1385
+ error(Errors.connection('CONNECTION_DESTROYED', options));
1386
+
1387
+ clearImmediate(nextWriteTimer);
1388
+ if (socket) {
1389
+ socket.removeListener('data', data);
1390
+ socket.removeListener('connect', connected);
1391
+ socket.readyState === 'open' && socket.end(b().X().end());
1392
+ }
1393
+ ended && (ended(), ending = ended = null);
1394
+ }
1395
+
1396
+ async function closed(hadError) {
1397
+ incoming = Buffer.alloc(0);
1398
+ remaining = 0;
1399
+ incomings = null;
1400
+ clearImmediate(nextWriteTimer);
1401
+ socket.removeListener('data', data);
1402
+ socket.removeListener('connect', connected);
1403
+ idleTimer.cancel();
1404
+ lifeTimer.cancel();
1405
+ connectTimer.cancel();
1406
+
1407
+ socket.removeAllListeners();
1408
+ socket = null;
1409
+
1410
+ if (initial)
1411
+ return reconnect()
1412
+
1413
+ !hadError && (query || sent.length) && error(Errors.connection('CONNECTION_CLOSED', options, socket));
1414
+ closedTime = performance$1.now();
1415
+ hadError && options.shared.retries++;
1416
+ delay = (typeof backoff === 'function' ? backoff(options.shared.retries) : backoff) * 1000;
1417
+ onclose(connection, Errors.connection('CONNECTION_CLOSED', options, socket));
1418
+ }
1419
+
1420
+ /* Handlers */
1421
+ function handle(xs, x = xs[0]) {
1422
+ (
1423
+ x === 68 ? DataRow : // D
1424
+ x === 100 ? CopyData : // d
1425
+ x === 65 ? NotificationResponse : // A
1426
+ x === 83 ? ParameterStatus : // S
1427
+ x === 90 ? ReadyForQuery : // Z
1428
+ x === 67 ? CommandComplete : // C
1429
+ x === 50 ? BindComplete : // 2
1430
+ x === 49 ? ParseComplete : // 1
1431
+ x === 116 ? ParameterDescription : // t
1432
+ x === 84 ? RowDescription : // T
1433
+ x === 82 ? Authentication : // R
1434
+ x === 110 ? NoData : // n
1435
+ x === 75 ? BackendKeyData : // K
1436
+ x === 69 ? ErrorResponse : // E
1437
+ x === 115 ? PortalSuspended : // s
1438
+ x === 51 ? CloseComplete : // 3
1439
+ x === 71 ? CopyInResponse : // G
1440
+ x === 78 ? NoticeResponse : // N
1441
+ x === 72 ? CopyOutResponse : // H
1442
+ x === 99 ? CopyDone : // c
1443
+ x === 73 ? EmptyQueryResponse : // I
1444
+ x === 86 ? FunctionCallResponse : // V
1445
+ x === 118 ? NegotiateProtocolVersion : // v
1446
+ x === 87 ? CopyBothResponse : // W
1447
+ /* c8 ignore next */
1448
+ UnknownMessage
1449
+ )(xs);
1450
+ }
1451
+
1452
+ function DataRow(x) {
1453
+ let index = 7;
1454
+ let length;
1455
+ let column;
1456
+ let value;
1457
+
1458
+ const row = query.isRaw ? new Array(query.statement.columns.length) : {};
1459
+ for (let i = 0; i < query.statement.columns.length; i++) {
1460
+ column = query.statement.columns[i];
1461
+ length = x.readInt32BE(index);
1462
+ index += 4;
1463
+
1464
+ value = length === -1
1465
+ ? null
1466
+ : query.isRaw === true
1467
+ ? x.subarray(index, index += length)
1468
+ : column.parser === undefined
1469
+ ? x.toString('utf8', index, index += length)
1470
+ : column.parser.array === true
1471
+ ? column.parser(x.toString('utf8', index + 1, index += length))
1472
+ : column.parser(x.toString('utf8', index, index += length));
1473
+
1474
+ query.isRaw
1475
+ ? (row[i] = query.isRaw === true
1476
+ ? value
1477
+ : transform.value.from ? transform.value.from(value, column) : value)
1478
+ : (row[column.name] = transform.value.from ? transform.value.from(value, column) : value);
1479
+ }
1480
+
1481
+ query.forEachFn
1482
+ ? query.forEachFn(transform.row.from ? transform.row.from(row) : row, result)
1483
+ : (result[rows++] = transform.row.from ? transform.row.from(row) : row);
1484
+ }
1485
+
1486
+ function ParameterStatus(x) {
1487
+ const [k, v] = x.toString('utf8', 5, x.length - 1).split(b.N);
1488
+ backendParameters[k] = v;
1489
+ if (options.parameters[k] !== v) {
1490
+ options.parameters[k] = v;
1491
+ onparameter && onparameter(k, v);
1492
+ }
1493
+ }
1494
+
1495
+ function ReadyForQuery(x) {
1496
+ if (query) {
1497
+ if (errorResponse) {
1498
+ query.retried
1499
+ ? errored(query.retried)
1500
+ : query.prepared && retryRoutines.has(errorResponse.routine)
1501
+ ? retry(query, errorResponse)
1502
+ : errored(errorResponse);
1503
+ } else {
1504
+ query.resolve(results || result);
1505
+ }
1506
+ } else if (errorResponse) {
1507
+ errored(errorResponse);
1508
+ }
1509
+
1510
+ query = results = errorResponse = null;
1511
+ result = new Result();
1512
+ connectTimer.cancel();
1513
+
1514
+ if (initial) {
1515
+ if (target_session_attrs) {
1516
+ if (!backendParameters.in_hot_standby || !backendParameters.default_transaction_read_only)
1517
+ return fetchState()
1518
+ else if (tryNext(target_session_attrs, backendParameters))
1519
+ return terminate()
1520
+ }
1521
+
1522
+ if (needsTypes) {
1523
+ initial.reserve && (initial = null);
1524
+ return fetchArrayTypes()
1525
+ }
1526
+
1527
+ initial && !initial.reserve && execute(initial);
1528
+ options.shared.retries = retries = 0;
1529
+ initial = null;
1530
+ return
1531
+ }
1532
+
1533
+ while (sent.length && (query = sent.shift()) && (query.active = true, query.cancelled))
1534
+ Connection(options).cancel(query.state, query.cancelled.resolve, query.cancelled.reject);
1535
+
1536
+ if (query)
1537
+ return // Consider opening if able and sent.length < 50
1538
+
1539
+ connection.reserved
1540
+ ? !connection.reserved.release && x[5] === 73 // I
1541
+ ? ending
1542
+ ? terminate()
1543
+ : (connection.reserved = null, onopen(connection))
1544
+ : connection.reserved()
1545
+ : ending
1546
+ ? terminate()
1547
+ : onopen(connection);
1548
+ }
1549
+
1550
+ function CommandComplete(x) {
1551
+ rows = 0;
1552
+
1553
+ for (let i = x.length - 1; i > 0; i--) {
1554
+ if (x[i] === 32 && x[i + 1] < 58 && result.count === null)
1555
+ result.count = +x.toString('utf8', i + 1, x.length - 1);
1556
+ if (x[i - 1] >= 65) {
1557
+ result.command = x.toString('utf8', 5, i);
1558
+ result.state = backend;
1559
+ break
1560
+ }
1561
+ }
1562
+
1563
+ final && (final(), final = null);
1564
+
1565
+ if (result.command === 'BEGIN' && max !== 1 && !connection.reserved)
1566
+ return errored(Errors.generic('UNSAFE_TRANSACTION', 'Only use sql.begin, sql.reserved or max: 1'))
1567
+
1568
+ if (query.options.simple)
1569
+ return BindComplete()
1570
+
1571
+ if (query.cursorFn) {
1572
+ result.count && query.cursorFn(result);
1573
+ write(Sync);
1574
+ }
1575
+ }
1576
+
1577
+ function ParseComplete() {
1578
+ query.parsing = false;
1579
+ }
1580
+
1581
+ function BindComplete() {
1582
+ !result.statement && (result.statement = query.statement);
1583
+ result.columns = query.statement.columns;
1584
+ }
1585
+
1586
+ function ParameterDescription(x) {
1587
+ const length = x.readUInt16BE(5);
1588
+
1589
+ for (let i = 0; i < length; ++i)
1590
+ !query.statement.types[i] && (query.statement.types[i] = x.readUInt32BE(7 + i * 4));
1591
+
1592
+ query.prepare && (statements[query.signature] = query.statement);
1593
+ query.describeFirst && !query.onlyDescribe && (write(prepared(query)), query.describeFirst = false);
1594
+ }
1595
+
1596
+ function RowDescription(x) {
1597
+ if (result.command) {
1598
+ results = results || [result];
1599
+ results.push(result = new Result());
1600
+ result.count = null;
1601
+ query.statement.columns = null;
1602
+ }
1603
+
1604
+ const length = x.readUInt16BE(5);
1605
+ let index = 7;
1606
+ let start;
1607
+
1608
+ query.statement.columns = Array(length);
1609
+
1610
+ for (let i = 0; i < length; ++i) {
1611
+ start = index;
1612
+ while (x[index++] !== 0);
1613
+ const table = x.readUInt32BE(index);
1614
+ const number = x.readUInt16BE(index + 4);
1615
+ const type = x.readUInt32BE(index + 6);
1616
+ query.statement.columns[i] = {
1617
+ name: transform.column.from
1618
+ ? transform.column.from(x.toString('utf8', start, index - 1))
1619
+ : x.toString('utf8', start, index - 1),
1620
+ parser: parsers[type],
1621
+ table,
1622
+ number,
1623
+ type
1624
+ };
1625
+ index += 18;
1626
+ }
1627
+
1628
+ result.statement = query.statement;
1629
+ if (query.onlyDescribe)
1630
+ return (query.resolve(query.statement), write(Sync))
1631
+ }
1632
+
1633
+ async function Authentication(x, type = x.readUInt32BE(5)) {
1634
+ (
1635
+ type === 3 ? AuthenticationCleartextPassword :
1636
+ type === 5 ? AuthenticationMD5Password :
1637
+ type === 10 ? SASL :
1638
+ type === 11 ? SASLContinue :
1639
+ type === 12 ? SASLFinal :
1640
+ type !== 0 ? UnknownAuth :
1641
+ noop$2
1642
+ )(x, type);
1643
+ }
1644
+
1645
+ /* c8 ignore next 5 */
1646
+ async function AuthenticationCleartextPassword() {
1647
+ const payload = await Pass();
1648
+ write(
1649
+ b().p().str(payload).z(1).end()
1650
+ );
1651
+ }
1652
+
1653
+ async function AuthenticationMD5Password(x) {
1654
+ const payload = 'md5' + (
1655
+ await md5(
1656
+ Buffer.concat([
1657
+ Buffer.from(await md5((await Pass()) + user)),
1658
+ x.subarray(9)
1659
+ ])
1660
+ )
1661
+ );
1662
+ write(
1663
+ b().p().str(payload).z(1).end()
1664
+ );
1665
+ }
1666
+
1667
+ async function SASL() {
1668
+ nonce = (await crypto.randomBytes(18)).toString('base64');
1669
+ b().p().str('SCRAM-SHA-256' + b.N);
1670
+ const i = b.i;
1671
+ write(b.inc(4).str('n,,n=*,r=' + nonce).i32(b.i - i - 4, i).end());
1672
+ }
1673
+
1674
+ async function SASLContinue(x) {
1675
+ const res = x.toString('utf8', 9).split(',').reduce((acc, x) => (acc[x[0]] = x.slice(2), acc), {});
1676
+
1677
+ const saltedPassword = await crypto.pbkdf2Sync(
1678
+ await Pass(),
1679
+ Buffer.from(res.s, 'base64'),
1680
+ parseInt(res.i), 32,
1681
+ 'sha256'
1682
+ );
1683
+
1684
+ const clientKey = await hmac(saltedPassword, 'Client Key');
1685
+
1686
+ const auth = 'n=*,r=' + nonce + ','
1687
+ + 'r=' + res.r + ',s=' + res.s + ',i=' + res.i
1688
+ + ',c=biws,r=' + res.r;
1689
+
1690
+ serverSignature = (await hmac(await hmac(saltedPassword, 'Server Key'), auth)).toString('base64');
1691
+
1692
+ const payload = 'c=biws,r=' + res.r + ',p=' + xor(
1693
+ clientKey, Buffer.from(await hmac(await sha256(clientKey), auth))
1694
+ ).toString('base64');
1695
+
1696
+ write(
1697
+ b().p().str(payload).end()
1698
+ );
1699
+ }
1700
+
1701
+ function SASLFinal(x) {
1702
+ if (x.toString('utf8', 9).split(b.N, 1)[0].slice(2) === serverSignature)
1703
+ return
1704
+ /* c8 ignore next 5 */
1705
+ errored(Errors.generic('SASL_SIGNATURE_MISMATCH', 'The server did not return the correct signature'));
1706
+ socket.destroy();
1707
+ }
1708
+
1709
+ function Pass() {
1710
+ return Promise.resolve(typeof options.pass === 'function'
1711
+ ? options.pass()
1712
+ : options.pass
1713
+ )
1714
+ }
1715
+
1716
+ function NoData() {
1717
+ result.statement = query.statement;
1718
+ result.statement.columns = [];
1719
+ if (query.onlyDescribe)
1720
+ return (query.resolve(query.statement), write(Sync))
1721
+ }
1722
+
1723
+ function BackendKeyData(x) {
1724
+ backend.pid = x.readUInt32BE(5);
1725
+ backend.secret = x.readUInt32BE(9);
1726
+ }
1727
+
1728
+ async function fetchArrayTypes() {
1729
+ needsTypes = false;
1730
+ const types = await new Query([`
1731
+ select b.oid, b.typarray
1732
+ from pg_catalog.pg_type a
1733
+ left join pg_catalog.pg_type b on b.oid = a.typelem
1734
+ where a.typcategory = 'A'
1735
+ group by b.oid, b.typarray
1736
+ order by b.oid
1737
+ `], [], execute);
1738
+ types.forEach(({ oid, typarray }) => addArrayType(oid, typarray));
1739
+ }
1740
+
1741
+ function addArrayType(oid, typarray) {
1742
+ if (!!options.parsers[typarray] && !!options.serializers[typarray]) return
1743
+ const parser = options.parsers[oid];
1744
+ options.shared.typeArrayMap[oid] = typarray;
1745
+ options.parsers[typarray] = (xs) => arrayParser(xs, parser, typarray);
1746
+ options.parsers[typarray].array = true;
1747
+ options.serializers[typarray] = (xs) => arraySerializer(xs, options.serializers[oid], options, typarray);
1748
+ }
1749
+
1750
+ function tryNext(x, xs) {
1751
+ return (
1752
+ (x === 'read-write' && xs.default_transaction_read_only === 'on') ||
1753
+ (x === 'read-only' && xs.default_transaction_read_only === 'off') ||
1754
+ (x === 'primary' && xs.in_hot_standby === 'on') ||
1755
+ (x === 'standby' && xs.in_hot_standby === 'off') ||
1756
+ (x === 'prefer-standby' && xs.in_hot_standby === 'off' && options.host[retries])
1757
+ )
1758
+ }
1759
+
1760
+ function fetchState() {
1761
+ const query = new Query([`
1762
+ show transaction_read_only;
1763
+ select pg_catalog.pg_is_in_recovery()
1764
+ `], [], execute, null, { simple: true });
1765
+ query.resolve = ([[a], [b]]) => {
1766
+ backendParameters.default_transaction_read_only = a.transaction_read_only;
1767
+ backendParameters.in_hot_standby = b.pg_is_in_recovery ? 'on' : 'off';
1768
+ };
1769
+ query.execute();
1770
+ }
1771
+
1772
+ function ErrorResponse(x) {
1773
+ if (query) {
1774
+ (query.cursorFn || query.describeFirst) && write(Sync);
1775
+ errorResponse = Errors.postgres(parseError(x));
1776
+ } else {
1777
+ errored(Errors.postgres(parseError(x)));
1778
+ }
1779
+ }
1780
+
1781
+ function retry(q, error) {
1782
+ delete statements[q.signature];
1783
+ q.retried = error;
1784
+ execute(q);
1785
+ }
1786
+
1787
+ function NotificationResponse(x) {
1788
+ if (!onnotify)
1789
+ return
1790
+
1791
+ let index = 9;
1792
+ while (x[index++] !== 0);
1793
+ onnotify(
1794
+ x.toString('utf8', 9, index - 1),
1795
+ x.toString('utf8', index, x.length - 1)
1796
+ );
1797
+ }
1798
+
1799
+ async function PortalSuspended() {
1800
+ try {
1801
+ const x = await Promise.resolve(query.cursorFn(result));
1802
+ rows = 0;
1803
+ x === CLOSE
1804
+ ? write(Close(query.portal))
1805
+ : (result = new Result(), write(Execute('', query.cursorRows)));
1806
+ } catch (err) {
1807
+ write(Sync);
1808
+ query.reject(err);
1809
+ }
1810
+ }
1811
+
1812
+ function CloseComplete() {
1813
+ result.count && query.cursorFn(result);
1814
+ query.resolve(result);
1815
+ }
1816
+
1817
+ function CopyInResponse() {
1818
+ stream = new Stream.Writable({
1819
+ autoDestroy: true,
1820
+ write(chunk, encoding, callback) {
1821
+ socket.write(b().d().raw(chunk).end(), callback);
1822
+ },
1823
+ destroy(error, callback) {
1824
+ callback(error);
1825
+ socket.write(b().f().str(error + b.N).end());
1826
+ stream = null;
1827
+ },
1828
+ final(callback) {
1829
+ socket.write(b().c().end());
1830
+ final = callback;
1831
+ stream = null;
1832
+ }
1833
+ });
1834
+ query.resolve(stream);
1835
+ }
1836
+
1837
+ function CopyOutResponse() {
1838
+ stream = new Stream.Readable({
1839
+ read() { socket.resume(); }
1840
+ });
1841
+ query.resolve(stream);
1842
+ }
1843
+
1844
+ /* c8 ignore next 3 */
1845
+ function CopyBothResponse() {
1846
+ stream = new Stream.Duplex({
1847
+ autoDestroy: true,
1848
+ read() { socket.resume(); },
1849
+ /* c8 ignore next 11 */
1850
+ write(chunk, encoding, callback) {
1851
+ socket.write(b().d().raw(chunk).end(), callback);
1852
+ },
1853
+ destroy(error, callback) {
1854
+ callback(error);
1855
+ socket.write(b().f().str(error + b.N).end());
1856
+ stream = null;
1857
+ },
1858
+ final(callback) {
1859
+ socket.write(b().c().end());
1860
+ final = callback;
1861
+ }
1862
+ });
1863
+ query.resolve(stream);
1864
+ }
1865
+
1866
+ function CopyData(x) {
1867
+ stream && (stream.push(x.subarray(5)) || socket.pause());
1868
+ }
1869
+
1870
+ function CopyDone() {
1871
+ stream && stream.push(null);
1872
+ stream = null;
1873
+ }
1874
+
1875
+ function NoticeResponse(x) {
1876
+ onnotice
1877
+ ? onnotice(parseError(x))
1878
+ : console.log(parseError(x)); // eslint-disable-line
1879
+
1880
+ }
1881
+
1882
+ /* c8 ignore next 3 */
1883
+ function EmptyQueryResponse() {
1884
+ /* noop */
1885
+ }
1886
+
1887
+ /* c8 ignore next 3 */
1888
+ function FunctionCallResponse() {
1889
+ errored(Errors.notSupported('FunctionCallResponse'));
1890
+ }
1891
+
1892
+ /* c8 ignore next 3 */
1893
+ function NegotiateProtocolVersion() {
1894
+ errored(Errors.notSupported('NegotiateProtocolVersion'));
1895
+ }
1896
+
1897
+ /* c8 ignore next 3 */
1898
+ function UnknownMessage(x) {
1899
+ console.error('Postgres.js : Unknown Message:', x[0]); // eslint-disable-line
1900
+ }
1901
+
1902
+ /* c8 ignore next 3 */
1903
+ function UnknownAuth(x, type) {
1904
+ console.error('Postgres.js : Unknown Auth:', type); // eslint-disable-line
1905
+ }
1906
+
1907
+ /* Messages */
1908
+ function Bind(parameters, types, statement = '', portal = '') {
1909
+ let prev
1910
+ , type;
1911
+
1912
+ b().B().str(portal + b.N).str(statement + b.N).i16(0).i16(parameters.length);
1913
+
1914
+ parameters.forEach((x, i) => {
1915
+ if (x === null)
1916
+ return b.i32(0xFFFFFFFF)
1917
+
1918
+ type = types[i];
1919
+ parameters[i] = x = type in options.serializers
1920
+ ? options.serializers[type](x)
1921
+ : '' + x;
1922
+
1923
+ prev = b.i;
1924
+ b.inc(4).str(x).i32(b.i - prev - 4, prev);
1925
+ });
1926
+
1927
+ b.i16(0);
1928
+
1929
+ return b.end()
1930
+ }
1931
+
1932
+ function Parse(str, parameters, types, name = '') {
1933
+ b().P().str(name + b.N).str(str + b.N).i16(parameters.length);
1934
+ parameters.forEach((x, i) => b.i32(types[i] || 0));
1935
+ return b.end()
1936
+ }
1937
+
1938
+ function Describe(x, name = '') {
1939
+ return b().D().str(x).str(name + b.N).end()
1940
+ }
1941
+
1942
+ function Execute(portal = '', rows = 0) {
1943
+ return Buffer.concat([
1944
+ b().E().str(portal + b.N).i32(rows).end(),
1945
+ Flush
1946
+ ])
1947
+ }
1948
+
1949
+ function Close(portal = '') {
1950
+ return Buffer.concat([
1951
+ b().C().str('P').str(portal + b.N).end(),
1952
+ b().S().end()
1953
+ ])
1954
+ }
1955
+
1956
+ function StartupMessage() {
1957
+ return cancelMessage || b().inc(4).i16(3).z(2).str(
1958
+ Object.entries(Object.assign({
1959
+ user,
1960
+ database,
1961
+ client_encoding: 'UTF8'
1962
+ },
1963
+ options.connection
1964
+ )).filter(([, v]) => v).map(([k, v]) => k + b.N + v).join(b.N)
1965
+ ).z(2).end(0)
1966
+ }
1967
+
1968
+ }
1969
+
1970
+ function parseError(x) {
1971
+ const error = {};
1972
+ let start = 5;
1973
+ for (let i = 5; i < x.length - 1; i++) {
1974
+ if (x[i] === 0) {
1975
+ error[errorFields[x[start]]] = x.toString('utf8', start + 1, i);
1976
+ start = i + 1;
1977
+ }
1978
+ }
1979
+ return error
1980
+ }
1981
+
1982
+ function md5(x) {
1983
+ return crypto.createHash('md5').update(x).digest('hex')
1984
+ }
1985
+
1986
+ function hmac(key, x) {
1987
+ return crypto.createHmac('sha256', key).update(x).digest()
1988
+ }
1989
+
1990
+ function sha256(x) {
1991
+ return crypto.createHash('sha256').update(x).digest()
1992
+ }
1993
+
1994
+ function xor(a, b) {
1995
+ const length = Math.max(a.length, b.length);
1996
+ const buffer = Buffer.allocUnsafe(length);
1997
+ for (let i = 0; i < length; i++)
1998
+ buffer[i] = a[i] ^ b[i];
1999
+ return buffer
2000
+ }
2001
+
2002
+ function timer(fn, seconds) {
2003
+ seconds = typeof seconds === 'function' ? seconds() : seconds;
2004
+ if (!seconds)
2005
+ return { cancel: noop$2, start: noop$2 }
2006
+
2007
+ let timer;
2008
+ return {
2009
+ cancel() {
2010
+ timer && (clearTimeout(timer), timer = null);
2011
+ },
2012
+ start() {
2013
+ timer && clearTimeout(timer);
2014
+ timer = setTimeout(done, seconds * 1000, arguments);
2015
+ }
2016
+ }
2017
+
2018
+ function done(args) {
2019
+ fn.apply(null, args);
2020
+ timer = null;
2021
+ }
2022
+ }
2023
+
2024
+ const noop$1 = () => { /* noop */ };
2025
+
2026
+ function Subscribe(postgres, options) {
2027
+ const subscribers = new Map()
2028
+ , slot = 'postgresjs_' + Math.random().toString(36).slice(2)
2029
+ , state = {};
2030
+
2031
+ let connection
2032
+ , stream
2033
+ , ended = false;
2034
+
2035
+ const sql = subscribe.sql = postgres({
2036
+ ...options,
2037
+ transform: { column: {}, value: {}, row: {} },
2038
+ max: 1,
2039
+ fetch_types: false,
2040
+ idle_timeout: null,
2041
+ max_lifetime: null,
2042
+ connection: {
2043
+ ...options.connection,
2044
+ replication: 'database'
2045
+ },
2046
+ onclose: async function() {
2047
+ if (ended)
2048
+ return
2049
+ stream = null;
2050
+ state.pid = state.secret = undefined;
2051
+ connected(await init(sql, slot, options.publications));
2052
+ subscribers.forEach(event => event.forEach(({ onsubscribe }) => onsubscribe()));
2053
+ },
2054
+ no_subscribe: true
2055
+ });
2056
+
2057
+ const end = sql.end
2058
+ , close = sql.close;
2059
+
2060
+ sql.end = async() => {
2061
+ ended = true;
2062
+ stream && (await new Promise(r => (stream.once('close', r), stream.end())));
2063
+ return end()
2064
+ };
2065
+
2066
+ sql.close = async() => {
2067
+ stream && (await new Promise(r => (stream.once('close', r), stream.end())));
2068
+ return close()
2069
+ };
2070
+
2071
+ return subscribe
2072
+
2073
+ async function subscribe(event, fn, onsubscribe = noop$1, onerror = noop$1) {
2074
+ event = parseEvent(event);
2075
+
2076
+ if (!connection)
2077
+ connection = init(sql, slot, options.publications);
2078
+
2079
+ const subscriber = { fn, onsubscribe };
2080
+ const fns = subscribers.has(event)
2081
+ ? subscribers.get(event).add(subscriber)
2082
+ : subscribers.set(event, new Set([subscriber])).get(event);
2083
+
2084
+ const unsubscribe = () => {
2085
+ fns.delete(subscriber);
2086
+ fns.size === 0 && subscribers.delete(event);
2087
+ };
2088
+
2089
+ return connection.then(x => {
2090
+ connected(x);
2091
+ onsubscribe();
2092
+ stream && stream.on('error', onerror);
2093
+ return { unsubscribe, state, sql }
2094
+ })
2095
+ }
2096
+
2097
+ function connected(x) {
2098
+ stream = x.stream;
2099
+ state.pid = x.state.pid;
2100
+ state.secret = x.state.secret;
2101
+ }
2102
+
2103
+ async function init(sql, slot, publications) {
2104
+ if (!publications)
2105
+ throw new Error('Missing publication names')
2106
+
2107
+ const xs = await sql.unsafe(
2108
+ `CREATE_REPLICATION_SLOT ${ slot } TEMPORARY LOGICAL pgoutput NOEXPORT_SNAPSHOT`
2109
+ );
2110
+
2111
+ const [x] = xs;
2112
+
2113
+ const stream = await sql.unsafe(
2114
+ `START_REPLICATION SLOT ${ slot } LOGICAL ${
2115
+ x.consistent_point
2116
+ } (proto_version '1', publication_names '${ publications }')`
2117
+ ).writable();
2118
+
2119
+ const state = {
2120
+ lsn: Buffer.concat(x.consistent_point.split('/').map(x => Buffer.from(('00000000' + x).slice(-8), 'hex')))
2121
+ };
2122
+
2123
+ stream.on('data', data);
2124
+ stream.on('error', error);
2125
+ stream.on('close', sql.close);
2126
+
2127
+ return { stream, state: xs.state }
2128
+
2129
+ function error(e) {
2130
+ console.error('Unexpected error during logical streaming - reconnecting', e); // eslint-disable-line
2131
+ }
2132
+
2133
+ function data(x) {
2134
+ if (x[0] === 0x77) {
2135
+ parse(x.subarray(25), state, sql.options.parsers, handle, options.transform);
2136
+ } else if (x[0] === 0x6b && x[17]) {
2137
+ state.lsn = x.subarray(1, 9);
2138
+ pong();
2139
+ }
2140
+ }
2141
+
2142
+ function handle(a, b) {
2143
+ const path = b.relation.schema + '.' + b.relation.table;
2144
+ call('*', a, b);
2145
+ call('*:' + path, a, b);
2146
+ b.relation.keys.length && call('*:' + path + '=' + b.relation.keys.map(x => a[x.name]), a, b);
2147
+ call(b.command, a, b);
2148
+ call(b.command + ':' + path, a, b);
2149
+ b.relation.keys.length && call(b.command + ':' + path + '=' + b.relation.keys.map(x => a[x.name]), a, b);
2150
+ }
2151
+
2152
+ function pong() {
2153
+ const x = Buffer.alloc(34);
2154
+ x[0] = 'r'.charCodeAt(0);
2155
+ x.fill(state.lsn, 1);
2156
+ x.writeBigInt64BE(BigInt(Date.now() - Date.UTC(2000, 0, 1)) * BigInt(1000), 25);
2157
+ stream.write(x);
2158
+ }
2159
+ }
2160
+
2161
+ function call(x, a, b) {
2162
+ subscribers.has(x) && subscribers.get(x).forEach(({ fn }) => fn(a, b, x));
2163
+ }
2164
+ }
2165
+
2166
+ function Time(x) {
2167
+ return new Date(Date.UTC(2000, 0, 1) + Number(x / BigInt(1000)))
2168
+ }
2169
+
2170
+ function parse(x, state, parsers, handle, transform) {
2171
+ const char = (acc, [k, v]) => (acc[k.charCodeAt(0)] = v, acc);
2172
+
2173
+ Object.entries({
2174
+ R: x => { // Relation
2175
+ let i = 1;
2176
+ const r = state[x.readUInt32BE(i)] = {
2177
+ schema: x.toString('utf8', i += 4, i = x.indexOf(0, i)) || 'pg_catalog',
2178
+ table: x.toString('utf8', i + 1, i = x.indexOf(0, i + 1)),
2179
+ columns: Array(x.readUInt16BE(i += 2)),
2180
+ keys: []
2181
+ };
2182
+ i += 2;
2183
+
2184
+ let columnIndex = 0
2185
+ , column;
2186
+
2187
+ while (i < x.length) {
2188
+ column = r.columns[columnIndex++] = {
2189
+ key: x[i++],
2190
+ name: transform.column.from
2191
+ ? transform.column.from(x.toString('utf8', i, i = x.indexOf(0, i)))
2192
+ : x.toString('utf8', i, i = x.indexOf(0, i)),
2193
+ type: x.readUInt32BE(i += 1),
2194
+ parser: parsers[x.readUInt32BE(i)],
2195
+ atttypmod: x.readUInt32BE(i += 4)
2196
+ };
2197
+
2198
+ column.key && r.keys.push(column);
2199
+ i += 4;
2200
+ }
2201
+ },
2202
+ Y: () => { /* noop */ }, // Type
2203
+ O: () => { /* noop */ }, // Origin
2204
+ B: x => { // Begin
2205
+ state.date = Time(x.readBigInt64BE(9));
2206
+ state.lsn = x.subarray(1, 9);
2207
+ },
2208
+ I: x => { // Insert
2209
+ let i = 1;
2210
+ const relation = state[x.readUInt32BE(i)];
2211
+ const { row } = tuples(x, relation.columns, i += 7, transform);
2212
+
2213
+ handle(row, {
2214
+ command: 'insert',
2215
+ relation
2216
+ });
2217
+ },
2218
+ D: x => { // Delete
2219
+ let i = 1;
2220
+ const relation = state[x.readUInt32BE(i)];
2221
+ i += 4;
2222
+ const key = x[i] === 75;
2223
+ handle(key || x[i] === 79
2224
+ ? tuples(x, relation.columns, i += 3, transform).row
2225
+ : null
2226
+ , {
2227
+ command: 'delete',
2228
+ relation,
2229
+ key
2230
+ });
2231
+ },
2232
+ U: x => { // Update
2233
+ let i = 1;
2234
+ const relation = state[x.readUInt32BE(i)];
2235
+ i += 4;
2236
+ const key = x[i] === 75;
2237
+ const xs = key || x[i] === 79
2238
+ ? tuples(x, relation.columns, i += 3, transform)
2239
+ : null;
2240
+
2241
+ xs && (i = xs.i);
2242
+
2243
+ const { row } = tuples(x, relation.columns, i + 3, transform);
2244
+
2245
+ handle(row, {
2246
+ command: 'update',
2247
+ relation,
2248
+ key,
2249
+ old: xs && xs.row
2250
+ });
2251
+ },
2252
+ T: () => { /* noop */ }, // Truncate,
2253
+ C: () => { /* noop */ } // Commit
2254
+ }).reduce(char, {})[x[0]](x);
2255
+ }
2256
+
2257
+ function tuples(x, columns, xi, transform) {
2258
+ let type
2259
+ , column
2260
+ , value;
2261
+
2262
+ const row = transform.raw ? new Array(columns.length) : {};
2263
+ for (let i = 0; i < columns.length; i++) {
2264
+ type = x[xi++];
2265
+ column = columns[i];
2266
+ value = type === 110 // n
2267
+ ? null
2268
+ : type === 117 // u
2269
+ ? undefined
2270
+ : column.parser === undefined
2271
+ ? x.toString('utf8', xi + 4, xi += 4 + x.readUInt32BE(xi))
2272
+ : column.parser.array === true
2273
+ ? column.parser(x.toString('utf8', xi + 5, xi += 4 + x.readUInt32BE(xi)))
2274
+ : column.parser(x.toString('utf8', xi + 4, xi += 4 + x.readUInt32BE(xi)));
2275
+
2276
+ transform.raw
2277
+ ? (row[i] = transform.raw === true
2278
+ ? value
2279
+ : transform.value.from ? transform.value.from(value, column) : value)
2280
+ : (row[column.name] = transform.value.from
2281
+ ? transform.value.from(value, column)
2282
+ : value
2283
+ );
2284
+ }
2285
+
2286
+ return { i: xi, row: transform.row.from ? transform.row.from(row) : row }
2287
+ }
2288
+
2289
+ function parseEvent(x) {
2290
+ const xs = x.match(/^(\*|insert|update|delete)?:?([^.]+?\.?[^=]+)?=?(.+)?/i) || [];
2291
+
2292
+ if (!xs)
2293
+ throw new Error('Malformed subscribe pattern: ' + x)
2294
+
2295
+ const [, command, path, key] = xs;
2296
+
2297
+ return (command || '*')
2298
+ + (path ? ':' + (path.indexOf('.') === -1 ? 'public.' + path : path) : '')
2299
+ + (key ? '=' + key : '')
2300
+ }
2301
+
2302
+ function largeObject(sql, oid, mode = 0x00020000 | 0x00040000) {
2303
+ return new Promise(async(resolve, reject) => {
2304
+ await sql.begin(async sql => {
2305
+ let finish;
2306
+ !oid && ([{ oid }] = await sql`select lo_creat(-1) as oid`);
2307
+ const [{ fd }] = await sql`select lo_open(${ oid }, ${ mode }) as fd`;
2308
+
2309
+ const lo = {
2310
+ writable,
2311
+ readable,
2312
+ close : () => sql`select lo_close(${ fd })`.then(finish),
2313
+ tell : () => sql`select lo_tell64(${ fd })`,
2314
+ read : (x) => sql`select loread(${ fd }, ${ x }) as data`,
2315
+ write : (x) => sql`select lowrite(${ fd }, ${ x })`,
2316
+ truncate : (x) => sql`select lo_truncate64(${ fd }, ${ x })`,
2317
+ seek : (x, whence = 0) => sql`select lo_lseek64(${ fd }, ${ x }, ${ whence })`,
2318
+ size : () => sql`
2319
+ select
2320
+ lo_lseek64(${ fd }, location, 0) as position,
2321
+ seek.size
2322
+ from (
2323
+ select
2324
+ lo_lseek64($1, 0, 2) as size,
2325
+ tell.location
2326
+ from (select lo_tell64($1) as location) tell
2327
+ ) seek
2328
+ `
2329
+ };
2330
+
2331
+ resolve(lo);
2332
+
2333
+ return new Promise(async r => finish = r)
2334
+
2335
+ async function readable({
2336
+ highWaterMark = 2048 * 8,
2337
+ start = 0,
2338
+ end = Infinity
2339
+ } = {}) {
2340
+ let max = end - start;
2341
+ start && await lo.seek(start);
2342
+ return new Stream.Readable({
2343
+ highWaterMark,
2344
+ async read(size) {
2345
+ const l = size > max ? size - max : size;
2346
+ max -= size;
2347
+ const [{ data }] = await lo.read(l);
2348
+ this.push(data);
2349
+ if (data.length < size)
2350
+ this.push(null);
2351
+ }
2352
+ })
2353
+ }
2354
+
2355
+ async function writable({
2356
+ highWaterMark = 2048 * 8,
2357
+ start = 0
2358
+ } = {}) {
2359
+ start && await lo.seek(start);
2360
+ return new Stream.Writable({
2361
+ highWaterMark,
2362
+ write(chunk, encoding, callback) {
2363
+ lo.write(chunk).then(() => callback(), callback);
2364
+ }
2365
+ })
2366
+ }
2367
+ }).catch(reject);
2368
+ })
2369
+ }
2370
+
2371
+ Object.assign(Postgres, {
2372
+ PostgresError,
2373
+ toPascal,
2374
+ pascal,
2375
+ toCamel,
2376
+ camel,
2377
+ toKebab,
2378
+ kebab,
2379
+ fromPascal,
2380
+ fromCamel,
2381
+ fromKebab,
2382
+ BigInt: {
2383
+ to: 20,
2384
+ from: [20],
2385
+ parse: x => BigInt(x), // eslint-disable-line
2386
+ serialize: x => x.toString()
2387
+ }
2388
+ });
2389
+
2390
+ function Postgres(a, b) {
2391
+ const options = parseOptions(a, b)
2392
+ , subscribe = options.no_subscribe || Subscribe(Postgres, { ...options });
2393
+
2394
+ let ending = false;
2395
+
2396
+ const queries = Queue()
2397
+ , connecting = Queue()
2398
+ , reserved = Queue()
2399
+ , closed = Queue()
2400
+ , ended = Queue()
2401
+ , open = Queue()
2402
+ , busy = Queue()
2403
+ , full = Queue()
2404
+ , queues = { connecting, closed};
2405
+
2406
+ const connections = [...Array(options.max)].map(() => Connection(options, queues, { onopen, onend, onclose }));
2407
+
2408
+ const sql = Sql(handler);
2409
+
2410
+ Object.assign(sql, {
2411
+ get parameters() { return options.parameters },
2412
+ largeObject: largeObject.bind(null, sql),
2413
+ subscribe,
2414
+ CLOSE,
2415
+ END: CLOSE,
2416
+ PostgresError,
2417
+ options,
2418
+ reserve,
2419
+ listen,
2420
+ begin,
2421
+ close,
2422
+ end
2423
+ });
2424
+
2425
+ return sql
2426
+
2427
+ function Sql(handler) {
2428
+ handler.debug = options.debug;
2429
+
2430
+ Object.entries(options.types).reduce((acc, [name, type]) => {
2431
+ acc[name] = (x) => new Parameter(x, type.to);
2432
+ return acc
2433
+ }, typed);
2434
+
2435
+ Object.assign(sql, {
2436
+ types: typed,
2437
+ typed,
2438
+ unsafe,
2439
+ notify,
2440
+ array,
2441
+ json,
2442
+ file
2443
+ });
2444
+
2445
+ return sql
2446
+
2447
+ function typed(value, type) {
2448
+ return new Parameter(value, type)
2449
+ }
2450
+
2451
+ function sql(strings, ...args) {
2452
+ const query = strings && Array.isArray(strings.raw)
2453
+ ? new Query(strings, args, handler, cancel)
2454
+ : typeof strings === 'string' && !args.length
2455
+ ? new Identifier(options.transform.column.to ? options.transform.column.to(strings) : strings)
2456
+ : new Builder(strings, args);
2457
+ return query
2458
+ }
2459
+
2460
+ function unsafe(string, args = [], options = {}) {
2461
+ arguments.length === 2 && !Array.isArray(args) && (options = args, args = []);
2462
+ const query = new Query([string], args, handler, cancel, {
2463
+ prepare: false,
2464
+ ...options,
2465
+ simple: 'simple' in options ? options.simple : args.length === 0
2466
+ });
2467
+ return query
2468
+ }
2469
+
2470
+ function file(path, args = [], options = {}) {
2471
+ arguments.length === 2 && !Array.isArray(args) && (options = args, args = []);
2472
+ const query = new Query([], args, (query) => {
2473
+ require$$0.readFile(path, 'utf8', (err, string) => {
2474
+ if (err)
2475
+ return query.reject(err)
2476
+
2477
+ query.strings = [string];
2478
+ handler(query);
2479
+ });
2480
+ }, cancel, {
2481
+ ...options,
2482
+ simple: 'simple' in options ? options.simple : args.length === 0
2483
+ });
2484
+ return query
2485
+ }
2486
+ }
2487
+
2488
+ async function listen(name, fn, onlisten) {
2489
+ const listener = { fn, onlisten };
2490
+
2491
+ const sql = listen.sql || (listen.sql = Postgres({
2492
+ ...options,
2493
+ max: 1,
2494
+ idle_timeout: null,
2495
+ max_lifetime: null,
2496
+ fetch_types: false,
2497
+ onclose() {
2498
+ Object.entries(listen.channels).forEach(([name, { listeners }]) => {
2499
+ delete listen.channels[name];
2500
+ Promise.all(listeners.map(l => listen(name, l.fn, l.onlisten).catch(() => { /* noop */ })));
2501
+ });
2502
+ },
2503
+ onnotify(c, x) {
2504
+ c in listen.channels && listen.channels[c].listeners.forEach(l => l.fn(x));
2505
+ }
2506
+ }));
2507
+
2508
+ const channels = listen.channels || (listen.channels = {})
2509
+ , exists = name in channels;
2510
+
2511
+ if (exists) {
2512
+ channels[name].listeners.push(listener);
2513
+ const result = await channels[name].result;
2514
+ listener.onlisten && listener.onlisten();
2515
+ return { state: result.state, unlisten }
2516
+ }
2517
+
2518
+ channels[name] = { result: sql`listen ${
2519
+ sql.unsafe('"' + name.replace(/"/g, '""') + '"')
2520
+ }`, listeners: [listener] };
2521
+ const result = await channels[name].result;
2522
+ listener.onlisten && listener.onlisten();
2523
+ return { state: result.state, unlisten }
2524
+
2525
+ async function unlisten() {
2526
+ if (name in channels === false)
2527
+ return
2528
+
2529
+ channels[name].listeners = channels[name].listeners.filter(x => x !== listener);
2530
+ if (channels[name].listeners.length)
2531
+ return
2532
+
2533
+ delete channels[name];
2534
+ return sql`unlisten ${
2535
+ sql.unsafe('"' + name.replace(/"/g, '""') + '"')
2536
+ }`
2537
+ }
2538
+ }
2539
+
2540
+ async function notify(channel, payload) {
2541
+ return await sql`select pg_notify(${ channel }, ${ '' + payload })`
2542
+ }
2543
+
2544
+ async function reserve() {
2545
+ const queue = Queue();
2546
+ const c = open.length
2547
+ ? open.shift()
2548
+ : await new Promise((resolve, reject) => {
2549
+ const query = { reserve: resolve, reject };
2550
+ queries.push(query);
2551
+ closed.length && connect(closed.shift(), query);
2552
+ });
2553
+
2554
+ move(c, reserved);
2555
+ c.reserved = () => queue.length
2556
+ ? c.execute(queue.shift())
2557
+ : move(c, reserved);
2558
+ c.reserved.release = true;
2559
+
2560
+ const sql = Sql(handler);
2561
+ sql.release = () => {
2562
+ c.reserved = null;
2563
+ onopen(c);
2564
+ };
2565
+
2566
+ return sql
2567
+
2568
+ function handler(q) {
2569
+ c.queue === full
2570
+ ? queue.push(q)
2571
+ : c.execute(q) || move(c, full);
2572
+ }
2573
+ }
2574
+
2575
+ async function begin(options, fn) {
2576
+ !fn && (fn = options, options = '');
2577
+ const queries = Queue();
2578
+ let savepoints = 0
2579
+ , connection
2580
+ , prepare = null;
2581
+
2582
+ try {
2583
+ await sql.unsafe('begin ' + options.replace(/[^a-z ]/ig, ''), [], { onexecute }).execute();
2584
+ return await Promise.race([
2585
+ scope(connection, fn),
2586
+ new Promise((_, reject) => connection.onclose = reject)
2587
+ ])
2588
+ } catch (error) {
2589
+ throw error
2590
+ }
2591
+
2592
+ async function scope(c, fn, name) {
2593
+ const sql = Sql(handler);
2594
+ sql.savepoint = savepoint;
2595
+ sql.prepare = x => prepare = x.replace(/[^a-z0-9$-_. ]/gi);
2596
+ let uncaughtError
2597
+ , result;
2598
+
2599
+ name && await sql`savepoint ${ sql(name) }`;
2600
+ try {
2601
+ result = await new Promise((resolve, reject) => {
2602
+ const x = fn(sql);
2603
+ Promise.resolve(Array.isArray(x) ? Promise.all(x) : x).then(resolve, reject);
2604
+ });
2605
+
2606
+ if (uncaughtError)
2607
+ throw uncaughtError
2608
+ } catch (e) {
2609
+ await (name
2610
+ ? sql`rollback to ${ sql(name) }`
2611
+ : sql`rollback`
2612
+ );
2613
+ throw e instanceof PostgresError && e.code === '25P02' && uncaughtError || e
2614
+ }
2615
+
2616
+ if (!name) {
2617
+ prepare
2618
+ ? await sql`prepare transaction '${ sql.unsafe(prepare) }'`
2619
+ : await sql`commit`;
2620
+ }
2621
+
2622
+ return result
2623
+
2624
+ function savepoint(name, fn) {
2625
+ if (name && Array.isArray(name.raw))
2626
+ return savepoint(sql => sql.apply(sql, arguments))
2627
+
2628
+ arguments.length === 1 && (fn = name, name = null);
2629
+ return scope(c, fn, 's' + savepoints++ + (name ? '_' + name : ''))
2630
+ }
2631
+
2632
+ function handler(q) {
2633
+ q.catch(e => uncaughtError || (uncaughtError = e));
2634
+ c.queue === full
2635
+ ? queries.push(q)
2636
+ : c.execute(q) || move(c, full);
2637
+ }
2638
+ }
2639
+
2640
+ function onexecute(c) {
2641
+ connection = c;
2642
+ move(c, reserved);
2643
+ c.reserved = () => queries.length
2644
+ ? c.execute(queries.shift())
2645
+ : move(c, reserved);
2646
+ }
2647
+ }
2648
+
2649
+ function move(c, queue) {
2650
+ c.queue.remove(c);
2651
+ queue.push(c);
2652
+ c.queue = queue;
2653
+ queue === open
2654
+ ? c.idleTimer.start()
2655
+ : c.idleTimer.cancel();
2656
+ return c
2657
+ }
2658
+
2659
+ function json(x) {
2660
+ return new Parameter(x, 3802)
2661
+ }
2662
+
2663
+ function array(x, type) {
2664
+ if (!Array.isArray(x))
2665
+ return array(Array.from(arguments))
2666
+
2667
+ return new Parameter(x, type || (x.length ? inferType(x) || 25 : 0), options.shared.typeArrayMap)
2668
+ }
2669
+
2670
+ function handler(query) {
2671
+ if (ending)
2672
+ return query.reject(Errors.connection('CONNECTION_ENDED', options, options))
2673
+
2674
+ if (open.length)
2675
+ return go(open.shift(), query)
2676
+
2677
+ if (closed.length)
2678
+ return connect(closed.shift(), query)
2679
+
2680
+ busy.length
2681
+ ? go(busy.shift(), query)
2682
+ : queries.push(query);
2683
+ }
2684
+
2685
+ function go(c, query) {
2686
+ return c.execute(query)
2687
+ ? move(c, busy)
2688
+ : move(c, full)
2689
+ }
2690
+
2691
+ function cancel(query) {
2692
+ return new Promise((resolve, reject) => {
2693
+ query.state
2694
+ ? query.active
2695
+ ? Connection(options).cancel(query.state, resolve, reject)
2696
+ : query.cancelled = { resolve, reject }
2697
+ : (
2698
+ queries.remove(query),
2699
+ query.cancelled = true,
2700
+ query.reject(Errors.generic('57014', 'canceling statement due to user request')),
2701
+ resolve()
2702
+ );
2703
+ })
2704
+ }
2705
+
2706
+ async function end({ timeout = null } = {}) {
2707
+ if (ending)
2708
+ return ending
2709
+
2710
+ await 1;
2711
+ let timer;
2712
+ return ending = Promise.race([
2713
+ new Promise(r => timeout !== null && (timer = setTimeout(destroy, timeout * 1000, r))),
2714
+ Promise.all(connections.map(c => c.end()).concat(
2715
+ listen.sql ? listen.sql.end({ timeout: 0 }) : [],
2716
+ subscribe.sql ? subscribe.sql.end({ timeout: 0 }) : []
2717
+ ))
2718
+ ]).then(() => clearTimeout(timer))
2719
+ }
2720
+
2721
+ async function close() {
2722
+ await Promise.all(connections.map(c => c.end()));
2723
+ }
2724
+
2725
+ async function destroy(resolve) {
2726
+ await Promise.all(connections.map(c => c.terminate()));
2727
+ while (queries.length)
2728
+ queries.shift().reject(Errors.connection('CONNECTION_DESTROYED', options));
2729
+ resolve();
2730
+ }
2731
+
2732
+ function connect(c, query) {
2733
+ move(c, connecting);
2734
+ c.connect(query);
2735
+ return c
2736
+ }
2737
+
2738
+ function onend(c) {
2739
+ move(c, ended);
2740
+ }
2741
+
2742
+ function onopen(c) {
2743
+ if (queries.length === 0)
2744
+ return move(c, open)
2745
+
2746
+ let max = Math.ceil(queries.length / (connecting.length + 1))
2747
+ , ready = true;
2748
+
2749
+ while (ready && queries.length && max-- > 0) {
2750
+ const query = queries.shift();
2751
+ if (query.reserve)
2752
+ return query.reserve(c)
2753
+
2754
+ ready = c.execute(query);
2755
+ }
2756
+
2757
+ ready
2758
+ ? move(c, busy)
2759
+ : move(c, full);
2760
+ }
2761
+
2762
+ function onclose(c, e) {
2763
+ move(c, closed);
2764
+ c.reserved = null;
2765
+ c.onclose && (c.onclose(e), c.onclose = null);
2766
+ options.onclose && options.onclose(c.id);
2767
+ queries.length && connect(c, queries.shift());
2768
+ }
2769
+ }
2770
+
2771
+ function parseOptions(a, b) {
2772
+ if (a && a.shared)
2773
+ return a
2774
+
2775
+ const env = process.env // eslint-disable-line
2776
+ , o = (!a || typeof a === 'string' ? b : a) || {}
2777
+ , { url, multihost } = parseUrl(a)
2778
+ , query = [...url.searchParams].reduce((a, [b, c]) => (a[b] = c, a), {})
2779
+ , host = o.hostname || o.host || multihost || url.hostname || env.PGHOST || 'localhost'
2780
+ , port = o.port || url.port || env.PGPORT || 5432
2781
+ , user = o.user || o.username || url.username || env.PGUSERNAME || env.PGUSER || osUsername();
2782
+
2783
+ o.no_prepare && (o.prepare = false);
2784
+ query.sslmode && (query.ssl = query.sslmode, delete query.sslmode);
2785
+ 'timeout' in o && (console.log('The timeout option is deprecated, use idle_timeout instead'), o.idle_timeout = o.timeout); // eslint-disable-line
2786
+ query.sslrootcert === 'system' && (query.ssl = 'verify-full');
2787
+
2788
+ const ints = ['idle_timeout', 'connect_timeout', 'max_lifetime', 'max_pipeline', 'backoff', 'keep_alive'];
2789
+ const defaults = {
2790
+ max : globalThis.Cloudflare ? 3 : 10,
2791
+ ssl : false,
2792
+ sslnegotiation : null,
2793
+ idle_timeout : null,
2794
+ connect_timeout : 30,
2795
+ max_lifetime : max_lifetime,
2796
+ max_pipeline : 100,
2797
+ backoff : backoff,
2798
+ keep_alive : 60,
2799
+ prepare : true,
2800
+ debug : false,
2801
+ fetch_types : true,
2802
+ publications : 'alltables',
2803
+ target_session_attrs: null
2804
+ };
2805
+
2806
+ return {
2807
+ host : Array.isArray(host) ? host : host.split(',').map(x => x.split(':')[0]),
2808
+ port : Array.isArray(port) ? port : host.split(',').map(x => parseInt(x.split(':')[1] || port)),
2809
+ path : o.path || host.indexOf('/') > -1 && host + '/.s.PGSQL.' + port,
2810
+ database : o.database || o.db || (url.pathname || '').slice(1) || env.PGDATABASE || user,
2811
+ user : user,
2812
+ pass : o.pass || o.password || url.password || env.PGPASSWORD || '',
2813
+ ...Object.entries(defaults).reduce(
2814
+ (acc, [k, d]) => {
2815
+ const value = k in o ? o[k] : k in query
2816
+ ? (query[k] === 'disable' || query[k] === 'false' ? false : query[k])
2817
+ : env['PG' + k.toUpperCase()] || d;
2818
+ acc[k] = typeof value === 'string' && ints.includes(k)
2819
+ ? +value
2820
+ : value;
2821
+ return acc
2822
+ },
2823
+ {}
2824
+ ),
2825
+ connection : {
2826
+ application_name: env.PGAPPNAME || 'postgres.js',
2827
+ ...o.connection,
2828
+ ...Object.entries(query).reduce((acc, [k, v]) => (k in defaults || (acc[k] = v), acc), {})
2829
+ },
2830
+ types : o.types || {},
2831
+ target_session_attrs: tsa(o, url, env),
2832
+ onnotice : o.onnotice,
2833
+ onnotify : o.onnotify,
2834
+ onclose : o.onclose,
2835
+ onparameter : o.onparameter,
2836
+ socket : o.socket,
2837
+ transform : parseTransform(o.transform || { undefined: undefined }),
2838
+ parameters : {},
2839
+ shared : { retries: 0, typeArrayMap: {} },
2840
+ ...mergeUserTypes(o.types)
2841
+ }
2842
+ }
2843
+
2844
+ function tsa(o, url, env) {
2845
+ const x = o.target_session_attrs || url.searchParams.get('target_session_attrs') || env.PGTARGETSESSIONATTRS;
2846
+ if (!x || ['read-write', 'read-only', 'primary', 'standby', 'prefer-standby'].includes(x))
2847
+ return x
2848
+
2849
+ throw new Error('target_session_attrs ' + x + ' is not supported')
2850
+ }
2851
+
2852
+ function backoff(retries) {
2853
+ return (0.5 + Math.random() / 2) * Math.min(3 ** retries / 100, 20)
2854
+ }
2855
+
2856
+ function max_lifetime() {
2857
+ return 60 * (30 + Math.random() * 30)
2858
+ }
2859
+
2860
+ function parseTransform(x) {
2861
+ return {
2862
+ undefined: x.undefined,
2863
+ column: {
2864
+ from: typeof x.column === 'function' ? x.column : x.column && x.column.from,
2865
+ to: x.column && x.column.to
2866
+ },
2867
+ value: {
2868
+ from: typeof x.value === 'function' ? x.value : x.value && x.value.from,
2869
+ to: x.value && x.value.to
2870
+ },
2871
+ row: {
2872
+ from: typeof x.row === 'function' ? x.row : x.row && x.row.from,
2873
+ to: x.row && x.row.to
2874
+ }
2875
+ }
2876
+ }
2877
+
2878
+ function parseUrl(url) {
2879
+ if (!url || typeof url !== 'string')
2880
+ return { url: { searchParams: new Map() } }
2881
+
2882
+ let host = url;
2883
+ host = host.slice(host.indexOf('://') + 3).split(/[?/]/)[0];
2884
+ host = decodeURIComponent(host.slice(host.indexOf('@') + 1));
2885
+
2886
+ const urlObj = new URL(url.replace(host, host.split(',')[0]));
2887
+
2888
+ return {
2889
+ url: {
2890
+ username: decodeURIComponent(urlObj.username),
2891
+ password: decodeURIComponent(urlObj.password),
2892
+ host: urlObj.host,
2893
+ hostname: urlObj.hostname,
2894
+ port: urlObj.port,
2895
+ pathname: urlObj.pathname,
2896
+ searchParams: urlObj.searchParams
2897
+ },
2898
+ multihost: host.indexOf(',') > -1 && host
2899
+ }
2900
+ }
2901
+
2902
+ function osUsername() {
2903
+ try {
2904
+ return os.userInfo().username // eslint-disable-line
2905
+ } catch (_) {
2906
+ return process.env.USERNAME || process.env.USER || process.env.LOGNAME // eslint-disable-line
2907
+ }
2908
+ }
2909
+
2910
+ var DatabaseSslMode = /*#__PURE__*/ function(DatabaseSslMode) {
2911
+ DatabaseSslMode["Disable"] = "disable";
2912
+ DatabaseSslMode["Allow"] = "allow";
2913
+ DatabaseSslMode["Prefer"] = "prefer";
2914
+ DatabaseSslMode["Require"] = "require";
2915
+ DatabaseSslMode["VerifyFull"] = "verify-full";
2916
+ return DatabaseSslMode;
2917
+ }({});
2918
+ var ConstraintType = /*#__PURE__*/ function(ConstraintType) {
2919
+ ConstraintType["PRIMARY_KEY"] = "primary-key";
2920
+ ConstraintType["FOREIGN_KEY"] = "foreign-key";
2921
+ ConstraintType["UNIQUE"] = "unique";
2922
+ ConstraintType["CHECK"] = "check";
2923
+ return ConstraintType;
2924
+ }({});
2925
+ var ActionType = /*#__PURE__*/ function(ActionType) {
2926
+ ActionType["NO_ACTION"] = "NO ACTION";
2927
+ ActionType["RESTRICT"] = "RESTRICT";
2928
+ ActionType["CASCADE"] = "CASCADE";
2929
+ ActionType["SET_NULL"] = "SET NULL";
2930
+ ActionType["SET_DEFAULT"] = "SET DEFAULT";
2931
+ return ActionType;
2932
+ }({});
2933
+ var Reason = /*#__PURE__*/ function(Reason) {
2934
+ Reason["MissingInSource"] = "missing in source";
2935
+ Reason["MissingInTarget"] = "missing in target";
2936
+ Reason["Rename"] = "name has changed";
2937
+ return Reason;
2938
+ }({});
2939
+
2940
+ const isPostgresSsl = (ssl)=>typeof ssl !== 'string' || ssl === 'require' || ssl === 'allow' || ssl === 'prefer' || ssl === 'verify-full';
2941
+ const asPostgresConfig = (params)=>{
2942
+ if (params.connectionType === 'parts') {
2943
+ return {
2944
+ host: params.host,
2945
+ port: params.port,
2946
+ username: params.username,
2947
+ password: params.password,
2948
+ database: params.database,
2949
+ ssl: params.ssl === DatabaseSslMode.Disable ? false : params.ssl
2950
+ };
2951
+ }
2952
+ const { host, port, user, password, database, ssl } = parse$1(params.url);
2953
+ if (ssl !== undefined && !isPostgresSsl(ssl)) {
2954
+ throw new Error(`Invalid ssl option: ${ssl}`);
2955
+ }
2956
+ return {
2957
+ host: host ?? undefined,
2958
+ port: port ? Number(port) : undefined,
2959
+ username: user,
2960
+ password,
2961
+ database: database ?? undefined,
2962
+ ssl
2963
+ };
2964
+ };
2965
+ const createPostgres = (options = {})=>{
2966
+ const { connection = {
2967
+ connectionType: 'url',
2968
+ url: 'postgres://postgres:postgres@localhost:5432/postgres'
2969
+ }, maxConnections = 10, timeZone = 'UTC', convertToJsDate = true, convertBigIntToNumber = true, onNotice, onClose } = options;
2970
+ const config = asPostgresConfig(connection);
2971
+ const types = {};
2972
+ if (convertToJsDate) {
2973
+ types.date = {
2974
+ to: 1184,
2975
+ from: [
2976
+ 1082,
2977
+ 1114,
2978
+ 1184
2979
+ ],
2980
+ serialize: (x)=>x instanceof Date ? x.toISOString() : x,
2981
+ parse: (x)=>new Date(x)
2982
+ };
2983
+ }
2984
+ if (convertBigIntToNumber) {
2985
+ types.bigint = {
2986
+ to: 20,
2987
+ from: [
2988
+ 20,
2989
+ 1700
2990
+ ],
2991
+ parse: (value)=>Number.parseInt(value),
2992
+ serialize: (value)=>value.toString()
2993
+ };
2994
+ }
2995
+ return Postgres({
2996
+ host: config.host,
2997
+ port: config.port,
2998
+ username: config.username,
2999
+ password: config.password,
3000
+ database: config.database,
3001
+ ssl: config.ssl,
3002
+ max: maxConnections,
3003
+ connection: {
3004
+ TimeZone: timeZone
3005
+ },
3006
+ types,
3007
+ onnotice: onNotice,
3008
+ onclose: onClose
3009
+ });
3010
+ };
3011
+
3
3012
  const items = [];
4
3013
  const register = (item)=>void items.push(item);
5
3014
  const getRegisteredItems = ()=>items;
@@ -576,28 +3585,6 @@ const asFunctionExpression = (options)=>{
576
3585
  return sql.join('\n ').trim();
577
3586
  };
578
3587
 
579
- var ConstraintType = /*#__PURE__*/ function(ConstraintType) {
580
- ConstraintType["PRIMARY_KEY"] = "primary-key";
581
- ConstraintType["FOREIGN_KEY"] = "foreign-key";
582
- ConstraintType["UNIQUE"] = "unique";
583
- ConstraintType["CHECK"] = "check";
584
- return ConstraintType;
585
- }({});
586
- var ActionType = /*#__PURE__*/ function(ActionType) {
587
- ActionType["NO_ACTION"] = "NO ACTION";
588
- ActionType["RESTRICT"] = "RESTRICT";
589
- ActionType["CASCADE"] = "CASCADE";
590
- ActionType["SET_NULL"] = "SET NULL";
591
- ActionType["SET_DEFAULT"] = "SET DEFAULT";
592
- return ActionType;
593
- }({});
594
- var Reason = /*#__PURE__*/ function(Reason) {
595
- Reason["MissingInSource"] = "missing in source";
596
- Reason["MissingInTarget"] = "missing in target";
597
- Reason["Rename"] = "name has changed";
598
- return Reason;
599
- }({});
600
-
601
3588
  const compareEnums = ()=>({
602
3589
  onMissing: (source)=>[
603
3590
  {
@@ -18764,27 +21751,23 @@ const readers = [
18764
21751
  readOverrides
18765
21752
  ];
18766
21753
 
18767
- const isKysely = (db)=>db instanceof Kysely;
18768
21754
  /**
18769
21755
  * Load schema from a database url
18770
- */ const schemaFromDatabase = async (database, options = {})=>{
18771
- const db = isKysely(database) ? database : new Kysely({
21756
+ */ const schemaFromDatabase = async (options = {})=>{
21757
+ const ctx = new ReaderContext(options);
21758
+ const db = new Kysely({
18772
21759
  dialect: new PostgresJSDialect({
18773
- postgres: database
21760
+ postgres: createPostgres(options)
18774
21761
  })
18775
21762
  });
18776
- const ctx = new ReaderContext(options);
18777
21763
  try {
18778
21764
  for (const reader of readers){
18779
21765
  await reader(ctx, db);
18780
21766
  }
18781
21767
  return ctx.build();
18782
21768
  } finally{
18783
- // only close the connection it we created it
18784
- if (!isKysely(database)) {
18785
- await db.destroy();
18786
- }
21769
+ await db.destroy();
18787
21770
  }
18788
21771
  };
18789
21772
 
18790
- export { ActionType, AfterDeleteTrigger, AfterInsertTrigger, BeforeUpdateTrigger, Check, Column, ConfigurationParameter, ConstraintType, CreateDateColumn, Database, DefaultNamingStrategy, DeleteDateColumn, Extension, Extensions, ForeignKeyColumn, ForeignKeyConstraint, GeneratedColumn, HashNamingStrategy, Index, PrimaryColumn, PrimaryGeneratedColumn, Reason, Table, Trigger, TriggerFunction, Unique, UpdateDateColumn, asHuman, asSql, registerEnum, registerFunction, schemaDiff, schemaDiffToHuman, schemaDiffToSql, schemaFromCode, schemaFromDatabase };
21773
+ export { ActionType, AfterDeleteTrigger, AfterInsertTrigger, BeforeUpdateTrigger, Check, Column, ConfigurationParameter, ConstraintType, CreateDateColumn, Database, DatabaseSslMode, DefaultNamingStrategy, DeleteDateColumn, Extension, Extensions, ForeignKeyColumn, ForeignKeyConstraint, GeneratedColumn, HashNamingStrategy, Index, PrimaryColumn, PrimaryGeneratedColumn, Reason, Table, Trigger, TriggerFunction, Unique, UpdateDateColumn, asHuman, asPostgresConfig, asSql, createPostgres, isPostgresSsl, registerEnum, registerFunction, schemaDiff, schemaDiffToHuman, schemaDiffToSql, schemaFromCode, schemaFromDatabase };