@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
@@ -0,0 +1,715 @@
1
+ import { createRequire as __createRequire } from "module";
2
+ __createRequire(import.meta.url);
3
+ import { r as __exportAll } from "./__vite-browser-external-BnuHet1e.js";
4
+ import { C as resolveLocalBin, T as forLibpq, w as execa } from "./rls-bootstrap-sql-DLDnUjtx.js";
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import os from "os";
8
+ //#region src/backup/pg-tools.ts
9
+ /**
10
+ * Pure helpers for the backup/restore commands.
11
+ *
12
+ * Everything in this file is side-effect free so it can be unit-tested
13
+ * without a live Postgres server, matching the constraint that CI must
14
+ * not require a database.
15
+ */
16
+ /**
17
+ * Extract the database name from a Postgres connection string.
18
+ * Returns `null` when the URL has no database path (e.g. bare host).
19
+ */
20
+ function parseDbNameFromUrl(connectionString) {
21
+ try {
22
+ const name = new URL(connectionString).pathname.replace(/^\//, "").trim();
23
+ return name.length > 0 ? name : null;
24
+ } catch {
25
+ const match = connectionString.match(/\/([^/?]+)(\?|$)/);
26
+ return match && match[1] ? match[1] : null;
27
+ }
28
+ }
29
+ /**
30
+ * Swap the database name in a connection string, preserving credentials,
31
+ * host, port and query params. Used by `--target-db` / `--create-db` so a
32
+ * restore can target a fresh database instead of clobbering the live one.
33
+ */
34
+ function withDatabaseName(connectionString, dbName) {
35
+ try {
36
+ const parsed = new URL(connectionString);
37
+ parsed.pathname = `/${dbName}`;
38
+ return parsed.toString();
39
+ } catch {
40
+ return connectionString.replace(/\/([^/?]+)(\?|$)/, `/${dbName}$2`);
41
+ }
42
+ }
43
+ /**
44
+ * Parse the major version out of `pg_dump --version` / `pg_restore --version`
45
+ * output, e.g. `"pg_dump (PostgreSQL) 16.2"` → `16`. Handles the pre-10
46
+ * `9.6.x` scheme (returns `9`) and beta strings like `"17beta1"`.
47
+ */
48
+ function parsePgToolMajor(versionOutput) {
49
+ const match = versionOutput.match(/(\d+)(?:\.(\d+))?/);
50
+ if (!match) return null;
51
+ const major = Number(match[1]);
52
+ if (!Number.isFinite(major)) return null;
53
+ if (major === 9 && match[2] !== void 0) return 9;
54
+ return major;
55
+ }
56
+ /**
57
+ * Convert `SELECT current_setting('server_version_num')` (e.g. `160002`)
58
+ * into a major version (`16`). Also accepts pre-10 encodings like `90603`
59
+ * → `9`.
60
+ */
61
+ function serverVersionNumToMajor(versionNum) {
62
+ const num = typeof versionNum === "string" ? Number(versionNum) : versionNum;
63
+ if (!Number.isFinite(num) || num <= 0) return null;
64
+ if (num < 1e5) return Math.floor(num / 1e4);
65
+ return Math.floor(num / 1e4);
66
+ }
67
+ /**
68
+ * pg_dump / pg_restore must be **at least** as new as the server they talk
69
+ * to. A newer client against an older server is supported; an older client
70
+ * against a newer server is not and produces corrupt or rejected output.
71
+ */
72
+ function checkToolServerCompatibility(toolMajor, serverMajor) {
73
+ if (toolMajor === null) return {
74
+ compatible: false,
75
+ reason: "Could not determine the client tool version."
76
+ };
77
+ if (serverMajor === null) return {
78
+ compatible: false,
79
+ reason: "Could not determine the Postgres server version."
80
+ };
81
+ if (toolMajor < serverMajor) return {
82
+ compatible: false,
83
+ reason: `Client tool is Postgres ${toolMajor} but the server is Postgres ${serverMajor}. pg_dump/pg_restore must be the same major version as the server or newer. Install Postgres ${serverMajor} client tools.`
84
+ };
85
+ return { compatible: true };
86
+ }
87
+ /**
88
+ * Build a deterministic, sortable backup file name:
89
+ * `rebase-<db>-<YYYYMMDD>T<HHMMSS>Z.dump`
90
+ *
91
+ * The UTC timestamp is embedded so retention pruning can recover the
92
+ * creation time from the object key alone, without extra metadata.
93
+ */
94
+ function buildBackupFilename(dbName, date = /* @__PURE__ */ new Date()) {
95
+ const stamp = date.toISOString().replace(/\.\d+Z$/, "Z").replace(/[-:]/g, "");
96
+ return `rebase-${dbName.replace(/[^a-zA-Z0-9_-]/g, "_")}-${stamp}.dump`;
97
+ }
98
+ /**
99
+ * Recover the creation timestamp encoded in a backup file name by
100
+ * {@link buildBackupFilename}. Returns `null` for names that don't match,
101
+ * so foreign objects in a shared prefix are never pruned.
102
+ */
103
+ function parseBackupTimestamp(fileName) {
104
+ const match = (fileName.split("/").pop() ?? fileName).match(/-(\d{8})T(\d{6})Z\.dump$/);
105
+ if (!match) return null;
106
+ const [, ymd, hms] = match;
107
+ const iso = `${ymd.slice(0, 4)}-${ymd.slice(4, 6)}-${ymd.slice(6, 8)}T${hms.slice(0, 2)}:${hms.slice(2, 4)}:${hms.slice(4, 6)}Z`;
108
+ const date = new Date(iso);
109
+ return Number.isNaN(date.getTime()) ? null : date;
110
+ }
111
+ /**
112
+ * Parse a destination string into a structured {@link BackupDestination}.
113
+ * `s3://bucket/prefix` and `gs://bucket/prefix` map to object storage;
114
+ * anything else is treated as a local path.
115
+ */
116
+ function parseBackupDestination(out) {
117
+ const s3 = out.match(/^s3:\/\/([^/]+)\/?(.*)$/);
118
+ if (s3) return {
119
+ kind: "s3",
120
+ bucket: s3[1],
121
+ prefix: stripTrailingSlash(s3[2])
122
+ };
123
+ const gcs = out.match(/^gs:\/\/([^/]+)\/?(.*)$/);
124
+ if (gcs) return {
125
+ kind: "gcs",
126
+ bucket: gcs[1],
127
+ prefix: stripTrailingSlash(gcs[2])
128
+ };
129
+ return {
130
+ kind: "local",
131
+ path: out
132
+ };
133
+ }
134
+ function stripTrailingSlash(s) {
135
+ return s.replace(/\/+$/, "");
136
+ }
137
+ /**
138
+ * Join a storage prefix and a file name without producing a leading or
139
+ * doubled slash.
140
+ */
141
+ function joinStorageKey(prefix, fileName) {
142
+ const clean = prefix.replace(/^\/+|\/+$/g, "");
143
+ return clean.length > 0 ? `${clean}/${fileName}` : fileName;
144
+ }
145
+ /**
146
+ * `PGOPTIONS` carrying an identity, for a libpq tool that has no other way to
147
+ * set a GUC.
148
+ *
149
+ * A backslash escape rather than quoting, which is what libpq's `-c` parsing
150
+ * takes: a space inside a value ends the option otherwise, so a role list is
151
+ * comma-joined and never spaced.
152
+ */
153
+ function buildRowSecurityPgOptions(identity) {
154
+ const escape = (value) => value.replace(/([\\ ])/g, "\\$1");
155
+ return [
156
+ `-c app.uid=${escape(identity.uid)}`,
157
+ `-c app.user_id=${escape(identity.uid)}`,
158
+ `-c app.user_roles=${escape(identity.roles.join(","))}`
159
+ ].join(" ");
160
+ }
161
+ /**
162
+ * Assemble the `pg_dump` argument vector. Uses the custom format (`-Fc`),
163
+ * which is compressed and restorable selectively via `pg_restore`.
164
+ */
165
+ function buildPgDumpArgs(opts) {
166
+ const args = [
167
+ "--format=custom",
168
+ "--no-password",
169
+ `--file=${opts.outFile}`
170
+ ];
171
+ if (opts.noOwner) args.push("--no-owner");
172
+ if (opts.rowSecurity) args.push("--enable-row-security");
173
+ for (const schema of opts.excludeSchemas ?? []) args.push(`--exclude-schema=${schema}`);
174
+ args.push(forLibpq(opts.connectionString));
175
+ return args;
176
+ }
177
+ /**
178
+ * Whether a `pg_dump` failure is the row-security one, and what to do about it.
179
+ *
180
+ * The error text names the table and nothing else, so the first read of it is
181
+ * "why would a backup be affected by RLS at all?" — the answer being that the
182
+ * dumping role is not the tables' owner and has no `BYPASSRLS`, which is the
183
+ * normal state of the `postgres` user on Cloud SQL, RDS and every other managed
184
+ * Postgres. Nothing about that is visible from the message.
185
+ *
186
+ * Returns `null` for any other failure, so the caller reports it unchanged.
187
+ */
188
+ function diagnoseRowSecurityDumpFailure(error) {
189
+ const text = [error?.stderr, error?.message].map((part) => typeof part === "string" ? part : "").join("\n");
190
+ if (!/row-level security policy/i.test(text)) return null;
191
+ const table = text.match(/for table "([^"]+)"/)?.[1];
192
+ return [
193
+ `pg_dump cannot read ${table ? `"${table}"` : "one of the tables"} because row-level security applies to it.`,
194
+ "",
195
+ " The dumping role is neither the table's owner nor `BYPASSRLS`, which is the normal",
196
+ " state of the `postgres` user on Cloud SQL, RDS and other managed Postgres — there is",
197
+ " no superuser to hand out.",
198
+ "",
199
+ " Two ways out:",
200
+ "",
201
+ " • Grant the dumping role BYPASSRLS, or make it the owner, and run this again. The",
202
+ " dump then contains every row, which is what a backup should mean.",
203
+ "",
204
+ " • Re-run with --enable-row-security to dump as an admin subject instead. Rebase",
205
+ " sets `app.uid`/`app.user_roles` so the generated `admin_full_access` policy",
206
+ " admits the dump. Read the warning it prints: the result contains exactly the",
207
+ " rows those policies admit, and any table whose policies do not include an",
208
+ " admin rule comes out short — with no error.",
209
+ "",
210
+ " Do not reach for a bare `pg_dump --enable-row-security` by hand. Without the",
211
+ " settings above it succeeds and silently omits rows."
212
+ ].join("\n");
213
+ }
214
+ /**
215
+ * Assemble the `pg_restore` argument vector for a custom-format dump.
216
+ */
217
+ function buildPgRestoreArgs(opts) {
218
+ const args = [
219
+ "--format=custom",
220
+ "--no-password",
221
+ `--dbname=${forLibpq(opts.connectionString)}`
222
+ ];
223
+ if (opts.clean) args.push("--clean", "--if-exists");
224
+ if (opts.noOwner) args.push("--no-owner");
225
+ if (opts.exitOnError !== false) args.push("--exit-on-error");
226
+ args.push(opts.inputFile);
227
+ return args;
228
+ }
229
+ /**
230
+ * Assemble the `pg_restore --list` argument vector. Reading a dump's table
231
+ * of contents parses the whole archive without touching a database, so it is
232
+ * a cheap integrity check that the file isn't truncated or corrupt.
233
+ */
234
+ function buildPgRestoreListArgs(inputFile) {
235
+ return ["--list", inputFile];
236
+ }
237
+ /**
238
+ * Assemble the `pg_dumpall --globals-only` argument vector. Roles (and other
239
+ * cluster-wide objects) live outside any single database, so a per-database
240
+ * `pg_dump` omits them. Without the `rebase_user` role the RLS GRANT
241
+ * statements in the main dump fail on restore and RLS is silently lost — so
242
+ * every backup captures the globals into a sidecar `.globals.sql`.
243
+ *
244
+ * `--no-role-passwords` keeps role secrets out of the artifact (backups may
245
+ * be shipped off-box); roles are recreated password-less and re-secured by
246
+ * the operator.
247
+ */
248
+ function buildPgDumpallGlobalsArgs(opts) {
249
+ return [
250
+ "--globals-only",
251
+ "--no-role-passwords",
252
+ "--no-password",
253
+ `--file=${opts.outFile}`,
254
+ `--dbname=${forLibpq(opts.connectionString)}`
255
+ ];
256
+ }
257
+ /**
258
+ * Derive the globals sidecar path/key for a given `.dump` file. Keeps the
259
+ * two artifacts adjacent so listing, uploading and pruning can find one from
260
+ * the other. A name that doesn't end in `.dump` is returned unchanged with a
261
+ * `.globals.sql` suffix appended.
262
+ */
263
+ function globalsFileForDump(dumpPath) {
264
+ return dumpPath.endsWith(".dump") ? dumpPath.slice(0, -5) + ".globals.sql" : dumpPath + ".globals.sql";
265
+ }
266
+ /**
267
+ * Split a `pg_dumpall --globals-only` script into individual statements.
268
+ * Used when replaying globals on restore so each `CREATE ROLE` / `GRANT`
269
+ * can run independently and a benign "role already exists" on one doesn't
270
+ * abort the rest. Drops `--` comment lines and blank statements.
271
+ */
272
+ function splitGlobalsStatements(sql) {
273
+ return sql.split("\n").filter((line) => {
274
+ const trimmed = line.trim();
275
+ return !trimmed.startsWith("--") && !trimmed.startsWith("\\");
276
+ }).join("\n").split(";").map((s) => s.trim()).filter((s) => s.length > 0);
277
+ }
278
+ /**
279
+ * Resolve the Postgres connection string the backup commands should use,
280
+ * mirroring the precedence the branch command already relies on.
281
+ */
282
+ function resolveConnectionString(env) {
283
+ return env.DATABASE_URL || env.ADMIN_CONNECTION_STRING || null;
284
+ }
285
+ //#endregion
286
+ //#region src/backup/retention.ts
287
+ /**
288
+ * Retention pruning for scheduled backups. Pure logic — no I/O — so it can
289
+ * be exhaustively unit-tested without touching a storage backend.
290
+ */
291
+ /**
292
+ * Decide which backups to delete under the given retention policy.
293
+ *
294
+ * Rules, applied in order:
295
+ * 1. Objects whose key isn't a recognised rebase backup (no parseable
296
+ * timestamp and no `createdAt`) are never selected — foreign files in a
297
+ * shared bucket are left untouched.
298
+ * 2. The `keepMinimum` newest backups are always retained.
299
+ * 3. Of the remainder, any older than `retentionDays` are selected for
300
+ * deletion.
301
+ *
302
+ * Returns the keys to delete, oldest first.
303
+ */
304
+ function selectBackupsToPrune(backups, options) {
305
+ const retentionDays = options.retentionDays ?? 0;
306
+ const keepMinimum = Math.max(0, options.keepMinimum ?? 0);
307
+ const now = options.now ?? /* @__PURE__ */ new Date();
308
+ if (retentionDays <= 0) return [];
309
+ const dated = backups.map((b) => {
310
+ const createdAt = b.createdAt ?? parseBackupTimestamp(b.key);
311
+ return createdAt ? {
312
+ key: b.key,
313
+ createdAt
314
+ } : null;
315
+ }).filter((b) => b !== null);
316
+ dated.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
317
+ const cutoff = now.getTime() - retentionDays * 24 * 60 * 60 * 1e3;
318
+ const toDelete = dated.slice(keepMinimum).filter((b) => b.createdAt.getTime() < cutoff);
319
+ toDelete.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
320
+ return toDelete.map((b) => b.key);
321
+ }
322
+ //#endregion
323
+ //#region src/backup/backup-logic.ts
324
+ /**
325
+ * Pure-ish orchestration for the backup/restore paths, kept free of `execa`
326
+ * and `pg` value imports so it can be unit-tested under jest (the impure
327
+ * edges — spawning processes, opening connections — live in
328
+ * `backup-service.ts`, which is vitest/runtime only).
329
+ *
330
+ * The functions here take their side-effecting dependency as an argument
331
+ * (a statement runner, an object deleter) so tests can inject fakes.
332
+ */
333
+ /**
334
+ * Replay a `pg_dumpall --globals-only` script one statement at a time,
335
+ * tolerating per-statement failures. On a same-cluster restore the roles
336
+ * usually already exist (`CREATE ROLE` → "already exists") and on a managed
337
+ * provider an `ALTER ROLE <superuser>` may be refused; neither should abort
338
+ * recreation of the roles that *are* missing. Returns how many statements
339
+ * applied vs were skipped.
340
+ *
341
+ * `runStatement` executes one SQL statement and rejects on error.
342
+ */
343
+ async function applyGlobalsWith(runStatement, globalsSql, log = () => {}) {
344
+ let applied = 0;
345
+ let skipped = 0;
346
+ for (const statement of splitGlobalsStatements(globalsSql)) try {
347
+ await runStatement(statement);
348
+ applied++;
349
+ } catch (err) {
350
+ skipped++;
351
+ log(` • Skipped global: ${statement.split("\n")[0].slice(0, 80)} (${err instanceof Error ? err.message : String(err)})`);
352
+ }
353
+ return {
354
+ applied,
355
+ skipped
356
+ };
357
+ }
358
+ /**
359
+ * Delete each pruned dump together with its `.globals.sql` roles sidecar, so
360
+ * pruning never orphans the roles file. The sidecar is best-effort — older
361
+ * backups predate it, so a missing-sidecar failure is swallowed while a
362
+ * failure deleting the dump itself propagates.
363
+ *
364
+ * `deleteObject` removes one key and rejects if it cannot (e.g. not found).
365
+ */
366
+ async function pruneWith(keys, deleteObject) {
367
+ for (const key of keys) {
368
+ await deleteObject(key);
369
+ try {
370
+ await deleteObject(globalsFileForDump(key));
371
+ } catch {}
372
+ }
373
+ }
374
+ /**
375
+ * Remove a dump artifact abandoned by a failed tool run.
376
+ *
377
+ * `pg_dump` creates its `--file=` target before it finishes connecting, so any
378
+ * failure — a URL libpq rejects, a dropped connection, a full disk — leaves a
379
+ * 0-byte file behind. That corpse is not inert: `rebase db backups list` used
380
+ * to show it as an ordinary entry, and `selectBackupsToPrune` ranks by
381
+ * timestamp alone, so it occupies a protected `keepMinimum` slot and can push
382
+ * a real backup out of retention.
383
+ *
384
+ * Best-effort on purpose: the caller is already throwing, and a failed unlink
385
+ * must not replace the real diagnosis with an ENOENT/EPERM from the cleanup.
386
+ *
387
+ * Lives here rather than in `backup-service.ts` for the reason at the top of
388
+ * this file — that module's top-level `execa` import makes it unloadable under
389
+ * jest, so anything placed there cannot be unit-tested.
390
+ *
391
+ * `remove` deletes one file and throws if it cannot; `exists` reports presence.
392
+ */
393
+ function discardPartialDumpWith(exists, remove, file) {
394
+ try {
395
+ if (exists(file)) remove(file);
396
+ } catch {}
397
+ }
398
+ //#endregion
399
+ //#region src/backup/backup-service.ts
400
+ /**
401
+ * Backup / restore orchestration: thin, well-typed wrappers around
402
+ * `pg_dump` and `pg_restore`, plus binary detection, version pre-flight,
403
+ * and upload/prune against a storage backend.
404
+ *
405
+ * The pure argument- and policy-logic lives in `pg-tools.ts` and
406
+ * `retention.ts`; this module is the impure edge (spawns processes, talks
407
+ * to Postgres and storage) and is intentionally kept small.
408
+ */
409
+ var backup_service_exports = /* @__PURE__ */ __exportAll({
410
+ BackupToolError: () => BackupToolError,
411
+ applyGlobals: () => applyGlobals,
412
+ createDump: () => createDump,
413
+ detectToolMajor: () => detectToolMajor,
414
+ discardPartialDump: () => discardPartialDump,
415
+ ensureDatabaseExists: () => ensureDatabaseExists,
416
+ getServerVersionMajor: () => getServerVersionMajor,
417
+ listBackups: () => listBackups,
418
+ preflight: () => preflight,
419
+ pruneBackups: () => pruneBackups,
420
+ resolvePgBinary: () => resolvePgBinary,
421
+ restoreDump: () => restoreDump,
422
+ uploadBackup: () => uploadBackup,
423
+ validateDump: () => validateDump
424
+ });
425
+ /**
426
+ * Remove a dump artifact abandoned by a failed tool run. See
427
+ * {@link discardPartialDumpWith} for why this exists and why the logic lives
428
+ * in the execa-free module.
429
+ */
430
+ function discardPartialDump(file) {
431
+ discardPartialDumpWith((f) => fs.existsSync(f), (f) => fs.unlinkSync(f), file);
432
+ }
433
+ var BackupToolError = class extends Error {
434
+ hint;
435
+ constructor(message, hint) {
436
+ super(message);
437
+ this.hint = hint;
438
+ this.name = "BackupToolError";
439
+ }
440
+ };
441
+ /** Locate `pg_dump` / `pg_restore` / `pg_dumpall`, honouring an env override. */
442
+ function resolvePgBinary(tool, env = process.env) {
443
+ const overrideVar = tool === "pg_dump" ? env.PG_DUMP_PATH : tool === "pg_restore" ? env.PG_RESTORE_PATH : env.PG_DUMPALL_PATH;
444
+ if (overrideVar && fs.existsSync(overrideVar)) return overrideVar;
445
+ return resolveLocalBin(tool);
446
+ }
447
+ /** Run `<bin> --version` and extract the major version. */
448
+ async function detectToolMajor(bin) {
449
+ try {
450
+ const { stdout } = await execa(bin, ["--version"]);
451
+ return parsePgToolMajor(stdout);
452
+ } catch {
453
+ return null;
454
+ }
455
+ }
456
+ /** Query the server for its major version via `server_version_num`. */
457
+ async function getServerVersionMajor(connectionString) {
458
+ const { Client } = await import("pg");
459
+ const client = new Client({ connectionString });
460
+ await client.connect();
461
+ try {
462
+ const raw = (await client.query("SHOW server_version_num")).rows?.[0]?.server_version_num;
463
+ return serverVersionNumToMajor(raw);
464
+ } finally {
465
+ await client.end();
466
+ }
467
+ }
468
+ /**
469
+ * Verify the requested client tool exists and its major version is
470
+ * compatible with the live server. Throws {@link BackupToolError} — with a
471
+ * doctor-style hint — when the binary is missing.
472
+ */
473
+ async function preflight(tool, connectionString, env = process.env) {
474
+ const bin = resolvePgBinary(tool, env);
475
+ if (!bin) throw new BackupToolError(`Could not find the '${tool}' binary.`, `Install the PostgreSQL client tools (e.g. 'brew install libpq' or 'apt-get install postgresql-client'), or set ${tool === "pg_dump" ? "PG_DUMP_PATH" : "PG_RESTORE_PATH"} to its full path.`);
476
+ const [toolMajor, serverMajor] = await Promise.all([detectToolMajor(bin), getServerVersionMajor(connectionString)]);
477
+ return {
478
+ bin,
479
+ toolMajor,
480
+ serverMajor,
481
+ ...checkToolServerCompatibility(toolMajor, serverMajor)
482
+ };
483
+ }
484
+ /**
485
+ * Produce a custom-format dump on local disk. When `outDir` is omitted the
486
+ * file is written to the OS temp directory (used by the upload path, which
487
+ * cleans it up afterwards).
488
+ *
489
+ * Alongside the `-Fc` dump it writes a `<name>.globals.sql` sidecar via
490
+ * `pg_dumpall --globals-only` so the roles the dump's GRANT/RLS statements
491
+ * depend on can be recreated on restore. Set `includeGlobals: false` to skip
492
+ * it (e.g. when the caller has no privilege to read cluster globals).
493
+ */
494
+ async function createDump(opts) {
495
+ const env = opts.env ?? process.env;
496
+ const bin = resolvePgBinary("pg_dump", env);
497
+ if (!bin) throw new BackupToolError("Could not find the 'pg_dump' binary.", "Install the PostgreSQL client tools or set PG_DUMP_PATH.");
498
+ const fileName = opts.fileName ?? buildBackupFilename(opts.dbName);
499
+ const outDir = opts.outDir ?? fs.mkdtempSync(path.join(os.tmpdir(), "rebase-backup-"));
500
+ fs.mkdirSync(outDir, { recursive: true });
501
+ const localFile = path.join(outDir, fileName);
502
+ const args = buildPgDumpArgs({
503
+ connectionString: opts.connectionString,
504
+ outFile: localFile,
505
+ excludeSchemas: opts.excludeSchemas,
506
+ noOwner: opts.noOwner,
507
+ rowSecurity: opts.rowSecurity
508
+ });
509
+ const dumpEnv = { ...env };
510
+ if (opts.rowSecurity) dumpEnv.PGOPTIONS = [env.PGOPTIONS, buildRowSecurityPgOptions(opts.rowSecurity)].filter(Boolean).join(" ");
511
+ try {
512
+ await execa(bin, args, {
513
+ stdio: opts.inheritStdio ? "inherit" : "pipe",
514
+ env: dumpEnv
515
+ });
516
+ } catch (error) {
517
+ discardPartialDump(localFile);
518
+ const diagnosis = diagnoseRowSecurityDumpFailure(error);
519
+ if (!diagnosis) throw error;
520
+ throw new BackupToolError(diagnosis, "Run `rebase db backup --help` for the flag, and read what it says about partial dumps.");
521
+ }
522
+ const result = {
523
+ localFile,
524
+ fileName,
525
+ sizeBytes: fs.existsSync(localFile) ? fs.statSync(localFile).size : 0
526
+ };
527
+ if (opts.includeGlobals !== false) {
528
+ const dumpallBin = resolvePgBinary("pg_dumpall", env);
529
+ if (!dumpallBin) throw new BackupToolError("Could not find the 'pg_dumpall' binary needed to capture cluster roles.", "Install the PostgreSQL client tools or set PG_DUMPALL_PATH. To take a role-incomplete backup anyway, pass includeGlobals: false.");
530
+ const globalsFile = globalsFileForDump(localFile);
531
+ try {
532
+ await execa(dumpallBin, buildPgDumpallGlobalsArgs({
533
+ connectionString: opts.connectionString,
534
+ outFile: globalsFile
535
+ }), {
536
+ stdio: opts.inheritStdio ? "inherit" : "pipe",
537
+ env: { ...env }
538
+ });
539
+ } catch (error) {
540
+ discardPartialDump(globalsFile);
541
+ discardPartialDump(localFile);
542
+ throw error;
543
+ }
544
+ result.globalsFile = globalsFile;
545
+ result.globalsSizeBytes = fs.existsSync(globalsFile) ? fs.statSync(globalsFile).size : 0;
546
+ }
547
+ return result;
548
+ }
549
+ /**
550
+ * Cheap integrity check on a freshly written dump: it must be non-empty and
551
+ * `pg_restore --list` must parse its table of contents without error. Used
552
+ * before pruning older backups so a corrupt-but-exit-0 dump never becomes
553
+ * the reason the last good backup is deleted.
554
+ */
555
+ async function validateDump(localFile, env = process.env) {
556
+ if (!fs.existsSync(localFile)) return {
557
+ ok: false,
558
+ reason: `Dump file does not exist: ${localFile}`
559
+ };
560
+ if (fs.statSync(localFile).size === 0) return {
561
+ ok: false,
562
+ reason: "Dump file is empty (0 bytes)."
563
+ };
564
+ const bin = resolvePgBinary("pg_restore", env);
565
+ if (!bin) return {
566
+ ok: false,
567
+ reason: "Could not find 'pg_restore' to verify the dump."
568
+ };
569
+ try {
570
+ await execa(bin, buildPgRestoreListArgs(localFile), {
571
+ stdio: "pipe",
572
+ env: { ...env }
573
+ });
574
+ return { ok: true };
575
+ } catch (err) {
576
+ return {
577
+ ok: false,
578
+ reason: `pg_restore --list failed: ${err instanceof Error ? err.message : String(err)}`
579
+ };
580
+ }
581
+ }
582
+ /**
583
+ * Replay a `pg_dumpall --globals-only` script to recreate cluster roles
584
+ * before a restore, so the dump's GRANT/RLS statements (which reference
585
+ * `rebase_user` and any owner roles) actually apply. Runs statement by
586
+ * statement and tolerates per-statement failures — on a same-cluster restore
587
+ * the roles usually already exist (`CREATE ROLE` → "already exists"), and on
588
+ * a managed provider an `ALTER ROLE <superuser>` may be refused; neither
589
+ * should abort role recreation. Returns how many statements applied vs were
590
+ * skipped.
591
+ */
592
+ async function applyGlobals(connectionString, globalsSql, log = () => {}) {
593
+ const { Client } = await import("pg");
594
+ const client = new Client({ connectionString });
595
+ await client.connect();
596
+ try {
597
+ return await applyGlobalsWith(async (sql) => {
598
+ await client.query(sql);
599
+ }, globalsSql, log);
600
+ } finally {
601
+ await client.end();
602
+ }
603
+ }
604
+ /**
605
+ * Restore a custom-format dump into the database named by
606
+ * `connectionString`. Destructive when `clean` is set (drops objects
607
+ * first). Never called automatically — the CLI gates it behind explicit
608
+ * confirmation.
609
+ *
610
+ * Runs with `--exit-on-error` by default: a restore that logs-and-continues
611
+ * past a failed GRANT (because a role was missing) reports success with RLS
612
+ * un-enforced. Callers should recreate roles first (see {@link applyGlobals})
613
+ * and only set `exitOnError: false` deliberately.
614
+ */
615
+ async function restoreDump(opts) {
616
+ const env = opts.env ?? process.env;
617
+ const bin = resolvePgBinary("pg_restore", env);
618
+ if (!bin) throw new BackupToolError("Could not find the 'pg_restore' binary.", "Install the PostgreSQL client tools or set PG_RESTORE_PATH.");
619
+ await execa(bin, buildPgRestoreArgs({
620
+ connectionString: opts.connectionString,
621
+ inputFile: opts.inputFile,
622
+ clean: opts.clean,
623
+ noOwner: opts.noOwner,
624
+ exitOnError: opts.exitOnError
625
+ }), {
626
+ stdio: opts.inheritStdio ? "inherit" : "pipe",
627
+ env: { ...env }
628
+ });
629
+ }
630
+ /**
631
+ * Create a database (if absent) by connecting to the maintenance
632
+ * `postgres` database. Used by `restore --create-db`.
633
+ */
634
+ async function ensureDatabaseExists(adminConnectionString, dbName) {
635
+ const { Client } = await import("pg");
636
+ const parsed = new URL(adminConnectionString);
637
+ parsed.pathname = "/postgres";
638
+ const client = new Client({ connectionString: parsed.toString() });
639
+ await client.connect();
640
+ try {
641
+ const existing = await client.query("SELECT 1 FROM pg_database WHERE datname = $1", [dbName]);
642
+ if (existing.rowCount && existing.rowCount > 0) return false;
643
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(dbName)) throw new BackupToolError(`Invalid database name: "${dbName}"`);
644
+ await client.query(`CREATE DATABASE "${dbName}"`);
645
+ return true;
646
+ } finally {
647
+ await client.end();
648
+ }
649
+ }
650
+ /**
651
+ * Upload a local dump to object storage under the destination's prefix.
652
+ * Backups may contain secrets/PII, so the object is written with a
653
+ * private/octet-stream content type; bucket-level ACLs must stay private.
654
+ */
655
+ async function uploadBackup(storage, localFile, dest) {
656
+ const fileName = path.basename(localFile);
657
+ const key = joinStorageKey(dest.prefix, fileName);
658
+ const buffer = fs.readFileSync(localFile);
659
+ const file = new File([buffer], fileName, { type: "application/octet-stream" });
660
+ return {
661
+ key,
662
+ storageUrl: (await storage.putObject({
663
+ file,
664
+ key,
665
+ bucket: dest.bucket,
666
+ metadata: { "rebase-backup": "1" }
667
+ })).storageUrl
668
+ };
669
+ }
670
+ /**
671
+ * List existing backups at a destination. For local destinations reads the
672
+ * directory; for object storage lists the prefix via the controller.
673
+ */
674
+ async function listBackups(dest, storage) {
675
+ if (dest.kind === "local") {
676
+ if (!fs.existsSync(dest.path)) return [];
677
+ const dir = fs.statSync(dest.path).isDirectory() ? dest.path : path.dirname(dest.path);
678
+ return fs.readdirSync(dir).filter((f) => f.endsWith(".dump")).map((f) => {
679
+ const full = path.join(dir, f);
680
+ const stats = fs.statSync(full);
681
+ return {
682
+ key: full,
683
+ createdAt: parseBackupTimestamp(f) ?? stats.mtime,
684
+ sizeBytes: stats.size
685
+ };
686
+ }).sort((a, b) => (b.createdAt?.getTime() ?? 0) - (a.createdAt?.getTime() ?? 0));
687
+ }
688
+ if (!storage) throw new BackupToolError(`Listing ${dest.kind} backups requires a configured storage backend.`);
689
+ return (await storage.listObjects(dest.prefix ? `${dest.prefix}/` : "", {
690
+ bucket: dest.bucket,
691
+ maxResults: 1e3
692
+ })).items.map((item) => item.fullPath).filter((key) => key.endsWith(".dump")).map((key) => ({
693
+ key,
694
+ createdAt: parseBackupTimestamp(key) ?? void 0
695
+ })).sort((a, b) => (b.createdAt?.getTime() ?? 0) - (a.createdAt?.getTime() ?? 0));
696
+ }
697
+ /**
698
+ * Apply a retention policy to a destination, deleting the backups selected
699
+ * by {@link selectBackupsToPrune}. Returns the keys that were removed.
700
+ */
701
+ async function pruneBackups(dest, options, storage) {
702
+ const toDelete = selectBackupsToPrune(await listBackups(dest, storage), options);
703
+ await pruneWith(toDelete, dest.kind === "local" ? async (key) => {
704
+ if (!fs.existsSync(key)) throw new Error(`not found: ${key}`);
705
+ fs.unlinkSync(key);
706
+ } : async (key) => {
707
+ if (!storage) throw new BackupToolError("Storage backend required to prune object backups.");
708
+ await storage.deleteObject(key, dest.bucket);
709
+ });
710
+ return toDelete;
711
+ }
712
+ //#endregion
713
+ export { parsePgToolMajor as A, checkToolServerCompatibility as C, parseBackupDestination as D, joinStorageKey as E, serverVersionNumToMajor as M, splitGlobalsStatements as N, parseBackupTimestamp as O, withDatabaseName as P, buildRowSecurityPgOptions as S, globalsFileForDump as T, buildBackupFilename as _, detectToolMajor as a, buildPgRestoreArgs as b, getServerVersionMajor as c, pruneBackups as d, resolvePgBinary as f, selectBackupsToPrune as g, validateDump as h, createDump as i, resolveConnectionString as j, parseDbNameFromUrl as k, listBackups as l, uploadBackup as m, applyGlobals as n, discardPartialDump as o, restoreDump as p, backup_service_exports as r, ensureDatabaseExists as s, BackupToolError as t, preflight as u, buildPgDumpArgs as v, diagnoseRowSecurityDumpFailure as w, buildPgRestoreListArgs as x, buildPgDumpallGlobalsArgs as y };
714
+
715
+ //# sourceMappingURL=backup-service-Br3tqwsy.js.map