@rebasepro/server-postgres 0.25.0-canary.ge06257e → 0.25.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 (126) hide show
  1. package/dist/{BranchService-DNg4txyf.js → BranchService-ClklxyAQ.js} +283 -20
  2. package/dist/BranchService-ClklxyAQ.js.map +1 -0
  3. package/dist/backup/backup-cli.d.ts +70 -1
  4. package/dist/backup/backup-service.d.ts +79 -0
  5. package/dist/backup/pg-binary.d.ts +2 -2
  6. package/dist/backup/pg-tools.d.ts +60 -1
  7. package/dist/backup-cli-gijeXe0u.js +1961 -0
  8. package/dist/backup-cli-gijeXe0u.js.map +1 -0
  9. package/dist/{boot-ddl-Dnvpmm_T.js → boot-ddl-DYH95Qeg.js} +3 -3
  10. package/dist/{boot-ddl-Dnvpmm_T.js.map → boot-ddl-DYH95Qeg.js.map} +1 -1
  11. package/dist/branch-argv.d.ts +15 -0
  12. package/dist/branch-prune.d.ts +18 -0
  13. package/dist/{cli-console-C_ISGwJo.js → cli-console-CQrQ0lAY.js} +19 -13
  14. package/dist/cli-console-CQrQ0lAY.js.map +1 -0
  15. package/dist/cli-console.d.ts +4 -3
  16. package/dist/{cli-errors-mx4sSjB8.js → cli-errors-DiA0XFIS.js} +110 -14
  17. package/dist/{cli-errors-mx4sSjB8.js.map → cli-errors-DiA0XFIS.js.map} +1 -1
  18. package/dist/cli-errors.d.ts +26 -1
  19. package/dist/cli-flags.d.ts +51 -0
  20. package/dist/{cli-prompt-egtNKkZl.js → cli-prompt-DXG0yk-h.js} +39 -4
  21. package/dist/{cli-prompt-egtNKkZl.js.map → cli-prompt-DXG0yk-h.js.map} +1 -1
  22. package/dist/cli.js +120 -184
  23. package/dist/cli.js.map +1 -1
  24. package/dist/collections/validate-relations.d.ts +8 -2
  25. package/dist/{column-plan-helpers-D_V4oaZh.js → column-plan-helpers-IG6uFb1s.js} +2 -2
  26. package/dist/{column-plan-helpers-D_V4oaZh.js.map → column-plan-helpers-IG6uFb1s.js.map} +1 -1
  27. package/dist/{connection-C938nR3E.js → connection-czvI7TZL.js} +57 -10
  28. package/dist/connection-czvI7TZL.js.map +1 -0
  29. package/dist/{databasePoolManager-Yqdw14wY.js → databasePoolManager-3stMNFL-.js} +4 -6
  30. package/dist/databasePoolManager-3stMNFL-.js.map +1 -0
  31. package/dist/db-command-line.d.ts +14 -0
  32. package/dist/{rls-bootstrap-sql-Bd-hJk08.js → db-subcommands-BPoHCxJR.js} +455 -3
  33. package/dist/db-subcommands-BPoHCxJR.js.map +1 -0
  34. package/dist/db-subcommands.d.ts +11 -0
  35. package/dist/{deferred-index-build-Ca6OqKyR.js → deferred-index-build-BE0I6sYU.js} +8 -8
  36. package/dist/{deferred-index-build-Ca6OqKyR.js.map → deferred-index-build-BE0I6sYU.js.map} +1 -1
  37. package/dist/{doctor-CJyuhV1n.js → doctor-BT--1kq3.js} +107 -11
  38. package/dist/doctor-BT--1kq3.js.map +1 -0
  39. package/dist/{ensure-collection-policies-C1ux3V_z.js → ensure-collection-policies-BnGOURpG.js} +60 -11
  40. package/dist/ensure-collection-policies-BnGOURpG.js.map +1 -0
  41. package/dist/{ensure-collection-tables-Do-Bvb64.js → ensure-collection-tables-Cet4650m.js} +9 -9
  42. package/dist/{ensure-collection-tables-Do-Bvb64.js.map → ensure-collection-tables-Cet4650m.js.map} +1 -1
  43. package/dist/{ensure-tables-Dl_Eh9ow.js → ensure-tables-l_OgFQjN.js} +5 -5
  44. package/dist/{ensure-tables-Dl_Eh9ow.js.map → ensure-tables-l_OgFQjN.js.map} +1 -1
  45. package/dist/{enum-labels-kept-D9eTIWCz.js → enum-labels-kept-nheku1pB.js} +3 -3
  46. package/dist/{enum-labels-kept-D9eTIWCz.js.map → enum-labels-kept-nheku1pB.js.map} +1 -1
  47. package/dist/{generate-drizzle-schema-Bf8canaR.js → generate-drizzle-schema-DC0BOUpn.js} +3 -3
  48. package/dist/{generate-drizzle-schema-Bf8canaR.js.map → generate-drizzle-schema-DC0BOUpn.js.map} +1 -1
  49. package/dist/{generate-drizzle-schema-logic-BaT0H7Gq.js → generate-drizzle-schema-logic-CPzCRD-8.js} +4 -4
  50. package/dist/{generate-drizzle-schema-logic-BaT0H7Gq.js.map → generate-drizzle-schema-logic-CPzCRD-8.js.map} +1 -1
  51. package/dist/{generate-files-D50Pxw1G.js → generate-files-BP-4W_gm.js} +6 -6
  52. package/dist/{generate-files-D50Pxw1G.js.map → generate-files-BP-4W_gm.js.map} +1 -1
  53. package/dist/{generate-next-step-DCd7yiJ2.js → generate-next-step-DgK5BlBn.js} +22 -14
  54. package/dist/{generate-next-step-DCd7yiJ2.js.map → generate-next-step-DgK5BlBn.js.map} +1 -1
  55. package/dist/{generate-postgres-ddl-logic-B4k9djAV.js → generate-postgres-ddl-logic-DPl1oH_z.js} +4 -4
  56. package/dist/{generate-postgres-ddl-logic-B4k9djAV.js.map → generate-postgres-ddl-logic-DPl1oH_z.js.map} +1 -1
  57. package/dist/generated-schema-diff-eZCklRZQ.js +1025 -0
  58. package/dist/generated-schema-diff-eZCklRZQ.js.map +1 -0
  59. package/dist/{generated-schema-staleness-FlxM2i4i.js → generated-schema-staleness-BvNF3i-s.js} +2 -2
  60. package/dist/{generated-schema-staleness-FlxM2i4i.js.map → generated-schema-staleness-BvNF3i-s.js.map} +1 -1
  61. package/dist/index.d.ts +1 -0
  62. package/dist/index.es.js +70 -11
  63. package/dist/index.es.js.map +1 -1
  64. package/dist/{introspect-db-logic-j2vYhmdP.js → introspect-db-logic-DgQVzccW.js} +2 -2
  65. package/dist/{introspect-db-logic-j2vYhmdP.js.map → introspect-db-logic-DgQVzccW.js.map} +1 -1
  66. package/dist/migrate-policy-stamps-3eqfhes6.js +89 -0
  67. package/dist/migrate-policy-stamps-3eqfhes6.js.map +1 -0
  68. package/dist/{open-rebase-D8rytTP0.js → open-rebase-EmqVmS14.js} +78 -1027
  69. package/dist/open-rebase-EmqVmS14.js.map +1 -0
  70. package/dist/{pg-error-utils-CdsGYMTm.js → pg-error-utils-CFEnm2m9.js} +11 -4
  71. package/dist/pg-error-utils-CFEnm2m9.js.map +1 -0
  72. package/dist/{plan-schema-CsNgK0qi.js → plan-schema-Czf3q4-Q.js} +4 -4
  73. package/dist/{plan-schema-CsNgK0qi.js.map → plan-schema-Czf3q4-Q.js.map} +1 -1
  74. package/dist/{policy-drift-CY5P1ZRu.js → policy-drift-X4A-xAzv.js} +3 -3
  75. package/dist/{policy-drift-CY5P1ZRu.js.map → policy-drift-X4A-xAzv.js.map} +1 -1
  76. package/dist/pool-disconnects.d.ts +28 -0
  77. package/dist/{push-index-prebuild-BDFcfRPo.js → push-index-prebuild-COd7i6wm.js} +4 -4
  78. package/dist/{push-index-prebuild-BDFcfRPo.js.map → push-index-prebuild-COd7i6wm.js.map} +1 -1
  79. package/dist/{push-legacy-renames-D4bvMWAb.js → push-legacy-renames-CLgYYwPE.js} +4 -4
  80. package/dist/{push-legacy-renames-D4bvMWAb.js.map → push-legacy-renames-CLgYYwPE.js.map} +1 -1
  81. package/dist/{push-policy-plan-DTXE6aVa.js → push-policy-plan-D2gpQsdv.js} +23 -7
  82. package/dist/push-policy-plan-D2gpQsdv.js.map +1 -0
  83. package/dist/{render-ddl-CrfEe__B.js → render-ddl-4v88y-Gv.js} +4 -4
  84. package/dist/{render-ddl-CrfEe__B.js.map → render-ddl-4v88y-Gv.js.map} +1 -1
  85. package/dist/{rls-enforcement-D7P4-ZYX.js → rls-enforcement-DDyNoOSy.js} +2 -2
  86. package/dist/{rls-enforcement-D7P4-ZYX.js.map → rls-enforcement-DDyNoOSy.js.map} +1 -1
  87. package/dist/schema/atlas-argv.d.ts +3 -1
  88. package/dist/schema/doctor-cli.js +5 -5
  89. package/dist/schema/doctor.d.ts +20 -2
  90. package/dist/schema/ensure-collection-policies.d.ts +28 -1
  91. package/dist/schema/generate-drizzle-schema.js +1 -1
  92. package/dist/schema/generate-next-step.d.ts +20 -8
  93. package/dist/schema/generate-postgres-ddl.js +2 -2
  94. package/dist/schema/generated-schema-diff.d.ts +21 -0
  95. package/dist/schema/introspect-db.js +6 -6
  96. package/dist/schema/introspect-db.js.map +1 -1
  97. package/dist/schema/migrate-policy-stamps.d.ts +23 -0
  98. package/dist/schema/push-policy-plan.d.ts +10 -2
  99. package/dist/services/BranchService.d.ts +85 -0
  100. package/dist/services/pg-notify-listener.d.ts +2 -0
  101. package/dist/{source-DB6xJv3p.js → source-fZb92pN8.js} +46 -3
  102. package/dist/source-fZb92pN8.js.map +1 -0
  103. package/dist/{vector-index-BFhyEaiz.js → vector-index-DsQ3V2d2.js} +2 -2
  104. package/dist/{vector-index-BFhyEaiz.js.map → vector-index-DsQ3V2d2.js.map} +1 -1
  105. package/dist/{websocket-DMeXOoyv.js → websocket-BKZwsjmf.js} +18 -5
  106. package/dist/websocket-BKZwsjmf.js.map +1 -0
  107. package/package.json +7 -7
  108. package/dist/BranchService-DNg4txyf.js.map +0 -1
  109. package/dist/backup-cli-HCEkPcQj.js +0 -556
  110. package/dist/backup-cli-HCEkPcQj.js.map +0 -1
  111. package/dist/backup-service-D-UpT7DH.js +0 -857
  112. package/dist/backup-service-D-UpT7DH.js.map +0 -1
  113. package/dist/cli-console-C_ISGwJo.js.map +0 -1
  114. package/dist/cli-flags-DUozBFyK.js +0 -205
  115. package/dist/cli-flags-DUozBFyK.js.map +0 -1
  116. package/dist/connection-C938nR3E.js.map +0 -1
  117. package/dist/databasePoolManager-Yqdw14wY.js.map +0 -1
  118. package/dist/doctor-CJyuhV1n.js.map +0 -1
  119. package/dist/ensure-collection-policies-C1ux3V_z.js.map +0 -1
  120. package/dist/open-rebase-D8rytTP0.js.map +0 -1
  121. package/dist/pg-error-utils-CdsGYMTm.js.map +0 -1
  122. package/dist/push-policy-plan-DTXE6aVa.js.map +0 -1
  123. package/dist/rls-bootstrap-sql-Bd-hJk08.js.map +0 -1
  124. package/dist/rolldown-runtime-V7rFbMRe.js +0 -39
  125. package/dist/source-DB6xJv3p.js.map +0 -1
  126. package/dist/websocket-DMeXOoyv.js.map +0 -1
@@ -42,8 +42,9 @@ export declare function consoleCommand(args: string[], streams?: ConsoleStreams)
42
42
  * every db command prints for a database it cannot reach, or one sentence —
43
43
  * never the driver's error serialised onto one line, stack and all.
44
44
  *
45
- * The managed development database refuses a connection over its limit by
46
- * resetting it, and `read ECONNRESET` says nothing about why. It accepts only a
47
- * few at a time, and a running `rebase dev` holds some of them.
45
+ * The managed development database accepts only a few connections at a time,
46
+ * and a running `rebase dev` holds some of them. Its proxy refuses one over the
47
+ * limit with SQLSTATE 53300; a database an earlier CLI started resets it
48
+ * instead, and `read ECONNRESET` says nothing about why.
48
49
  */
49
50
  export declare function describeOpenFailure(error: unknown, databaseUrl: string, managed: boolean): string;
@@ -1,6 +1,6 @@
1
1
  import { createRequire as __createRequire } from "module";
2
2
  __createRequire(import.meta.url);
3
- import { a as outWarn, i as outError, m as isRebaseIndexName, o as atlasExcludePattern, r as out, s as excludePatternParts, t as chalk } from "./source-DB6xJv3p.js";
3
+ import { a as outWarn, i as outError, m as isRebaseIndexName, o as atlasExcludePattern, r as out, s as excludePatternParts, t as chalk } from "./source-fZb92pN8.js";
4
4
  import path from "path";
5
5
  import fs from "fs";
6
6
  import { fileURLToPath, pathToFileURL } from "url";
@@ -1292,7 +1292,7 @@ async function applySearchDdl(databaseUrl, sqlDir = generatedSqlDir()) {
1292
1292
  * `search` block, which is every project that has not opted in.
1293
1293
  */
1294
1294
  async function getSearchExcludes(collectionsPath) {
1295
- const { searchExcludePatterns } = await import("./generate-postgres-ddl-logic-B4k9djAV.js").then((n) => n.o);
1295
+ const { searchExcludePatterns } = await import("./generate-postgres-ddl-logic-DPl1oH_z.js").then((n) => n.o);
1296
1296
  return searchExcludePatterns(await loadCollectionsForCli(collectionsPath));
1297
1297
  }
1298
1298
  /**
@@ -1379,7 +1379,7 @@ function readVectorDdl(sqlDir = generatedSqlDir()) {
1379
1379
  async function applyVectorDdl(databaseUrl, sqlDir = generatedSqlDir()) {
1380
1380
  const sql = readVectorDdl(sqlDir);
1381
1381
  if (!sql) return;
1382
- const { vectorExtensionHint } = await import("./vector-index-BFhyEaiz.js").then((n) => n.f);
1382
+ const { vectorExtensionHint } = await import("./vector-index-DsQ3V2d2.js").then((n) => n.f);
1383
1383
  try {
1384
1384
  await withAppClient(databaseUrl, (client) => client.query(sql));
1385
1385
  } catch (err) {
@@ -1397,7 +1397,7 @@ async function applyVectorDdl(databaseUrl, sqlDir = generatedSqlDir()) {
1397
1397
  * `vector` property, which is every project that has not opted in.
1398
1398
  */
1399
1399
  async function getVectorExcludes(collectionsPath) {
1400
- const { vectorExcludePatterns } = await import("./generate-postgres-ddl-logic-B4k9djAV.js").then((n) => n.o);
1400
+ const { vectorExcludePatterns } = await import("./generate-postgres-ddl-logic-DPl1oH_z.js").then((n) => n.o);
1401
1401
  return vectorExcludePatterns(await loadCollectionsForCli(collectionsPath));
1402
1402
  }
1403
1403
  /**
@@ -1434,7 +1434,7 @@ async function applyTriggersDdl(databaseUrl, sqlDir = generatedSqlDir()) {
1434
1434
  }
1435
1435
  /** @see getSearchExcludes */
1436
1436
  async function getTriggerExcludes(collectionsPath) {
1437
- const { triggerExcludePatterns } = await import("./generate-postgres-ddl-logic-B4k9djAV.js").then((n) => n.o);
1437
+ const { triggerExcludePatterns } = await import("./generate-postgres-ddl-logic-DPl1oH_z.js").then((n) => n.o);
1438
1438
  return triggerExcludePatterns(await loadCollectionsForCli(collectionsPath));
1439
1439
  }
1440
1440
  /**
@@ -1511,9 +1511,9 @@ async function getForeignIndexExcludes(databaseUrl, collectionsPath, deps = {})
1511
1511
  */
1512
1512
  async function managedIndexNames(collectionsPath) {
1513
1513
  const collections = await loadCollectionsForCli(collectionsPath);
1514
- const { searchExcludePatterns, vectorExcludePatterns } = await import("./generate-postgres-ddl-logic-B4k9djAV.js").then((n) => n.o);
1515
- const { resolveColumnName } = await import("./column-plan-helpers-D_V4oaZh.js").then((n) => n.t);
1516
- const { buildCollectionIndexPlan } = await import("./source-DB6xJv3p.js").then((n) => n.d);
1514
+ const { searchExcludePatterns, vectorExcludePatterns } = await import("./generate-postgres-ddl-logic-DPl1oH_z.js").then((n) => n.o);
1515
+ const { resolveColumnName } = await import("./column-plan-helpers-IG6uFb1s.js").then((n) => n.t);
1516
+ const { buildCollectionIndexPlan } = await import("./source-fZb92pN8.js").then((n) => n.d);
1517
1517
  const names = new Set(buildCollectionIndexPlan(collections, resolveColumnName).map((spec) => spec.indexName));
1518
1518
  for (const pattern of [...searchExcludePatterns(collections), ...vectorExcludePatterns(collections)]) {
1519
1519
  const object = excludePatternParts(pattern)?.[2];
@@ -1649,6 +1649,27 @@ function isSslNotEnabled(err) {
1649
1649
  return false;
1650
1650
  }
1651
1651
  /**
1652
+ * The database a connection was refused by because it is closed to new
1653
+ * connections (`ALLOW_CONNECTIONS false`), or null.
1654
+ *
1655
+ * Postgres says it as `database "x" is not currently accepting connections`,
1656
+ * SQLSTATE 55000. That code also covers failures that have nothing to do with
1657
+ * connecting (`lastval is not yet defined in this session`), so the sentence is
1658
+ * what is matched, through Drizzle's `cause` and a dual-stack `AggregateError`.
1659
+ */
1660
+ function closedDatabaseName(err) {
1661
+ if (!err || typeof err !== "object") return null;
1662
+ if ("message" in err && typeof err.message === "string") {
1663
+ const named = /database "(.+)" is not currently accepting connections/.exec(err.message);
1664
+ if (named) return named[1];
1665
+ }
1666
+ if (err instanceof AggregateError) for (const inner of err.errors) {
1667
+ const named = closedDatabaseName(inner);
1668
+ if (named) return named;
1669
+ }
1670
+ return "cause" in err ? closedDatabaseName(err.cause) : null;
1671
+ }
1672
+ /**
1652
1673
  * Detect PostgreSQL "cannot drop ... because other objects depend on it"
1653
1674
  * (error code 2BP01, dependent_objects_still_exist). This is the failure that
1654
1675
  * strands a declarative `db push` half-applied when a collection is removed but
@@ -1781,17 +1802,43 @@ function formatSslNotEnabledBanner(databaseUrl) {
1781
1802
  ❌ SSL is not enabled on the PostgreSQL server at ${hostInfo}\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n The client tried to connect over SSL, but the server does not\n support it. This is normal for a plain local dev database.\n\n Fix: append ${chalk.bold("sslmode=disable")} to DATABASE_URL, e.g.\n\n DATABASE_URL=...${suggestion}\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
1782
1803
  }
1783
1804
  /**
1805
+ * Format a diagnostic banner for a database closed to new connections.
1806
+ *
1807
+ * Nothing in a development database closes one but `rebase db branch create
1808
+ * --force`, which does it for the length of the copy; one killed before it
1809
+ * opened it again leaves the project's database refusing everything. Every
1810
+ * `rebase db branch` command opens it again before it does anything else, so
1811
+ * that is the command named — with the statement itself, for a server the CLI
1812
+ * cannot reach that way.
1813
+ */
1814
+ function formatClosedDatabaseBanner(databaseUrl, database, err) {
1815
+ const hostInfo = parseHostInfo(databaseUrl);
1816
+ const reopen = databaseSource() === "flag" ? "rebase db branch list --database-url <the same URL>" : "rebase db branch list";
1817
+ return `
1818
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1819
+ ❌ Database "${database}" at ${hostInfo} is closed to new connections\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n` + driverReasonLine(err) + ` It is set to refuse every new connection (ALLOW_CONNECTIONS false).
1820
+ \`rebase db branch create --force\` closes its source for the copy, and
1821
+ one stopped before it finished (a closed terminal, a kill) leaves it
1822
+ closed. Nothing in it is lost. Open it again with:
1823
+
1824
+ ${chalk.bold.green(reopen)}\n (every rebase db branch command opens it before anything else)\n\n or run this, connected to the server's postgres database:\n\n ALTER DATABASE "${database.replace(/"/g, "\"\"")}" ALLOW_CONNECTIONS true;\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
1825
+ }
1826
+ /**
1784
1827
  * Format a diagnostic banner for a dependency-drop failure during `db push`.
1785
1828
  * Explains that the database may be left partially migrated and how to recover.
1829
+ *
1830
+ * The DROP reads the connection string from `rebase db url`, as the NOT NULL
1831
+ * box's backfill does: on the managed development database `.env` leaves
1832
+ * `DATABASE_URL` unset, and the shell has none.
1786
1833
  */
1787
- function formatDependencyDropBanner() {
1834
+ function formatDependencyDropBanner(manager = detectProjectPackageManager()) {
1788
1835
  return `
1789
1836
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1790
1837
  ❌ Schema push failed: a type/table could not be dropped
1791
1838
  because other objects still depend on it.
1792
1839
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1793
1840
 
1794
- ${chalk.yellow("The database may now be partially migrated.")} Atlas applies\n statements individually, so earlier changes in this push may\n already be committed while later ones failed.\n\n This commonly happens when a collection is removed but an enum\n type it defined is still referenced. To recover:\n\n 1. Inspect the leftover object named in the error above.\n 2. Drop it with CASCADE, e.g.:\n psql "$DATABASE_URL" -c 'DROP TYPE "<name>" CASCADE;'\n 3. Re-run: ${chalk.bold.green("rebase db push")}\n\n Prefer a safe, versioned workflow? Use ${chalk.bold("rebase db generate")}\n + ${chalk.bold("rebase db migrate")} instead of push for destructive changes.\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
1841
+ ${chalk.yellow("The database may now be partially migrated.")} Atlas applies\n statements individually, so earlier changes in this push may\n already be committed while later ones failed.\n\n This commonly happens when a collection is removed but an enum\n type it defined is still referenced. To recover:\n\n 1. Inspect the leftover object named in the error above.\n 2. Drop it with CASCADE, e.g.:\n psql "$(${projectRebaseCommand(manager)} db url)" -c 'DROP TYPE "<name>" CASCADE;'\n 3. Re-run: ${chalk.bold.green("rebase db push")}\n\n Prefer a safe, versioned workflow? Use ${chalk.bold("rebase db generate")}\n + ${chalk.bold("rebase db migrate")} instead of push for destructive changes.\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
1795
1842
  }
1796
1843
  /**
1797
1844
  * Pre-flight check: verify that the database is reachable before running
@@ -1816,6 +1863,11 @@ async function checkDatabaseConnectivity(databaseUrl) {
1816
1863
  outError(formatSslNotEnabledBanner(databaseUrl));
1817
1864
  process.exit(1);
1818
1865
  }
1866
+ const closed = closedDatabaseName(err);
1867
+ if (closed) {
1868
+ outError(formatClosedDatabaseBanner(databaseUrl, closed, err));
1869
+ process.exit(1);
1870
+ }
1819
1871
  outWarn(chalk.yellow(` ⚠ Could not verify database connectivity: ${err instanceof Error ? err.message : String(err)}`));
1820
1872
  outWarn(chalk.gray(" Proceeding anyway — the command may fail if the database is unreachable."));
1821
1873
  }
@@ -1829,6 +1881,8 @@ function diagnoseDbError(err, databaseUrl) {
1829
1881
  if (isEconnrefused(err)) return formatConnectionRefusedBanner(databaseUrl || "", err);
1830
1882
  if (isAuthFailure(err)) return formatAuthFailureBanner(databaseUrl || "", err);
1831
1883
  if (isSslNotEnabled(err)) return formatSslNotEnabledBanner(databaseUrl || "");
1884
+ const closed = closedDatabaseName(err);
1885
+ if (closed) return formatClosedDatabaseBanner(databaseUrl || "", closed, err);
1832
1886
  if (isDependencyDropError(err)) return formatDependencyDropBanner();
1833
1887
  return null;
1834
1888
  }
@@ -1984,6 +2038,48 @@ function notNullColumnIsNew(stderr, column) {
1984
2038
  return new RegExp(`ADD\\s+COLUMN\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?"${quoted}"`, "i").test(statement);
1985
2039
  }
1986
2040
  /**
2041
+ * `rebase`, spelled the way a project runs it from its own shell: a scaffold
2042
+ * keeps the CLI in `node_modules/.bin`, not on PATH, so it is `pnpm exec
2043
+ * rebase`, as `rebase start`'s hint and `rebase init`'s next steps spell it.
2044
+ */
2045
+ function projectRebaseCommand(manager) {
2046
+ switch (manager) {
2047
+ case "pnpm": return "pnpm exec rebase";
2048
+ case "npm": return "npx rebase";
2049
+ case "yarn": return "yarn rebase";
2050
+ case "bun": return "bunx rebase";
2051
+ default: return "rebase";
2052
+ }
2053
+ }
2054
+ /** A PostgreSQL identifier, double-quoted, with any `"` in it doubled. */
2055
+ function sqlIdentifier(name) {
2056
+ return `"${name.replace(/"/g, "\"\"")}"`;
2057
+ }
2058
+ /**
2059
+ * `text` as one double-quoted `sh` word: `\`, `"`, `$` and a backtick are the
2060
+ * characters a double-quoted string does not take literally.
2061
+ */
2062
+ function shDoubleQuoted(text) {
2063
+ return `"${text.replace(/[\\"$`]/g, "\\$&")}"`;
2064
+ }
2065
+ /**
2066
+ * The backfill for a column that refused NOT NULL, as one line a POSIX shell
2067
+ * runs once the value is typed between its single quotes.
2068
+ *
2069
+ * The SQL is the shell's double-quoted word, so the value's own quotes are
2070
+ * SQL's: `'tbd'`, or `'O''Brien'` for a value with a quote in it, as SQL
2071
+ * writes one. It was the SQL in shell single quotes, and the first quote a
2072
+ * value was typed with ended the shell's: `= 'tbd'` reached psql as `= tbd`,
2073
+ * `column "tbd" does not exist`.
2074
+ *
2075
+ * `rebase db url`, not `$DATABASE_URL`: on the managed development database
2076
+ * `.env` leaves DATABASE_URL unset, and the shell has none.
2077
+ */
2078
+ function backfillCommand(table, column, manager) {
2079
+ const sql = `UPDATE ${sqlIdentifier(table)} SET ${sqlIdentifier(column)} = '…' WHERE ${sqlIdentifier(column)} IS NULL;`;
2080
+ return `psql "$(${projectRebaseCommand(manager)} db url)" -c ${shDoubleQuoted(sql)}`;
2081
+ }
2082
+ /**
1987
2083
  * The ways out, and only the ones that work for this column.
1988
2084
  *
1989
2085
  * A `defaultValue` backfills only a column the push is adding: PostgreSQL
@@ -1996,10 +2092,10 @@ function notNullColumnIsNew(stderr, column) {
1996
2092
  * only when the table is empty — so a push that dies here is strictly worse
1997
2093
  * than the boot that would have run instead.
1998
2094
  */
1999
- function formatNotNullViolationBanner(violation, rowCount, isNew = null) {
2095
+ function formatNotNullViolationBanner(violation, rowCount, isNew = null, manager = detectProjectPackageManager()) {
2000
2096
  const { table, column } = violation;
2001
2097
  const rows = rowCount === null ? ` "${table}" already holds rows, and none of them has a value for "${column}".\n` : ` "${table}" already holds ${rowCount} row${rowCount === 1 ? "" : "s"}, and they have no value for "${column}".\n`;
2002
- const backfill = `Backfill by hand first, then push again:\n ${chalk.gray(`psql "$DATABASE_URL" -c 'UPDATE "${table}" SET "${column}" = … WHERE "${column}" IS NULL;'`)}\n`;
2098
+ const backfill = `Backfill by hand first, then push again, with the value between the single quotes:\n ${chalk.gray(backfillCommand(table, column, manager))}\n`;
2003
2099
  const leaveOptional = `Leave it optional — take \`validation.required\` off the property.\n`;
2004
2100
  const defaultLine = (caveat) => `Give the property a default, so the push can backfill${caveat}:\n ${chalk.gray(`{ type: "string", defaultValue: "…", validation: { required: true } }`)}\n`;
2005
2101
  const remedies = isNew === false ? [backfill, leaveOptional] : isNew === true ? [
@@ -2288,6 +2384,6 @@ async function diagnoseAtlasFailure(context) {
2288
2384
  return null;
2289
2385
  }
2290
2386
  //#endregion
2291
- export { redactConnectionPasswords as $, getVectorExcludes as A, workspaceMemberDir as B, dropGeneratedColumns as C, getTableExcludes as D, getSearchExcludes as E, readSearchDdl as F, decidePushSafety as G, GENERATED_SQL_DIR as H, readTriggersDdl as I, extractPlanStatements as J, destructiveOptInFlag as K, readVectorDdl as L, queryColumnTypes as M, queryGeneratedColumnDependencies as N, getTriggerExcludes as O, queryUndeclarableConstraints as P, forLibpq as Q, resolveLocalBin as R, dropDevDatabase as S, getForeignIndexExcludes as T, generatedSqlDir as U, DESIRED_STATE_URL as V, prepareGeneratedSqlDir as W, isSyncedPlan as X, fromAlterTable as Y, forAtlas as Z, describeBuildScriptRemedy as _, formatForeignGeneratedColumnBanner as a, detectProjectPackageManager as b, isSslNotEnabled as c, ExcludeIntrospectionError as d, splitPassword as et, applySearchDdl as f, closeAppClients as g, atlasDevDatabaseUrl as h, diagnoseDbError as i, loadCollectionsForCli as j, getUndeclaredConstraintExcludes as k, parseHostInfo as l, applyVectorDdl as m, deepestErrorMessage as n, isAuthFailure as o, applyTriggersDdl as p, detectDestructiveStatements as q, diagnoseAtlasFailure as r, isEconnrefused as s, checkDatabaseConnectivity as t, extractCauseMessage as tt, reportCommandFailure as u, describeDevAddCommand as v, ensureDevDatabaseExists as w, diagnoseMissingBin as x, describeReinstallCommand as y, withAppClient as z };
2387
+ export { forLibpq as $, getUndeclaredConstraintExcludes as A, withAppClient as B, dropDevDatabase as C, getSearchExcludes as D, getForeignIndexExcludes as E, queryUndeclarableConstraints as F, prepareGeneratedSqlDir as G, DESIRED_STATE_URL as H, readSearchDdl as I, detectDestructiveStatements as J, decidePushSafety as K, readTriggersDdl as L, loadCollectionsForCli as M, queryColumnTypes as N, getTableExcludes as O, queryGeneratedColumnDependencies as P, forAtlas as Q, readVectorDdl as R, diagnoseMissingBin as S, ensureDevDatabaseExists as T, GENERATED_SQL_DIR as U, workspaceMemberDir as V, generatedSqlDir as W, fromAlterTable as X, extractPlanStatements as Y, isSyncedPlan as Z, closeAppClients as _, diagnoseDbError as a, describeReinstallCommand as b, isEconnrefused as c, reportCommandFailure as d, redactConnectionPasswords as et, ExcludeIntrospectionError as f, atlasDevDatabaseUrl as g, applyVectorDdl as h, diagnoseAtlasFailure as i, getVectorExcludes as j, getTriggerExcludes as k, isSslNotEnabled as l, applyTriggersDdl as m, closedDatabaseName as n, extractCauseMessage as nt, formatForeignGeneratedColumnBanner as o, applySearchDdl as p, destructiveOptInFlag as q, deepestErrorMessage as r, isAuthFailure as s, checkDatabaseConnectivity as t, splitPassword as tt, parseHostInfo as u, describeBuildScriptRemedy as v, dropGeneratedColumns as w, detectProjectPackageManager as x, describeDevAddCommand as y, resolveLocalBin as z };
2292
2388
 
2293
- //# sourceMappingURL=cli-errors-mx4sSjB8.js.map
2389
+ //# sourceMappingURL=cli-errors-DiA0XFIS.js.map