@juit/pgproxy-client 1.2.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -86,7 +86,23 @@ const result = await client.query('SELECT * FROM test WHERE value = $1', [ 'theV
86
86
  ```
87
87
 
88
88
  More complex queries (e.g. transactions) can be performed using the
89
- `connect(...)` method:
89
+ _connection_ returned by the `connect()` method:
90
+
91
+ ```ts
92
+ const client = new PGClient()
93
+
94
+ await using connection = await client.connect() // the "connection" is AsyncDisposable
95
+
96
+ await connection.begin() // ... begin transaction
97
+ await connection.query(...) // ... all transaction queries
98
+ await connection.commit() // ... commit transaction, or "rollback()"
99
+
100
+ // if not declaring with "async using" connections can be closed manually:
101
+ //
102
+ // await connection.close()
103
+ ```
104
+
105
+ Or using a _connection consumer_:
90
106
 
91
107
  ```ts
92
108
  const client = new PGClient()
@@ -109,7 +125,8 @@ A second form of the `query(...)` function accepts an object with two keys:
109
125
  * `query`: the SQL query to execute optionally containing placeholders
110
126
  * `params`: any parameter replacement for `$x` placeholders
111
127
 
112
- The object passed to the `connect(...)` callback provides the following methods:
128
+ When used with callbacks, the object passed to the `connect(...)` callback
129
+ provides the following methods:
113
130
 
114
131
  * `query(...)`: as above
115
132
  * `begin()`: issues the `BEGIN` SQL statement (starts a transaction)
@@ -118,6 +135,10 @@ The object passed to the `connect(...)` callback provides the following methods:
118
135
 
119
136
  Uncommitted transactions will always be rolled back by the connection pool code.
120
137
 
138
+ Otherwise, when using `connect()` without callbacks, the returned _connection_
139
+ will be `AsyncDisposable`, and (if not using `async using`) can be manually
140
+ disposed of calling the `close()` function.
141
+
121
142
  ### Result
122
143
 
123
144
  The result returned by the `query(...)` method is a simple object containing:
package/dist/client.cjs CHANGED
@@ -3,6 +3,10 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
7
+ var __typeError = (msg) => {
8
+ throw TypeError(msg);
9
+ };
6
10
  var __export = (target, all) => {
7
11
  for (var name in all)
8
12
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -16,6 +20,47 @@ var __copyProps = (to, from, except, desc) => {
16
20
  return to;
17
21
  };
18
22
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
23
+ var __using = (stack, value, async) => {
24
+ if (value != null) {
25
+ if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
26
+ var dispose, inner;
27
+ if (async) dispose = value[__knownSymbol("asyncDispose")];
28
+ if (dispose === void 0) {
29
+ dispose = value[__knownSymbol("dispose")];
30
+ if (async) inner = dispose;
31
+ }
32
+ if (typeof dispose !== "function") __typeError("Object not disposable");
33
+ if (inner) dispose = function() {
34
+ try {
35
+ inner.call(this);
36
+ } catch (e) {
37
+ return Promise.reject(e);
38
+ }
39
+ };
40
+ stack.push([async, dispose, value]);
41
+ } else if (async) {
42
+ stack.push([async]);
43
+ }
44
+ return value;
45
+ };
46
+ var __callDispose = (stack, error, hasError) => {
47
+ var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
48
+ return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
49
+ };
50
+ var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
51
+ var next = (it) => {
52
+ while (it = stack.pop()) {
53
+ try {
54
+ var result = it[1] && it[1].call(it[2]);
55
+ if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
56
+ } catch (e) {
57
+ fail(e);
58
+ }
59
+ }
60
+ if (hasError) throw error;
61
+ };
62
+ return next();
63
+ };
19
64
 
20
65
  // client.ts
21
66
  var client_exports = {};
@@ -36,62 +81,115 @@ function serializeParams(params) {
36
81
  return result;
37
82
  }
38
83
  var PGClient = class PGClientImpl {
39
- registry = new import_pgproxy_types.Registry();
84
+ _registry = new import_pgproxy_types.Registry();
40
85
  _provider;
41
- constructor(urlOrProvider) {
42
- urlOrProvider = urlOrProvider || globalThis?.process?.env?.PGURL;
43
- (0, import_assert.assert)(urlOrProvider, "No URL to connect to (PGURL environment variable missing?)");
44
- if (typeof urlOrProvider === "string") urlOrProvider = new URL(urlOrProvider, "psql:///");
45
- (0, import_assert.assert)(urlOrProvider, "Missing URL or provider for client");
46
- if (urlOrProvider instanceof URL) {
47
- if (!(urlOrProvider.username || urlOrProvider.password)) {
86
+ constructor(arg) {
87
+ arg = arg || globalThis?.process?.env?.PGURL;
88
+ (0, import_assert.assert)(arg, "No URL to connect to (PGURL environment variable missing?)");
89
+ if (typeof arg === "string") arg = new URL(arg, "psql:///");
90
+ (0, import_assert.assert)(arg, "Missing URL or provider for client");
91
+ if ("href" in arg) {
92
+ if (!(arg.username || arg.password)) {
48
93
  const username = globalThis?.process?.env?.PGUSER || "";
49
94
  const password = globalThis?.process?.env?.PGPASSWORD || "";
50
- urlOrProvider.username = encodeURIComponent(username);
51
- urlOrProvider.password = encodeURIComponent(password);
95
+ arg.username = encodeURIComponent(username);
96
+ arg.password = encodeURIComponent(password);
97
+ }
98
+ this._provider = (0, import_provider.createProvider)(arg);
99
+ } else if ("query" in arg && "acquire" in arg && "release" in arg) {
100
+ this._provider = arg;
101
+ } else {
102
+ const {
103
+ protocol = "psql",
104
+ database = "",
105
+ username = globalThis?.process?.env?.PGUSER,
106
+ password = globalThis?.process?.env?.PGPASSWORD,
107
+ host = "localhost",
108
+ port,
109
+ parameters = {}
110
+ } = arg;
111
+ const url = new URL(`${protocol}://`);
112
+ if (host) url.hostname = host;
113
+ if (port) url.port = String(port);
114
+ if (username) url.username = encodeURIComponent(username);
115
+ if (password) url.password = encodeURIComponent(password);
116
+ url.pathname = `/${database}`;
117
+ for (const [key, value] of Object.entries(parameters)) {
118
+ url.searchParams.set(key, String(value));
52
119
  }
120
+ this._provider = (0, import_provider.createProvider)(url);
53
121
  }
54
- this._provider = urlOrProvider instanceof URL ? (0, import_provider.createProvider)(urlOrProvider) : urlOrProvider;
122
+ }
123
+ get registry() {
124
+ return this._registry;
125
+ }
126
+ get url() {
127
+ return this._provider.url;
55
128
  }
56
129
  async query(textOrQuery, maybeParams = []) {
57
130
  const [text, params = []] = typeof textOrQuery === "string" ? [textOrQuery, maybeParams] : [textOrQuery.query, textOrQuery.params];
58
131
  const result = await this._provider.query(text, serializeParams(params));
59
- return new import_result.PGResult(result, this.registry);
132
+ return new import_result.PGResult(result, this._registry);
60
133
  }
61
134
  async connect(consumer) {
62
135
  const connection = await this._provider.acquire();
63
- let transaction = false;
64
- try {
65
- const registry = this.registry;
66
- const consumable = {
67
- async query(textOrQuery, maybeParams = []) {
68
- const [text, params = []] = typeof textOrQuery === "string" ? [textOrQuery, maybeParams] : [textOrQuery.query, textOrQuery.params];
69
- const result = await connection.query(text, serializeParams(params));
70
- return new import_result.PGResult(result, registry);
71
- },
72
- async begin() {
73
- if (transaction) return false;
74
- await connection.query("BEGIN");
75
- return transaction = true;
76
- },
77
- async commit() {
78
- await connection.query("COMMIT");
79
- transaction = false;
80
- },
81
- async rollback() {
82
- await connection.query("ROLLBACK");
83
- transaction = false;
84
- }
85
- };
86
- return await consumer(consumable);
87
- } finally {
88
- if (transaction) await connection.query("ROLLBACK");
89
- await this._provider.release(connection);
136
+ if (!consumer) {
137
+ return new PGConnectionImpl(connection, this._provider, this._registry);
138
+ } else {
139
+ var _stack = [];
140
+ try {
141
+ const conn = __using(_stack, new PGConnectionImpl(connection, this._provider, this._registry), true);
142
+ return await consumer(conn);
143
+ } catch (_) {
144
+ var _error = _, _hasError = true;
145
+ } finally {
146
+ var _promise = __callDispose(_stack, _error, _hasError);
147
+ _promise && await _promise;
148
+ }
90
149
  }
91
150
  }
92
151
  async destroy() {
93
152
  return await this._provider.destroy();
94
153
  }
154
+ async [Symbol.asyncDispose]() {
155
+ await this.destroy();
156
+ }
157
+ };
158
+ var PGConnectionImpl = class {
159
+ _transaction = false;
160
+ _connection;
161
+ _provider;
162
+ _registry;
163
+ constructor(connection, provider, registry) {
164
+ this._connection = connection;
165
+ this._provider = provider;
166
+ this._registry = registry;
167
+ }
168
+ async query(textOrQuery, maybeParams = []) {
169
+ const [text, params = []] = typeof textOrQuery === "string" ? [textOrQuery, maybeParams] : [textOrQuery.query, textOrQuery.params];
170
+ const result = await this._connection.query(text, serializeParams(params));
171
+ return new import_result.PGResult(result, this._registry);
172
+ }
173
+ async begin() {
174
+ if (this._transaction) return false;
175
+ await this._connection.query("BEGIN");
176
+ return this._transaction = true;
177
+ }
178
+ async commit() {
179
+ await this._connection.query("COMMIT");
180
+ this._transaction = false;
181
+ }
182
+ async rollback() {
183
+ await this._connection.query("ROLLBACK");
184
+ this._transaction = false;
185
+ }
186
+ async close() {
187
+ if (this._transaction) await this._connection.query("ROLLBACK");
188
+ await this._provider.release(this._connection);
189
+ }
190
+ [Symbol.asyncDispose]() {
191
+ return this.close();
192
+ }
95
193
  };
96
194
  // Annotate the CommonJS export names for ESM import in node:
97
195
  0 && (module.exports = {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/client.ts"],
4
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAAoC;AAEpC,oBAAuB;AACvB,sBAA+B;AAC/B,oBAAyB;AAIzB,SAAS,gBAAgB,QAA2C;AAClE,MAAI,OAAO,UAAU,EAAG,QAAO,CAAC;AAEhC,QAAM,SAA4B,IAAI,MAAM,OAAO,MAAM;AACzD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAM;AACvC,WAAO,CAAC,IACN,OAAO,CAAC,MAAM,SAAY,OAC1B,OAAO,CAAC,MAAM,OAAO,WACrB,gCAAU,OAAO,CAAC,CAAC;AAAA,EACvB;AAEA,SAAO;AACT;AAsHO,IAAM,WAAgC,MAAM,aAAiC;AAAA,EACzE,WAAqB,IAAI,8BAAS;AAAA,EAEnC;AAAA,EAIR,YAAY,eAAyD;AACnE,oBAAgB,iBAAmB,YAAoB,SAAS,KAAK;AACrE,8BAAO,eAAe,4DAA4D;AAClF,QAAI,OAAO,kBAAkB,SAAU,iBAAgB,IAAI,IAAI,eAAe,UAAU;AACxF,8BAAO,eAAe,oCAAoC;AAE1D,QAAI,yBAAyB,KAAK;AAChC,UAAI,EAAE,cAAc,YAAY,cAAc,WAAW;AACvD,cAAM,WAAa,YAAoB,SAAS,KAAK,UAAiC;AACtF,cAAM,WAAa,YAAoB,SAAS,KAAK,cAAqC;AAC1F,sBAAc,WAAW,mBAAmB,QAAQ;AACpD,sBAAc,WAAW,mBAAmB,QAAQ;AAAA,MACtD;AAAA,IACF;AAEA,SAAK,YAAY,yBAAyB,UACxC,gCAAe,aAAa,IAC5B;AAAA,EACJ;AAAA,EAaA,MAAM,MAGJ,aAA+B,cAA8B,CAAC,GAAkC;AAChG,UAAM,CAAE,MAAM,SAAS,CAAC,CAAE,IAAI,OAAO,gBAAgB,WACnD,CAAE,aAAa,WAAY,IAAI,CAAE,YAAY,OAAO,YAAY,MAAO;AAGzE,UAAM,SAAS,MAAM,KAAK,UAAU,MAAM,MAAM,gBAAgB,MAAM,CAAC;AACvE,WAAO,IAAI,uBAAqB,QAAQ,KAAK,QAAQ;AAAA,EACvD;AAAA,EAEA,MAAM,QAAW,UAAqC;AACpD,UAAM,aAAa,MAAM,KAAK,UAAU,QAAQ;AAChD,QAAI,cAAc;AAElB,QAAI;AACF,YAAM,WAAW,KAAK;AAEtB,YAAM,aAAgC;AAAA,QACpC,MAAM,MAGJ,aAA+B,cAA8B,CAAC,GAAkC;AAChG,gBAAM,CAAE,MAAM,SAAS,CAAC,CAAE,IAAI,OAAO,gBAAgB,WACnD,CAAE,aAAa,WAAY,IAAI,CAAE,YAAY,OAAO,YAAY,MAAO;AAEzE,gBAAM,SAAS,MAAM,WAAW,MAAM,MAAM,gBAAgB,MAAM,CAAC;AACnE,iBAAO,IAAI,uBAAS,QAAQ,QAAQ;AAAA,QACtC;AAAA,QACA,MAAM,QAA0B;AAC9B,cAAI,YAAa,QAAO;AACxB,gBAAM,WAAW,MAAM,OAAO;AAC9B,iBAAO,cAAc;AAAA,QACvB;AAAA,QACA,MAAM,SAAwB;AAC5B,gBAAM,WAAW,MAAM,QAAQ;AAC/B,wBAAc;AAAA,QAChB;AAAA,QACA,MAAM,WAA0B;AAC9B,gBAAM,WAAW,MAAM,UAAU;AACjC,wBAAc;AAAA,QAChB;AAAA,MACF;AAEA,aAAO,MAAM,SAAS,UAAU;AAAA,IAClC,UAAE;AACA,UAAI,YAAa,OAAM,WAAW,MAAM,UAAU;AAClD,YAAM,KAAK,UAAU,QAAQ,UAAU;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAC7B,WAAO,MAAM,KAAK,UAAU,QAAQ;AAAA,EACtC;AACF;",
4
+ "mappings": "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",
5
5
  "names": []
6
6
  }
package/dist/client.d.ts CHANGED
@@ -1,6 +1,28 @@
1
1
  import { Registry } from '@juit/pgproxy-types';
2
2
  import { PGResult } from './result';
3
- import type { PGConnection, PGProvider } from './provider';
3
+ import type { PGProvider } from './provider';
4
+ /**
5
+ * Options to create a `PGClient`
6
+ *
7
+ * As an alternative to using URLs, a `PGClient` can be instantiated with
8
+ * options passed in this object.
9
+ */
10
+ export interface PGClientOptions {
11
+ /** The protocol used to connect to the database (defaults to "psql") */
12
+ readonly protocol?: string;
13
+ /** The PostgreSQL database to connect to */
14
+ readonly database?: string;
15
+ /** The user to authenticate as */
16
+ readonly username?: string;
17
+ /** The password to use for authentication */
18
+ readonly password?: string;
19
+ /** The host to connect to */
20
+ readonly host?: string;
21
+ /** The port to connect to */
22
+ readonly port?: number;
23
+ /** Any additional options to pass to the provider */
24
+ readonly parameters?: Record<string, string | number | boolean>;
25
+ }
4
26
  /** An interface representing a SQL query to a database */
5
27
  export interface PGQuery {
6
28
  /** The SQL query to execute optionally containing placeholders. */
@@ -27,7 +49,8 @@ export interface PGQueryable {
27
49
  }
28
50
  /**
29
51
  * An interface for an object that can execute queries _and transactions_
30
- * on a database */
52
+ * on a database
53
+ */
31
54
  export interface PGTransactionable extends PGQueryable {
32
55
  /**
33
56
  * Start a transaction by issuing a `BEGIN` statement
@@ -41,12 +64,21 @@ export interface PGTransactionable extends PGQueryable {
41
64
  /** Cancel a transaction by issuing a `ROLLBACK` statement */
42
65
  rollback(): Promise<void>;
43
66
  }
67
+ /**
68
+ * A connection to a database that can be asynchronously disposed of.
69
+ */
70
+ export interface PGConnection extends PGTransactionable, AsyncDisposable {
71
+ /** Forcedly close the underlying connection to the database */
72
+ close(): Promise<void>;
73
+ }
44
74
  /** A consumer for a {@link PGTransactionable} connection */
45
75
  export type PGConsumer<T> = (connection: PGTransactionable) => T | PromiseLike<T>;
46
76
  /** The PostgreSQL client */
47
- export interface PGClient extends PGQueryable {
77
+ export interface PGClient extends PGQueryable, AsyncDisposable {
48
78
  /** The {@link @juit/pgproxy-types#Registry} used to parse results from PostgreSQL */
49
79
  readonly registry: Registry;
80
+ /** The URL used to create this provider, devoid of any credentials */
81
+ readonly url: Readonly<URL>;
50
82
  /**
51
83
  * Execute a _single_ query on the database.
52
84
  *
@@ -69,6 +101,11 @@ export interface PGClient extends PGQueryable {
69
101
  * related parameters) to execute
70
102
  */
71
103
  query<Row extends Record<string, any> = Record<string, any>, Tuple extends readonly any[] = readonly any[]>(query: PGQuery): Promise<PGResult<Row, Tuple>>;
104
+ /**
105
+ * Connect to the database and return an _async disposable_
106
+ * {@link PGConnection}.
107
+ */
108
+ connect(): Promise<PGConnection>;
72
109
  /**
73
110
  * Connect to the database to execute a number of different queries.
74
111
  *
@@ -86,11 +123,10 @@ export interface PGClient extends PGQueryable {
86
123
  /** A constructor for {@link (PGClient:interface)} instances */
87
124
  export interface PGClientConstructor {
88
125
  new (url?: string | URL): PGClient;
89
- new (provider: PGProvider<PGConnection>): PGClient;
126
+ new (provider: PGProvider): PGClient;
127
+ new (options: PGClientOptions): PGClient;
90
128
  }
91
129
  /**
92
130
  * The PostgreSQL client
93
- *
94
- * @constructor
95
131
  */
96
132
  export declare const PGClient: PGClientConstructor;
package/dist/client.mjs CHANGED
@@ -1,3 +1,49 @@
1
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
2
+ var __typeError = (msg) => {
3
+ throw TypeError(msg);
4
+ };
5
+ var __using = (stack, value, async) => {
6
+ if (value != null) {
7
+ if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
8
+ var dispose, inner;
9
+ if (async) dispose = value[__knownSymbol("asyncDispose")];
10
+ if (dispose === void 0) {
11
+ dispose = value[__knownSymbol("dispose")];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") __typeError("Object not disposable");
15
+ if (inner) dispose = function() {
16
+ try {
17
+ inner.call(this);
18
+ } catch (e) {
19
+ return Promise.reject(e);
20
+ }
21
+ };
22
+ stack.push([async, dispose, value]);
23
+ } else if (async) {
24
+ stack.push([async]);
25
+ }
26
+ return value;
27
+ };
28
+ var __callDispose = (stack, error, hasError) => {
29
+ var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
30
+ return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
31
+ };
32
+ var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
33
+ var next = (it) => {
34
+ while (it = stack.pop()) {
35
+ try {
36
+ var result = it[1] && it[1].call(it[2]);
37
+ if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
38
+ } catch (e) {
39
+ fail(e);
40
+ }
41
+ }
42
+ if (hasError) throw error;
43
+ };
44
+ return next();
45
+ };
46
+
1
47
  // client.ts
2
48
  import { Registry, serialize } from "@juit/pgproxy-types";
3
49
  import { assert } from "./assert.mjs";
@@ -12,62 +58,115 @@ function serializeParams(params) {
12
58
  return result;
13
59
  }
14
60
  var PGClient = class PGClientImpl {
15
- registry = new Registry();
61
+ _registry = new Registry();
16
62
  _provider;
17
- constructor(urlOrProvider) {
18
- urlOrProvider = urlOrProvider || globalThis?.process?.env?.PGURL;
19
- assert(urlOrProvider, "No URL to connect to (PGURL environment variable missing?)");
20
- if (typeof urlOrProvider === "string") urlOrProvider = new URL(urlOrProvider, "psql:///");
21
- assert(urlOrProvider, "Missing URL or provider for client");
22
- if (urlOrProvider instanceof URL) {
23
- if (!(urlOrProvider.username || urlOrProvider.password)) {
63
+ constructor(arg) {
64
+ arg = arg || globalThis?.process?.env?.PGURL;
65
+ assert(arg, "No URL to connect to (PGURL environment variable missing?)");
66
+ if (typeof arg === "string") arg = new URL(arg, "psql:///");
67
+ assert(arg, "Missing URL or provider for client");
68
+ if ("href" in arg) {
69
+ if (!(arg.username || arg.password)) {
24
70
  const username = globalThis?.process?.env?.PGUSER || "";
25
71
  const password = globalThis?.process?.env?.PGPASSWORD || "";
26
- urlOrProvider.username = encodeURIComponent(username);
27
- urlOrProvider.password = encodeURIComponent(password);
72
+ arg.username = encodeURIComponent(username);
73
+ arg.password = encodeURIComponent(password);
74
+ }
75
+ this._provider = createProvider(arg);
76
+ } else if ("query" in arg && "acquire" in arg && "release" in arg) {
77
+ this._provider = arg;
78
+ } else {
79
+ const {
80
+ protocol = "psql",
81
+ database = "",
82
+ username = globalThis?.process?.env?.PGUSER,
83
+ password = globalThis?.process?.env?.PGPASSWORD,
84
+ host = "localhost",
85
+ port,
86
+ parameters = {}
87
+ } = arg;
88
+ const url = new URL(`${protocol}://`);
89
+ if (host) url.hostname = host;
90
+ if (port) url.port = String(port);
91
+ if (username) url.username = encodeURIComponent(username);
92
+ if (password) url.password = encodeURIComponent(password);
93
+ url.pathname = `/${database}`;
94
+ for (const [key, value] of Object.entries(parameters)) {
95
+ url.searchParams.set(key, String(value));
28
96
  }
97
+ this._provider = createProvider(url);
29
98
  }
30
- this._provider = urlOrProvider instanceof URL ? createProvider(urlOrProvider) : urlOrProvider;
99
+ }
100
+ get registry() {
101
+ return this._registry;
102
+ }
103
+ get url() {
104
+ return this._provider.url;
31
105
  }
32
106
  async query(textOrQuery, maybeParams = []) {
33
107
  const [text, params = []] = typeof textOrQuery === "string" ? [textOrQuery, maybeParams] : [textOrQuery.query, textOrQuery.params];
34
108
  const result = await this._provider.query(text, serializeParams(params));
35
- return new PGResult(result, this.registry);
109
+ return new PGResult(result, this._registry);
36
110
  }
37
111
  async connect(consumer) {
38
112
  const connection = await this._provider.acquire();
39
- let transaction = false;
40
- try {
41
- const registry = this.registry;
42
- const consumable = {
43
- async query(textOrQuery, maybeParams = []) {
44
- const [text, params = []] = typeof textOrQuery === "string" ? [textOrQuery, maybeParams] : [textOrQuery.query, textOrQuery.params];
45
- const result = await connection.query(text, serializeParams(params));
46
- return new PGResult(result, registry);
47
- },
48
- async begin() {
49
- if (transaction) return false;
50
- await connection.query("BEGIN");
51
- return transaction = true;
52
- },
53
- async commit() {
54
- await connection.query("COMMIT");
55
- transaction = false;
56
- },
57
- async rollback() {
58
- await connection.query("ROLLBACK");
59
- transaction = false;
60
- }
61
- };
62
- return await consumer(consumable);
63
- } finally {
64
- if (transaction) await connection.query("ROLLBACK");
65
- await this._provider.release(connection);
113
+ if (!consumer) {
114
+ return new PGConnectionImpl(connection, this._provider, this._registry);
115
+ } else {
116
+ var _stack = [];
117
+ try {
118
+ const conn = __using(_stack, new PGConnectionImpl(connection, this._provider, this._registry), true);
119
+ return await consumer(conn);
120
+ } catch (_) {
121
+ var _error = _, _hasError = true;
122
+ } finally {
123
+ var _promise = __callDispose(_stack, _error, _hasError);
124
+ _promise && await _promise;
125
+ }
66
126
  }
67
127
  }
68
128
  async destroy() {
69
129
  return await this._provider.destroy();
70
130
  }
131
+ async [Symbol.asyncDispose]() {
132
+ await this.destroy();
133
+ }
134
+ };
135
+ var PGConnectionImpl = class {
136
+ _transaction = false;
137
+ _connection;
138
+ _provider;
139
+ _registry;
140
+ constructor(connection, provider, registry) {
141
+ this._connection = connection;
142
+ this._provider = provider;
143
+ this._registry = registry;
144
+ }
145
+ async query(textOrQuery, maybeParams = []) {
146
+ const [text, params = []] = typeof textOrQuery === "string" ? [textOrQuery, maybeParams] : [textOrQuery.query, textOrQuery.params];
147
+ const result = await this._connection.query(text, serializeParams(params));
148
+ return new PGResult(result, this._registry);
149
+ }
150
+ async begin() {
151
+ if (this._transaction) return false;
152
+ await this._connection.query("BEGIN");
153
+ return this._transaction = true;
154
+ }
155
+ async commit() {
156
+ await this._connection.query("COMMIT");
157
+ this._transaction = false;
158
+ }
159
+ async rollback() {
160
+ await this._connection.query("ROLLBACK");
161
+ this._transaction = false;
162
+ }
163
+ async close() {
164
+ if (this._transaction) await this._connection.query("ROLLBACK");
165
+ await this._provider.release(this._connection);
166
+ }
167
+ [Symbol.asyncDispose]() {
168
+ return this.close();
169
+ }
71
170
  };
72
171
  export {
73
172
  PGClient
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/client.ts"],
4
- "mappings": ";AAAA,SAAS,UAAU,iBAAiB;AAEpC,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AAIzB,SAAS,gBAAgB,QAA2C;AAClE,MAAI,OAAO,UAAU,EAAG,QAAO,CAAC;AAEhC,QAAM,SAA4B,IAAI,MAAM,OAAO,MAAM;AACzD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAM;AACvC,WAAO,CAAC,IACN,OAAO,CAAC,MAAM,SAAY,OAC1B,OAAO,CAAC,MAAM,OAAO,OACrB,UAAU,OAAO,CAAC,CAAC;AAAA,EACvB;AAEA,SAAO;AACT;AAsHO,IAAM,WAAgC,MAAM,aAAiC;AAAA,EACzE,WAAqB,IAAI,SAAS;AAAA,EAEnC;AAAA,EAIR,YAAY,eAAyD;AACnE,oBAAgB,iBAAmB,YAAoB,SAAS,KAAK;AACrE,WAAO,eAAe,4DAA4D;AAClF,QAAI,OAAO,kBAAkB,SAAU,iBAAgB,IAAI,IAAI,eAAe,UAAU;AACxF,WAAO,eAAe,oCAAoC;AAE1D,QAAI,yBAAyB,KAAK;AAChC,UAAI,EAAE,cAAc,YAAY,cAAc,WAAW;AACvD,cAAM,WAAa,YAAoB,SAAS,KAAK,UAAiC;AACtF,cAAM,WAAa,YAAoB,SAAS,KAAK,cAAqC;AAC1F,sBAAc,WAAW,mBAAmB,QAAQ;AACpD,sBAAc,WAAW,mBAAmB,QAAQ;AAAA,MACtD;AAAA,IACF;AAEA,SAAK,YAAY,yBAAyB,MACxC,eAAe,aAAa,IAC5B;AAAA,EACJ;AAAA,EAaA,MAAM,MAGJ,aAA+B,cAA8B,CAAC,GAAkC;AAChG,UAAM,CAAE,MAAM,SAAS,CAAC,CAAE,IAAI,OAAO,gBAAgB,WACnD,CAAE,aAAa,WAAY,IAAI,CAAE,YAAY,OAAO,YAAY,MAAO;AAGzE,UAAM,SAAS,MAAM,KAAK,UAAU,MAAM,MAAM,gBAAgB,MAAM,CAAC;AACvE,WAAO,IAAI,SAAqB,QAAQ,KAAK,QAAQ;AAAA,EACvD;AAAA,EAEA,MAAM,QAAW,UAAqC;AACpD,UAAM,aAAa,MAAM,KAAK,UAAU,QAAQ;AAChD,QAAI,cAAc;AAElB,QAAI;AACF,YAAM,WAAW,KAAK;AAEtB,YAAM,aAAgC;AAAA,QACpC,MAAM,MAGJ,aAA+B,cAA8B,CAAC,GAAkC;AAChG,gBAAM,CAAE,MAAM,SAAS,CAAC,CAAE,IAAI,OAAO,gBAAgB,WACnD,CAAE,aAAa,WAAY,IAAI,CAAE,YAAY,OAAO,YAAY,MAAO;AAEzE,gBAAM,SAAS,MAAM,WAAW,MAAM,MAAM,gBAAgB,MAAM,CAAC;AACnE,iBAAO,IAAI,SAAS,QAAQ,QAAQ;AAAA,QACtC;AAAA,QACA,MAAM,QAA0B;AAC9B,cAAI,YAAa,QAAO;AACxB,gBAAM,WAAW,MAAM,OAAO;AAC9B,iBAAO,cAAc;AAAA,QACvB;AAAA,QACA,MAAM,SAAwB;AAC5B,gBAAM,WAAW,MAAM,QAAQ;AAC/B,wBAAc;AAAA,QAChB;AAAA,QACA,MAAM,WAA0B;AAC9B,gBAAM,WAAW,MAAM,UAAU;AACjC,wBAAc;AAAA,QAChB;AAAA,MACF;AAEA,aAAO,MAAM,SAAS,UAAU;AAAA,IAClC,UAAE;AACA,UAAI,YAAa,OAAM,WAAW,MAAM,UAAU;AAClD,YAAM,KAAK,UAAU,QAAQ,UAAU;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAC7B,WAAO,MAAM,KAAK,UAAU,QAAQ;AAAA,EACtC;AACF;",
4
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,UAAU,iBAAiB;AAEpC,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AAIzB,SAAS,gBAAgB,QAA2C;AAClE,MAAI,OAAO,UAAU,EAAG,QAAO,CAAC;AAEhC,QAAM,SAA4B,IAAI,MAAM,OAAO,MAAM;AACzD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAM;AACvC,WAAO,CAAC,IACN,OAAO,CAAC,MAAM,SAAY,OAC1B,OAAO,CAAC,MAAM,OAAO,OACrB,UAAU,OAAO,CAAC,CAAC;AAAA,EACvB;AAEA,SAAO;AACT;AA4JO,IAAM,WAAgC,MAAM,aAAiC;AAAA,EACjE,YAAsB,IAAI,SAAS;AAAA,EACnC;AAAA,EAKjB,YAAY,KAAmD;AAE7D,UAAM,OAAS,YAAoB,SAAS,KAAK;AACjD,WAAO,KAAK,4DAA4D;AAGxE,QAAI,OAAO,QAAQ,SAAU,OAAM,IAAI,IAAI,KAAK,UAAU;AAC1D,WAAO,KAAK,oCAAoC;AAIhD,QAAI,UAAU,KAAK;AACjB,UAAI,EAAE,IAAI,YAAY,IAAI,WAAW;AACnC,cAAM,WAAa,YAAoB,SAAS,KAAK,UAAiC;AACtF,cAAM,WAAa,YAAoB,SAAS,KAAK,cAAqC;AAC1F,YAAI,WAAW,mBAAmB,QAAQ;AAC1C,YAAI,WAAW,mBAAmB,QAAQ;AAAA,MAC5C;AACA,WAAK,YAAY,eAAe,GAAG;AAAA,IAGrC,WAAY,WAAW,OAAS,aAAa,OAAS,aAAa,KAAM;AACvE,WAAK,YAAY;AAAA,IAGnB,OAAO;AACL,YAAM;AAAA,QACJ,WAAW;AAAA,QACX,WAAW;AAAA,QACX,WAAa,YAAoB,SAAS,KAAK;AAAA,QAC/C,WAAa,YAAoB,SAAS,KAAK;AAAA,QAC/C,OAAO;AAAA,QACP;AAAA,QACA,aAAa,CAAC;AAAA,MAChB,IAAI;AAEJ,YAAM,MAAM,IAAI,IAAI,GAAG,QAAQ,KAAK;AACpC,UAAI,KAAM,KAAI,WAAW;AACzB,UAAI,KAAM,KAAI,OAAO,OAAO,IAAI;AAChC,UAAI,SAAU,KAAI,WAAW,mBAAmB,QAAQ;AACxD,UAAI,SAAU,KAAI,WAAW,mBAAmB,QAAQ;AACxD,UAAI,WAAW,IAAI,QAAQ;AAE3B,iBAAW,CAAE,KAAK,KAAM,KAAK,OAAO,QAAQ,UAAU,GAAG;AACvD,YAAI,aAAa,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,MACzC;AAEA,WAAK,YAAY,eAAe,GAAG;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,IAAI,WAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAqB;AACvB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAYA,MAAM,MAGJ,aAA+B,cAA8B,CAAC,GAAkC;AAChG,UAAM,CAAE,MAAM,SAAS,CAAC,CAAE,IAAI,OAAO,gBAAgB,WACnD,CAAE,aAAa,WAAY,IAAI,CAAE,YAAY,OAAO,YAAY,MAAO;AAEzE,UAAM,SAAS,MAAM,KAAK,UAAU,MAAM,MAAM,gBAAgB,MAAM,CAAC;AACvE,WAAO,IAAI,SAAqB,QAAQ,KAAK,SAAS;AAAA,EACxD;AAAA,EAEA,MAAM,QAAW,UAAqD;AACpE,UAAM,aAAa,MAAM,KAAK,UAAU,QAAQ;AAEhD,QAAI,CAAE,UAAU;AACd,aAAO,IAAI,iBAAiB,YAAY,KAAK,WAAW,KAAK,SAAS;AAAA,IACxE,OAAO;AACL;AAAA;AAAA,cAAY,OAAO,oBAAI,iBAAiB,YAAY,KAAK,WAAW,KAAK,SAAS,GAA/D;AACnB,eAAO,MAAM,SAAS,IAAI;AAAA,eAD1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAEF;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAC7B,WAAO,MAAM,KAAK,UAAU,QAAQ;AAAA,EACtC;AAAA,EAEA,OAAO,OAAO,YAAY,IAAmB;AAC3C,UAAM,KAAK,QAAQ;AAAA,EACrB;AACF;AAIA,IAAM,mBAAN,MAA+C;AAAA,EACrC,eAAwB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YACI,YACA,UACA,UAAoB;AACtB,SAAK,cAAc;AACnB,SAAK,YAAY;AACjB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAM,MAGJ,aAA+B,cAA8B,CAAC,GAAkC;AAChG,UAAM,CAAE,MAAM,SAAS,CAAC,CAAE,IAAI,OAAO,gBAAgB,WACnD,CAAE,aAAa,WAAY,IAAI,CAAE,YAAY,OAAO,YAAY,MAAO;AAEzE,UAAM,SAAS,MAAM,KAAK,YAAY,MAAM,MAAM,gBAAgB,MAAM,CAAC;AACzE,WAAO,IAAI,SAAS,QAAQ,KAAK,SAAS;AAAA,EAC5C;AAAA,EAEA,MAAM,QAA0B;AAC9B,QAAI,KAAK,aAAc,QAAO;AAC9B,UAAM,KAAK,YAAY,MAAM,OAAO;AACpC,WAAO,KAAK,eAAe;AAAA,EAC7B;AAAA,EAEA,MAAM,SAAwB;AAC5B,UAAM,KAAK,YAAY,MAAM,QAAQ;AACrC,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,MAAM,WAA0B;AAC9B,UAAM,KAAK,YAAY,MAAM,UAAU;AACvC,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK,aAAc,OAAM,KAAK,YAAY,MAAM,UAAU;AAC9D,UAAM,KAAK,UAAU,QAAQ,KAAK,WAAW;AAAA,EAC/C;AAAA,EAEA,CAAC,OAAO,YAAY,IAAmB;AACrC,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;",
5
5
  "names": []
6
6
  }
package/dist/provider.cjs CHANGED
@@ -26,7 +26,19 @@ __export(provider_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(provider_exports);
28
28
  var import_assert = require("./assert.cjs");
29
+ var providerUrls = /* @__PURE__ */ new WeakMap();
29
30
  var AbstractPGProvider = class {
31
+ constructor(url) {
32
+ providerUrls.set(this, new URL(url));
33
+ }
34
+ get url() {
35
+ const url = providerUrls.get(this);
36
+ (0, import_assert.assert)(url, "Internal error: missing provider URL");
37
+ const sanitizedUrl = new URL(url);
38
+ sanitizedUrl.username = "";
39
+ sanitizedUrl.password = "";
40
+ return sanitizedUrl;
41
+ }
30
42
  async query(text, params = []) {
31
43
  const connection = await this.acquire();
32
44
  try {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/provider.ts"],
4
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAuB;AAqChB,IAAe,qBAAf,MAC2B;AAAA,EAIhC,MAAM,MAAM,MAAc,SAA4B,CAAC,GAAgC;AACrF,UAAM,aAAa,MAAM,KAAK,QAAQ;AACtC,QAAI;AACF,aAAO,MAAM,WAAW,MAAM,MAAM,MAAM;AAAA,IAC5C,UAAE;AACA,YAAM,KAAK,QAAQ,UAAU;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAAA,EAE/B;AACF;AAOA,IAAM,YAAY,oBAAI,IAAiD;AAGhE,SAAS,iBACZ,UACA,aACI;AACN,aAAW,GAAG,QAAQ;AACtB,4BAAO,CAAE,UAAU,IAAI,QAAQ,GAAG,4BAA4B,QAAQ,yBAAyB;AAC/F,YAAU,IAAI,UAAU,WAAW;AACnC,YAAU,IAAI,UAAU,WAAW;AACrC;AAGO,SAAS,eAAe,KAAoC;AACjE,QAAM,WAAW,UAAU,IAAI,IAAI,QAAQ;AAC3C,4BAAO,UAAU,0CAA0C,IAAI,QAAQ,MAAM;AAC7E,SAAO,IAAI,SAAS,GAAG;AACzB;",
4
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAuB;AAyCvB,IAAM,eAAe,oBAAI,QAAiC;AAEnD,IAAe,qBAAf,MAC2B;AAAA,EAChC,YAAY,KAAmB;AAC7B,iBAAa,IAAI,MAAM,IAAI,IAAI,GAAG,CAAC;AAAA,EACrC;AAAA,EAEA,IAAI,MAAqB;AACvB,UAAM,MAAM,aAAa,IAAI,IAAI;AACjC,8BAAO,KAAK,sCAAsC;AAClD,UAAM,eAAe,IAAI,IAAI,GAAG;AAChC,iBAAa,WAAW;AACxB,iBAAa,WAAW;AACxB,WAAO;AAAA,EACT;AAAA,EAKA,MAAM,MAAM,MAAc,SAA4B,CAAC,GAA8B;AACnF,UAAM,aAAa,MAAM,KAAK,QAAQ;AACtC,QAAI;AACF,aAAO,MAAM,WAAW,MAAM,MAAM,MAAM;AAAA,IAC5C,UAAE;AACA,YAAM,KAAK,QAAQ,UAAU;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAAA,EAE/B;AACF;AAQA,IAAM,YAAY,oBAAI,IAAmC;AAGlD,SAAS,iBACZ,UACA,aACI;AACN,aAAW,GAAG,QAAQ;AACtB,4BAAO,CAAE,UAAU,IAAI,QAAQ,GAAG,4BAA4B,QAAQ,yBAAyB;AAC/F,YAAU,IAAI,UAAU,WAAW;AACnC,YAAU,IAAI,UAAU,WAAW;AACrC;AAGO,SAAS,eAAe,KAAsB;AACnD,QAAM,WAAW,UAAU,IAAI,IAAI,QAAQ;AAC3C,4BAAO,UAAU,0CAA0C,IAAI,QAAQ,MAAM;AAC7E,SAAO,IAAI,SAAS,GAAG;AACzB;",
5
5
  "names": []
6
6
  }