@rebasepro/server-postgres 0.17.3 → 0.18.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.
Files changed (204) hide show
  1. package/LICENSE +0 -1
  2. package/README.md +31 -0
  3. package/dist/BranchService-ByLfM_Tt.js +360 -0
  4. package/dist/BranchService-ByLfM_Tt.js.map +1 -0
  5. package/dist/__vite-browser-external-BnuHet1e.js +46 -0
  6. package/dist/__vite-browser-external-BnuHet1e.js.map +1 -0
  7. package/dist/arg-Dni7MzLB.js +87 -0
  8. package/dist/arg-Dni7MzLB.js.map +1 -0
  9. package/dist/auth-users-columns-D2LBFrMH.js +116 -0
  10. package/dist/auth-users-columns-D2LBFrMH.js.map +1 -0
  11. package/dist/backup-argv.d.ts +19 -0
  12. package/dist/backup-cli-oM9WQVlV.js +408 -0
  13. package/dist/backup-cli-oM9WQVlV.js.map +1 -0
  14. package/dist/backup-service-Br3tqwsy.js +715 -0
  15. package/dist/backup-service-Br3tqwsy.js.map +1 -0
  16. package/dist/branch-argv.d.ts +28 -0
  17. package/dist/branch-prune.d.ts +77 -0
  18. package/dist/cli-collections-path.d.ts +31 -0
  19. package/dist/cli-errors-DxN4yzdH.js +657 -0
  20. package/dist/cli-errors-DxN4yzdH.js.map +1 -0
  21. package/dist/cli-errors.d.ts +123 -0
  22. package/dist/cli-flags.d.ts +101 -0
  23. package/dist/cli-helpers.d.ts +94 -10
  24. package/dist/cli-output-CNdMql-L.js +47 -0
  25. package/dist/cli-output-CNdMql-L.js.map +1 -0
  26. package/dist/cli.js +2020 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/collection-index-BHgT_TKd.js +276 -0
  29. package/dist/collection-index-BHgT_TKd.js.map +1 -0
  30. package/dist/{collections-schema-version-BMeu3cgv.js → collections-schema-version-T6cGvrDi.js} +1 -2
  31. package/dist/{collections-schema-version-BMeu3cgv.js.map → collections-schema-version-T6cGvrDi.js.map} +1 -1
  32. package/dist/{connection-GOKU3Hu5.js → databasePoolManager-Bj5FbeAs.js} +112 -40
  33. package/dist/databasePoolManager-Bj5FbeAs.js.map +1 -0
  34. package/dist/databasePoolManager.d.ts +27 -0
  35. package/dist/doctor-D7HWmGzs.js +974 -0
  36. package/dist/doctor-D7HWmGzs.js.map +1 -0
  37. package/dist/{ensure-collection-policies-UCqgv_8c.js → ensure-collection-policies-2c2NV8zX.js} +7 -27
  38. package/dist/ensure-collection-policies-2c2NV8zX.js.map +1 -0
  39. package/dist/ensure-collection-tables-D4wJzM4y.js +820 -0
  40. package/dist/ensure-collection-tables-D4wJzM4y.js.map +1 -0
  41. package/dist/ensure-tables-CIojK-Rx.js +650 -0
  42. package/dist/ensure-tables-CIojK-Rx.js.map +1 -0
  43. package/dist/generate-drizzle-schema-CwEgVyjO.js +123 -0
  44. package/dist/generate-drizzle-schema-CwEgVyjO.js.map +1 -0
  45. package/dist/generate-drizzle-schema-logic-so2Z_lyC.js +528 -0
  46. package/dist/generate-drizzle-schema-logic-so2Z_lyC.js.map +1 -0
  47. package/dist/{ensure-collection-tables-DgVixhX3.js → generate-postgres-ddl-logic-CtnpIBVv.js} +126 -984
  48. package/dist/generate-postgres-ddl-logic-CtnpIBVv.js.map +1 -0
  49. package/dist/generated-schema-staleness-DQdfJl2A.js +157 -0
  50. package/dist/generated-schema-staleness-DQdfJl2A.js.map +1 -0
  51. package/dist/index.d.ts +12 -0
  52. package/dist/index.es.js +7423 -1133
  53. package/dist/index.es.js.map +1 -1
  54. package/dist/introspect-db-logic-C6LQdTxj.js +1378 -0
  55. package/dist/introspect-db-logic-C6LQdTxj.js.map +1 -0
  56. package/dist/policy-drift-kNJ6X2Uj.js +313 -0
  57. package/dist/policy-drift-kNJ6X2Uj.js.map +1 -0
  58. package/dist/{backup-service-DCk7KhhL.js → rls-bootstrap-sql-DLDnUjtx.js} +737 -2689
  59. package/dist/rls-bootstrap-sql-DLDnUjtx.js.map +1 -0
  60. package/dist/{rls-enforcement-DvAbL9YJ.js → rls-enforcement-DeYEjYLt.js} +65 -190
  61. package/dist/rls-enforcement-DeYEjYLt.js.map +1 -0
  62. package/dist/schema/bin/generate-drizzle-schema.d.ts +1 -0
  63. package/dist/schema/bin/generate-postgres-ddl.d.ts +1 -0
  64. package/dist/schema/column-type-drift.d.ts +79 -0
  65. package/dist/schema/doctor-cli.js +129 -0
  66. package/dist/schema/doctor-cli.js.map +1 -0
  67. package/dist/schema/doctor.d.ts +42 -0
  68. package/dist/schema/ensure-collection-tables.d.ts +90 -0
  69. package/dist/schema/generate-drizzle-schema.d.ts +1 -1
  70. package/dist/schema/generate-drizzle-schema.js +24 -0
  71. package/dist/schema/generate-drizzle-schema.js.map +1 -0
  72. package/dist/schema/generate-next-step.d.ts +30 -0
  73. package/dist/schema/generate-postgres-ddl-logic.d.ts +28 -0
  74. package/dist/schema/generate-postgres-ddl.d.ts +1 -1
  75. package/dist/schema/generate-postgres-ddl.js +138 -0
  76. package/dist/schema/generate-postgres-ddl.js.map +1 -0
  77. package/dist/schema/generated-schema-staleness.d.ts +37 -0
  78. package/dist/schema/introspect-db-queries.d.ts +34 -0
  79. package/dist/schema/introspect-db.js +866 -0
  80. package/dist/schema/introspect-db.js.map +1 -0
  81. package/dist/security/rls-enforcement.d.ts +63 -2
  82. package/dist/services/BranchService.d.ts +86 -1
  83. package/dist/services/collection-helpers.d.ts +1 -1
  84. package/dist/services/realtimeService.d.ts +30 -2
  85. package/dist/services/row-pipeline.d.ts +12 -1
  86. package/dist/source-Br7L7GOI.js +410 -0
  87. package/dist/source-Br7L7GOI.js.map +1 -0
  88. package/dist/utils/pg-error-utils.d.ts +3 -1
  89. package/dist/utils/pg-numeric-number-patch.d.ts +31 -0
  90. package/dist/vector-index-DkWxm2de.js +309 -0
  91. package/dist/vector-index-DkWxm2de.js.map +1 -0
  92. package/package.json +32 -27
  93. package/dist/backup-service-DCk7KhhL.js.map +0 -1
  94. package/dist/collection-index-BRUg10H5.js +0 -5690
  95. package/dist/collection-index-BRUg10H5.js.map +0 -1
  96. package/dist/connection-GOKU3Hu5.js.map +0 -1
  97. package/dist/ensure-collection-policies-UCqgv_8c.js.map +0 -1
  98. package/dist/ensure-collection-tables-DgVixhX3.js.map +0 -1
  99. package/dist/rls-bootstrap-sql-B5C9LoJ6.js +0 -244
  100. package/dist/rls-bootstrap-sql-B5C9LoJ6.js.map +0 -1
  101. package/dist/rls-enforcement-DvAbL9YJ.js.map +0 -1
  102. package/dist/src-DiB5RP2Z.js +0 -541
  103. package/dist/src-DiB5RP2Z.js.map +0 -1
  104. package/dist/websocket-BZ4H5wUz.js +0 -8198
  105. package/dist/websocket-BZ4H5wUz.js.map +0 -1
  106. package/src/PostgresAdapter.ts +0 -91
  107. package/src/PostgresBackendDriver.ts +0 -1857
  108. package/src/PostgresBootstrapper.ts +0 -1157
  109. package/src/auth/ensure-tables.ts +0 -896
  110. package/src/auth/schema-version.ts +0 -260
  111. package/src/auth/services.ts +0 -1610
  112. package/src/backup/backup-cli.ts +0 -520
  113. package/src/backup/backup-cron.ts +0 -212
  114. package/src/backup/backup-logic.ts +0 -93
  115. package/src/backup/backup-service.ts +0 -485
  116. package/src/backup/index.ts +0 -12
  117. package/src/backup/pg-tools.ts +0 -403
  118. package/src/backup/retention.ts +0 -86
  119. package/src/cli-errors.ts +0 -265
  120. package/src/cli-helpers.ts +0 -569
  121. package/src/cli-output.ts +0 -43
  122. package/src/cli.ts +0 -1339
  123. package/src/collections/PostgresCollectionRegistry.ts +0 -108
  124. package/src/collections/buildRegistry.ts +0 -68
  125. package/src/collections/validate-relations.ts +0 -402
  126. package/src/connection.ts +0 -333
  127. package/src/data-transformer.ts +0 -845
  128. package/src/databasePoolManager.ts +0 -95
  129. package/src/history/HistoryService.ts +0 -254
  130. package/src/history/ensure-history-table.ts +0 -53
  131. package/src/index.ts +0 -19
  132. package/src/interfaces.ts +0 -60
  133. package/src/module-dir.ts +0 -7
  134. package/src/schema/atlas-argv.ts +0 -94
  135. package/src/schema/auth-schema.ts +0 -298
  136. package/src/schema/auth-users-columns.ts +0 -131
  137. package/src/schema/carved-out-migration.ts +0 -404
  138. package/src/schema/classify-change.ts +0 -436
  139. package/src/schema/collection-index.ts +0 -427
  140. package/src/schema/collections-schema-version.ts +0 -103
  141. package/src/schema/destructive-sql.ts +0 -94
  142. package/src/schema/doctor-cli.ts +0 -66
  143. package/src/schema/doctor-policy-checks.ts +0 -105
  144. package/src/schema/doctor.ts +0 -837
  145. package/src/schema/drizzle-ddl.ts +0 -33
  146. package/src/schema/dynamic-tables.test.ts +0 -302
  147. package/src/schema/dynamic-tables.ts +0 -293
  148. package/src/schema/ensure-collection-policies.ts +0 -198
  149. package/src/schema/ensure-collection-tables.test.ts +0 -518
  150. package/src/schema/ensure-collection-tables.ts +0 -1267
  151. package/src/schema/generate-drizzle-schema-logic.ts +0 -957
  152. package/src/schema/generate-drizzle-schema.ts +0 -143
  153. package/src/schema/generate-postgres-ddl-logic.ts +0 -1339
  154. package/src/schema/generate-postgres-ddl.ts +0 -180
  155. package/src/schema/generate-schema-commit.ts +0 -267
  156. package/src/schema/generated-schema-staleness.ts +0 -284
  157. package/src/schema/introspect-db-constraints.ts +0 -385
  158. package/src/schema/introspect-db-inference.ts +0 -255
  159. package/src/schema/introspect-db-logic.ts +0 -1387
  160. package/src/schema/introspect-db-naming.ts +0 -15
  161. package/src/schema/introspect-db-project.ts +0 -78
  162. package/src/schema/introspect-db-queries.ts +0 -326
  163. package/src/schema/introspect-db-structure.ts +0 -670
  164. package/src/schema/introspect-db-types.ts +0 -56
  165. package/src/schema/introspect-db.ts +0 -257
  166. package/src/schema/introspect-runtime.test.ts +0 -260
  167. package/src/schema/introspect-runtime.ts +0 -327
  168. package/src/schema/non-sql-collections.test.ts +0 -131
  169. package/src/schema/rls-bootstrap-sql.ts +0 -288
  170. package/src/schema/search-column.ts +0 -643
  171. package/src/schema/test-schema.ts +0 -11
  172. package/src/schema/vector-index.ts +0 -491
  173. package/src/security/anonymous-grants.test.ts +0 -73
  174. package/src/security/policy-drift.test.ts +0 -435
  175. package/src/security/policy-drift.ts +0 -473
  176. package/src/security/rls-enforcement.ts +0 -505
  177. package/src/services/BranchService.ts +0 -326
  178. package/src/services/FetchService.ts +0 -2115
  179. package/src/services/PersistService.ts +0 -557
  180. package/src/services/RelationService.ts +0 -978
  181. package/src/services/RelationWriteService.ts +0 -653
  182. package/src/services/cdc/CdcListener.ts +0 -103
  183. package/src/services/cdc/junction-tables.ts +0 -91
  184. package/src/services/cdc/trigger-cdc.ts +0 -173
  185. package/src/services/channel-bus/ChannelBus.ts +0 -44
  186. package/src/services/channel-bus/PostgresChannelBus.ts +0 -299
  187. package/src/services/channel-bus/index.ts +0 -114
  188. package/src/services/channel-history.ts +0 -424
  189. package/src/services/channel-presence.ts +0 -185
  190. package/src/services/collection-helpers.ts +0 -420
  191. package/src/services/dataService.ts +0 -256
  192. package/src/services/index.ts +0 -14
  193. package/src/services/junction-writes.ts +0 -295
  194. package/src/services/nested-path.ts +0 -145
  195. package/src/services/pg-notify-listener.ts +0 -151
  196. package/src/services/realtimeService.ts +0 -2545
  197. package/src/services/row-pipeline.ts +0 -240
  198. package/src/services/write-denial.ts +0 -55
  199. package/src/types.ts +0 -4
  200. package/src/utils/connection-string.ts +0 -58
  201. package/src/utils/drizzle-conditions.ts +0 -2743
  202. package/src/utils/pg-array-null-patch.ts +0 -42
  203. package/src/utils/pg-error-utils.ts +0 -391
  204. package/src/websocket.ts +0 -855
package/src/cli-errors.ts DELETED
@@ -1,265 +0,0 @@
1
- import chalk from "chalk";
2
- import { outWarn, outError } from "./cli-output";
3
-
4
- /**
5
- * Detect whether an error (or AggregateError wrapping multiple attempts)
6
- * represents an ECONNREFUSED — i.e. the database is simply not running.
7
- *
8
- * Handles:
9
- * - Direct `{ code: "ECONNREFUSED" }` errors from Node `net`
10
- * - `AggregateError` from dual-stack IPv4+IPv6 connection attempts
11
- * - Drizzle's `cause`-wrapped pg errors
12
- */
13
- export function isEconnrefused(err: unknown): boolean {
14
- if (!err || typeof err !== "object") return false;
15
- const e = err as { code?: string; cause?: unknown; errors?: unknown[] };
16
- if (e.code === "ECONNREFUSED") return true;
17
- // AggregateError from Node net (dual-stack IPv4 + IPv6)
18
- if (Array.isArray(e.errors)) {
19
- return e.errors.some(inner =>
20
- inner && typeof inner === "object" && (inner as { code?: string }).code === "ECONNREFUSED"
21
- );
22
- }
23
- // Drizzle wraps the pg error in `cause`
24
- if (e.cause && typeof e.cause === "object") {
25
- return isEconnrefused(e.cause);
26
- }
27
- return false;
28
- }
29
-
30
- /**
31
- * Detect PostgreSQL authentication failures.
32
- * PG error codes: 28P01 (invalid_password), 28000 (invalid_authorization_specification)
33
- */
34
- export function isAuthFailure(err: unknown): boolean {
35
- if (!err || typeof err !== "object") return false;
36
- const e = err as { code?: string; cause?: unknown };
37
- if (e.code === "28P01" || e.code === "28000") return true;
38
- if (e.cause && typeof e.cause === "object") {
39
- return isAuthFailure(e.cause);
40
- }
41
- // Also check the message for common pg auth failure text
42
- if ("message" in e && typeof (e as { message?: string }).message === "string") {
43
- const msg = (e as { message: string }).message.toLowerCase();
44
- if (msg.includes("password authentication failed") || msg.includes("no pg_hba.conf entry")) {
45
- return true;
46
- }
47
- }
48
- return false;
49
- }
50
-
51
- /**
52
- * Detect the "SSL is not enabled on the server" failure — the client attempted
53
- * an SSL handshake against a Postgres server that doesn't support it (common
54
- * with a plain local dev database). The fix is `?sslmode=disable` on the URL.
55
- */
56
- export function isSslNotEnabled(err: unknown): boolean {
57
- if (!err || typeof err !== "object") return false;
58
- const e = err as { message?: string; cause?: unknown };
59
- if (typeof e.message === "string" && e.message.toLowerCase().includes("ssl is not enabled on the server")) {
60
- return true;
61
- }
62
- if (e.cause && typeof e.cause === "object") {
63
- return isSslNotEnabled(e.cause);
64
- }
65
- return false;
66
- }
67
-
68
- /**
69
- * Detect PostgreSQL "cannot drop ... because other objects depend on it"
70
- * (error code 2BP01, dependent_objects_still_exist). This is the failure that
71
- * strands a declarative `db push` half-applied when a collection is removed but
72
- * an enum type it defined is still referenced by another object.
73
- */
74
- export function isDependencyDropError(err: unknown): boolean {
75
- if (!err || typeof err !== "object") return false;
76
- const e = err as { code?: string; message?: string; cause?: unknown };
77
- if (e.code === "2BP01") return true;
78
- if (typeof e.message === "string") {
79
- const msg = e.message.toLowerCase();
80
- if (msg.includes("other objects depend on it") || msg.includes("cannot drop type")) {
81
- return true;
82
- }
83
- }
84
- if (e.cause && typeof e.cause === "object") {
85
- return isDependencyDropError(e.cause);
86
- }
87
- return false;
88
- }
89
-
90
- /**
91
- * Parse host:port from a DATABASE_URL for display purposes.
92
- */
93
- function parseHostInfo(databaseUrl: string): string {
94
- try {
95
- const parsed = new URL(databaseUrl);
96
- return `${parsed.hostname}:${parsed.port || 5432}`;
97
- } catch {
98
- return "unknown";
99
- }
100
- }
101
-
102
- /**
103
- * Format a diagnostic banner for ECONNREFUSED errors.
104
- */
105
- function formatConnectionRefusedBanner(databaseUrl: string): string {
106
- const hostInfo = parseHostInfo(databaseUrl);
107
- return (
108
- `\n` +
109
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
110
- ` ❌ Cannot connect to PostgreSQL at ${hostInfo}\n` +
111
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
112
- `\n` +
113
- ` The database server is not running or is not accepting\n` +
114
- ` connections. Common fixes:\n` +
115
- `\n` +
116
- ` • docker compose up -d db (the service a Rebase scaffold ships)\n` +
117
- ` • brew services start postgresql@18\n` +
118
- ` • Verify DATABASE_URL in your .env file\n` +
119
- `\n` +
120
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`
121
- );
122
- }
123
-
124
- /**
125
- * Format a diagnostic banner for authentication failures.
126
- */
127
- function formatAuthFailureBanner(databaseUrl: string): string {
128
- const hostInfo = parseHostInfo(databaseUrl);
129
- let username = "unknown";
130
- try {
131
- username = new URL(databaseUrl).username || "unknown";
132
- } catch { /* ignore */ }
133
-
134
- return (
135
- `\n` +
136
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
137
- ` ❌ Authentication failed for user "${username}" at ${hostInfo}\n` +
138
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
139
- `\n` +
140
- ` PostgreSQL rejected the credentials. Common fixes:\n` +
141
- `\n` +
142
- ` • Check the username and password in DATABASE_URL\n` +
143
- ` • Verify the user exists: psql -c "\\du"\n` +
144
- ` • Reset the password: ALTER USER ${username} PASSWORD 'new_password';\n` +
145
- `\n` +
146
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`
147
- );
148
- }
149
-
150
- /**
151
- * Format a diagnostic banner for "SSL is not enabled on the server".
152
- */
153
- function formatSslNotEnabledBanner(databaseUrl: string): string {
154
- const hostInfo = parseHostInfo(databaseUrl);
155
- const suggestion = databaseUrl.includes("?") ? "&sslmode=disable" : "?sslmode=disable";
156
- return (
157
- `\n` +
158
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
159
- ` ❌ SSL is not enabled on the PostgreSQL server at ${hostInfo}\n` +
160
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
161
- `\n` +
162
- ` The client tried to connect over SSL, but the server does not\n` +
163
- ` support it. This is normal for a plain local dev database.\n` +
164
- `\n` +
165
- ` Fix: append ${chalk.bold("sslmode=disable")} to DATABASE_URL, e.g.\n` +
166
- `\n` +
167
- ` DATABASE_URL=...${suggestion}\n` +
168
- `\n` +
169
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`
170
- );
171
- }
172
-
173
- /**
174
- * Format a diagnostic banner for a dependency-drop failure during `db push`.
175
- * Explains that the database may be left partially migrated and how to recover.
176
- */
177
- function formatDependencyDropBanner(): string {
178
- return (
179
- `\n` +
180
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
181
- ` ❌ Schema push failed: a type/table could not be dropped\n` +
182
- ` because other objects still depend on it.\n` +
183
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
184
- `\n` +
185
- ` ${chalk.yellow("The database may now be partially migrated.")} Atlas applies\n` +
186
- ` statements individually, so earlier changes in this push may\n` +
187
- ` already be committed while later ones failed.\n` +
188
- `\n` +
189
- ` This commonly happens when a collection is removed but an enum\n` +
190
- ` type it defined is still referenced. To recover:\n` +
191
- `\n` +
192
- ` 1. Inspect the leftover object named in the error above.\n` +
193
- ` 2. Drop it with CASCADE, e.g.:\n` +
194
- ` psql "$DATABASE_URL" -c 'DROP TYPE "<name>" CASCADE;'\n` +
195
- ` 3. Re-run: ${chalk.bold.green("rebase db push")}\n` +
196
- `\n` +
197
- ` Prefer a safe, versioned workflow? Use ${chalk.bold("rebase db generate")}\n` +
198
- ` + ${chalk.bold("rebase db migrate")} instead of push for destructive changes.\n` +
199
- `\n` +
200
- `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`
201
- );
202
- }
203
-
204
- /**
205
- * Pre-flight check: verify that the database is reachable before running
206
- * a heavy subprocess (Atlas, migrations, etc.).
207
- *
208
- * Exits with code 1 and a friendly banner on known failure modes.
209
- * On unknown errors, logs a warning and allows the caller to proceed.
210
- */
211
- export async function checkDatabaseConnectivity(databaseUrl: string): Promise<void> {
212
- let client: import("pg").Client | undefined;
213
- try {
214
- const { Client } = await import("pg");
215
- client = new Client({
216
- connectionString: databaseUrl,
217
- connectionTimeoutMillis: 5000
218
- });
219
- await client.connect();
220
- await client.query("SELECT 1");
221
- } catch (err: unknown) {
222
- if (isEconnrefused(err)) {
223
- outError(formatConnectionRefusedBanner(databaseUrl));
224
- process.exit(1);
225
- }
226
- if (isAuthFailure(err)) {
227
- outError(formatAuthFailureBanner(databaseUrl));
228
- process.exit(1);
229
- }
230
- if (isSslNotEnabled(err)) {
231
- outError(formatSslNotEnabledBanner(databaseUrl));
232
- process.exit(1);
233
- }
234
- // Unknown error — warn but don't block; let the downstream tool surface details
235
- outWarn(chalk.yellow(` ⚠ Could not verify database connectivity: ${err instanceof Error ? err.message : String(err)}`));
236
- outWarn(chalk.gray(" Proceeding anyway — the command may fail if the database is unreachable."));
237
- } finally {
238
- try {
239
- await client?.end();
240
- } catch {
241
- // ignore cleanup errors
242
- }
243
- }
244
- }
245
-
246
- /**
247
- * Post-hoc error diagnosis for direct database operations (e.g. applyPolicies).
248
- * Returns a formatted diagnostic string if the error matches a known pattern,
249
- * or null if unrecognized.
250
- */
251
- export function diagnoseDbError(err: unknown, databaseUrl?: string): string | null {
252
- if (isEconnrefused(err)) {
253
- return formatConnectionRefusedBanner(databaseUrl || "");
254
- }
255
- if (isAuthFailure(err)) {
256
- return formatAuthFailureBanner(databaseUrl || "");
257
- }
258
- if (isSslNotEnabled(err)) {
259
- return formatSslNotEnabledBanner(databaseUrl || "");
260
- }
261
- if (isDependencyDropError(err)) {
262
- return formatDependencyDropBanner();
263
- }
264
- return null;
265
- }