@rebasepro/server-postgres 0.12.1-canary.gdfba2a1 → 0.12.1-canary.ge1bb178

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 (87) hide show
  1. package/dist/PostgresBackendDriver.d.ts +1 -1
  2. package/dist/PostgresBootstrapper.d.ts +25 -1
  3. package/dist/auth/services.d.ts +6 -1
  4. package/dist/backup/backup-service.d.ts +10 -1
  5. package/dist/backup/pg-tools.d.ts +47 -0
  6. package/dist/{backup-service-DH9kPg-E.js → backup-service-CD8o_1Sl.js} +144 -11
  7. package/dist/backup-service-CD8o_1Sl.js.map +1 -0
  8. package/dist/cli-helpers.d.ts +39 -0
  9. package/dist/{connection-B5Wndbr1.js → connection-BuZ97wsr.js} +57 -3
  10. package/dist/connection-BuZ97wsr.js.map +1 -0
  11. package/dist/connection.d.ts +42 -0
  12. package/dist/ensure-collection-policies-BrUVgjz3.js +57 -0
  13. package/dist/ensure-collection-policies-BrUVgjz3.js.map +1 -0
  14. package/dist/ensure-collection-tables-Da2oGkX2.js +650 -0
  15. package/dist/ensure-collection-tables-Da2oGkX2.js.map +1 -0
  16. package/dist/index.es.js +529 -142
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/policy-CeA1JcxP.js +105 -0
  19. package/dist/policy-CeA1JcxP.js.map +1 -0
  20. package/dist/schema/ensure-collection-policies.d.ts +60 -0
  21. package/dist/schema/ensure-collection-tables.d.ts +44 -2
  22. package/dist/schema/generate-postgres-ddl-logic.d.ts +135 -1
  23. package/dist/schema/introspect-db-constraints.d.ts +57 -0
  24. package/dist/schema/introspect-db-logic.d.ts +94 -5
  25. package/dist/schema/introspect-db-queries.d.ts +119 -0
  26. package/dist/schema/introspect-db-structure.d.ts +263 -0
  27. package/dist/schema/introspect-db-types.d.ts +11 -0
  28. package/dist/services/FetchService.d.ts +4 -1
  29. package/dist/services/RelationService.d.ts +24 -1
  30. package/dist/services/channel-bus/index.d.ts +1 -7
  31. package/dist/services/collection-helpers.d.ts +24 -1
  32. package/dist/services/dataService.d.ts +3 -1
  33. package/dist/services/row-pipeline.d.ts +1 -1
  34. package/dist/{src-DihrDFuP.js → src-CzbghKwf.js} +189 -101
  35. package/dist/src-CzbghKwf.js.map +1 -0
  36. package/dist/utils/connection-string.d.ts +29 -0
  37. package/dist/utils/drizzle-conditions.d.ts +5 -4
  38. package/dist/utils/pg-error-utils.d.ts +19 -0
  39. package/dist/{websocket-BKcGvILX.js → websocket-B2LsrINK.js} +8 -6
  40. package/dist/websocket-B2LsrINK.js.map +1 -0
  41. package/package.json +6 -6
  42. package/src/PostgresAdapter.ts +21 -2
  43. package/src/PostgresBackendDriver.ts +4 -0
  44. package/src/PostgresBootstrapper.ts +192 -33
  45. package/src/auth/services.ts +6 -3
  46. package/src/backup/backup-cli.ts +41 -2
  47. package/src/backup/backup-service.ts +38 -5
  48. package/src/backup/pg-tools.ts +96 -3
  49. package/src/cli-helpers.ts +70 -0
  50. package/src/cli.ts +44 -26
  51. package/src/collections/validate-relations.ts +15 -0
  52. package/src/connection.ts +73 -0
  53. package/src/data-transformer.ts +9 -3
  54. package/src/databasePoolManager.ts +5 -2
  55. package/src/schema/ensure-collection-policies.ts +105 -0
  56. package/src/schema/ensure-collection-tables.test.ts +105 -9
  57. package/src/schema/ensure-collection-tables.ts +220 -32
  58. package/src/schema/generate-drizzle-schema-logic.ts +16 -3
  59. package/src/schema/generate-postgres-ddl-logic.ts +375 -16
  60. package/src/schema/introspect-db-constraints.ts +385 -0
  61. package/src/schema/introspect-db-inference.ts +18 -8
  62. package/src/schema/introspect-db-logic.ts +385 -71
  63. package/src/schema/introspect-db-queries.ts +326 -0
  64. package/src/schema/introspect-db-structure.ts +670 -0
  65. package/src/schema/introspect-db-types.ts +56 -0
  66. package/src/schema/introspect-db.ts +37 -80
  67. package/src/schema/introspect-runtime.test.ts +56 -8
  68. package/src/schema/introspect-runtime.ts +31 -9
  69. package/src/security/policy-drift.test.ts +11 -3
  70. package/src/services/FetchService.ts +76 -14
  71. package/src/services/PersistService.ts +20 -6
  72. package/src/services/RelationService.ts +249 -48
  73. package/src/services/channel-bus/index.ts +0 -9
  74. package/src/services/collection-helpers.ts +40 -1
  75. package/src/services/dataService.ts +3 -1
  76. package/src/services/realtimeService.ts +3 -3
  77. package/src/services/row-pipeline.ts +1 -1
  78. package/src/utils/connection-string.ts +58 -0
  79. package/src/utils/drizzle-conditions.ts +31 -6
  80. package/src/utils/pg-error-utils.ts +46 -0
  81. package/src/websocket.ts +18 -9
  82. package/dist/backup-service-DH9kPg-E.js.map +0 -1
  83. package/dist/connection-B5Wndbr1.js.map +0 -1
  84. package/dist/ensure-collection-tables-CIHSH962.js +0 -304
  85. package/dist/ensure-collection-tables-CIHSH962.js.map +0 -1
  86. package/dist/src-DihrDFuP.js.map +0 -1
  87. package/dist/websocket-BKcGvILX.js.map +0 -1
@@ -105,7 +105,7 @@ export declare class PostgresBackendDriver implements DataDriver {
105
105
  delete<M extends Record<string, unknown>>({ row, collection }: DeleteProps<M>): Promise<void>;
106
106
  deleteAll(path: string): Promise<void>;
107
107
  checkUniqueField(path: string, name: string, value: unknown, id?: string, collection?: CollectionConfig): Promise<boolean>;
108
- count<M extends Record<string, unknown>>({ path, collection, filter, searchString }: FetchCollectionProps<M>): Promise<number>;
108
+ count<M extends Record<string, unknown>>({ path, collection, filter, logical, searchString }: FetchCollectionProps<M>): Promise<number>;
109
109
  private getTargetDb;
110
110
  executeSql(sqlText: string, options?: {
111
111
  database?: string;
@@ -4,7 +4,7 @@
4
4
  * Implements the `BackendBootstrapper` interface for PostgreSQL.
5
5
  */
6
6
  import { NodePgDatabase } from "drizzle-orm/node-postgres";
7
- import { BackendBootstrapper, type RealtimeChannelsConfig } from "@rebasepro/types";
7
+ import { BackendBootstrapper, CollectionConfig, type RealtimeChannelsConfig } from "@rebasepro/types";
8
8
  import { PostgresBackendDriver } from "./PostgresBackendDriver";
9
9
  import { RealtimeService } from "./services/realtimeService";
10
10
  import { DatabasePoolManager } from "./databasePoolManager";
@@ -65,6 +65,30 @@ export interface PostgresDriverInternals {
65
65
  */
66
66
  provisionCdcForTables?: (tables: CdcTableRef[]) => Promise<void>;
67
67
  }
68
+ /**
69
+ * Which table name the boot-time drift check should look for, for one collection.
70
+ *
71
+ * A declared `table` IS the table name, not a hint to be second-guessed. This
72
+ * used to ask the registry whether it had indexed the declared name and fall
73
+ * back to the SLUG when it had not — but "the registry does not know this table"
74
+ * is exactly the condition the drift check exists to report, so the fallback
75
+ * fired precisely when it was most harmful.
76
+ *
77
+ * A collection with `slug: "usage-daily", table: "usage_daily"` was reported as
78
+ * missing table `usage-daily`: a name that does not exist, should never exist,
79
+ * and that nobody can find by looking. Worse, the remediation the caller prints
80
+ * says to run `rebase db push` — which would then CREATE that invented table
81
+ * beside the correct one, the same "second copy" hazard the misplaced-schema
82
+ * branch further down exists to prevent. Seen in production, where a correctly
83
+ * migrated database reported drift on every boot.
84
+ *
85
+ * The slug is used only when nothing was declared, which is the config shape
86
+ * where the slug genuinely is the table name.
87
+ *
88
+ * Exported for its own test: the caller needs a live pool and a real database,
89
+ * and this is the part that was wrong.
90
+ */
91
+ export declare function resolveDriftCheckName(col: CollectionConfig, registeredTableNames: string[]): string;
68
92
  /**
69
93
  * Default PostgreSQL bootstrapper.
70
94
  *
@@ -23,8 +23,13 @@ export interface AuthSchemaTables {
23
23
  *
24
24
  * Whitespace goes too: a trailing space survives the fold and reproduces the
25
25
  * problem exactly.
26
+ *
27
+ * Re-exported rather than defined here: `@rebasepro/server` and
28
+ * `@rebasepro/server-mongo` write this column too, and a second copy of this
29
+ * rule is the defect it exists to prevent.
26
30
  */
27
- export declare function normalizeEmail<T>(email: T): T | string;
31
+ import { normalizeEmail } from "@rebasepro/common";
32
+ export { normalizeEmail };
28
33
  /**
29
34
  * PostgreSQL implementation of UserRepository.
30
35
  * Handles all user-related database operations using Drizzle ORM.
@@ -1,5 +1,5 @@
1
1
  import type { StorageController } from "@rebasepro/server";
2
- import { BackupDestination, VersionCompatibility } from "./pg-tools";
2
+ import { BackupDestination, type RowSecurityIdentity, VersionCompatibility } from "./pg-tools";
3
3
  import { BackupObject, RetentionOptions } from "./retention";
4
4
  export declare class BackupToolError extends Error {
5
5
  readonly hint?: string | undefined;
@@ -54,6 +54,15 @@ export declare function createDump(opts: {
54
54
  inheritStdio?: boolean;
55
55
  includeGlobals?: boolean;
56
56
  env?: Record<string, string | undefined>;
57
+ /**
58
+ * Dump with row security left on, reading as this identity.
59
+ *
60
+ * The escape hatch for a managed Postgres, where the dumping role owns
61
+ * nothing and has no `BYPASSRLS`. Off by default, and deliberately so: with
62
+ * row security on, `pg_dump` stops erroring on rows it cannot see and
63
+ * simply omits them. See {@link RowSecurityIdentity}.
64
+ */
65
+ rowSecurity?: RowSecurityIdentity;
57
66
  }): Promise<BackupResult>;
58
67
  /**
59
68
  * Cheap integrity check on a freshly written dump: it must be non-empty and
@@ -79,6 +79,36 @@ export declare function parseBackupDestination(out: string): BackupDestination;
79
79
  * doubled slash.
80
80
  */
81
81
  export declare function joinStorageKey(prefix: string, fileName: string): string;
82
+ /**
83
+ * The identity `pg_dump` reads rows as, when row security is left on.
84
+ *
85
+ * Not optional, and that is the whole design. `pg_dump --enable-row-security`
86
+ * on its own is the dangerous command in this file: it turns the "query would
87
+ * be affected by row-level security policy" *error* into a dump that exits 0
88
+ * and is silently missing every row the dumping role's policies exclude. A
89
+ * backup that looks fine and restores most of your data is worse than one that
90
+ * refused to run.
91
+ *
92
+ * So the flag is unreachable without a subject to evaluate the policies
93
+ * against. Rebase's generated policies read `app.uid` and `app.user_roles`;
94
+ * supplying an admin role satisfies the `admin_full_access` rule and the dump
95
+ * sees everything that rule sees.
96
+ */
97
+ export interface RowSecurityIdentity {
98
+ /** Written to `app.uid`. Any non-empty value — it is only an audit trail. */
99
+ uid: string;
100
+ /** Written to `app.user_roles`. Must include a role the policies admit. */
101
+ roles: string[];
102
+ }
103
+ /**
104
+ * `PGOPTIONS` carrying an identity, for a libpq tool that has no other way to
105
+ * set a GUC.
106
+ *
107
+ * A backslash escape rather than quoting, which is what libpq's `-c` parsing
108
+ * takes: a space inside a value ends the option otherwise, so a role list is
109
+ * comma-joined and never spaced.
110
+ */
111
+ export declare function buildRowSecurityPgOptions(identity: RowSecurityIdentity): string;
82
112
  /**
83
113
  * Assemble the `pg_dump` argument vector. Uses the custom format (`-Fc`),
84
114
  * which is compressed and restorable selectively via `pg_restore`.
@@ -90,7 +120,24 @@ export declare function buildPgDumpArgs(opts: {
90
120
  excludeSchemas?: string[];
91
121
  /** Number of parallel jobs (directory format only; ignored for -Fc). */
92
122
  noOwner?: boolean;
123
+ /**
124
+ * Dump with row security on, as this identity. Omit — which is the default
125
+ * — and `pg_dump` errors rather than skipping rows it cannot see.
126
+ */
127
+ rowSecurity?: RowSecurityIdentity;
93
128
  }): string[];
129
+ /**
130
+ * Whether a `pg_dump` failure is the row-security one, and what to do about it.
131
+ *
132
+ * The error text names the table and nothing else, so the first read of it is
133
+ * "why would a backup be affected by RLS at all?" — the answer being that the
134
+ * dumping role is not the tables' owner and has no `BYPASSRLS`, which is the
135
+ * normal state of the `postgres` user on Cloud SQL, RDS and every other managed
136
+ * Postgres. Nothing about that is visible from the message.
137
+ *
138
+ * Returns `null` for any other failure, so the caller reports it unchanged.
139
+ */
140
+ export declare function diagnoseRowSecurityDumpFailure(error: unknown): string | null;
94
141
  /**
95
142
  * Assemble the `pg_restore` argument vector for a custom-format dump.
96
143
  */
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "module";
2
2
  import process from "process";
3
3
  __createRequire(import.meta.url);
4
- import { c as __require, l as __toESM, o as __commonJSMin, s as __exportAll } from "./connection-B5Wndbr1.js";
4
+ import { c as __exportAll, l as __require, s as __commonJSMin, u as __toESM } from "./connection-BuZ97wsr.js";
5
5
  import "./src-DoU9yPqq.js";
6
6
  import "@rebasepro/server";
7
7
  import fs from "fs";
@@ -23,9 +23,72 @@ import { appendFileSync, createReadStream, createWriteStream, readFileSync, stat
23
23
  import { finished } from "node:stream/promises";
24
24
  import { Duplex, PassThrough, Readable, Transform, Writable, getDefaultHighWaterMark } from "node:stream";
25
25
  import { Buffer as Buffer$1 } from "node:buffer";
26
+ import "module";
26
27
  import { fileURLToPath as fileURLToPath$1 } from "url";
28
+ //#region src/utils/connection-string.ts
29
+ /**
30
+ * Connection-string rewrites for the tools Rebase shells out to.
31
+ *
32
+ * Pure and dependency-free: `pg-tools` builds argument vectors without a live
33
+ * server, and these have to be usable from there.
34
+ */
35
+ /**
36
+ * The `sslmode` values libpq accepts. `no-verify` is conspicuously not one.
37
+ */
38
+ var LIBPQ_SSLMODES = /* @__PURE__ */ new Set([
39
+ "disable",
40
+ "allow",
41
+ "prefer",
42
+ "require",
43
+ "verify-ca",
44
+ "verify-full"
45
+ ]);
46
+ /**
47
+ * Make a connection string safe to hand to a libpq program.
48
+ *
49
+ * `sslmode=no-verify` is a node-postgres convention — encrypt, but do not check
50
+ * the certificate — and libpq does not have it. It does not degrade or warn:
51
+ *
52
+ * psql: error: invalid sslmode value: "no-verify"
53
+ *
54
+ * which means a `DATABASE_URL` that works perfectly for the app makes `psql`,
55
+ * `pg_dump`, `pg_restore` and Atlas all refuse to start, with an error that
56
+ * points at the value rather than at the convention it comes from. It has cost
57
+ * this project time more than once.
58
+ *
59
+ * `require` is the honest translation: libpq's `require` encrypts and does not
60
+ * verify the certificate either, which is exactly what `no-verify` asks for.
61
+ * Nothing is relaxed by the rewrite — `verify-ca` and `verify-full` are left
62
+ * alone, so a connection string that asked for verification still gets it.
63
+ *
64
+ * Only `sslmode` is touched, and only when it is a value libpq would reject.
65
+ * Anything unparseable is returned as given: a connection that works
66
+ * unverified beats one this corrupted.
67
+ */
68
+ function forLibpq(connectionString) {
69
+ let url;
70
+ try {
71
+ url = new URL(connectionString);
72
+ } catch {
73
+ return connectionString;
74
+ }
75
+ if (url.protocol !== "postgres:" && url.protocol !== "postgresql:") return connectionString;
76
+ const sslmode = url.searchParams.get("sslmode");
77
+ if (sslmode === null || LIBPQ_SSLMODES.has(sslmode)) return connectionString;
78
+ url.searchParams.set("sslmode", "require");
79
+ url.search = Array.from(url.searchParams.entries()).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
80
+ return url.toString();
81
+ }
82
+ //#endregion
27
83
  //#region src/backup/pg-tools.ts
28
84
  /**
85
+ * Pure helpers for the backup/restore commands.
86
+ *
87
+ * Everything in this file is side-effect free so it can be unit-tested
88
+ * without a live Postgres server, matching the constraint that CI must
89
+ * not require a database.
90
+ */
91
+ /**
29
92
  * Extract the database name from a Postgres connection string.
30
93
  * Returns `null` when the URL has no database path (e.g. bare host).
31
94
  */
@@ -155,6 +218,22 @@ function joinStorageKey(prefix, fileName) {
155
218
  return clean.length > 0 ? `${clean}/${fileName}` : fileName;
156
219
  }
157
220
  /**
221
+ * `PGOPTIONS` carrying an identity, for a libpq tool that has no other way to
222
+ * set a GUC.
223
+ *
224
+ * A backslash escape rather than quoting, which is what libpq's `-c` parsing
225
+ * takes: a space inside a value ends the option otherwise, so a role list is
226
+ * comma-joined and never spaced.
227
+ */
228
+ function buildRowSecurityPgOptions(identity) {
229
+ const escape = (value) => value.replace(/([\\ ])/g, "\\$1");
230
+ return [
231
+ `-c app.uid=${escape(identity.uid)}`,
232
+ `-c app.user_id=${escape(identity.uid)}`,
233
+ `-c app.user_roles=${escape(identity.roles.join(","))}`
234
+ ].join(" ");
235
+ }
236
+ /**
158
237
  * Assemble the `pg_dump` argument vector. Uses the custom format (`-Fc`),
159
238
  * which is compressed and restorable selectively via `pg_restore`.
160
239
  */
@@ -165,18 +244,56 @@ function buildPgDumpArgs(opts) {
165
244
  `--file=${opts.outFile}`
166
245
  ];
167
246
  if (opts.noOwner) args.push("--no-owner");
247
+ if (opts.rowSecurity) args.push("--enable-row-security");
168
248
  for (const schema of opts.excludeSchemas ?? []) args.push(`--exclude-schema=${schema}`);
169
- args.push(opts.connectionString);
249
+ args.push(forLibpq(opts.connectionString));
170
250
  return args;
171
251
  }
172
252
  /**
253
+ * Whether a `pg_dump` failure is the row-security one, and what to do about it.
254
+ *
255
+ * The error text names the table and nothing else, so the first read of it is
256
+ * "why would a backup be affected by RLS at all?" — the answer being that the
257
+ * dumping role is not the tables' owner and has no `BYPASSRLS`, which is the
258
+ * normal state of the `postgres` user on Cloud SQL, RDS and every other managed
259
+ * Postgres. Nothing about that is visible from the message.
260
+ *
261
+ * Returns `null` for any other failure, so the caller reports it unchanged.
262
+ */
263
+ function diagnoseRowSecurityDumpFailure(error) {
264
+ const text = [error?.stderr, error?.message].map((part) => typeof part === "string" ? part : "").join("\n");
265
+ if (!/row-level security policy/i.test(text)) return null;
266
+ const table = text.match(/for table "([^"]+)"/)?.[1];
267
+ return [
268
+ `pg_dump cannot read ${table ? `"${table}"` : "one of the tables"} because row-level security applies to it.`,
269
+ "",
270
+ " The dumping role is neither the table's owner nor `BYPASSRLS`, which is the normal",
271
+ " state of the `postgres` user on Cloud SQL, RDS and other managed Postgres — there is",
272
+ " no superuser to hand out.",
273
+ "",
274
+ " Two ways out:",
275
+ "",
276
+ " • Grant the dumping role BYPASSRLS, or make it the owner, and run this again. The",
277
+ " dump then contains every row, which is what a backup should mean.",
278
+ "",
279
+ " • Re-run with --enable-row-security to dump as an admin subject instead. Rebase",
280
+ " sets `app.uid`/`app.user_roles` so the generated `admin_full_access` policy",
281
+ " admits the dump. Read the warning it prints: the result contains exactly the",
282
+ " rows those policies admit, and any table whose policies do not include an",
283
+ " admin rule comes out short — with no error.",
284
+ "",
285
+ " Do not reach for a bare `pg_dump --enable-row-security` by hand. Without the",
286
+ " settings above it succeeds and silently omits rows."
287
+ ].join("\n");
288
+ }
289
+ /**
173
290
  * Assemble the `pg_restore` argument vector for a custom-format dump.
174
291
  */
175
292
  function buildPgRestoreArgs(opts) {
176
293
  const args = [
177
294
  "--format=custom",
178
295
  "--no-password",
179
- `--dbname=${opts.connectionString}`
296
+ `--dbname=${forLibpq(opts.connectionString)}`
180
297
  ];
181
298
  if (opts.clean) args.push("--clean", "--if-exists");
182
299
  if (opts.noOwner) args.push("--no-owner");
@@ -209,7 +326,7 @@ function buildPgDumpallGlobalsArgs(opts) {
209
326
  "--no-role-passwords",
210
327
  "--no-password",
211
328
  `--file=${opts.outFile}`,
212
- `--dbname=${opts.connectionString}`
329
+ `--dbname=${forLibpq(opts.connectionString)}`
213
330
  ];
214
331
  }
215
332
  /**
@@ -6446,6 +6563,11 @@ createExeca(mapNode);
6446
6563
  createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
6447
6564
  var { sendMessage, getOneMessage, getEachMessage, getCancelSignal } = getIpcExport();
6448
6565
  //#endregion
6566
+ //#region __vite-browser-external
6567
+ var require___vite_browser_external = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6568
+ module.exports = {};
6569
+ }));
6570
+ //#endregion
6449
6571
  //#region ../../node_modules/.pnpm/color-name@1.1.4/node_modules/color-name/index.js
6450
6572
  var require_color_name = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6451
6573
  module.exports = {
@@ -8495,6 +8617,7 @@ var require_source = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8495
8617
  chalk.stderr.supportsColor = stderrColor;
8496
8618
  module.exports = chalk;
8497
8619
  }));
8620
+ require___vite_browser_external();
8498
8621
  require_source();
8499
8622
  var moduleDir = path.dirname(fileURLToPath$1(import.meta.url));
8500
8623
  //#endregion
@@ -8669,15 +8792,25 @@ async function createDump(opts) {
8669
8792
  const outDir = opts.outDir ?? fs.mkdtempSync(path.join(os.tmpdir(), "rebase-backup-"));
8670
8793
  fs.mkdirSync(outDir, { recursive: true });
8671
8794
  const localFile = path.join(outDir, fileName);
8672
- await execa(bin, buildPgDumpArgs({
8795
+ const args = buildPgDumpArgs({
8673
8796
  connectionString: opts.connectionString,
8674
8797
  outFile: localFile,
8675
8798
  excludeSchemas: opts.excludeSchemas,
8676
- noOwner: opts.noOwner
8677
- }), {
8678
- stdio: opts.inheritStdio ? "inherit" : "pipe",
8679
- env: { ...env }
8799
+ noOwner: opts.noOwner,
8800
+ rowSecurity: opts.rowSecurity
8680
8801
  });
8802
+ const dumpEnv = { ...env };
8803
+ if (opts.rowSecurity) dumpEnv.PGOPTIONS = [env.PGOPTIONS, buildRowSecurityPgOptions(opts.rowSecurity)].filter(Boolean).join(" ");
8804
+ try {
8805
+ await execa(bin, args, {
8806
+ stdio: opts.inheritStdio ? "inherit" : "pipe",
8807
+ env: dumpEnv
8808
+ });
8809
+ } catch (error) {
8810
+ const diagnosis = diagnoseRowSecurityDumpFailure(error);
8811
+ if (!diagnosis) throw error;
8812
+ throw new BackupToolError(diagnosis, "Run `rebase db backup --help` for the flag, and read what it says about partial dumps.");
8813
+ }
8681
8814
  const result = {
8682
8815
  localFile,
8683
8816
  fileName,
@@ -8861,6 +8994,6 @@ async function pruneBackups(dest, options, storage) {
8861
8994
  return toDelete;
8862
8995
  }
8863
8996
  //#endregion
8864
- export { serverVersionNumToMajor as A, globalsFileForDump as C, parseDbNameFromUrl as D, parseBackupTimestamp as E, withDatabaseName as M, parsePgToolMajor as O, checkToolServerCompatibility as S, parseBackupDestination as T, buildBackupFilename as _, detectToolMajor as a, buildPgRestoreArgs as b, listBackups as c, resolvePgBinary as d, restoreDump as f, selectBackupsToPrune as g, require_source as h, createDump as i, splitGlobalsStatements as j, resolveConnectionString as k, preflight as l, validateDump as m, applyGlobals as n, ensureDatabaseExists as o, uploadBackup as p, backup_service_exports as r, getServerVersionMajor as s, BackupToolError as t, pruneBackups as u, buildPgDumpArgs as v, joinStorageKey as w, buildPgRestoreListArgs as x, buildPgDumpallGlobalsArgs as y };
8997
+ 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, listBackups as c, resolvePgBinary as d, restoreDump as f, selectBackupsToPrune as g, require_source as h, createDump as i, resolveConnectionString as j, parseDbNameFromUrl as k, preflight as l, validateDump as m, applyGlobals as n, ensureDatabaseExists as o, uploadBackup as p, backup_service_exports as r, getServerVersionMajor as s, BackupToolError as t, pruneBackups as u, buildPgDumpArgs as v, diagnoseRowSecurityDumpFailure as w, buildPgRestoreListArgs as x, buildPgDumpallGlobalsArgs as y };
8865
8998
 
8866
- //# sourceMappingURL=backup-service-DH9kPg-E.js.map
8999
+ //# sourceMappingURL=backup-service-CD8o_1Sl.js.map