@juit/pgproxy-client 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # PostgreSQL Proxy Client (Base Package)
2
+
3
+ This package provides the main entry point for clients to work with PGProxy
4
+ Servers. It acts both as an abstraction layer over the various client
5
+ implementations _and_ as a registry for them.
6
+
7
+ * [Connecting](#connecting)
8
+ * [Client](#client)
9
+ * [PGProxy](https://github.com/juitnow/juit-pgproxy/blob/main/README.md)
10
+ * [Copyright Notice](https://github.com/juitnow/juit-pgproxy/blob/main/NOTICE.md)
11
+ * [License](https://github.com/juitnow/juit-pgproxy/blob/main/NOTICE.md)
12
+
13
+ ### Connecting
14
+
15
+ In the code, you can simply depend on the `PGClient` class:
16
+
17
+ ```ts
18
+ import { PGClient } from '@juit/pgproxy-client'
19
+
20
+ const client = new PGClient()
21
+ ```
22
+
23
+ The client can be constructed with a `url` as a parameter, indicating the
24
+ endpoint of the connection _and_ the specific client to be used. If no such
25
+ parameter is specified, the value of the `PGURL` environment variable will be
26
+ used.
27
+
28
+ Additionally if the URL specified at construction (or in the `PGURL` environment
29
+ variable) does not provide ANY authentication information, the `PGUSER` and
30
+ `PGPASSWORD` environment variables will be used to fill in those details.
31
+
32
+ Specific implementations are registered by simply importing their library:
33
+
34
+ * `@juit/pgproxy-client-node`: The HTTP client for NodeJS \
35
+ handles URLs like: `http(s)://secret@host:port/`
36
+ * `@juit/pgproxy-client-whatwg`: The HTTP client for WhatWG + WebCrypto \
37
+ handles URLs like: `http(s)://secret@host:port/`
38
+ * `@juit/pgproxy-client-psql`: The direct LibPQ-based client \
39
+ handles URLs like: `psql://usrname:password@host:port/database`
40
+
41
+ The ability to abstract client and connection details allows the code to be
42
+ as portable as possible. For example in an AWS Lambda Function:
43
+
44
+ ```ts
45
+ // Entry point for AWS Lambda functions
46
+
47
+ // Import the _node_ client, the PGURL environment variable comes from the
48
+ // Lambda definitions and can be specified via the AWS console, it will have
49
+ // a format like: https://my-secret@my-ec2-instance:54321/
50
+ import '@pgproxy/client-node'
51
+
52
+ export const handler = async (event: LambdaEvent) => {
53
+ // ... use code that connects to the database using `new PGClient()`
54
+ }
55
+ ```
56
+
57
+ Similarly, when running a test requiring a connection to a _local_ database
58
+ (no need to spin up a whole PGProxy Server to test):
59
+
60
+ ```ts
61
+ // Entry point for tests
62
+
63
+ // Import the _psql_ client, which will be registered as a handler for the
64
+ // "psql" protocol in PGClient
65
+ import '@pgproxy/client-psql'
66
+
67
+ beforeAll(() => {
68
+ process.env.PGURL = "psql://username:password@localhost:5432/my-database"
69
+ })
70
+
71
+ it('should run tests connecting to the database', async () => {
72
+ // ... test the code using `new PGCLient()`
73
+ })
74
+ ```
75
+
76
+ ### Client
77
+
78
+ Simple queries can be executed on the database via the `query(...)` method:
79
+
80
+ ```ts
81
+ const client = new PGClient()
82
+ const result = await client.query('SELECT * FROM test WHERE value = $1', [ 'theValue' ])
83
+ ```
84
+
85
+ More complex queries (e.g. transactions) can be performed using the
86
+ `connect(...)` method:
87
+
88
+ ```ts
89
+ const client = new PGClient()
90
+ // here "result" will be the value returned by the callback passed to "connect"
91
+ const result = await client.connect(async (connection) => {
92
+ await connection.begin()
93
+
94
+ await connection.query(...) // ... all transaction queries
95
+
96
+ await connection.commit()
97
+ return result // returned to whatever is awaiting on "connect"
98
+ })
99
+ ```
100
+
101
+ The `query(...)` method requires one parameter, the SQL query to run, and allows
102
+ parameters (as an array) to be declared as a second, optional parameter.
103
+
104
+ The object passed to the `connect(...)` callback provides the following methods:
105
+
106
+ * `query(...)`: as above
107
+ * `begin()`: issues the `BEGIN` SQL statement (starts a transaction)
108
+ * `commit()`: issues the `COMMIT` SQL statement (commits a transaction)
109
+ * `rollback()`: issues the `ROLLBACK` SQL statement (rolls back a transaction)
110
+
111
+ Uncommitted transactions will always be rolled back by the connection pool code.
112
+
113
+ ### Result
114
+
115
+ The result returned by the `query(...)` method is a simple object containing:
116
+
117
+ * `command` (_string_): The SQL command that generated this result (e.g.
118
+ `SELECT`, `INSERT`, ...)
119
+ * `rowCount` (_number_): The number of rows affected by the query. \
120
+ This can be the number of lines returned in `rows` (for `SELECT`
121
+ statements, for example) or the number of lines _affected_ by the query
122
+ (the number of records inserted by an `INSERT` query).
123
+ * `rows` (_Record<string, any>[]_): The rows returned by the database query,
124
+ keyed by the column name.
125
+ * `tuples` (_any[][]_): The tuples returned by the database query, keyed by
126
+ the column index. */
127
+
128
+
129
+ ### Types
130
+
131
+ Each client exposes its own _types registry_ in the `registry` field.
132
+
133
+ By manipulating the registry, one can tweak the conversion of PostgreSQL types
134
+ to JavaScript types.
135
+
136
+ For more informations see the `@juit/pgproxy-types` package.
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // assert.ts
21
+ var assert_exports = {};
22
+ __export(assert_exports, {
23
+ assert: () => assert
24
+ });
25
+ module.exports = __toCommonJS(assert_exports);
26
+ function assert(what, message) {
27
+ if (!what)
28
+ throw new Error(message);
29
+ }
30
+ // Annotate the CommonJS export names for ESM import in node:
31
+ 0 && (module.exports = {
32
+ assert
33
+ });
34
+ //# sourceMappingURL=assert.cjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/assert.ts"],
4
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACO,SAAS,OAAO,MAAe,SAA+B;AACnE,MAAI,CAAE;AAAM,UAAM,IAAI,MAAM,OAAO;AACrC;",
5
+ "names": []
6
+ }
@@ -0,0 +1,2 @@
1
+ /** The easiest assertion function in the world */
2
+ export declare function assert(what: unknown, message: string): asserts what;
@@ -0,0 +1,9 @@
1
+ // assert.ts
2
+ function assert(what, message) {
3
+ if (!what)
4
+ throw new Error(message);
5
+ }
6
+ export {
7
+ assert
8
+ };
9
+ //# sourceMappingURL=assert.mjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/assert.ts"],
4
+ "mappings": ";AACO,SAAS,OAAO,MAAe,SAA+B;AACnE,MAAI,CAAE;AAAM,UAAM,IAAI,MAAM,OAAO;AACrC;",
5
+ "names": []
6
+ }
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // client.ts
21
+ var client_exports = {};
22
+ __export(client_exports, {
23
+ PGClient: () => PGClient
24
+ });
25
+ module.exports = __toCommonJS(client_exports);
26
+ var import_pgproxy_types = require("@juit/pgproxy-types");
27
+ var import_assert = require("./assert.cjs");
28
+ var import_provider = require("./provider.cjs");
29
+ var import_result = require("./result.cjs");
30
+ function serializeParams(params) {
31
+ if (params.length == 0)
32
+ return [];
33
+ const result = new Array(params.length);
34
+ for (let i = 0; i < params.length; i++) {
35
+ result[i] = params[i] === void 0 ? null : params[i] === null ? null : (0, import_pgproxy_types.serialize)(params[i]);
36
+ }
37
+ return result;
38
+ }
39
+ var PGClient = class PGClientImpl {
40
+ registry = new import_pgproxy_types.Registry();
41
+ _provider;
42
+ constructor(urlOrProvider) {
43
+ urlOrProvider = urlOrProvider || globalThis?.process?.env?.PGURL;
44
+ (0, import_assert.assert)(urlOrProvider, "No URL to connect to (PGURL environment variable missing?)");
45
+ if (typeof urlOrProvider === "string")
46
+ urlOrProvider = new URL(urlOrProvider, "psql:///");
47
+ (0, import_assert.assert)(urlOrProvider, "Missing URL or provider for client");
48
+ if (urlOrProvider instanceof URL) {
49
+ if (!(urlOrProvider.username || urlOrProvider.password)) {
50
+ const username = globalThis?.process?.env?.PGUSER || "";
51
+ const password = globalThis?.process?.env?.PGPASSWORD || "";
52
+ urlOrProvider.username = encodeURIComponent(username);
53
+ urlOrProvider.password = encodeURIComponent(password);
54
+ }
55
+ }
56
+ this._provider = urlOrProvider instanceof URL ? (0, import_provider.createProvider)(urlOrProvider) : urlOrProvider;
57
+ }
58
+ async query(text, params = []) {
59
+ const result = await this._provider.query(text, serializeParams(params));
60
+ return new import_result.PGResult(result, this.registry);
61
+ }
62
+ async connect(consumer) {
63
+ const connection = await this._provider.acquire();
64
+ try {
65
+ const registry = this.registry;
66
+ const consumable = {
67
+ async query(text, params = []) {
68
+ const result = await connection.query(text, serializeParams(params));
69
+ return new import_result.PGResult(result, registry);
70
+ },
71
+ async begin() {
72
+ await this.query("BEGIN");
73
+ return this;
74
+ },
75
+ async commit() {
76
+ await this.query("COMMIT");
77
+ return this;
78
+ },
79
+ async rollback() {
80
+ await this.query("ROLLBACK");
81
+ return this;
82
+ }
83
+ };
84
+ return await consumer(consumable);
85
+ } finally {
86
+ await this._provider.release(connection);
87
+ }
88
+ }
89
+ async destroy() {
90
+ return await this._provider.destroy();
91
+ }
92
+ };
93
+ // Annotate the CommonJS export names for ESM import in node:
94
+ 0 && (module.exports = {
95
+ PGClient
96
+ });
97
+ //# sourceMappingURL=client.cjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 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,QAAkC;AACzD,MAAI,OAAO,UAAU;AAAG,WAAO,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;AA+EO,IAAM,WAAgC,MAAM,aAAiC;AAAA,EACzE,WAAqB,IAAI,8BAAS;AAAA,EAEnC;AAAA,EAIR,YAAY,eAAyD;AACnE,oBAAgB,iBAAiB,YAAY,SAAS,KAAK;AAC3D,8BAAO,eAAe,4DAA4D;AAClF,QAAI,OAAO,kBAAkB;AAAU,sBAAgB,IAAI,IAAI,eAAe,UAAU;AACxF,8BAAO,eAAe,oCAAoC;AAE1D,QAAI,yBAAyB,KAAK;AAChC,UAAI,EAAE,cAAc,YAAY,cAAc,WAAW;AACvD,cAAM,WAAW,YAAY,SAAS,KAAK,UAAU;AACrD,cAAM,WAAW,YAAY,SAAS,KAAK,cAAc;AACzD,sBAAc,WAAW,mBAAmB,QAAQ;AACpD,sBAAc,WAAW,mBAAmB,QAAQ;AAAA,MACtD;AAAA,IACF;AAEA,SAAK,YAAY,yBAAyB,UACtC,gCAAe,aAAa,IAC5B;AAAA,EACN;AAAA,EAEA,MAAM,MAGJ,MAAc,SAAgB,CAAC,GAAkC;AACjE,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;AAEhD,QAAI;AACF,YAAM,WAAW,KAAK;AAEtB,YAAM,aAAgC;AAAA,QACpC,MAAM,MAGJ,MAAc,SAAgB,CAAC,GAAkC;AACjE,gBAAM,SAAS,MAAM,WAAW,MAAM,MAAM,gBAAgB,MAAM,CAAC;AACnE,iBAAO,IAAI,uBAAS,QAAQ,QAAQ;AAAA,QACtC;AAAA,QACA,MAAM,QAAoC;AACxC,gBAAM,KAAK,MAAM,OAAO;AACxB,iBAAO;AAAA,QACT;AAAA,QACA,MAAM,SAAqC;AACzC,gBAAM,KAAK,MAAM,QAAQ;AACzB,iBAAO;AAAA,QACT;AAAA,QACA,MAAM,WAAuC;AAC3C,gBAAM,KAAK,MAAM,UAAU;AAC3B,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO,MAAM,SAAS,UAAU;AAAA,IAClC,UAAE;AACA,YAAM,KAAK,UAAU,QAAQ,UAAU;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAC7B,WAAO,MAAM,KAAK,UAAU,QAAQ;AAAA,EACtC;AACF;",
5
+ "names": []
6
+ }
@@ -0,0 +1,67 @@
1
+ /// <reference types="node" />
2
+ import { Registry } from '@juit/pgproxy-types';
3
+ import { PGResult } from './result';
4
+ import type { PGConnection, PGProvider } from './provider';
5
+ /** An interface for an object that can execute queries on a database */
6
+ export interface PGQueryable {
7
+ /**
8
+ * Execute a query on the database
9
+ *
10
+ * @param text - The SQL query to execute optionally containing placeholders.
11
+ * @param params - Any parameter replacement for `$x` placeholders.
12
+ */
13
+ query<Row extends Record<string, any> = Record<string, any>, Tuple extends readonly any[] = readonly any[]>(text: string, params?: any[]): Promise<PGResult<Row, Tuple>>;
14
+ }
15
+ /**
16
+ * An interface for an object that can execute queries _and transactions_
17
+ * on a database */
18
+ export interface PGTransactionable extends PGQueryable {
19
+ /** Start a transaction by issuing a `BEGIN` statement */
20
+ begin(): Promise<this>;
21
+ /** Commit a transaction by issuing a `COMMIT` statement */
22
+ commit(): Promise<this>;
23
+ /** Cancel a transaction by issuing a `ROLLBACK` statement */
24
+ rollback(): Promise<this>;
25
+ }
26
+ /** A consumer for a {@link PGTransactionable} connection */
27
+ export type PGConsumer<T> = (connection: PGTransactionable) => T | PromiseLike<T>;
28
+ /** The PostgreSQL client */
29
+ export interface PGClient extends PGQueryable {
30
+ /** The {@link @juit/pgproxy-types#Registry} used to parse results from PostgreSQL */
31
+ readonly registry: Registry;
32
+ /**
33
+ * Execute a _single_ query on the database.
34
+ *
35
+ * Invoking the `query` method on a {@link (PGClient:interface)} does NOT guarantee that
36
+ * the query will be executed on the same connection, therefore things like
37
+ * _transactions_ will be immediately rolled back after the query.
38
+ *
39
+ * @param text - The SQL query to execute optionally containing placeholders.
40
+ * @param params - Any parameter replacement for `$x` placeholders.
41
+ */
42
+ query<Row extends Record<string, any> = Record<string, any>, Tuple extends readonly any[] = readonly any[]>(text: string, params?: any[]): Promise<PGResult<Row, Tuple>>;
43
+ /**
44
+ * Connect to the database to execute a number of different queries.
45
+ *
46
+ * The `consumer` will be passed a {@link PGTransactionable} instance backed
47
+ * by the _same_ connection to the database, therefore transactions can be
48
+ * safely executed in the context of the consumer function itself.
49
+ */
50
+ connect<T>(consumer: PGConsumer<T>): Promise<T>;
51
+ /**
52
+ * Destroy any resource and underlying connection associated with this
53
+ * instance's {@link PGProvider}.
54
+ */
55
+ destroy(): Promise<void>;
56
+ }
57
+ /** A constructor for {@link (PGClient:interface)} instances */
58
+ export interface PGClientConstructor {
59
+ new (url?: string | URL): PGClient;
60
+ new (provider: PGProvider<PGConnection>): PGClient;
61
+ }
62
+ /**
63
+ * The PostgreSQL client
64
+ *
65
+ * @constructor
66
+ */
67
+ export declare const PGClient: PGClientConstructor;
@@ -0,0 +1,72 @@
1
+ // client.ts
2
+ import { Registry, serialize } from "@juit/pgproxy-types";
3
+ import { assert } from "./assert.mjs";
4
+ import { createProvider } from "./provider.mjs";
5
+ import { PGResult } from "./result.mjs";
6
+ function serializeParams(params) {
7
+ if (params.length == 0)
8
+ return [];
9
+ const result = new Array(params.length);
10
+ for (let i = 0; i < params.length; i++) {
11
+ result[i] = params[i] === void 0 ? null : params[i] === null ? null : serialize(params[i]);
12
+ }
13
+ return result;
14
+ }
15
+ var PGClient = class PGClientImpl {
16
+ registry = new Registry();
17
+ _provider;
18
+ constructor(urlOrProvider) {
19
+ urlOrProvider = urlOrProvider || globalThis?.process?.env?.PGURL;
20
+ assert(urlOrProvider, "No URL to connect to (PGURL environment variable missing?)");
21
+ if (typeof urlOrProvider === "string")
22
+ urlOrProvider = new URL(urlOrProvider, "psql:///");
23
+ assert(urlOrProvider, "Missing URL or provider for client");
24
+ if (urlOrProvider instanceof URL) {
25
+ if (!(urlOrProvider.username || urlOrProvider.password)) {
26
+ const username = globalThis?.process?.env?.PGUSER || "";
27
+ const password = globalThis?.process?.env?.PGPASSWORD || "";
28
+ urlOrProvider.username = encodeURIComponent(username);
29
+ urlOrProvider.password = encodeURIComponent(password);
30
+ }
31
+ }
32
+ this._provider = urlOrProvider instanceof URL ? createProvider(urlOrProvider) : urlOrProvider;
33
+ }
34
+ async query(text, params = []) {
35
+ const result = await this._provider.query(text, serializeParams(params));
36
+ return new PGResult(result, this.registry);
37
+ }
38
+ async connect(consumer) {
39
+ const connection = await this._provider.acquire();
40
+ try {
41
+ const registry = this.registry;
42
+ const consumable = {
43
+ async query(text, params = []) {
44
+ const result = await connection.query(text, serializeParams(params));
45
+ return new PGResult(result, registry);
46
+ },
47
+ async begin() {
48
+ await this.query("BEGIN");
49
+ return this;
50
+ },
51
+ async commit() {
52
+ await this.query("COMMIT");
53
+ return this;
54
+ },
55
+ async rollback() {
56
+ await this.query("ROLLBACK");
57
+ return this;
58
+ }
59
+ };
60
+ return await consumer(consumable);
61
+ } finally {
62
+ await this._provider.release(connection);
63
+ }
64
+ }
65
+ async destroy() {
66
+ return await this._provider.destroy();
67
+ }
68
+ };
69
+ export {
70
+ PGClient
71
+ };
72
+ //# sourceMappingURL=client.mjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 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,QAAkC;AACzD,MAAI,OAAO,UAAU;AAAG,WAAO,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;AA+EO,IAAM,WAAgC,MAAM,aAAiC;AAAA,EACzE,WAAqB,IAAI,SAAS;AAAA,EAEnC;AAAA,EAIR,YAAY,eAAyD;AACnE,oBAAgB,iBAAiB,YAAY,SAAS,KAAK;AAC3D,WAAO,eAAe,4DAA4D;AAClF,QAAI,OAAO,kBAAkB;AAAU,sBAAgB,IAAI,IAAI,eAAe,UAAU;AACxF,WAAO,eAAe,oCAAoC;AAE1D,QAAI,yBAAyB,KAAK;AAChC,UAAI,EAAE,cAAc,YAAY,cAAc,WAAW;AACvD,cAAM,WAAW,YAAY,SAAS,KAAK,UAAU;AACrD,cAAM,WAAW,YAAY,SAAS,KAAK,cAAc;AACzD,sBAAc,WAAW,mBAAmB,QAAQ;AACpD,sBAAc,WAAW,mBAAmB,QAAQ;AAAA,MACtD;AAAA,IACF;AAEA,SAAK,YAAY,yBAAyB,MACtC,eAAe,aAAa,IAC5B;AAAA,EACN;AAAA,EAEA,MAAM,MAGJ,MAAc,SAAgB,CAAC,GAAkC;AACjE,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;AAEhD,QAAI;AACF,YAAM,WAAW,KAAK;AAEtB,YAAM,aAAgC;AAAA,QACpC,MAAM,MAGJ,MAAc,SAAgB,CAAC,GAAkC;AACjE,gBAAM,SAAS,MAAM,WAAW,MAAM,MAAM,gBAAgB,MAAM,CAAC;AACnE,iBAAO,IAAI,SAAS,QAAQ,QAAQ;AAAA,QACtC;AAAA,QACA,MAAM,QAAoC;AACxC,gBAAM,KAAK,MAAM,OAAO;AACxB,iBAAO;AAAA,QACT;AAAA,QACA,MAAM,SAAqC;AACzC,gBAAM,KAAK,MAAM,QAAQ;AACzB,iBAAO;AAAA,QACT;AAAA,QACA,MAAM,WAAuC;AAC3C,gBAAM,KAAK,MAAM,UAAU;AAC3B,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO,MAAM,SAAS,UAAU;AAAA,IAClC,UAAE;AACA,YAAM,KAAK,UAAU,QAAQ,UAAU;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAC7B,WAAO,MAAM,KAAK,UAAU,QAAQ;AAAA,EACtC;AACF;",
5
+ "names": []
6
+ }
package/dist/index.cjs ADDED
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
+
17
+ // index.ts
18
+ var src_exports = {};
19
+ module.exports = __toCommonJS(src_exports);
20
+ __reExport(src_exports, require("./assert.cjs"), module.exports);
21
+ __reExport(src_exports, require("./client.cjs"), module.exports);
22
+ __reExport(src_exports, require("./provider.cjs"), module.exports);
23
+ __reExport(src_exports, require("./result.cjs"), module.exports);
24
+ __reExport(src_exports, require("./websocket.cjs"), module.exports);
25
+ // Annotate the CommonJS export names for ESM import in node:
26
+ 0 && (module.exports = {
27
+ ...require("./assert.cjs"),
28
+ ...require("./client.cjs"),
29
+ ...require("./provider.cjs"),
30
+ ...require("./result.cjs"),
31
+ ...require("./websocket.cjs")
32
+ });
33
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,wBAAc,yBAAd;AACA,wBAAc,yBADd;AAEA,wBAAc,2BAFd;AAGA,wBAAc,yBAHd;AAIA,wBAAc,4BAJd;",
5
+ "names": []
6
+ }
@@ -0,0 +1,5 @@
1
+ export * from './assert';
2
+ export * from './client';
3
+ export * from './provider';
4
+ export * from './result';
5
+ export * from './websocket';
package/dist/index.mjs ADDED
@@ -0,0 +1,7 @@
1
+ // index.ts
2
+ export * from "./assert.mjs";
3
+ export * from "./client.mjs";
4
+ export * from "./provider.mjs";
5
+ export * from "./result.mjs";
6
+ export * from "./websocket.mjs";
7
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "mappings": ";AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
5
+ "names": []
6
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // provider.ts
21
+ var provider_exports = {};
22
+ __export(provider_exports, {
23
+ AbstractPGProvider: () => AbstractPGProvider,
24
+ createProvider: () => createProvider,
25
+ registerProvider: () => registerProvider
26
+ });
27
+ module.exports = __toCommonJS(provider_exports);
28
+ var import_assert = require("./assert.cjs");
29
+ var AbstractPGProvider = class {
30
+ async query(text, params) {
31
+ const connection = await this.acquire();
32
+ try {
33
+ return await connection.query(text, params);
34
+ } finally {
35
+ await this.release(connection);
36
+ }
37
+ }
38
+ async destroy() {
39
+ }
40
+ };
41
+ var providers = /* @__PURE__ */ new Map();
42
+ function registerProvider(protocol, constructor) {
43
+ protocol = `${protocol}:`;
44
+ (0, import_assert.assert)(!providers.has(protocol), `Connection provider for "${protocol}..." already registered`);
45
+ providers.set(protocol, constructor);
46
+ providers.set(protocol, constructor);
47
+ }
48
+ function createProvider(url) {
49
+ const Provider = providers.get(url.protocol);
50
+ (0, import_assert.assert)(Provider, `No connection provider registered for "${url.protocol}..."`);
51
+ return new Provider(url);
52
+ }
53
+ // Annotate the CommonJS export names for ESM import in node:
54
+ 0 && (module.exports = {
55
+ AbstractPGProvider,
56
+ createProvider,
57
+ registerProvider
58
+ });
59
+ //# sourceMappingURL=provider.cjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 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,QAA+C;AACvE,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;",
5
+ "names": []
6
+ }
@@ -0,0 +1,33 @@
1
+ /// <reference types="node" />
2
+ /** Describes the result of a query from a {@link PGProvider} */
3
+ export interface PGConnectionResult {
4
+ /** The SQL command that generated this result (`SELECT`, `INSERT`, ...) */
5
+ command: string;
6
+ /** Number of rows affected by this query (e.g. added rows in `INSERT`) */
7
+ rowCount: number;
8
+ /** Fields description with `name` (column name) and `oid` (type) */
9
+ fields: [name: string, oid: number][];
10
+ /** Result rows, as an array of unparsed `string` results from `libpq` */
11
+ rows: (string | null)[][];
12
+ }
13
+ export interface PGConnection {
14
+ query(text: string, params: (string | null)[]): Promise<PGConnectionResult>;
15
+ }
16
+ export interface PGProviderConstructor<Connection extends PGConnection> {
17
+ new (url: URL): PGProvider<Connection>;
18
+ }
19
+ export interface PGProvider<Connection extends PGConnection> extends PGConnection {
20
+ acquire(): Promise<Connection>;
21
+ release(connection: Connection): Promise<void>;
22
+ destroy(): Promise<void>;
23
+ }
24
+ export declare abstract class AbstractPGProvider<Connection extends PGConnection> implements PGProvider<Connection> {
25
+ abstract acquire(): Promise<Connection>;
26
+ abstract release(connection: PGConnection): Promise<void>;
27
+ query(text: string, params: string[]): Promise<PGConnectionResult>;
28
+ destroy(): Promise<void>;
29
+ }
30
+ /** Register a provider, associating it with the specified protocol */
31
+ export declare function registerProvider(protocol: string, constructor: PGProviderConstructor<PGConnection>): void;
32
+ /** Create a new {@link PGProvider} instance for the specified URL */
33
+ export declare function createProvider(url: URL): PGProvider<PGConnection>;
@@ -0,0 +1,32 @@
1
+ // provider.ts
2
+ import { assert } from "./assert.mjs";
3
+ var AbstractPGProvider = class {
4
+ async query(text, params) {
5
+ const connection = await this.acquire();
6
+ try {
7
+ return await connection.query(text, params);
8
+ } finally {
9
+ await this.release(connection);
10
+ }
11
+ }
12
+ async destroy() {
13
+ }
14
+ };
15
+ var providers = /* @__PURE__ */ new Map();
16
+ function registerProvider(protocol, constructor) {
17
+ protocol = `${protocol}:`;
18
+ assert(!providers.has(protocol), `Connection provider for "${protocol}..." already registered`);
19
+ providers.set(protocol, constructor);
20
+ providers.set(protocol, constructor);
21
+ }
22
+ function createProvider(url) {
23
+ const Provider = providers.get(url.protocol);
24
+ assert(Provider, `No connection provider registered for "${url.protocol}..."`);
25
+ return new Provider(url);
26
+ }
27
+ export {
28
+ AbstractPGProvider,
29
+ createProvider,
30
+ registerProvider
31
+ };
32
+ //# sourceMappingURL=provider.mjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/provider.ts"],
4
+ "mappings": ";AAAA,SAAS,cAAc;AAqChB,IAAe,qBAAf,MAC2B;AAAA,EAIhC,MAAM,MAAM,MAAc,QAA+C;AACvE,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,SAAO,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,SAAO,UAAU,0CAA0C,IAAI,QAAQ,MAAM;AAC7E,SAAO,IAAI,SAAS,GAAG;AACzB;",
5
+ "names": []
6
+ }