@effect/sql-pg 4.0.0-rc.114 → 4.0.0-rc.116
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 +125 -1
- package/ai-docs/package.json +1 -1
- package/dist/PgClient.d.ts +27 -3
- package/dist/PgClient.d.ts.map +1 -1
- package/dist/PgClient.js.map +1 -1
- package/dist/PgConnection.d.ts +37 -9
- package/dist/PgConnection.d.ts.map +1 -1
- package/dist/PgConnection.js +74 -39
- package/dist/PgConnection.js.map +1 -1
- package/dist/PgMigrator.d.ts.map +1 -1
- package/dist/PgMigrator.js +15 -10
- package/dist/PgMigrator.js.map +1 -1
- package/dist/PgTypes.d.ts +18 -10
- package/dist/PgTypes.d.ts.map +1 -1
- package/dist/PgTypes.js +48 -31
- package/dist/PgTypes.js.map +1 -1
- package/dist/internal/password.d.ts +4 -0
- package/dist/internal/password.d.ts.map +1 -0
- package/dist/internal/password.js +4 -0
- package/dist/internal/password.js.map +1 -0
- package/package.json +5 -5
- package/src/PgClient.ts +28 -4
- package/src/PgConnection.ts +119 -53
- package/src/PgMigrator.ts +18 -19
- package/src/PgTypes.ts +49 -31
- package/src/internal/password.ts +11 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @effect/sql-pg
|
|
2
2
|
|
|
3
|
-
An Effect SQL client for PostgreSQL
|
|
3
|
+
An Effect SQL client for PostgreSQL with a native wire-protocol driver.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,6 +8,130 @@ An Effect SQL client for PostgreSQL, built on the [`pg`](https://node-postgres.c
|
|
|
8
8
|
npm install effect@rc @effect/sql-pg@rc
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Session defaults
|
|
12
|
+
|
|
13
|
+
Use `startupParameters` to establish PostgreSQL session defaults when each physical
|
|
14
|
+
connection opens, including replacement connections in a pool:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { PgClient } from "@effect/sql-pg"
|
|
18
|
+
import { Redacted } from "effect"
|
|
19
|
+
|
|
20
|
+
const PostgresLive = PgClient.layer({
|
|
21
|
+
url: Redacted.make("postgres://user:password@localhost/app"),
|
|
22
|
+
startupParameters: {
|
|
23
|
+
statement_timeout: "5s",
|
|
24
|
+
search_path: "app, public"
|
|
25
|
+
},
|
|
26
|
+
startupOptions: "-c lock_timeout=1000"
|
|
27
|
+
})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
These settings are sent in the startup packet. PostgreSQL's `RESET ALL` restores
|
|
31
|
+
the startup defaults after session-level changes. Both `PgConnection.Config` and
|
|
32
|
+
`PgClientConfig` accept these fields, and pools inherit them.
|
|
33
|
+
|
|
34
|
+
Parameter names are normalized to lowercase. Empty names and NUL bytes in names
|
|
35
|
+
or values are rejected before connecting. The names `user`, `database`,
|
|
36
|
+
`replication`, and `options` are reserved; use `username`, `database`, and `startupOptions`
|
|
37
|
+
on the config for identity and opaque options. Replication mode is not supported
|
|
38
|
+
through `startupParameters`. The driver accepts only `UTF8` or `UTF-8`
|
|
39
|
+
(case-insensitive) for `client_encoding` and sends the canonical value `UTF8`.
|
|
40
|
+
PostgreSQL validates other settings and reports invalid names or values at connect
|
|
41
|
+
time.
|
|
42
|
+
|
|
43
|
+
The `startupOptions` field is an opaque PostgreSQL options string. It can also come
|
|
44
|
+
from the URL query, for example `?options=-c%20statement_timeout%3D5000`. Explicit
|
|
45
|
+
config `startupOptions` overrides URL `options`, including when the explicit value
|
|
46
|
+
is empty. The URL query key and startup packet field are both named `options`.
|
|
47
|
+
Named parameters and opaque options can be sent together, but callers must not
|
|
48
|
+
set the same GUC in both. The driver does not parse `-c` flags, detect conflicts,
|
|
49
|
+
or read `PGOPTIONS`.
|
|
50
|
+
|
|
51
|
+
The startup `application_name` is selected in this order:
|
|
52
|
+
|
|
53
|
+
1. Explicit `applicationName`
|
|
54
|
+
2. `startupParameters.application_name`
|
|
55
|
+
3. URL `application_name`
|
|
56
|
+
4. `"@effect/sql-pg"`
|
|
57
|
+
|
|
58
|
+
The driver does not extract `application_name` from the opaque options string.
|
|
59
|
+
|
|
60
|
+
## User-defined types
|
|
61
|
+
|
|
62
|
+
Columns whose type OID has no codec are decoded as UTF-8 text, so user-defined
|
|
63
|
+
enums read as plain strings:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { PgClient } from "@effect/sql-pg"
|
|
67
|
+
import { Effect } from "effect"
|
|
68
|
+
|
|
69
|
+
// CREATE TYPE capability AS ENUM ('use_key', 'manage')
|
|
70
|
+
const program = Effect.gen(function*() {
|
|
71
|
+
const sql = yield* PgClient.PgClient
|
|
72
|
+
const rows = yield* sql`SELECT 'use_key'::capability AS capability`
|
|
73
|
+
// rows[0].capability === "use_key"
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Strings bind to enum columns without any setup; the server infers the type.
|
|
78
|
+
|
|
79
|
+
The fallback applies to every OID without a codec, not only enums, and it has
|
|
80
|
+
two failure modes:
|
|
81
|
+
|
|
82
|
+
- Invalid UTF-8 fails with `PgTypes.CodecError`, as it does for `text`. A codec
|
|
83
|
+
failure while reading a row is fatal to the connection, not just to the
|
|
84
|
+
query: the socket is destroyed, every other query pipelined on that
|
|
85
|
+
connection fails, an open transaction is lost, `LISTEN` channels on it are
|
|
86
|
+
torn down, and the pool replaces the connection. Columns of a binary
|
|
87
|
+
user-defined type such as a composite, a PostGIS geometry, or a pgvector
|
|
88
|
+
`vector` hold bytes that are usually not valid UTF-8, so register a codec
|
|
89
|
+
before querying them.
|
|
90
|
+
- Bytes that happen to be valid UTF-8 decode as garbled text without any
|
|
91
|
+
error. Arrays of user-defined types, including enum arrays, land here: the
|
|
92
|
+
array header is all low bytes, so a `capability[]` column reads as a string
|
|
93
|
+
of control characters followed by the labels.
|
|
94
|
+
|
|
95
|
+
Register a codec for a scalar user-defined type with
|
|
96
|
+
`PgTypes.register(oid, codec)`; registered codecs take precedence over the
|
|
97
|
+
fallback. `PgTypes.register` cannot attach an array type. For arrays, create a
|
|
98
|
+
registry, register the element codec with its `arrayOid`, and pass the registry
|
|
99
|
+
to the client as `types`. The registry builds the array codec from the element
|
|
100
|
+
codec:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { PgClient, PgTypes } from "@effect/sql-pg"
|
|
104
|
+
import { Redacted, Result } from "effect"
|
|
105
|
+
|
|
106
|
+
// SELECT oid, typarray FROM pg_type WHERE typname = 'capability'
|
|
107
|
+
declare const capabilityOid: number
|
|
108
|
+
declare const capabilityArrayOid: number
|
|
109
|
+
|
|
110
|
+
const decoder = new TextDecoder("utf-8", { fatal: true })
|
|
111
|
+
|
|
112
|
+
const utf8: PgTypes.Codec<string> = {
|
|
113
|
+
encode: (value) => Result.succeed(new TextEncoder().encode(value)),
|
|
114
|
+
decode: (bytes) => {
|
|
115
|
+
try {
|
|
116
|
+
return Result.succeed(decoder.decode(bytes))
|
|
117
|
+
} catch {
|
|
118
|
+
return Result.fail(new PgTypes.CodecError({ message: "Invalid UTF-8 in capability" }))
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const types = PgTypes.makeRegistry()
|
|
124
|
+
types.register(capabilityOid, utf8, { arrayOid: capabilityArrayOid })
|
|
125
|
+
|
|
126
|
+
const PostgresLive = PgClient.layer({
|
|
127
|
+
url: Redacted.make("postgres://user:password@localhost/app"),
|
|
128
|
+
types
|
|
129
|
+
})
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
OIDs of user-defined types are assigned per database, so look them up in
|
|
133
|
+
`pg_type` at startup rather than hard-coding them.
|
|
134
|
+
|
|
11
135
|
## Documentation
|
|
12
136
|
|
|
13
137
|
- [Effect website](https://effect.website)
|
package/ai-docs/package.json
CHANGED
package/dist/PgClient.d.ts
CHANGED
|
@@ -40,11 +40,13 @@ export interface PgClient extends Client.SqlClient {
|
|
|
40
40
|
readonly config: PgClientConfig;
|
|
41
41
|
readonly json: (_: unknown) => Fragment;
|
|
42
42
|
/**
|
|
43
|
-
* Registers a channel listener and returns its
|
|
43
|
+
* Registers a channel listener and returns its notification queue after
|
|
44
44
|
* PostgreSQL confirms `LISTEN`. The listener holds a connection until the
|
|
45
45
|
* scope closes.
|
|
46
|
+
* Connection failures after registration fail the queue with the original
|
|
47
|
+
* `SqlError`. Intentional scope closure interrupts consumers.
|
|
46
48
|
*/
|
|
47
|
-
readonly listen: (channel: string) => Effect.Effect<Queue.Dequeue<PgConnection.Notification>, SqlError, Scope.Scope>;
|
|
49
|
+
readonly listen: (channel: string) => Effect.Effect<Queue.Dequeue<PgConnection.Notification, SqlError>, SqlError, Scope.Scope>;
|
|
48
50
|
readonly notify: (channel: string, payload: string) => Effect.Effect<void, SqlError>;
|
|
49
51
|
}
|
|
50
52
|
/**
|
|
@@ -68,10 +70,32 @@ export interface PgClientConfig {
|
|
|
68
70
|
readonly ssl?: boolean | ConnectionOptions | undefined;
|
|
69
71
|
readonly database?: string | undefined;
|
|
70
72
|
readonly username?: string | undefined;
|
|
71
|
-
|
|
73
|
+
/**
|
|
74
|
+
* A static password or an Effect evaluated for each connection attempt.
|
|
75
|
+
* Providers must handle typed errors and require no services.
|
|
76
|
+
* {@link Effect.orDie} converts typed errors to defects, not retryable SQL errors.
|
|
77
|
+
*/
|
|
78
|
+
readonly password?: Redacted.Redacted | Effect.Effect<Redacted.Redacted> | undefined;
|
|
72
79
|
readonly connectTimeout?: Duration.Input | undefined;
|
|
73
80
|
readonly stream?: (() => Duplex) | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Overrides `startupParameters.application_name`, the URL's `application_name`,
|
|
83
|
+
* and the default `"@effect/sql-pg"`, in that order.
|
|
84
|
+
*/
|
|
74
85
|
readonly applicationName?: string | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Session defaults sent in every physical connection's startup packet.
|
|
88
|
+
* Names are lowercased; `user`, `database`, `replication`, and `options` are
|
|
89
|
+
* reserved. `client_encoding` only accepts UTF8 / UTF-8 (case-insensitive).
|
|
90
|
+
* Empty names and NUL bytes fail before connecting; PostgreSQL validates
|
|
91
|
+
* other settings. Do not set the same GUC here and in `startupOptions`.
|
|
92
|
+
*/
|
|
93
|
+
readonly startupParameters?: Readonly<Record<string, string>> | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Opaque PostgreSQL startup options, overriding the URL's `options` parameter.
|
|
96
|
+
* Forwarded without parsing `-c` flags or checking for duplicate GUCs.
|
|
97
|
+
*/
|
|
98
|
+
readonly startupOptions?: string | undefined;
|
|
75
99
|
readonly spanAttributes?: Record<string, unknown> | undefined;
|
|
76
100
|
readonly transformResultNames?: ((str: string) => string) | undefined;
|
|
77
101
|
readonly transformQueryNames?: ((str: string) => string) | undefined;
|
package/dist/PgClient.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PgClient.d.ts","sourceRoot":"","sources":["../src/PgClient.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAE1C,OAAO,KAAK,UAAU,MAAM,uCAAuC,CAAA;AACnE,OAAO,KAAK,MAAM,MAAM,+BAA+B,CAAA;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAA;AACrE,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAEjD,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,MAAmC,CAAA;AAExD;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,0BAA0B,CAAA;AAE/C;;;;;GAKG;AACH,MAAM,WAAW,QAAS,SAAQ,MAAM,CAAC,SAAS;IAChD,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,QAAQ,CAAA;IACvC
|
|
1
|
+
{"version":3,"file":"PgClient.d.ts","sourceRoot":"","sources":["../src/PgClient.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAE1C,OAAO,KAAK,UAAU,MAAM,uCAAuC,CAAA;AACnE,OAAO,KAAK,MAAM,MAAM,+BAA+B,CAAA;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAA;AACrE,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAEjD,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,MAAmC,CAAA;AAExD;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,0BAA0B,CAAA;AAE/C;;;;;GAKG;AACH,MAAM,WAAW,QAAS,SAAQ,MAAM,CAAC,SAAS;IAChD,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,QAAQ,CAAA;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,CACf,OAAO,EAAE,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC7F,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;CACrF;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,qCAAuD,CAAA;AAE5E;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAA;IAE5C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAAA;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAA;IAEpF,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;IAEpD,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAA;IAE5C;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;IACzE;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;IAE7D,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IACrE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IACpE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAA;IAC7C;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClD;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACtC,0EAA0E;IAC1E,QAAQ,CAAC,0BAA0B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxD,iEAAiE;IACjE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC7C;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;IAEjD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;CACpD;AAED;;;;;GAKG;AACH,eAAO,MAAM,IAAI,YAAa,YAAY,KAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,UAAU,CAQ3G,CAAA;AAEP;;;;;GAKG;AACH,eAAO,MAAM,UAAU,YACZ,cAAc,GAAG;IACxB;;OAEG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAChD,KACA,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,UAAU,CAUjE,CAAA;AAqIP;;;;;GAKG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,WACnB,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,KACrC,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAM9C,CAAA;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,WACd,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,KAChC,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,GAAG,QAAQ,CAIrE,CAAA;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,KAAK,WACR,YAAY,KACnB,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,SAAS,EAAE,QAAQ,CAA4B,CAAA;AAEhF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,eACX,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,8BAEhC,SAAS,CAAC,QAqCZ,CAAA;AAID;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAA;AAE7B;;;GAGG;AACH,UAAU,MAAO,SAAQ,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC;CAAG;AACrD;;;GAGG;AACH,QAAA,MAAM,MAAM,yDAAqC,CAAA"}
|
package/dist/PgClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PgClient.js","names":[],"sources":["../src/PgClient.ts"],"sourcesContent":[null],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,eAAe;AACvC,OAAO,KAAK,OAAO,MAAM,gBAAgB;AAEzC,OAAO,KAAK,MAAM,MAAM,eAAe;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc;AAIrC,OAAO,KAAK,MAAM,MAAM,eAAe;AACvC,OAAO,KAAK,UAAU,MAAM,uCAAuC;AACnE,OAAO,KAAK,MAAM,MAAM,+BAA+B;AAIvD,OAAO,KAAK,SAAS,MAAM,+BAA+B;AAG1D,SAAS,mBAAmB,QAAQ,wBAAwB;AAC5D,OAAO,KAAK,YAAY,MAAM,mBAAmB;AACjD,OAAO,KAAK,MAAM,MAAM,aAAa;AACrC,OAAO,KAAK,OAAO,MAAM,cAAc;AAEvC;;;;;;AAMA,OAAO,MAAM,MAAM,GAAW,0BAA0B;
|
|
1
|
+
{"version":3,"file":"PgClient.js","names":[],"sources":["../src/PgClient.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/dist/PgConnection.d.ts
CHANGED
|
@@ -34,6 +34,11 @@ export type TypeId = "~@effect/sql-pg/PgConnection";
|
|
|
34
34
|
* socket path, while a `host` beginning with `/` is treated as a socket
|
|
35
35
|
* directory and expands to `${host}/.s.PGSQL.${port}`.
|
|
36
36
|
*
|
|
37
|
+
* URL modes `sslmode=prefer` and `sslmode=allow` try TLS first, falling back
|
|
38
|
+
* to plaintext only when the server answers `SSLRequest` with `N`. Unlike
|
|
39
|
+
* libpq, `allow` also tries TLS first. Certificate verification stays enabled
|
|
40
|
+
* unless explicitly disabled through `ssl` options.
|
|
41
|
+
*
|
|
37
42
|
* Prepared statements are enabled by default and limited by
|
|
38
43
|
* `preparedStatementCacheSize`. Disable them for statement-mode poolers or
|
|
39
44
|
* workloads that generate unique SQL. Streams always use unnamed statements.
|
|
@@ -54,9 +59,31 @@ export interface Config {
|
|
|
54
59
|
readonly ssl?: boolean | ConnectionOptions | undefined;
|
|
55
60
|
readonly database?: string | undefined;
|
|
56
61
|
readonly username?: string | undefined;
|
|
57
|
-
|
|
62
|
+
/**
|
|
63
|
+
* A static password or an Effect evaluated for each connection attempt.
|
|
64
|
+
* Providers must handle typed errors and require no services.
|
|
65
|
+
* {@link Effect.orDie} converts typed errors to defects, not retryable SQL errors.
|
|
66
|
+
*/
|
|
67
|
+
readonly password?: Redacted.Redacted | Effect.Effect<Redacted.Redacted> | undefined;
|
|
58
68
|
readonly connectTimeout?: Duration.Input | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Overrides `startupParameters.application_name`, the URL's `application_name`,
|
|
71
|
+
* and the default `"@effect/sql-pg"`, in that order.
|
|
72
|
+
*/
|
|
59
73
|
readonly applicationName?: string | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Session defaults sent in every physical connection's startup packet.
|
|
76
|
+
* Names are lowercased; `user`, `database`, `replication`, and `options` are
|
|
77
|
+
* reserved. `client_encoding` only accepts UTF8 / UTF-8 (case-insensitive).
|
|
78
|
+
* Empty names and NUL bytes fail before connecting; PostgreSQL validates
|
|
79
|
+
* other settings. Do not set the same GUC here and in `startupOptions`.
|
|
80
|
+
*/
|
|
81
|
+
readonly startupParameters?: Readonly<Record<string, string>> | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Opaque PostgreSQL startup options, overriding the URL's `options` parameter.
|
|
84
|
+
* Forwarded without parsing `-c` flags or checking for duplicate GUCs.
|
|
85
|
+
*/
|
|
86
|
+
readonly startupOptions?: string | undefined;
|
|
60
87
|
readonly stream?: (() => Duplex) | undefined;
|
|
61
88
|
readonly types?: PgTypes.Registry | undefined;
|
|
62
89
|
readonly multiplex?: boolean | undefined;
|
|
@@ -140,8 +167,10 @@ export interface PgConnection {
|
|
|
140
167
|
* PostgreSQL confirms `LISTEN`. The session stays pinned until the scope
|
|
141
168
|
* closes, when it runs `UNLISTEN` and shuts down the queue. PostgreSQL
|
|
142
169
|
* registration errors fail the acquiring effect.
|
|
170
|
+
* Connection failures after registration fail the queue with the original
|
|
171
|
+
* `SqlError`. Intentional scope closure interrupts consumers.
|
|
143
172
|
*/
|
|
144
|
-
readonly listen: (channel: string) => Effect.Effect<Queue.Dequeue<Notification>, SqlError, Scope.Scope>;
|
|
173
|
+
readonly listen: (channel: string) => Effect.Effect<Queue.Dequeue<Notification, SqlError>, SqlError, Scope.Scope>;
|
|
145
174
|
/**
|
|
146
175
|
* Attempts to cancel the active query through a side connection. This is a
|
|
147
176
|
* no-op for an unpinned multiplexed connection because the active
|
|
@@ -161,14 +190,13 @@ export declare const PgConnection: Context.Service<PgConnection, PgConnection>;
|
|
|
161
190
|
*
|
|
162
191
|
* **Details**
|
|
163
192
|
*
|
|
164
|
-
*
|
|
165
|
-
* under `connectTimeout` (5 seconds by default). The effect
|
|
166
|
-
* backend sends `ReadyForQuery`.
|
|
167
|
-
*
|
|
193
|
+
* Password resolution, transport, optional `SSLRequest`, startup, and
|
|
194
|
+
* authentication run under `connectTimeout` (5 seconds by default). The effect
|
|
195
|
+
* resolves when the backend sends `ReadyForQuery`. Closing the scope sends
|
|
196
|
+
* `Terminate` and ends the socket.
|
|
168
197
|
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* explicitly.
|
|
198
|
+
* Use `sslmode=require` or explicit `ssl: true` to require encryption.
|
|
199
|
+
* Unix sockets and custom streams should set `ssl.servername` explicitly.
|
|
172
200
|
*
|
|
173
201
|
* @category constructors
|
|
174
202
|
* @since 4.0.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PgConnection.d.ts","sourceRoot":"","sources":["../src/PgConnection.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AAEzC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAE3C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAGL,QAAQ,EAGT,MAAM,8BAA8B,CAAA;AAIrC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"PgConnection.d.ts","sourceRoot":"","sources":["../src/PgConnection.ts"],"names":[],"mappings":"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"}
|
package/dist/PgConnection.js
CHANGED
|
@@ -17,6 +17,7 @@ import { randomBytes } from "node:crypto";
|
|
|
17
17
|
import * as Net from "node:net";
|
|
18
18
|
import * as Tls from "node:tls";
|
|
19
19
|
import { internalsKey } from "./internal/connection.js";
|
|
20
|
+
import * as PasswordInternal from "./internal/password.js";
|
|
20
21
|
import { classifySqlState, validateChannelName } from "./internal/sqlError.js";
|
|
21
22
|
import * as PgAuth from "./PgAuth.js";
|
|
22
23
|
import * as PgProtocol from "./PgProtocol.js";
|
|
@@ -49,19 +50,22 @@ export const PgConnection = /*#__PURE__*/Context.Service("@effect/sql-pg/PgConne
|
|
|
49
50
|
*
|
|
50
51
|
* **Details**
|
|
51
52
|
*
|
|
52
|
-
*
|
|
53
|
-
* under `connectTimeout` (5 seconds by default). The effect
|
|
54
|
-
* backend sends `ReadyForQuery`.
|
|
55
|
-
*
|
|
53
|
+
* Password resolution, transport, optional `SSLRequest`, startup, and
|
|
54
|
+
* authentication run under `connectTimeout` (5 seconds by default). The effect
|
|
55
|
+
* resolves when the backend sends `ReadyForQuery`. Closing the scope sends
|
|
56
|
+
* `Terminate` and ends the socket.
|
|
56
57
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* explicitly.
|
|
58
|
+
* Use `sslmode=require` or explicit `ssl: true` to require encryption.
|
|
59
|
+
* Unix sockets and custom streams should set `ssl.servername` explicitly.
|
|
60
60
|
*
|
|
61
61
|
* @category constructors
|
|
62
62
|
* @since 4.0.0
|
|
63
63
|
*/
|
|
64
|
-
export const make = options => Effect.flatMap(resolveConfig(options), config => Effect.acquireRelease(Effect.
|
|
64
|
+
export const make = options => Effect.flatMap(resolveConfig(options), config => Effect.acquireRelease(Effect.gen(function* () {
|
|
65
|
+
const password = yield* PasswordInternal.resolve(config.password);
|
|
66
|
+
const session = yield* connect(config, password);
|
|
67
|
+
return new PgConnectionImpl(options, config, session, options.types);
|
|
68
|
+
}), connection => Effect.sync(() => connection.closeUnsafe()), {
|
|
65
69
|
interruptible: true
|
|
66
70
|
}).pipe(Effect.timeoutOrElse({
|
|
67
71
|
duration: config.connectTimeout,
|
|
@@ -181,8 +185,9 @@ class PgConnectionImpl {
|
|
|
181
185
|
consumer?.onFatal(error);
|
|
182
186
|
const sets = Array.from(this.channels.values());
|
|
183
187
|
this.channels.clear();
|
|
188
|
+
const cause = this.closed ? Cause.interrupt() : Cause.fail(error);
|
|
184
189
|
for (const set of sets) {
|
|
185
|
-
for (const queue of set) Queue.failCauseUnsafe(queue,
|
|
190
|
+
for (const queue of set) Queue.failCauseUnsafe(queue, cause);
|
|
186
191
|
}
|
|
187
192
|
if (!this.closed) {
|
|
188
193
|
for (const hook of this.fatalHooks) hook();
|
|
@@ -373,7 +378,7 @@ class PgConnectionImpl {
|
|
|
373
378
|
/** Sends a `CancelRequest` for this session on a side connection. */
|
|
374
379
|
cancel = /*#__PURE__*/Effect.suspend(() => {
|
|
375
380
|
if (this.deadWith !== undefined) return Effect.void;
|
|
376
|
-
return sendCancelRequest(this.resolved, this.session
|
|
381
|
+
return sendCancelRequest(this.resolved, this.session);
|
|
377
382
|
});
|
|
378
383
|
pin = /*#__PURE__*/Effect.suspend(() => {
|
|
379
384
|
const reserve = this[internalsKey].reserve;
|
|
@@ -457,13 +462,7 @@ const inferScalar = value => {
|
|
|
457
462
|
// or timestamp column the way it did with the text-protocol drivers.
|
|
458
463
|
return inferredParameter(0, value);
|
|
459
464
|
}
|
|
460
|
-
if (value instanceof Date)
|
|
461
|
-
const time = value.getTime();
|
|
462
|
-
if (Number.isNaN(time)) throw new PgTypes.CodecError({
|
|
463
|
-
message: "Invalid Date parameter"
|
|
464
|
-
});
|
|
465
|
-
return inferredParameter(PgTypes.OID.timestamptz, time);
|
|
466
|
-
}
|
|
465
|
+
if (value instanceof Date) return inferredParameter(PgTypes.OID.timestamptz, value);
|
|
467
466
|
if (value instanceof Uint8Array) return inferredParameter(PgTypes.OID.bytea, value);
|
|
468
467
|
if (value instanceof Int8Array) {
|
|
469
468
|
return inferredParameter(PgTypes.OID.bytea, new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
|
|
@@ -1330,7 +1329,7 @@ const listenChannel = (conn, pin, channel) => Effect.uninterruptibleMask(restore
|
|
|
1330
1329
|
return queue;
|
|
1331
1330
|
})).pipe(Effect.tapCause(cause => Scope.close(scope, Exit.failCause(cause))));
|
|
1332
1331
|
}));
|
|
1333
|
-
const sendCancelRequest = (config,
|
|
1332
|
+
const sendCancelRequest = (config, session) => Effect.callback(resume => {
|
|
1334
1333
|
let done = false;
|
|
1335
1334
|
let socket;
|
|
1336
1335
|
let timer;
|
|
@@ -1342,8 +1341,8 @@ const sendCancelRequest = (config, pid, secret) => Effect.callback(resume => {
|
|
|
1342
1341
|
resume(Effect.void);
|
|
1343
1342
|
};
|
|
1344
1343
|
const frame = PgProtocol.encodeCancelRequest({
|
|
1345
|
-
pid,
|
|
1346
|
-
secret
|
|
1344
|
+
pid: session.processId,
|
|
1345
|
+
secret: session.secretKey
|
|
1347
1346
|
});
|
|
1348
1347
|
// After the frame is written the server processes the request and closes
|
|
1349
1348
|
// the connection, which lands in the `close` handler.
|
|
@@ -1354,8 +1353,8 @@ const sendCancelRequest = (config, pid, secret) => Effect.callback(resume => {
|
|
|
1354
1353
|
if (config.ssl === false) return send();
|
|
1355
1354
|
socket.once("data", chunk => {
|
|
1356
1355
|
if (done) return;
|
|
1357
|
-
//
|
|
1358
|
-
|
|
1356
|
+
// A TLS session's cancel secret must stay encrypted.
|
|
1357
|
+
if (chunk.length === 1 && chunk[0] === 0x4e && config.sslOptional && !session.encrypted) return send();
|
|
1359
1358
|
if (chunk.length !== 1 || chunk[0] !== 0x53) return finish();
|
|
1360
1359
|
const raw = socket;
|
|
1361
1360
|
raw.off("error", finish);
|
|
@@ -1390,9 +1389,10 @@ const sendCancelRequest = (config, pid, secret) => Effect.callback(resume => {
|
|
|
1390
1389
|
if (config.stream !== undefined) begin();else socket.once("connect", begin);
|
|
1391
1390
|
return Effect.sync(finish);
|
|
1392
1391
|
});
|
|
1393
|
-
const connect = config => Effect.callback(resume => {
|
|
1392
|
+
const connect = (config, resolvedPassword) => Effect.callback(resume => {
|
|
1394
1393
|
let done = false;
|
|
1395
1394
|
let socket;
|
|
1395
|
+
let encrypted = false;
|
|
1396
1396
|
let parser;
|
|
1397
1397
|
let sslErrorParser;
|
|
1398
1398
|
let scram;
|
|
@@ -1419,11 +1419,11 @@ const connect = config => Effect.callback(resume => {
|
|
|
1419
1419
|
const onError = cause => failConnect(cause, "PgConnection: Failed to connect");
|
|
1420
1420
|
const onClose = () => failConnect(new Error("Connection closed unexpectedly"), "PgConnection: Connection closed during startup");
|
|
1421
1421
|
const password = () => {
|
|
1422
|
-
if (
|
|
1422
|
+
if (resolvedPassword === undefined) {
|
|
1423
1423
|
failAuth(new Error("The server requested password authentication"), "PgConnection: No password configured");
|
|
1424
1424
|
return undefined;
|
|
1425
1425
|
}
|
|
1426
|
-
return
|
|
1426
|
+
return resolvedPassword;
|
|
1427
1427
|
};
|
|
1428
1428
|
const handleMessage = message => {
|
|
1429
1429
|
switch (message._tag) {
|
|
@@ -1525,6 +1525,7 @@ const connect = config => Effect.callback(resume => {
|
|
|
1525
1525
|
socket.on("error", ignoreError);
|
|
1526
1526
|
resume(Effect.succeed({
|
|
1527
1527
|
socket,
|
|
1528
|
+
encrypted,
|
|
1528
1529
|
parser: parser,
|
|
1529
1530
|
processId,
|
|
1530
1531
|
secretKey
|
|
@@ -1551,11 +1552,7 @@ const connect = config => Effect.callback(resume => {
|
|
|
1551
1552
|
maxMessageSize: config.maxMessageSize
|
|
1552
1553
|
});
|
|
1553
1554
|
socket.on("data", onData);
|
|
1554
|
-
socket.write(PgProtocol.encodeStartupMessage(
|
|
1555
|
-
user: config.username,
|
|
1556
|
-
database: config.database,
|
|
1557
|
-
application_name: config.applicationName
|
|
1558
|
-
}));
|
|
1555
|
+
socket.write(PgProtocol.encodeStartupMessage(config.startupParameters));
|
|
1559
1556
|
};
|
|
1560
1557
|
const onSslResponse = chunk => {
|
|
1561
1558
|
if (done) return;
|
|
@@ -1586,6 +1583,7 @@ const connect = config => Effect.callback(resume => {
|
|
|
1586
1583
|
return failConnect(response.failure, "PgConnection: Invalid SSLRequest response");
|
|
1587
1584
|
}
|
|
1588
1585
|
if (response.success === "N") {
|
|
1586
|
+
if (config.sslOptional) return startup();
|
|
1589
1587
|
return failConnect(new Error("The server does not support TLS"), "PgConnection: Server refused TLS");
|
|
1590
1588
|
}
|
|
1591
1589
|
const raw = socket;
|
|
@@ -1599,7 +1597,10 @@ const connect = config => Effect.callback(resume => {
|
|
|
1599
1597
|
});
|
|
1600
1598
|
socket.on("error", onError);
|
|
1601
1599
|
socket.on("close", onClose);
|
|
1602
|
-
socket.once("secureConnect",
|
|
1600
|
+
socket.once("secureConnect", () => {
|
|
1601
|
+
encrypted = true;
|
|
1602
|
+
startup();
|
|
1603
|
+
});
|
|
1603
1604
|
};
|
|
1604
1605
|
const begin = () => {
|
|
1605
1606
|
if (config.ssl === false) return startup();
|
|
@@ -1649,7 +1650,7 @@ const configError = (message, cause) => new SqlError({
|
|
|
1649
1650
|
})
|
|
1650
1651
|
});
|
|
1651
1652
|
const resolveConfig = options => Effect.suspend(() => {
|
|
1652
|
-
const parsed = options.url !== undefined ? parseUrl(Redacted.value(options.url)
|
|
1653
|
+
const parsed = options.url !== undefined ? parseUrl(Redacted.value(options.url)) : EffectResult.succeed({});
|
|
1653
1654
|
if (EffectResult.isFailure(parsed)) return Effect.fail(parsed.failure);
|
|
1654
1655
|
const url = parsed.success;
|
|
1655
1656
|
const host = options.host ?? url.host ?? "localhost";
|
|
@@ -1658,16 +1659,47 @@ const resolveConfig = options => Effect.suspend(() => {
|
|
|
1658
1659
|
if (username === undefined) {
|
|
1659
1660
|
return Effect.fail(configError("No username configured"));
|
|
1660
1661
|
}
|
|
1662
|
+
const named = Object.create(null);
|
|
1663
|
+
for (const [name, value] of Object.entries(options.startupParameters ?? {})) {
|
|
1664
|
+
const key = name.toLowerCase();
|
|
1665
|
+
if (key === "user" || key === "database" || key === "replication" || key === "options") {
|
|
1666
|
+
return Effect.fail(configError(`Reserved startup parameter: "${name}"`));
|
|
1667
|
+
}
|
|
1668
|
+
if (key === "client_encoding") {
|
|
1669
|
+
const encoding = value.toUpperCase();
|
|
1670
|
+
if (encoding !== "UTF8" && encoding !== "UTF-8") {
|
|
1671
|
+
return Effect.fail(configError("Startup parameter client_encoding must be UTF8 or UTF-8"));
|
|
1672
|
+
}
|
|
1673
|
+
named[key] = "UTF8";
|
|
1674
|
+
} else {
|
|
1675
|
+
named[key] = value;
|
|
1676
|
+
}
|
|
1677
|
+
if (name === "" || name.includes("\0") || value.includes("\0")) {
|
|
1678
|
+
return Effect.fail(configError("Startup parameter names must be nonempty and names/values must not contain NUL"));
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
const startupParameters = {
|
|
1682
|
+
...named,
|
|
1683
|
+
user: username,
|
|
1684
|
+
database: options.database ?? url.database,
|
|
1685
|
+
application_name: options.applicationName ?? named.application_name ?? url.applicationName ?? "@effect/sql-pg",
|
|
1686
|
+
options: options.startupOptions ?? url.options
|
|
1687
|
+
};
|
|
1688
|
+
for (const [name, value] of Object.entries(startupParameters)) {
|
|
1689
|
+
if (value?.includes("\0")) {
|
|
1690
|
+
return Effect.fail(configError(`Startup parameter "${name}" must not contain NUL`));
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1661
1693
|
return Effect.succeed({
|
|
1662
1694
|
host,
|
|
1663
1695
|
port,
|
|
1664
1696
|
path: options.path ?? (host.startsWith("/") ? `${host}/.s.PGSQL.${port}` : undefined),
|
|
1665
|
-
ssl: options.ssl ?? url.ssl ?? false,
|
|
1666
|
-
|
|
1697
|
+
ssl: options.ssl ?? (url.ssl === "prefer" ? true : url.ssl ?? false),
|
|
1698
|
+
sslOptional: options.ssl === undefined && url.ssl === "prefer",
|
|
1667
1699
|
username,
|
|
1668
|
-
password: options.password !== undefined ? Redacted.
|
|
1700
|
+
password: options.password ?? (url.password !== undefined ? Redacted.make(url.password) : undefined),
|
|
1669
1701
|
connectTimeout: Duration.fromInputUnsafe(options.connectTimeout ?? url.connectTimeout ?? Duration.seconds(5)),
|
|
1670
|
-
|
|
1702
|
+
startupParameters,
|
|
1671
1703
|
stream: options.stream,
|
|
1672
1704
|
maxMessageSize: options.maxMessageSize
|
|
1673
1705
|
});
|
|
@@ -1683,7 +1715,7 @@ const parsePort = (value, what) => {
|
|
|
1683
1715
|
const port = Number(value);
|
|
1684
1716
|
return !Number.isInteger(port) || port < 1 || port > 65535 ? EffectResult.fail(configError(`Invalid port in URL ${what}: "${value}"`)) : EffectResult.succeed(port);
|
|
1685
1717
|
};
|
|
1686
|
-
const parseUrl =
|
|
1718
|
+
const parseUrl = raw => {
|
|
1687
1719
|
let url;
|
|
1688
1720
|
try {
|
|
1689
1721
|
url = new URL(raw);
|
|
@@ -1745,6 +1777,9 @@ const parseUrl = (raw, hasExplicitSsl) => {
|
|
|
1745
1777
|
case "application_name":
|
|
1746
1778
|
config.applicationName = value;
|
|
1747
1779
|
break;
|
|
1780
|
+
case "options":
|
|
1781
|
+
config.options = value;
|
|
1782
|
+
break;
|
|
1748
1783
|
case "connect_timeout":
|
|
1749
1784
|
{
|
|
1750
1785
|
const seconds = Number(value);
|
|
@@ -1766,8 +1801,8 @@ const parseUrl = (raw, hasExplicitSsl) => {
|
|
|
1766
1801
|
break;
|
|
1767
1802
|
case "prefer":
|
|
1768
1803
|
case "allow":
|
|
1769
|
-
|
|
1770
|
-
|
|
1804
|
+
config.ssl = "prefer";
|
|
1805
|
+
break;
|
|
1771
1806
|
default:
|
|
1772
1807
|
return EffectResult.fail(configError(`Unrecognized sslmode in URL: "${value}"`));
|
|
1773
1808
|
}
|