neon 2.47.0 → 3.1.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.
Files changed (198) hide show
  1. package/README.md +54 -0
  2. package/dist/_shared/auth_selection.js +76 -79
  3. package/dist/_shared/credentials.js +166 -187
  4. package/dist/_shared/env-core/env.js +395 -0
  5. package/dist/_shared/env-core/reuse-secrets.js +179 -0
  6. package/dist/_shared/paths.js +129 -126
  7. package/dist/_shared/profiles.js +192 -242
  8. package/dist/_shared/secure_file.js +36 -38
  9. package/dist/_virtual/_rolldown/runtime.js +13 -0
  10. package/dist/analytics.js +163 -207
  11. package/dist/api.js +815 -758
  12. package/dist/auth.js +121 -141
  13. package/dist/auth_context.js +39 -53
  14. package/dist/cli.js +4 -7
  15. package/dist/commands/api.js +220 -250
  16. package/dist/commands/api_keys.js +251 -314
  17. package/dist/commands/auth.js +283 -328
  18. package/dist/commands/bootstrap.js +372 -437
  19. package/dist/commands/branches.js +304 -455
  20. package/dist/commands/bucket.js +374 -514
  21. package/dist/commands/checkout.js +213 -298
  22. package/dist/commands/config.js +575 -658
  23. package/dist/commands/connection_string.js +137 -165
  24. package/dist/commands/data_api.js +238 -260
  25. package/dist/commands/databases.js +67 -76
  26. package/dist/commands/deploy.js +31 -25
  27. package/dist/commands/dev.js +642 -681
  28. package/dist/commands/diff.js +156 -200
  29. package/dist/commands/env.js +243 -303
  30. package/dist/commands/functions.js +275 -341
  31. package/dist/commands/index.js +70 -65
  32. package/dist/commands/init.js +84 -119
  33. package/dist/commands/inspect.js +55 -55
  34. package/dist/commands/ip_allow.js +88 -120
  35. package/dist/commands/link.js +874 -1019
  36. package/dist/commands/logs.js +291 -0
  37. package/dist/commands/neon_auth.js +725 -933
  38. package/dist/commands/operations.js +34 -25
  39. package/dist/commands/orgs.js +28 -18
  40. package/dist/commands/profile.js +614 -845
  41. package/dist/commands/projects.js +313 -373
  42. package/dist/commands/psql.js +60 -58
  43. package/dist/commands/roles.js +55 -58
  44. package/dist/commands/schema_diff.js +87 -131
  45. package/dist/commands/set_context.js +34 -26
  46. package/dist/commands/snapshots.js +288 -413
  47. package/dist/commands/status.js +41 -37
  48. package/dist/commands/user.js +21 -10
  49. package/dist/commands/vpc_endpoints.js +85 -113
  50. package/dist/config.js +7 -6
  51. package/dist/config_format.js +50 -66
  52. package/dist/config_template.js +128 -157
  53. package/dist/context.js +183 -235
  54. package/dist/current_branch_fast_path.js +40 -49
  55. package/dist/dev/env.js +313 -394
  56. package/dist/dev/functions.js +54 -64
  57. package/dist/dev/inputs.js +46 -58
  58. package/dist/dev/runtime.js +135 -164
  59. package/dist/dev/websocket.js +766 -959
  60. package/dist/env.js +27 -33
  61. package/dist/env_file.js +118 -132
  62. package/dist/env_services.js +36 -38
  63. package/dist/errors.js +57 -68
  64. package/dist/functions_api.js +45 -43
  65. package/dist/help.js +189 -140
  66. package/dist/index.js +182 -257
  67. package/dist/init/agents.js +137 -118
  68. package/dist/init/auth.js +58 -68
  69. package/dist/init/bootstrap.js +325 -396
  70. package/dist/init/build_config.js +4 -2
  71. package/dist/init/detect_agent.js +56 -101
  72. package/dist/init/editors.js +35 -52
  73. package/dist/init/enrich_output.js +51 -66
  74. package/dist/init/extension.js +134 -171
  75. package/dist/init/inspect.js +179 -266
  76. package/dist/init/interactive.js +510 -622
  77. package/dist/init/neonctl.js +117 -168
  78. package/dist/init/orchestrate.js +157 -173
  79. package/dist/init/phases/auth.js +188 -202
  80. package/dist/init/phases/cleanup.js +23 -23
  81. package/dist/init/phases/db.js +251 -277
  82. package/dist/init/phases/getting_started.js +213 -223
  83. package/dist/init/phases/mcp.js +174 -224
  84. package/dist/init/phases/migrations.js +247 -248
  85. package/dist/init/phases/neon_auth.js +114 -133
  86. package/dist/init/phases/setup.js +546 -703
  87. package/dist/init/phases/skills.js +75 -86
  88. package/dist/init/phases/status.js +72 -67
  89. package/dist/init/resolve_context.js +102 -99
  90. package/dist/init/route_command.js +91 -98
  91. package/dist/init/skills.js +174 -218
  92. package/dist/init/vsix.js +77 -99
  93. package/dist/log.js +17 -16
  94. package/dist/neon_services.js +104 -129
  95. package/dist/parameters.gen.js +481 -471
  96. package/dist/pkg.js +17 -19
  97. package/dist/profile_keys.js +44 -47
  98. package/dist/psql/cli.js +44 -47
  99. package/dist/psql/command/cmd_cond.js +231 -406
  100. package/dist/psql/command/cmd_connect.js +557 -764
  101. package/dist/psql/command/cmd_copy.js +727 -983
  102. package/dist/psql/command/cmd_describe.js +1499 -1688
  103. package/dist/psql/command/cmd_format.js +733 -905
  104. package/dist/psql/command/cmd_io.js +1293 -2082
  105. package/dist/psql/command/cmd_lo.js +297 -359
  106. package/dist/psql/command/cmd_meta.js +727 -878
  107. package/dist/psql/command/cmd_misc.js +138 -172
  108. package/dist/psql/command/cmd_pipeline.js +547 -1099
  109. package/dist/psql/command/cmd_restrict.js +119 -155
  110. package/dist/psql/command/cmd_show.js +529 -688
  111. package/dist/psql/command/dispatch.js +261 -325
  112. package/dist/psql/command/inputQueue.js +35 -33
  113. package/dist/psql/command/shared.js +49 -63
  114. package/dist/psql/complete/filenames.js +90 -133
  115. package/dist/psql/complete/index.js +59 -97
  116. package/dist/psql/complete/matcher.js +236 -300
  117. package/dist/psql/complete/psqlVars.js +218 -223
  118. package/dist/psql/complete/queries.js +159 -177
  119. package/dist/psql/complete/rules.js +1493 -2299
  120. package/dist/psql/core/common.js +762 -1180
  121. package/dist/psql/core/help.js +456 -546
  122. package/dist/psql/core/mainloop.js +692 -1302
  123. package/dist/psql/core/prompt.js +391 -408
  124. package/dist/psql/core/settings.js +429 -644
  125. package/dist/psql/core/sqlHelp.js +480 -554
  126. package/dist/psql/core/startup.js +626 -815
  127. package/dist/psql/core/syncVars.js +67 -110
  128. package/dist/psql/core/variables.js +156 -278
  129. package/dist/psql/describe/formatters.js +884 -1285
  130. package/dist/psql/describe/processNamePattern.js +173 -260
  131. package/dist/psql/describe/queries.js +1368 -2403
  132. package/dist/psql/describe/versionGate.js +32 -41
  133. package/dist/psql/index.js +1414 -1927
  134. package/dist/psql/io/history.js +232 -271
  135. package/dist/psql/io/input.js +103 -108
  136. package/dist/psql/io/lineEditor/buffer.js +238 -319
  137. package/dist/psql/io/lineEditor/complete.js +135 -213
  138. package/dist/psql/io/lineEditor/filename.js +139 -148
  139. package/dist/psql/io/lineEditor/index.js +653 -870
  140. package/dist/psql/io/lineEditor/keymap.js +544 -702
  141. package/dist/psql/io/lineEditor/vt100.js +294 -341
  142. package/dist/psql/io/pgpass.js +158 -187
  143. package/dist/psql/io/pgservice.js +146 -183
  144. package/dist/psql/io/psqlrc.js +328 -403
  145. package/dist/psql/print/aligned.js +1020 -1683
  146. package/dist/psql/print/asciidoc.js +180 -214
  147. package/dist/psql/print/crosstab.js +281 -442
  148. package/dist/psql/print/csv.js +48 -70
  149. package/dist/psql/print/html.js +195 -226
  150. package/dist/psql/print/json.js +75 -88
  151. package/dist/psql/print/latex.js +291 -364
  152. package/dist/psql/print/pager.js +171 -242
  153. package/dist/psql/print/troff.js +194 -226
  154. package/dist/psql/print/unaligned.js +69 -95
  155. package/dist/psql/print/units.js +167 -169
  156. package/dist/psql/scanner/slash.js +428 -483
  157. package/dist/psql/scanner/sql.js +445 -889
  158. package/dist/psql/scanner/stringutils.js +309 -379
  159. package/dist/psql/types/index.js +2 -7
  160. package/dist/psql/types/scanner.js +25 -22
  161. package/dist/psql/wire/connection.js +2042 -2803
  162. package/dist/psql/wire/copy.js +84 -100
  163. package/dist/psql/wire/notify.js +39 -59
  164. package/dist/psql/wire/pipeline.js +305 -518
  165. package/dist/psql/wire/protocol.js +349 -417
  166. package/dist/psql/wire/sasl.js +180 -265
  167. package/dist/psql/wire/tls.js +400 -561
  168. package/dist/storage_api.js +115 -129
  169. package/dist/test_utils/fixtures.js +94 -113
  170. package/dist/test_utils/oauth_server.js +10 -7
  171. package/dist/test_utils/project_dir.js +33 -0
  172. package/dist/utils/ai_gateway_notice.js +131 -162
  173. package/dist/utils/api_enums.js +21 -28
  174. package/dist/utils/auth.js +10 -4
  175. package/dist/utils/branch_notice.js +20 -19
  176. package/dist/utils/branch_picker.js +83 -89
  177. package/dist/utils/cli_name.js +15 -12
  178. package/dist/utils/compute_units.js +20 -27
  179. package/dist/utils/config_diff.js +127 -158
  180. package/dist/utils/enrichers.js +95 -148
  181. package/dist/utils/esbuild.js +133 -147
  182. package/dist/utils/flags.js +35 -47
  183. package/dist/utils/formats.js +8 -15
  184. package/dist/utils/git_diff.js +69 -80
  185. package/dist/utils/inspect_db.js +101 -143
  186. package/dist/utils/inspect_queries.js +179 -142
  187. package/dist/utils/middlewares.js +37 -44
  188. package/dist/utils/openapi.js +87 -99
  189. package/dist/utils/package_manager.js +312 -110
  190. package/dist/utils/point_in_time.js +49 -53
  191. package/dist/utils/psql.js +89 -106
  192. package/dist/utils/service_picker.js +55 -58
  193. package/dist/utils/string.js +5 -5
  194. package/dist/utils/ui.js +38 -55
  195. package/dist/utils/write_sync.js +26 -35
  196. package/dist/utils/zip.js +4 -3
  197. package/dist/writer.js +67 -87
  198. package/package.json +9 -7
@@ -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
- export class ProtocolError extends Error {
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
- * StartupMessage. pg-protocol always appends `client_encoding=UTF8`; we
74
- * strip any incoming `client_encoding` to avoid duplicating it on the wire.
75
- * Our connect layer always sets UTF8 anyway, so this is a no-op in practice.
76
- */
77
- export function StartupMessage(params) {
78
- const filtered = {};
79
- for (const [key, value] of Object.entries(params)) {
80
- if (value === undefined)
81
- continue;
82
- if (key === "client_encoding")
83
- continue;
84
- filtered[key] = value;
85
- }
86
- return serialize.startup(filtered);
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
- export function SSLRequest() {
90
- return serialize.requestSsl();
68
+ function SSLRequest() {
69
+ return serialize.requestSsl();
91
70
  }
92
71
  /** CancelRequest — pg-protocol's `cancel` is layout-compatible. */
93
- export function CancelRequest(processId, secretKey) {
94
- return serialize.cancel(processId, secretKey);
72
+ function CancelRequest(processId, secretKey) {
73
+ return serialize.cancel(processId, secretKey);
95
74
  }
96
75
  /** Query: 'Q' + cstring(sql). */
97
- export function Query(sql) {
98
- return serialize.query(sql);
76
+ function Query(sql) {
77
+ return serialize.query(sql);
99
78
  }
100
79
  /** Terminate: 'X' + 4-byte length. */
101
- export function Terminate() {
102
- return serialize.end();
80
+ function Terminate() {
81
+ return serialize.end();
103
82
  }
104
83
  /** Sync: 'S' + 4-byte length. */
105
- export function Sync() {
106
- return serialize.sync();
84
+ function Sync() {
85
+ return serialize.sync();
107
86
  }
108
87
  /** Flush: 'H' + 4-byte length. */
109
- export function Flush() {
110
- return serialize.flush();
88
+ function Flush() {
89
+ return serialize.flush();
111
90
  }
112
91
  /** Parse: 'P' + cstring(name) + cstring(sql) + Int16 nparam + {Int32 oid}*. */
113
- export function Parse(name, sql, paramTypes) {
114
- return serialize.parse({ name, text: sql, types: paramTypes });
92
+ function Parse(name, sql, paramTypes) {
93
+ return serialize.parse({
94
+ name,
95
+ text: sql,
96
+ types: paramTypes
97
+ });
115
98
  }
116
99
  /**
117
- * Bind: 'B' + cstring(portal) + cstring(stmt) + per-value param formats +
118
- * value array + result formats.
119
- *
120
- * Note on parameter formats: pg-protocol's `serialize.bind` auto-detects the
121
- * format byte per value (`Buffer → 1`, `string/null → 0`); the caller-supplied
122
- * `paramFormats` arg is therefore ignored. This matches the hand-rolled
123
- * codec's effective behaviour because every caller passes either an empty
124
- * array (= "all text", which is what pg-protocol picks for strings) or a
125
- * format list that already agrees with the value's type.
126
- *
127
- * Note on result formats: we want every column in *text* format (`[0]`) for
128
- * `psql`-style printing. pg-protocol forces a single shared result-format
129
- * byte (`binary: boolean`); we pass `binary: false` to get text columns
130
- * regardless of the caller-supplied `resultFormats` array.
131
- */
132
- export function Bind(portal, stmt, paramFormats, params, resultFormats) {
133
- // `paramFormats` and `resultFormats` are read for the rare future caller
134
- // that might want explicit control; pg-protocol's `serialize.bind` doesn't
135
- // expose either, so we intentionally drop them on the floor for now.
136
- void paramFormats;
137
- void resultFormats;
138
- return serialize.bind({
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
- export function Describe(target, name) {
147
- return serialize.describe({ type: target, name });
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
- export function Execute(portal, maxRows) {
151
- return serialize.execute({ portal, rows: maxRows });
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
- export function Close(target, name) {
155
- return serialize.close({ type: target, name });
138
+ function Close(target, name) {
139
+ return serialize.close({
140
+ type: target,
141
+ name
142
+ });
156
143
  }
157
144
  /** PasswordMessage: 'p' + cstring(password). */
158
- export function PasswordMessage(password) {
159
- return serialize.password(password);
145
+ function PasswordMessage(password) {
146
+ return serialize.password(password);
160
147
  }
161
148
  /**
162
- * SASLInitialResponse: 'p' + cstring(mechanism) + Int32(bodyLen) + body.
163
- *
164
- * pg-protocol takes the initial response as a *string*; our SCRAM client
165
- * hands back a Buffer. SCRAM-SHA-256 messages are ASCII so this round-trips
166
- * losslessly via UTF-8.
167
- */
168
- export function SASLInitialResponse(mechanism, response) {
169
- return serialize.sendSASLInitialResponseMessage(mechanism, response.toString("utf8"));
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
- export function SASLResponse(response) {
173
- return serialize.sendSCRAMClientFinalMessage(response.toString("utf8"));
159
+ function SASLResponse(response) {
160
+ return serialize.sendSCRAMClientFinalMessage(response.toString("utf8"));
174
161
  }
175
162
  /** CopyData: 'd' + opaque bytes. */
176
- export function CopyData(data) {
177
- return serialize.copyData(data);
163
+ function CopyData(data) {
164
+ return serialize.copyData(data);
178
165
  }
179
166
  /** CopyDone: 'c' + 4-byte length. */
180
- export function CopyDone() {
181
- return serialize.copyDone();
167
+ function CopyDone() {
168
+ return serialize.copyDone();
182
169
  }
183
170
  /** CopyFail: 'f' + cstring(reason). */
184
- export function CopyFail(message) {
185
- return serialize.copyFail(message);
171
+ function CopyFail(message) {
172
+ return serialize.copyFail(message);
186
173
  }
187
- // ---------------------------------------------------------------------------
188
- // Backend message parser
189
- // ---------------------------------------------------------------------------
190
174
  /**
191
- * Streaming framer with a synchronous `feed()` API.
192
- *
193
- * Internally delegates to `pg-protocol`'s `Parser` (which exposes a
194
- * `parse(buffer, callback)` method that emits each completed backend message
195
- * via callback). On each `feed()` call we drain the parser and collect the
196
- * emitted messages into an array, reshaping each pg-protocol message into our
197
- * `BackendMessage` union (so `connection.ts`'s switch arms keep working).
198
- *
199
- * pg-protocol's `Parser.parse` calls the callback synchronously for every
200
- * complete message and keeps incomplete trailing bytes buffered internally.
201
- * That's a near-perfect match for our previous hand-rolled `MessageParser`.
202
- */
203
- export class MessageParser {
204
- constructor() {
205
- this.inner = new Parser();
206
- /** Bytes buffered inside `inner` but not yet emitted. Diagnostic only. */
207
- this.buffered = 0;
208
- }
209
- feed(chunk) {
210
- const out = [];
211
- try {
212
- this.inner.parse(chunk, (msg) => {
213
- out.push(adaptBackendMessage(msg));
214
- });
215
- }
216
- catch (err) {
217
- // pg-protocol throws plain `Error` on bad input (unknown auth
218
- // subtype, truncated frames, …). Normalize to our type.
219
- throw err instanceof ProtocolError
220
- ? err
221
- : new ProtocolError(err instanceof Error ? err.message : String(err));
222
- }
223
- // Probe the parser's leftover length via its internal field. Used by a
224
- // handful of tests for diagnostics; not relied on in production code.
225
- const probe = this.inner;
226
- this.buffered = probe.bufferLength ?? 0;
227
- return out;
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
- const msg = raw;
239
- switch (msg.name) {
240
- case "authenticationOk":
241
- return { type: "AuthenticationOk" };
242
- case "authenticationCleartextPassword":
243
- return { type: "AuthenticationCleartextPassword" };
244
- case "authenticationMD5Password":
245
- return {
246
- type: "AuthenticationMD5Password",
247
- salt: Buffer.from(msg.salt),
248
- };
249
- case "authenticationSASL":
250
- return {
251
- type: "AuthenticationSASL",
252
- mechanisms: msg.mechanisms,
253
- };
254
- case "authenticationSASLContinue":
255
- return {
256
- type: "AuthenticationSASLContinue",
257
- data: Buffer.from(msg.data, "utf8"),
258
- };
259
- case "authenticationSASLFinal":
260
- return {
261
- type: "AuthenticationSASLFinal",
262
- data: Buffer.from(msg.data, "utf8"),
263
- };
264
- case "parameterStatus":
265
- return {
266
- type: "ParameterStatus",
267
- name: msg.parameterName,
268
- value: msg.parameterValue,
269
- };
270
- case "backendKeyData":
271
- return {
272
- type: "BackendKeyData",
273
- processId: msg.processID,
274
- secretKey: msg.secretKey,
275
- };
276
- case "readyForQuery": {
277
- const status = msg.status;
278
- if (status !== "I" && status !== "T" && status !== "E") {
279
- throw new ProtocolError(`ReadyForQuery: unexpected status ${JSON.stringify(status)}`);
280
- }
281
- return { type: "ReadyForQuery", status };
282
- }
283
- case "rowDescription": {
284
- const fields = msg.fields.map((f) => ({
285
- name: f.name,
286
- tableID: f.tableID,
287
- columnID: f.columnID,
288
- dataTypeID: f.dataTypeID,
289
- dataTypeSize: f.dataTypeSize,
290
- dataTypeModifier: f.dataTypeModifier,
291
- format: f.format === "binary" ? 1 : 0,
292
- }));
293
- return { type: "RowDescription", fields };
294
- }
295
- case "dataRow": {
296
- // pg-protocol always parses values as UTF-8 strings (or null for SQL
297
- // NULL). Our connection layer expects (Buffer | null)[] so it can hand
298
- // text-format columns through `.toString('utf8')` and pass binary
299
- // columns through unchanged. Re-encode here.
300
- const fields = msg.fields;
301
- const values = new Array(fields.length);
302
- for (let i = 0; i < fields.length; i++) {
303
- const v = fields[i];
304
- values[i] = v === null ? null : Buffer.from(v, "utf8");
305
- }
306
- return { type: "DataRow", values };
307
- }
308
- case "commandComplete":
309
- return { type: "CommandComplete", tag: msg.text };
310
- case "emptyQuery":
311
- return { type: "EmptyQueryResponse" };
312
- case "error":
313
- return { type: "ErrorResponse", fields: errorOrNoticeFields(msg) };
314
- case "notice":
315
- return { type: "NoticeResponse", fields: errorOrNoticeFields(msg) };
316
- case "notification":
317
- return {
318
- type: "NotificationResponse",
319
- processId: msg.processId,
320
- channel: msg.channel,
321
- payload: msg.payload,
322
- };
323
- case "copyInResponse":
324
- return adaptCopyResponse("CopyInResponse", msg);
325
- case "copyOutResponse":
326
- return adaptCopyResponse("CopyOutResponse", msg);
327
- case "replicationStart":
328
- // pg-protocol emits a bare marker for the 'W' (CopyBothResponse) byte
329
- // — its `Parser` recognises the message code but does not decode the
330
- // payload (overall format + per-column format bytes). The body shape
331
- // is identical to CopyInResponse / CopyOutResponse but we don't need
332
- // those fields: the connection layer reacts to CopyBothResponse by
333
- // raising a clean diagnostic because this client does not implement
334
- // CopyBoth streaming.
335
- return { type: "CopyBothResponse" };
336
- case "copyData":
337
- return { type: "CopyData", data: Buffer.from(msg.chunk) };
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
- const binary = msg.binary;
361
- const columnTypes = msg.columnTypes;
362
- const columnFormats = columnTypes.map((f) => (f === 1 ? 1 : 0));
363
- return {
364
- type,
365
- overallFormat: binary ? 1 : 0,
366
- columnFormats,
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
- * Re-pack pg-protocol's flattened Error/Notice fields (named properties like
371
- * `severity`, `code`, `detail`, …) into our previous `Map<tag, value>` shape
372
- * keyed by the on-wire single-letter tag. The map is consumed by
373
- * `fieldsToNotice` below.
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
- const out = new Map();
377
- // The on-wire tag → field-name mapping is per PG docs §53.8. pg-protocol
378
- // stores `severity` from BOTH `S` and `V` (it overwrites with `V` if present)
379
- // — to preserve our previous behaviour (where the map carried both raw
380
- // tags), we copy S = V = severity when severity is defined. Consumers like
381
- // `fieldsToNotice` look at V then S so this matches.
382
- const set = (tag, value) => {
383
- if (typeof value === "string")
384
- out.set(tag, value);
385
- };
386
- set("S", msg.severity);
387
- set("V", msg.severity);
388
- set("C", msg.code);
389
- set("M", msg.message);
390
- set("D", msg.detail);
391
- set("H", msg.hint);
392
- set("P", msg.position);
393
- set("p", msg.internalPosition);
394
- set("q", msg.internalQuery);
395
- set("W", msg.where);
396
- set("s", msg.schema);
397
- set("t", msg.table);
398
- set("c", msg.column);
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
- * Convert a notice/error field map into a Notice-shaped object. The wire
411
- * tags are PG's single-letter codes; we promote the ones the Connection
412
- * interface exposes.
413
- */
414
- export function fieldsToNotice(fields) {
415
- // Per PG docs: V is the non-localized severity (preferred when present),
416
- // S is the localized severity (always present). Message M is mandatory.
417
- const severity = fields.get("V") ?? fields.get("S") ?? "";
418
- const message = fields.get("M") ?? "";
419
- const out = { severity, message };
420
- const code = fields.get("C");
421
- if (code !== undefined)
422
- out.code = code;
423
- const detail = fields.get("D");
424
- if (detail !== undefined)
425
- out.detail = detail;
426
- const hint = fields.get("H");
427
- if (hint !== undefined)
428
- out.hint = hint;
429
- const position = fields.get("P");
430
- if (position !== undefined)
431
- out.position = position;
432
- const internalPosition = fields.get("p");
433
- if (internalPosition !== undefined)
434
- out.internalPosition = internalPosition;
435
- const internalQuery = fields.get("q");
436
- if (internalQuery !== undefined)
437
- out.internalQuery = internalQuery;
438
- const where = fields.get("W");
439
- if (where !== undefined)
440
- out.where = where;
441
- const schema = fields.get("s");
442
- if (schema !== undefined)
443
- out.schema = schema;
444
- const table = fields.get("t");
445
- if (table !== undefined)
446
- out.table = table;
447
- const column = fields.get("c");
448
- if (column !== undefined)
449
- out.column = column;
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 };