neon 3.0.0 → 3.1.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 +70 -5
- package/dist/_chunks/auth_selection-DGgq6ifc.js +83 -0
- package/dist/_chunks/cmd_pipeline-CUbBO9U_.js +2818 -0
- package/dist/_chunks/credentials-MYdHdKah.js +188 -0
- package/dist/_chunks/env-NbA61JR3.js +585 -0
- package/dist/_chunks/env_services-Tz9G4JeT.js +531 -0
- package/dist/_chunks/paths-DMq0Lt7a.js +151 -0
- package/dist/_chunks/profiles-Ir29rqns.js +217 -0
- package/dist/_chunks/psql-DWH-kc69.js +2169 -0
- package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/_chunks/secure_file-BucZj4yQ.js +39 -0
- package/dist/analytics.js +163 -207
- package/dist/api.js +815 -758
- package/dist/auth.js +121 -141
- package/dist/auth_context.js +39 -53
- package/dist/cli.js +4 -7
- package/dist/commands/api.js +220 -250
- package/dist/commands/api_keys.js +251 -314
- package/dist/commands/auth.js +283 -328
- package/dist/commands/bootstrap.js +372 -437
- package/dist/commands/branches.js +304 -455
- package/dist/commands/bucket.js +374 -514
- package/dist/commands/checkout.js +213 -298
- package/dist/commands/config.js +573 -690
- package/dist/commands/connection_string.js +137 -165
- package/dist/commands/data_api.js +238 -260
- package/dist/commands/databases.js +67 -76
- package/dist/commands/deploy.js +31 -25
- package/dist/commands/dev.js +639 -719
- package/dist/commands/diff.js +156 -200
- package/dist/commands/env.js +255 -305
- package/dist/commands/functions.js +275 -355
- package/dist/commands/index.js +70 -65
- package/dist/commands/init.js +84 -119
- package/dist/commands/inspect.js +55 -55
- package/dist/commands/ip_allow.js +88 -120
- package/dist/commands/link.js +874 -1019
- package/dist/commands/logs.js +291 -0
- package/dist/commands/neon_auth.js +725 -933
- package/dist/commands/operations.js +34 -25
- package/dist/commands/orgs.js +28 -18
- package/dist/commands/profile.js +615 -846
- package/dist/commands/projects.js +313 -373
- package/dist/commands/psql.js +60 -58
- package/dist/commands/roles.js +55 -58
- package/dist/commands/schema_diff.js +87 -131
- package/dist/commands/set_context.js +34 -26
- package/dist/commands/snapshots.js +288 -413
- package/dist/commands/status.js +41 -37
- package/dist/commands/user.js +21 -10
- package/dist/commands/vpc_endpoints.js +85 -113
- package/dist/config.js +7 -6
- package/dist/config_format.js +50 -66
- package/dist/config_template.js +128 -157
- package/dist/context.js +183 -235
- package/dist/current_branch_fast_path.js +40 -49
- package/dist/dev/env.js +2 -446
- package/dist/dev/functions.js +54 -68
- package/dist/dev/inputs.js +46 -58
- package/dist/dev/runtime.js +135 -164
- package/dist/dev/websocket.js +766 -959
- package/dist/env.js +27 -33
- package/dist/env_file.js +118 -132
- package/dist/env_services.js +2 -51
- package/dist/errors.js +57 -68
- package/dist/functions_api.js +45 -43
- package/dist/help.js +189 -140
- package/dist/index.js +182 -257
- package/dist/init/agents.js +137 -118
- package/dist/init/auth.js +58 -68
- package/dist/init/bootstrap.js +325 -396
- package/dist/init/build_config.js +4 -2
- package/dist/init/detect_agent.js +56 -101
- package/dist/init/editors.js +35 -52
- package/dist/init/enrich_output.js +51 -66
- package/dist/init/extension.js +134 -171
- package/dist/init/inspect.js +179 -266
- package/dist/init/interactive.js +510 -622
- package/dist/init/neonctl.js +117 -168
- package/dist/init/orchestrate.js +157 -173
- package/dist/init/phases/auth.js +188 -202
- package/dist/init/phases/cleanup.js +23 -23
- package/dist/init/phases/db.js +251 -277
- package/dist/init/phases/getting_started.js +213 -223
- package/dist/init/phases/mcp.js +174 -224
- package/dist/init/phases/migrations.js +247 -248
- package/dist/init/phases/neon_auth.js +114 -133
- package/dist/init/phases/setup.js +546 -703
- package/dist/init/phases/skills.js +75 -86
- package/dist/init/phases/status.js +72 -67
- package/dist/init/resolve_context.js +102 -99
- package/dist/init/route_command.js +91 -98
- package/dist/init/skills.js +174 -218
- package/dist/init/vsix.js +77 -99
- package/dist/log.js +17 -16
- package/dist/neon_services.js +104 -129
- package/dist/parameters.gen.js +481 -471
- package/dist/pkg.js +17 -19
- package/dist/profile_keys.js +44 -47
- package/dist/psql/cli.js +44 -47
- package/dist/psql/command/cmd_cond.js +231 -406
- package/dist/psql/command/cmd_connect.js +557 -764
- package/dist/psql/command/cmd_copy.js +728 -984
- package/dist/psql/command/cmd_describe.js +1499 -1688
- package/dist/psql/command/cmd_format.js +733 -905
- package/dist/psql/command/cmd_io.js +2 -2193
- package/dist/psql/command/cmd_lo.js +297 -359
- package/dist/psql/command/cmd_meta.js +727 -878
- package/dist/psql/command/cmd_misc.js +138 -172
- package/dist/psql/command/cmd_pipeline.js +2 -1148
- package/dist/psql/command/cmd_restrict.js +119 -155
- package/dist/psql/command/cmd_show.js +529 -688
- package/dist/psql/command/dispatch.js +260 -325
- package/dist/psql/command/inputQueue.js +35 -33
- package/dist/psql/command/shared.js +49 -63
- package/dist/psql/complete/filenames.js +90 -133
- package/dist/psql/complete/index.js +59 -97
- package/dist/psql/complete/matcher.js +236 -300
- package/dist/psql/complete/psqlVars.js +218 -223
- package/dist/psql/complete/queries.js +159 -177
- package/dist/psql/complete/rules.js +1493 -2299
- package/dist/psql/core/common.js +2 -1253
- package/dist/psql/core/help.js +456 -546
- package/dist/psql/core/mainloop.js +692 -1303
- package/dist/psql/core/prompt.js +391 -408
- package/dist/psql/core/settings.js +429 -644
- package/dist/psql/core/sqlHelp.js +480 -554
- package/dist/psql/core/startup.js +2 -846
- package/dist/psql/core/syncVars.js +67 -110
- package/dist/psql/core/variables.js +156 -278
- package/dist/psql/describe/formatters.js +884 -1285
- package/dist/psql/describe/processNamePattern.js +173 -260
- package/dist/psql/describe/queries.js +1368 -2403
- package/dist/psql/describe/versionGate.js +32 -41
- package/dist/psql/index.js +2 -2030
- package/dist/psql/io/history.js +232 -271
- package/dist/psql/io/input.js +103 -108
- package/dist/psql/io/lineEditor/buffer.js +238 -319
- package/dist/psql/io/lineEditor/complete.js +135 -213
- package/dist/psql/io/lineEditor/filename.js +139 -148
- package/dist/psql/io/lineEditor/index.js +653 -870
- package/dist/psql/io/lineEditor/keymap.js +544 -702
- package/dist/psql/io/lineEditor/vt100.js +294 -341
- package/dist/psql/io/pgpass.js +158 -187
- package/dist/psql/io/pgservice.js +146 -183
- package/dist/psql/io/psqlrc.js +328 -403
- package/dist/psql/print/aligned.js +1020 -1683
- package/dist/psql/print/asciidoc.js +180 -214
- package/dist/psql/print/crosstab.js +281 -442
- package/dist/psql/print/csv.js +48 -70
- package/dist/psql/print/html.js +195 -226
- package/dist/psql/print/json.js +75 -88
- package/dist/psql/print/latex.js +291 -364
- package/dist/psql/print/pager.js +171 -242
- package/dist/psql/print/troff.js +194 -226
- package/dist/psql/print/unaligned.js +69 -95
- package/dist/psql/print/units.js +167 -169
- package/dist/psql/scanner/slash.js +428 -483
- package/dist/psql/scanner/sql.js +445 -889
- package/dist/psql/scanner/stringutils.js +309 -379
- package/dist/psql/types/index.js +8 -7
- package/dist/psql/types/scanner.js +25 -22
- package/dist/psql/wire/connection.js +2042 -2803
- package/dist/psql/wire/copy.js +84 -100
- package/dist/psql/wire/notify.js +39 -59
- package/dist/psql/wire/pipeline.js +305 -518
- package/dist/psql/wire/protocol.js +349 -417
- package/dist/psql/wire/sasl.js +180 -265
- package/dist/psql/wire/tls.js +400 -561
- package/dist/storage_api.js +115 -129
- package/dist/test_utils/fixtures.js +94 -113
- package/dist/test_utils/oauth_server.js +10 -7
- package/dist/test_utils/project_dir.js +33 -0
- package/dist/utils/ai_gateway_notice.js +131 -162
- package/dist/utils/api_enums.js +21 -28
- package/dist/utils/auth.js +10 -4
- package/dist/utils/branch_notice.js +20 -19
- package/dist/utils/branch_picker.js +83 -89
- package/dist/utils/cli_name.js +15 -12
- package/dist/utils/compute_units.js +20 -27
- package/dist/utils/config_diff.js +127 -158
- package/dist/utils/enrichers.js +95 -148
- package/dist/utils/esbuild.js +130 -189
- package/dist/utils/flags.js +35 -47
- package/dist/utils/formats.js +8 -15
- package/dist/utils/git_diff.js +69 -80
- package/dist/utils/inspect_db.js +101 -143
- package/dist/utils/inspect_queries.js +179 -142
- package/dist/utils/middlewares.js +39 -45
- package/dist/utils/openapi.js +87 -99
- package/dist/utils/package_manager.js +312 -110
- package/dist/utils/point_in_time.js +49 -53
- package/dist/utils/psql.js +89 -106
- package/dist/utils/service_picker.js +55 -58
- package/dist/utils/string.js +5 -5
- package/dist/utils/ui.js +38 -55
- package/dist/utils/write_sync.js +26 -35
- package/dist/utils/zip.js +4 -3
- package/dist/writer.js +67 -87
- package/package.json +11 -6
- package/dist/_shared/auth_selection.js +0 -86
- package/dist/_shared/credentials.js +0 -209
- package/dist/_shared/env-core/env.js +0 -558
- package/dist/_shared/env-core/reuse-secrets.js +0 -223
- package/dist/_shared/paths.js +0 -148
- package/dist/_shared/profiles.js +0 -276
- package/dist/_shared/secure_file.js +0 -43
|
@@ -1,466 +1,398 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PostgreSQL wire protocol message codec — thin adapter over `pg-protocol`.
|
|
3
|
-
*
|
|
4
|
-
* Background (per the plan): the original module was a hand-rolled wire codec
|
|
5
|
-
* for protocol v3.0. We've now swapped the bytes for `pg-protocol@1.14`
|
|
6
|
-
* (node-postgres' upstream codec) and this file is the seam:
|
|
7
|
-
*
|
|
8
|
-
* - Frontend builders (`Query`, `StartupMessage`, `Parse`, `Bind`, …) are
|
|
9
|
-
* re-exports of `serialize.*` adapted to our existing call signatures, so
|
|
10
|
-
* `connection.ts` and `pipeline.ts` keep working unchanged.
|
|
11
|
-
* - `MessageParser` wraps pg-protocol's synchronous `Parser` and reshapes
|
|
12
|
-
* each parsed message into our existing `BackendMessage` union — so the
|
|
13
|
-
* connection-state-machine switches on `.type` ('RowDescription', 'DataRow',
|
|
14
|
-
* …) and reads the same field names ('values', 'tag', 'fields', …) as
|
|
15
|
-
* before.
|
|
16
|
-
*
|
|
17
|
-
* Exceptions (kept hand-rolled):
|
|
18
|
-
*
|
|
19
|
-
* - `CancelRequest`: pg-protocol exposes one as `serialize.cancel`, and it
|
|
20
|
-
* is layout-compatible with our previous output. We delegate to it.
|
|
21
|
-
* - `SSLRequest`: pg-protocol *does* expose this as `serialize.requestSsl`;
|
|
22
|
-
* we re-export it for symmetry. No hand-roll needed.
|
|
23
|
-
* - `StartupMessage`: pg-protocol's `serialize.startup` unconditionally
|
|
24
|
-
* appends `client_encoding=UTF8` to whatever the caller supplies. We
|
|
25
|
-
* defensively filter `client_encoding` from the caller-provided map
|
|
26
|
-
* before passing through, since our connect layer always sets it to UTF8
|
|
27
|
-
* anyway. If it's set to something else, that's a caller bug — assert.
|
|
28
|
-
*
|
|
29
|
-
* Why this shim layer (instead of using pg-protocol directly):
|
|
30
|
-
*
|
|
31
|
-
* - Field-name mapping. pg-protocol's parser emits camelCase names
|
|
32
|
-
* (`'rowDescription'`, `'dataRow'`, …) and uses different field names
|
|
33
|
-
* (`fields` vs `values`, `text` vs `tag`, `processID` vs `processId`).
|
|
34
|
-
* Translating in one place keeps `connection.ts` minimal.
|
|
35
|
-
* - DataRow values. pg-protocol parses every value as a UTF-8 string;
|
|
36
|
-
* our connection layer expects `(Buffer | null)[]` (so binary-format
|
|
37
|
-
* columns can keep their bytes intact later). We re-buffer here.
|
|
38
|
-
* - ErrorResponse / NoticeResponse fields. pg-protocol attaches the parsed
|
|
39
|
-
* fields as named properties on the Error/Notice instance. We re-pack
|
|
40
|
-
* them into the Map<tag,value> shape our `fieldsToNotice` helper consumes.
|
|
41
|
-
*/
|
|
42
1
|
import { Buffer } from "node:buffer";
|
|
43
|
-
// pg-protocol@1.14 ships two entry points via its `exports` map:
|
|
44
|
-
// - `./esm/index.js` (the `"import"` key) — a thin ESM wrapper that does
|
|
45
|
-
// `import * as protocol from '../dist/index.js'`.
|
|
46
|
-
// - `./dist/index.js` (the `"require"` / `"default"` keys) — the actual
|
|
47
|
-
// CJS implementation.
|
|
48
|
-
// On Node 20, resolving `'pg-protocol'` from an ESM context picks the
|
|
49
|
-
// `esm/index.js` wrapper, BUT the surrounding `package.json` has no
|
|
50
|
-
// `"type": "module"` field. Node 20 still parses the wrapper as CJS, hits
|
|
51
|
-
// the `import` syntax, and dies with `SyntaxError: Cannot use import
|
|
52
|
-
// statement outside a module`. Node 22+ honours the `"import"` exports
|
|
53
|
-
// key as a forced-ESM hint and avoids this. To stay portable across both,
|
|
54
|
-
// we import the CJS implementation directly — same pattern node-postgres
|
|
55
|
-
// uses for the `Parser` subpath, and what we already do on the next line.
|
|
56
2
|
import pgProtocol from "pg-protocol/dist/index.js";
|
|
57
|
-
const { serialize } = pgProtocol;
|
|
58
3
|
import { Parser } from "pg-protocol/dist/parser.js";
|
|
59
|
-
|
|
60
|
-
constructor(message) {
|
|
61
|
-
super(message);
|
|
62
|
-
this.name = "ProtocolError";
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
// ---------------------------------------------------------------------------
|
|
66
|
-
// Frontend message encoders
|
|
67
|
-
//
|
|
68
|
-
// These are thin wrappers over `pg-protocol`'s `serialize.*`. The signatures
|
|
69
|
-
// mirror our previous hand-rolled API so callers in `connection.ts` and
|
|
70
|
-
// `pipeline.ts` don't need to change.
|
|
71
|
-
// ---------------------------------------------------------------------------
|
|
4
|
+
//#region src/psql/wire/protocol.ts
|
|
72
5
|
/**
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
6
|
+
* PostgreSQL wire protocol message codec — thin adapter over `pg-protocol`.
|
|
7
|
+
*
|
|
8
|
+
* Background (per the plan): the original module was a hand-rolled wire codec
|
|
9
|
+
* for protocol v3.0. We've now swapped the bytes for `pg-protocol@1.14`
|
|
10
|
+
* (node-postgres' upstream codec) and this file is the seam:
|
|
11
|
+
*
|
|
12
|
+
* - Frontend builders (`Query`, `StartupMessage`, `Parse`, `Bind`, …) are
|
|
13
|
+
* re-exports of `serialize.*` adapted to our existing call signatures, so
|
|
14
|
+
* `connection.ts` and `pipeline.ts` keep working unchanged.
|
|
15
|
+
* - `MessageParser` wraps pg-protocol's synchronous `Parser` and reshapes
|
|
16
|
+
* each parsed message into our existing `BackendMessage` union — so the
|
|
17
|
+
* connection-state-machine switches on `.type` ('RowDescription', 'DataRow',
|
|
18
|
+
* …) and reads the same field names ('values', 'tag', 'fields', …) as
|
|
19
|
+
* before.
|
|
20
|
+
*
|
|
21
|
+
* Exceptions (kept hand-rolled):
|
|
22
|
+
*
|
|
23
|
+
* - `CancelRequest`: pg-protocol exposes one as `serialize.cancel`, and it
|
|
24
|
+
* is layout-compatible with our previous output. We delegate to it.
|
|
25
|
+
* - `SSLRequest`: pg-protocol *does* expose this as `serialize.requestSsl`;
|
|
26
|
+
* we re-export it for symmetry. No hand-roll needed.
|
|
27
|
+
* - `StartupMessage`: pg-protocol's `serialize.startup` unconditionally
|
|
28
|
+
* appends `client_encoding=UTF8` to whatever the caller supplies. We
|
|
29
|
+
* defensively filter `client_encoding` from the caller-provided map
|
|
30
|
+
* before passing through, since our connect layer always sets it to UTF8
|
|
31
|
+
* anyway. If it's set to something else, that's a caller bug — assert.
|
|
32
|
+
*
|
|
33
|
+
* Why this shim layer (instead of using pg-protocol directly):
|
|
34
|
+
*
|
|
35
|
+
* - Field-name mapping. pg-protocol's parser emits camelCase names
|
|
36
|
+
* (`'rowDescription'`, `'dataRow'`, …) and uses different field names
|
|
37
|
+
* (`fields` vs `values`, `text` vs `tag`, `processID` vs `processId`).
|
|
38
|
+
* Translating in one place keeps `connection.ts` minimal.
|
|
39
|
+
* - DataRow values. pg-protocol parses every value as a UTF-8 string;
|
|
40
|
+
* our connection layer expects `(Buffer | null)[]` (so binary-format
|
|
41
|
+
* columns can keep their bytes intact later). We re-buffer here.
|
|
42
|
+
* - ErrorResponse / NoticeResponse fields. pg-protocol attaches the parsed
|
|
43
|
+
* fields as named properties on the Error/Notice instance. We re-pack
|
|
44
|
+
* them into the Map<tag,value> shape our `fieldsToNotice` helper consumes.
|
|
45
|
+
*/
|
|
46
|
+
const { serialize } = pgProtocol;
|
|
47
|
+
var ProtocolError = class extends Error {
|
|
48
|
+
constructor(message) {
|
|
49
|
+
super(message);
|
|
50
|
+
this.name = "ProtocolError";
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* StartupMessage. pg-protocol always appends `client_encoding=UTF8`; we
|
|
55
|
+
* strip any incoming `client_encoding` to avoid duplicating it on the wire.
|
|
56
|
+
* Our connect layer always sets UTF8 anyway, so this is a no-op in practice.
|
|
57
|
+
*/
|
|
58
|
+
function StartupMessage(params) {
|
|
59
|
+
const filtered = {};
|
|
60
|
+
for (const [key, value] of Object.entries(params)) {
|
|
61
|
+
if (value === void 0) continue;
|
|
62
|
+
if (key === "client_encoding") continue;
|
|
63
|
+
filtered[key] = value;
|
|
64
|
+
}
|
|
65
|
+
return serialize.startup(filtered);
|
|
87
66
|
}
|
|
88
67
|
/** SSLRequest — pg-protocol exposes this as `requestSsl`. */
|
|
89
|
-
|
|
90
|
-
|
|
68
|
+
function SSLRequest() {
|
|
69
|
+
return serialize.requestSsl();
|
|
91
70
|
}
|
|
92
71
|
/** CancelRequest — pg-protocol's `cancel` is layout-compatible. */
|
|
93
|
-
|
|
94
|
-
|
|
72
|
+
function CancelRequest(processId, secretKey) {
|
|
73
|
+
return serialize.cancel(processId, secretKey);
|
|
95
74
|
}
|
|
96
75
|
/** Query: 'Q' + cstring(sql). */
|
|
97
|
-
|
|
98
|
-
|
|
76
|
+
function Query(sql) {
|
|
77
|
+
return serialize.query(sql);
|
|
99
78
|
}
|
|
100
79
|
/** Terminate: 'X' + 4-byte length. */
|
|
101
|
-
|
|
102
|
-
|
|
80
|
+
function Terminate() {
|
|
81
|
+
return serialize.end();
|
|
103
82
|
}
|
|
104
83
|
/** Sync: 'S' + 4-byte length. */
|
|
105
|
-
|
|
106
|
-
|
|
84
|
+
function Sync() {
|
|
85
|
+
return serialize.sync();
|
|
107
86
|
}
|
|
108
87
|
/** Flush: 'H' + 4-byte length. */
|
|
109
|
-
|
|
110
|
-
|
|
88
|
+
function Flush() {
|
|
89
|
+
return serialize.flush();
|
|
111
90
|
}
|
|
112
91
|
/** Parse: 'P' + cstring(name) + cstring(sql) + Int16 nparam + {Int32 oid}*. */
|
|
113
|
-
|
|
114
|
-
|
|
92
|
+
function Parse(name, sql, paramTypes) {
|
|
93
|
+
return serialize.parse({
|
|
94
|
+
name,
|
|
95
|
+
text: sql,
|
|
96
|
+
types: paramTypes
|
|
97
|
+
});
|
|
115
98
|
}
|
|
116
99
|
/**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
portal,
|
|
140
|
-
statement: stmt,
|
|
141
|
-
values: params,
|
|
142
|
-
binary: false,
|
|
143
|
-
});
|
|
100
|
+
* Bind: 'B' + cstring(portal) + cstring(stmt) + per-value param formats +
|
|
101
|
+
* value array + result formats.
|
|
102
|
+
*
|
|
103
|
+
* Note on parameter formats: pg-protocol's `serialize.bind` auto-detects the
|
|
104
|
+
* format byte per value (`Buffer → 1`, `string/null → 0`); the caller-supplied
|
|
105
|
+
* `paramFormats` arg is therefore ignored. This matches the hand-rolled
|
|
106
|
+
* codec's effective behaviour because every caller passes either an empty
|
|
107
|
+
* array (= "all text", which is what pg-protocol picks for strings) or a
|
|
108
|
+
* format list that already agrees with the value's type.
|
|
109
|
+
*
|
|
110
|
+
* Note on result formats: we want every column in *text* format (`[0]`) for
|
|
111
|
+
* `psql`-style printing. pg-protocol forces a single shared result-format
|
|
112
|
+
* byte (`binary: boolean`); we pass `binary: false` to get text columns
|
|
113
|
+
* regardless of the caller-supplied `resultFormats` array.
|
|
114
|
+
*/
|
|
115
|
+
function Bind(portal, stmt, paramFormats, params, resultFormats) {
|
|
116
|
+
return serialize.bind({
|
|
117
|
+
portal,
|
|
118
|
+
statement: stmt,
|
|
119
|
+
values: params,
|
|
120
|
+
binary: false
|
|
121
|
+
});
|
|
144
122
|
}
|
|
145
123
|
/** Describe: 'D' + byte('S'|'P') + cstring(name). */
|
|
146
|
-
|
|
147
|
-
|
|
124
|
+
function Describe(target, name) {
|
|
125
|
+
return serialize.describe({
|
|
126
|
+
type: target,
|
|
127
|
+
name
|
|
128
|
+
});
|
|
148
129
|
}
|
|
149
130
|
/** Execute: 'E' + cstring(portal) + Int32 maxRows. */
|
|
150
|
-
|
|
151
|
-
|
|
131
|
+
function Execute(portal, maxRows) {
|
|
132
|
+
return serialize.execute({
|
|
133
|
+
portal,
|
|
134
|
+
rows: maxRows
|
|
135
|
+
});
|
|
152
136
|
}
|
|
153
137
|
/** Close: 'C' + byte('S'|'P') + cstring(name). */
|
|
154
|
-
|
|
155
|
-
|
|
138
|
+
function Close(target, name) {
|
|
139
|
+
return serialize.close({
|
|
140
|
+
type: target,
|
|
141
|
+
name
|
|
142
|
+
});
|
|
156
143
|
}
|
|
157
144
|
/** PasswordMessage: 'p' + cstring(password). */
|
|
158
|
-
|
|
159
|
-
|
|
145
|
+
function PasswordMessage(password) {
|
|
146
|
+
return serialize.password(password);
|
|
160
147
|
}
|
|
161
148
|
/**
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
149
|
+
* SASLInitialResponse: 'p' + cstring(mechanism) + Int32(bodyLen) + body.
|
|
150
|
+
*
|
|
151
|
+
* pg-protocol takes the initial response as a *string*; our SCRAM client
|
|
152
|
+
* hands back a Buffer. SCRAM-SHA-256 messages are ASCII so this round-trips
|
|
153
|
+
* losslessly via UTF-8.
|
|
154
|
+
*/
|
|
155
|
+
function SASLInitialResponse(mechanism, response) {
|
|
156
|
+
return serialize.sendSASLInitialResponseMessage(mechanism, response.toString("utf8"));
|
|
170
157
|
}
|
|
171
158
|
/** SASLResponse: 'p' + opaque body (no NUL terminator). */
|
|
172
|
-
|
|
173
|
-
|
|
159
|
+
function SASLResponse(response) {
|
|
160
|
+
return serialize.sendSCRAMClientFinalMessage(response.toString("utf8"));
|
|
174
161
|
}
|
|
175
162
|
/** CopyData: 'd' + opaque bytes. */
|
|
176
|
-
|
|
177
|
-
|
|
163
|
+
function CopyData(data) {
|
|
164
|
+
return serialize.copyData(data);
|
|
178
165
|
}
|
|
179
166
|
/** CopyDone: 'c' + 4-byte length. */
|
|
180
|
-
|
|
181
|
-
|
|
167
|
+
function CopyDone() {
|
|
168
|
+
return serialize.copyDone();
|
|
182
169
|
}
|
|
183
170
|
/** CopyFail: 'f' + cstring(reason). */
|
|
184
|
-
|
|
185
|
-
|
|
171
|
+
function CopyFail(message) {
|
|
172
|
+
return serialize.copyFail(message);
|
|
186
173
|
}
|
|
187
|
-
// ---------------------------------------------------------------------------
|
|
188
|
-
// Backend message parser
|
|
189
|
-
// ---------------------------------------------------------------------------
|
|
190
174
|
/**
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Number of bytes buffered but not yet emitted (e.g. partial trailing
|
|
231
|
-
* message). Exposed for tests / diagnostics.
|
|
232
|
-
*/
|
|
233
|
-
get bufferedBytes() {
|
|
234
|
-
return this.buffered;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
175
|
+
* Streaming framer with a synchronous `feed()` API.
|
|
176
|
+
*
|
|
177
|
+
* Internally delegates to `pg-protocol`'s `Parser` (which exposes a
|
|
178
|
+
* `parse(buffer, callback)` method that emits each completed backend message
|
|
179
|
+
* via callback). On each `feed()` call we drain the parser and collect the
|
|
180
|
+
* emitted messages into an array, reshaping each pg-protocol message into our
|
|
181
|
+
* `BackendMessage` union (so `connection.ts`'s switch arms keep working).
|
|
182
|
+
*
|
|
183
|
+
* pg-protocol's `Parser.parse` calls the callback synchronously for every
|
|
184
|
+
* complete message and keeps incomplete trailing bytes buffered internally.
|
|
185
|
+
* That's a near-perfect match for our previous hand-rolled `MessageParser`.
|
|
186
|
+
*/
|
|
187
|
+
var MessageParser = class {
|
|
188
|
+
constructor() {
|
|
189
|
+
this.inner = new Parser();
|
|
190
|
+
this.buffered = 0;
|
|
191
|
+
}
|
|
192
|
+
feed(chunk) {
|
|
193
|
+
const out = [];
|
|
194
|
+
try {
|
|
195
|
+
this.inner.parse(chunk, (msg) => {
|
|
196
|
+
out.push(adaptBackendMessage(msg));
|
|
197
|
+
});
|
|
198
|
+
} catch (err) {
|
|
199
|
+
throw err instanceof ProtocolError ? err : new ProtocolError(err instanceof Error ? err.message : String(err));
|
|
200
|
+
}
|
|
201
|
+
const probe = this.inner;
|
|
202
|
+
this.buffered = probe.bufferLength ?? 0;
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Number of bytes buffered but not yet emitted (e.g. partial trailing
|
|
207
|
+
* message). Exposed for tests / diagnostics.
|
|
208
|
+
*/
|
|
209
|
+
get bufferedBytes() {
|
|
210
|
+
return this.buffered;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
237
213
|
function adaptBackendMessage(raw) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
case "copyDone":
|
|
339
|
-
return { type: "CopyDone" };
|
|
340
|
-
case "noData":
|
|
341
|
-
return { type: "NoData" };
|
|
342
|
-
case "parseComplete":
|
|
343
|
-
return { type: "ParseComplete" };
|
|
344
|
-
case "bindComplete":
|
|
345
|
-
return { type: "BindComplete" };
|
|
346
|
-
case "closeComplete":
|
|
347
|
-
return { type: "CloseComplete" };
|
|
348
|
-
case "portalSuspended":
|
|
349
|
-
return { type: "PortalSuspended" };
|
|
350
|
-
case "parameterDescription":
|
|
351
|
-
return {
|
|
352
|
-
type: "ParameterDescription",
|
|
353
|
-
oids: msg.dataTypeIDs,
|
|
354
|
-
};
|
|
355
|
-
default:
|
|
356
|
-
throw new ProtocolError(`Unknown backend message: ${String(msg.name)}`);
|
|
357
|
-
}
|
|
214
|
+
const msg = raw;
|
|
215
|
+
switch (msg.name) {
|
|
216
|
+
case "authenticationOk": return { type: "AuthenticationOk" };
|
|
217
|
+
case "authenticationCleartextPassword": return { type: "AuthenticationCleartextPassword" };
|
|
218
|
+
case "authenticationMD5Password": return {
|
|
219
|
+
type: "AuthenticationMD5Password",
|
|
220
|
+
salt: Buffer.from(msg.salt)
|
|
221
|
+
};
|
|
222
|
+
case "authenticationSASL": return {
|
|
223
|
+
type: "AuthenticationSASL",
|
|
224
|
+
mechanisms: msg.mechanisms
|
|
225
|
+
};
|
|
226
|
+
case "authenticationSASLContinue": return {
|
|
227
|
+
type: "AuthenticationSASLContinue",
|
|
228
|
+
data: Buffer.from(msg.data, "utf8")
|
|
229
|
+
};
|
|
230
|
+
case "authenticationSASLFinal": return {
|
|
231
|
+
type: "AuthenticationSASLFinal",
|
|
232
|
+
data: Buffer.from(msg.data, "utf8")
|
|
233
|
+
};
|
|
234
|
+
case "parameterStatus": return {
|
|
235
|
+
type: "ParameterStatus",
|
|
236
|
+
name: msg.parameterName,
|
|
237
|
+
value: msg.parameterValue
|
|
238
|
+
};
|
|
239
|
+
case "backendKeyData": return {
|
|
240
|
+
type: "BackendKeyData",
|
|
241
|
+
processId: msg.processID,
|
|
242
|
+
secretKey: msg.secretKey
|
|
243
|
+
};
|
|
244
|
+
case "readyForQuery": {
|
|
245
|
+
const status = msg.status;
|
|
246
|
+
if (status !== "I" && status !== "T" && status !== "E") throw new ProtocolError(`ReadyForQuery: unexpected status ${JSON.stringify(status)}`);
|
|
247
|
+
return {
|
|
248
|
+
type: "ReadyForQuery",
|
|
249
|
+
status
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
case "rowDescription": return {
|
|
253
|
+
type: "RowDescription",
|
|
254
|
+
fields: msg.fields.map((f) => ({
|
|
255
|
+
name: f.name,
|
|
256
|
+
tableID: f.tableID,
|
|
257
|
+
columnID: f.columnID,
|
|
258
|
+
dataTypeID: f.dataTypeID,
|
|
259
|
+
dataTypeSize: f.dataTypeSize,
|
|
260
|
+
dataTypeModifier: f.dataTypeModifier,
|
|
261
|
+
format: f.format === "binary" ? 1 : 0
|
|
262
|
+
}))
|
|
263
|
+
};
|
|
264
|
+
case "dataRow": {
|
|
265
|
+
const fields = msg.fields;
|
|
266
|
+
const values = new Array(fields.length);
|
|
267
|
+
for (let i = 0; i < fields.length; i++) {
|
|
268
|
+
const v = fields[i];
|
|
269
|
+
values[i] = v === null ? null : Buffer.from(v, "utf8");
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
type: "DataRow",
|
|
273
|
+
values
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
case "commandComplete": return {
|
|
277
|
+
type: "CommandComplete",
|
|
278
|
+
tag: msg.text
|
|
279
|
+
};
|
|
280
|
+
case "emptyQuery": return { type: "EmptyQueryResponse" };
|
|
281
|
+
case "error": return {
|
|
282
|
+
type: "ErrorResponse",
|
|
283
|
+
fields: errorOrNoticeFields(msg)
|
|
284
|
+
};
|
|
285
|
+
case "notice": return {
|
|
286
|
+
type: "NoticeResponse",
|
|
287
|
+
fields: errorOrNoticeFields(msg)
|
|
288
|
+
};
|
|
289
|
+
case "notification": return {
|
|
290
|
+
type: "NotificationResponse",
|
|
291
|
+
processId: msg.processId,
|
|
292
|
+
channel: msg.channel,
|
|
293
|
+
payload: msg.payload
|
|
294
|
+
};
|
|
295
|
+
case "copyInResponse": return adaptCopyResponse("CopyInResponse", msg);
|
|
296
|
+
case "copyOutResponse": return adaptCopyResponse("CopyOutResponse", msg);
|
|
297
|
+
case "replicationStart": return { type: "CopyBothResponse" };
|
|
298
|
+
case "copyData": return {
|
|
299
|
+
type: "CopyData",
|
|
300
|
+
data: Buffer.from(msg.chunk)
|
|
301
|
+
};
|
|
302
|
+
case "copyDone": return { type: "CopyDone" };
|
|
303
|
+
case "noData": return { type: "NoData" };
|
|
304
|
+
case "parseComplete": return { type: "ParseComplete" };
|
|
305
|
+
case "bindComplete": return { type: "BindComplete" };
|
|
306
|
+
case "closeComplete": return { type: "CloseComplete" };
|
|
307
|
+
case "portalSuspended": return { type: "PortalSuspended" };
|
|
308
|
+
case "parameterDescription": return {
|
|
309
|
+
type: "ParameterDescription",
|
|
310
|
+
oids: msg.dataTypeIDs
|
|
311
|
+
};
|
|
312
|
+
default: throw new ProtocolError(`Unknown backend message: ${String(msg.name)}`);
|
|
313
|
+
}
|
|
358
314
|
}
|
|
359
315
|
function adaptCopyResponse(type, msg) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
};
|
|
316
|
+
const binary = msg.binary;
|
|
317
|
+
const columnFormats = msg.columnTypes.map((f) => f === 1 ? 1 : 0);
|
|
318
|
+
return {
|
|
319
|
+
type,
|
|
320
|
+
overallFormat: binary ? 1 : 0,
|
|
321
|
+
columnFormats
|
|
322
|
+
};
|
|
368
323
|
}
|
|
369
324
|
/**
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
325
|
+
* Re-pack pg-protocol's flattened Error/Notice fields (named properties like
|
|
326
|
+
* `severity`, `code`, `detail`, …) into our previous `Map<tag, value>` shape
|
|
327
|
+
* keyed by the on-wire single-letter tag. The map is consumed by
|
|
328
|
+
* `fieldsToNotice` below.
|
|
329
|
+
*/
|
|
375
330
|
function errorOrNoticeFields(msg) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
set("d", msg.dataType);
|
|
400
|
-
set("n", msg.constraint);
|
|
401
|
-
set("F", msg.file);
|
|
402
|
-
set("L", msg.line);
|
|
403
|
-
set("R", msg.routine);
|
|
404
|
-
return out;
|
|
331
|
+
const out = /* @__PURE__ */ new Map();
|
|
332
|
+
const set = (tag, value) => {
|
|
333
|
+
if (typeof value === "string") out.set(tag, value);
|
|
334
|
+
};
|
|
335
|
+
set("S", msg.severity);
|
|
336
|
+
set("V", msg.severity);
|
|
337
|
+
set("C", msg.code);
|
|
338
|
+
set("M", msg.message);
|
|
339
|
+
set("D", msg.detail);
|
|
340
|
+
set("H", msg.hint);
|
|
341
|
+
set("P", msg.position);
|
|
342
|
+
set("p", msg.internalPosition);
|
|
343
|
+
set("q", msg.internalQuery);
|
|
344
|
+
set("W", msg.where);
|
|
345
|
+
set("s", msg.schema);
|
|
346
|
+
set("t", msg.table);
|
|
347
|
+
set("c", msg.column);
|
|
348
|
+
set("d", msg.dataType);
|
|
349
|
+
set("n", msg.constraint);
|
|
350
|
+
set("F", msg.file);
|
|
351
|
+
set("L", msg.line);
|
|
352
|
+
set("R", msg.routine);
|
|
353
|
+
return out;
|
|
405
354
|
}
|
|
406
|
-
// ---------------------------------------------------------------------------
|
|
407
|
-
// Notice helper (unchanged; consumed by connection.ts)
|
|
408
|
-
// ---------------------------------------------------------------------------
|
|
409
355
|
/**
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
const dataType = fields.get("d");
|
|
451
|
-
if (dataType !== undefined)
|
|
452
|
-
out.dataType = dataType;
|
|
453
|
-
const constraint = fields.get("n");
|
|
454
|
-
if (constraint !== undefined)
|
|
455
|
-
out.constraint = constraint;
|
|
456
|
-
const file = fields.get("F");
|
|
457
|
-
if (file !== undefined)
|
|
458
|
-
out.file = file;
|
|
459
|
-
const line = fields.get("L");
|
|
460
|
-
if (line !== undefined)
|
|
461
|
-
out.line = line;
|
|
462
|
-
const routine = fields.get("R");
|
|
463
|
-
if (routine !== undefined)
|
|
464
|
-
out.routine = routine;
|
|
465
|
-
return out;
|
|
356
|
+
* Convert a notice/error field map into a Notice-shaped object. The wire
|
|
357
|
+
* tags are PG's single-letter codes; we promote the ones the Connection
|
|
358
|
+
* interface exposes.
|
|
359
|
+
*/
|
|
360
|
+
function fieldsToNotice(fields) {
|
|
361
|
+
const out = {
|
|
362
|
+
severity: fields.get("V") ?? fields.get("S") ?? "",
|
|
363
|
+
message: fields.get("M") ?? ""
|
|
364
|
+
};
|
|
365
|
+
const code = fields.get("C");
|
|
366
|
+
if (code !== void 0) out.code = code;
|
|
367
|
+
const detail = fields.get("D");
|
|
368
|
+
if (detail !== void 0) out.detail = detail;
|
|
369
|
+
const hint = fields.get("H");
|
|
370
|
+
if (hint !== void 0) out.hint = hint;
|
|
371
|
+
const position = fields.get("P");
|
|
372
|
+
if (position !== void 0) out.position = position;
|
|
373
|
+
const internalPosition = fields.get("p");
|
|
374
|
+
if (internalPosition !== void 0) out.internalPosition = internalPosition;
|
|
375
|
+
const internalQuery = fields.get("q");
|
|
376
|
+
if (internalQuery !== void 0) out.internalQuery = internalQuery;
|
|
377
|
+
const where = fields.get("W");
|
|
378
|
+
if (where !== void 0) out.where = where;
|
|
379
|
+
const schema = fields.get("s");
|
|
380
|
+
if (schema !== void 0) out.schema = schema;
|
|
381
|
+
const table = fields.get("t");
|
|
382
|
+
if (table !== void 0) out.table = table;
|
|
383
|
+
const column = fields.get("c");
|
|
384
|
+
if (column !== void 0) out.column = column;
|
|
385
|
+
const dataType = fields.get("d");
|
|
386
|
+
if (dataType !== void 0) out.dataType = dataType;
|
|
387
|
+
const constraint = fields.get("n");
|
|
388
|
+
if (constraint !== void 0) out.constraint = constraint;
|
|
389
|
+
const file = fields.get("F");
|
|
390
|
+
if (file !== void 0) out.file = file;
|
|
391
|
+
const line = fields.get("L");
|
|
392
|
+
if (line !== void 0) out.line = line;
|
|
393
|
+
const routine = fields.get("R");
|
|
394
|
+
if (routine !== void 0) out.routine = routine;
|
|
395
|
+
return out;
|
|
466
396
|
}
|
|
397
|
+
//#endregion
|
|
398
|
+
export { Bind, CancelRequest, Close, CopyData, CopyDone, CopyFail, Describe, Execute, Flush, MessageParser, Parse, PasswordMessage, ProtocolError, Query, SASLInitialResponse, SASLResponse, SSLRequest, StartupMessage, Sync, Terminate, fieldsToNotice };
|