@rebasepro/server-postgres 0.25.0 → 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 (114) hide show
  1. package/dist/{BranchService-iXXZeVYD.js → BranchService-ClklxyAQ.js} +66 -6
  2. package/dist/BranchService-ClklxyAQ.js.map +1 -0
  3. package/dist/backup/backup-cli.d.ts +40 -3
  4. package/dist/backup/backup-service.d.ts +11 -0
  5. package/dist/{backup-service-Bb39plam.js → backup-cli-gijeXe0u.js} +777 -10
  6. package/dist/backup-cli-gijeXe0u.js.map +1 -0
  7. package/dist/{boot-ddl-s_3Hkz94.js → boot-ddl-DYH95Qeg.js} +3 -3
  8. package/dist/{boot-ddl-s_3Hkz94.js.map → boot-ddl-DYH95Qeg.js.map} +1 -1
  9. package/dist/branch-argv.d.ts +15 -0
  10. package/dist/{cli-console-DQ_K-sdM.js → cli-console-CQrQ0lAY.js} +8 -9
  11. package/dist/{cli-console-DQ_K-sdM.js.map → cli-console-CQrQ0lAY.js.map} +1 -1
  12. package/dist/{cli-errors-DwQnNATs.js → cli-errors-DiA0XFIS.js} +38 -10
  13. package/dist/{cli-errors-DwQnNATs.js.map → cli-errors-DiA0XFIS.js.map} +1 -1
  14. package/dist/cli-errors.d.ts +14 -0
  15. package/dist/cli-flags.d.ts +51 -0
  16. package/dist/{cli-prompt-egtNKkZl.js → cli-prompt-DXG0yk-h.js} +39 -4
  17. package/dist/{cli-prompt-egtNKkZl.js.map → cli-prompt-DXG0yk-h.js.map} +1 -1
  18. package/dist/cli.js +44 -174
  19. package/dist/cli.js.map +1 -1
  20. package/dist/{column-plan-helpers-D_V4oaZh.js → column-plan-helpers-IG6uFb1s.js} +2 -2
  21. package/dist/{column-plan-helpers-D_V4oaZh.js.map → column-plan-helpers-IG6uFb1s.js.map} +1 -1
  22. package/dist/{connection-C938nR3E.js → connection-czvI7TZL.js} +57 -10
  23. package/dist/connection-czvI7TZL.js.map +1 -0
  24. package/dist/{databasePoolManager-Yqdw14wY.js → databasePoolManager-3stMNFL-.js} +4 -6
  25. package/dist/databasePoolManager-3stMNFL-.js.map +1 -0
  26. package/dist/db-command-line.d.ts +14 -0
  27. package/dist/{rls-bootstrap-sql-Bd-hJk08.js → db-subcommands-BPoHCxJR.js} +455 -3
  28. package/dist/db-subcommands-BPoHCxJR.js.map +1 -0
  29. package/dist/db-subcommands.d.ts +11 -0
  30. package/dist/{deferred-index-build-Cis_HoGn.js → deferred-index-build-BE0I6sYU.js} +8 -8
  31. package/dist/{deferred-index-build-Cis_HoGn.js.map → deferred-index-build-BE0I6sYU.js.map} +1 -1
  32. package/dist/{doctor-DvJH-IQG.js → doctor-BT--1kq3.js} +107 -11
  33. package/dist/doctor-BT--1kq3.js.map +1 -0
  34. package/dist/{ensure-collection-policies-CCqayoUz.js → ensure-collection-policies-BnGOURpG.js} +13 -10
  35. package/dist/ensure-collection-policies-BnGOURpG.js.map +1 -0
  36. package/dist/{ensure-collection-tables-DvvImXDe.js → ensure-collection-tables-Cet4650m.js} +9 -9
  37. package/dist/{ensure-collection-tables-DvvImXDe.js.map → ensure-collection-tables-Cet4650m.js.map} +1 -1
  38. package/dist/{ensure-tables-Dpgwx5sy.js → ensure-tables-l_OgFQjN.js} +5 -5
  39. package/dist/{ensure-tables-Dpgwx5sy.js.map → ensure-tables-l_OgFQjN.js.map} +1 -1
  40. package/dist/{enum-labels-kept-CUlUlRkO.js → enum-labels-kept-nheku1pB.js} +3 -3
  41. package/dist/{enum-labels-kept-CUlUlRkO.js.map → enum-labels-kept-nheku1pB.js.map} +1 -1
  42. package/dist/{generate-drizzle-schema-C3EAP9HE.js → generate-drizzle-schema-DC0BOUpn.js} +3 -3
  43. package/dist/{generate-drizzle-schema-C3EAP9HE.js.map → generate-drizzle-schema-DC0BOUpn.js.map} +1 -1
  44. package/dist/{generate-drizzle-schema-logic-DA3zM8zc.js → generate-drizzle-schema-logic-CPzCRD-8.js} +4 -4
  45. package/dist/{generate-drizzle-schema-logic-DA3zM8zc.js.map → generate-drizzle-schema-logic-CPzCRD-8.js.map} +1 -1
  46. package/dist/{generate-files-ClmOUHXj.js → generate-files-BP-4W_gm.js} +6 -6
  47. package/dist/{generate-files-ClmOUHXj.js.map → generate-files-BP-4W_gm.js.map} +1 -1
  48. package/dist/{generate-next-step-DCeS4LrJ.js → generate-next-step-DgK5BlBn.js} +2 -2
  49. package/dist/{generate-next-step-DCeS4LrJ.js.map → generate-next-step-DgK5BlBn.js.map} +1 -1
  50. package/dist/{generate-postgres-ddl-logic-4eUP4t8w.js → generate-postgres-ddl-logic-DPl1oH_z.js} +4 -4
  51. package/dist/{generate-postgres-ddl-logic-4eUP4t8w.js.map → generate-postgres-ddl-logic-DPl1oH_z.js.map} +1 -1
  52. package/dist/generated-schema-diff-eZCklRZQ.js +1025 -0
  53. package/dist/generated-schema-diff-eZCklRZQ.js.map +1 -0
  54. package/dist/{generated-schema-staleness-FlxM2i4i.js → generated-schema-staleness-BvNF3i-s.js} +2 -2
  55. package/dist/{generated-schema-staleness-FlxM2i4i.js.map → generated-schema-staleness-BvNF3i-s.js.map} +1 -1
  56. package/dist/index.d.ts +1 -0
  57. package/dist/index.es.js +70 -11
  58. package/dist/index.es.js.map +1 -1
  59. package/dist/{introspect-db-logic-CI5CU_n0.js → introspect-db-logic-DgQVzccW.js} +2 -2
  60. package/dist/{introspect-db-logic-CI5CU_n0.js.map → introspect-db-logic-DgQVzccW.js.map} +1 -1
  61. package/dist/migrate-policy-stamps-3eqfhes6.js +89 -0
  62. package/dist/migrate-policy-stamps-3eqfhes6.js.map +1 -0
  63. package/dist/{open-rebase-BKA7Nyoe.js → open-rebase-EmqVmS14.js} +51 -1020
  64. package/dist/open-rebase-EmqVmS14.js.map +1 -0
  65. package/dist/{pg-error-utils-Bv5n2PLn.js → pg-error-utils-CFEnm2m9.js} +2 -2
  66. package/dist/{pg-error-utils-Bv5n2PLn.js.map → pg-error-utils-CFEnm2m9.js.map} +1 -1
  67. package/dist/{plan-schema-CXOucCw-.js → plan-schema-Czf3q4-Q.js} +4 -4
  68. package/dist/{plan-schema-CXOucCw-.js.map → plan-schema-Czf3q4-Q.js.map} +1 -1
  69. package/dist/{policy-drift-vm0BcvcE.js → policy-drift-X4A-xAzv.js} +3 -3
  70. package/dist/{policy-drift-vm0BcvcE.js.map → policy-drift-X4A-xAzv.js.map} +1 -1
  71. package/dist/pool-disconnects.d.ts +28 -0
  72. package/dist/{push-index-prebuild-DIequ4bV.js → push-index-prebuild-COd7i6wm.js} +4 -4
  73. package/dist/{push-index-prebuild-DIequ4bV.js.map → push-index-prebuild-COd7i6wm.js.map} +1 -1
  74. package/dist/{push-legacy-renames-BqJut4F3.js → push-legacy-renames-CLgYYwPE.js} +4 -4
  75. package/dist/{push-legacy-renames-BqJut4F3.js.map → push-legacy-renames-CLgYYwPE.js.map} +1 -1
  76. package/dist/{push-policy-plan-CvX8hiPb.js → push-policy-plan-D2gpQsdv.js} +5 -5
  77. package/dist/{push-policy-plan-CvX8hiPb.js.map → push-policy-plan-D2gpQsdv.js.map} +1 -1
  78. package/dist/{render-ddl-CQNwZdse.js → render-ddl-4v88y-Gv.js} +4 -4
  79. package/dist/{render-ddl-CQNwZdse.js.map → render-ddl-4v88y-Gv.js.map} +1 -1
  80. package/dist/{rls-enforcement-D7P4-ZYX.js → rls-enforcement-DDyNoOSy.js} +2 -2
  81. package/dist/{rls-enforcement-D7P4-ZYX.js.map → rls-enforcement-DDyNoOSy.js.map} +1 -1
  82. package/dist/schema/doctor-cli.js +5 -5
  83. package/dist/schema/doctor.d.ts +20 -2
  84. package/dist/schema/ensure-collection-policies.d.ts +4 -1
  85. package/dist/schema/generate-drizzle-schema.js +1 -1
  86. package/dist/schema/generate-postgres-ddl.js +2 -2
  87. package/dist/schema/generated-schema-diff.d.ts +21 -0
  88. package/dist/schema/introspect-db.js +5 -6
  89. package/dist/schema/introspect-db.js.map +1 -1
  90. package/dist/schema/migrate-policy-stamps.d.ts +23 -0
  91. package/dist/schema/push-policy-plan.d.ts +5 -0
  92. package/dist/services/BranchService.d.ts +20 -2
  93. package/dist/services/pg-notify-listener.d.ts +2 -0
  94. package/dist/{source-Bv5KPeIx.js → source-fZb92pN8.js} +2 -2
  95. package/dist/{source-Bv5KPeIx.js.map → source-fZb92pN8.js.map} +1 -1
  96. package/dist/{vector-index-BFhyEaiz.js → vector-index-DsQ3V2d2.js} +2 -2
  97. package/dist/{vector-index-BFhyEaiz.js.map → vector-index-DsQ3V2d2.js.map} +1 -1
  98. package/dist/{websocket-MC0zTBar.js → websocket-BKZwsjmf.js} +18 -5
  99. package/dist/websocket-BKZwsjmf.js.map +1 -0
  100. package/package.json +7 -7
  101. package/dist/BranchService-iXXZeVYD.js.map +0 -1
  102. package/dist/backup-cli-B2CAn9fR.js +0 -647
  103. package/dist/backup-cli-B2CAn9fR.js.map +0 -1
  104. package/dist/backup-service-Bb39plam.js.map +0 -1
  105. package/dist/cli-flags-D-b0qL9T.js +0 -206
  106. package/dist/cli-flags-D-b0qL9T.js.map +0 -1
  107. package/dist/connection-C938nR3E.js.map +0 -1
  108. package/dist/databasePoolManager-Yqdw14wY.js.map +0 -1
  109. package/dist/doctor-DvJH-IQG.js.map +0 -1
  110. package/dist/ensure-collection-policies-CCqayoUz.js.map +0 -1
  111. package/dist/open-rebase-BKA7Nyoe.js.map +0 -1
  112. package/dist/rls-bootstrap-sql-Bd-hJk08.js.map +0 -1
  113. package/dist/rolldown-runtime-V7rFbMRe.js +0 -39
  114. package/dist/websocket-MC0zTBar.js.map +0 -1
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":[],"sources":["../src/tsx-loader.ts","../src/schema/generated-column-conflicts.ts","../src/schema/carved-out-migration.ts","../src/schema/migration-post-process.ts","../src/schema/atlas-argv.ts","../src/schema/atlas-revisions.ts","../src/schema/atlas-apply-report.ts","../src/cli-scratch-database.ts","../src/schema/migrate-baseline.ts","../src/cli-push.ts","../src/branch-argv.ts","../src/cli-collections-path.ts","../src/backup-argv.ts","../src/branch-prune.ts","../src/cli.ts"],"sourcesContent":["import { createRequire } from \"module\";\nimport path from \"path\";\nimport { pathToFileURL } from \"url\";\n\n/**\n * tsx's loader, as the URL `node --import` takes, or null when none resolves.\n *\n * For running one of this driver's scripts in one Node process. The `tsx`\n * binary is a relay — pnpm's `.bin/tsx` shell shim, then tsx's CLI in one Node,\n * which spawns a second Node with this same loader to run the script — so\n * spawning through it costs a shell and a Node start (~50–100 ms) per child.\n *\n * Resolved the way Node resolves the package: from the project the driver\n * runs in first (its cwd is the backend, where a scaffold declares tsx), then\n * from this package. A URL rather than a path: a Windows path is not a valid\n * `--import` specifier.\n */\nexport function resolveTsxLoader(): string | null {\n const bases = [path.join(process.cwd(), \"noop.js\"), import.meta.url];\n for (const base of bases) {\n try {\n return pathToFileURL(createRequire(base).resolve(\"tsx\")).href;\n } catch {\n // Not resolvable from here; try the next base.\n }\n }\n return null;\n}\n","/**\n * Which columns an Atlas plan cannot touch, because a generated column reads\n * them.\n *\n * PostgreSQL refuses `ALTER COLUMN … TYPE` and `DROP COLUMN` on any column a\n * `GENERATED ALWAYS AS … STORED` expression depends on:\n *\n * cannot alter type of a column used by a generated column\n *\n * Atlas cannot see that coming. A search block's `tsvector` is *deliberately*\n * hidden from it (`searchExcludePatterns`) — Rebase owns that column, and an\n * Atlas that could see it would plan a `DROP COLUMN` for it on every push,\n * since the desired state it is given never mentions one. So Atlas plans an\n * alter against a column whose dependant is invisible to it, PostgreSQL\n * refuses, and because `schema apply` runs its plan in a single transaction\n * **every unrelated statement rolls back with it**. One `varchar(255)` → `text`\n * widening on a searched column is enough to make `rebase db push` a no-op\n * forever, with an error that names neither the generated column nor the reason.\n *\n * The fix is the same one the search column's own stamp guard already\n * prescribes when a `search` block changes: drop the generated column, let the\n * apply through, and rebuild it from `search.sql` afterwards. It is cheap to\n * rebuild (one table rewrite, which the `ALTER … TYPE` was going to cost\n * anyway) and there is no other order that works — the expression cannot be\n * altered in place at all.\n *\n * Everything here is side-effect free: the plan is text and the dependencies\n * are rows someone else read. Unit-tested in\n * `generated-column-conflicts.test.ts`.\n */\nimport { atlasExcludePattern } from \"./atlas-exclude\";\nimport { extractPlanStatements, fromAlterTable } from \"./destructive-sql\";\n\n/** An operation on a column that PostgreSQL refuses while a dependant exists. */\nexport type ColumnMutationKind = \"type\" | \"drop\";\n\nexport interface ColumnMutation {\n /** Absent when the plan did not qualify the table; matched loosely then. */\n schema?: string;\n table: string;\n column: string;\n kind: ColumnMutationKind;\n}\n\n/** One `generated column → column it reads` edge, as read from the catalogue. */\nexport interface GeneratedColumnDependency {\n schema: string;\n table: string;\n /** The generated column. */\n column: string;\n /** A column its expression reads. */\n dependsOn: string;\n}\n\n/** A generated column standing in the way of the plan, and why. */\nexport interface GeneratedColumnConflict {\n schema: string;\n table: string;\n /** The generated column that has to go before the apply. */\n column: string;\n /** The mutated columns it reads, deduplicated and sorted. */\n blocking: { column: string; kind: ColumnMutationKind }[];\n}\n\n/** `\"public\".\"posts\"` / `public.posts` / `posts` → its parts. */\nconst IDENT = String.raw`(?:\"[^\"]+\"|[A-Za-z_][A-Za-z0-9_$]*)`;\nconst TABLE_RE = new RegExp(String.raw`^ALTER\\s+TABLE\\s+(?:ONLY\\s+)?(${IDENT})(?:\\.(${IDENT}))?`, \"i\");\nconst ALTER_COLUMN_RE = new RegExp(\n String.raw`\\bALTER\\s+(?:COLUMN\\s+)?(${IDENT})\\s+(?:SET\\s+DATA\\s+)?TYPE\\b`, \"gi\"\n);\nconst DROP_COLUMN_RE = new RegExp(\n String.raw`\\bDROP\\s+COLUMN\\s+(?:IF\\s+EXISTS\\s+)?(${IDENT})`, \"gi\"\n);\n\nconst unquote = (ident: string): string =>\n ident.startsWith(\"\\\"\") ? ident.slice(1, -1) : ident;\n\n/**\n * Every column an Atlas plan retypes or drops, with the table it belongs to.\n *\n * One statement carries many clauses — Atlas emits `ALTER TABLE \"public\".\"posts\"\n * ALTER COLUMN \"title\" TYPE text, ALTER COLUMN \"slug\" TYPE text, …` — so the\n * table is read once per statement and the clauses are scanned within it.\n */\nexport function parseColumnMutations(planSql: string): ColumnMutation[] {\n const mutations: ColumnMutation[] = [];\n\n // The same reading of the plan the destructive gate uses, and it has to\n // be the same: what `schema apply --dry-run` prints is a report, not SQL,\n // with a heading glued above the first statement and every statement\n // printed twice. Stripping a leading `->` off `;`-split text was the old\n // reading here, and it never saw the first statement of a plan — so a\n // retyped searched column failed every push with no hint, while\n // `db generate`, which parses a clean migration file, got it right.\n for (const raw of extractPlanStatements(planSql)) {\n const statement = fromAlterTable(raw);\n const table = TABLE_RE.exec(statement);\n if (!table) continue;\n // With both groups present the first is the schema; with one, the\n // statement named a bare table and the schema is whatever search_path\n // resolves to — which we cannot know here, so it stays undefined and\n // `findGeneratedColumnConflicts` matches on the table name alone.\n const [schema, name] = table[2]\n ? [unquote(table[1]), unquote(table[2])]\n : [undefined, unquote(table[1])];\n\n const collect = (re: RegExp, kind: ColumnMutationKind) => {\n re.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = re.exec(statement)) !== null) {\n mutations.push({ schema, table: name, column: unquote(match[1]), kind });\n }\n };\n collect(ALTER_COLUMN_RE, \"type\");\n collect(DROP_COLUMN_RE, \"drop\");\n }\n\n return mutations;\n}\n\n/**\n * The generated columns that block a plan: those reading a column it retypes\n * or drops.\n *\n * A mutation with no schema matches on table name alone. That is deliberately\n * loose — a bare `ALTER TABLE posts` resolves through `search_path` at\n * execution time, and guessing wrong in the *permissive* direction costs a\n * generated column that is rebuilt seconds later, while guessing wrong in the\n * strict direction costs the whole push.\n */\nexport function findGeneratedColumnConflicts(\n mutations: ColumnMutation[],\n dependencies: GeneratedColumnDependency[]\n): GeneratedColumnConflict[] {\n const conflicts = new Map<string, GeneratedColumnConflict>();\n\n for (const dependency of dependencies) {\n for (const mutation of mutations) {\n if (mutation.table !== dependency.table) continue;\n if (mutation.schema !== undefined && mutation.schema !== dependency.schema) continue;\n if (mutation.column !== dependency.dependsOn) continue;\n\n const key = `${dependency.schema}.${dependency.table}.${dependency.column}`;\n const conflict = conflicts.get(key) ?? {\n schema: dependency.schema,\n table: dependency.table,\n column: dependency.column,\n blocking: []\n };\n if (!conflict.blocking.some(b => b.column === mutation.column && b.kind === mutation.kind)) {\n conflict.blocking.push({ column: mutation.column, kind: mutation.kind });\n }\n conflicts.set(key, conflict);\n }\n }\n\n const ordered = [...conflicts.values()];\n for (const conflict of ordered) conflict.blocking.sort((a, b) => a.column.localeCompare(b.column));\n return ordered.sort((a, b) => `${a.schema}.${a.table}.${a.column}`.localeCompare(`${b.schema}.${b.table}.${b.column}`));\n}\n\n/**\n * Split the conflicts into the ones Rebase can rebuild and the ones it cannot.\n *\n * `managed` is decided by the very list that hid the column from Atlas: a\n * `schema.table.column` exclude pattern means Rebase generated the column and\n * `search.sql` will put it back. Anything else is somebody's hand-written\n * generated column — dropping it would destroy a definition Rebase has no copy\n * of, so it is reported and the push stops instead.\n */\nexport function partitionByOwnership(\n conflicts: GeneratedColumnConflict[],\n excludePatterns: string[]\n): { managed: GeneratedColumnConflict[]; foreign: GeneratedColumnConflict[] } {\n const owned = new Set(excludePatterns);\n const managed: GeneratedColumnConflict[] = [];\n const foreign: GeneratedColumnConflict[] = [];\n for (const conflict of conflicts) {\n // Spelled the way the exclude was, so a name holding a `.` or glob\n // syntax is still recognised as ours.\n const target = atlasExcludePattern(conflict.schema, conflict.table, conflict.column);\n (owned.has(target) ? managed : foreign).push(conflict);\n }\n return { managed, foreign };\n}\n\n/**\n * `ALTER TABLE … DROP COLUMN …` for each conflict, in catalogue order.\n *\n * `ifExists` is for the migration path, where the statement is written now and\n * runs later against a database nobody can inspect: on a fresh one the column\n * does not exist yet (the migration is about to create the table), on a live\n * one it does, and the same file has to survive both.\n */\nexport function dropGeneratedColumnStatements(\n conflicts: GeneratedColumnConflict[],\n opts: { ifExists?: boolean } = {}\n): string[] {\n const guard = opts.ifExists ? \"IF EXISTS \" : \"\";\n return conflicts.map(c => `ALTER TABLE \"${c.schema}\".\"${c.table}\" DROP COLUMN ${guard}\"${c.column}\";`);\n}\n\n/**\n * The preamble a migration needs when it retypes a column a search block reads.\n *\n * Prepended, because the drop has to precede the `ALTER COLUMN … TYPE` that\n * PostgreSQL would otherwise refuse. The column comes back at the end of the\n * same migration: `db generate` appends `search.sql`, whose\n * `ADD COLUMN IF NOT EXISTS` rebuilds the column, its index and its stamp.\n */\nexport function migrationDropPreamble(conflicts: GeneratedColumnConflict[]): string {\n if (conflicts.length === 0) return \"\";\n const reasons = conflicts.map(c => {\n const reads = c.blocking.map(b => `${b.column} (${b.kind})`).join(\", \");\n return `-- ${describeConflict(c)} reads ${reads}`;\n });\n return [\n \"-- Rebase: generated columns removed so the statements below can run.\",\n \"-- PostgreSQL refuses to retype or drop a column while a GENERATED\",\n \"-- ALWAYS AS … STORED expression reads it.\",\n ...reasons,\n \"-- The search DDL appended at the end of this migration rebuilds them.\",\n ...dropGeneratedColumnStatements(conflicts, { ifExists: true }),\n \"\"\n ].join(\"\\n\");\n}\n\n/** `public.posts.search_vector`, the way every message here names one. */\nexport function describeConflict(conflict: GeneratedColumnConflict): string {\n return `${conflict.schema}.${conflict.table}.${conflict.column}`;\n}\n","/**\n * Keep the objects Rebase carved out of Atlas's view out of the migrations\n * Atlas writes.\n *\n * `db push` protects them with `--exclude`. `atlas migrate diff` has no such\n * flag — measured on the pinned 1.2.3, `--exclude` is rejected outright with\n * `unknown flag`, and the `exclude` attribute of an `atlas.hcl` `env` block is\n * accepted and then silently ignored on that path. So the diff sees the search\n * column that the migration directory's own appended DDL created when it\n * replayed, does not see it in `schema.sql`, and plans a drop:\n *\n * ALTER TABLE \"public\".\"talents\" DROP COLUMN \"search_vector\";\n *\n * That statement is removed here, after Atlas has written the file and before\n * anything is appended to it — so the input is always Atlas's own plain output,\n * never the dollar-quoted helper bodies that get appended afterwards.\n *\n * The drop does not arrive alone. Atlas folds every change to one table into a\n * single statement, so a real edit in the same run produces\n *\n * ALTER TABLE \"public\".\"talents\"\n * DROP COLUMN \"search_vector\", DROP COLUMN \"interests\", ADD COLUMN \"headline\" text NULL;\n *\n * and dropping the whole statement would silently throw away a migration the\n * project asked for. The removal is therefore per *clause*.\n *\n * Fail-safe throughout: a statement that mentions a carved-out object but does\n * not match a shape this understands is left exactly as it is and reported as\n * `unhandled`, so the caller can say so out loud. A spurious drop the developer\n * can see beats a migration quietly rewritten wrong.\n */\n\nimport { excludePatternParts } from \"./atlas-exclude\";\n\n/** Anything Postgres accepts in an unquoted identifier past ASCII. */\nconst IDENT = \"(?:\\\"(?:[^\\\"]|\\\"\\\")*\\\"|[A-Za-z_\\\\u0080-\\\\uffff][\\\\w$\\\\u0080-\\\\uffff]*)\";\nconst QUALIFIED = `${IDENT}(?:\\\\s*\\\\.\\\\s*${IDENT})*`;\n\nconst ALTER_TABLE_RE = new RegExp(`^ALTER\\\\s+TABLE\\\\s+(?:ONLY\\\\s+)?(${QUALIFIED})\\\\s+([\\\\s\\\\S]+)$`, \"i\");\nconst DROP_COLUMN_RE = new RegExp(`^DROP\\\\s+(?:COLUMN\\\\s+)?(?:IF\\\\s+EXISTS\\\\s+)?(${IDENT})$`, \"i\");\nconst DROP_INDEX_RE = new RegExp(`^DROP\\\\s+INDEX\\\\s+(?:CONCURRENTLY\\\\s+)?(?:IF\\\\s+EXISTS\\\\s+)?(${QUALIFIED})$`, \"i\");\n\n/**\n * Does this statement destroy anything at all?\n *\n * The gate on reporting. A statement that merely *names* a carved-out object —\n * `COMMENT ON COLUMN … \"search_vector\"` — is not a problem and must not be\n * reported as one, because an unrewritable drop stops the caller outright.\n */\nconst MENTIONS_DROP = /\\bDROP\\b/i;\n\n/** One `schema.table.object` exclude pattern, taken apart. */\nexport interface CarvedOutObject {\n schema: string;\n table: string;\n object: string;\n}\n\nexport interface StripResult {\n /** The migration text with the carved-out clauses gone. */\n sql: string;\n /** What was removed, as SQL fragments, for reporting. */\n removed: string[];\n /**\n * Statements naming a carved-out object that this could not rewrite with\n * confidence. Left untouched in `sql`.\n */\n unhandled: string[];\n /** True when nothing but comments and whitespace survives. */\n empty: boolean;\n}\n\n/**\n * Split `schema.table.object` patterns back into the names they were built\n * from (`excludePatternParts`, the inverse of how every exclude is spelled).\n * Anything not in three parts is ignored rather than guessed at — the two-part\n * form is the one Atlas itself silently mis-reads, and repeating that mistake\n * here would be worse than doing nothing.\n */\nexport function parseExcludePatterns(patterns: string[]): CarvedOutObject[] {\n const parsed: CarvedOutObject[] = [];\n for (const pattern of patterns) {\n const parts = excludePatternParts(pattern);\n if (parts === undefined || parts.length !== 3) continue;\n if (parts.some((p) => p.length === 0)) continue;\n parsed.push({ schema: parts[0], table: parts[1], object: parts[2] });\n }\n return parsed;\n}\n\n/** `\"public\"` and `public` are the same name; `\"Public\"` is not `public`. */\nfunction unquoteIdentifier(raw: string): string {\n const trimmed = raw.trim();\n if (trimmed.startsWith(\"\\\"\") && trimmed.endsWith(\"\\\"\") && trimmed.length >= 2) {\n return trimmed.slice(1, -1).replace(/\"\"/g, \"\\\"\");\n }\n // An unquoted identifier is folded to lower case by Postgres.\n return trimmed.toLowerCase();\n}\n\n/** Split a dotted identifier at its top-level dots, respecting quoting. */\nfunction splitQualifiedName(raw: string): string[] | null {\n const parts: string[] = [];\n let current = \"\";\n let inQuote = false;\n for (let i = 0; i < raw.length; i++) {\n const ch = raw[i];\n if (inQuote) {\n if (ch === \"\\\"\") {\n if (raw[i + 1] === \"\\\"\") { current += \"\\\"\\\"\"; i++; continue; }\n inQuote = false;\n }\n current += ch;\n continue;\n }\n if (ch === \"\\\"\") { inQuote = true; current += ch; continue; }\n if (ch === \".\") { parts.push(current); current = \"\"; continue; }\n current += ch;\n }\n if (inQuote) return null;\n parts.push(current);\n return parts.map(unquoteIdentifier);\n}\n\n/**\n * One statement located in the source text, with the comment lines that\n * introduce it. Atlas writes `-- Modify \"talents\" table` above each statement;\n * removing the statement without its comment leaves a caption over nothing.\n */\ninterface LocatedStatement {\n /** Offset of the first character of the leading comment block. */\n start: number;\n /** Offset just past the terminating semicolon. */\n end: number;\n /** Offset of the first character of the statement itself. */\n bodyStart: number;\n /** The statement without its leading comments or trailing semicolon. */\n body: string;\n}\n\n/**\n * Walk the script and locate every statement. Quote-, comment- and\n * dollar-aware: the appended halves of a migration are not passed here, but a\n * splitter that shreds a `DO $tag$ ... $tag$` block is a trap worth not\n * leaving behind — it is how the derived-names renderer broke.\n *\n * Returns null if the text ends inside a quote or a dollar-quoted body, or\n * trails off in a statement with no semicolon. Either means this cannot be\n * reasoned about safely.\n */\nfunction locateStatements(sql: string): LocatedStatement[] | null {\n const statements: LocatedStatement[] = [];\n let i = 0;\n let statementStart = 0;\n let sawCode = false;\n\n const pushStatement = (endExclusive: number) => {\n const leading = sql.slice(statementStart, endExclusive);\n // The leading run of comment/blank lines belongs to this statement.\n let consumed = 0;\n for (const line of leading.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"\" || trimmed.startsWith(\"--\")) {\n consumed += line.length + 1;\n continue;\n }\n break;\n }\n const bodyStart = statementStart + consumed;\n statements.push({\n start: statementStart,\n end: endExclusive,\n bodyStart,\n body: sql.slice(bodyStart, endExclusive).replace(/;\\s*$/, \"\").trim()\n });\n };\n\n while (i < sql.length) {\n const ch = sql[i];\n\n if (ch === \"-\" && sql[i + 1] === \"-\") {\n const nl = sql.indexOf(\"\\n\", i);\n i = nl === -1 ? sql.length : nl + 1;\n continue;\n }\n if (ch === \"/\" && sql[i + 1] === \"*\") {\n const close = sql.indexOf(\"*/\", i + 2);\n if (close === -1) return null;\n i = close + 2;\n sawCode = true;\n continue;\n }\n if (ch === \"'\" || ch === \"\\\"\") {\n const quote = ch;\n i++;\n let closed = false;\n while (i < sql.length) {\n if (sql[i] === quote) {\n if (sql[i + 1] === quote) { i += 2; continue; }\n i++;\n closed = true;\n break;\n }\n i++;\n }\n if (!closed) return null;\n sawCode = true;\n continue;\n }\n if (ch === \"$\") {\n const tag = /^\\$(?:[A-Za-z_\\u0080-\\uffff][\\w\\u0080-\\uffff]*)?\\$/.exec(sql.slice(i));\n if (tag) {\n const close = sql.indexOf(tag[0], i + tag[0].length);\n if (close === -1) return null;\n i = close + tag[0].length;\n sawCode = true;\n continue;\n }\n }\n if (ch === \";\") {\n pushStatement(i + 1);\n i++;\n statementStart = i;\n sawCode = false;\n continue;\n }\n if (!/\\s/.test(ch)) sawCode = true;\n i++;\n }\n\n // Trailing text with no semicolon: only comments and whitespace is fine.\n if (sawCode) return null;\n return statements;\n}\n\n/** Split an ALTER TABLE action list at its top-level commas. */\nfunction splitClauses(actions: string): string[] | null {\n const clauses: string[] = [];\n let depth = 0;\n let current = \"\";\n let i = 0;\n while (i < actions.length) {\n const ch = actions[i];\n if (ch === \"'\" || ch === \"\\\"\") {\n const quote = ch;\n current += ch;\n i++;\n let closed = false;\n while (i < actions.length) {\n current += actions[i];\n if (actions[i] === quote) {\n if (actions[i + 1] === quote) { current += actions[i + 1]; i += 2; continue; }\n i++;\n closed = true;\n break;\n }\n i++;\n }\n if (!closed) return null;\n continue;\n }\n if (ch === \"(\") { depth++; current += ch; i++; continue; }\n if (ch === \")\") { depth--; current += ch; i++; continue; }\n if (ch === \",\" && depth === 0) { clauses.push(current); current = \"\"; i++; continue; }\n current += ch;\n i++;\n }\n if (depth !== 0) return null;\n clauses.push(current);\n return clauses.map((c) => c.trim()).filter((c) => c.length > 0);\n}\n\n/**\n * Remove every clause and statement that would drop one of `patterns`.\n *\n * `patterns` are the `schema.table.object` strings the CLI already builds for\n * Atlas's `--exclude`, so the diff path and the apply path protect exactly the\n * same set by construction.\n */\nexport function stripCarvedOutStatements(migrationSql: string, patterns: string[]): StripResult {\n const carved = parseExcludePatterns(patterns);\n if (carved.length === 0) {\n return { sql: migrationSql, removed: [], unhandled: [], empty: isBlank(migrationSql) };\n }\n\n const located = locateStatements(migrationSql);\n if (located === null) {\n // Nothing can be trusted about the offsets, so nothing moves. Worth\n // stopping the caller over only if one of ours is being dropped in\n // there; otherwise this file has nothing to do with us.\n const atStake = MENTIONS_DROP.test(migrationSql)\n && carved.some((c) => migrationSql.includes(c.object));\n return {\n sql: migrationSql,\n removed: [],\n unhandled: atStake ? [migrationSql.trim()] : [],\n empty: isBlank(migrationSql)\n };\n }\n\n const removed: string[] = [];\n const unhandled: string[] = [];\n // Edits as [start, end) → replacement, applied back-to-front so the\n // offsets of the ones still pending stay valid.\n const edits: { start: number; end: number; replacement: string }[] = [];\n\n for (const statement of located) {\n if (!carved.some((c) => statement.body.includes(c.object))) continue;\n\n const dropIndex = DROP_INDEX_RE.exec(statement.body);\n if (dropIndex) {\n const parts = splitQualifiedName(dropIndex[1]);\n const name = parts?.[parts.length - 1];\n const schema = parts && parts.length > 1 ? parts[parts.length - 2] : undefined;\n if (name !== undefined && carved.some((c) =>\n c.object === name && (schema === undefined || c.schema === schema))) {\n removed.push(statement.body);\n edits.push({ start: statement.start, end: statement.end, replacement: \"\" });\n } else {\n // A near-miss on the name — some other index whose name\n // contains ours. Left alone, and still a drop, so still\n // reported.\n unhandled.push(statement.body);\n }\n continue;\n }\n\n // Anything else naming a carved-out object is only our business if it\n // destroys something. `COMMENT ON COLUMN … \"search_vector\"` does not.\n const alter = ALTER_TABLE_RE.exec(statement.body);\n if (!alter) {\n if (MENTIONS_DROP.test(statement.body)) unhandled.push(statement.body);\n continue;\n }\n\n const target = splitQualifiedName(alter[1]);\n if (!target) {\n if (MENTIONS_DROP.test(statement.body)) unhandled.push(statement.body);\n continue;\n }\n const table = target[target.length - 1];\n const schema = target.length > 1 ? target[target.length - 2] : undefined;\n\n const clauses = splitClauses(alter[2]);\n if (!clauses) {\n if (MENTIONS_DROP.test(statement.body)) unhandled.push(statement.body);\n continue;\n }\n\n const survivors: string[] = [];\n let removedHere = 0;\n let unhandledHere = false;\n for (const clause of clauses) {\n const drop = DROP_COLUMN_RE.exec(clause);\n const column = drop ? unquoteIdentifier(drop[1]) : undefined;\n const isCarved = column !== undefined && carved.some((c) =>\n c.object === column &&\n c.table === table &&\n (schema === undefined || c.schema === schema));\n if (isCarved) {\n removed.push(`ALTER TABLE ${alter[1]}: ${clause}`);\n removedHere++;\n continue;\n }\n // A clause naming a carved-out object in some other shape is not\n // something to guess at — if it destroys it.\n if (MENTIONS_DROP.test(clause) && carved.some((c) => clause.includes(c.object))) {\n unhandledHere = true;\n }\n survivors.push(clause);\n }\n\n if (unhandledHere) unhandled.push(statement.body);\n if (removedHere === 0) continue;\n\n if (survivors.length === 0) {\n edits.push({ start: statement.start, end: statement.end, replacement: \"\" });\n } else {\n edits.push({\n start: statement.bodyStart,\n end: statement.end,\n replacement: `ALTER TABLE ${alter[1]} ${survivors.join(\", \")};`\n });\n }\n }\n\n let sql = migrationSql;\n for (const edit of edits.sort((a, b) => b.start - a.start)) {\n sql = sql.slice(0, edit.start) + edit.replacement + sql.slice(edit.end);\n }\n if (edits.length > 0) sql = tidy(sql);\n\n return { sql, removed, unhandled, empty: isBlank(sql) };\n}\n\n/** Only comments and whitespace left — nothing a migration would do. */\nfunction isBlank(sql: string): boolean {\n return sql\n .split(\"\\n\")\n .every((line) => line.trim() === \"\" || line.trim().startsWith(\"--\"));\n}\n\n/** Collapse the blank runs an excision leaves behind. */\nfunction tidy(sql: string): string {\n const trimmed = sql.replace(/\\n{3,}/g, \"\\n\\n\").replace(/^\\s*\\n/, \"\").trimEnd();\n return trimmed.length === 0 ? \"\" : `${trimmed}\\n`;\n}\n","import fs from \"fs\";\n\n/**\n * What became of a migration `db generate` was finishing.\n *\n * `removed` says whether the half-finished file is gone; `rehashError` is set\n * when it is gone but `atlas.sum` could not be brought back in line with the\n * directory, which `atlas migrate` then refuses with a checksum error — loud,\n * which is the point.\n */\nexport type MigrationPostProcessOutcome =\n | { ok: true }\n | { ok: false; error: string; removed: boolean; rehashError?: string };\n\n/**\n * Run the steps that finish a migration Atlas just wrote — the search, vector\n * and trigger DDL, the RLS bootstrap and policies, the re-hash — and take the\n * migration back out when any of them fails.\n *\n * Atlas's own file creates the tables and nothing else: no `ENABLE ROW LEVEL\n * SECURITY`, no policy. Those arrive in the append. A failure here used to be a\n * yellow warning followed by \"You can now run rebase db migrate\", and when it\n * struck before the file was rewritten the checksum still matched — so the\n * migration applied cleanly and created every new table with RLS off while\n * the schema's default privileges handed `rebase_user` full DML on it. On a\n * deployment that runs migrations and never provisions at boot\n * (`REBASE_MIGRATE_ON_BOOT=none`), nothing closed it again.\n *\n * Deleting the file is safe because it is the one this run created: running\n * `db generate` again, once the cause is fixed, writes the same diff.\n */\nexport async function finishNewMigration(\n file: string,\n steps: () => Promise<void>,\n rehash: () => Promise<void>\n): Promise<MigrationPostProcessOutcome> {\n try {\n await steps();\n return { ok: true };\n } catch (err) {\n const error = err instanceof Error ? err.message : String(err);\n let removed = false;\n try {\n if (fs.existsSync(file)) fs.unlinkSync(file);\n removed = !fs.existsSync(file);\n } catch {\n removed = false;\n }\n if (!removed) return { ok: false, error, removed };\n try {\n await rehash();\n return { ok: false, error, removed };\n } catch (hashErr) {\n return { ok: false, error, removed, rehashError: hashErr instanceof Error ? hashErr.message : String(hashErr) };\n }\n }\n}\n","/**\n * The argv `runAtlas` hands the Atlas binary, as a pure function.\n *\n * Split out of `cli.ts` because the flags an Atlas subcommand accepts are not\n * uniform and getting one wrong is fatal rather than degraded: Atlas rejects an\n * unknown flag before doing any work, so a flag on the wrong subcommand takes\n * the whole command down.\n *\n * `--exclude` is the one that bit. Of the six invocations here, exactly one\n * accepts it. The guard this replaces was `args.includes(\"apply\") ||\n * args.includes(\"diff\")`, and reading it as a *subcommand* test is the trap:\n * `migrate apply` passes `args.includes(\"apply\")` just as `schema apply` does.\n * So the flag went onto three invocations, two of which reject it, and both\n * `rebase db generate` and `rebase db migrate` exited 1 with `unknown flag:\n * --exclude` for every project declaring a `search` block.\n *\n * The domain is half the identity of an Atlas subcommand, and a guard that\n * looks only at `args` cannot tell `schema apply` from `migrate apply`.\n *\n * Nothing here touches a database or the filesystem, so the whole matrix is\n * unit-tested in `atlas-argv.test.ts`.\n */\n\nexport interface AtlasInvocation {\n /** `schema` or `migrate`. */\n domain: string;\n /** The subcommand and its own flags, e.g. `[\"diff\", \"--dir\", \"file://…\"]`. */\n args: string[];\n /** The target database, already rewritten for libpq. */\n url: string;\n /** The database Atlas plans against, already rewritten for libpq. */\n devUrl: string;\n /**\n * Everything the caller resolved for `--exclude`, in the order it should\n * appear. Dropped entirely when the subcommand does not accept the flag —\n * see {@link acceptsExcludeFlag}.\n */\n excludes?: string[];\n /**\n * The target is one database session that every connection shares — the\n * managed development database (PGlite). See {@link buildAtlasArgs} for\n * what that changes.\n */\n singleSession?: boolean;\n}\n\n/**\n * Does this Atlas invocation accept `--exclude`?\n *\n * Only `atlas schema apply` does, on the pinned 1.2.3. Measured against the\n * binary: `migrate diff` and `migrate apply` both answer `unknown flag:\n * --exclude`, and neither lists it in `--help` (`migrate apply` offers\n * `--url/--dir/--format/--revisions-schema/--dry-run/--lock-name/--lock-timeout/`\n * `--skip-lock/--baseline/--to-version/--tx-mode/--exec-order/--allow-dirty`).\n * Hence `domain === \"schema\"` and not just the subcommand.\n *\n * The `exclude` attribute of an `atlas.hcl` `env` block is not a way round it\n * either: measured, it is accepted and then ignored on the diff path, which is\n * the silent-no-match shape that costs the most time to notice.\n *\n * So the diff keeps the carved-out objects out of the migration afterwards\n * instead, with `stripCarvedOutStatements`.\n */\nexport function acceptsExcludeFlag(domain: string, args: string[]): boolean {\n return domain === \"schema\" && args.includes(\"apply\");\n}\n\n/**\n * Does this Atlas invocation plan against the scratch database (`--dev-url`)?\n *\n * `schema apply` and `migrate diff` do; `migrate apply`, `hash` and `status`\n * never read it, so `db migrate` has no reason to create one.\n */\nexport function takesDevUrl(domain: string, args: string[]): boolean {\n return (domain === \"schema\" && args.includes(\"apply\"))\n || (domain === \"migrate\" && args.includes(\"diff\"));\n}\n\n/**\n * Does this Atlas invocation read or write the revisions table\n * (`rebase.atlas_schema_revisions`)? `migrate apply`, `set` and `status` do;\n * they are the ones handed `--revisions-schema`.\n */\nexport function readsRevisions(domain: string, args: string[]): boolean {\n return domain === \"migrate\" && (args.includes(\"apply\") || args.includes(\"status\") || args.includes(\"set\"));\n}\n\n/**\n * Assemble the full argv, connection flags and all.\n *\n * On a single-session database `migrate apply` skips its advisory lock. The\n * lock is session-level, and a session every connection shares grants it to\n * all of them, so it excludes no one; what it does cost there is a connection.\n * The managed database accepts four and a running `rebase dev` holds two, so\n * `migrate apply`'s third — its own, the lock's, the revisions table's — was\n * closed unanswered and Atlas said only `Error: EOF`. `migrate set`, which has\n * no `--skip-lock`, is bound to the revisions schema instead, which spares it\n * the revisions table's connection.\n */\nexport function buildAtlasArgs(invocation: AtlasInvocation): string[] {\n const { domain, args, url, devUrl, excludes = [], singleSession = false } = invocation;\n const argv = [domain, ...args];\n\n if (domain === \"schema\") {\n if (args.includes(\"apply\")) {\n argv.push(\"--url\", url, \"--dev-url\", devUrl);\n } else if (args.includes(\"clean\") || args.includes(\"inspect\")) {\n argv.push(\"--url\", url);\n }\n } else if (domain === \"migrate\") {\n if (args.includes(\"diff\")) {\n argv.push(\"--dev-url\", devUrl);\n } else if (args.includes(\"set\") && singleSession) {\n // `migrate set` takes no `--skip-lock`, and with `--revisions-schema`\n // it opens a second client for that schema: three connections, of\n // which beside a running `rebase dev` the third was closed\n // unanswered (`EOF`). Bound to the schema the table is in, Atlas\n // reads and writes it on the connection it already has — two.\n argv.push(\"--url\", withSearchPath(url, \"rebase\"));\n } else if (readsRevisions(domain, args)) {\n argv.push(\"--url\", url, \"--revisions-schema\", \"rebase\");\n // Measured against the pinned binary: `sql/migrate: baseline and\n // allow-dirty are mutually exclusive`. `--baseline` is the caller's\n // explicit answer to the same question `--allow-dirty` answers by\n // default, so it wins, and adding both would refuse the command.\n if (args.includes(\"apply\") && !args.includes(\"--baseline\")) {\n argv.push(\"--allow-dirty\");\n }\n // Only `apply` takes it: `migrate set` and `status` take no lock.\n if (args.includes(\"apply\") && singleSession) {\n argv.push(\"--skip-lock\");\n }\n }\n }\n\n // Second line of defence, deliberately not a caller's responsibility: a\n // future caller that resolves excludes for the diff path gets them dropped\n // here rather than a command that will not run.\n if (acceptsExcludeFlag(domain, args)) {\n for (const exclude of excludes) {\n argv.push(\"--exclude\", exclude);\n }\n }\n\n return argv;\n}\n\n/**\n * The URL with its `search_path` set to `schema`: an Atlas URL bound to that\n * schema. Every other parameter is kept as written. A URL that does not\n * parse is returned unchanged.\n */\nfunction withSearchPath(url: string, schema: string): string {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return url;\n }\n const params = Array.from(parsed.searchParams.entries()).filter(([key]) => key !== \"search_path\");\n params.push([\"search_path\", schema]);\n // By hand, as `forLibpq` re-serializes: URLSearchParams writes a space as\n // `+`, which libpq does not read as one.\n parsed.search = params.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join(\"&\");\n return parsed.toString();\n}\n\n/**\n * `atlas migrate apply`'s own arguments for `rebase db migrate`.\n *\n * `positionals` are what is left of the user's line once every flag the\n * driver knows has been consumed — at most the optional amount Atlas takes. A\n * flag reaching here is a flag Atlas rejects before doing any work.\n */\nexport function migrateApplyArgs(positionals: string[], baseline: string | undefined): string[] {\n return [\n \"apply\",\n \"--dir\", \"file://drizzle/migrations\",\n ...(baseline ? [\"--baseline\", baseline] : []),\n ...positionals.filter(positional => positional !== \"migrate\")\n ];\n}\n","/**\n * Atlas's revisions table on the managed development database, made by Rebase.\n *\n * `rebase db migrate` passes `--revisions-schema rebase`, so Atlas keeps its\n * history in `rebase.atlas_schema_revisions`. Atlas finds that table by\n * qualified name, but creates it through a second connection whose startup\n * message sets `search_path=rebase`, with an unqualified `CREATE TABLE`. The\n * managed database is one PGlite session that every connection shares, so a\n * connection's own `search_path` is never applied: the table landed in\n * `public`, the read that followed failed on `relation\n * \"rebase.atlas_schema_revisions\" does not exist (42P01)`, and every later run\n * failed on `relation \"atlas_schema_revisions\" already exists (42P07)`, with or\n * without `--baseline`.\n *\n * So on that database the table is created here first, qualified, and Atlas\n * finds it where it looks. The definition is Atlas's own for the pinned\n * `@ariga/atlas`, read off a table Atlas created on PostgreSQL 18. Should a\n * later Atlas want a different one, it alters the table through the same\n * unqualified path and fails loudly there, and the managed `db migrate`\n * integration test fails with it.\n *\n * Not used on any other database: there the connection's `search_path` holds,\n * and Atlas creates and maintains its table itself.\n */\nimport { withAppClient } from \"../cli-helpers\";\n\n/** Atlas's revisions table, in the schema `--revisions-schema rebase` names. */\nexport const ATLAS_REVISIONS_TABLE_SQL = `CREATE SCHEMA IF NOT EXISTS \"rebase\";\nCREATE TABLE IF NOT EXISTS \"rebase\".\"atlas_schema_revisions\" (\n \"version\" character varying NOT NULL,\n \"description\" character varying NOT NULL,\n \"type\" bigint NOT NULL DEFAULT 2,\n \"applied\" bigint NOT NULL DEFAULT 0,\n \"total\" bigint NOT NULL DEFAULT 0,\n \"executed_at\" timestamp with time zone NOT NULL,\n \"execution_time\" bigint NOT NULL,\n \"error\" text NULL,\n \"error_stmt\" text NULL,\n \"hash\" character varying NOT NULL,\n \"partial_hashes\" jsonb NULL,\n \"operator_version\" character varying NOT NULL,\n PRIMARY KEY (\"version\")\n);`;\n\n/** Create `rebase.atlas_schema_revisions` if it is not there yet. */\nexport async function ensureAtlasRevisionsTable(databaseUrl: string): Promise<void> {\n await withAppClient(databaseUrl, client => client.query(ATLAS_REVISIONS_TABLE_SQL));\n}\n","/**\n * Atlas's `schema apply --auto-approve` report, as `rebase db push` shows it.\n *\n * Atlas prints its plan (\"Planning migration statements …\"), a separator, and\n * then the run (\"Applying approved migration …\"), echoing every statement in\n * both. The push has planned already — the plan it gated on, which a\n * destructive change listed in full — so the first section is a repeat, and a\n * reader saw each statement twice in a row. The run's section is kept: it is\n * the progress, the `-- ok` per statement and the summary.\n */\n\nconst PLANNING_HEADER = /^Planning migration statements\\b/;\n/** The separator Atlas ends a section with, at the start of a line. */\nconst SECTION_SEPARATOR = /^-{3,}\\s*$/;\n\nexport interface ApplyReportFilter {\n /** The part of `chunk` to show, whole lines only; a partial line waits for the next chunk. */\n push(chunk: string): string;\n /** What is left once the stream has ended. */\n flush(): string;\n}\n\n/**\n * A stream filter that drops the planning section of an apply report, its\n * separator and the blank line after it, and passes everything else through\n * unchanged. A report with no planning section (`Schema is synced…`, an\n * error) comes out as it went in.\n */\nexport function createApplyReportFilter(): ApplyReportFilter {\n let pending = \"\";\n let state: \"pass\" | \"planning\" | \"after-separator\" = \"pass\";\n\n const keep = (line: string): boolean => {\n if (state === \"pass\" && PLANNING_HEADER.test(line)) {\n state = \"planning\";\n return false;\n }\n if (state === \"planning\") {\n if (SECTION_SEPARATOR.test(line)) state = \"after-separator\";\n return false;\n }\n if (state === \"after-separator\") {\n state = \"pass\";\n if (line.trim() === \"\") return false;\n }\n return true;\n };\n\n return {\n push(chunk) {\n pending += chunk;\n const lines = pending.split(\"\\n\");\n pending = lines.pop() ?? \"\";\n return lines.filter(keep).map((line) => `${line}\\n`).join(\"\");\n },\n flush() {\n const rest = pending;\n pending = \"\";\n return rest !== \"\" && keep(rest) ? rest : \"\";\n }\n };\n}\n","/**\n * The scratch database Atlas plans against, for the length of one db command.\n *\n * `atlas schema apply` and `atlas migrate diff` need a `--dev-url`: an empty\n * database they build the desired state in, made as `<db>_dev_diff` beside the\n * real one. It is a full copy of the schema, so it is removed again once the\n * command that made it has succeeded — every such command, not only an applied\n * `db push`: a `--dry-run` that left one behind while saying nothing was\n * applied, and `db generate`, left one per target on the server.\n *\n * It is dropped on every way out of the command: success, a destructive push\n * the user declined or that had no terminal to ask, and a crash. A crash that\n * kept it left it for good, because the next push finds it already there and\n * takes it for one made by hand.\n *\n * Two cases keep it. An Atlas run that failed while planning against it leaves\n * the state Atlas was planning, which is the one thing worth inspecting. And\n * one this process did not create (made by hand, the remedy for a role without\n * `CREATEDB`) is the user's, and dropping it would put them back at the same\n * refusal next time. An Atlas run that failed before planning (see\n * {@link atlasFailedBeforePlanning}) left nothing in it, and it is dropped.\n */\nexport interface ScratchDatabaseOps {\n /** Create it if it is missing; `true` only when this call created it. */\n create(databaseUrl: string, devDatabaseUrl: string): Promise<boolean>;\n drop(databaseUrl: string, devDatabaseUrl: string): Promise<void>;\n}\n\nexport class ScratchDatabase {\n private created: { databaseUrl: string; devDatabaseUrl: string } | undefined;\n private keptAsEvidence = false;\n\n constructor(private readonly ops: ScratchDatabaseOps) {}\n\n /** Make sure it exists before an Atlas call that plans against it. */\n async ensure(databaseUrl: string, devDatabaseUrl: string): Promise<void> {\n if (await this.ops.create(databaseUrl, devDatabaseUrl)) {\n this.created = { databaseUrl, devDatabaseUrl };\n }\n }\n\n /** An Atlas run against it failed: keep it, whatever the command does next. */\n keepAsEvidence(): void {\n this.keptAsEvidence = true;\n }\n\n /**\n * An Atlas run failed with `stderr`. Failing before it planned, it left\n * nothing here to read, so the database is dropped now — before the\n * command exits, which may not unwind through {@link around}. Otherwise\n * it is kept as the evidence.\n */\n async afterAtlasFailure(stderr: string): Promise<void> {\n if (atlasFailedBeforePlanning(stderr)) await this.release();\n else this.keepAsEvidence();\n }\n\n /**\n * Run a command, then drop the scratch database if the command created it,\n * whether the command returned or threw. A throw after\n * {@link keepAsEvidence} keeps it. A command that wants to stop with exit 1\n * throws {@link CommandStopped} rather than calling `process.exit`, which\n * would skip this.\n */\n async around<T>(command: () => Promise<T>): Promise<T> {\n let result: T;\n try {\n result = await command();\n } catch (err) {\n if (!this.keptAsEvidence) await this.release();\n throw err;\n }\n await this.release();\n return result;\n }\n\n /** Drop it now if this process created it. Safe to call twice. */\n async release(): Promise<void> {\n const created = this.created;\n if (!created) return;\n this.created = undefined;\n await this.ops.drop(created.databaseUrl, created.devDatabaseUrl);\n }\n}\n\n/**\n * Whether Atlas failed before it planned anything: on connecting, which it\n * reports as `querying system variables: …` — SSL the server does not offer, a\n * login refused, a socket that closed or never opened.\n */\nexport function atlasFailedBeforePlanning(stderr: string): boolean {\n return /querying system variables:/.test(stderr);\n}\n\n/**\n * A db command stopping with exit 1 after it has said why: a destructive push\n * the user declined, or one with no terminal to ask on.\n *\n * Thrown instead of `process.exit(1)`, so it unwinds through\n * {@link ScratchDatabase.around} and the scratch database is dropped on the way\n * out. `alreadyReported` tells `reportCommandFailure` the explanation is on the\n * terminal already; the entry point sets the exit code.\n */\nexport class CommandStopped extends Error {\n readonly alreadyReported = true;\n\n constructor(reason: string) {\n super(reason);\n this.name = \"CommandStopped\";\n }\n}\n","/**\n * What `rebase db migrate --baseline <version>` does, given the history the\n * database already has.\n *\n * The flag promises to record `<version>` as applied and migrate from the next\n * one. Atlas's own `migrate apply --baseline` keeps that promise only on a\n * database with no revision history: once one row exists it ignores the flag\n * without a word, applies the migration anyway, and the CLI had already printed\n * \"Recording … as already applied\". That is the normal second time: a project\n * baselines once, then `rebase dev` adds a column at boot, `db generate` writes\n * the migration for it, and `db migrate` fails on `column … already exists\n * (42701)` however the baseline is spelled.\n *\n * So the history is read first. With none, Atlas's baseline does the work.\n * Behind `<version>`, `atlas migrate set` marks every migration up to it as\n * applied, which is what a baseline means. At or past it, there is nothing to\n * record, and the command says so instead of claiming it recorded something.\n */\nimport { withAppClient } from \"../cli-helpers\";\n\nexport type BaselinePlan =\n /** No history: `migrate apply --baseline <version>`, Atlas's own mechanism. */\n | { kind: \"atlas-baseline\" }\n /** History behind `<version>`: `migrate set <version>`, then a plain apply. */\n | { kind: \"set\"; latest: string }\n /** History at or past `<version>`: nothing to record, a plain apply. */\n | { kind: \"already-recorded\"; latest: string };\n\n/**\n * Atlas's version order for the versions Rebase writes: numeric timestamps,\n * compared as numbers so a shorter one is not read as later; anything else as\n * text.\n */\nexport function compareMigrationVersions(a: string, b: string): number {\n if (/^\\d+$/.test(a) && /^\\d+$/.test(b)) {\n const x = BigInt(a);\n const y = BigInt(b);\n return x === y ? 0 : x < y ? -1 : 1;\n }\n return a.localeCompare(b);\n}\n\n/**\n * The version Atlas records for a migration file: its numeric prefix\n * (`20260906101530_init.sql` → `20260906101530`), or the name without `.sql`.\n */\nexport function migrationVersionOf(file: string): string {\n return /^(\\d+)/.exec(file)?.[1] ?? file.replace(/\\.sql$/, \"\");\n}\n\n/** How many versions a refused baseline names, newest last. */\nconst VERSIONS_NAMED = 5;\n\n/**\n * Why `--baseline <version>` cannot run, or `null` when it names a migration\n * file in `drizzle/migrations`.\n *\n * Asked before anything else, the database included. A version no file has\n * was refused only by Atlas, after the command had said \"Marking every\n * migration up to abc as applied…\"; and one older than every file read\n * \"Nothing to record\" and migrated on, though it named nothing to baseline.\n *\n * @param files the migration files, sorted oldest first.\n * @returns the refusal, its first line the error and the rest the detail.\n */\nexport function baselineVersionProblem(version: string, files: readonly string[]): string | null {\n const versions = files.map(migrationVersionOf);\n if (versions.length === 0) {\n return `--baseline ${version}: There are no migrations in drizzle/migrations to baseline. Nothing was run.\\n` +\n \"Run `rebase db generate` to write the first one.\";\n }\n if (versions.includes(version)) return null;\n const named = versions.slice(-VERSIONS_NAMED).join(\", \");\n const which = versions.length > VERSIONS_NAMED\n ? `The newest ${VERSIONS_NAMED} of the ${versions.length} versions there`\n : \"The versions there\";\n return `--baseline ${version} names no migration in drizzle/migrations. Nothing was run.\\n` +\n `${which}: ${named}. A baseline is one of them: the newest migration the database already holds.`;\n}\n\n/** How to keep `--baseline <version>`'s promise, given the newest recorded version. */\nexport function planBaseline(version: string, latestRecorded: string | null): BaselinePlan {\n if (latestRecorded === null) return { kind: \"atlas-baseline\" };\n if (compareMigrationVersions(version, latestRecorded) > 0) return { kind: \"set\", latest: latestRecorded };\n return { kind: \"already-recorded\", latest: latestRecorded };\n}\n\n/** What the command says before it migrates, for each plan. */\nexport function describeBaselinePlan(version: string, plan: BaselinePlan): string {\n switch (plan.kind) {\n case \"atlas-baseline\":\n return `Recording ${version} as already applied, then migrating from the next one.`;\n case \"set\":\n return `This database already records migrations up to ${plan.latest}, and Atlas applies --baseline only ` +\n `to a database with none.\\n Marking every migration up to ${version} as applied with \\`atlas migrate set\\`, ` +\n \"then migrating from the next one.\";\n case \"already-recorded\":\n return `Nothing to record: this database already records migrations up to ${plan.latest}, which ` +\n `includes ${version}.\\n Migrating from the next one.`;\n }\n}\n\n/**\n * The newest version Atlas has recorded on this database, or `null` when it\n * has recorded none (no revisions table yet included).\n *\n * The table is `rebase.atlas_schema_revisions`: the CLI passes\n * `--revisions-schema rebase` to every `migrate apply`.\n */\nexport async function latestRecordedMigration(databaseUrl: string): Promise<string | null> {\n return withAppClient(databaseUrl, async (client) => {\n const exists = await client.query<{ present: boolean }>(\n \"SELECT to_regclass('rebase.atlas_schema_revisions') IS NOT NULL AS present\"\n );\n if (!exists.rows[0]?.present) return null;\n const rows = await client.query<{ version: string }>(\n \"SELECT version FROM rebase.atlas_schema_revisions WHERE version NOT LIKE '.%'\"\n );\n const versions = rows.rows.map(row => row.version);\n if (versions.length === 0) return null;\n return versions.reduce((latest, version) => (compareMigrationVersions(version, latest) > 0 ? version : latest));\n });\n}\n","import { isSyncedPlan } from \"./schema/destructive-sql\";\n\n/**\n * The steps `rebase db push` takes once the dry-run has been read and gated.\n *\n * Callbacks rather than calls, so the order is testable without a database or\n * an Atlas binary: `cli.ts` itself cannot be loaded by the jest suite.\n */\nexport interface PushApplySteps {\n /** Drop the generated columns that read a column the plan retypes. */\n dropRebuildable: () => Promise<void>;\n /** `atlas schema apply --auto-approve`: Atlas plans again, then applies. */\n atlasApply: () => Promise<void>;\n /** Say what the skipped apply would have printed. */\n reportSynced: () => void;\n /** Put those generated columns back after a failed apply. */\n rebuildAfterFailure: () => Promise<void>;\n /**\n * Everything Atlas cannot see: RLS locks, auth tables, vector, search,\n * triggers, policies, the user role. Runs whether or not Atlas had work.\n */\n afterApply: () => Promise<void>;\n}\n\n/**\n * Apply a planned push.\n *\n * A dry-run that answered \"Schema is synced\" skips the second Atlas run: that\n * run would plan the same diff again (≈0.9 s at 111 tables, 5.5 s at 411 —\n * Atlas's cost grows faster than the table count) and then apply nothing. The\n * steps after it still run, because Atlas cannot see what they own. A plan with\n * anything in it keeps the old flow, including Atlas re-planning at apply time.\n *\n * @returns `\"synced\"` when Atlas was not run again, `\"applied\"` otherwise.\n */\nexport async function applyPushPlan(\n plan: { dryRun: string; rebuildable: number },\n steps: PushApplySteps\n): Promise<\"applied\" | \"synced\"> {\n const synced = isSyncedPlan(plan.dryRun) && plan.rebuildable === 0;\n if (synced) {\n steps.reportSynced();\n } else {\n if (plan.rebuildable > 0) await steps.dropRebuildable();\n try {\n await steps.atlasApply();\n } catch (err) {\n // Atlas rolled its transaction back, so the columns those\n // expressions read are as they were and the definitions in\n // search.sql still fit. Put them back before surfacing the failure:\n // a push that fails must not also leave search broken.\n if (plan.rebuildable > 0) await steps.rebuildAfterFailure();\n throw err;\n }\n }\n await steps.afterApply();\n return synced ? \"synced\" : \"applied\";\n}\n\n/** The one call {@link applyPoliciesFile} needs from a connection. */\nexport interface PolicyConnection {\n query(text: string): Promise<unknown>;\n}\n\n/** What {@link applyPoliciesFile} stamps, and how to read the definitions back. */\nexport interface PolicyStamping {\n /**\n * `policyStampSql` of every table whose policies `policies.sql` creates\n * exactly as the boot would — see {@link stampableTables}.\n */\n statements: string[];\n /**\n * The `search_path` a boot reads policies under, when the connection's own\n * differs. A stamp hashes `pg_get_expr`, which spells a function on the\n * path unqualified: read under `\"$user\", public` with a `rebase` role, the\n * boot's `rebase.uid()` prints as `uid()` and no stamp would ever match.\n */\n searchPath?: string;\n}\n\n/**\n * The tables whose stamp `db push` may write: those every one of whose planned\n * statements `policies.sql` carries, verbatim.\n *\n * A stamp says \"this stored definition is what the plan's statement made\". It\n * is only true of a policy the statement *did* make — and since both are\n * rendered by the same function from the same collections, a table whose\n * statements are all in the file is one whose policies the file just created.\n * Anything else (a hand-edited file, a file generated elsewhere) is not\n * stamped, and the next boot re-applies that table, as before.\n */\nexport function stampableTables<T extends { policyStatements: string[] }>(plans: readonly T[], policiesSql: string): T[] {\n return plans.filter(plan => plan.policyStatements.length > 0\n && plan.policyStatements.every(statement => policiesSql.includes(statement)));\n}\n\n/**\n * Run `policies.sql`, then stamp the policies it created the way a boot does,\n * in the same transaction.\n *\n * Before stamps the push's policies carried none, so the first boot after\n * every push re-applied them all — a DROP and a CREATE per policy, an ACCESS\n * EXCLUSIVE lock per table. Stamped here, that boot finds them current.\n *\n * The file runs in one transaction, as it did as one implicit one: a policy\n * that fails leaves the previous ones in place. The stamps run after it, under\n * a savepoint: a stamp that cannot be written costs the next boot a re-apply,\n * which is what it did before, so it is reported and the policies are kept.\n * Nothing is left set on the connection: `SET LOCAL` ends with the transaction.\n */\nexport async function applyPoliciesFile(\n client: PolicyConnection,\n policiesSql: string,\n stamping: PolicyStamping\n): Promise<{ stamped: number; stampError?: string }> {\n await client.query(\"BEGIN\");\n let stamped = 0;\n let stampError: string | undefined;\n try {\n await client.query(policiesSql);\n if (stamping.statements.length > 0) {\n await client.query(\"SAVEPOINT rebase_policy_stamps\");\n try {\n if (stamping.searchPath) {\n await client.query(`SET LOCAL search_path TO ${stamping.searchPath}`);\n }\n await client.query(stamping.statements.join(\"\\n\"));\n await client.query(\"RELEASE SAVEPOINT rebase_policy_stamps\");\n stamped = stamping.statements.length;\n } catch (err) {\n await client.query(\"ROLLBACK TO SAVEPOINT rebase_policy_stamps\");\n stampError = err instanceof Error ? err.message : String(err);\n }\n }\n await client.query(\"COMMIT\");\n } catch (err) {\n await client.query(\"ROLLBACK\").catch(() => undefined);\n throw err;\n }\n return { stamped, stampError };\n}\n","/**\n * Argument shapes for `rebase db branch`, with no runtime dependencies.\n *\n * Its own module for the same reason `schema/atlas-argv.ts` is: `cli.ts` pulls\n * in chalk, execa and the driver runtime, so a unit test that imports it cannot\n * run. Argv parsing is the part most worth testing and the part least in need\n * of any of that.\n */\nimport arg from \"arg\";\n\nimport { closestWord, RELAYED_FLAGS } from \"./cli-flags\";\n\n/**\n * The flags each driver-side `db branch` action takes, besides the ones the CLI\n * relays on every line (`--database-url`, `--docker`, `--debug`).\n *\n * `switch` is absent: the CLI answers it before the driver is ever spawned.\n * An action not listed here is not checked, so the dispatch can say it does\n * not exist in its own words.\n */\nexport const BRANCH_ACTION_FLAGS: Record<string, arg.Spec> = {\n create: { \"--from\": String, \"--force\": Boolean },\n list: {},\n info: {},\n // `delete` does not ask, but `--yes` is what a script passes to every\n // destructive command; refusing it would break that line for nothing.\n delete: { \"--force\": Boolean, \"--yes\": Boolean, \"-y\": \"--yes\" },\n prune: { \"--older-than\": String, \"--include-dev-diff\": Boolean, \"--yes\": Boolean, \"-y\": \"--yes\" }\n};\n\n/**\n * Refuse a flag `action` does not take, naming the one it was probably meant\n * to be — the same sentence `db backup` and `db restore` say.\n *\n * Throws: the driver's entry turns a thrown error into one red line and exit 1,\n * and this runs before anything connects.\n */\nfunction assertKnownBranchFlags(action: string, rest: readonly string[]): void {\n const spec = BRANCH_ACTION_FLAGS[action];\n if (!spec) return;\n\n const full = { ...RELAYED_FLAGS, ...spec };\n try {\n arg(full, { argv: [...rest] });\n } catch (error) {\n if (!(error instanceof Error) || !(\"code\" in error) || error.code !== \"ARG_UNKNOWN_OPTION\") throw error;\n // arg's wording: `unknown or unexpected option: --froce`.\n const unknown = /option: (\\S+)$/.exec(error.message)?.[1] ?? error.message;\n const typed = unknown.split(\"=\")[0];\n const known = Object.keys(full).filter((flag) => flag.startsWith(\"--\"));\n const suggestion = closestWord(typed, known);\n const own = Object.keys(spec).filter((flag) => flag.startsWith(\"--\"));\n const takes = own.length > 0 ? `it takes ${own.join(\", \")}` : \"it takes no options of its own\";\n throw new Error(\n `\\`rebase db branch ${action}\\` has no option ${typed}` +\n (suggestion ? ` — did you mean ${suggestion}?` : ` — ${takes}.`) +\n \" Nothing was run. See `rebase db branch --help`.\"\n );\n }\n}\n\n/**\n * Words on a `db branch` command line that no argument accounts for.\n *\n * `rebase db branch create alpha beta` created a branch called `alpha` and\n * threw `beta` away without a word. The shapes that produces are all quiet and\n * all wrong: an unquoted name (`create my feature` → `my`), a flag written\n * without its dashes (`create feat from main` → `feat`), a shell that split\n * something you thought was one token. In each case the command succeeds and\n * the branch is not the one asked for — and branch names are the thing you\n * later type to switch, delete, or point a deploy at.\n *\n * A flag the action does not take is refused outright, by throwing — see\n * {@link BRANCH_ACTION_FLAGS}. It was let through on the reasoning that a\n * subcommand added later might take flags this file had never heard of; what\n * that bought was every typo running without the flag it meant:\n * `prune --older-then 1d --yes` pruned by no age, `create x --froce` ran\n * without --force. A new action gets its line in the table. The value after a\n * flag that takes one is skipped: it is that flag's argument, not a stray word.\n *\n * @param words The command's own arguments: action, name, then the rest.\n */\nexport function unexpectedBranchArgs(words: readonly string[]): string[] {\n if (words[0]) assertKnownBranchFlags(words[0], words.slice(1));\n\n const extras: string[] = [];\n\n // 0 is the action (\"create\"); the first bare word after it is the name.\n //\n // Found by scanning rather than by position, which is the fix: `[\"list\",\n // \"--database-url\", \"postgres://…\"]` put a flag in slot 1, so the scan\n // started past it and read the URL as a stray word.\n let seenName = false;\n for (let index = 1; index < words.length; index += 1) {\n const word = words[index];\n if (word.startsWith(\"-\")) {\n if (TAKES_A_VALUE.has(word.split(\"=\")[0])) index += 1;\n continue;\n }\n if (!seenName) {\n seenName = true;\n continue;\n }\n extras.push(word);\n }\n\n return extras;\n}\n\n/**\n * Branch-line flags whose next word belongs to them.\n *\n * `--from` was the only one listed, and `--database-url` is the one that bit:\n * `rebase db branch list --database-url postgres://…` — which the CLI itself\n * appends when the checkout is on a branch, so `rebase.branches` is read in the\n * parent where it lives — answered `✗ Unexpected argument: postgres://…`. The\n * `=` form carries its value in the same word and needs no skip.\n */\nconst TAKES_A_VALUE = new Set([\"--from\", \"--older-than\", \"--database-url\"]);\n","/**\n * `--collections <dir>`, checked once, before anything is written.\n *\n * A path that does not resolve used to warn and carry on. Four times over —\n * `schemaCommand`, `generatePostgresDdlCommand` and the Atlas argv assembly\n * each re-enter the loader with the same line — and then both generators wrote\n * an *empty* schema: `drizzle/schema.sql` truncated to `CREATE SCHEMA IF NOT\n * EXISTS \"rebase\";`, `src/schema.generated.ts` to ten lines. Both were committed\n * artifacts then. The push that followed planned a `DROP TABLE` for every table in\n * the database, and the only thing between a typo and that was the destructive\n * gate.\n *\n * The check has to be here rather than inside `loadCollectionsForCli`, which is\n * deliberately forgiving: its callers use it to narrow what Atlas may touch,\n * and making a broken *file* fatal there would block a push over something\n * unrelated. \"Does the directory the user named exist\" is a different question,\n * it was answerable before the first write, and the code already knew.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { outError } from \"./cli-output\";\n\n/**\n * Thrown rather than exited, so the tests can see it and the entry point owns\n * the exit code.\n *\n * `alreadyReported` is read by `reportCommandFailure`: the full diagnosis is on\n * stderr by the time this is thrown, and the point of the whole change is that\n * it is printed once.\n */\nexport class CollectionsPathMissing extends Error {\n readonly alreadyReported = true;\n\n constructor(readonly typed: string, readonly resolved: string) {\n super(`Collections path not found: \"${typed}\"`);\n this.name = \"CollectionsPathMissing\";\n }\n}\n\n/**\n * The whole message, in one place, because it is printed by two callers.\n *\n * Names what was typed, what it resolved to, and the working directory it\n * resolved against — a relative `--collections` is resolved against the cwd,\n * and the generated npm script runs with `cwd: backend/`, so \"the path is\n * right and the directory is wrong\" is the commonest way to arrive here.\n */\nexport function describeMissingCollectionsPath(typed: string, resolved: string): string {\n return [\n chalk.red(`✗ Collections path not found: \"${typed}\"`),\n chalk.gray(` Resolved to: ${resolved}`),\n chalk.gray(` (relative to cwd: ${process.cwd()})`),\n \"\",\n chalk.gray(\" Nothing was generated and nothing was applied — a schema generated from a\"),\n chalk.gray(\" directory that is not there is an empty one, and applying it would drop\"),\n chalk.gray(\" every table it does not describe.\"),\n \"\",\n chalk.gray(\" Pass an absolute path, or one relative to where you run the command.\")\n ].join(\"\\n\");\n}\n\n/**\n * Refuse a `--collections` path that does not exist.\n *\n * `null` means the flag was not given: the default (`../config/collections`) is\n * left to the loader, which warns and continues — a project may legitimately\n * have no collections directory, and a headless scaffold does.\n */\nexport function assertCollectionsPathExists(typed: string | null): void {\n if (typed === null) return;\n\n const resolved = path.resolve(process.cwd(), typed);\n if (fs.existsSync(resolved)) return;\n\n outError(\"\");\n outError(describeMissingCollectionsPath(typed, resolved));\n outError(\"\");\n throw new CollectionsPathMissing(typed, resolved);\n}\n","/**\n * Which of the two things `rebase db backup …` means.\n *\n * The cloud family spells the listing `rebase cloud db backup list`. Locally\n * the same words *created a backup*: `backup` dispatched straight to\n * `backupCommand`, which parsed permissively and dropped \"list\" into the\n * positionals it never reads. One CLI, two spellings, and the wrong guess wrote\n * a dump instead of reading one — quiet, slow, and on a large database not\n * free.\n *\n * A separate module for the same reason `branch-argv.ts` is one: the decision\n * is pure, and the dispatch it lives in cannot be imported without loading the\n * environment and reaching for a database.\n */\nexport type BackupAction = \"create\" | \"list\";\n\n/**\n * @param rawArgs the driver's whole line, `[\"db\", \"backup\", …]`.\n */\nexport function backupActionOf(rawArgs: readonly string[]): BackupAction {\n return rawArgs[2] === \"list\" ? \"list\" : \"create\";\n}\n","/**\n * What `rebase db branch prune` should remove, decided without a database.\n *\n * Branching had no cleanup story at all: no TTL, no prune, no `delete --all`,\n * and every branch is a **full-size copy** — `CREATE DATABASE ... TEMPLATE`\n * duplicates the files on disk, so five branches of a 100 GB database cost\n * 500 GB. The only way to reclaim any of it was to remember every name you had\n * ever typed.\n *\n * Three things drift apart, and they are not the same problem:\n *\n * 1. **Stale rows** — `rebase.branches` says a branch exists and its database\n * is gone. Someone dropped it with plain SQL, or restored the cluster from\n * a backup taken before it. The row is what `list` reads, so the branch goes\n * on being reported forever; `switch` and `info` then fail against a\n * database nothing can find.\n *\n * 2. **Orphan databases** — an `rb_*` database with no row. `createBranch`\n * creates the database first and records it second, so a crash between the\n * two leaves exactly this: disk consumed by something no Rebase command will\n * ever mention again.\n *\n * 3. **Expired branches** — alive, registered, and older than you meant to keep.\n * This is the ordinary case and the reason the command exists.\n *\n * Atlas's scratch databases are reported alongside but never removed by\n * default. `rebase db push` creates `<db>_dev_diff` to compute its diff against\n * and does not always clean it up, so they accumulate next to the branches and\n * look like them. They are not branches, and one may belong to an Atlas run\n * happening right now — so this names them and leaves the decision to a flag.\n */\n\n/** A branch as `rebase.branches` records it. */\nexport interface BranchRow {\n name: string;\n dbName: string;\n createdAt: Date;\n}\n\nexport interface PrunePlan {\n /** Registered, but the database is gone. Remove the row only. */\n staleRows: BranchRow[];\n /** An `rb_*` database with no row. Drop the database only. */\n orphanDatabases: string[];\n /** Alive, registered, older than the cutoff. Drop both. */\n expired: { branch: BranchRow; ageDays: number }[];\n /** Atlas scratch databases. Reported; removed only when asked. */\n devDiff: string[];\n /**\n * The branch the checkout is switched to, when prune would otherwise have\n * removed it: kept, as `delete` refuses it, and named so the plan says\n * why. `null` when prune would not have touched it.\n */\n active: { name: string; database: string } | null;\n}\n\n/**\n * The variable the CLI hands the driver the database its checkout is switched\n * to in. The pointer is the CLI's (`dev-db/branch-pointer.ts`); the driver is\n * a child process that cannot read it. Spelled the same in\n * `packages/cli/src/commands/db.ts`.\n */\nexport const ACTIVE_BRANCH_DATABASE_ENV = \"REBASE_ACTIVE_BRANCH_DATABASE\";\n\n/** True when nothing at all needs doing. */\nexport function planIsEmpty(plan: PrunePlan, includeDevDiff: boolean): boolean {\n return plan.staleRows.length === 0\n && plan.orphanDatabases.length === 0\n && plan.expired.length === 0\n && (!includeDevDiff || plan.devDiff.length === 0);\n}\n\n/**\n * Age in whole days, floored.\n *\n * Floored rather than rounded so `--older-than 7` never catches something six\n * and a half days old: a prune that removes more than it said it would is worse\n * than one that waits another twelve hours.\n */\nexport function ageInDays(createdAt: Date, now: Date): number {\n return Math.floor((now.getTime() - createdAt.getTime()) / 86_400_000);\n}\n\n/**\n * Parse `--older-than`. Accepts a bare number of days, or `7d` / `2w`.\n *\n * Returns null for anything else, so the caller refuses rather than guessing —\n * silently reading `--older-than 7h` as seven *days* would delete a week of\n * work.\n */\nexport function parseOlderThan(value: string): number | null {\n const match = /^(\\d+)\\s*([dw])?$/i.exec(value.trim());\n if (!match) return null;\n\n const amount = Number(match[1]);\n if (!Number.isFinite(amount)) return null;\n\n return match[2]?.toLowerCase() === \"w\" ? amount * 7 : amount;\n}\n\nexport function planPrune(\n input: {\n rows: readonly BranchRow[];\n /** Every database name on the server. */\n databases: readonly string[];\n branchPrefix: string;\n },\n options: {\n olderThanDays?: number | null;\n now?: Date;\n /** The database the checkout is switched to, which prune never drops. */\n activeDatabase?: string | null;\n } = {}\n): PrunePlan {\n const now = options.now ?? new Date();\n const present = new Set(input.databases);\n const registered = new Set(input.rows.map((row) => row.dbName));\n const isActive = (database: string): boolean => options.activeDatabase != null && database === options.activeDatabase;\n let active: PrunePlan[\"active\"] = null;\n\n const staleRows = input.rows.filter((row) => !present.has(row.dbName));\n\n const orphanDatabases = input.databases\n .filter((name) => name.startsWith(input.branchPrefix) && !registered.has(name))\n .filter((name) => {\n if (!isActive(name)) return true;\n active = { name, database: name };\n return false;\n })\n .sort();\n\n const expired = options.olderThanDays == null\n ? []\n : input.rows\n // A row whose database is already gone is a stale row, not an\n // expired branch — listing it under both would offer to drop a\n // database that does not exist.\n .filter((row) => present.has(row.dbName))\n .map((branch) => ({ branch, ageDays: ageInDays(branch.createdAt, now) }))\n .filter((entry) => entry.ageDays >= options.olderThanDays!)\n .filter((entry) => {\n if (!isActive(entry.branch.dbName)) return true;\n active = { name: entry.branch.name, database: entry.branch.dbName };\n return false;\n })\n .sort((a, b) => b.ageDays - a.ageDays);\n\n const devDiff = input.databases.filter((name) => name.endsWith(\"_dev_diff\")).sort();\n\n return { staleRows, orphanDatabases, expired, devDiff, active };\n}\n","import arg from \"arg\";\nimport chalk from \"chalk\";\nimport { execa } from \"execa\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { out, outWarn, outError } from \"./cli-output\";\nimport { resolveTsxLoader } from \"./tsx-loader\";\nimport { formatRelativeTime } from \"@rebasepro/utils\";\nimport {\n diagnoseMissingBin,\n detectProjectPackageManager,\n describeBuildScriptRemedy,\n describeDevAddCommand,\n describeReinstallCommand,\n workspaceMemberDir,\n resolveLocalBin,\n getTableIncludes,\n atlasDevDatabaseUrl,\n ensureDevDatabaseExists,\n dropDevDatabase,\n applySearchDdl,\n getSearchExcludes,\n readSearchDdl,\n applyVectorDdl,\n getVectorExcludes,\n readVectorDdl,\n applyTriggersDdl,\n getTriggerExcludes,\n readTriggersDdl,\n getTableExcludes,\n getForeignIndexExcludes,\n getUndeclaredConstraintExcludes,\n queryUndeclarableConstraints,\n ExcludeIntrospectionError,\n queryGeneratedColumnDependencies,\n queryColumnTypes,\n dropGeneratedColumns,\n loadCollectionsForCli,\n withAppClient,\n closeAppClients\n} from \"./cli-helpers\";\nimport {\n checkDatabaseConnectivity,\n diagnoseAtlasFailure,\n diagnoseDbError,\n formatForeignGeneratedColumnBanner,\n isAuthFailure,\n isEconnrefused,\n isSslNotEnabled,\n reportCommandFailure\n} from \"./cli-errors\";\nimport { forAtlas, redactConnectionPasswords } from \"./utils/connection-string\";\nimport { dropLegacyAuthSchema, RLS_BOOTSTRAP_SQL } from \"./schema/rls-bootstrap-sql\";\nimport { detectDestructiveStatements, decidePushSafety, destructiveOptInFlag, extractPlanStatements, type DestructiveStatement, type ExistingColumnType } from \"./schema/destructive-sql\";\nimport type { LegacyRename } from \"./schema/push-legacy-renames\";\nimport {\n parseColumnMutations,\n findGeneratedColumnConflicts,\n partitionByOwnership,\n dropGeneratedColumnStatements,\n migrationDropPreamble,\n describeConflict\n} from \"./schema/generated-column-conflicts\";\nimport { stripCarvedOutStatements } from \"./schema/carved-out-migration\";\nimport type { ExistingConstraint } from \"./schema/undeclarable-constraints\";\nimport { finishNewMigration } from \"./schema/migration-post-process\";\nimport { acceptsExcludeFlag, buildAtlasArgs, migrateApplyArgs, readsRevisions, takesDevUrl } from \"./schema/atlas-argv\";\nimport { ensureAtlasRevisionsTable } from \"./schema/atlas-revisions\";\nimport { createApplyReportFilter } from \"./schema/atlas-apply-report\";\nimport { nextStepAfterDbGenerate } from \"./schema/generate-next-step\";\nimport { CommandStopped, ScratchDatabase } from \"./cli-scratch-database\";\nimport { baselineVersionProblem, describeBaselinePlan, latestRecordedMigration, planBaseline } from \"./schema/migrate-baseline\";\nimport { promptConfirm } from \"./cli-prompt\";\nimport { applyPoliciesFile, applyPushPlan, stampableTables, type PolicyStamping } from \"./cli-push\";\nimport { unexpectedBranchArgs } from \"./branch-argv\";\nimport { assertKnownFlags, collectionsPathIn, parseDriverLine } from \"./cli-flags\";\nimport { assertCollectionsPathExists } from \"./cli-collections-path\";\nimport { DESIRED_STATE_URL, GENERATED_SQL_DIR, generatedSqlDir, prepareGeneratedSqlDir } from \"./generated-sql\";\nimport { backupActionOf } from \"./backup-argv\";\nimport type { TableLockResult } from \"./schema/ensure-collection-policies\";\nimport type { DeferredIndexBuild } from \"./schema/plan/diff-plan\";\n\nimport { ACTIVE_BRANCH_DATABASE_ENV, planIsEmpty, planPrune, parseOlderThan } from \"./branch-prune\";\n\nconst __cliDirname = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * A script this CLI spawns, and how to run it.\n *\n * Four commands — `schema generate`, the DDL plan, `introspect` and the schema\n * doctor — run as child processes, located by path relative to this file. That\n * path used to be `<dir>/schema/<name>.ts`, which worked only because `files`\n * shipped `src`. When the tarball stopped shipping `src`, every one of those\n * commands broke for every npm consumer at once: the file was simply absent,\n * and the parent CLI reported the absence as \"Dependencies are not installed\"\n * at projects that had installed perfectly. 0.18.0 shipped that way — a\n * scaffolded project's first `rebase dev` could not regenerate its schema and\n * every `GET /api/data/*` answered `Table not found for collection 'posts'`.\n *\n * The build emits each of them beside this file, so a published copy carries\n * the command surface as an artifact. Source still wins where there is no\n * build, which is how the monorepo runs before `pnpm build`.\n *\n * **The interpreter is tsx either way, and that is not incidental.** These\n * scripts load the *project's* collection files, which are TypeScript and\n * import each other as `./authors.js` — the extension TypeScript tells you to\n * write. Node resolves that literally and fails on a file that does not exist;\n * tsx maps it back. Running the built `.js` under plain `node` therefore fails\n * on the user's code rather than on ours, one directory further from anything\n * the error mentions.\n *\n * tsx's loader in one Node (`node --import`) when it resolves, rather than the\n * `tsx` binary, which is a shell shim and a relay Node in front of that same\n * loader (see `tsx-loader.ts`). The binary stays the fallback — a global tsx.\n * `args` is everything after `bin`, the script included.\n */\nfunction resolveChildScript(name: string):\n | { ok: true; bin: string; args: string[] }\n | { ok: false; reason: \"script\" | \"tsx\" } {\n const built = path.join(__cliDirname, \"schema\", `${name}.js`);\n const source = path.join(__cliDirname, \"schema\", `${name}.ts`);\n const script = fs.existsSync(built) ? built : fs.existsSync(source) ? source : null;\n if (!script) return { ok: false, reason: \"script\" };\n\n const tsxLoader = resolveTsxLoader();\n if (tsxLoader) return { ok: true, bin: process.execPath, args: [\"--import\", tsxLoader, script] };\n\n const tsxBin = resolveLocalBin(\"tsx\");\n if (!tsxBin) return { ok: false, reason: \"tsx\" };\n\n return { ok: true, bin: tsxBin, args: [script] };\n}\n\n/** What to print when {@link resolveChildScript} cannot produce a command. */\nfunction childScriptError(what: string, reason: \"script\" | \"tsx\"): string {\n if (reason === \"tsx\") {\n return `✗ Could not find the tsx binary, which ${what} needs to read your collection files. `\n + \"Install your project's dependencies and try again.\";\n }\n return `✗ The driver's ${what} is missing. This copy of @rebasepro/server-postgres is `\n + \"incomplete — reinstall it, or run its build if you are working in the monorepo.\";\n}\n\n/**\n * Whether this process can run the generators itself — that is, whether it\n * runs under tsx, the interpreter the project's collection files need (see\n * {@link resolveChildScript}). `rebase` always starts the driver that way when\n * tsx is installed, which a scaffold guarantees; a driver started with plain\n * `node` keeps the child process, which brings its own tsx.\n */\nfunction generatesInProcess(): boolean {\n const flags = [...process.execArgv, process.env.NODE_OPTIONS ?? \"\"];\n return flags.some(flag => /(?:^|[\\s\\\\/=])tsx(?:$|[\\s\\\\/@])/.test(flag));\n}\n\n/**\n * Run one of the generators in this process — see `schema/generate-files.ts`\n * for why a one-shot generation no longer gets a process of its own.\n *\n * The messages and the exit code are the child's: a generator that failed has\n * printed its own error, and this adds the one-line verdict; one that could not\n * even be loaded is reported the way a child that never started was.\n */\nasync function generateInProcess(\n what: string,\n label: string,\n run: (generators: typeof import(\"./schema/generate-files\")) => Promise<void>\n): Promise<void> {\n let generators: typeof import(\"./schema/generate-files\");\n try {\n generators = await import(\"./schema/generate-files\");\n } catch (err) {\n outError(chalk.red(`✗ Failed to run ${what}: ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n try {\n await run(generators);\n } catch (err) {\n if (err instanceof generators.GenerationFailed) {\n outError(chalk.red(`✗ ${label} generation failed — nothing was applied.`));\n } else {\n outError(chalk.red(`✗ Failed to run ${what}: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n}\n\n\n\nasync function loadEnv(): Promise<void> {\n try {\n const dotenv = await import(\"dotenv\");\n const envPaths = [\n process.env.DOTENV_CONFIG_PATH,\n path.resolve(process.cwd(), \".env\"),\n path.resolve(process.cwd(), \"../.env\"),\n path.resolve(process.cwd(), \"../../.env\")\n ].filter(Boolean) as string[];\n\n for (const p of envPaths) {\n if (fs.existsSync(p)) {\n const parsed = dotenv.config({ path: p, quiet: true });\n if (parsed.parsed) {\n for (const [key, val] of Object.entries(parsed.parsed)) {\n if (process.env[key] === undefined) {\n process.env[key] = val;\n }\n }\n break;\n }\n }\n }\n } catch {\n // ignore\n }\n}\n\nexport async function runPluginCommand(args: string[]) {\n // Also set as an environment variable, not just per `config()` call: this\n // command spawns `tsx` subprocesses (the schema generator, the DDL\n // generator, doctor) that load `.env` themselves, and they inherit this.\n // dotenv reads it before `options.quiet`; an explicit `false` still wins.\n if (process.env.DOTENV_CONFIG_QUIET === undefined) {\n process.env.DOTENV_CONFIG_QUIET = \"true\";\n }\n await loadEnv();\n const domain = args[0]; // \"db\" or \"schema\"\n const subcommand = args[1];\n\n // Before anything reads the line: every parser below runs `permissive`,\n // which turns an undeclared flag into a positional rather than an error, so\n // `db push --alow-destructive` pushed with the destructive gate still shut\n // and `schema generate --ouput x` wrote the default path in silence. See\n // cli-flags.ts for why the check has to be here and not in those parsers.\n assertKnownFlags(domain, subcommand, args);\n\n // And before anything is generated: a `--collections` path that does not\n // resolve used to warn and carry on, four times over, and the generators\n // then wrote an *empty* schema over `drizzle/schema.sql` and\n // `src/schema.generated.ts` — both committed artifacts — after which the\n // push planned a DROP TABLE for every table in the database. Only the\n // destructive gate stood between a typo and the whole schema.\n //\n // Checked here rather than in `loadCollectionsForCli`, which is\n // deliberately forgiving: its callers use it to *narrow* what Atlas may\n // touch, and a hard failure there would block a push over one broken file.\n // This is a different question — \"does the directory the user named\n // exist\" — and the answer was already known before the first write.\n assertCollectionsPathExists(collectionsPathIn(args));\n\n try {\n if (domain === \"db\") {\n await scratchDatabase.around(() => dbCommand(subcommand, args));\n } else if (domain === \"schema\") {\n await schemaCommand(subcommand, args);\n } else if (domain === \"doctor\") {\n await doctorPluginCommand(args);\n } else if (domain === \"console\") {\n const { consoleCommand } = await import(\"./cli-console\");\n process.exitCode = await consoleCommand(args);\n } else {\n outError(chalk.red(`Unknown domain command: ${domain}`));\n process.exit(1);\n }\n } finally {\n // The one connection every step shared (see `withAppClient`). Open, it\n // would keep this process alive after the command has finished.\n await closeAppClients();\n }\n}\n\n/** The migration files on disk, sorted, or none if the directory is absent. */\nfunction listMigrationFiles(): string[] {\n const dir = path.resolve(process.cwd(), \"drizzle\", \"migrations\");\n if (!fs.existsSync(dir)) return [];\n return fs.readdirSync(dir).filter(f => f.endsWith(\".sql\")).sort();\n}\n\n/**\n * The newest migration's version — the numeric prefix Atlas records.\n *\n * `20260906101530_init.sql` → `20260906101530`. Named in the baseline remedy so\n * the command it prints can be typed rather than worked out.\n */\nfunction latestMigrationVersion(): string | null {\n const newest = listMigrationFiles().at(-1);\n if (!newest) return null;\n const match = /^(\\d+)/.exec(newest);\n return match ? match[1] : newest.replace(/\\.sql$/, \"\");\n}\n\n/**\n * Take Atlas's carve-outs back out of the migration `migrate diff` just wrote.\n *\n * The apply path hands Atlas `--exclude` and it never sees the search or vector\n * columns. The diff path has no such flag — `atlas migrate diff` rejects\n * `--exclude` outright, and an `atlas.hcl` `env` block's `exclude` is accepted\n * and then ignored — so Atlas replays the migration directory (which builds\n * both columns, because that DDL is appended to migrations), does not find them\n * in `schema.sql`, and plans `DROP COLUMN`. Applied, that would take search and\n * the embeddings away from every database the migration reaches.\n *\n * Returns whether a migration Atlas just wrote is still there afterwards: a\n * file whose only content was the spurious drop is deleted, because an empty\n * migration is worse than none — it takes a slot in the revision history and\n * the caller would append the carved-out DDL and the policies to it.\n *\n * @returns true when a new migration survives and may be appended to.\n */\nasync function stripCarvedOutFromNewestMigration(collectionsPath: string): Promise<boolean> {\n // Both carve-outs, for one reason: they are the same problem. Search is out\n // of Atlas's sight because its free tier will not parse a function; vector\n // is out because Atlas resolves the desired state in a dev database that\n // can never have pgvector. What follows from that is identical — the diff\n // replays a migration directory holding objects `schema.sql` omits, and\n // plans a drop for every one.\n const patterns = [\n ...await getSearchExcludes(collectionsPath),\n ...await getVectorExcludes(collectionsPath),\n ...await getTriggerExcludes(collectionsPath)\n ];\n if (patterns.length === 0) return true;\n\n const newest = listMigrationFiles().at(-1);\n if (!newest) return false;\n const file = path.resolve(process.cwd(), \"drizzle\", \"migrations\", newest);\n\n const result = stripCarvedOutStatements(fs.readFileSync(file, \"utf-8\"), patterns);\n\n // Fail CLOSED, and loudly. A drop this could not rewrite stays in the file\n // exactly as Atlas wrote it, and the file is one somebody applies next week\n // — by which time the column is gone and nothing connects it to this run.\n // The destructive gate does not cover it either: that reads the *push*\n // plan. So `db generate` stops here rather than hand back a migration that\n // destroys a column the developer never asked to lose.\n if (result.unhandled.length > 0) {\n outError(chalk.red(\n `\\n ✗ ${newest} drops an object Rebase manages outside Atlas, in a form the CLI`\n ));\n outError(chalk.red(\" could not remove:\"));\n for (const statement of result.unhandled) {\n outError(chalk.gray(` ${statement.replace(/\\s+/g, \" \")}`));\n }\n outError(chalk.gray(\n \" Left as Atlas wrote it. Delete those statements by hand before running\\n\" +\n \" `rebase db migrate` — and please report them: rewriting this is meant to\\n\" +\n \" be automatic.\"\n ));\n process.exit(1);\n }\n\n if (result.removed.length === 0) return true;\n\n if (result.empty) {\n fs.rmSync(file);\n out(chalk.gray(\n ` ✓ Dropped ${newest} — it planned nothing but the removal of columns\\n` +\n \" Atlas cannot see and Rebase applies itself.\"\n ));\n } else {\n fs.writeFileSync(file, result.sql, \"utf-8\");\n out(chalk.gray(` ✓ Kept Rebase's own columns out of ${newest} (${result.removed.length} statement(s))`));\n }\n\n await runAtlas(\"migrate\", [\"hash\", \"--dir\", \"file://drizzle/migrations\"], collectionsPath);\n return !result.empty;\n}\n\n/**\n * One line per destructive statement, as `db push` prints them — shared by\n * push, `db generate` and `db migrate --refuse-destructive`, so the three\n * describe the same statement the same way.\n */\nfunction destructiveLines(destructive: readonly DestructiveStatement[]): string[] {\n return destructive.map(d =>\n chalk.red(` ${d.kind}${d.detail ? ` (${d.detail})` : \"\"}: `) + chalk.gray(d.statement.replace(/\\s+/g, \" \")));\n}\n\n/**\n * The column types `detectDestructiveStatements` reads a type change against,\n * or none when the database cannot be asked — every type change then counts\n * as destructive, which is the safe side of a report.\n */\nasync function columnTypesOrNone(databaseUrl: string | undefined): Promise<ExistingColumnType[]> {\n if (!databaseUrl) return [];\n try {\n return await queryColumnTypes(databaseUrl);\n } catch {\n return [];\n }\n}\n\n/**\n * The CHECK and EXCLUDE constraints `detectDestructiveStatements` reads a\n * `DROP CONSTRAINT` against, or none when the database cannot be asked. A\n * report then cannot tell a dropped CHECK from a dropped foreign key, and says\n * nothing about either, as before.\n */\nasync function constraintsOrNone(databaseUrl: string | undefined): Promise<ExistingConstraint[]> {\n if (!databaseUrl) return [];\n try {\n return await queryUndeclarableConstraints(databaseUrl);\n } catch {\n return [];\n }\n}\n\n/**\n * Say what in the migration `db generate` just wrote destroys data.\n *\n * `db push` stops before a destructive change; `db generate` wrote the same\n * `DROP COLUMN` into a file without a word, and `db migrate` applied it. Only\n * the part Atlas planned is read: what is appended after it (the search\n * rebuild, policies, triggers) is Rebase's own and puts back what it drops.\n * A report, not a refusal — the exit code is unchanged.\n */\nasync function reportDestructiveMigration(migrationSql: string, migrationFile: string, databaseUrl: string | undefined): Promise<void> {\n const destructive = detectDestructiveStatements(migrationSql, await columnTypesOrNone(databaseUrl), await constraintsOrNone(databaseUrl));\n if (destructive.length === 0) return;\n outWarn(\"\");\n outWarn(chalk.yellow(` ⚠️ ${migrationFile} includes ${destructive.length} destructive change(s) that will DESTROY data when applied:`));\n outWarn(\"\");\n for (const line of destructiveLines(destructive)) outWarn(line);\n outWarn(\"\");\n outWarn(chalk.yellow(\" Review it before `rebase db migrate`. `rebase db migrate --refuse-destructive` will not apply it.\"));\n outWarn(chalk.yellow(\" Back up first: rebase db backup\"));\n outWarn(\"\");\n}\n\n/**\n * The flags `rebase db` reads for the subcommands it parses itself. Hoisted\n * and named `…FLAGS` so the documentation verifier, which reads specs out of\n * this source, sees them.\n */\nconst DB_FLAGS = {\n \"--collections\": String,\n \"--allow-destructive\": Boolean,\n \"--refuse-destructive\": Boolean,\n \"--dry-run\": Boolean,\n \"--yes\": Boolean,\n \"--baseline\": String,\n \"-c\": \"--collections\",\n \"-y\": \"--yes\"\n} satisfies arg.Spec;\n\nasync function dbCommand(subcommand: string, rawArgs: string[]): Promise<void> {\n const VALID_ACTIONS = [\"push\", \"generate\", \"migrate\", \"branch\", \"backup\", \"restore\", \"backups\"];\n if (!subcommand || !VALID_ACTIONS.includes(subcommand)) {\n outError(chalk.red(`Unknown db command. Valid: ${VALID_ACTIONS.join(\", \")}`));\n process.exit(1);\n }\n\n // A second line of defence, and not a redundant one. `rebase db` answers\n // `--help` before it ever spawns this file, but this file is also its own\n // CLI — the driver is spawned directly by `resolvePluginCliScript`, and is\n // executable on its own — so a `--help` reaching here means nobody upstream\n // caught it. Only `branch` had a case for it; `push`, `migrate` and\n // `restore` all took `--help` as an ordinary flag and did the work.\n if (rawArgs.includes(\"--help\") || rawArgs.includes(\"-h\")) {\n out(\"\");\n out(chalk.bold(` rebase db ${subcommand}`));\n out(chalk.gray(\" Run `rebase db --help` for the full page — this is the driver's own entry point.\"));\n out(\"\");\n return;\n }\n\n if (subcommand === \"branch\") {\n await branchCommand(rawArgs);\n return;\n }\n\n if (subcommand === \"backup\" || subcommand === \"restore\" || subcommand === \"backups\") {\n const { backupCommand, restoreCommand, backupsCommand } = await import(\"./backup/backup-cli\");\n // `rebase cloud db backup list` is how the cloud family spells this, and\n // locally the same words *created a backup*: \"list\" was a positional\n // `backupCommand` ignored. One CLI, two spellings, and the wrong guess\n // wrote a dump instead of reading one. Both spellings list now.\n if (subcommand === \"backup\" && backupActionOf(rawArgs) === \"list\") await backupsCommand(rawArgs);\n else if (subcommand === \"backup\") await backupCommand(rawArgs);\n else if (subcommand === \"restore\") await restoreCommand(rawArgs);\n else await backupsCommand(rawArgs);\n return;\n }\n\n const argsList = parseDriverLine(DB_FLAGS, rawArgs);\n const collectionsPath = argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n\n if (subcommand === \"generate\") {\n out(\"\");\n out(chalk.bold(\" 📦 Rebase DB Generate\"));\n out(chalk.gray(\" Step 1/2: Generating Drizzle schema & Postgres DDL from collections...\"));\n out(\"\");\n await schemaCommand(\"generate\", rawArgs, { nextStep: false });\n await generatePostgresDdlCommand(rawArgs);\n out(\"\");\n out(chalk.gray(\" Step 2/2: Generating SQL migration files with Atlas...\"));\n out(\"\");\n const migrationName = argsList._[0] || \"migration\";\n const migrationsBefore = listMigrationFiles();\n await runAtlas(\"migrate\", [\"diff\", migrationName, \"--dir\", \"file://drizzle/migrations\", \"--to\", DESIRED_STATE_URL], collectionsPath);\n // The diff cannot be told to ignore the carved-out objects the way the\n // apply can, so the drop it plans for them is taken back out of the\n // file it just wrote. A migration that was nothing else is deleted.\n let wroteNewMigration = listMigrationFiles().length > migrationsBefore.length;\n if (wroteNewMigration) {\n wroteNewMigration = await stripCarvedOutFromNewestMigration(collectionsPath);\n }\n const newestWritten = wroteNewMigration ? listMigrationFiles().at(-1) : undefined;\n if (newestWritten) {\n await reportDestructiveMigration(\n fs.readFileSync(path.resolve(process.cwd(), \"drizzle\", \"migrations\", newestWritten), \"utf-8\"),\n newestWritten,\n process.env.DATABASE_URL\n );\n }\n \n // Post-process the migration Atlas just wrote.\n //\n // `wroteNewMigration` gates the whole block, and that gate is the point.\n // \"The newest migration file\" is only Atlas's when Atlas wrote one;\n // otherwise it is a migration that has already run in production, and\n // appending to it changes a hash Atlas has recorded while the appended\n // SQL never runs anywhere. The search half already said so and checked;\n // the `CREATE SCHEMA` rewrite and the policy append did not, so every\n // `db generate` that found nothing to diff still grew the last\n // migration by another copy of the policies.\n //\n // A failure here takes the migration back out and stops: see\n // `finishNewMigration`. Atlas's half creates the tables, the append\n // locks them, and a migration with only the first half applies cleanly.\n const migrationsDir = path.resolve(process.cwd(), \"drizzle\", \"migrations\");\n const newestSql = fs.existsSync(migrationsDir) && wroteNewMigration\n ? fs.readdirSync(migrationsDir).filter(f => f.endsWith(\".sql\")).sort().at(-1)\n : undefined;\n if (newestSql) {\n const newestMigrationFile = path.join(migrationsDir, newestSql);\n const finished = await finishNewMigration(newestMigrationFile, async () => {\n // Make CREATE SCHEMA idempotent so it doesn't conflict with\n // --revisions-schema (Atlas pre-creates the rebase schema\n // for its revision table before running migrations).\n let migrationContent = fs.readFileSync(newestMigrationFile, \"utf-8\");\n migrationContent = migrationContent.replace(\n /CREATE SCHEMA (?!IF NOT EXISTS)(\"[^\"]+\");/g,\n \"CREATE SCHEMA IF NOT EXISTS $1;\"\n );\n // Atlas never writes the search or vector objects into a\n // migration — it is not shown them — so a migration\n // replayed against a fresh database would build every table\n // except the parts that make search and vector search work.\n // Appending, because these are `ALTER TABLE ... ADD COLUMN`\n // over the tables the migration just created.\n //\n // Vector first: `vector.sql` may open with\n // `CREATE EXTENSION vector`, so prerequisites lead, which is\n // the order a reader of the migration expects. Nothing in\n // search depends on it either way.\n const vectorContent = readVectorDdl();\n if (vectorContent) {\n migrationContent = `${migrationContent}\\n\\n${vectorContent}`;\n out(chalk.gray(\" ✓ Appended vector DDL to the migration\"));\n }\n\n const searchContent = readSearchDdl();\n if (searchContent) {\n // The same refusal `db push` works around, but decided\n // here and written into the file: this migration runs\n // later, somewhere else, against a database nobody can\n // inspect from this machine. A column retyped by the\n // statements above cannot be retyped while the search\n // column reads it, and the appended DDL below runs too\n // late to help — so the drop is prepended and the\n // rebuild is the append that was already happening.\n //\n // Derived from the collections rather than a catalogue:\n // `searchColumnDependencies` knows which columns each\n // block reads, which is all the decision needs.\n const { searchColumnDependencies } = await import(\"./schema/generate-postgres-ddl-logic\");\n const migrationConflicts = findGeneratedColumnConflicts(\n parseColumnMutations(migrationContent),\n searchColumnDependencies(await loadCollectionsForCli(collectionsPath))\n );\n const preamble = migrationDropPreamble(migrationConflicts);\n if (preamble) {\n migrationContent = `${preamble}\\n${migrationContent}`;\n for (const conflict of migrationConflicts) {\n out(chalk.gray(` ✓ ${describeConflict(conflict)} is dropped and rebuilt inside the migration`));\n }\n }\n migrationContent = `${migrationContent}\\n\\n${searchContent}`;\n out(chalk.gray(\" ✓ Appended search DDL to the migration\"));\n }\n\n // Last of the three: a trigger needs its table and its\n // column, and both arrive above.\n const triggersContent = readTriggersDdl();\n if (triggersContent) {\n migrationContent = `${migrationContent}\\n\\n${triggersContent}`;\n out(chalk.gray(\" ✓ Appended `updated_at` triggers to the migration\"));\n }\n\n fs.writeFileSync(newestMigrationFile, migrationContent, \"utf-8\");\n\n // Append RLS policies, preceded by the RLS bootstrap so the\n // migration is self-contained: Atlas replays migrations\n // against a clean dev database where `rebase.uid()` would\n // not otherwise exist.\n const policiesFile = path.join(generatedSqlDir(), \"policies.sql\");\n if (fs.existsSync(policiesFile)) {\n const policiesContent = fs.readFileSync(policiesFile, \"utf-8\");\n fs.appendFileSync(newestMigrationFile, \"\\n\\n\" + RLS_BOOTSTRAP_SQL + \"\\n\" + policiesContent);\n out(chalk.gray(` ✓ Appended RLS policies to migration file: ${path.basename(newestMigrationFile)}`));\n\n // Re-hash the migration directory\n out(chalk.gray(\" Re-hashing migration files...\"));\n await runAtlas(\"migrate\", [\"hash\", \"--dir\", \"file://drizzle/migrations\"], collectionsPath, { throwOnFailure: true });\n out(chalk.gray(\" ✓ Migration directory checksum updated successfully.\"));\n }\n }, async () => {\n await runAtlas(\"migrate\", [\"hash\", \"--dir\", \"file://drizzle/migrations\"], collectionsPath, { throwOnFailure: true });\n });\n if (!finished.ok) {\n outError(chalk.red(`\\n ✗ Could not finish ${newestSql}: ${finished.error}`));\n outError(chalk.gray(\n \" Atlas's half of a migration creates the tables; the part that failed adds their\\n\" +\n \" row-level security, policies, search, vector and trigger DDL. Applied alone, it\\n\" +\n \" would serve the new tables with no row filtering.\"\n ));\n outError(chalk.gray(finished.removed\n ? ` ${newestSql} was removed. Fix the cause and run \\`rebase db generate\\` again.`\n : ` ${newestSql} could not be removed — delete it by hand before \\`rebase db migrate\\`.`));\n if (finished.rehashError) {\n outError(chalk.gray(\n ` Re-hashing failed too (${finished.rehashError}); run \\`atlas migrate hash\\` or generate again.`\n ));\n }\n process.exit(1);\n }\n }\n\n if (!wroteNewMigration) {\n // Reachable whenever the only thing that changed is something Atlas\n // cannot see — a `search` block, a `vector` property, or a\n // `securityRules` edit. There is no new file to carry it, and the\n // previous migration must not be reopened: it has already run\n // wherever this project is deployed.\n out(chalk.gray(\n \" ℹ No migration written — nothing in this change is visible to Atlas.\\n\" +\n \" Search, vector, trigger and RLS DDL are applied by `rebase db push`, and at\\n\" +\n \" boot by the schema ensure. For a migration-only deployment, add\\n\" +\n ` ${GENERATED_SQL_DIR}/search.sql, vector.sql, triggers.sql and\\n` +\n \" policies.sql to a migration by hand.\"\n ));\n }\n\n const nextStep = nextStepAfterDbGenerate({\n newestVersion: latestMigrationVersion(),\n wrote: wroteNewMigration,\n first: migrationsBefore.length === 0\n });\n out(\"\");\n for (const line of nextStep) out(line);\n if (nextStep.length > 0) out(\"\");\n } else {\n out(\"\");\n out(chalk.bold(` 🗄️ Rebase DB ${subcommand.charAt(0).toUpperCase() + subcommand.slice(1)}`));\n out(\"\");\n\n if (subcommand === \"push\") {\n const dryRun = argsList[\"--dry-run\"] === true;\n out(chalk.gray(dryRun\n ? \" Step 1/3: Generating the Postgres DDL from collections (the plan's input)...\"\n : \" Step 1/3: Generating Drizzle schema & Postgres DDL from collections...\"));\n out(\"\");\n // `--dry-run` applies nothing, and that includes the project's\n // files: it used to rewrite the tracked `src/schema.generated.ts`\n // and delete the `drizzle/*.sql` copies an older release committed.\n // Atlas plans from the DDL alone, which goes to the scratch\n // directory `.rebase/sql/` that ignores itself.\n if (dryRun) {\n out(chalk.gray(\" --dry-run: src/schema.generated.ts is left as it is.\"));\n } else {\n await schemaCommand(\"generate\", rawArgs, { nextStep: false });\n }\n await generatePostgresDdlCommand(rawArgs, { retireLegacyCopies: !dryRun });\n out(\"\");\n out(chalk.gray(dryRun\n ? \" Step 2/3: Planning the change against the database (nothing is applied)...\"\n : \" Step 2/3: Pushing schema to database with Atlas...\"));\n out(\"\");\n const databaseUrl = process.env.DATABASE_URL;\n // Skipped under --dry-run: this creates the auth schema and its\n // functions, which is a write. \"Show me what would happen\" that\n // changes something on the way is not a plan.\n if (databaseUrl && !dryRun) {\n await ensureAuthSchemaAndFunctions(databaseUrl);\n }\n\n // Before Atlas plans: the foreign-key indexes an existing table is\n // missing, built CONCURRENTLY — so the plan finds them, and the\n // push's one transaction never builds one while holding the\n // table's writes. See `schema/push-index-prebuild.ts`. A dry-run\n // only names them.\n // First of all: relation columns a pre-0.13 Rebase named the old\n // way (`categorie_id`) are renamed — the lossless, metadata-only\n // statement boot runs — so Atlas does not plan them as a drop and\n // an add. See `schema/push-legacy-renames.ts`.\n if (databaseUrl) await renameLegacyForeignKeys(databaseUrl, collectionsPath, dryRun);\n\n const prebuilt = databaseUrl ? await prebuildForeignKeyIndexes(databaseUrl, collectionsPath, dryRun) : [];\n\n // Preview the plan before touching data. `atlas schema apply` with\n // --auto-approve will silently DROP COLUMN on a field removal and\n // drop+add on a rename, so we first dry-run to obtain the planned\n // SQL and gate anything destructive.\n const plan = await runAtlas(\n \"schema\",\n [\"apply\", \"--to\", DESIRED_STATE_URL, \"--dry-run\"],\n collectionsPath,\n { captureStdout: true }\n );\n // The columns' current types, because an `ALTER COLUMN … TYPE`\n // loses data or does not depending on what the column is now.\n // Without them every type change is gated. And the CHECK and\n // EXCLUDE constraints, so a drop of one that the excludes missed\n // is gated too.\n const destructive = detectDestructiveStatements(\n plan,\n databaseUrl ? await queryColumnTypes(databaseUrl) : [],\n databaseUrl ? await queryUndeclarableConstraints(databaseUrl) : []\n );\n // What to show a person: the statements, once each. Atlas's report\n // prints every one twice and wraps them in timings; when the gate\n // could not read it, the report itself is the only honest thing\n // to show.\n const unreadable = destructive.some(d => d.kind === \"UNREADABLE PLAN\");\n const planStatements = extractPlanStatements(plan);\n const planListing = unreadable\n ? plan.trim()\n : planStatements.map(statement => `${statement};`).join(\"\\n\");\n\n // A generated column makes every column it reads immutable to\n // Atlas: PostgreSQL refuses `ALTER COLUMN … TYPE` and `DROP COLUMN`\n // while one depends on it, and `schema apply` runs its plan in a\n // single transaction — so one refusal rolls back the whole push,\n // including the statements that had nothing to do with it.\n //\n // Atlas cannot avoid planning it. The search column is hidden from\n // its view on purpose (`searchExcludePatterns`), because a desired\n // state that never mentions the column reads to Atlas as an\n // instruction to drop it. So the dependant is invisible exactly\n // where it would have to be visible.\n //\n // Rebase owns those columns, so it takes them out of the way and\n // `applySearchDdl` puts them back below — the same drop-and-re-apply\n // the search stamp guard already prescribes when a block changes.\n const generatedConflicts = databaseUrl\n ? findGeneratedColumnConflicts(\n parseColumnMutations(plan),\n await queryGeneratedColumnDependencies(databaseUrl)\n )\n : [];\n const { managed: rebuildable, foreign: unowned } = partitionByOwnership(\n generatedConflicts,\n collectionsPath ? await getSearchExcludes(collectionsPath) : []\n );\n\n // A removed enum option plans nothing (no ALTER TYPE … DROP VALUE\n // exists), so the push would succeed and the database go on\n // accepting the value. Not a refusal — boot does the same — but said.\n if (databaseUrl) await reportKeptEnumLabels(databaseUrl, collectionsPath);\n\n // What the push does to row-level security, which Atlas's plan\n // cannot show: it has no model for a policy. Read once, here, for\n // the dry run to list and the push to summarize — see\n // `schema/push-policy-plan.ts`.\n const policyPlan = databaseUrl ? await readPolicyPushPlan(databaseUrl, collectionsPath) : undefined;\n const policyLines = policyPlan ?? { changes: [], notes: [] };\n\n // `--dry-run` stops here, having printed the SQL and nothing else.\n //\n // It exists because the only way to see this plan was to trigger\n // the destructive gate, and the gate prints the plan while exiting\n // 1 — so \"what would this do?\" was answerable only by a command\n // that looked like a failure, and unanswerable at all when the\n // change was additive. An agent with no way to show the SQL either\n // asks a human to approve something neither of them has read, or\n // runs the push to find out.\n if (dryRun) {\n out(chalk.gray(\" Step 3/3: --dry-run — nothing was applied.\"));\n out(\"\");\n const schemaChanges = planStatements.length > 0 || unreadable;\n if (schemaChanges) {\n out(chalk.bold(\" Planned changes:\"));\n out(chalk.gray(planListing.split(\"\\n\").map((l) => ` ${l}`).join(\"\\n\")));\n out(\"\");\n }\n const [rlsHeading, ...rlsChanges] = policyLines.changes;\n if (rlsHeading) {\n out(chalk.bold(rlsHeading));\n for (const line of rlsChanges) out(chalk.gray(line));\n out(\"\");\n }\n if (!schemaChanges && !rlsHeading) {\n out(chalk.green(policyPlan\n ? \" ✓ No changes: the database already matches these collections.\"\n : \" ✓ No schema changes: the tables already match these collections.\"));\n out(\"\");\n }\n if (databaseUrl && !policyPlan) {\n outWarn(chalk.yellow(\" ⚠️ The row-level security the push would change could not be read, so none is listed.\"));\n outWarn(\"\");\n }\n if (policyLines.notes.length > 0) {\n for (const line of policyLines.notes) out(chalk.gray(line));\n out(\"\");\n }\n if (prebuilt.length > 0) {\n out(chalk.gray(` ${prebuilt.length} foreign-key index(es) on existing tables would be built first,`));\n out(chalk.gray(\" CONCURRENTLY, so the apply would not build them under a write lock (the plan\"));\n out(chalk.gray(\" above lists them because they do not exist yet):\"));\n for (const name of prebuilt) {\n out(chalk.gray(` ${name}`));\n }\n out(\"\");\n }\n if (rebuildable.length > 0) {\n out(chalk.gray(` ${rebuildable.length} generated column(s) would be dropped before the apply and`));\n out(chalk.gray(\" rebuilt from search.sql after it — Postgres cannot retype a column\"));\n out(chalk.gray(\" while one reads it:\"));\n for (const conflict of rebuildable) {\n out(chalk.gray(` ${describeConflict(conflict)}`));\n }\n out(\"\");\n }\n if (unowned.length > 0) {\n outWarn(formatForeignGeneratedColumnBanner(unowned));\n }\n if (destructive.length > 0) {\n outWarn(chalk.yellow(` ⚠️ ${destructive.length} of those DESTROY data:`));\n for (const line of destructiveLines(destructive)) outWarn(line);\n outWarn(\"\");\n outWarn(chalk.yellow(\" Applying them needs `rebase db push --allow-destructive`. Back up first: rebase db backup\"));\n outWarn(\"\");\n }\n out(chalk.gray(\" The auth schema step was skipped, because it writes. A real push runs it first.\"));\n out(\"\");\n return;\n }\n\n // Before the destructive gate, and separately from it: this is not a\n // change the operator can approve their way through. Rebase has no\n // copy of the expression, so there is nothing to put back.\n if (unowned.length > 0) {\n outError(formatForeignGeneratedColumnBanner(unowned));\n throw new CommandStopped(\"A generated column Rebase does not own blocks the push.\");\n }\n\n const optIn = destructiveOptInFlag(argsList);\n const decision = decidePushSafety({\n destructiveCount: destructive.length,\n allowDestructive: optIn !== undefined,\n interactive: process.stdin.isTTY === true\n });\n\n if (destructive.length > 0) {\n outWarn(chalk.yellow(` ⚠️ This push includes ${destructive.length} destructive change(s) that will DESTROY data:`));\n outWarn(\"\");\n for (const line of destructiveLines(destructive)) outWarn(line);\n outWarn(\"\");\n outWarn(chalk.yellow(\" Full planned changes:\"));\n outWarn(chalk.gray(planListing.split(\"\\n\").map((l) => ` ${l}`).join(\"\\n\")));\n outWarn(\"\");\n\n if (decision === \"refuse\") {\n outError(chalk.red(\" ✗ Aborting: destructive changes require confirmation.\"));\n outError(chalk.gray(\" Re-run interactively, or pass --allow-destructive to proceed. Back up first: rebase db backup\"));\n throw new CommandStopped(\"Destructive changes need confirmation.\");\n }\n if (decision === \"confirm\") {\n const confirmed = await promptConfirm(\n chalk.yellow(\" Type 'yes' to apply these destructive changes (this cannot be undone): \")\n );\n if (!confirmed) {\n out(chalk.gray(\" Aborted. No changes were made.\"));\n throw new CommandStopped(\"The destructive push was declined.\");\n }\n } else {\n // decision === \"apply\" via --allow-destructive or --yes\n outWarn(chalk.yellow(` Proceeding because ${optIn ?? \"--allow-destructive\"} was passed.`));\n }\n }\n\n if (policyPlan?.summary) {\n out(chalk.gray(policyPlan.summary));\n out(\"\");\n }\n\n // Without a database URL there is nothing to drop or rebuild: runAtlas\n // refuses to run without one anyway.\n const rebuildCount = databaseUrl ? rebuildable.length : 0;\n await applyPushPlan({ dryRun: plan, rebuildable: rebuildCount }, {\n dropRebuildable: async () => {\n if (!databaseUrl) return;\n for (const conflict of rebuildable) {\n out(chalk.gray(` Dropping ${describeConflict(conflict)} — it reads a column this push retypes.`));\n }\n await dropGeneratedColumns(databaseUrl, dropGeneratedColumnStatements(rebuildable));\n },\n // Thrown, not exited: an exit from inside runAtlas skipped the\n // rebuild below entirely, so a failed apply left the search\n // columns it had just dropped dropped.\n atlasApply: async () => {\n await runAtlas(\"schema\", [\"apply\", \"--to\", DESIRED_STATE_URL, \"--auto-approve\"], collectionsPath, { throwOnFailure: true, omitPlanEcho: true });\n },\n reportSynced: () => out(\"Schema is synced, no changes to be made\"),\n rebuildAfterFailure: async () => {\n if (!databaseUrl) return;\n out(chalk.gray(\" The apply failed — rebuilding the generated columns it needed out of the way.\"));\n await applySearchDdl(databaseUrl);\n },\n afterApply: async () => {\n out(\"\");\n if (!databaseUrl) {\n outWarn(chalk.yellow(\" ⚠️ DATABASE_URL not found in environment, skipping RLS policies application.\"));\n return;\n }\n // First, before anything below can fail. Atlas has just\n // committed any new table with RLS off and the user role\n // already holding DML on it; every later step may refuse.\n await lockManagedTables(databaseUrl, collectionsPath);\n await ensureAuthTables(databaseUrl, collectionsPath);\n // After the tables exist and before the policies: the vector and\n // search columns are `ALTER TABLE ... ADD COLUMN`, and a policy\n // may reference the table they are added to.\n await applyVectorDdl(databaseUrl);\n await applySearchDdl(databaseUrl);\n await applyTriggersDdl(databaseUrl);\n await applyPolicies(databaseUrl, collectionsPath);\n await reconcilePolicies(databaseUrl, collectionsPath);\n await ensureRlsUserRole(databaseUrl);\n await retireLegacyAuthSchema(databaseUrl);\n }\n });\n } else if (subcommand === \"migrate\") {\n const databaseUrl = process.env.DATABASE_URL;\n // `--baseline <version>` records the version as already applied and\n // starts from the next one. The database a Rebase boot has\n // provisioned is exactly the case it is for, and without it\n // `migrate apply` there is unusable — see `formatBaselineRemedy`,\n // which is what prints when it is missing. Atlas's own `--baseline`\n // does it on a database with no revision history and ignores it in\n // silence on one that has any, so the history is read first and\n // `planBaseline` picks the way that works.\n const baseline = argsList[\"--baseline\"];\n const baselineProblem = baseline ? baselineVersionProblem(baseline, listMigrationFiles()) : null;\n if (baselineProblem) {\n const [message, ...detail] = baselineProblem.split(\"\\n\");\n outError(chalk.red(` ✗ ${message}`));\n for (const line of detail) outError(chalk.gray(` ${line}`));\n throw new CommandStopped(\"The baseline names no migration.\");\n }\n const baselinePlan = baseline\n ? planBaseline(baseline, databaseUrl ? await latestRecordedMigration(databaseUrl) : null)\n : null;\n const atlasBaseline = baselinePlan?.kind === \"atlas-baseline\" ? baseline : undefined;\n // Opt-in, and first: a refused run writes nothing at all. Atlas's\n // own dry-run lists exactly the statements the apply would run, in\n // the files still pending — the same reading `db push` gates on.\n if (argsList[\"--refuse-destructive\"] === true) {\n const plan = await runAtlas(\n \"migrate\",\n [...migrateApplyArgs(argsList._, atlasBaseline), \"--dry-run\"],\n collectionsPath,\n { captureStdout: true }\n );\n const destructive = detectDestructiveStatements(plan, await columnTypesOrNone(databaseUrl), await constraintsOrNone(databaseUrl));\n if (destructive.length > 0) {\n outError(chalk.red(` ✗ Refusing to migrate: the pending migrations include ${destructive.length} destructive change(s):`));\n outError(\"\");\n for (const line of destructiveLines(destructive)) outError(line);\n outError(\"\");\n outError(chalk.gray(\" Nothing was applied. Run `rebase db migrate` without --refuse-destructive to apply them.\"));\n outError(chalk.gray(\" Back up first: rebase db backup\"));\n process.exit(1);\n }\n out(chalk.gray(` --refuse-destructive: ${extractPlanStatements(plan).length} pending statement(s), none destructive.`));\n out(\"\");\n }\n if (databaseUrl) {\n await ensureAuthSchemaAndFunctions(databaseUrl);\n }\n if (baseline && baselinePlan) {\n out(chalk.gray(` ${describeBaselinePlan(baseline, baselinePlan)}`));\n out(\"\");\n if (baselinePlan.kind === \"set\") {\n await runAtlas(\"migrate\", [\"set\", baseline, \"--dir\", \"file://drizzle/migrations\"], collectionsPath);\n }\n }\n await runAtlas(\n \"migrate\",\n migrateApplyArgs(argsList._, atlasBaseline),\n collectionsPath\n );\n if (databaseUrl) {\n await ensureRlsUserRole(databaseUrl);\n await retireLegacyAuthSchema(databaseUrl);\n }\n }\n\n out(\"\");\n out(chalk.green(` ✓ rebase db ${subcommand} completed successfully.`));\n out(\"\");\n }\n}\n\n/**\n * Build, CONCURRENTLY and before Atlas plans, the derived foreign-key indexes\n * an existing table is missing — see `schema/push-index-prebuild.ts`. With\n * `dryRun`, only find them.\n *\n * Never fatal: an index not built here is one Atlas builds inside the push, as\n * it always did.\n *\n * @returns `schema.index` of each one missing when this started.\n */\n/** Renames relation columns that carry their pre-0.13 derived name, as boot does; a dry-run only names them. */\nasync function renameLegacyForeignKeys(databaseUrl: string, collectionsPath: string, dryRun: boolean): Promise<void> {\n let renames: LegacyRename[];\n try {\n const { loadCollections } = await import(\"./schema/doctor\");\n const { legacyForeignKeyRenames } = await import(\"./schema/push-legacy-renames\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n renames = await withAppClient(databaseUrl, client => legacyForeignKeyRenames(\n { query: async (text) => ({ rows: (await client.query(text)).rows }) },\n collections\n ));\n } catch {\n // Not knowing leaves Atlas's plan as it was, and its destructive gate with it.\n return;\n }\n if (renames.length === 0) return;\n out(chalk.gray(dryRun\n ? ` ${renames.length} relation column(s) carry the name Rebase derived before 0.13; a push renames them first,`\n : ` Renaming ${renames.length} relation column(s) that carry the name Rebase derived before 0.13 (data, indexes and`));\n out(chalk.gray(dryRun\n ? \" keeping their data (the plan below still shows them as a drop and an add, because nothing ran):\"\n : \" constraints are kept — the same rename `rebase dev` runs):\"));\n for (const rename of renames) {\n out(chalk.gray(` ${rename.table}: \"${rename.legacy}\" → \"${rename.expected}\"`));\n }\n if (!dryRun) {\n await withAppClient(databaseUrl, async client => {\n for (const rename of renames) await client.query(rename.sql);\n });\n }\n out(chalk.gray(\" To keep an old name instead, name the column on the relation (`localKey`, or `through` on a many-to-many).\"));\n out(\"\");\n}\n\n/** Names the enum labels the database keeps after the collections dropped them. See `schema/enum-labels-kept.ts`. */\nasync function reportKeptEnumLabels(databaseUrl: string, collectionsPath: string): Promise<void> {\n try {\n const { loadCollections } = await import(\"./schema/doctor\");\n const { keptEnumLabels, formatKeptEnumLabelsNotice } = await import(\"./schema/enum-labels-kept\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n const kept = await withAppClient(databaseUrl, client => keptEnumLabels(\n { query: async (text) => ({ rows: (await client.query(text)).rows }) },\n collections\n ));\n if (kept.length > 0) outWarn(chalk.yellow(formatKeptEnumLabelsNotice(kept)));\n } catch {\n // A notice, not a gate: not knowing changes nothing the push does.\n }\n}\n\nasync function prebuildForeignKeyIndexes(databaseUrl: string, collectionsPath: string, dryRun: boolean): Promise<string[]> {\n let missing: DeferredIndexBuild[];\n try {\n const { loadCollections } = await import(\"./schema/doctor\");\n const { missingForeignKeyIndexes } = await import(\"./schema/push-index-prebuild\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n missing = await withAppClient(databaseUrl, client => missingForeignKeyIndexes(\n { query: async (text) => ({ rows: (await client.query(text)).rows }) },\n collections\n ));\n } catch {\n // Not knowing changes nothing that matters: Atlas plans whatever is missing.\n return [];\n }\n const names = missing.map(index => `${index.schema}.${index.indexName}`);\n if (missing.length === 0 || dryRun) return names;\n\n out(chalk.gray(` Building ${missing.length} foreign-key index(es) on existing tables first — CONCURRENTLY, so writes go on:`));\n try {\n const { buildDeferredIndexes } = await import(\"./schema/deferred-index-build\");\n // This process's one connection, which is the dedicated session the\n // builder needs: it lifts `statement_timeout` and resets it, and takes\n // and releases its claims, on the same backend.\n const outcome = await withAppClient(databaseUrl, client => buildDeferredIndexes(\n async () => ({\n dedicated: true,\n query: async (text) => ({ rows: (await client.query(text)).rows }),\n release: () => undefined\n }),\n missing,\n { log: message => out(chalk.gray(` ${message}`)) }\n ));\n for (const failure of outcome.failed) {\n outWarn(chalk.yellow(` ⚠️ ${failure.index} was not built ahead (${failure.error}); the push builds it inside its transaction instead.`));\n }\n } catch (err) {\n outWarn(chalk.yellow(` ⚠️ The foreign-key indexes were not built ahead (${err instanceof Error ? err.message : String(err)}); the push builds them inside its transaction instead.`));\n }\n out(\"\");\n return names;\n}\n\nasync function ensureAuthSchemaAndFunctions(databaseUrl: string): Promise<void> {\n try {\n await withAppClient(databaseUrl, async client => {\n // Creates the `rebase` schema as its first statement, which also\n // covers the schema Atlas puts its revision table in\n // (`--revisions-schema rebase`). That used to need a separate,\n // deliberately migration-stream-excluded statement here, because the\n // helper functions lived in `auth` and creating `rebase` from the\n // preamble would have made Atlas plan a DROP for it. The generator\n // now always declares `rebase` in the desired schema, so there is\n // nothing to keep out.\n await client.query(RLS_BOOTSTRAP_SQL);\n });\n } catch (err) {\n // A database that cannot be reached is the whole answer, in the banner\n // every db command prints for it. As a warning first, it said the same\n // thing twice: `⚠️ Failed to bootstrap the RLS helper functions:\n // connect ECONNREFUSED…`, then the banner from the next step.\n if (isEconnrefused(err) || isAuthFailure(err) || isSslNotEnabled(err)) {\n outError(diagnoseDbError(err, databaseUrl) ?? ` ✗ ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n outWarn(chalk.yellow(` ⚠️ Failed to bootstrap the RLS helper functions: ${err instanceof Error ? err.message : String(err)}`));\n }\n}\n\n/**\n * Switch row-level security on for every table the collections declare, right\n * after Atlas has applied the schema.\n *\n * Atlas cannot carry `ENABLE ROW LEVEL SECURITY` in `schema.sql`: its free tier\n * neither plans it nor reads it back, so a table it creates is born with RLS\n * off — and `rebase_user`, the role every authenticated request runs as, holds\n * DML on it from that moment through the schema's default privileges. RLS used\n * to arrive with the policies, the last step of the push; a refusal from the\n * vector, search or trigger step in between left the new table readable and\n * writable by every caller, with no policy, until a later push or boot fixed\n * it — and a deployment with `REBASE_MIGRATE_ON_BOOT=none` never did. Locked\n * first, a failure later leaves a table that denies, not one that is open.\n *\n * Fatal when a table cannot be locked, and before the steps that follow: the\n * role provisioning at the end re-grants on every table in the schema, which\n * would undo the revoke that is the fallback here.\n */\nasync function lockManagedTables(databaseUrl: string, collectionsPath: string): Promise<void> {\n let unsecured: TableLockResult[\"unsecured\"];\n let userRole: string;\n try {\n const { lockCollectionTables } = await import(\"./schema/ensure-collection-policies\");\n const { loadCollections } = await import(\"./schema/doctor\");\n userRole = (await import(\"./security/rls-enforcement\")).REBASE_USER_ROLE;\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n ({ unsecured } = await withAppClient(databaseUrl, client => lockCollectionTables(\n { query: async (text) => ({ rows: (await client.query(text)).rows }) },\n collections\n )));\n } catch (err) {\n outError(chalk.red(\n `\\n ✗ The schema was applied, but row-level security could not be switched on for its tables: ` +\n `${err instanceof Error ? err.message : String(err)}`\n ));\n outError(chalk.gray(\n \" A table this push created may be readable and writable by every authenticated request\\n\" +\n \" until it is. Re-run `rebase db push` — it locks every collection table before anything else.\"\n ));\n process.exit(1);\n }\n if (unsecured.length === 0) return;\n\n outError(chalk.red(\"\\n ✗ The schema was applied, but row-level security could not be switched on for:\"));\n for (const u of unsecured) {\n outError(chalk.red(` ${u.table}: ${u.error}`));\n outError(chalk.gray(u.grantWithdrawn\n ? ` Its privileges were taken back from ${userRole}, so it is unreachable rather than unprotected.`\n : ` ${userRole} still holds its privileges: every authenticated request can read and write every row.`));\n }\n outError(chalk.gray(\" Nothing after the schema apply ran. Fix the cause — the connection role must own these\\n\" +\n \" tables, or be able to ALTER them — and run `rebase db push` again, or as their owner:\"));\n for (const u of unsecured) {\n const [schema, ...table] = u.table.split(\".\");\n outError(chalk.bold(` ALTER TABLE \"${schema}\".\"${table.join(\".\")}\" ENABLE ROW LEVEL SECURITY;`));\n }\n process.exit(1);\n}\n\n/**\n * Create the framework auth tables (e.g. `rebase.users`) that the generated RLS\n * policies reference, before `applyPolicies` runs. Mirrors what the server does\n * at boot (`PostgresBootstrapper.initializeAuth` → `ensureAuthTablesExist`).\n *\n * Without this, `rebase db push` against a database that has never booted the\n * server fails while applying policies with `relation \"rebase.users\" does not\n * exist` — the documented first-run does `db push` *before* the first `dev`.\n * `ensureAuthTablesExist` is idempotent (CREATE TABLE IF NOT EXISTS), so it is\n * safe to run on every push and harmless once the server has also created them.\n */\nasync function ensureAuthTables(databaseUrl: string, collectionsPath: string): Promise<void> {\n try {\n const { drizzle } = await import(\"drizzle-orm/node-postgres\");\n const { ensureAuthTablesExist } = await import(\"./auth/ensure-tables\");\n const { loadCollections } = await import(\"./schema/doctor\");\n\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n // The auth collection is flagged with `auth: true` or `auth: { enabled: true }`.\n const authCollection = collections.find((c) => {\n const a = c.auth;\n return a === true || (typeof a === \"object\" && a !== null && a.enabled === true);\n });\n\n await withAppClient(databaseUrl, client => ensureAuthTablesExist(drizzle(client), authCollection));\n } catch (err) {\n outWarn(chalk.yellow(` ⚠️ Failed to ensure framework auth tables: ${err instanceof Error ? err.message : String(err)}`));\n }\n}\n\n/**\n * Provision the restricted `rebase_user` role right after schema changes land,\n * so grants cover freshly created tables (default privileges cover future\n * ones). Only needed — and only possible without extra setup — when the\n * connection would bypass RLS (superuser / BYPASSRLS / table owner).\n */\nasync function ensureRlsUserRole(databaseUrl: string): Promise<void> {\n // Every failure in here used to escape uncaught, and `db migrate`'s caller\n // turns that into a bare `process.exit(1)` — so the migration would apply,\n // print `-- ok`, and then the command would die with NO output whatsoever\n // and a non-zero status. Seen with a module-resolution error inside the\n // dynamic import, where the entire diagnosis was one silent exit code.\n //\n // Reported rather than rethrown, and deliberately not fatal: the schema\n // change has already landed at this point, so failing the command implies a\n // rollback that did not happen. What is actually lost is the role\n // provisioning, and the message says so and how to finish it by hand.\n // No `auth`: the RLS helpers live in `rebase` now, and a schema the\n // framework no longer creates must not be granted on — on a Supabase\n // database that would hand the end-user role USAGE on their auth schema.\n const schemas = [\"public\", \"rebase\"];\n let rls: typeof import(\"./security/rls-enforcement\");\n try {\n rls = await import(\"./security/rls-enforcement\");\n } catch (err) {\n // A module-resolution failure here is a build problem, not a database\n // one, and it is exactly the case that used to produce the silent exit.\n outError(chalk.red(\n `\\n ✗ Could not load the RLS provisioning module: ${err instanceof Error ? err.message : String(err)}`\n ));\n return;\n }\n\n try {\n await withAppClient(databaseUrl, async client => {\n const runSql = async (text: string) => (await client.query(text)).rows as Record<string, unknown>[];\n const posture = await rls.detectConnectionPosture(runSql);\n if (posture.privileged) {\n await rls.ensureAppRole(runSql, schemas);\n out(chalk.gray(` ✓ RLS role \"${rls.REBASE_USER_ROLE}\" provisioned/refreshed.`));\n }\n });\n } catch (err) {\n outError(chalk.red(\n `\\n ✗ The schema change was applied, but the \"${rls.REBASE_USER_ROLE}\" role could not be ` +\n `provisioned: ${err instanceof Error ? err.message : String(err)}`\n ));\n outError(chalk.gray(rls.appRoleSetupInstructions(\"your database user\", schemas)));\n }\n}\n\n/**\n * Retire the pre-1.0 `auth` schema, once nothing depends on it any more.\n *\n * Runs last on purpose. Postgres refuses to drop a function an RLS policy still\n * calls, so this only succeeds after the policies above have been rewritten to\n * `rebase.uid()`. See `dropLegacyAuthSchema` for what it reports when something\n * hand-written is still holding the schema open, and DROP_LEGACY_AUTH_SCHEMA_SQL\n * for the guards that keep it off a Supabase `auth` schema.\n */\nasync function retireLegacyAuthSchema(databaseUrl: string): Promise<void> {\n try {\n await withAppClient(databaseUrl, client => dropLegacyAuthSchema(\n async (text) => (await client.query(text)).rows as Record<string, unknown>[],\n {\n info: (m) => out(chalk.gray(` ${m}`)),\n warn: (m) => outWarn(chalk.yellow(` ⚠️ ${m}`))\n }\n ));\n } catch {\n // Connection-level failure only; the schema is inert either way.\n }\n}\n\nasync function applyPolicies(databaseUrl: string, collectionsPath: string): Promise<void> {\n try {\n const policiesPath = path.join(generatedSqlDir(), \"policies.sql\");\n if (!fs.existsSync(policiesPath)) return;\n \n out(chalk.gray(\" Step 3/3: Applying RLS policies to database...\"));\n out(\"\");\n \n const policiesContent = fs.readFileSync(policiesPath, \"utf-8\");\n const stamping = await policyStamping(databaseUrl, collectionsPath, policiesContent);\n const { stampError } = await withAppClient(databaseUrl, client => applyPoliciesFile(client, policiesContent, stamping));\n out(chalk.green(\" ✓ RLS policies applied successfully.\"));\n if (stampError) {\n // The policies are in; only the boot's shortcut is not. See applyPoliciesFile.\n outWarn(chalk.yellow(` ⚠️ The policies could not be stamped (${stampError}); the next boot applies them again.`));\n }\n } catch (err) {\n const hint = diagnoseDbError(err, databaseUrl);\n if (hint) {\n outError(hint);\n } else {\n outError(chalk.red(` ✗ Failed to apply RLS policies: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n}\n\n/**\n * The stamps a boot looks for, for the policies `policies.sql` is about to\n * create — see `applyPoliciesFile`. None when the collections cannot be read\n * here, which costs only the shortcut: the next boot re-applies, as before.\n */\nasync function policyStamping(databaseUrl: string, collectionsPath: string, policiesSql: string): Promise<PolicyStamping> {\n try {\n const { loadCollections } = await import(\"./schema/doctor\");\n const { planCollectionPolicies } = await import(\"./schema/generate-postgres-ddl-logic\");\n const { policyStampSql } = await import(\"./schema/ensure-collection-policies\");\n // The rule the boot's connections follow: `search_path=public` unless\n // the URL pins one of its own, in which case this connection has it too.\n const { pinSearchPath } = await import(\"./connection\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n const statements = stampableTables(planCollectionPolicies(collections), policiesSql)\n .map(plan => policyStampSql(plan))\n .filter((statement): statement is string => statement !== undefined);\n return { statements, searchPath: pinSearchPath(databaseUrl) === databaseUrl ? undefined : \"public\" };\n } catch {\n return { statements: [] };\n }\n}\n\n/**\n * `planPolicyPush` for this database and these collections, read under the\n * `search_path` the push stamps policies under, as the lines the dry run\n * prints and the one the push does; `undefined`, having said why, when it\n * cannot be read.\n */\nasync function readPolicyPushPlan(databaseUrl: string, collectionsPath: string): Promise<{\n changes: string[];\n notes: string[];\n summary: string | null;\n} | undefined> {\n try {\n const { formatPolicyPushPlan, planPolicyPush, summarizePolicyPushPlan } = await import(\"./schema/push-policy-plan\");\n const { loadCollections } = await import(\"./schema/doctor\");\n const { pinSearchPath } = await import(\"./connection\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n const plan = await withAppClient(databaseUrl, client => planPolicyPush(\n { query: async (text, values) => ({ rows: (await client.query(text, values)).rows }) },\n collections,\n { searchPath: pinSearchPath(databaseUrl) === databaseUrl ? undefined : \"public\" }\n ));\n return { ...formatPolicyPushPlan(plan), summary: summarizePolicyPushPlan(plan) };\n } catch (err) {\n outWarn(chalk.yellow(` ⚠️ Could not read the database's row-level security: ${err instanceof Error ? err.message : String(err)}`));\n return undefined;\n }\n}\n\n/**\n * Remove the policies an earlier push superseded but never dropped.\n *\n * `policies.sql` only DROPs the names it is about to CREATE, and a rule's\n * generated name contains a hash of its own semantics — so editing a rule\n * writes a *new* policy and abandons the old one. Postgres ORs PERMISSIVE\n * policies together, which makes an abandoned grant outrank every tightening\n * that replaced it, and push reported success the whole time.\n *\n * Runs after `applyPolicies` so the current policies are already in place: the\n * drift check then sees exactly the set that should survive, and anything else\n * on a managed table is by definition left over.\n */\nasync function reconcilePolicies(databaseUrl: string, collectionsPath: string): Promise<void> {\n try {\n const { checkPolicyDrift, dropOrphanedPolicies, formatPolicyDrift, hasDrift } =\n await import(\"./security/policy-drift\");\n const { loadCollections } = await import(\"./schema/doctor\");\n\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n await withAppClient(databaseUrl, async client => {\n const drift = await checkPolicyDrift(client as never, collections);\n const { dropped, kept } = await dropOrphanedPolicies(client as never, drift, collections);\n\n for (const p of dropped) {\n out(chalk.gray(` ✓ Dropped superseded policy \"${p.name}\" on ${p.schema}.${p.table}`));\n }\n if (dropped.length > 0) {\n out(chalk.green(` ✓ Removed ${dropped.length} superseded RLS ${dropped.length === 1 ? \"policy\" : \"policies\"}.`));\n }\n\n // Custom-named orphans are indistinguishable from policies someone\n // wrote in SQL deliberately, so they are reported, never dropped.\n if (kept.length > 0) {\n outWarn(chalk.yellow(\" ⚠️ Policies in the database that no collection describes:\"));\n for (const p of kept) {\n outWarn(chalk.yellow(` • ${p.schema}.${p.table} → \"${p.name}\" (${p.command} TO ${p.roles.join(\", \")})`));\n }\n outWarn(chalk.yellow(\" Each is still in force. To keep one, describe it in its collection's `securityRules`\"));\n outWarn(chalk.yellow(\" (Studio's RLS view imports it); if it is stale, drop it by hand.\"));\n }\n\n // Missing/diverged are not push's to fix, but staying silent about\n // them is how a database ends up not matching its config.\n const remaining = { ...drift, orphaned: kept };\n if (hasDrift(remaining) && (remaining.missing.length > 0 || remaining.diverged.length > 0)) {\n outWarn(chalk.yellow(\" ⚠️ RLS policies do not match your collections:\"));\n outWarn(formatPolicyDrift({ ...remaining, orphaned: [] }));\n }\n });\n } catch (err) {\n outWarn(chalk.yellow(` ⚠️ Could not reconcile RLS policies: ${err instanceof Error ? err.message : String(err)}`));\n }\n}\n\n/**\n * Flags the `branch` subcommands take.\n *\n * Declared as an `arg` spec rather than picked out of argv by hand, which is\n * both how the rest of this file parses flags and how the documentation\n * verifier discovers them: it reads `arg({ … })` specs out of this source, so a\n * flag parsed any other way is one it reports as unrunnable in every page that\n * documents it. Hand-rolled parsing here cost exactly that — `--older-than`\n * worked and the docs check called it a command a reader cannot run.\n */\nconst BRANCH_FLAGS = {\n \"--older-than\": String,\n \"--include-dev-diff\": Boolean,\n \"--from\": String,\n \"--yes\": Boolean,\n \"-y\": \"--yes\"\n} as const;\n\n/** The source `branch create --from <source>` names, if it names one. */\nfunction createSource(rawArgs: readonly string[]): string | undefined {\n const at = rawArgs.indexOf(\"--from\");\n return at !== -1 && rawArgs[at + 1] ? rawArgs[at + 1] : undefined;\n}\n\nasync function branchCommand(rawArgs: string[]): Promise<void> {\n const branchAction = rawArgs[2]; // create, list, delete, info\n\n if (!branchAction || branchAction === \"--help\") {\n printBranchHelp();\n return;\n }\n\n // Before anything connects: a name that is not the name asked for is worth\n // refusing, and it costs a database round-trip to discover later.\n const extras = unexpectedBranchArgs(rawArgs.slice(2));\n if (extras.length > 0) {\n outError(\"\");\n outError(chalk.red(` ✗ Unexpected argument${extras.length > 1 ? \"s\" : \"\"}: ${extras.join(\" \")}`));\n outError(\"\");\n outError(chalk.gray(` ${chalk.bold(\"rebase db branch\")} takes one name. A branch name may contain letters,`));\n outError(chalk.gray(\" digits, underscores and hyphens — no spaces.\"));\n if (rawArgs[3]) {\n outError(chalk.gray(` Did you mean: ${chalk.cyan(`rebase db branch ${branchAction} ${[rawArgs[3], ...extras].join(\"-\")}`)}`));\n }\n outError(\"\");\n process.exit(1);\n }\n\n // Load .env for DATABASE_URL\n try {\n const dotenv = await import(\"dotenv\");\n const envPath = process.env.DOTENV_CONFIG_PATH;\n if (envPath) {\n dotenv.config({ path: envPath, quiet: true });\n } else {\n dotenv.config({ quiet: true });\n }\n } catch {\n // dotenv may not be installed\n }\n\n const databaseUrl = process.env.DATABASE_URL || process.env.ADMIN_CONNECTION_STRING;\n if (!databaseUrl) {\n outError(chalk.red(\"✗ DATABASE_URL is not set. Make sure your .env file is configured.\"));\n process.exit(1);\n }\n\n // Dynamic imports to avoid loading heavy deps when not needed\n const { DatabasePoolManager } = await import(\"./databasePoolManager\");\n const { BranchService, reopenClosedDatabases, reopenedDatabasesNotice } = await import(\"./services/BranchService\");\n const { drizzle } = await import(\"drizzle-orm/node-postgres\");\n const { Pool } = await import(\"pg\");\n\n // Before anything else, the databases this command can copy from opened\n // again if a forced create was killed with them closed — the main one, a\n // `--from` source, the branch this checkout is on. Every connection below,\n // the check just after this included, would otherwise fail on them.\n const healed = await reopenClosedDatabases(databaseUrl, [\n branchAction === \"create\" ? createSource(rawArgs) : undefined,\n process.env[ACTIVE_BRANCH_DATABASE_ENV]\n ]);\n for (const line of reopenedDatabasesNotice(healed)) outWarn(chalk.yellow(` ${line}`));\n\n // A database that is not running is said the way `db push` says it, not\n // as the Drizzle wrapper of whatever statement met it first.\n await checkDatabaseConnectivity(databaseUrl);\n // …and the probe's connection let go at once. It is the one the other\n // commands keep between steps, and this one does not use it again — while\n // open it is a session on the source database, and `CREATE DATABASE …\n // TEMPLATE` refuses a source with active connections, so every\n // `branch create` failed with \"the source database has active connections\".\n await closeAppClients();\n\n const pool = new Pool({ connectionString: databaseUrl,\nmax: 3 });\n const db = drizzle(pool);\n const poolManager = new DatabasePoolManager(databaseUrl);\n const branchService = new BranchService(db, poolManager);\n\n try {\n // The registry table, for the actions that write to it. `list` and\n // `info` only read, and run no DDL: a database without the table has\n // no branches.\n if (branchAction === \"create\" || branchAction === \"delete\" || branchAction === \"prune\") {\n await branchService.ensureBranchMetadataTable();\n }\n switch (branchAction) {\n case \"create\": {\n const name = rawArgs[3];\n if (!name) {\n outError(chalk.red(\"✗ Branch name is required.\"));\n out(chalk.gray(\" Usage: rebase db branch create <name> [--from <source>]\"));\n process.exit(1);\n }\n const source = createSource(rawArgs);\n const force = rawArgs.includes(\"--force\");\n out(\"\");\n out(chalk.bold(\" 🌿 Creating database branch...\"));\n out(chalk.gray(` Name: ${name}`));\n if (source) out(chalk.gray(` Source: ${source}`));\n if (force) out(chalk.gray(\" Force: other connections to the source will be disconnected\"));\n out(\"\");\n const branch = await branchService.createBranch(name, { source, force });\n out(chalk.green(` ✓ Branch \"${branch.name}\" created successfully.`));\n out(chalk.gray(` Database: rb_${branch.name}`));\n out(chalk.gray(` Parent: ${branch.parentDatabase}`));\n out(\"\");\n break;\n }\n\n case \"list\": {\n const branches = await branchService.hasBranchRegistry() ? await branchService.listBranches() : [];\n out(\"\");\n if (branches.length === 0) {\n out(chalk.gray(\" No branches found. Create one with: rebase db branch create <name>\"));\n } else {\n out(chalk.bold(` 🌿 ${branches.length} branch(es):`));\n out(\"\");\n // The one this checkout is switched to, as the CLI says.\n const current = process.env[ACTIVE_BRANCH_DATABASE_ENV]?.trim();\n for (const b of branches) {\n const size = b.sizeBytes != null\n ? chalk.gray(` (${formatBytes(b.sizeBytes)})`)\n : \"\";\n const age = chalk.gray(` — created ${timeAgo(b.createdAt)}`);\n const here = current && b.database === current ? chalk.cyan(\" (current — this checkout is on it)\") : \"\";\n out(` ${chalk.green(\"●\")} ${chalk.bold(b.name)}${here}${size}${age}`);\n out(chalk.gray(` from ${b.parentDatabase}`));\n }\n }\n out(\"\");\n break;\n }\n\n case \"delete\": {\n const name = rawArgs[3];\n if (!name) {\n outError(chalk.red(\"✗ Branch name is required.\"));\n out(chalk.gray(\" Usage: rebase db branch delete <name>\"));\n process.exit(1);\n }\n out(\"\");\n out(chalk.bold(` 🗑️ Deleting branch \"${name}\"...`));\n await branchService.deleteBranch(name, { force: rawArgs.includes(\"--force\") });\n out(chalk.green(` ✓ Branch \"${name}\" deleted.`));\n out(\"\");\n break;\n }\n\n case \"info\": {\n const name = rawArgs[3];\n if (!name) {\n outError(chalk.red(\"✗ Branch name is required.\"));\n out(chalk.gray(\" Usage: rebase db branch info <name>\"));\n process.exit(1);\n }\n const info = await branchService.hasBranchRegistry() ? await branchService.getBranchInfo(name) : undefined;\n out(\"\");\n if (!info) {\n // Exit 1, like `delete` on a branch that is not there.\n // These two answered the same question — \"is there a branch\n // called this?\" — and disagreed about how to say no: delete\n // failed, info printed `✗ Branch \"x\" not found.` and exited\n // 0. Anything reading the status saw success, so\n // `rebase db branch info \"$b\" && deploy_against \"$b\"` ran\n // the deploy against a branch that does not exist.\n outError(chalk.red(` ✗ Branch \"${name}\" not found.`));\n out(\"\");\n process.exit(1);\n } else {\n out(chalk.bold(` 🌿 Branch: ${info.name}`));\n out(chalk.gray(` Database: rb_${info.name}`));\n out(chalk.gray(` Parent: ${info.parentDatabase}`));\n out(chalk.gray(` Created: ${info.createdAt.toISOString()}`));\n if (info.sizeBytes != null) {\n out(chalk.gray(` Size: ${formatBytes(info.sizeBytes)}`));\n }\n }\n out(\"\");\n break;\n }\n\n case \"prune\": {\n const parsed = arg(BRANCH_FLAGS, { argv: rawArgs.slice(3), permissive: true });\n const olderThanRaw = parsed[\"--older-than\"] ?? null;\n const olderThanDays = olderThanRaw == null ? null : parseOlderThan(olderThanRaw);\n if (olderThanRaw != null && olderThanDays == null) {\n outError(chalk.red(` ✗ --older-than \"${olderThanRaw}\" is not a duration.`));\n out(chalk.gray(\" Use a number of days (14), or 14d / 2w.\"));\n process.exit(1);\n }\n\n const includeDevDiff = parsed[\"--include-dev-diff\"] === true;\n const { rows, databases } = await branchService.pruneCandidates();\n const plan = planPrune({ rows, databases, branchPrefix: \"rb_\" }, {\n olderThanDays,\n activeDatabase: process.env[ACTIVE_BRANCH_DATABASE_ENV]?.trim() || null\n });\n // Kept as `delete` keeps it, and said, whichever way the plan goes.\n const keptActive = (): void => {\n if (!plan.active) return;\n out(` ${chalk.gray(\"○\")} ${chalk.bold(plan.active.name)} ${chalk.gray(\"— this checkout is switched to it, so it is kept\")}`);\n out(chalk.gray(` To prune it, leave it first: ${chalk.cyan(\"rebase db branch switch --off\")}`));\n };\n\n out(\"\");\n if (planIsEmpty(plan, includeDevDiff)) {\n keptActive();\n out(chalk.gray(\" Nothing to prune.\"));\n if (!olderThanDays && rows.length > 0) {\n out(chalk.gray(` ${rows.length} branch(es) are healthy — --older-than 14 also removes old ones.`));\n }\n if (!includeDevDiff && plan.devDiff.length > 0) {\n out(chalk.gray(` ${plan.devDiff.length} Atlas scratch database(s) left over from db push;`));\n out(chalk.gray(\" --include-dev-diff removes those too.\"));\n }\n out(\"\");\n break;\n }\n\n out(chalk.bold(\" 🧹 Prune plan\"));\n out(\"\");\n for (const row of plan.staleRows) {\n out(` ${chalk.yellow(\"○\")} ${chalk.bold(row.name)} ${chalk.gray(\"— registered, but its database is gone; the entry will be removed\")}`);\n }\n for (const dbName of plan.orphanDatabases) {\n out(` ${chalk.yellow(\"○\")} ${chalk.bold(dbName)} ${chalk.gray(\"— a branch database with no entry; the database will be dropped\")}`);\n }\n for (const { branch, ageDays } of plan.expired) {\n out(` ${chalk.red(\"●\")} ${chalk.bold(branch.name)} ${chalk.gray(`— ${ageDays} days old; branch and database will be dropped`)}`);\n }\n keptActive();\n if (includeDevDiff) {\n for (const dbName of plan.devDiff) {\n out(` ${chalk.red(\"●\")} ${chalk.bold(dbName)} ${chalk.gray(\"— Atlas scratch database; will be dropped\")}`);\n }\n } else if (plan.devDiff.length > 0) {\n out(chalk.gray(` (${plan.devDiff.length} Atlas scratch database(s) not listed — --include-dev-diff)`));\n }\n out(\"\");\n\n if (parsed[\"--yes\"] !== true) {\n // Without a terminal nobody can answer, and \"Nothing was\n // changed.\" with exit 0 read as a prune that found nothing\n // to do. Refused, as `db reset` and `db pull` refuse.\n if (!process.stdin.isTTY) {\n outError(chalk.red(\" ✗ Nothing was pruned: there is no terminal to confirm on.\"));\n outError(chalk.gray(\" Re-run with --yes to remove what is listed above.\"));\n outError(\"\");\n process.exit(1);\n }\n // Dropping a database is not undoable and a branch may be\n // the only copy of an afternoon's work.\n const confirmed = await promptConfirm(\" Remove these? (y/N) \");\n if (!confirmed) {\n out(chalk.gray(\" Nothing was changed.\"));\n out(\"\");\n break;\n }\n }\n\n let removed = 0;\n for (const row of plan.staleRows) {\n await branchService.forgetBranchRow(row.name);\n removed += 1;\n }\n for (const dbName of plan.orphanDatabases) {\n await branchService.dropDatabase(dbName);\n removed += 1;\n }\n for (const { branch } of plan.expired) {\n await branchService.deleteBranch(branch.name);\n removed += 1;\n }\n if (includeDevDiff) {\n for (const dbName of plan.devDiff) {\n await branchService.dropDatabase(dbName);\n removed += 1;\n }\n }\n\n out(chalk.green(` ✓ Pruned ${removed} item(s).`));\n out(\"\");\n break;\n }\n\n default:\n outError(chalk.red(`Unknown branch action: \"${branchAction}\".`));\n printBranchHelp();\n process.exit(1);\n }\n } finally {\n await poolManager.shutdown();\n await pool.end();\n }\n}\n\nfunction printBranchHelp() {\n out(`\n${chalk.bold(\"rebase db branch\")} — Database branching commands\n\n${chalk.green.bold(\"Usage\")}\n rebase db branch ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.blue.bold(\"create\")} <name> [--from <source>] Create a new branch\n ${chalk.blue.bold(\"list\")} List all branches\n ${chalk.blue.bold(\"switch\")} [<name>|--off] Point this checkout at a branch\n ${chalk.blue.bold(\"delete\")} <name> Delete a branch\n ${chalk.blue.bold(\"info\")} <name> Show branch details\n ${chalk.blue.bold(\"prune\")} [--older-than <14|14d|2w>] Remove branches nothing is using\n\n${chalk.green.bold(\"Why prune\")}\n Every branch is a full-size copy — CREATE DATABASE ... TEMPLATE duplicates the\n files on disk, so five branches of a 100GB database cost 500GB. Prune also\n finds the two ways branches drift: an entry whose database was dropped\n outside Rebase, and a branch database whose entry never got written.\n\n${chalk.green.bold(\"Options\")}\n ${chalk.blue.bold(\"--force\")} Disconnect other sessions first.\n Postgres refuses to copy or drop a database\n anything else is connected to — usually your\n own \\`rebase dev\\`.\n ${chalk.blue.bold(\"--include-dev-diff\")} Also prune the Atlas scratch databases\n \\`db push\\` leaves behind.\n ${chalk.blue.bold(\"--yes, -y\")} Skip prune's confirmation prompt. Dropping a\n branch is not undoable, so this is the flag\n a CI job passes and a person usually should not.\n\n${chalk.green.bold(\"Examples\")}\n ${chalk.gray(\"# Create a branch and work on it\")}\n rebase db branch create feature_auth\n rebase db branch switch feature_auth\n\n ${chalk.gray(\"# Create a branch from a specific source\")}\n rebase db branch create staging --from production\n\n ${chalk.gray(\"# Remove branches older than two weeks, and anything orphaned\")}\n rebase db branch prune --older-than 2w\n\n ${chalk.gray(\"# List all branches\")}\n rebase db branch list\n\n ${chalk.gray(\"# Delete a branch\")}\n rebase db branch delete feature_auth\n`);\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\n/** A branch's age, for \"…created 6d ago\". */\nfunction timeAgo(date: Date): string {\n // No horizon: a branch created a year ago should still report an age here,\n // rather than fall back to a bare date in a one-line list entry.\n return formatRelativeTime(date, { maxMs: Number.POSITIVE_INFINITY }) ?? \"unknown\";\n}\n\n\n\n/**\n * Whether DATABASE_URL is the managed development database (PGlite), as the\n * CLI resolved it and says in `REBASE_DEV_DATABASE_KIND`.\n */\nfunction managedDatabase(): boolean {\n return process.env.REBASE_DEV_DATABASE_KIND === \"managed\";\n}\n\n/**\n * The Atlas scratch database this process created, dropped once the db\n * command that needed it succeeds — see `ScratchDatabase`.\n */\nconst scratchDatabase = new ScratchDatabase({ create: ensureDevDatabaseExists, drop: dropDevDatabase });\n\nasync function runAtlas(\n domain: \"schema\" | \"migrate\",\n args: string[],\n collectionsPath?: string,\n opts: {\n captureStdout?: boolean;\n /**\n * Throw instead of exiting once the failure has been explained, so a\n * caller with something to put back — the generated columns a push\n * dropped out of Atlas's way — gets to do it. The error is marked\n * `alreadyReported`: everything worth saying is on stderr already.\n */\n throwOnFailure?: boolean;\n /**\n * Show the apply's report without the plan Atlas prints before it —\n * see `schema/atlas-apply-report.ts`. For the apply a push has already\n * planned, which otherwise shows each statement twice.\n */\n omitPlanEcho?: boolean;\n } = {}\n): Promise<string> {\n const atlasBin = resolveLocalBin(\"atlas\");\n if (!atlasBin) {\n // Two very different causes, and the advice for one is a loop for the\n // other — see `diagnoseMissingBin`. This used to say \"Install it with:\n // pnpm add -D @ariga/atlas\" unconditionally, which is the exact command\n // that produces the far more common of the two states.\n outError(chalk.red(\"\\n✗ The atlas binary is missing, so the schema cannot be applied.\\n\"));\n\n // Every remedy below is package-manager specific, and this used to print\n // pnpm's unconditionally. npm 12 blocks a dependency's install scripts\n // the same way pnpm 10 does, so an npm reader was handed `pnpm\n // approve-builds` and a `\"pnpm\"` package.json key — correct advice, for\n // somebody else. Read the lockfile and answer the reader in front of us.\n const manager = detectProjectPackageManager();\n\n const diagnosis = diagnoseMissingBin(\"@ariga/atlas\");\n\n if (diagnosis === \"bin-link-missing\") {\n // The binary IS on disk; only the `node_modules/.bin` shim that\n // points at it is not. pnpm produces this when it writes the link\n // before the script that creates the target (\"Failed to create bin\n // … ENOENT\"), and so does a tree copied without its symlinks.\n // Sending this reader to `approve-builds` does nothing: nothing is\n // blocked.\n outError(chalk.yellow(\" @ariga/atlas and its binary are both on disk — only the\\n\"\n + \" node_modules/.bin/atlas link that puts it on PATH is missing.\\n\"));\n outError(chalk.gray(\n \" Usually a half-written install: the link is created before the script that\\n\"\n + \" downloads the target, so an interrupted or copied tree keeps the binary and\\n\"\n + \" loses the shim.\\n\"\n ));\n outError(\" Fix it with:\\n\");\n outError(chalk.bold(` ${describeReinstallCommand(manager)}\\n`));\n } else if (diagnosis === \"build-script-blocked\") {\n outError(chalk.yellow(\" @ariga/atlas IS installed — only its binary is missing.\\n\"));\n outError(chalk.gray(\n \" It downloads that binary in a `preinstall` script, and pnpm 10+ and npm 12+\\n\" +\n \" do not run a dependency's scripts unless you allow it. The install still\\n\" +\n \" exits 0, so the only sign is a line several screens up: pnpm's\\n\" +\n \" `Ignored build scripts: @ariga/atlas`, or npm's `install scripts blocked`.\\n\"\n ));\n outError(\" Fix it with either:\\n\");\n for (const line of describeBuildScriptRemedy(\"@ariga/atlas\", manager)) {\n outError(line ? chalk.bold(line) : \"\");\n }\n outError(\"\");\n } else {\n outError(chalk.gray(\" It is not installed in this project.\\n\"));\n const member = workspaceMemberDir();\n outError(member === null ? \" Install it with:\\n\" : \" Install it with (from the project root):\\n\");\n outError(chalk.bold(` ${describeDevAddCommand(\"@ariga/atlas\", manager, member)}\\n`));\n outError(chalk.gray(\n \" If the install then reports blocked or ignored build scripts, allow them too —\\n\" +\n \" the package carries a `preinstall` script that fetches the binary.\\n\"\n ));\n }\n process.exit(1);\n }\n\n const env = { ...process.env as Record<string, string> };\n try {\n const dotenv = await import(\"dotenv\");\n const envPaths = [\n process.env.DOTENV_CONFIG_PATH,\n path.resolve(process.cwd(), \".env\"),\n path.resolve(process.cwd(), \"../.env\"),\n path.resolve(process.cwd(), \"../../.env\")\n ].filter(Boolean) as string[];\n\n for (const p of envPaths) {\n if (fs.existsSync(p)) {\n const parsed = dotenv.config({ path: p, quiet: true });\n if (parsed.parsed) {\n for (const [key, val] of Object.entries(parsed.parsed)) {\n if (env[key] === undefined) {\n env[key] = val;\n }\n }\n break;\n }\n }\n }\n } catch {\n // ignore\n }\n\n const databaseUrl = env.DATABASE_URL;\n if (!databaseUrl) {\n outError(chalk.red(\"✗ DATABASE_URL is not set. Make sure your .env file is configured.\"));\n process.exit(1);\n }\n\n // Pre-flight: verify the database is reachable before running Atlas.\n // This catches ECONNREFUSED / auth failures with a friendly banner\n // instead of letting Atlas surface a raw error.\n await checkDatabaseConnectivity(databaseUrl);\n\n let devDatabase: { url: string; named: boolean };\n try {\n devDatabase = atlasDevDatabaseUrl(databaseUrl, env);\n } catch (err) {\n outError(chalk.red(`✗ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n const devDatabaseUrl = devDatabase.url;\n // Only for the calls that plan against it: `migrate apply`, `hash` and\n // `status` never read `--dev-url`, so `db migrate` makes no scratch copy.\n // A database `REBASE_ATLAS_DEV_URL` names is someone else's: not made here.\n if (takesDevUrl(domain, args) && !devDatabase.named) await scratchDatabase.ensure(databaseUrl, devDatabaseUrl);\n\n // Atlas speaks libpq, which rejects the `sslmode=no-verify` that\n // node-postgres accepts, and defaults to `require` where node-postgres\n // asks for no SSL — see `forAtlas`. Rewritten only for the argv, so\n // everything above still connects with the URL as configured.\n const atlasUrl = forAtlas(databaseUrl);\n const atlasDevUrl = forAtlas(devDatabaseUrl);\n\n // Everything Atlas must keep its hands off, in one list.\n //\n // Gathered only for the invocations that accept the flag — which is\n // `schema apply` and nothing else. `atlas migrate diff` and `migrate apply`\n // both reject `--exclude` outright with `unknown flag`, and passing it there\n // took `rebase db generate` and `rebase db migrate` down for every project\n // declaring a `search` block; the diff keeps the same objects out of the\n // migration afterwards instead, with `stripCarvedOutStatements`. See\n // `acceptsExcludeFlag`.\n const excludes: string[] = [];\n if (collectionsPath && acceptsExcludeFlag(domain, args)) {\n // Search and vector objects are Rebase's, not Atlas's: the desired state\n // does not carry them, so an apply left to itself would drop them.\n excludes.push(...await getSearchExcludes(collectionsPath));\n excludes.push(...await getVectorExcludes(collectionsPath));\n excludes.push(...await getTriggerExcludes(collectionsPath));\n\n // Fail CLOSED: the exclude list is the only thing shielding\n // non-collection tables from the auto-approved apply. If we can't\n // introspect the database to build it, abort rather than proceed with\n // a partial list that would let Atlas drop unmanaged tables.\n try {\n excludes.push(...await getTableExcludes(databaseUrl, collectionsPath));\n } catch (err) {\n if (err instanceof ExcludeIntrospectionError) {\n outError(chalk.red(\"\\n✗ Aborting push: could not determine which tables to protect.\"));\n outError(chalk.gray(` ${err.message}`));\n outError(chalk.gray(\" Refusing to apply — a partial exclude list could drop tables Rebase does not manage.\"));\n const hint = diagnoseDbError(err.cause ?? err, databaseUrl);\n if (hint) outError(hint);\n throw new CommandStopped(\"Could not determine which tables to protect.\");\n }\n throw err;\n }\n\n // And the indexes on those tables that Rebase did not create. Same\n // fail-closed contract as the table list above, for the same reason: a\n // partial answer here silently drops somebody's index.\n try {\n excludes.push(...await getForeignIndexExcludes(databaseUrl, collectionsPath));\n } catch (err) {\n if (err instanceof ExcludeIntrospectionError) {\n outError(chalk.red(\"\\n✗ Aborting push: could not determine which indexes to protect.\"));\n outError(chalk.gray(` ${err.message}`));\n outError(chalk.gray(\" Refusing to apply — a partial exclude list could drop an index Rebase does not manage.\"));\n const hint = diagnoseDbError(err.cause ?? err, databaseUrl);\n if (hint) outError(hint);\n throw new CommandStopped(\"Could not determine which indexes to protect.\");\n }\n throw err;\n }\n\n // And the CHECK and EXCLUDE constraints, which a collection cannot\n // declare: left out of the plan, Atlas drops every one of them in the\n // first push after `schema introspect`. Same fail-closed contract.\n try {\n const desiredSqlFile = path.join(generatedSqlDir(), \"schema.sql\");\n const desiredSql = fs.existsSync(desiredSqlFile) ? fs.readFileSync(desiredSqlFile, \"utf-8\") : \"\";\n excludes.push(...await getUndeclaredConstraintExcludes(databaseUrl, desiredSql));\n } catch (err) {\n if (err instanceof ExcludeIntrospectionError) {\n outError(chalk.red(\"\\n✗ Aborting push: could not determine which constraints to protect.\"));\n outError(chalk.gray(` ${err.message}`));\n outError(chalk.gray(\" Refusing to apply — a partial exclude list could drop a CHECK or EXCLUDE constraint the database enforces.\"));\n const hint = diagnoseDbError(err.cause ?? err, databaseUrl);\n if (hint) outError(hint);\n throw new CommandStopped(\"Could not determine which constraints to protect.\");\n }\n throw err;\n }\n }\n\n const atlasArgs = buildAtlasArgs({\n domain, args, url: atlasUrl, devUrl: atlasDevUrl, excludes, singleSession: managedDatabase()\n });\n\n // The managed database is one session every connection shares, so the\n // `search_path` Atlas gives the connection it creates its revisions table\n // on is never applied, and the table lands in `public` while Atlas reads it\n // from `rebase`. Made here, qualified, Atlas finds it where it looks — see\n // `schema/atlas-revisions.ts`.\n if (managedDatabase() && readsRevisions(domain, args)) await ensureAtlasRevisionsTable(databaseUrl);\n\n // On the managed database a connection is the scarce thing. PGlite is one\n // session behind a socket server that accepts only a few, a running\n // `rebase dev` holds some of them, and `schema apply` and `migrate apply`\n // open two each. The one over the limit is closed unanswered, and Atlas\n // says only `Error: EOF`. So the connection this process keeps between\n // steps is let go while Atlas runs; the next step opens another, which\n // locally costs milliseconds.\n if (managedDatabase()) await closeAppClients();\n\n // Stream stdout live but tee stderr so we can inspect Atlas's error text\n // for known, actionable failure modes (e.g. a dependency-drop that leaves\n // the schema half-applied) after the process exits. When capturing (used\n // for the destructive-change dry-run), pipe stdout and collect it instead.\n const subprocess = execa(atlasBin, atlasArgs, {\n cwd: process.cwd(),\n stdout: opts.captureStdout || opts.omitPlanEcho ? \"pipe\" : \"inherit\",\n stderr: \"pipe\",\n env\n });\n let stdoutText = \"\";\n if (opts.captureStdout) {\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n stdoutText += chunk.toString();\n });\n } else if (opts.omitPlanEcho) {\n const report = createApplyReportFilter();\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => process.stdout.write(report.push(chunk.toString())));\n subprocess.stdout?.on(\"end\", () => process.stdout.write(report.flush()));\n }\n let stderrText = \"\";\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stderrText += text;\n // Atlas has the URLs on its command line, and an error such as a URL\n // it cannot parse quotes one back, password and all.\n process.stderr.write(redactConnectionPasswords(text));\n });\n try {\n await subprocess;\n } catch {\n // What Atlas was planning against is the one thing worth reading after\n // its own failure, so the scratch database outlives this command —\n // unless Atlas never got as far as planning, when it holds nothing.\n await scratchDatabase.afterAtlasFailure(stderrText);\n outError(chalk.red(`\\n✗ atlas ${domain} ${args.join(\" \")} failed.\\n`));\n // Surface actionable recovery guidance for recognized failures. The\n // Atlas-shaped ones first: they read the invocation as well as the\n // text, so they can tell `migrate apply` hitting an already-provisioned\n // database (which wants a baseline) from `schema apply` hitting a real\n // conflict. `diagnoseDbError` is the connection-level fallback, shared\n // with the boot path.\n const atlasHint = await diagnoseAtlasFailure({\n domain,\n args,\n stderr: stderrText,\n databaseUrl,\n latestMigrationVersion: latestMigrationVersion(),\n managedDatabase: managedDatabase()\n });\n const hint = atlasHint ?? diagnoseDbError({ message: stderrText }, databaseUrl);\n if (hint) {\n outError(hint);\n }\n if (opts.throwOnFailure) {\n throw Object.assign(new Error(`atlas ${domain} ${args.join(\" \")} failed`), { alreadyReported: true });\n }\n process.exit(1);\n }\n // Atlas prints the plan to stdout, but fall back to stderr so the\n // destructive-change detector never misses a plan on a version/build that\n // routes it differently.\n if (opts.captureStdout) {\n return stdoutText.trim().length > 0 ? stdoutText : stderrText;\n }\n return \"\";\n}\n\nasync function generatePostgresDdlCommand(\n rawArgs: string[],\n options: { retireLegacyCopies?: boolean } = {}\n): Promise<void> {\n const argsList = arg(\n {\n \"--collections\": String,\n \"--output\": String,\n \"-c\": \"--collections\",\n \"-o\": \"--output\"\n },\n {\n argv: rawArgs.slice(2),\n permissive: true\n }\n );\n\n const inProcess = generatesInProcess();\n const ddl = inProcess ? undefined : resolveChildScript(\"generate-postgres-ddl\");\n if (ddl && !ddl.ok) {\n outError(chalk.red(childScriptError(\"DDL generator\", ddl.reason)));\n process.exit(1);\n }\n\n const collectionsPath = argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n const outputPath = argsList[\"--output\"] || path.join(GENERATED_SQL_DIR, \"schema.sql\");\n\n // Only for the default location: an explicit `--output` is somebody's own\n // arrangement, and its directory is theirs to manage.\n if (!argsList[\"--output\"]) {\n const retire = options.retireLegacyCopies !== false;\n const retired = prepareGeneratedSqlDir(process.cwd(), { retire });\n if (retired.length > 0 && !retire) {\n out(chalk.gray(\n ` The next \\`rebase db push\\` or \\`rebase db generate\\` removes the old copies an earlier ` +\n `release committed:\\n ${retired.join(\", \")}`\n ));\n } else if (retired.length > 0) {\n out(chalk.gray(\n ` Generated SQL is written to ${GENERATED_SQL_DIR}/ now, which is not committed. ` +\n `Removed the old copies — commit the deletion:\\n ${retired.join(\", \")}`\n ));\n }\n }\n\n if (!ddl) {\n await generateInProcess(\"Postgres DDL generator\", \"Postgres DDL\", async ({ writePostgresDdl }) => {\n await writePostgresDdl({\n collectionsPath: path.resolve(process.cwd(), collectionsPath),\n outputPath: path.resolve(process.cwd(), outputPath)\n });\n });\n return;\n }\n\n const cmdParts = [\n ddl.bin,\n ...ddl.args,\n `--collections=${collectionsPath}`,\n `--output=${outputPath}`\n ];\n\n try {\n await execa(cmdParts[0], cmdParts.slice(1), {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: { ...process.env as Record<string, string> }\n });\n } catch (err: unknown) {\n // The generator runs with inherited stdio, so on a non-zero exit its\n // own message is already the last useful thing on the terminal and\n // execa's wrapper (\"Command failed with exit code 1: …/tsx …\") would\n // bury it. Repeat it only when the child never got as far as speaking.\n if (typeof (err as { exitCode?: number }).exitCode === \"number\") {\n outError(chalk.red(\"✗ Postgres DDL generation failed — nothing was applied.\"));\n } else {\n outError(chalk.red(`✗ Failed to run Postgres DDL generator: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n}\n\n/**\n * `schema stale [--fix]` — is the generated Drizzle schema older than the rule\n * that derives its foreign-key names?\n *\n * This exists for one upgrade path and is worth the command. 0.13 derives\n * `category_id` where 0.12 derived `categorie_id`; boot-ensure renames the\n * database column to match, and the project's checked-in\n * `backend/src/schema.generated.ts` is then wrong in a way nothing the developer\n * did would explain. Relation validation refuses to boot on it, permanently,\n * because the rename has already been applied and will not run again.\n *\n * `rebase dev` calls this with `--fix` before starting the backend, so the\n * upgrade behaves the way the release note says it does: the column moves and the\n * project keeps working. Without `--fix` it reports and exits non-zero, which is\n * what a build or a CI step wants.\n */\nasync function schemaStaleCommand(rawArgs: string[]): Promise<void> {\n const argsList = arg(\n {\n \"--collections\": String,\n \"--output\": String,\n \"--fix\": Boolean,\n \"-c\": \"--collections\",\n \"-o\": \"--output\",\n // Both spellings, on every command that writes a file. See\n // `OUTPUT_FLAG_ALIASES` in cli-flags.ts.\n \"--out\": \"--output\"\n },\n { argv: rawArgs.slice(2), permissive: true }\n );\n\n const collectionsPath = argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n const outputPath = argsList[\"--output\"] || path.join(\"src\", \"schema.generated.ts\");\n const schemaFile = path.resolve(process.cwd(), outputPath);\n\n const fix = Boolean(argsList[\"--fix\"]);\n const generatedExists = fs.existsSync(schemaFile);\n\n const { loadCollections } = await import(\"./schema/doctor\");\n const { findLegacyForeignKeyNames, compareGeneratedDeclarations, staleVerdict } =\n await import(\"./schema/generated-schema-staleness\");\n const { generateSchema } = await import(\"./schema/generate-drizzle-schema-logic\");\n const { relationalCollections } = await import(\"@rebasepro/common\");\n\n let stale: ReturnType<typeof findLegacyForeignKeyNames> = [];\n let differences: ReturnType<typeof compareGeneratedDeclarations> = [];\n let unreadable: string | undefined;\n if (generatedExists) {\n try {\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n const onDisk = fs.readFileSync(schemaFile, \"utf8\");\n stale = findLegacyForeignKeyNames(onDisk, collections);\n // The check the command's own summary promises, and the one it did\n // not make: render what these collections generate and compare it,\n // declaration by declaration, with the file on disk. Without this\n // the verdict rested entirely on `findLegacyForeignKeyNames`, which\n // looks for one historical naming defect — so a file the generator\n // visibly rewrites was reported as a match.\n const postgresCollections = relationalCollections(collections);\n if (postgresCollections.length > 0) {\n differences = compareGeneratedDeclarations(generateSchema(postgresCollections), onDisk);\n }\n } catch (err) {\n // Best-effort by design: a collections directory that will not load\n // is a real error, but it is one the boot reports far better than\n // this does. Said out loud all the same — this command used to exit\n // 0 in silence here, which is indistinguishable from a clean run.\n unreadable = err instanceof Error ? err.message : String(err);\n // Imported here, not at the top: the server is a 1.2 MB bundle plus\n // hono, drizzle and zod, and every driver command — `db push`, the\n // two runs in each `rebase dev` start — paid ~0.4 s under tsx to\n // load it before parsing its argv, for this one debug line.\n const { logger } = await import(\"@rebasepro/server\");\n logger.debug(`schema stale: skipped (${unreadable})`);\n }\n }\n\n // The decision lives in `generated-schema-staleness.ts` so it can be tested:\n // this file uses `import.meta`, which the driver's jest suite cannot load,\n // and three of this command's four paths were silent because of it.\n const verdict = staleVerdict({ outputPath, generatedExists, stale, differences, unreadable, fix });\n\n for (const line of verdict.lines) {\n if (!line) out(\"\");\n else if (line.includes(\"⚠️\")) outWarn(chalk.yellow(line));\n else if (verdict.exitCode !== 0) outError(chalk.red(line));\n else if (line.includes(\"✓\")) out(chalk.green(line));\n else out(chalk.gray(line));\n }\n\n if (verdict.exitCode !== 0) process.exit(verdict.exitCode);\n if (!verdict.regenerate) return;\n\n await schemaCommand(\"generate\", [\"schema\", \"generate\", `--collections=${collectionsPath}`, `--output=${outputPath}`]);\n}\n\nasync function schemaCommand(\n subcommand: string,\n rawArgs: string[],\n options: { nextStep?: boolean } = {}\n): Promise<void> {\n // The same second line of defence `dbCommand` above carries, for the same\n // reason: this file is also its own CLI, spawned directly by\n // `resolvePluginCliScript` and executable on its own. Nothing here had a\n // `--help` case, so `schema generate --help` regenerated the schema and\n // `schema introspect --help` rewrote the collection files — a flag whose\n // entire job is to print text, overwriting authored source.\n //\n // Guarded by a real subcommand: the internal callers below re-enter this\n // function with a synthesised argv, and none of them can carry `--help`.\n if (subcommand && (rawArgs.includes(\"--help\") || rawArgs.includes(\"-h\"))) {\n out(\"\");\n out(chalk.bold(` rebase schema ${subcommand}`));\n out(chalk.gray(\" Run `rebase schema --help` for the full page — this is the driver's own entry point.\"));\n out(\"\");\n return;\n }\n\n if (subcommand === \"stale\") {\n await schemaStaleCommand(rawArgs);\n return;\n }\n\n if (subcommand === \"generate\") {\n const argsList = arg(\n {\n \"--collections\": String,\n \"--output\": String,\n \"--watch\": Boolean,\n \"-c\": \"--collections\",\n \"-o\": \"--output\",\n \"--out\": \"--output\",\n \"-w\": \"--watch\"\n },\n {\n argv: rawArgs.slice(2), // db generate ... or schema generate ...\n permissive: true\n }\n );\n\n const collectionsPath = argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n const outputPath = argsList[\"--output\"] || path.join(\"src\", \"schema.generated.ts\");\n const watch = argsList[\"--watch\"] || false;\n\n // One-shot generation runs here, in this process: see `generate-files.ts`.\n // `--watch` keeps its own process, which re-imports the collections on\n // every save — this process's module cache would not.\n if (!watch && generatesInProcess()) {\n out(\"\");\n out(chalk.bold(\" 🔧 Rebase Schema Generator\"));\n out(\"\");\n await generateInProcess(\"schema generator\", \"Drizzle schema\", async ({ writeDrizzleSchema }) => {\n await writeDrizzleSchema({\n collectionsPath: path.resolve(process.cwd(), collectionsPath),\n outputPath: path.resolve(process.cwd(), outputPath),\n nextStep: options.nextStep\n });\n });\n return;\n }\n\n // Here we just invoke the local generate-drizzle-schema.ts since we are inside the postgresql-backend\n // If installed in node_modules, __cliDirname is node_modules/@rebasepro/server-postgres/dist or src.\n const generator = resolveChildScript(\"generate-drizzle-schema\");\n if (!generator.ok) {\n outError(chalk.red(childScriptError(\"schema generator\", generator.reason)));\n process.exit(1);\n }\n\n out(\"\");\n out(chalk.bold(\" 🔧 Rebase Schema Generator\"));\n out(\"\");\n\n const cmdParts = [\n generator.bin,\n ...generator.args,\n `--collections=${collectionsPath}`,\n `--output=${outputPath}`\n ];\n if (watch) {\n cmdParts.push(\"--watch\");\n }\n if (options.nextStep === false) {\n cmdParts.push(\"--no-next-step\");\n }\n\n try {\n await execa(cmdParts[0], cmdParts.slice(1), {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: { ...process.env as Record<string, string> }\n });\n } catch (err: unknown) {\n // Same contract as the DDL generator above: a child that exited\n // non-zero has already printed the cause on inherited stdio.\n if (typeof (err as { exitCode?: number }).exitCode === \"number\") {\n outError(chalk.red(\"✗ Drizzle schema generation failed — nothing was applied.\"));\n } else {\n outError(chalk.red(`✗ Failed to run schema generator: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n } else if (subcommand === \"introspect\") {\n const argsList = arg(\n {\n \"--output\": String,\n \"--collections\": String,\n \"--force\": Boolean,\n \"--schema\": String,\n \"--data-inference\": Boolean,\n \"--no-data-inference\": Boolean,\n \"-o\": \"--output\",\n \"--out\": \"--output\",\n \"-c\": \"--collections\",\n \"-f\": \"--force\"\n },\n {\n argv: rawArgs.slice(2),\n permissive: true\n }\n );\n\n const introspect = resolveChildScript(\"introspect-db\");\n if (!introspect.ok) {\n outError(chalk.red(childScriptError(\"introspection script\", introspect.reason)));\n process.exit(1);\n }\n\n const outputPath = argsList[\"--output\"] || argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n\n out(\"\");\n out(chalk.bold(\" 🔍 Rebase Schema Introspector\"));\n out(\"\");\n\n const cmdParts = [\n introspect.bin,\n ...introspect.args,\n `--output=${outputPath}`,\n ...(argsList[\"--force\"] ? [\"--force\"] : []),\n ...(argsList[\"--schema\"] ? [`--schema=${argsList[\"--schema\"]}`] : []),\n // The introspector reads these itself; without one it asks.\n ...(argsList[\"--data-inference\"] ? [\"--data-inference\"] : []),\n ...(argsList[\"--no-data-inference\"] ? [\"--no-data-inference\"] : [])\n ];\n\n try {\n await execa(cmdParts[0], cmdParts.slice(1), {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: { ...process.env as Record<string, string> }\n });\n } catch (err: unknown) {\n // A child that ran and exited non-zero already said why, through\n // the inherited stdio; repeating execa's \"Command failed with exit\n // code 1: node --import …\" under it only buried that. A child that\n // never started printed nothing, so that one is said here.\n const exitCode = typeof err === \"object\" && err !== null ? Reflect.get(err, \"exitCode\") : undefined;\n if (typeof exitCode !== \"number\") {\n outError(chalk.red(`✗ Failed to run schema introspector: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n } else {\n outError(chalk.red(\"Unknown schema command.\"));\n process.exit(1);\n }\n}\n\nasync function doctorPluginCommand(rawArgs: string[]): Promise<void> {\n const parsedArgs = arg(\n {\n \"--collections\": String,\n \"--schema\": String,\n \"--sdk\": String,\n \"--policies\": Boolean,\n \"-c\": \"--collections\",\n \"-s\": \"--schema\",\n \"-k\": \"--sdk\"\n },\n {\n argv: rawArgs.slice(1), // skip \"doctor\"\n permissive: true\n }\n );\n\n const doctor = resolveChildScript(\"doctor-cli\");\n if (!doctor.ok) {\n outError(chalk.red(childScriptError(\"doctor script\", doctor.reason)));\n process.exit(1);\n }\n\n const collectionsPath = parsedArgs[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n const schemaPath = parsedArgs[\"--schema\"] || path.join(\"src\", \"schema.generated.ts\");\n const sdkPath = parsedArgs[\"--sdk\"] || path.join(\"..\", \"generated\", \"sdk\", \"database.types.ts\");\n\n const cmdParts = [\n doctor.bin,\n ...doctor.args,\n `--collections=${collectionsPath}`,\n `--schema=${schemaPath}`,\n `--sdk=${sdkPath}`,\n // Only the RLS checks: skips the schema/SDK diff, so it can run against\n // a deployed database as a CI gate.\n ...(parsedArgs[\"--policies\"] ? [\"--policies\"] : [])\n ];\n\n try {\n await execa(cmdParts[0], cmdParts.slice(1), {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: { ...process.env as Record<string, string> }\n });\n } catch {\n process.exit(1);\n }\n}\n\n\n// Entry point when called directly\nconst argv1Real = process.argv[1] ? fs.realpathSync(process.argv[1]) : \"\";\nif (import.meta.url === `file://${argv1Real}`) {\n // Drop node and script path\n runPluginCommand(process.argv.slice(2)).catch((error: unknown) => {\n reportCommandFailure(error);\n process.exit(1);\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../src/tsx-loader.ts","../src/schema/generated-column-conflicts.ts","../src/schema/carved-out-migration.ts","../src/schema/migration-post-process.ts","../src/schema/atlas-argv.ts","../src/schema/atlas-revisions.ts","../src/schema/atlas-apply-report.ts","../src/cli-scratch-database.ts","../src/schema/migrate-baseline.ts","../src/cli-push.ts","../src/cli-collections-path.ts","../src/branch-prune.ts","../src/cli.ts"],"sourcesContent":["import { createRequire } from \"module\";\nimport path from \"path\";\nimport { pathToFileURL } from \"url\";\n\n/**\n * tsx's loader, as the URL `node --import` takes, or null when none resolves.\n *\n * For running one of this driver's scripts in one Node process. The `tsx`\n * binary is a relay — pnpm's `.bin/tsx` shell shim, then tsx's CLI in one Node,\n * which spawns a second Node with this same loader to run the script — so\n * spawning through it costs a shell and a Node start (~50–100 ms) per child.\n *\n * Resolved the way Node resolves the package: from the project the driver\n * runs in first (its cwd is the backend, where a scaffold declares tsx), then\n * from this package. A URL rather than a path: a Windows path is not a valid\n * `--import` specifier.\n */\nexport function resolveTsxLoader(): string | null {\n const bases = [path.join(process.cwd(), \"noop.js\"), import.meta.url];\n for (const base of bases) {\n try {\n return pathToFileURL(createRequire(base).resolve(\"tsx\")).href;\n } catch {\n // Not resolvable from here; try the next base.\n }\n }\n return null;\n}\n","/**\n * Which columns an Atlas plan cannot touch, because a generated column reads\n * them.\n *\n * PostgreSQL refuses `ALTER COLUMN … TYPE` and `DROP COLUMN` on any column a\n * `GENERATED ALWAYS AS … STORED` expression depends on:\n *\n * cannot alter type of a column used by a generated column\n *\n * Atlas cannot see that coming. A search block's `tsvector` is *deliberately*\n * hidden from it (`searchExcludePatterns`) — Rebase owns that column, and an\n * Atlas that could see it would plan a `DROP COLUMN` for it on every push,\n * since the desired state it is given never mentions one. So Atlas plans an\n * alter against a column whose dependant is invisible to it, PostgreSQL\n * refuses, and because `schema apply` runs its plan in a single transaction\n * **every unrelated statement rolls back with it**. One `varchar(255)` → `text`\n * widening on a searched column is enough to make `rebase db push` a no-op\n * forever, with an error that names neither the generated column nor the reason.\n *\n * The fix is the same one the search column's own stamp guard already\n * prescribes when a `search` block changes: drop the generated column, let the\n * apply through, and rebuild it from `search.sql` afterwards. It is cheap to\n * rebuild (one table rewrite, which the `ALTER … TYPE` was going to cost\n * anyway) and there is no other order that works — the expression cannot be\n * altered in place at all.\n *\n * Everything here is side-effect free: the plan is text and the dependencies\n * are rows someone else read. Unit-tested in\n * `generated-column-conflicts.test.ts`.\n */\nimport { atlasExcludePattern } from \"./atlas-exclude\";\nimport { extractPlanStatements, fromAlterTable } from \"./destructive-sql\";\n\n/** An operation on a column that PostgreSQL refuses while a dependant exists. */\nexport type ColumnMutationKind = \"type\" | \"drop\";\n\nexport interface ColumnMutation {\n /** Absent when the plan did not qualify the table; matched loosely then. */\n schema?: string;\n table: string;\n column: string;\n kind: ColumnMutationKind;\n}\n\n/** One `generated column → column it reads` edge, as read from the catalogue. */\nexport interface GeneratedColumnDependency {\n schema: string;\n table: string;\n /** The generated column. */\n column: string;\n /** A column its expression reads. */\n dependsOn: string;\n}\n\n/** A generated column standing in the way of the plan, and why. */\nexport interface GeneratedColumnConflict {\n schema: string;\n table: string;\n /** The generated column that has to go before the apply. */\n column: string;\n /** The mutated columns it reads, deduplicated and sorted. */\n blocking: { column: string; kind: ColumnMutationKind }[];\n}\n\n/** `\"public\".\"posts\"` / `public.posts` / `posts` → its parts. */\nconst IDENT = String.raw`(?:\"[^\"]+\"|[A-Za-z_][A-Za-z0-9_$]*)`;\nconst TABLE_RE = new RegExp(String.raw`^ALTER\\s+TABLE\\s+(?:ONLY\\s+)?(${IDENT})(?:\\.(${IDENT}))?`, \"i\");\nconst ALTER_COLUMN_RE = new RegExp(\n String.raw`\\bALTER\\s+(?:COLUMN\\s+)?(${IDENT})\\s+(?:SET\\s+DATA\\s+)?TYPE\\b`, \"gi\"\n);\nconst DROP_COLUMN_RE = new RegExp(\n String.raw`\\bDROP\\s+COLUMN\\s+(?:IF\\s+EXISTS\\s+)?(${IDENT})`, \"gi\"\n);\n\nconst unquote = (ident: string): string =>\n ident.startsWith(\"\\\"\") ? ident.slice(1, -1) : ident;\n\n/**\n * Every column an Atlas plan retypes or drops, with the table it belongs to.\n *\n * One statement carries many clauses — Atlas emits `ALTER TABLE \"public\".\"posts\"\n * ALTER COLUMN \"title\" TYPE text, ALTER COLUMN \"slug\" TYPE text, …` — so the\n * table is read once per statement and the clauses are scanned within it.\n */\nexport function parseColumnMutations(planSql: string): ColumnMutation[] {\n const mutations: ColumnMutation[] = [];\n\n // The same reading of the plan the destructive gate uses, and it has to\n // be the same: what `schema apply --dry-run` prints is a report, not SQL,\n // with a heading glued above the first statement and every statement\n // printed twice. Stripping a leading `->` off `;`-split text was the old\n // reading here, and it never saw the first statement of a plan — so a\n // retyped searched column failed every push with no hint, while\n // `db generate`, which parses a clean migration file, got it right.\n for (const raw of extractPlanStatements(planSql)) {\n const statement = fromAlterTable(raw);\n const table = TABLE_RE.exec(statement);\n if (!table) continue;\n // With both groups present the first is the schema; with one, the\n // statement named a bare table and the schema is whatever search_path\n // resolves to — which we cannot know here, so it stays undefined and\n // `findGeneratedColumnConflicts` matches on the table name alone.\n const [schema, name] = table[2]\n ? [unquote(table[1]), unquote(table[2])]\n : [undefined, unquote(table[1])];\n\n const collect = (re: RegExp, kind: ColumnMutationKind) => {\n re.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = re.exec(statement)) !== null) {\n mutations.push({ schema, table: name, column: unquote(match[1]), kind });\n }\n };\n collect(ALTER_COLUMN_RE, \"type\");\n collect(DROP_COLUMN_RE, \"drop\");\n }\n\n return mutations;\n}\n\n/**\n * The generated columns that block a plan: those reading a column it retypes\n * or drops.\n *\n * A mutation with no schema matches on table name alone. That is deliberately\n * loose — a bare `ALTER TABLE posts` resolves through `search_path` at\n * execution time, and guessing wrong in the *permissive* direction costs a\n * generated column that is rebuilt seconds later, while guessing wrong in the\n * strict direction costs the whole push.\n */\nexport function findGeneratedColumnConflicts(\n mutations: ColumnMutation[],\n dependencies: GeneratedColumnDependency[]\n): GeneratedColumnConflict[] {\n const conflicts = new Map<string, GeneratedColumnConflict>();\n\n for (const dependency of dependencies) {\n for (const mutation of mutations) {\n if (mutation.table !== dependency.table) continue;\n if (mutation.schema !== undefined && mutation.schema !== dependency.schema) continue;\n if (mutation.column !== dependency.dependsOn) continue;\n\n const key = `${dependency.schema}.${dependency.table}.${dependency.column}`;\n const conflict = conflicts.get(key) ?? {\n schema: dependency.schema,\n table: dependency.table,\n column: dependency.column,\n blocking: []\n };\n if (!conflict.blocking.some(b => b.column === mutation.column && b.kind === mutation.kind)) {\n conflict.blocking.push({ column: mutation.column, kind: mutation.kind });\n }\n conflicts.set(key, conflict);\n }\n }\n\n const ordered = [...conflicts.values()];\n for (const conflict of ordered) conflict.blocking.sort((a, b) => a.column.localeCompare(b.column));\n return ordered.sort((a, b) => `${a.schema}.${a.table}.${a.column}`.localeCompare(`${b.schema}.${b.table}.${b.column}`));\n}\n\n/**\n * Split the conflicts into the ones Rebase can rebuild and the ones it cannot.\n *\n * `managed` is decided by the very list that hid the column from Atlas: a\n * `schema.table.column` exclude pattern means Rebase generated the column and\n * `search.sql` will put it back. Anything else is somebody's hand-written\n * generated column — dropping it would destroy a definition Rebase has no copy\n * of, so it is reported and the push stops instead.\n */\nexport function partitionByOwnership(\n conflicts: GeneratedColumnConflict[],\n excludePatterns: string[]\n): { managed: GeneratedColumnConflict[]; foreign: GeneratedColumnConflict[] } {\n const owned = new Set(excludePatterns);\n const managed: GeneratedColumnConflict[] = [];\n const foreign: GeneratedColumnConflict[] = [];\n for (const conflict of conflicts) {\n // Spelled the way the exclude was, so a name holding a `.` or glob\n // syntax is still recognised as ours.\n const target = atlasExcludePattern(conflict.schema, conflict.table, conflict.column);\n (owned.has(target) ? managed : foreign).push(conflict);\n }\n return { managed, foreign };\n}\n\n/**\n * `ALTER TABLE … DROP COLUMN …` for each conflict, in catalogue order.\n *\n * `ifExists` is for the migration path, where the statement is written now and\n * runs later against a database nobody can inspect: on a fresh one the column\n * does not exist yet (the migration is about to create the table), on a live\n * one it does, and the same file has to survive both.\n */\nexport function dropGeneratedColumnStatements(\n conflicts: GeneratedColumnConflict[],\n opts: { ifExists?: boolean } = {}\n): string[] {\n const guard = opts.ifExists ? \"IF EXISTS \" : \"\";\n return conflicts.map(c => `ALTER TABLE \"${c.schema}\".\"${c.table}\" DROP COLUMN ${guard}\"${c.column}\";`);\n}\n\n/**\n * The preamble a migration needs when it retypes a column a search block reads.\n *\n * Prepended, because the drop has to precede the `ALTER COLUMN … TYPE` that\n * PostgreSQL would otherwise refuse. The column comes back at the end of the\n * same migration: `db generate` appends `search.sql`, whose\n * `ADD COLUMN IF NOT EXISTS` rebuilds the column, its index and its stamp.\n */\nexport function migrationDropPreamble(conflicts: GeneratedColumnConflict[]): string {\n if (conflicts.length === 0) return \"\";\n const reasons = conflicts.map(c => {\n const reads = c.blocking.map(b => `${b.column} (${b.kind})`).join(\", \");\n return `-- ${describeConflict(c)} reads ${reads}`;\n });\n return [\n \"-- Rebase: generated columns removed so the statements below can run.\",\n \"-- PostgreSQL refuses to retype or drop a column while a GENERATED\",\n \"-- ALWAYS AS … STORED expression reads it.\",\n ...reasons,\n \"-- The search DDL appended at the end of this migration rebuilds them.\",\n ...dropGeneratedColumnStatements(conflicts, { ifExists: true }),\n \"\"\n ].join(\"\\n\");\n}\n\n/** `public.posts.search_vector`, the way every message here names one. */\nexport function describeConflict(conflict: GeneratedColumnConflict): string {\n return `${conflict.schema}.${conflict.table}.${conflict.column}`;\n}\n","/**\n * Keep the objects Rebase carved out of Atlas's view out of the migrations\n * Atlas writes.\n *\n * `db push` protects them with `--exclude`. `atlas migrate diff` has no such\n * flag — measured on the pinned 1.2.3, `--exclude` is rejected outright with\n * `unknown flag`, and the `exclude` attribute of an `atlas.hcl` `env` block is\n * accepted and then silently ignored on that path. So the diff sees the search\n * column that the migration directory's own appended DDL created when it\n * replayed, does not see it in `schema.sql`, and plans a drop:\n *\n * ALTER TABLE \"public\".\"talents\" DROP COLUMN \"search_vector\";\n *\n * That statement is removed here, after Atlas has written the file and before\n * anything is appended to it — so the input is always Atlas's own plain output,\n * never the dollar-quoted helper bodies that get appended afterwards.\n *\n * The drop does not arrive alone. Atlas folds every change to one table into a\n * single statement, so a real edit in the same run produces\n *\n * ALTER TABLE \"public\".\"talents\"\n * DROP COLUMN \"search_vector\", DROP COLUMN \"interests\", ADD COLUMN \"headline\" text NULL;\n *\n * and dropping the whole statement would silently throw away a migration the\n * project asked for. The removal is therefore per *clause*.\n *\n * Fail-safe throughout: a statement that mentions a carved-out object but does\n * not match a shape this understands is left exactly as it is and reported as\n * `unhandled`, so the caller can say so out loud. A spurious drop the developer\n * can see beats a migration quietly rewritten wrong.\n */\n\nimport { excludePatternParts } from \"./atlas-exclude\";\n\n/** Anything Postgres accepts in an unquoted identifier past ASCII. */\nconst IDENT = \"(?:\\\"(?:[^\\\"]|\\\"\\\")*\\\"|[A-Za-z_\\\\u0080-\\\\uffff][\\\\w$\\\\u0080-\\\\uffff]*)\";\nconst QUALIFIED = `${IDENT}(?:\\\\s*\\\\.\\\\s*${IDENT})*`;\n\nconst ALTER_TABLE_RE = new RegExp(`^ALTER\\\\s+TABLE\\\\s+(?:ONLY\\\\s+)?(${QUALIFIED})\\\\s+([\\\\s\\\\S]+)$`, \"i\");\nconst DROP_COLUMN_RE = new RegExp(`^DROP\\\\s+(?:COLUMN\\\\s+)?(?:IF\\\\s+EXISTS\\\\s+)?(${IDENT})$`, \"i\");\nconst DROP_INDEX_RE = new RegExp(`^DROP\\\\s+INDEX\\\\s+(?:CONCURRENTLY\\\\s+)?(?:IF\\\\s+EXISTS\\\\s+)?(${QUALIFIED})$`, \"i\");\n\n/**\n * Does this statement destroy anything at all?\n *\n * The gate on reporting. A statement that merely *names* a carved-out object —\n * `COMMENT ON COLUMN … \"search_vector\"` — is not a problem and must not be\n * reported as one, because an unrewritable drop stops the caller outright.\n */\nconst MENTIONS_DROP = /\\bDROP\\b/i;\n\n/** One `schema.table.object` exclude pattern, taken apart. */\nexport interface CarvedOutObject {\n schema: string;\n table: string;\n object: string;\n}\n\nexport interface StripResult {\n /** The migration text with the carved-out clauses gone. */\n sql: string;\n /** What was removed, as SQL fragments, for reporting. */\n removed: string[];\n /**\n * Statements naming a carved-out object that this could not rewrite with\n * confidence. Left untouched in `sql`.\n */\n unhandled: string[];\n /** True when nothing but comments and whitespace survives. */\n empty: boolean;\n}\n\n/**\n * Split `schema.table.object` patterns back into the names they were built\n * from (`excludePatternParts`, the inverse of how every exclude is spelled).\n * Anything not in three parts is ignored rather than guessed at — the two-part\n * form is the one Atlas itself silently mis-reads, and repeating that mistake\n * here would be worse than doing nothing.\n */\nexport function parseExcludePatterns(patterns: string[]): CarvedOutObject[] {\n const parsed: CarvedOutObject[] = [];\n for (const pattern of patterns) {\n const parts = excludePatternParts(pattern);\n if (parts === undefined || parts.length !== 3) continue;\n if (parts.some((p) => p.length === 0)) continue;\n parsed.push({ schema: parts[0], table: parts[1], object: parts[2] });\n }\n return parsed;\n}\n\n/** `\"public\"` and `public` are the same name; `\"Public\"` is not `public`. */\nfunction unquoteIdentifier(raw: string): string {\n const trimmed = raw.trim();\n if (trimmed.startsWith(\"\\\"\") && trimmed.endsWith(\"\\\"\") && trimmed.length >= 2) {\n return trimmed.slice(1, -1).replace(/\"\"/g, \"\\\"\");\n }\n // An unquoted identifier is folded to lower case by Postgres.\n return trimmed.toLowerCase();\n}\n\n/** Split a dotted identifier at its top-level dots, respecting quoting. */\nfunction splitQualifiedName(raw: string): string[] | null {\n const parts: string[] = [];\n let current = \"\";\n let inQuote = false;\n for (let i = 0; i < raw.length; i++) {\n const ch = raw[i];\n if (inQuote) {\n if (ch === \"\\\"\") {\n if (raw[i + 1] === \"\\\"\") { current += \"\\\"\\\"\"; i++; continue; }\n inQuote = false;\n }\n current += ch;\n continue;\n }\n if (ch === \"\\\"\") { inQuote = true; current += ch; continue; }\n if (ch === \".\") { parts.push(current); current = \"\"; continue; }\n current += ch;\n }\n if (inQuote) return null;\n parts.push(current);\n return parts.map(unquoteIdentifier);\n}\n\n/**\n * One statement located in the source text, with the comment lines that\n * introduce it. Atlas writes `-- Modify \"talents\" table` above each statement;\n * removing the statement without its comment leaves a caption over nothing.\n */\ninterface LocatedStatement {\n /** Offset of the first character of the leading comment block. */\n start: number;\n /** Offset just past the terminating semicolon. */\n end: number;\n /** Offset of the first character of the statement itself. */\n bodyStart: number;\n /** The statement without its leading comments or trailing semicolon. */\n body: string;\n}\n\n/**\n * Walk the script and locate every statement. Quote-, comment- and\n * dollar-aware: the appended halves of a migration are not passed here, but a\n * splitter that shreds a `DO $tag$ ... $tag$` block is a trap worth not\n * leaving behind — it is how the derived-names renderer broke.\n *\n * Returns null if the text ends inside a quote or a dollar-quoted body, or\n * trails off in a statement with no semicolon. Either means this cannot be\n * reasoned about safely.\n */\nfunction locateStatements(sql: string): LocatedStatement[] | null {\n const statements: LocatedStatement[] = [];\n let i = 0;\n let statementStart = 0;\n let sawCode = false;\n\n const pushStatement = (endExclusive: number) => {\n const leading = sql.slice(statementStart, endExclusive);\n // The leading run of comment/blank lines belongs to this statement.\n let consumed = 0;\n for (const line of leading.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"\" || trimmed.startsWith(\"--\")) {\n consumed += line.length + 1;\n continue;\n }\n break;\n }\n const bodyStart = statementStart + consumed;\n statements.push({\n start: statementStart,\n end: endExclusive,\n bodyStart,\n body: sql.slice(bodyStart, endExclusive).replace(/;\\s*$/, \"\").trim()\n });\n };\n\n while (i < sql.length) {\n const ch = sql[i];\n\n if (ch === \"-\" && sql[i + 1] === \"-\") {\n const nl = sql.indexOf(\"\\n\", i);\n i = nl === -1 ? sql.length : nl + 1;\n continue;\n }\n if (ch === \"/\" && sql[i + 1] === \"*\") {\n const close = sql.indexOf(\"*/\", i + 2);\n if (close === -1) return null;\n i = close + 2;\n sawCode = true;\n continue;\n }\n if (ch === \"'\" || ch === \"\\\"\") {\n const quote = ch;\n i++;\n let closed = false;\n while (i < sql.length) {\n if (sql[i] === quote) {\n if (sql[i + 1] === quote) { i += 2; continue; }\n i++;\n closed = true;\n break;\n }\n i++;\n }\n if (!closed) return null;\n sawCode = true;\n continue;\n }\n if (ch === \"$\") {\n const tag = /^\\$(?:[A-Za-z_\\u0080-\\uffff][\\w\\u0080-\\uffff]*)?\\$/.exec(sql.slice(i));\n if (tag) {\n const close = sql.indexOf(tag[0], i + tag[0].length);\n if (close === -1) return null;\n i = close + tag[0].length;\n sawCode = true;\n continue;\n }\n }\n if (ch === \";\") {\n pushStatement(i + 1);\n i++;\n statementStart = i;\n sawCode = false;\n continue;\n }\n if (!/\\s/.test(ch)) sawCode = true;\n i++;\n }\n\n // Trailing text with no semicolon: only comments and whitespace is fine.\n if (sawCode) return null;\n return statements;\n}\n\n/** Split an ALTER TABLE action list at its top-level commas. */\nfunction splitClauses(actions: string): string[] | null {\n const clauses: string[] = [];\n let depth = 0;\n let current = \"\";\n let i = 0;\n while (i < actions.length) {\n const ch = actions[i];\n if (ch === \"'\" || ch === \"\\\"\") {\n const quote = ch;\n current += ch;\n i++;\n let closed = false;\n while (i < actions.length) {\n current += actions[i];\n if (actions[i] === quote) {\n if (actions[i + 1] === quote) { current += actions[i + 1]; i += 2; continue; }\n i++;\n closed = true;\n break;\n }\n i++;\n }\n if (!closed) return null;\n continue;\n }\n if (ch === \"(\") { depth++; current += ch; i++; continue; }\n if (ch === \")\") { depth--; current += ch; i++; continue; }\n if (ch === \",\" && depth === 0) { clauses.push(current); current = \"\"; i++; continue; }\n current += ch;\n i++;\n }\n if (depth !== 0) return null;\n clauses.push(current);\n return clauses.map((c) => c.trim()).filter((c) => c.length > 0);\n}\n\n/**\n * Remove every clause and statement that would drop one of `patterns`.\n *\n * `patterns` are the `schema.table.object` strings the CLI already builds for\n * Atlas's `--exclude`, so the diff path and the apply path protect exactly the\n * same set by construction.\n */\nexport function stripCarvedOutStatements(migrationSql: string, patterns: string[]): StripResult {\n const carved = parseExcludePatterns(patterns);\n if (carved.length === 0) {\n return { sql: migrationSql, removed: [], unhandled: [], empty: isBlank(migrationSql) };\n }\n\n const located = locateStatements(migrationSql);\n if (located === null) {\n // Nothing can be trusted about the offsets, so nothing moves. Worth\n // stopping the caller over only if one of ours is being dropped in\n // there; otherwise this file has nothing to do with us.\n const atStake = MENTIONS_DROP.test(migrationSql)\n && carved.some((c) => migrationSql.includes(c.object));\n return {\n sql: migrationSql,\n removed: [],\n unhandled: atStake ? [migrationSql.trim()] : [],\n empty: isBlank(migrationSql)\n };\n }\n\n const removed: string[] = [];\n const unhandled: string[] = [];\n // Edits as [start, end) → replacement, applied back-to-front so the\n // offsets of the ones still pending stay valid.\n const edits: { start: number; end: number; replacement: string }[] = [];\n\n for (const statement of located) {\n if (!carved.some((c) => statement.body.includes(c.object))) continue;\n\n const dropIndex = DROP_INDEX_RE.exec(statement.body);\n if (dropIndex) {\n const parts = splitQualifiedName(dropIndex[1]);\n const name = parts?.[parts.length - 1];\n const schema = parts && parts.length > 1 ? parts[parts.length - 2] : undefined;\n if (name !== undefined && carved.some((c) =>\n c.object === name && (schema === undefined || c.schema === schema))) {\n removed.push(statement.body);\n edits.push({ start: statement.start, end: statement.end, replacement: \"\" });\n } else {\n // A near-miss on the name — some other index whose name\n // contains ours. Left alone, and still a drop, so still\n // reported.\n unhandled.push(statement.body);\n }\n continue;\n }\n\n // Anything else naming a carved-out object is only our business if it\n // destroys something. `COMMENT ON COLUMN … \"search_vector\"` does not.\n const alter = ALTER_TABLE_RE.exec(statement.body);\n if (!alter) {\n if (MENTIONS_DROP.test(statement.body)) unhandled.push(statement.body);\n continue;\n }\n\n const target = splitQualifiedName(alter[1]);\n if (!target) {\n if (MENTIONS_DROP.test(statement.body)) unhandled.push(statement.body);\n continue;\n }\n const table = target[target.length - 1];\n const schema = target.length > 1 ? target[target.length - 2] : undefined;\n\n const clauses = splitClauses(alter[2]);\n if (!clauses) {\n if (MENTIONS_DROP.test(statement.body)) unhandled.push(statement.body);\n continue;\n }\n\n const survivors: string[] = [];\n let removedHere = 0;\n let unhandledHere = false;\n for (const clause of clauses) {\n const drop = DROP_COLUMN_RE.exec(clause);\n const column = drop ? unquoteIdentifier(drop[1]) : undefined;\n const isCarved = column !== undefined && carved.some((c) =>\n c.object === column &&\n c.table === table &&\n (schema === undefined || c.schema === schema));\n if (isCarved) {\n removed.push(`ALTER TABLE ${alter[1]}: ${clause}`);\n removedHere++;\n continue;\n }\n // A clause naming a carved-out object in some other shape is not\n // something to guess at — if it destroys it.\n if (MENTIONS_DROP.test(clause) && carved.some((c) => clause.includes(c.object))) {\n unhandledHere = true;\n }\n survivors.push(clause);\n }\n\n if (unhandledHere) unhandled.push(statement.body);\n if (removedHere === 0) continue;\n\n if (survivors.length === 0) {\n edits.push({ start: statement.start, end: statement.end, replacement: \"\" });\n } else {\n edits.push({\n start: statement.bodyStart,\n end: statement.end,\n replacement: `ALTER TABLE ${alter[1]} ${survivors.join(\", \")};`\n });\n }\n }\n\n let sql = migrationSql;\n for (const edit of edits.sort((a, b) => b.start - a.start)) {\n sql = sql.slice(0, edit.start) + edit.replacement + sql.slice(edit.end);\n }\n if (edits.length > 0) sql = tidy(sql);\n\n return { sql, removed, unhandled, empty: isBlank(sql) };\n}\n\n/** Only comments and whitespace left — nothing a migration would do. */\nfunction isBlank(sql: string): boolean {\n return sql\n .split(\"\\n\")\n .every((line) => line.trim() === \"\" || line.trim().startsWith(\"--\"));\n}\n\n/** Collapse the blank runs an excision leaves behind. */\nfunction tidy(sql: string): string {\n const trimmed = sql.replace(/\\n{3,}/g, \"\\n\\n\").replace(/^\\s*\\n/, \"\").trimEnd();\n return trimmed.length === 0 ? \"\" : `${trimmed}\\n`;\n}\n","import fs from \"fs\";\n\n/**\n * What became of a migration `db generate` was finishing.\n *\n * `removed` says whether the half-finished file is gone; `rehashError` is set\n * when it is gone but `atlas.sum` could not be brought back in line with the\n * directory, which `atlas migrate` then refuses with a checksum error — loud,\n * which is the point.\n */\nexport type MigrationPostProcessOutcome =\n | { ok: true }\n | { ok: false; error: string; removed: boolean; rehashError?: string };\n\n/**\n * Run the steps that finish a migration Atlas just wrote — the search, vector\n * and trigger DDL, the RLS bootstrap and policies, the re-hash — and take the\n * migration back out when any of them fails.\n *\n * Atlas's own file creates the tables and nothing else: no `ENABLE ROW LEVEL\n * SECURITY`, no policy. Those arrive in the append. A failure here used to be a\n * yellow warning followed by \"You can now run rebase db migrate\", and when it\n * struck before the file was rewritten the checksum still matched — so the\n * migration applied cleanly and created every new table with RLS off while\n * the schema's default privileges handed `rebase_user` full DML on it. On a\n * deployment that runs migrations and never provisions at boot\n * (`REBASE_MIGRATE_ON_BOOT=none`), nothing closed it again.\n *\n * Deleting the file is safe because it is the one this run created: running\n * `db generate` again, once the cause is fixed, writes the same diff.\n */\nexport async function finishNewMigration(\n file: string,\n steps: () => Promise<void>,\n rehash: () => Promise<void>\n): Promise<MigrationPostProcessOutcome> {\n try {\n await steps();\n return { ok: true };\n } catch (err) {\n const error = err instanceof Error ? err.message : String(err);\n let removed = false;\n try {\n if (fs.existsSync(file)) fs.unlinkSync(file);\n removed = !fs.existsSync(file);\n } catch {\n removed = false;\n }\n if (!removed) return { ok: false, error, removed };\n try {\n await rehash();\n return { ok: false, error, removed };\n } catch (hashErr) {\n return { ok: false, error, removed, rehashError: hashErr instanceof Error ? hashErr.message : String(hashErr) };\n }\n }\n}\n","/**\n * The argv `runAtlas` hands the Atlas binary, as a pure function.\n *\n * Split out of `cli.ts` because the flags an Atlas subcommand accepts are not\n * uniform and getting one wrong is fatal rather than degraded: Atlas rejects an\n * unknown flag before doing any work, so a flag on the wrong subcommand takes\n * the whole command down.\n *\n * `--exclude` is the one that bit. Of the six invocations here, exactly one\n * accepts it. The guard this replaces was `args.includes(\"apply\") ||\n * args.includes(\"diff\")`, and reading it as a *subcommand* test is the trap:\n * `migrate apply` passes `args.includes(\"apply\")` just as `schema apply` does.\n * So the flag went onto three invocations, two of which reject it, and both\n * `rebase db generate` and `rebase db migrate` exited 1 with `unknown flag:\n * --exclude` for every project declaring a `search` block.\n *\n * The domain is half the identity of an Atlas subcommand, and a guard that\n * looks only at `args` cannot tell `schema apply` from `migrate apply`.\n *\n * Nothing here touches a database or the filesystem, so the whole matrix is\n * unit-tested in `atlas-argv.test.ts`.\n */\n\nexport interface AtlasInvocation {\n /** `schema` or `migrate`. */\n domain: string;\n /** The subcommand and its own flags, e.g. `[\"diff\", \"--dir\", \"file://…\"]`. */\n args: string[];\n /** The target database, already rewritten for libpq. */\n url: string;\n /** The database Atlas plans against, already rewritten for libpq. */\n devUrl: string;\n /**\n * Everything the caller resolved for `--exclude`, in the order it should\n * appear. Dropped entirely when the subcommand does not accept the flag —\n * see {@link acceptsExcludeFlag}.\n */\n excludes?: string[];\n /**\n * The target is one database session that every connection shares — the\n * managed development database (PGlite). See {@link buildAtlasArgs} for\n * what that changes.\n */\n singleSession?: boolean;\n}\n\n/**\n * Does this Atlas invocation accept `--exclude`?\n *\n * Only `atlas schema apply` does, on the pinned 1.2.3. Measured against the\n * binary: `migrate diff` and `migrate apply` both answer `unknown flag:\n * --exclude`, and neither lists it in `--help` (`migrate apply` offers\n * `--url/--dir/--format/--revisions-schema/--dry-run/--lock-name/--lock-timeout/`\n * `--skip-lock/--baseline/--to-version/--tx-mode/--exec-order/--allow-dirty`).\n * Hence `domain === \"schema\"` and not just the subcommand.\n *\n * The `exclude` attribute of an `atlas.hcl` `env` block is not a way round it\n * either: measured, it is accepted and then ignored on the diff path, which is\n * the silent-no-match shape that costs the most time to notice.\n *\n * So the diff keeps the carved-out objects out of the migration afterwards\n * instead, with `stripCarvedOutStatements`.\n */\nexport function acceptsExcludeFlag(domain: string, args: string[]): boolean {\n return domain === \"schema\" && args.includes(\"apply\");\n}\n\n/**\n * Does this Atlas invocation plan against the scratch database (`--dev-url`)?\n *\n * `schema apply` and `migrate diff` do; `migrate apply`, `hash` and `status`\n * never read it, so `db migrate` has no reason to create one.\n */\nexport function takesDevUrl(domain: string, args: string[]): boolean {\n return (domain === \"schema\" && args.includes(\"apply\"))\n || (domain === \"migrate\" && args.includes(\"diff\"));\n}\n\n/**\n * Does this Atlas invocation read or write the revisions table\n * (`rebase.atlas_schema_revisions`)? `migrate apply`, `set` and `status` do;\n * they are the ones handed `--revisions-schema`.\n */\nexport function readsRevisions(domain: string, args: string[]): boolean {\n return domain === \"migrate\" && (args.includes(\"apply\") || args.includes(\"status\") || args.includes(\"set\"));\n}\n\n/**\n * Assemble the full argv, connection flags and all.\n *\n * On a single-session database `migrate apply` skips its advisory lock. The\n * lock is session-level, and a session every connection shares grants it to\n * all of them, so it excludes no one; what it does cost there is a connection.\n * The managed database accepts four and a running `rebase dev` holds two, so\n * `migrate apply`'s third — its own, the lock's, the revisions table's — was\n * closed unanswered and Atlas said only `Error: EOF`. `migrate set`, which has\n * no `--skip-lock`, is bound to the revisions schema instead, which spares it\n * the revisions table's connection.\n */\nexport function buildAtlasArgs(invocation: AtlasInvocation): string[] {\n const { domain, args, url, devUrl, excludes = [], singleSession = false } = invocation;\n const argv = [domain, ...args];\n\n if (domain === \"schema\") {\n if (args.includes(\"apply\")) {\n argv.push(\"--url\", url, \"--dev-url\", devUrl);\n } else if (args.includes(\"clean\") || args.includes(\"inspect\")) {\n argv.push(\"--url\", url);\n }\n } else if (domain === \"migrate\") {\n if (args.includes(\"diff\")) {\n argv.push(\"--dev-url\", devUrl);\n } else if (args.includes(\"set\") && singleSession) {\n // `migrate set` takes no `--skip-lock`, and with `--revisions-schema`\n // it opens a second client for that schema: three connections, of\n // which beside a running `rebase dev` the third was closed\n // unanswered (`EOF`). Bound to the schema the table is in, Atlas\n // reads and writes it on the connection it already has — two.\n argv.push(\"--url\", withSearchPath(url, \"rebase\"));\n } else if (readsRevisions(domain, args)) {\n argv.push(\"--url\", url, \"--revisions-schema\", \"rebase\");\n // Measured against the pinned binary: `sql/migrate: baseline and\n // allow-dirty are mutually exclusive`. `--baseline` is the caller's\n // explicit answer to the same question `--allow-dirty` answers by\n // default, so it wins, and adding both would refuse the command.\n if (args.includes(\"apply\") && !args.includes(\"--baseline\")) {\n argv.push(\"--allow-dirty\");\n }\n // Only `apply` takes it: `migrate set` and `status` take no lock.\n if (args.includes(\"apply\") && singleSession) {\n argv.push(\"--skip-lock\");\n }\n }\n }\n\n // Second line of defence, deliberately not a caller's responsibility: a\n // future caller that resolves excludes for the diff path gets them dropped\n // here rather than a command that will not run.\n if (acceptsExcludeFlag(domain, args)) {\n for (const exclude of excludes) {\n argv.push(\"--exclude\", exclude);\n }\n }\n\n return argv;\n}\n\n/**\n * The URL with its `search_path` set to `schema`: an Atlas URL bound to that\n * schema. Every other parameter is kept as written. A URL that does not\n * parse is returned unchanged.\n */\nfunction withSearchPath(url: string, schema: string): string {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return url;\n }\n const params = Array.from(parsed.searchParams.entries()).filter(([key]) => key !== \"search_path\");\n params.push([\"search_path\", schema]);\n // By hand, as `forLibpq` re-serializes: URLSearchParams writes a space as\n // `+`, which libpq does not read as one.\n parsed.search = params.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join(\"&\");\n return parsed.toString();\n}\n\n/**\n * `atlas migrate apply`'s own arguments for `rebase db migrate`.\n *\n * `positionals` are what is left of the user's line once every flag the\n * driver knows has been consumed — at most the optional amount Atlas takes. A\n * flag reaching here is a flag Atlas rejects before doing any work.\n */\nexport function migrateApplyArgs(positionals: string[], baseline: string | undefined): string[] {\n return [\n \"apply\",\n \"--dir\", \"file://drizzle/migrations\",\n ...(baseline ? [\"--baseline\", baseline] : []),\n ...positionals.filter(positional => positional !== \"migrate\")\n ];\n}\n","/**\n * Atlas's revisions table on the managed development database, made by Rebase.\n *\n * `rebase db migrate` passes `--revisions-schema rebase`, so Atlas keeps its\n * history in `rebase.atlas_schema_revisions`. Atlas finds that table by\n * qualified name, but creates it through a second connection whose startup\n * message sets `search_path=rebase`, with an unqualified `CREATE TABLE`. The\n * managed database is one PGlite session that every connection shares, so a\n * connection's own `search_path` is never applied: the table landed in\n * `public`, the read that followed failed on `relation\n * \"rebase.atlas_schema_revisions\" does not exist (42P01)`, and every later run\n * failed on `relation \"atlas_schema_revisions\" already exists (42P07)`, with or\n * without `--baseline`.\n *\n * So on that database the table is created here first, qualified, and Atlas\n * finds it where it looks. The definition is Atlas's own for the pinned\n * `@ariga/atlas`, read off a table Atlas created on PostgreSQL 18. Should a\n * later Atlas want a different one, it alters the table through the same\n * unqualified path and fails loudly there, and the managed `db migrate`\n * integration test fails with it.\n *\n * Not used on any other database: there the connection's `search_path` holds,\n * and Atlas creates and maintains its table itself.\n */\nimport { withAppClient } from \"../cli-helpers\";\n\n/** Atlas's revisions table, in the schema `--revisions-schema rebase` names. */\nexport const ATLAS_REVISIONS_TABLE_SQL = `CREATE SCHEMA IF NOT EXISTS \"rebase\";\nCREATE TABLE IF NOT EXISTS \"rebase\".\"atlas_schema_revisions\" (\n \"version\" character varying NOT NULL,\n \"description\" character varying NOT NULL,\n \"type\" bigint NOT NULL DEFAULT 2,\n \"applied\" bigint NOT NULL DEFAULT 0,\n \"total\" bigint NOT NULL DEFAULT 0,\n \"executed_at\" timestamp with time zone NOT NULL,\n \"execution_time\" bigint NOT NULL,\n \"error\" text NULL,\n \"error_stmt\" text NULL,\n \"hash\" character varying NOT NULL,\n \"partial_hashes\" jsonb NULL,\n \"operator_version\" character varying NOT NULL,\n PRIMARY KEY (\"version\")\n);`;\n\n/** Create `rebase.atlas_schema_revisions` if it is not there yet. */\nexport async function ensureAtlasRevisionsTable(databaseUrl: string): Promise<void> {\n await withAppClient(databaseUrl, client => client.query(ATLAS_REVISIONS_TABLE_SQL));\n}\n","/**\n * Atlas's `schema apply --auto-approve` report, as `rebase db push` shows it.\n *\n * Atlas prints its plan (\"Planning migration statements …\"), a separator, and\n * then the run (\"Applying approved migration …\"), echoing every statement in\n * both. The push has planned already — the plan it gated on, which a\n * destructive change listed in full — so the first section is a repeat, and a\n * reader saw each statement twice in a row. The run's section is kept: it is\n * the progress, the `-- ok` per statement and the summary.\n */\n\nconst PLANNING_HEADER = /^Planning migration statements\\b/;\n/** The separator Atlas ends a section with, at the start of a line. */\nconst SECTION_SEPARATOR = /^-{3,}\\s*$/;\n\nexport interface ApplyReportFilter {\n /** The part of `chunk` to show, whole lines only; a partial line waits for the next chunk. */\n push(chunk: string): string;\n /** What is left once the stream has ended. */\n flush(): string;\n}\n\n/**\n * A stream filter that drops the planning section of an apply report, its\n * separator and the blank line after it, and passes everything else through\n * unchanged. A report with no planning section (`Schema is synced…`, an\n * error) comes out as it went in.\n */\nexport function createApplyReportFilter(): ApplyReportFilter {\n let pending = \"\";\n let state: \"pass\" | \"planning\" | \"after-separator\" = \"pass\";\n\n const keep = (line: string): boolean => {\n if (state === \"pass\" && PLANNING_HEADER.test(line)) {\n state = \"planning\";\n return false;\n }\n if (state === \"planning\") {\n if (SECTION_SEPARATOR.test(line)) state = \"after-separator\";\n return false;\n }\n if (state === \"after-separator\") {\n state = \"pass\";\n if (line.trim() === \"\") return false;\n }\n return true;\n };\n\n return {\n push(chunk) {\n pending += chunk;\n const lines = pending.split(\"\\n\");\n pending = lines.pop() ?? \"\";\n return lines.filter(keep).map((line) => `${line}\\n`).join(\"\");\n },\n flush() {\n const rest = pending;\n pending = \"\";\n return rest !== \"\" && keep(rest) ? rest : \"\";\n }\n };\n}\n","/**\n * The scratch database Atlas plans against, for the length of one db command.\n *\n * `atlas schema apply` and `atlas migrate diff` need a `--dev-url`: an empty\n * database they build the desired state in, made as `<db>_dev_diff` beside the\n * real one. It is a full copy of the schema, so it is removed again once the\n * command that made it has succeeded — every such command, not only an applied\n * `db push`: a `--dry-run` that left one behind while saying nothing was\n * applied, and `db generate`, left one per target on the server.\n *\n * It is dropped on every way out of the command: success, a destructive push\n * the user declined or that had no terminal to ask, and a crash. A crash that\n * kept it left it for good, because the next push finds it already there and\n * takes it for one made by hand.\n *\n * Two cases keep it. An Atlas run that failed while planning against it leaves\n * the state Atlas was planning, which is the one thing worth inspecting. And\n * one this process did not create (made by hand, the remedy for a role without\n * `CREATEDB`) is the user's, and dropping it would put them back at the same\n * refusal next time. An Atlas run that failed before planning (see\n * {@link atlasFailedBeforePlanning}) left nothing in it, and it is dropped.\n */\nexport interface ScratchDatabaseOps {\n /** Create it if it is missing; `true` only when this call created it. */\n create(databaseUrl: string, devDatabaseUrl: string): Promise<boolean>;\n drop(databaseUrl: string, devDatabaseUrl: string): Promise<void>;\n}\n\nexport class ScratchDatabase {\n private created: { databaseUrl: string; devDatabaseUrl: string } | undefined;\n private keptAsEvidence = false;\n\n constructor(private readonly ops: ScratchDatabaseOps) {}\n\n /** Make sure it exists before an Atlas call that plans against it. */\n async ensure(databaseUrl: string, devDatabaseUrl: string): Promise<void> {\n if (await this.ops.create(databaseUrl, devDatabaseUrl)) {\n this.created = { databaseUrl, devDatabaseUrl };\n }\n }\n\n /** An Atlas run against it failed: keep it, whatever the command does next. */\n keepAsEvidence(): void {\n this.keptAsEvidence = true;\n }\n\n /**\n * An Atlas run failed with `stderr`. Failing before it planned, it left\n * nothing here to read, so the database is dropped now — before the\n * command exits, which may not unwind through {@link around}. Otherwise\n * it is kept as the evidence.\n */\n async afterAtlasFailure(stderr: string): Promise<void> {\n if (atlasFailedBeforePlanning(stderr)) await this.release();\n else this.keepAsEvidence();\n }\n\n /**\n * Run a command, then drop the scratch database if the command created it,\n * whether the command returned or threw. A throw after\n * {@link keepAsEvidence} keeps it. A command that wants to stop with exit 1\n * throws {@link CommandStopped} rather than calling `process.exit`, which\n * would skip this.\n */\n async around<T>(command: () => Promise<T>): Promise<T> {\n let result: T;\n try {\n result = await command();\n } catch (err) {\n if (!this.keptAsEvidence) await this.release();\n throw err;\n }\n await this.release();\n return result;\n }\n\n /** Drop it now if this process created it. Safe to call twice. */\n async release(): Promise<void> {\n const created = this.created;\n if (!created) return;\n this.created = undefined;\n await this.ops.drop(created.databaseUrl, created.devDatabaseUrl);\n }\n}\n\n/**\n * Whether Atlas failed before it planned anything: on connecting, which it\n * reports as `querying system variables: …` — SSL the server does not offer, a\n * login refused, a socket that closed or never opened.\n */\nexport function atlasFailedBeforePlanning(stderr: string): boolean {\n return /querying system variables:/.test(stderr);\n}\n\n/**\n * A db command stopping with exit 1 after it has said why: a destructive push\n * the user declined, or one with no terminal to ask on.\n *\n * Thrown instead of `process.exit(1)`, so it unwinds through\n * {@link ScratchDatabase.around} and the scratch database is dropped on the way\n * out. `alreadyReported` tells `reportCommandFailure` the explanation is on the\n * terminal already; the entry point sets the exit code.\n */\nexport class CommandStopped extends Error {\n readonly alreadyReported = true;\n\n constructor(reason: string) {\n super(reason);\n this.name = \"CommandStopped\";\n }\n}\n","/**\n * What `rebase db migrate --baseline <version>` does, given the history the\n * database already has.\n *\n * The flag promises to record `<version>` as applied and migrate from the next\n * one. Atlas's own `migrate apply --baseline` keeps that promise only on a\n * database with no revision history: once one row exists it ignores the flag\n * without a word, applies the migration anyway, and the CLI had already printed\n * \"Recording … as already applied\". That is the normal second time: a project\n * baselines once, then `rebase dev` adds a column at boot, `db generate` writes\n * the migration for it, and `db migrate` fails on `column … already exists\n * (42701)` however the baseline is spelled.\n *\n * So the history is read first. With none, Atlas's baseline does the work.\n * Behind `<version>`, `atlas migrate set` marks every migration up to it as\n * applied, which is what a baseline means. At or past it, there is nothing to\n * record, and the command says so instead of claiming it recorded something.\n */\nimport { withAppClient } from \"../cli-helpers\";\n\nexport type BaselinePlan =\n /** No history: `migrate apply --baseline <version>`, Atlas's own mechanism. */\n | { kind: \"atlas-baseline\" }\n /** History behind `<version>`: `migrate set <version>`, then a plain apply. */\n | { kind: \"set\"; latest: string }\n /** History at or past `<version>`: nothing to record, a plain apply. */\n | { kind: \"already-recorded\"; latest: string };\n\n/**\n * Atlas's version order for the versions Rebase writes: numeric timestamps,\n * compared as numbers so a shorter one is not read as later; anything else as\n * text.\n */\nexport function compareMigrationVersions(a: string, b: string): number {\n if (/^\\d+$/.test(a) && /^\\d+$/.test(b)) {\n const x = BigInt(a);\n const y = BigInt(b);\n return x === y ? 0 : x < y ? -1 : 1;\n }\n return a.localeCompare(b);\n}\n\n/**\n * The version Atlas records for a migration file: its numeric prefix\n * (`20260906101530_init.sql` → `20260906101530`), or the name without `.sql`.\n */\nexport function migrationVersionOf(file: string): string {\n return /^(\\d+)/.exec(file)?.[1] ?? file.replace(/\\.sql$/, \"\");\n}\n\n/** How many versions a refused baseline names, newest last. */\nconst VERSIONS_NAMED = 5;\n\n/**\n * Why `--baseline <version>` cannot run, or `null` when it names a migration\n * file in `drizzle/migrations`.\n *\n * Asked before anything else, the database included. A version no file has\n * was refused only by Atlas, after the command had said \"Marking every\n * migration up to abc as applied…\"; and one older than every file read\n * \"Nothing to record\" and migrated on, though it named nothing to baseline.\n *\n * @param files the migration files, sorted oldest first.\n * @returns the refusal, its first line the error and the rest the detail.\n */\nexport function baselineVersionProblem(version: string, files: readonly string[]): string | null {\n const versions = files.map(migrationVersionOf);\n if (versions.length === 0) {\n return `--baseline ${version}: There are no migrations in drizzle/migrations to baseline. Nothing was run.\\n` +\n \"Run `rebase db generate` to write the first one.\";\n }\n if (versions.includes(version)) return null;\n const named = versions.slice(-VERSIONS_NAMED).join(\", \");\n const which = versions.length > VERSIONS_NAMED\n ? `The newest ${VERSIONS_NAMED} of the ${versions.length} versions there`\n : \"The versions there\";\n return `--baseline ${version} names no migration in drizzle/migrations. Nothing was run.\\n` +\n `${which}: ${named}. A baseline is one of them: the newest migration the database already holds.`;\n}\n\n/** How to keep `--baseline <version>`'s promise, given the newest recorded version. */\nexport function planBaseline(version: string, latestRecorded: string | null): BaselinePlan {\n if (latestRecorded === null) return { kind: \"atlas-baseline\" };\n if (compareMigrationVersions(version, latestRecorded) > 0) return { kind: \"set\", latest: latestRecorded };\n return { kind: \"already-recorded\", latest: latestRecorded };\n}\n\n/** What the command says before it migrates, for each plan. */\nexport function describeBaselinePlan(version: string, plan: BaselinePlan): string {\n switch (plan.kind) {\n case \"atlas-baseline\":\n return `Recording ${version} as already applied, then migrating from the next one.`;\n case \"set\":\n return `This database already records migrations up to ${plan.latest}, and Atlas applies --baseline only ` +\n `to a database with none.\\n Marking every migration up to ${version} as applied with \\`atlas migrate set\\`, ` +\n \"then migrating from the next one.\";\n case \"already-recorded\":\n return `Nothing to record: this database already records migrations up to ${plan.latest}, which ` +\n `includes ${version}.\\n Migrating from the next one.`;\n }\n}\n\n/**\n * The newest version Atlas has recorded on this database, or `null` when it\n * has recorded none (no revisions table yet included).\n *\n * The table is `rebase.atlas_schema_revisions`: the CLI passes\n * `--revisions-schema rebase` to every `migrate apply`.\n */\nexport async function latestRecordedMigration(databaseUrl: string): Promise<string | null> {\n return withAppClient(databaseUrl, async (client) => {\n const exists = await client.query<{ present: boolean }>(\n \"SELECT to_regclass('rebase.atlas_schema_revisions') IS NOT NULL AS present\"\n );\n if (!exists.rows[0]?.present) return null;\n const rows = await client.query<{ version: string }>(\n \"SELECT version FROM rebase.atlas_schema_revisions WHERE version NOT LIKE '.%'\"\n );\n const versions = rows.rows.map(row => row.version);\n if (versions.length === 0) return null;\n return versions.reduce((latest, version) => (compareMigrationVersions(version, latest) > 0 ? version : latest));\n });\n}\n","import { isSyncedPlan } from \"./schema/destructive-sql\";\n\n/**\n * The steps `rebase db push` takes once the dry-run has been read and gated.\n *\n * Callbacks rather than calls, so the order is testable without a database or\n * an Atlas binary: `cli.ts` itself cannot be loaded by the jest suite.\n */\nexport interface PushApplySteps {\n /** Drop the generated columns that read a column the plan retypes. */\n dropRebuildable: () => Promise<void>;\n /** `atlas schema apply --auto-approve`: Atlas plans again, then applies. */\n atlasApply: () => Promise<void>;\n /** Say what the skipped apply would have printed. */\n reportSynced: () => void;\n /** Put those generated columns back after a failed apply. */\n rebuildAfterFailure: () => Promise<void>;\n /**\n * Everything Atlas cannot see: RLS locks, auth tables, vector, search,\n * triggers, policies, the user role. Runs whether or not Atlas had work.\n */\n afterApply: () => Promise<void>;\n}\n\n/**\n * Apply a planned push.\n *\n * A dry-run that answered \"Schema is synced\" skips the second Atlas run: that\n * run would plan the same diff again (≈0.9 s at 111 tables, 5.5 s at 411 —\n * Atlas's cost grows faster than the table count) and then apply nothing. The\n * steps after it still run, because Atlas cannot see what they own. A plan with\n * anything in it keeps the old flow, including Atlas re-planning at apply time.\n *\n * @returns `\"synced\"` when Atlas was not run again, `\"applied\"` otherwise.\n */\nexport async function applyPushPlan(\n plan: { dryRun: string; rebuildable: number },\n steps: PushApplySteps\n): Promise<\"applied\" | \"synced\"> {\n const synced = isSyncedPlan(plan.dryRun) && plan.rebuildable === 0;\n if (synced) {\n steps.reportSynced();\n } else {\n if (plan.rebuildable > 0) await steps.dropRebuildable();\n try {\n await steps.atlasApply();\n } catch (err) {\n // Atlas rolled its transaction back, so the columns those\n // expressions read are as they were and the definitions in\n // search.sql still fit. Put them back before surfacing the failure:\n // a push that fails must not also leave search broken.\n if (plan.rebuildable > 0) await steps.rebuildAfterFailure();\n throw err;\n }\n }\n await steps.afterApply();\n return synced ? \"synced\" : \"applied\";\n}\n\n/** The one call {@link applyPoliciesFile} needs from a connection. */\nexport interface PolicyConnection {\n query(text: string): Promise<unknown>;\n}\n\n/** What {@link applyPoliciesFile} stamps, and how to read the definitions back. */\nexport interface PolicyStamping {\n /**\n * `policyStampSql` of every table whose policies `policies.sql` creates\n * exactly as the boot would — see {@link stampableTables}.\n */\n statements: string[];\n /**\n * The `search_path` a boot reads policies under, when the connection's own\n * differs. A stamp hashes `pg_get_expr`, which spells a function on the\n * path unqualified: read under `\"$user\", public` with a `rebase` role, the\n * boot's `rebase.uid()` prints as `uid()` and no stamp would ever match.\n */\n searchPath?: string;\n}\n\n/**\n * The tables whose stamp `db push` may write: those every one of whose planned\n * statements `policies.sql` carries, verbatim.\n *\n * A stamp says \"this stored definition is what the plan's statement made\". It\n * is only true of a policy the statement *did* make — and since both are\n * rendered by the same function from the same collections, a table whose\n * statements are all in the file is one whose policies the file just created.\n * Anything else (a hand-edited file, a file generated elsewhere) is not\n * stamped, and the next boot re-applies that table, as before.\n */\nexport function stampableTables<T extends { policyStatements: string[] }>(plans: readonly T[], policiesSql: string): T[] {\n return plans.filter(plan => plan.policyStatements.length > 0\n && plan.policyStatements.every(statement => policiesSql.includes(statement)));\n}\n\n/**\n * Run `policies.sql`, then stamp the policies it created the way a boot does,\n * in the same transaction.\n *\n * Before stamps the push's policies carried none, so the first boot after\n * every push re-applied them all — a DROP and a CREATE per policy, an ACCESS\n * EXCLUSIVE lock per table. Stamped here, that boot finds them current.\n *\n * The file runs in one transaction, as it did as one implicit one: a policy\n * that fails leaves the previous ones in place. The stamps run after it, under\n * a savepoint: a stamp that cannot be written costs the next boot a re-apply,\n * which is what it did before, so it is reported and the policies are kept.\n * Nothing is left set on the connection: `SET LOCAL` ends with the transaction.\n */\nexport async function applyPoliciesFile(\n client: PolicyConnection,\n policiesSql: string,\n stamping: PolicyStamping\n): Promise<{ stamped: number; stampError?: string }> {\n await client.query(\"BEGIN\");\n let stamped = 0;\n let stampError: string | undefined;\n try {\n await client.query(policiesSql);\n if (stamping.statements.length > 0) {\n await client.query(\"SAVEPOINT rebase_policy_stamps\");\n try {\n if (stamping.searchPath) {\n await client.query(`SET LOCAL search_path TO ${stamping.searchPath}`);\n }\n await client.query(stamping.statements.join(\"\\n\"));\n await client.query(\"RELEASE SAVEPOINT rebase_policy_stamps\");\n stamped = stamping.statements.length;\n } catch (err) {\n await client.query(\"ROLLBACK TO SAVEPOINT rebase_policy_stamps\");\n stampError = err instanceof Error ? err.message : String(err);\n }\n }\n await client.query(\"COMMIT\");\n } catch (err) {\n await client.query(\"ROLLBACK\").catch(() => undefined);\n throw err;\n }\n return { stamped, stampError };\n}\n","/**\n * `--collections <dir>`, checked once, before anything is written.\n *\n * A path that does not resolve used to warn and carry on. Four times over —\n * `schemaCommand`, `generatePostgresDdlCommand` and the Atlas argv assembly\n * each re-enter the loader with the same line — and then both generators wrote\n * an *empty* schema: `drizzle/schema.sql` truncated to `CREATE SCHEMA IF NOT\n * EXISTS \"rebase\";`, `src/schema.generated.ts` to ten lines. Both were committed\n * artifacts then. The push that followed planned a `DROP TABLE` for every table in\n * the database, and the only thing between a typo and that was the destructive\n * gate.\n *\n * The check has to be here rather than inside `loadCollectionsForCli`, which is\n * deliberately forgiving: its callers use it to narrow what Atlas may touch,\n * and making a broken *file* fatal there would block a push over something\n * unrelated. \"Does the directory the user named exist\" is a different question,\n * it was answerable before the first write, and the code already knew.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { outError } from \"./cli-output\";\n\n/**\n * Thrown rather than exited, so the tests can see it and the entry point owns\n * the exit code.\n *\n * `alreadyReported` is read by `reportCommandFailure`: the full diagnosis is on\n * stderr by the time this is thrown, and the point of the whole change is that\n * it is printed once.\n */\nexport class CollectionsPathMissing extends Error {\n readonly alreadyReported = true;\n\n constructor(readonly typed: string, readonly resolved: string) {\n super(`Collections path not found: \"${typed}\"`);\n this.name = \"CollectionsPathMissing\";\n }\n}\n\n/**\n * The whole message, in one place, because it is printed by two callers.\n *\n * Names what was typed, what it resolved to, and the working directory it\n * resolved against — a relative `--collections` is resolved against the cwd,\n * and the generated npm script runs with `cwd: backend/`, so \"the path is\n * right and the directory is wrong\" is the commonest way to arrive here.\n */\nexport function describeMissingCollectionsPath(typed: string, resolved: string): string {\n return [\n chalk.red(`✗ Collections path not found: \"${typed}\"`),\n chalk.gray(` Resolved to: ${resolved}`),\n chalk.gray(` (relative to cwd: ${process.cwd()})`),\n \"\",\n chalk.gray(\" Nothing was generated and nothing was applied — a schema generated from a\"),\n chalk.gray(\" directory that is not there is an empty one, and applying it would drop\"),\n chalk.gray(\" every table it does not describe.\"),\n \"\",\n chalk.gray(\" Pass an absolute path, or one relative to where you run the command.\")\n ].join(\"\\n\");\n}\n\n/**\n * Refuse a `--collections` path that does not exist.\n *\n * `null` means the flag was not given: the default (`../config/collections`) is\n * left to the loader, which warns and continues — a project may legitimately\n * have no collections directory, and a headless scaffold does.\n */\nexport function assertCollectionsPathExists(typed: string | null): void {\n if (typed === null) return;\n\n const resolved = path.resolve(process.cwd(), typed);\n if (fs.existsSync(resolved)) return;\n\n outError(\"\");\n outError(describeMissingCollectionsPath(typed, resolved));\n outError(\"\");\n throw new CollectionsPathMissing(typed, resolved);\n}\n","/**\n * What `rebase db branch prune` should remove, decided without a database.\n *\n * Branching had no cleanup story at all: no TTL, no prune, no `delete --all`,\n * and every branch is a **full-size copy** — `CREATE DATABASE ... TEMPLATE`\n * duplicates the files on disk, so five branches of a 100 GB database cost\n * 500 GB. The only way to reclaim any of it was to remember every name you had\n * ever typed.\n *\n * Three things drift apart, and they are not the same problem:\n *\n * 1. **Stale rows** — `rebase.branches` says a branch exists and its database\n * is gone. Someone dropped it with plain SQL, or restored the cluster from\n * a backup taken before it. The row is what `list` reads, so the branch goes\n * on being reported forever; `switch` and `info` then fail against a\n * database nothing can find.\n *\n * 2. **Orphan databases** — an `rb_*` database with no row. `createBranch`\n * creates the database first and records it second, so a crash between the\n * two leaves exactly this: disk consumed by something no Rebase command will\n * ever mention again.\n *\n * 3. **Expired branches** — alive, registered, and older than you meant to keep.\n * This is the ordinary case and the reason the command exists.\n *\n * Atlas's scratch databases are reported alongside but never removed by\n * default. `rebase db push` creates `<db>_dev_diff` to compute its diff against\n * and does not always clean it up, so they accumulate next to the branches and\n * look like them. They are not branches, and one may belong to an Atlas run\n * happening right now — so this names them and leaves the decision to a flag.\n */\n\n/** A branch as `rebase.branches` records it. */\nexport interface BranchRow {\n name: string;\n dbName: string;\n createdAt: Date;\n}\n\nexport interface PrunePlan {\n /** Registered, but the database is gone. Remove the row only. */\n staleRows: BranchRow[];\n /** An `rb_*` database with no row. Drop the database only. */\n orphanDatabases: string[];\n /** Alive, registered, older than the cutoff. Drop both. */\n expired: { branch: BranchRow; ageDays: number }[];\n /** Atlas scratch databases. Reported; removed only when asked. */\n devDiff: string[];\n /**\n * The branch the checkout is switched to, when prune would otherwise have\n * removed it: kept, as `delete` refuses it, and named so the plan says\n * why. `null` when prune would not have touched it.\n */\n active: { name: string; database: string } | null;\n}\n\n/**\n * The variable the CLI hands the driver the database its checkout is switched\n * to in. The pointer is the CLI's (`dev-db/branch-pointer.ts`); the driver is\n * a child process that cannot read it. Spelled the same in\n * `packages/cli/src/commands/db.ts`.\n */\nexport const ACTIVE_BRANCH_DATABASE_ENV = \"REBASE_ACTIVE_BRANCH_DATABASE\";\n\n/** True when nothing at all needs doing. */\nexport function planIsEmpty(plan: PrunePlan, includeDevDiff: boolean): boolean {\n return plan.staleRows.length === 0\n && plan.orphanDatabases.length === 0\n && plan.expired.length === 0\n && (!includeDevDiff || plan.devDiff.length === 0);\n}\n\n/**\n * Age in whole days, floored.\n *\n * Floored rather than rounded so `--older-than 7` never catches something six\n * and a half days old: a prune that removes more than it said it would is worse\n * than one that waits another twelve hours.\n */\nexport function ageInDays(createdAt: Date, now: Date): number {\n return Math.floor((now.getTime() - createdAt.getTime()) / 86_400_000);\n}\n\n/**\n * Parse `--older-than`. Accepts a bare number of days, or `7d` / `2w`.\n *\n * Returns null for anything else, so the caller refuses rather than guessing —\n * silently reading `--older-than 7h` as seven *days* would delete a week of\n * work.\n */\nexport function parseOlderThan(value: string): number | null {\n const match = /^(\\d+)\\s*([dw])?$/i.exec(value.trim());\n if (!match) return null;\n\n const amount = Number(match[1]);\n if (!Number.isFinite(amount)) return null;\n\n return match[2]?.toLowerCase() === \"w\" ? amount * 7 : amount;\n}\n\nexport function planPrune(\n input: {\n rows: readonly BranchRow[];\n /** Every database name on the server. */\n databases: readonly string[];\n branchPrefix: string;\n },\n options: {\n olderThanDays?: number | null;\n now?: Date;\n /** The database the checkout is switched to, which prune never drops. */\n activeDatabase?: string | null;\n } = {}\n): PrunePlan {\n const now = options.now ?? new Date();\n const present = new Set(input.databases);\n const registered = new Set(input.rows.map((row) => row.dbName));\n const isActive = (database: string): boolean => options.activeDatabase != null && database === options.activeDatabase;\n let active: PrunePlan[\"active\"] = null;\n\n const staleRows = input.rows.filter((row) => !present.has(row.dbName));\n\n const orphanDatabases = input.databases\n .filter((name) => name.startsWith(input.branchPrefix) && !registered.has(name))\n .filter((name) => {\n if (!isActive(name)) return true;\n active = { name, database: name };\n return false;\n })\n .sort();\n\n const expired = options.olderThanDays == null\n ? []\n : input.rows\n // A row whose database is already gone is a stale row, not an\n // expired branch — listing it under both would offer to drop a\n // database that does not exist.\n .filter((row) => present.has(row.dbName))\n .map((branch) => ({ branch, ageDays: ageInDays(branch.createdAt, now) }))\n .filter((entry) => entry.ageDays >= options.olderThanDays!)\n .filter((entry) => {\n if (!isActive(entry.branch.dbName)) return true;\n active = { name: entry.branch.name, database: entry.branch.dbName };\n return false;\n })\n .sort((a, b) => b.ageDays - a.ageDays);\n\n const devDiff = input.databases.filter((name) => name.endsWith(\"_dev_diff\")).sort();\n\n return { staleRows, orphanDatabases, expired, devDiff, active };\n}\n","import arg from \"arg\";\nimport chalk from \"chalk\";\nimport { execa } from \"execa\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { out, outWarn, outError } from \"./cli-output\";\nimport { resolveTsxLoader } from \"./tsx-loader\";\nimport { formatRelativeTime } from \"@rebasepro/utils\";\nimport {\n diagnoseMissingBin,\n detectProjectPackageManager,\n describeBuildScriptRemedy,\n describeDevAddCommand,\n describeReinstallCommand,\n workspaceMemberDir,\n resolveLocalBin,\n getTableIncludes,\n atlasDevDatabaseUrl,\n ensureDevDatabaseExists,\n dropDevDatabase,\n applySearchDdl,\n getSearchExcludes,\n readSearchDdl,\n applyVectorDdl,\n getVectorExcludes,\n readVectorDdl,\n applyTriggersDdl,\n getTriggerExcludes,\n readTriggersDdl,\n getTableExcludes,\n getForeignIndexExcludes,\n getUndeclaredConstraintExcludes,\n queryUndeclarableConstraints,\n ExcludeIntrospectionError,\n queryGeneratedColumnDependencies,\n queryColumnTypes,\n dropGeneratedColumns,\n loadCollectionsForCli,\n withAppClient,\n closeAppClients\n} from \"./cli-helpers\";\nimport {\n checkDatabaseConnectivity,\n diagnoseAtlasFailure,\n diagnoseDbError,\n formatForeignGeneratedColumnBanner,\n isAuthFailure,\n isEconnrefused,\n isSslNotEnabled,\n reportCommandFailure\n} from \"./cli-errors\";\nimport { forAtlas, redactConnectionPasswords } from \"./utils/connection-string\";\nimport { dropLegacyAuthSchema, RLS_BOOTSTRAP_SQL } from \"./schema/rls-bootstrap-sql\";\nimport { detectDestructiveStatements, decidePushSafety, destructiveOptInFlag, extractPlanStatements, type DestructiveStatement, type ExistingColumnType } from \"./schema/destructive-sql\";\nimport type { LegacyRename } from \"./schema/push-legacy-renames\";\nimport {\n parseColumnMutations,\n findGeneratedColumnConflicts,\n partitionByOwnership,\n dropGeneratedColumnStatements,\n migrationDropPreamble,\n describeConflict\n} from \"./schema/generated-column-conflicts\";\nimport { stripCarvedOutStatements } from \"./schema/carved-out-migration\";\nimport type { ExistingConstraint } from \"./schema/undeclarable-constraints\";\nimport { finishNewMigration } from \"./schema/migration-post-process\";\nimport { acceptsExcludeFlag, buildAtlasArgs, migrateApplyArgs, readsRevisions, takesDevUrl } from \"./schema/atlas-argv\";\nimport { ensureAtlasRevisionsTable } from \"./schema/atlas-revisions\";\nimport { createApplyReportFilter } from \"./schema/atlas-apply-report\";\nimport { nextStepAfterDbGenerate } from \"./schema/generate-next-step\";\nimport { CommandStopped, ScratchDatabase } from \"./cli-scratch-database\";\nimport { baselineVersionProblem, describeBaselinePlan, latestRecordedMigration, planBaseline } from \"./schema/migrate-baseline\";\nimport { promptConfirm } from \"./cli-prompt\";\nimport { applyPoliciesFile, applyPushPlan, stampableTables, type PolicyStamping } from \"./cli-push\";\nimport { resolveBranchSwitches, unexpectedBranchArgs } from \"./branch-argv\";\nimport { assertKnownFlags, collectionsPathIn, parseDriverLine, resolveDriverSwitches } from \"./cli-flags\";\nimport { assertCollectionsPathExists } from \"./cli-collections-path\";\nimport { DESIRED_STATE_URL, GENERATED_SQL_DIR, generatedSqlDir, prepareGeneratedSqlDir } from \"./generated-sql\";\nimport { backupActionOf } from \"./backup-argv\";\nimport { DRIVER_DB_SUBCOMMANDS, isDriverDbSubcommand } from \"./db-subcommands\";\nimport type { TableLockResult } from \"./schema/ensure-collection-policies\";\nimport type { DeferredIndexBuild } from \"./schema/plan/diff-plan\";\n\nimport { ACTIVE_BRANCH_DATABASE_ENV, planIsEmpty, planPrune, parseOlderThan } from \"./branch-prune\";\n\nconst __cliDirname = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * A script this CLI spawns, and how to run it.\n *\n * Four commands — `schema generate`, the DDL plan, `introspect` and the schema\n * doctor — run as child processes, located by path relative to this file. That\n * path used to be `<dir>/schema/<name>.ts`, which worked only because `files`\n * shipped `src`. When the tarball stopped shipping `src`, every one of those\n * commands broke for every npm consumer at once: the file was simply absent,\n * and the parent CLI reported the absence as \"Dependencies are not installed\"\n * at projects that had installed perfectly. 0.18.0 shipped that way — a\n * scaffolded project's first `rebase dev` could not regenerate its schema and\n * every `GET /api/data/*` answered `Table not found for collection 'posts'`.\n *\n * The build emits each of them beside this file, so a published copy carries\n * the command surface as an artifact. Source still wins where there is no\n * build, which is how the monorepo runs before `pnpm build`.\n *\n * **The interpreter is tsx either way, and that is not incidental.** These\n * scripts load the *project's* collection files, which are TypeScript and\n * import each other as `./authors.js` — the extension TypeScript tells you to\n * write. Node resolves that literally and fails on a file that does not exist;\n * tsx maps it back. Running the built `.js` under plain `node` therefore fails\n * on the user's code rather than on ours, one directory further from anything\n * the error mentions.\n *\n * tsx's loader in one Node (`node --import`) when it resolves, rather than the\n * `tsx` binary, which is a shell shim and a relay Node in front of that same\n * loader (see `tsx-loader.ts`). The binary stays the fallback — a global tsx.\n * `args` is everything after `bin`, the script included.\n */\nfunction resolveChildScript(name: string):\n | { ok: true; bin: string; args: string[] }\n | { ok: false; reason: \"script\" | \"tsx\" } {\n const built = path.join(__cliDirname, \"schema\", `${name}.js`);\n const source = path.join(__cliDirname, \"schema\", `${name}.ts`);\n const script = fs.existsSync(built) ? built : fs.existsSync(source) ? source : null;\n if (!script) return { ok: false, reason: \"script\" };\n\n const tsxLoader = resolveTsxLoader();\n if (tsxLoader) return { ok: true, bin: process.execPath, args: [\"--import\", tsxLoader, script] };\n\n const tsxBin = resolveLocalBin(\"tsx\");\n if (!tsxBin) return { ok: false, reason: \"tsx\" };\n\n return { ok: true, bin: tsxBin, args: [script] };\n}\n\n/** What to print when {@link resolveChildScript} cannot produce a command. */\nfunction childScriptError(what: string, reason: \"script\" | \"tsx\"): string {\n if (reason === \"tsx\") {\n return `✗ Could not find the tsx binary, which ${what} needs to read your collection files. `\n + \"Install your project's dependencies and try again.\";\n }\n return `✗ The driver's ${what} is missing. This copy of @rebasepro/server-postgres is `\n + \"incomplete — reinstall it, or run its build if you are working in the monorepo.\";\n}\n\n/**\n * Whether this process can run the generators itself — that is, whether it\n * runs under tsx, the interpreter the project's collection files need (see\n * {@link resolveChildScript}). `rebase` always starts the driver that way when\n * tsx is installed, which a scaffold guarantees; a driver started with plain\n * `node` keeps the child process, which brings its own tsx.\n */\nfunction generatesInProcess(): boolean {\n const flags = [...process.execArgv, process.env.NODE_OPTIONS ?? \"\"];\n return flags.some(flag => /(?:^|[\\s\\\\/=])tsx(?:$|[\\s\\\\/@])/.test(flag));\n}\n\n/**\n * Run one of the generators in this process — see `schema/generate-files.ts`\n * for why a one-shot generation no longer gets a process of its own.\n *\n * The messages and the exit code are the child's: a generator that failed has\n * printed its own error, and this adds the one-line verdict; one that could not\n * even be loaded is reported the way a child that never started was.\n */\nasync function generateInProcess(\n what: string,\n label: string,\n run: (generators: typeof import(\"./schema/generate-files\")) => Promise<void>\n): Promise<void> {\n let generators: typeof import(\"./schema/generate-files\");\n try {\n generators = await import(\"./schema/generate-files\");\n } catch (err) {\n outError(chalk.red(`✗ Failed to run ${what}: ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n try {\n await run(generators);\n } catch (err) {\n if (err instanceof generators.GenerationFailed) {\n outError(chalk.red(`✗ ${label} generation failed — nothing was applied.`));\n } else {\n outError(chalk.red(`✗ Failed to run ${what}: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n}\n\n\n\nasync function loadEnv(): Promise<void> {\n try {\n const dotenv = await import(\"dotenv\");\n const envPaths = [\n process.env.DOTENV_CONFIG_PATH,\n path.resolve(process.cwd(), \".env\"),\n path.resolve(process.cwd(), \"../.env\"),\n path.resolve(process.cwd(), \"../../.env\")\n ].filter(Boolean) as string[];\n\n for (const p of envPaths) {\n if (fs.existsSync(p)) {\n const parsed = dotenv.config({ path: p, quiet: true });\n if (parsed.parsed) {\n for (const [key, val] of Object.entries(parsed.parsed)) {\n if (process.env[key] === undefined) {\n process.env[key] = val;\n }\n }\n break;\n }\n }\n }\n } catch {\n // ignore\n }\n}\n\nexport async function runPluginCommand(args: string[]) {\n // Also set as an environment variable, not just per `config()` call: this\n // command spawns `tsx` subprocesses (the schema generator, the DDL\n // generator, doctor) that load `.env` themselves, and they inherit this.\n // dotenv reads it before `options.quiet`; an explicit `false` still wins.\n if (process.env.DOTENV_CONFIG_QUIET === undefined) {\n process.env.DOTENV_CONFIG_QUIET = \"true\";\n }\n await loadEnv();\n const domain = args[0]; // \"db\" or \"schema\"\n const subcommand = args[1];\n\n // Before anything reads the line: every parser below runs `permissive`,\n // which turns an undeclared flag into a positional rather than an error, so\n // `db push --alow-destructive` pushed with the destructive gate still shut\n // and `schema generate --ouput x` wrote the default path in silence. See\n // cli-flags.ts for why the check has to be here and not in those parsers.\n assertKnownFlags(domain, subcommand, args);\n // Every parser below reads the line with its switches' values resolved:\n // they run `permissive`, and `arg` reads `--allow-destructive=false` as on.\n args = resolveDriverSwitches(domain, subcommand, args);\n\n // And before anything is generated: a `--collections` path that does not\n // resolve used to warn and carry on, four times over, and the generators\n // then wrote an *empty* schema over `drizzle/schema.sql` and\n // `src/schema.generated.ts` — both committed artifacts — after which the\n // push planned a DROP TABLE for every table in the database. Only the\n // destructive gate stood between a typo and the whole schema.\n //\n // Checked here rather than in `loadCollectionsForCli`, which is\n // deliberately forgiving: its callers use it to *narrow* what Atlas may\n // touch, and a hard failure there would block a push over one broken file.\n // This is a different question — \"does the directory the user named\n // exist\" — and the answer was already known before the first write.\n assertCollectionsPathExists(collectionsPathIn(args));\n\n try {\n if (domain === \"db\") {\n await scratchDatabase.around(() => dbCommand(subcommand, args));\n } else if (domain === \"schema\") {\n await schemaCommand(subcommand, args);\n } else if (domain === \"doctor\") {\n await doctorPluginCommand(args);\n } else if (domain === \"console\") {\n const { consoleCommand } = await import(\"./cli-console\");\n process.exitCode = await consoleCommand(args);\n } else {\n outError(chalk.red(`Unknown domain command: ${domain}`));\n process.exit(1);\n }\n } finally {\n // The one connection every step shared (see `withAppClient`). Open, it\n // would keep this process alive after the command has finished.\n await closeAppClients();\n }\n}\n\n/** The migration files on disk, sorted, or none if the directory is absent. */\nfunction listMigrationFiles(): string[] {\n const dir = path.resolve(process.cwd(), \"drizzle\", \"migrations\");\n if (!fs.existsSync(dir)) return [];\n return fs.readdirSync(dir).filter(f => f.endsWith(\".sql\")).sort();\n}\n\n/**\n * The newest migration's version — the numeric prefix Atlas records.\n *\n * `20260906101530_init.sql` → `20260906101530`. Named in the baseline remedy so\n * the command it prints can be typed rather than worked out.\n */\nfunction latestMigrationVersion(): string | null {\n const newest = listMigrationFiles().at(-1);\n if (!newest) return null;\n const match = /^(\\d+)/.exec(newest);\n return match ? match[1] : newest.replace(/\\.sql$/, \"\");\n}\n\n/**\n * Take Atlas's carve-outs back out of the migration `migrate diff` just wrote.\n *\n * The apply path hands Atlas `--exclude` and it never sees the search or vector\n * columns. The diff path has no such flag — `atlas migrate diff` rejects\n * `--exclude` outright, and an `atlas.hcl` `env` block's `exclude` is accepted\n * and then ignored — so Atlas replays the migration directory (which builds\n * both columns, because that DDL is appended to migrations), does not find them\n * in `schema.sql`, and plans `DROP COLUMN`. Applied, that would take search and\n * the embeddings away from every database the migration reaches.\n *\n * Returns whether a migration Atlas just wrote is still there afterwards: a\n * file whose only content was the spurious drop is deleted, because an empty\n * migration is worse than none — it takes a slot in the revision history and\n * the caller would append the carved-out DDL and the policies to it.\n *\n * @returns true when a new migration survives and may be appended to.\n */\nasync function stripCarvedOutFromNewestMigration(collectionsPath: string): Promise<boolean> {\n // Both carve-outs, for one reason: they are the same problem. Search is out\n // of Atlas's sight because its free tier will not parse a function; vector\n // is out because Atlas resolves the desired state in a dev database that\n // can never have pgvector. What follows from that is identical — the diff\n // replays a migration directory holding objects `schema.sql` omits, and\n // plans a drop for every one.\n const patterns = [\n ...await getSearchExcludes(collectionsPath),\n ...await getVectorExcludes(collectionsPath),\n ...await getTriggerExcludes(collectionsPath)\n ];\n if (patterns.length === 0) return true;\n\n const newest = listMigrationFiles().at(-1);\n if (!newest) return false;\n const file = path.resolve(process.cwd(), \"drizzle\", \"migrations\", newest);\n\n const result = stripCarvedOutStatements(fs.readFileSync(file, \"utf-8\"), patterns);\n\n // Fail CLOSED, and loudly. A drop this could not rewrite stays in the file\n // exactly as Atlas wrote it, and the file is one somebody applies next week\n // — by which time the column is gone and nothing connects it to this run.\n // The destructive gate does not cover it either: that reads the *push*\n // plan. So `db generate` stops here rather than hand back a migration that\n // destroys a column the developer never asked to lose.\n if (result.unhandled.length > 0) {\n outError(chalk.red(\n `\\n ✗ ${newest} drops an object Rebase manages outside Atlas, in a form the CLI`\n ));\n outError(chalk.red(\" could not remove:\"));\n for (const statement of result.unhandled) {\n outError(chalk.gray(` ${statement.replace(/\\s+/g, \" \")}`));\n }\n outError(chalk.gray(\n \" Left as Atlas wrote it. Delete those statements by hand before running\\n\" +\n \" `rebase db migrate` — and please report them: rewriting this is meant to\\n\" +\n \" be automatic.\"\n ));\n process.exit(1);\n }\n\n if (result.removed.length === 0) return true;\n\n if (result.empty) {\n fs.rmSync(file);\n out(chalk.gray(\n ` ✓ Dropped ${newest} — it planned nothing but the removal of columns\\n` +\n \" Atlas cannot see and Rebase applies itself.\"\n ));\n } else {\n fs.writeFileSync(file, result.sql, \"utf-8\");\n out(chalk.gray(` ✓ Kept Rebase's own columns out of ${newest} (${result.removed.length} statement(s))`));\n }\n\n await runAtlas(\"migrate\", [\"hash\", \"--dir\", \"file://drizzle/migrations\"], collectionsPath);\n return !result.empty;\n}\n\n/**\n * One line per destructive statement, as `db push` prints them — shared by\n * push, `db generate` and `db migrate --refuse-destructive`, so the three\n * describe the same statement the same way.\n */\nfunction destructiveLines(destructive: readonly DestructiveStatement[]): string[] {\n return destructive.map(d =>\n chalk.red(` ${d.kind}${d.detail ? ` (${d.detail})` : \"\"}: `) + chalk.gray(d.statement.replace(/\\s+/g, \" \")));\n}\n\n/**\n * The column types `detectDestructiveStatements` reads a type change against,\n * or none when the database cannot be asked — every type change then counts\n * as destructive, which is the safe side of a report.\n */\nasync function columnTypesOrNone(databaseUrl: string | undefined): Promise<ExistingColumnType[]> {\n if (!databaseUrl) return [];\n try {\n return await queryColumnTypes(databaseUrl);\n } catch {\n return [];\n }\n}\n\n/**\n * The CHECK and EXCLUDE constraints `detectDestructiveStatements` reads a\n * `DROP CONSTRAINT` against, or none when the database cannot be asked. A\n * report then cannot tell a dropped CHECK from a dropped foreign key, and says\n * nothing about either, as before.\n */\nasync function constraintsOrNone(databaseUrl: string | undefined): Promise<ExistingConstraint[]> {\n if (!databaseUrl) return [];\n try {\n return await queryUndeclarableConstraints(databaseUrl);\n } catch {\n return [];\n }\n}\n\n/**\n * Say what in the migration `db generate` just wrote destroys data.\n *\n * `db push` stops before a destructive change; `db generate` wrote the same\n * `DROP COLUMN` into a file without a word, and `db migrate` applied it. Only\n * the part Atlas planned is read: what is appended after it (the search\n * rebuild, policies, triggers) is Rebase's own and puts back what it drops.\n * A report, not a refusal — the exit code is unchanged.\n */\nasync function reportDestructiveMigration(migrationSql: string, migrationFile: string, databaseUrl: string | undefined): Promise<void> {\n const destructive = detectDestructiveStatements(migrationSql, await columnTypesOrNone(databaseUrl), await constraintsOrNone(databaseUrl));\n if (destructive.length === 0) return;\n outWarn(\"\");\n outWarn(chalk.yellow(` ⚠️ ${migrationFile} includes ${destructive.length} destructive change(s) that will DESTROY data when applied:`));\n outWarn(\"\");\n for (const line of destructiveLines(destructive)) outWarn(line);\n outWarn(\"\");\n outWarn(chalk.yellow(\" Review it before `rebase db migrate`. `rebase db migrate --refuse-destructive` will not apply it.\"));\n outWarn(chalk.yellow(\" Back up first: rebase db backup\"));\n outWarn(\"\");\n}\n\n/**\n * The flags `rebase db` reads for the subcommands it parses itself. Hoisted\n * and named `…FLAGS` so the documentation verifier, which reads specs out of\n * this source, sees them.\n */\nconst DB_FLAGS = {\n \"--collections\": String,\n \"--allow-destructive\": Boolean,\n \"--refuse-destructive\": Boolean,\n \"--dry-run\": Boolean,\n \"--yes\": Boolean,\n \"--baseline\": String,\n \"-c\": \"--collections\",\n \"-y\": \"--yes\"\n} satisfies arg.Spec;\n\nasync function dbCommand(subcommand: string, rawArgs: string[]): Promise<void> {\n if (!isDriverDbSubcommand(subcommand)) {\n outError(chalk.red(`Unknown db command. Valid: ${DRIVER_DB_SUBCOMMANDS.join(\", \")}`));\n process.exit(1);\n }\n\n // A second line of defence, and not a redundant one. `rebase db` answers\n // `--help` before it ever spawns this file, but this file is also its own\n // CLI — the driver is spawned directly by `resolvePluginCliScript`, and is\n // executable on its own — so a `--help` reaching here means nobody upstream\n // caught it. Only `branch` had a case for it; `push`, `migrate` and\n // `restore` all took `--help` as an ordinary flag and did the work.\n if (rawArgs.includes(\"--help\") || rawArgs.includes(\"-h\")) {\n out(\"\");\n out(chalk.bold(` rebase db ${subcommand}`));\n out(chalk.gray(\" Run `rebase db --help` for the full page — this is the driver's own entry point.\"));\n out(\"\");\n return;\n }\n\n if (subcommand === \"branch\") {\n await branchCommand(rawArgs);\n return;\n }\n\n if (subcommand === \"backup\" || subcommand === \"restore\" || subcommand === \"backups\") {\n const { backupCommand, restoreCommand, backupsCommand } = await import(\"./backup/backup-cli\");\n // `rebase cloud db backup list` is how the cloud family spells this, and\n // locally the same words *created a backup*: \"list\" was a positional\n // `backupCommand` ignored. One CLI, two spellings, and the wrong guess\n // wrote a dump instead of reading one. Both spellings list now.\n if (subcommand === \"backup\" && backupActionOf(rawArgs) === \"list\") await backupsCommand(rawArgs);\n else if (subcommand === \"backup\") await backupCommand(rawArgs);\n else if (subcommand === \"restore\") await restoreCommand(rawArgs);\n else await backupsCommand(rawArgs);\n return;\n }\n\n const argsList = parseDriverLine(DB_FLAGS, rawArgs);\n const collectionsPath = argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n\n if (subcommand === \"generate\") {\n out(\"\");\n out(chalk.bold(\" 📦 Rebase DB Generate\"));\n out(chalk.gray(\" Step 1/2: Generating Drizzle schema & Postgres DDL from collections...\"));\n out(\"\");\n await schemaCommand(\"generate\", rawArgs, { nextStep: false });\n await generatePostgresDdlCommand(rawArgs);\n out(\"\");\n out(chalk.gray(\" Step 2/2: Generating SQL migration files with Atlas...\"));\n out(\"\");\n const migrationName = argsList._[0] || \"migration\";\n const migrationsBefore = listMigrationFiles();\n await runAtlas(\"migrate\", [\"diff\", migrationName, \"--dir\", \"file://drizzle/migrations\", \"--to\", DESIRED_STATE_URL], collectionsPath);\n // The diff cannot be told to ignore the carved-out objects the way the\n // apply can, so the drop it plans for them is taken back out of the\n // file it just wrote. A migration that was nothing else is deleted.\n let wroteNewMigration = listMigrationFiles().length > migrationsBefore.length;\n if (wroteNewMigration) {\n wroteNewMigration = await stripCarvedOutFromNewestMigration(collectionsPath);\n }\n const newestWritten = wroteNewMigration ? listMigrationFiles().at(-1) : undefined;\n if (newestWritten) {\n await reportDestructiveMigration(\n fs.readFileSync(path.resolve(process.cwd(), \"drizzle\", \"migrations\", newestWritten), \"utf-8\"),\n newestWritten,\n process.env.DATABASE_URL\n );\n }\n \n // Post-process the migration Atlas just wrote.\n //\n // `wroteNewMigration` gates the whole block, and that gate is the point.\n // \"The newest migration file\" is only Atlas's when Atlas wrote one;\n // otherwise it is a migration that has already run in production, and\n // appending to it changes a hash Atlas has recorded while the appended\n // SQL never runs anywhere. The search half already said so and checked;\n // the `CREATE SCHEMA` rewrite and the policy append did not, so every\n // `db generate` that found nothing to diff still grew the last\n // migration by another copy of the policies.\n //\n // A failure here takes the migration back out and stops: see\n // `finishNewMigration`. Atlas's half creates the tables, the append\n // locks them, and a migration with only the first half applies cleanly.\n const migrationsDir = path.resolve(process.cwd(), \"drizzle\", \"migrations\");\n const newestSql = fs.existsSync(migrationsDir) && wroteNewMigration\n ? fs.readdirSync(migrationsDir).filter(f => f.endsWith(\".sql\")).sort().at(-1)\n : undefined;\n if (newestSql) {\n const newestMigrationFile = path.join(migrationsDir, newestSql);\n const finished = await finishNewMigration(newestMigrationFile, async () => {\n // Make CREATE SCHEMA idempotent so it doesn't conflict with\n // --revisions-schema (Atlas pre-creates the rebase schema\n // for its revision table before running migrations).\n let migrationContent = fs.readFileSync(newestMigrationFile, \"utf-8\");\n migrationContent = migrationContent.replace(\n /CREATE SCHEMA (?!IF NOT EXISTS)(\"[^\"]+\");/g,\n \"CREATE SCHEMA IF NOT EXISTS $1;\"\n );\n // Atlas never writes the search or vector objects into a\n // migration — it is not shown them — so a migration\n // replayed against a fresh database would build every table\n // except the parts that make search and vector search work.\n // Appending, because these are `ALTER TABLE ... ADD COLUMN`\n // over the tables the migration just created.\n //\n // Vector first: `vector.sql` may open with\n // `CREATE EXTENSION vector`, so prerequisites lead, which is\n // the order a reader of the migration expects. Nothing in\n // search depends on it either way.\n const vectorContent = readVectorDdl();\n if (vectorContent) {\n migrationContent = `${migrationContent}\\n\\n${vectorContent}`;\n out(chalk.gray(\" ✓ Appended vector DDL to the migration\"));\n }\n\n const searchContent = readSearchDdl();\n if (searchContent) {\n // The same refusal `db push` works around, but decided\n // here and written into the file: this migration runs\n // later, somewhere else, against a database nobody can\n // inspect from this machine. A column retyped by the\n // statements above cannot be retyped while the search\n // column reads it, and the appended DDL below runs too\n // late to help — so the drop is prepended and the\n // rebuild is the append that was already happening.\n //\n // Derived from the collections rather than a catalogue:\n // `searchColumnDependencies` knows which columns each\n // block reads, which is all the decision needs.\n const { searchColumnDependencies } = await import(\"./schema/generate-postgres-ddl-logic\");\n const migrationConflicts = findGeneratedColumnConflicts(\n parseColumnMutations(migrationContent),\n searchColumnDependencies(await loadCollectionsForCli(collectionsPath))\n );\n const preamble = migrationDropPreamble(migrationConflicts);\n if (preamble) {\n migrationContent = `${preamble}\\n${migrationContent}`;\n for (const conflict of migrationConflicts) {\n out(chalk.gray(` ✓ ${describeConflict(conflict)} is dropped and rebuilt inside the migration`));\n }\n }\n migrationContent = `${migrationContent}\\n\\n${searchContent}`;\n out(chalk.gray(\" ✓ Appended search DDL to the migration\"));\n }\n\n // Last of the three: a trigger needs its table and its\n // column, and both arrive above.\n const triggersContent = readTriggersDdl();\n if (triggersContent) {\n migrationContent = `${migrationContent}\\n\\n${triggersContent}`;\n out(chalk.gray(\" ✓ Appended `updated_at` triggers to the migration\"));\n }\n\n fs.writeFileSync(newestMigrationFile, migrationContent, \"utf-8\");\n\n // Append RLS policies, preceded by the RLS bootstrap so the\n // migration is self-contained: Atlas replays migrations\n // against a clean dev database where `rebase.uid()` would\n // not otherwise exist.\n const policiesFile = path.join(generatedSqlDir(), \"policies.sql\");\n if (fs.existsSync(policiesFile)) {\n const policiesContent = fs.readFileSync(policiesFile, \"utf-8\");\n fs.appendFileSync(newestMigrationFile, \"\\n\\n\" + RLS_BOOTSTRAP_SQL + \"\\n\" + policiesContent);\n out(chalk.gray(` ✓ Appended RLS policies to migration file: ${path.basename(newestMigrationFile)}`));\n\n // Re-hash the migration directory\n out(chalk.gray(\" Re-hashing migration files...\"));\n await runAtlas(\"migrate\", [\"hash\", \"--dir\", \"file://drizzle/migrations\"], collectionsPath, { throwOnFailure: true });\n out(chalk.gray(\" ✓ Migration directory checksum updated successfully.\"));\n }\n }, async () => {\n await runAtlas(\"migrate\", [\"hash\", \"--dir\", \"file://drizzle/migrations\"], collectionsPath, { throwOnFailure: true });\n });\n if (!finished.ok) {\n outError(chalk.red(`\\n ✗ Could not finish ${newestSql}: ${finished.error}`));\n outError(chalk.gray(\n \" Atlas's half of a migration creates the tables; the part that failed adds their\\n\" +\n \" row-level security, policies, search, vector and trigger DDL. Applied alone, it\\n\" +\n \" would serve the new tables with no row filtering.\"\n ));\n outError(chalk.gray(finished.removed\n ? ` ${newestSql} was removed. Fix the cause and run \\`rebase db generate\\` again.`\n : ` ${newestSql} could not be removed — delete it by hand before \\`rebase db migrate\\`.`));\n if (finished.rehashError) {\n outError(chalk.gray(\n ` Re-hashing failed too (${finished.rehashError}); run \\`atlas migrate hash\\` or generate again.`\n ));\n }\n process.exit(1);\n }\n }\n\n if (!wroteNewMigration) {\n // Reachable whenever the only thing that changed is something Atlas\n // cannot see — a `search` block, a `vector` property, or a\n // `securityRules` edit. There is no new file to carry it, and the\n // previous migration must not be reopened: it has already run\n // wherever this project is deployed.\n out(chalk.gray(\n \" ℹ No migration written — nothing in this change is visible to Atlas.\\n\" +\n \" Search, vector, trigger and RLS DDL are applied by `rebase db push`, and at\\n\" +\n \" boot by the schema ensure. For a migration-only deployment, add\\n\" +\n ` ${GENERATED_SQL_DIR}/search.sql, vector.sql, triggers.sql and\\n` +\n \" policies.sql to a migration by hand.\"\n ));\n }\n\n const nextStep = nextStepAfterDbGenerate({\n newestVersion: latestMigrationVersion(),\n wrote: wroteNewMigration,\n first: migrationsBefore.length === 0\n });\n out(\"\");\n for (const line of nextStep) out(line);\n if (nextStep.length > 0) out(\"\");\n } else {\n out(\"\");\n out(chalk.bold(` 🗄️ Rebase DB ${subcommand.charAt(0).toUpperCase() + subcommand.slice(1)}`));\n out(\"\");\n\n if (subcommand === \"push\") {\n const dryRun = argsList[\"--dry-run\"] === true;\n out(chalk.gray(dryRun\n ? \" Step 1/3: Generating the Postgres DDL from collections (the plan's input)...\"\n : \" Step 1/3: Generating Drizzle schema & Postgres DDL from collections...\"));\n out(\"\");\n // `--dry-run` applies nothing, and that includes the project's\n // files: it used to rewrite the tracked `src/schema.generated.ts`\n // and delete the `drizzle/*.sql` copies an older release committed.\n // Atlas plans from the DDL alone, which goes to the scratch\n // directory `.rebase/sql/` that ignores itself.\n if (dryRun) {\n out(chalk.gray(\" --dry-run: src/schema.generated.ts is left as it is.\"));\n } else {\n await schemaCommand(\"generate\", rawArgs, { nextStep: false });\n }\n await generatePostgresDdlCommand(rawArgs, { retireLegacyCopies: !dryRun });\n out(\"\");\n out(chalk.gray(dryRun\n ? \" Step 2/3: Planning the change against the database (nothing is applied)...\"\n : \" Step 2/3: Pushing schema to database with Atlas...\"));\n out(\"\");\n const databaseUrl = process.env.DATABASE_URL;\n // Skipped under --dry-run: this creates the auth schema and its\n // functions, which is a write. \"Show me what would happen\" that\n // changes something on the way is not a plan.\n if (databaseUrl && !dryRun) {\n await ensureAuthSchemaAndFunctions(databaseUrl);\n }\n\n // Before Atlas plans: the foreign-key indexes an existing table is\n // missing, built CONCURRENTLY — so the plan finds them, and the\n // push's one transaction never builds one while holding the\n // table's writes. See `schema/push-index-prebuild.ts`. A dry-run\n // only names them.\n // First of all: relation columns a pre-0.13 Rebase named the old\n // way (`categorie_id`) are renamed — the lossless, metadata-only\n // statement boot runs — so Atlas does not plan them as a drop and\n // an add. See `schema/push-legacy-renames.ts`.\n if (databaseUrl) await renameLegacyForeignKeys(databaseUrl, collectionsPath, dryRun);\n\n const prebuilt = databaseUrl ? await prebuildForeignKeyIndexes(databaseUrl, collectionsPath, dryRun) : [];\n\n // Preview the plan before touching data. `atlas schema apply` with\n // --auto-approve will silently DROP COLUMN on a field removal and\n // drop+add on a rename, so we first dry-run to obtain the planned\n // SQL and gate anything destructive.\n const plan = await runAtlas(\n \"schema\",\n [\"apply\", \"--to\", DESIRED_STATE_URL, \"--dry-run\"],\n collectionsPath,\n { captureStdout: true }\n );\n // The columns' current types, because an `ALTER COLUMN … TYPE`\n // loses data or does not depending on what the column is now.\n // Without them every type change is gated. And the CHECK and\n // EXCLUDE constraints, so a drop of one that the excludes missed\n // is gated too.\n const destructive = detectDestructiveStatements(\n plan,\n databaseUrl ? await queryColumnTypes(databaseUrl) : [],\n databaseUrl ? await queryUndeclarableConstraints(databaseUrl) : []\n );\n // What to show a person: the statements, once each. Atlas's report\n // prints every one twice and wraps them in timings; when the gate\n // could not read it, the report itself is the only honest thing\n // to show.\n const unreadable = destructive.some(d => d.kind === \"UNREADABLE PLAN\");\n const planStatements = extractPlanStatements(plan);\n const planListing = unreadable\n ? plan.trim()\n : planStatements.map(statement => `${statement};`).join(\"\\n\");\n\n // A generated column makes every column it reads immutable to\n // Atlas: PostgreSQL refuses `ALTER COLUMN … TYPE` and `DROP COLUMN`\n // while one depends on it, and `schema apply` runs its plan in a\n // single transaction — so one refusal rolls back the whole push,\n // including the statements that had nothing to do with it.\n //\n // Atlas cannot avoid planning it. The search column is hidden from\n // its view on purpose (`searchExcludePatterns`), because a desired\n // state that never mentions the column reads to Atlas as an\n // instruction to drop it. So the dependant is invisible exactly\n // where it would have to be visible.\n //\n // Rebase owns those columns, so it takes them out of the way and\n // `applySearchDdl` puts them back below — the same drop-and-re-apply\n // the search stamp guard already prescribes when a block changes.\n const generatedConflicts = databaseUrl\n ? findGeneratedColumnConflicts(\n parseColumnMutations(plan),\n await queryGeneratedColumnDependencies(databaseUrl)\n )\n : [];\n const { managed: rebuildable, foreign: unowned } = partitionByOwnership(\n generatedConflicts,\n collectionsPath ? await getSearchExcludes(collectionsPath) : []\n );\n\n // A removed enum option plans nothing (no ALTER TYPE … DROP VALUE\n // exists), so the push would succeed and the database go on\n // accepting the value. Not a refusal — boot does the same — but said.\n if (databaseUrl) await reportKeptEnumLabels(databaseUrl, collectionsPath);\n\n // What the push does to row-level security, which Atlas's plan\n // cannot show: it has no model for a policy. Read once, here, for\n // the dry run to list and the push to summarize — see\n // `schema/push-policy-plan.ts`.\n const policyPlan = databaseUrl ? await readPolicyPushPlan(databaseUrl, collectionsPath) : undefined;\n const policyLines = policyPlan ?? { changes: [], notes: [] };\n\n // `--dry-run` stops here, having printed the SQL and nothing else.\n //\n // It exists because the only way to see this plan was to trigger\n // the destructive gate, and the gate prints the plan while exiting\n // 1 — so \"what would this do?\" was answerable only by a command\n // that looked like a failure, and unanswerable at all when the\n // change was additive. An agent with no way to show the SQL either\n // asks a human to approve something neither of them has read, or\n // runs the push to find out.\n if (dryRun) {\n out(chalk.gray(\" Step 3/3: --dry-run — nothing was applied.\"));\n out(\"\");\n const schemaChanges = planStatements.length > 0 || unreadable;\n if (schemaChanges) {\n out(chalk.bold(\" Planned changes:\"));\n out(chalk.gray(planListing.split(\"\\n\").map((l) => ` ${l}`).join(\"\\n\")));\n out(\"\");\n }\n const [rlsHeading, ...rlsChanges] = policyLines.changes;\n if (rlsHeading) {\n out(chalk.bold(rlsHeading));\n for (const line of rlsChanges) out(chalk.gray(line));\n out(\"\");\n }\n if (!schemaChanges && !rlsHeading) {\n out(chalk.green(policyPlan\n ? \" ✓ No changes: the database already matches these collections.\"\n : \" ✓ No schema changes: the tables already match these collections.\"));\n out(\"\");\n }\n if (databaseUrl && !policyPlan) {\n outWarn(chalk.yellow(\" ⚠️ The row-level security the push would change could not be read, so none is listed.\"));\n outWarn(\"\");\n }\n if (policyLines.notes.length > 0) {\n for (const line of policyLines.notes) out(chalk.gray(line));\n out(\"\");\n }\n if (prebuilt.length > 0) {\n out(chalk.gray(` ${prebuilt.length} foreign-key index(es) on existing tables would be built first,`));\n out(chalk.gray(\" CONCURRENTLY, so the apply would not build them under a write lock (the plan\"));\n out(chalk.gray(\" above lists them because they do not exist yet):\"));\n for (const name of prebuilt) {\n out(chalk.gray(` ${name}`));\n }\n out(\"\");\n }\n if (rebuildable.length > 0) {\n out(chalk.gray(` ${rebuildable.length} generated column(s) would be dropped before the apply and`));\n out(chalk.gray(\" rebuilt from search.sql after it — Postgres cannot retype a column\"));\n out(chalk.gray(\" while one reads it:\"));\n for (const conflict of rebuildable) {\n out(chalk.gray(` ${describeConflict(conflict)}`));\n }\n out(\"\");\n }\n if (unowned.length > 0) {\n outWarn(formatForeignGeneratedColumnBanner(unowned));\n }\n if (destructive.length > 0) {\n outWarn(chalk.yellow(` ⚠️ ${destructive.length} of those DESTROY data:`));\n for (const line of destructiveLines(destructive)) outWarn(line);\n outWarn(\"\");\n outWarn(chalk.yellow(\" Applying them needs `rebase db push --allow-destructive`. Back up first: rebase db backup\"));\n outWarn(\"\");\n }\n out(chalk.gray(\" The auth schema step was skipped, because it writes. A real push runs it first.\"));\n out(\"\");\n return;\n }\n\n // Before the destructive gate, and separately from it: this is not a\n // change the operator can approve their way through. Rebase has no\n // copy of the expression, so there is nothing to put back.\n if (unowned.length > 0) {\n outError(formatForeignGeneratedColumnBanner(unowned));\n throw new CommandStopped(\"A generated column Rebase does not own blocks the push.\");\n }\n\n const optIn = destructiveOptInFlag(argsList);\n const decision = decidePushSafety({\n destructiveCount: destructive.length,\n allowDestructive: optIn !== undefined,\n interactive: process.stdin.isTTY === true\n });\n\n if (destructive.length > 0) {\n outWarn(chalk.yellow(` ⚠️ This push includes ${destructive.length} destructive change(s) that will DESTROY data:`));\n outWarn(\"\");\n for (const line of destructiveLines(destructive)) outWarn(line);\n outWarn(\"\");\n outWarn(chalk.yellow(\" Full planned changes:\"));\n outWarn(chalk.gray(planListing.split(\"\\n\").map((l) => ` ${l}`).join(\"\\n\")));\n outWarn(\"\");\n\n if (decision === \"refuse\") {\n outError(chalk.red(\" ✗ Aborting: destructive changes require confirmation.\"));\n outError(chalk.gray(\" Re-run interactively, or pass --allow-destructive to proceed. Back up first: rebase db backup\"));\n throw new CommandStopped(\"Destructive changes need confirmation.\");\n }\n if (decision === \"confirm\") {\n const confirmed = await promptConfirm(\n chalk.yellow(\" Type 'yes' to apply these destructive changes (this cannot be undone): \")\n );\n if (!confirmed) {\n out(chalk.gray(\" Aborted. No changes were made.\"));\n throw new CommandStopped(\"The destructive push was declined.\");\n }\n } else {\n // decision === \"apply\" via --allow-destructive or --yes\n outWarn(chalk.yellow(` Proceeding because ${optIn ?? \"--allow-destructive\"} was passed.`));\n }\n }\n\n if (policyPlan?.summary) {\n out(chalk.gray(policyPlan.summary));\n out(\"\");\n }\n\n // Without a database URL there is nothing to drop or rebuild: runAtlas\n // refuses to run without one anyway.\n const rebuildCount = databaseUrl ? rebuildable.length : 0;\n await applyPushPlan({ dryRun: plan, rebuildable: rebuildCount }, {\n dropRebuildable: async () => {\n if (!databaseUrl) return;\n for (const conflict of rebuildable) {\n out(chalk.gray(` Dropping ${describeConflict(conflict)} — it reads a column this push retypes.`));\n }\n await dropGeneratedColumns(databaseUrl, dropGeneratedColumnStatements(rebuildable));\n },\n // Thrown, not exited: an exit from inside runAtlas skipped the\n // rebuild below entirely, so a failed apply left the search\n // columns it had just dropped dropped.\n atlasApply: async () => {\n await runAtlas(\"schema\", [\"apply\", \"--to\", DESIRED_STATE_URL, \"--auto-approve\"], collectionsPath, { throwOnFailure: true, omitPlanEcho: true });\n },\n reportSynced: () => out(\"Schema is synced, no changes to be made\"),\n rebuildAfterFailure: async () => {\n if (!databaseUrl) return;\n out(chalk.gray(\" The apply failed — rebuilding the generated columns it needed out of the way.\"));\n await applySearchDdl(databaseUrl);\n },\n afterApply: async () => {\n out(\"\");\n if (!databaseUrl) {\n outWarn(chalk.yellow(\" ⚠️ DATABASE_URL not found in environment, skipping RLS policies application.\"));\n return;\n }\n // First, before anything below can fail. Atlas has just\n // committed any new table with RLS off and the user role\n // already holding DML on it; every later step may refuse.\n await lockManagedTables(databaseUrl, collectionsPath);\n await ensureAuthTables(databaseUrl, collectionsPath);\n // After the tables exist and before the policies: the vector and\n // search columns are `ALTER TABLE ... ADD COLUMN`, and a policy\n // may reference the table they are added to.\n await applyVectorDdl(databaseUrl);\n await applySearchDdl(databaseUrl);\n await applyTriggersDdl(databaseUrl);\n await applyPolicies(databaseUrl, collectionsPath);\n await reconcilePolicies(databaseUrl, collectionsPath);\n await ensureRlsUserRole(databaseUrl);\n await retireLegacyAuthSchema(databaseUrl);\n }\n });\n } else if (subcommand === \"migrate\") {\n const databaseUrl = process.env.DATABASE_URL;\n // `--baseline <version>` records the version as already applied and\n // starts from the next one. The database a Rebase boot has\n // provisioned is exactly the case it is for, and without it\n // `migrate apply` there is unusable — see `formatBaselineRemedy`,\n // which is what prints when it is missing. Atlas's own `--baseline`\n // does it on a database with no revision history and ignores it in\n // silence on one that has any, so the history is read first and\n // `planBaseline` picks the way that works.\n const baseline = argsList[\"--baseline\"];\n const baselineProblem = baseline ? baselineVersionProblem(baseline, listMigrationFiles()) : null;\n if (baselineProblem) {\n const [message, ...detail] = baselineProblem.split(\"\\n\");\n outError(chalk.red(` ✗ ${message}`));\n for (const line of detail) outError(chalk.gray(` ${line}`));\n throw new CommandStopped(\"The baseline names no migration.\");\n }\n const baselinePlan = baseline\n ? planBaseline(baseline, databaseUrl ? await latestRecordedMigration(databaseUrl) : null)\n : null;\n const atlasBaseline = baselinePlan?.kind === \"atlas-baseline\" ? baseline : undefined;\n // Opt-in, and first: a refused run writes nothing at all. Atlas's\n // own dry-run lists exactly the statements the apply would run, in\n // the files still pending — the same reading `db push` gates on.\n if (argsList[\"--refuse-destructive\"] === true) {\n const plan = await runAtlas(\n \"migrate\",\n [...migrateApplyArgs(argsList._, atlasBaseline), \"--dry-run\"],\n collectionsPath,\n { captureStdout: true }\n );\n const destructive = detectDestructiveStatements(plan, await columnTypesOrNone(databaseUrl), await constraintsOrNone(databaseUrl));\n if (destructive.length > 0) {\n outError(chalk.red(` ✗ Refusing to migrate: the pending migrations include ${destructive.length} destructive change(s):`));\n outError(\"\");\n for (const line of destructiveLines(destructive)) outError(line);\n outError(\"\");\n outError(chalk.gray(\" Nothing was applied. Run `rebase db migrate` without --refuse-destructive to apply them.\"));\n outError(chalk.gray(\" Back up first: rebase db backup\"));\n process.exit(1);\n }\n out(chalk.gray(` --refuse-destructive: ${extractPlanStatements(plan).length} pending statement(s), none destructive.`));\n out(\"\");\n }\n if (databaseUrl) {\n await ensureAuthSchemaAndFunctions(databaseUrl);\n }\n if (baseline && baselinePlan) {\n out(chalk.gray(` ${describeBaselinePlan(baseline, baselinePlan)}`));\n out(\"\");\n if (baselinePlan.kind === \"set\") {\n await runAtlas(\"migrate\", [\"set\", baseline, \"--dir\", \"file://drizzle/migrations\"], collectionsPath);\n }\n }\n await runAtlas(\n \"migrate\",\n migrateApplyArgs(argsList._, atlasBaseline),\n collectionsPath\n );\n if (databaseUrl) {\n await ensureRlsUserRole(databaseUrl);\n await retireLegacyAuthSchema(databaseUrl);\n // As push stamps what it applies, so the first boot after a\n // migrate does not re-apply every policy once.\n const { stampMigratedPolicies } = await import(\"./schema/migrate-policy-stamps\");\n await stampMigratedPolicies(databaseUrl, collectionsPath);\n }\n }\n\n out(\"\");\n out(chalk.green(` ✓ rebase db ${subcommand} completed successfully.`));\n out(\"\");\n }\n}\n\n/**\n * Build, CONCURRENTLY and before Atlas plans, the derived foreign-key indexes\n * an existing table is missing — see `schema/push-index-prebuild.ts`. With\n * `dryRun`, only find them.\n *\n * Never fatal: an index not built here is one Atlas builds inside the push, as\n * it always did.\n *\n * @returns `schema.index` of each one missing when this started.\n */\n/** Renames relation columns that carry their pre-0.13 derived name, as boot does; a dry-run only names them. */\nasync function renameLegacyForeignKeys(databaseUrl: string, collectionsPath: string, dryRun: boolean): Promise<void> {\n let renames: LegacyRename[];\n try {\n const { loadCollections } = await import(\"./schema/doctor\");\n const { legacyForeignKeyRenames } = await import(\"./schema/push-legacy-renames\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n renames = await withAppClient(databaseUrl, client => legacyForeignKeyRenames(\n { query: async (text) => ({ rows: (await client.query(text)).rows }) },\n collections\n ));\n } catch {\n // Not knowing leaves Atlas's plan as it was, and its destructive gate with it.\n return;\n }\n if (renames.length === 0) return;\n out(chalk.gray(dryRun\n ? ` ${renames.length} relation column(s) carry the name Rebase derived before 0.13; a push renames them first,`\n : ` Renaming ${renames.length} relation column(s) that carry the name Rebase derived before 0.13 (data, indexes and`));\n out(chalk.gray(dryRun\n ? \" keeping their data (the plan below still shows them as a drop and an add, because nothing ran):\"\n : \" constraints are kept — the same rename `rebase dev` runs):\"));\n for (const rename of renames) {\n out(chalk.gray(` ${rename.table}: \"${rename.legacy}\" → \"${rename.expected}\"`));\n }\n if (!dryRun) {\n await withAppClient(databaseUrl, async client => {\n for (const rename of renames) await client.query(rename.sql);\n });\n }\n out(chalk.gray(\" To keep an old name instead, name the column on the relation (`localKey`, or `through` on a many-to-many).\"));\n out(\"\");\n}\n\n/** Names the enum labels the database keeps after the collections dropped them. See `schema/enum-labels-kept.ts`. */\nasync function reportKeptEnumLabels(databaseUrl: string, collectionsPath: string): Promise<void> {\n try {\n const { loadCollections } = await import(\"./schema/doctor\");\n const { keptEnumLabels, formatKeptEnumLabelsNotice } = await import(\"./schema/enum-labels-kept\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n const kept = await withAppClient(databaseUrl, client => keptEnumLabels(\n { query: async (text) => ({ rows: (await client.query(text)).rows }) },\n collections\n ));\n if (kept.length > 0) outWarn(chalk.yellow(formatKeptEnumLabelsNotice(kept)));\n } catch {\n // A notice, not a gate: not knowing changes nothing the push does.\n }\n}\n\nasync function prebuildForeignKeyIndexes(databaseUrl: string, collectionsPath: string, dryRun: boolean): Promise<string[]> {\n let missing: DeferredIndexBuild[];\n try {\n const { loadCollections } = await import(\"./schema/doctor\");\n const { missingForeignKeyIndexes } = await import(\"./schema/push-index-prebuild\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n missing = await withAppClient(databaseUrl, client => missingForeignKeyIndexes(\n { query: async (text) => ({ rows: (await client.query(text)).rows }) },\n collections\n ));\n } catch {\n // Not knowing changes nothing that matters: Atlas plans whatever is missing.\n return [];\n }\n const names = missing.map(index => `${index.schema}.${index.indexName}`);\n if (missing.length === 0 || dryRun) return names;\n\n out(chalk.gray(` Building ${missing.length} foreign-key index(es) on existing tables first — CONCURRENTLY, so writes go on:`));\n try {\n const { buildDeferredIndexes } = await import(\"./schema/deferred-index-build\");\n // This process's one connection, which is the dedicated session the\n // builder needs: it lifts `statement_timeout` and resets it, and takes\n // and releases its claims, on the same backend.\n const outcome = await withAppClient(databaseUrl, client => buildDeferredIndexes(\n async () => ({\n dedicated: true,\n query: async (text) => ({ rows: (await client.query(text)).rows }),\n release: () => undefined\n }),\n missing,\n { log: message => out(chalk.gray(` ${message}`)) }\n ));\n for (const failure of outcome.failed) {\n outWarn(chalk.yellow(` ⚠️ ${failure.index} was not built ahead (${failure.error}); the push builds it inside its transaction instead.`));\n }\n } catch (err) {\n outWarn(chalk.yellow(` ⚠️ The foreign-key indexes were not built ahead (${err instanceof Error ? err.message : String(err)}); the push builds them inside its transaction instead.`));\n }\n out(\"\");\n return names;\n}\n\nasync function ensureAuthSchemaAndFunctions(databaseUrl: string): Promise<void> {\n try {\n await withAppClient(databaseUrl, async client => {\n // Creates the `rebase` schema as its first statement, which also\n // covers the schema Atlas puts its revision table in\n // (`--revisions-schema rebase`). That used to need a separate,\n // deliberately migration-stream-excluded statement here, because the\n // helper functions lived in `auth` and creating `rebase` from the\n // preamble would have made Atlas plan a DROP for it. The generator\n // now always declares `rebase` in the desired schema, so there is\n // nothing to keep out.\n await client.query(RLS_BOOTSTRAP_SQL);\n });\n } catch (err) {\n // A database that cannot be reached is the whole answer, in the banner\n // every db command prints for it. As a warning first, it said the same\n // thing twice: `⚠️ Failed to bootstrap the RLS helper functions:\n // connect ECONNREFUSED…`, then the banner from the next step.\n if (isEconnrefused(err) || isAuthFailure(err) || isSslNotEnabled(err)) {\n outError(diagnoseDbError(err, databaseUrl) ?? ` ✗ ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n outWarn(chalk.yellow(` ⚠️ Failed to bootstrap the RLS helper functions: ${err instanceof Error ? err.message : String(err)}`));\n }\n}\n\n/**\n * Switch row-level security on for every table the collections declare, right\n * after Atlas has applied the schema.\n *\n * Atlas cannot carry `ENABLE ROW LEVEL SECURITY` in `schema.sql`: its free tier\n * neither plans it nor reads it back, so a table it creates is born with RLS\n * off — and `rebase_user`, the role every authenticated request runs as, holds\n * DML on it from that moment through the schema's default privileges. RLS used\n * to arrive with the policies, the last step of the push; a refusal from the\n * vector, search or trigger step in between left the new table readable and\n * writable by every caller, with no policy, until a later push or boot fixed\n * it — and a deployment with `REBASE_MIGRATE_ON_BOOT=none` never did. Locked\n * first, a failure later leaves a table that denies, not one that is open.\n *\n * Fatal when a table cannot be locked, and before the steps that follow: the\n * role provisioning at the end re-grants on every table in the schema, which\n * would undo the revoke that is the fallback here.\n */\nasync function lockManagedTables(databaseUrl: string, collectionsPath: string): Promise<void> {\n let unsecured: TableLockResult[\"unsecured\"];\n let userRole: string;\n try {\n const { lockCollectionTables } = await import(\"./schema/ensure-collection-policies\");\n const { loadCollections } = await import(\"./schema/doctor\");\n userRole = (await import(\"./security/rls-enforcement\")).REBASE_USER_ROLE;\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n ({ unsecured } = await withAppClient(databaseUrl, client => lockCollectionTables(\n { query: async (text) => ({ rows: (await client.query(text)).rows }) },\n collections\n )));\n } catch (err) {\n outError(chalk.red(\n `\\n ✗ The schema was applied, but row-level security could not be switched on for its tables: ` +\n `${err instanceof Error ? err.message : String(err)}`\n ));\n outError(chalk.gray(\n \" A table this push created may be readable and writable by every authenticated request\\n\" +\n \" until it is. Re-run `rebase db push` — it locks every collection table before anything else.\"\n ));\n process.exit(1);\n }\n if (unsecured.length === 0) return;\n\n outError(chalk.red(\"\\n ✗ The schema was applied, but row-level security could not be switched on for:\"));\n for (const u of unsecured) {\n outError(chalk.red(` ${u.table}: ${u.error}`));\n outError(chalk.gray(u.grantWithdrawn\n ? ` Its privileges were taken back from ${userRole}, so it is unreachable rather than unprotected.`\n : ` ${userRole} still holds its privileges: every authenticated request can read and write every row.`));\n }\n outError(chalk.gray(\" Nothing after the schema apply ran. Fix the cause — the connection role must own these\\n\" +\n \" tables, or be able to ALTER them — and run `rebase db push` again, or as their owner:\"));\n for (const u of unsecured) {\n const [schema, ...table] = u.table.split(\".\");\n outError(chalk.bold(` ALTER TABLE \"${schema}\".\"${table.join(\".\")}\" ENABLE ROW LEVEL SECURITY;`));\n }\n process.exit(1);\n}\n\n/**\n * Create the framework auth tables (e.g. `rebase.users`) that the generated RLS\n * policies reference, before `applyPolicies` runs. Mirrors what the server does\n * at boot (`PostgresBootstrapper.initializeAuth` → `ensureAuthTablesExist`).\n *\n * Without this, `rebase db push` against a database that has never booted the\n * server fails while applying policies with `relation \"rebase.users\" does not\n * exist` — the documented first-run does `db push` *before* the first `dev`.\n * `ensureAuthTablesExist` is idempotent (CREATE TABLE IF NOT EXISTS), so it is\n * safe to run on every push and harmless once the server has also created them.\n */\nasync function ensureAuthTables(databaseUrl: string, collectionsPath: string): Promise<void> {\n try {\n const { drizzle } = await import(\"drizzle-orm/node-postgres\");\n const { ensureAuthTablesExist } = await import(\"./auth/ensure-tables\");\n const { loadCollections } = await import(\"./schema/doctor\");\n\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n // The auth collection is flagged with `auth: true` or `auth: { enabled: true }`.\n const authCollection = collections.find((c) => {\n const a = c.auth;\n return a === true || (typeof a === \"object\" && a !== null && a.enabled === true);\n });\n\n await withAppClient(databaseUrl, client => ensureAuthTablesExist(drizzle(client), authCollection));\n } catch (err) {\n outWarn(chalk.yellow(` ⚠️ Failed to ensure framework auth tables: ${err instanceof Error ? err.message : String(err)}`));\n }\n}\n\n/**\n * Provision the restricted `rebase_user` role right after schema changes land,\n * so grants cover freshly created tables (default privileges cover future\n * ones). Only needed — and only possible without extra setup — when the\n * connection would bypass RLS (superuser / BYPASSRLS / table owner).\n */\nasync function ensureRlsUserRole(databaseUrl: string): Promise<void> {\n // Every failure in here used to escape uncaught, and `db migrate`'s caller\n // turns that into a bare `process.exit(1)` — so the migration would apply,\n // print `-- ok`, and then the command would die with NO output whatsoever\n // and a non-zero status. Seen with a module-resolution error inside the\n // dynamic import, where the entire diagnosis was one silent exit code.\n //\n // Reported rather than rethrown, and deliberately not fatal: the schema\n // change has already landed at this point, so failing the command implies a\n // rollback that did not happen. What is actually lost is the role\n // provisioning, and the message says so and how to finish it by hand.\n // No `auth`: the RLS helpers live in `rebase` now, and a schema the\n // framework no longer creates must not be granted on — on a Supabase\n // database that would hand the end-user role USAGE on their auth schema.\n const schemas = [\"public\", \"rebase\"];\n let rls: typeof import(\"./security/rls-enforcement\");\n try {\n rls = await import(\"./security/rls-enforcement\");\n } catch (err) {\n // A module-resolution failure here is a build problem, not a database\n // one, and it is exactly the case that used to produce the silent exit.\n outError(chalk.red(\n `\\n ✗ Could not load the RLS provisioning module: ${err instanceof Error ? err.message : String(err)}`\n ));\n return;\n }\n\n try {\n await withAppClient(databaseUrl, async client => {\n const runSql = async (text: string) => (await client.query(text)).rows as Record<string, unknown>[];\n const posture = await rls.detectConnectionPosture(runSql);\n if (posture.privileged) {\n await rls.ensureAppRole(runSql, schemas);\n out(chalk.gray(` ✓ RLS role \"${rls.REBASE_USER_ROLE}\" provisioned/refreshed.`));\n }\n });\n } catch (err) {\n outError(chalk.red(\n `\\n ✗ The schema change was applied, but the \"${rls.REBASE_USER_ROLE}\" role could not be ` +\n `provisioned: ${err instanceof Error ? err.message : String(err)}`\n ));\n outError(chalk.gray(rls.appRoleSetupInstructions(\"your database user\", schemas)));\n }\n}\n\n/**\n * Retire the pre-1.0 `auth` schema, once nothing depends on it any more.\n *\n * Runs last on purpose. Postgres refuses to drop a function an RLS policy still\n * calls, so this only succeeds after the policies above have been rewritten to\n * `rebase.uid()`. See `dropLegacyAuthSchema` for what it reports when something\n * hand-written is still holding the schema open, and DROP_LEGACY_AUTH_SCHEMA_SQL\n * for the guards that keep it off a Supabase `auth` schema.\n */\nasync function retireLegacyAuthSchema(databaseUrl: string): Promise<void> {\n try {\n await withAppClient(databaseUrl, client => dropLegacyAuthSchema(\n async (text) => (await client.query(text)).rows as Record<string, unknown>[],\n {\n info: (m) => out(chalk.gray(` ${m}`)),\n warn: (m) => outWarn(chalk.yellow(` ⚠️ ${m}`))\n }\n ));\n } catch {\n // Connection-level failure only; the schema is inert either way.\n }\n}\n\nasync function applyPolicies(databaseUrl: string, collectionsPath: string): Promise<void> {\n try {\n const policiesPath = path.join(generatedSqlDir(), \"policies.sql\");\n if (!fs.existsSync(policiesPath)) return;\n \n out(chalk.gray(\" Step 3/3: Applying RLS policies to database...\"));\n out(\"\");\n \n const policiesContent = fs.readFileSync(policiesPath, \"utf-8\");\n const stamping = await policyStamping(databaseUrl, collectionsPath, policiesContent);\n const { stampError } = await withAppClient(databaseUrl, client => applyPoliciesFile(client, policiesContent, stamping));\n out(chalk.green(\" ✓ RLS policies applied successfully.\"));\n if (stampError) {\n // The policies are in; only the boot's shortcut is not. See applyPoliciesFile.\n outWarn(chalk.yellow(` ⚠️ The policies could not be stamped (${stampError}); the next boot applies them again.`));\n }\n } catch (err) {\n const hint = diagnoseDbError(err, databaseUrl);\n if (hint) {\n outError(hint);\n } else {\n outError(chalk.red(` ✗ Failed to apply RLS policies: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n}\n\n/**\n * The stamps a boot looks for, for the policies `policies.sql` is about to\n * create — see `applyPoliciesFile`. None when the collections cannot be read\n * here, which costs only the shortcut: the next boot re-applies, as before.\n */\nasync function policyStamping(databaseUrl: string, collectionsPath: string, policiesSql: string): Promise<PolicyStamping> {\n try {\n const { loadCollections } = await import(\"./schema/doctor\");\n const { planCollectionPolicies } = await import(\"./schema/generate-postgres-ddl-logic\");\n const { policyStampSql } = await import(\"./schema/ensure-collection-policies\");\n // The rule the boot's connections follow: `search_path=public` unless\n // the URL pins one of its own, in which case this connection has it too.\n const { pinSearchPath } = await import(\"./connection\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n const statements = stampableTables(planCollectionPolicies(collections), policiesSql)\n .map(plan => policyStampSql(plan))\n .filter((statement): statement is string => statement !== undefined);\n return { statements, searchPath: pinSearchPath(databaseUrl) === databaseUrl ? undefined : \"public\" };\n } catch {\n return { statements: [] };\n }\n}\n\n/**\n * `planPolicyPush` for this database and these collections, read under the\n * `search_path` the push stamps policies under, as the lines the dry run\n * prints and the one the push does; `undefined`, having said why, when it\n * cannot be read.\n */\nasync function readPolicyPushPlan(databaseUrl: string, collectionsPath: string): Promise<{\n changes: string[];\n notes: string[];\n summary: string | null;\n} | undefined> {\n try {\n const { formatPolicyPushPlan, planPolicyPush, summarizePolicyPushPlan } = await import(\"./schema/push-policy-plan\");\n const { loadCollections } = await import(\"./schema/doctor\");\n const { pinSearchPath } = await import(\"./connection\");\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n const plan = await withAppClient(databaseUrl, client => planPolicyPush(\n { query: async (text, values) => ({ rows: (await client.query(text, values)).rows }) },\n collections,\n { searchPath: pinSearchPath(databaseUrl) === databaseUrl ? undefined : \"public\" }\n ));\n return { ...formatPolicyPushPlan(plan), summary: summarizePolicyPushPlan(plan) };\n } catch (err) {\n outWarn(chalk.yellow(` ⚠️ Could not read the database's row-level security: ${err instanceof Error ? err.message : String(err)}`));\n return undefined;\n }\n}\n\n/**\n * Remove the policies an earlier push superseded but never dropped.\n *\n * `policies.sql` only DROPs the names it is about to CREATE, and a rule's\n * generated name contains a hash of its own semantics — so editing a rule\n * writes a *new* policy and abandons the old one. Postgres ORs PERMISSIVE\n * policies together, which makes an abandoned grant outrank every tightening\n * that replaced it, and push reported success the whole time.\n *\n * Runs after `applyPolicies` so the current policies are already in place: the\n * drift check then sees exactly the set that should survive, and anything else\n * on a managed table is by definition left over.\n */\nasync function reconcilePolicies(databaseUrl: string, collectionsPath: string): Promise<void> {\n try {\n const { checkPolicyDrift, dropOrphanedPolicies, formatPolicyDrift, hasDrift } =\n await import(\"./security/policy-drift\");\n const { loadCollections } = await import(\"./schema/doctor\");\n\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n await withAppClient(databaseUrl, async client => {\n const drift = await checkPolicyDrift(client as never, collections);\n const { dropped, kept } = await dropOrphanedPolicies(client as never, drift, collections);\n\n for (const p of dropped) {\n out(chalk.gray(` ✓ Dropped superseded policy \"${p.name}\" on ${p.schema}.${p.table}`));\n }\n if (dropped.length > 0) {\n out(chalk.green(` ✓ Removed ${dropped.length} superseded RLS ${dropped.length === 1 ? \"policy\" : \"policies\"}.`));\n }\n\n // Custom-named orphans are indistinguishable from policies someone\n // wrote in SQL deliberately, so they are reported, never dropped.\n if (kept.length > 0) {\n outWarn(chalk.yellow(\" ⚠️ Policies in the database that no collection describes:\"));\n for (const p of kept) {\n outWarn(chalk.yellow(` • ${p.schema}.${p.table} → \"${p.name}\" (${p.command} TO ${p.roles.join(\", \")})`));\n }\n outWarn(chalk.yellow(\" Each is still in force. To keep one, describe it in its collection's `securityRules`\"));\n outWarn(chalk.yellow(\" (Studio's RLS view imports it); if it is stale, drop it by hand.\"));\n }\n\n // Missing/diverged are not push's to fix, but staying silent about\n // them is how a database ends up not matching its config.\n const remaining = { ...drift, orphaned: kept };\n if (hasDrift(remaining) && (remaining.missing.length > 0 || remaining.diverged.length > 0)) {\n outWarn(chalk.yellow(\" ⚠️ RLS policies do not match your collections:\"));\n outWarn(formatPolicyDrift({ ...remaining, orphaned: [] }));\n }\n });\n } catch (err) {\n outWarn(chalk.yellow(` ⚠️ Could not reconcile RLS policies: ${err instanceof Error ? err.message : String(err)}`));\n }\n}\n\n/**\n * Flags the `branch` subcommands take.\n *\n * Declared as an `arg` spec rather than picked out of argv by hand, which is\n * both how the rest of this file parses flags and how the documentation\n * verifier discovers them: it reads `arg({ … })` specs out of this source, so a\n * flag parsed any other way is one it reports as unrunnable in every page that\n * documents it. Hand-rolled parsing here cost exactly that — `--older-than`\n * worked and the docs check called it a command a reader cannot run.\n */\nconst BRANCH_FLAGS = {\n \"--older-than\": String,\n \"--include-dev-diff\": Boolean,\n \"--from\": String,\n \"--yes\": Boolean,\n \"-y\": \"--yes\"\n} as const;\n\n/** The source `branch create --from <source>` names, if it names one. */\nfunction createSource(rawArgs: readonly string[]): string | undefined {\n const at = rawArgs.indexOf(\"--from\");\n return at !== -1 && rawArgs[at + 1] ? rawArgs[at + 1] : undefined;\n}\n\nasync function branchCommand(rawArgs: string[]): Promise<void> {\n const branchAction = rawArgs[2]; // create, list, delete, info\n\n if (!branchAction || branchAction === \"--help\") {\n printBranchHelp();\n return;\n }\n\n // Before anything connects: a name that is not the name asked for is worth\n // refusing, and it costs a database round-trip to discover later.\n const extras = unexpectedBranchArgs(rawArgs.slice(2));\n // And read from here with its switches' values resolved: `prune` parses\n // permissively, and `arg` reads `--yes=false` as a yes.\n rawArgs = resolveBranchSwitches(rawArgs);\n if (extras.length > 0) {\n outError(\"\");\n outError(chalk.red(` ✗ Unexpected argument${extras.length > 1 ? \"s\" : \"\"}: ${redactConnectionPasswords(extras.join(\" \"))}`));\n outError(\"\");\n outError(chalk.gray(` ${chalk.bold(\"rebase db branch\")} takes one name. A branch name may contain letters,`));\n outError(chalk.gray(\" digits, underscores and hyphens — no spaces.\"));\n if (rawArgs[3]) {\n outError(chalk.gray(` Did you mean: ${chalk.cyan(redactConnectionPasswords(`rebase db branch ${branchAction} ${[rawArgs[3], ...extras].join(\"-\")}`))}`));\n }\n outError(\"\");\n process.exit(1);\n }\n\n // Load .env for DATABASE_URL\n try {\n const dotenv = await import(\"dotenv\");\n const envPath = process.env.DOTENV_CONFIG_PATH;\n if (envPath) {\n dotenv.config({ path: envPath, quiet: true });\n } else {\n dotenv.config({ quiet: true });\n }\n } catch {\n // dotenv may not be installed\n }\n\n const databaseUrl = process.env.DATABASE_URL || process.env.ADMIN_CONNECTION_STRING;\n if (!databaseUrl) {\n outError(chalk.red(\"✗ DATABASE_URL is not set. Make sure your .env file is configured.\"));\n process.exit(1);\n }\n\n // Dynamic imports to avoid loading heavy deps when not needed\n const { DatabasePoolManager } = await import(\"./databasePoolManager\");\n const { BranchService, reopenClosedDatabases, reopenedDatabasesNotice } = await import(\"./services/BranchService\");\n const { drizzle } = await import(\"drizzle-orm/node-postgres\");\n const { Pool } = await import(\"pg\");\n\n // Before anything else, the databases this command can copy from opened\n // again if a forced create was killed with them closed — the main one, a\n // `--from` source, the branch this checkout is on. Every connection below,\n // the check just after this included, would otherwise fail on them.\n const healed = await reopenClosedDatabases(databaseUrl, [\n branchAction === \"create\" ? createSource(rawArgs) : undefined,\n process.env[ACTIVE_BRANCH_DATABASE_ENV]\n ]);\n for (const line of reopenedDatabasesNotice(healed)) outWarn(chalk.yellow(` ${line}`));\n\n // A database that is not running is said the way `db push` says it, not\n // as the Drizzle wrapper of whatever statement met it first.\n await checkDatabaseConnectivity(databaseUrl);\n // …and the probe's connection let go at once. It is the one the other\n // commands keep between steps, and this one does not use it again — while\n // open it is a session on the source database, and `CREATE DATABASE …\n // TEMPLATE` refuses a source with active connections, so every\n // `branch create` failed with \"the source database has active connections\".\n await closeAppClients();\n\n const pool = new Pool({ connectionString: databaseUrl,\nmax: 3 });\n const db = drizzle(pool);\n const poolManager = new DatabasePoolManager(databaseUrl);\n const branchService = new BranchService(db, poolManager);\n\n try {\n // The registry table, for the actions that write to it. `list` and\n // `info` only read, and run no DDL: a database without the table has\n // no branches.\n if (branchAction === \"create\" || branchAction === \"delete\" || branchAction === \"prune\") {\n await branchService.ensureBranchMetadataTable();\n }\n switch (branchAction) {\n case \"create\": {\n const name = rawArgs[3];\n if (!name) {\n outError(chalk.red(\"✗ Branch name is required.\"));\n out(chalk.gray(\" Usage: rebase db branch create <name> [--from <source>]\"));\n process.exit(1);\n }\n const source = createSource(rawArgs);\n const force = rawArgs.includes(\"--force\");\n out(\"\");\n out(chalk.bold(\" 🌿 Creating database branch...\"));\n out(chalk.gray(` Name: ${name}`));\n if (source) out(chalk.gray(` Source: ${source}`));\n if (force) out(chalk.gray(\" Force: other connections to the source will be disconnected\"));\n out(\"\");\n const branch = await branchService.createBranch(name, { source, force });\n out(chalk.green(` ✓ Branch \"${branch.name}\" created successfully.`));\n out(chalk.gray(` Database: rb_${branch.name}`));\n out(chalk.gray(` Parent: ${branch.parentDatabase}`));\n out(\"\");\n break;\n }\n\n case \"list\": {\n const branches = await branchService.hasBranchRegistry() ? await branchService.listBranches() : [];\n out(\"\");\n if (branches.length === 0) {\n out(chalk.gray(\" No branches found. Create one with: rebase db branch create <name>\"));\n } else {\n out(chalk.bold(` 🌿 ${branches.length} branch(es):`));\n out(\"\");\n // The one this checkout is switched to, as the CLI says.\n const current = process.env[ACTIVE_BRANCH_DATABASE_ENV]?.trim();\n for (const b of branches) {\n const size = b.sizeBytes != null\n ? chalk.gray(` (${formatBytes(b.sizeBytes)})`)\n : \"\";\n const age = chalk.gray(` — created ${timeAgo(b.createdAt)}`);\n const here = current && b.database === current ? chalk.cyan(\" (current — this checkout is on it)\") : \"\";\n out(` ${chalk.green(\"●\")} ${chalk.bold(b.name)}${here}${size}${age}`);\n out(chalk.gray(` from ${b.parentDatabase}`));\n }\n }\n out(\"\");\n break;\n }\n\n case \"delete\": {\n const name = rawArgs[3];\n if (!name) {\n outError(chalk.red(\"✗ Branch name is required.\"));\n out(chalk.gray(\" Usage: rebase db branch delete <name>\"));\n process.exit(1);\n }\n out(\"\");\n out(chalk.bold(` 🗑️ Deleting branch \"${name}\"...`));\n await branchService.deleteBranch(name, { force: rawArgs.includes(\"--force\") });\n out(chalk.green(` ✓ Branch \"${name}\" deleted.`));\n out(\"\");\n break;\n }\n\n case \"info\": {\n const name = rawArgs[3];\n if (!name) {\n outError(chalk.red(\"✗ Branch name is required.\"));\n out(chalk.gray(\" Usage: rebase db branch info <name>\"));\n process.exit(1);\n }\n const info = await branchService.hasBranchRegistry() ? await branchService.getBranchInfo(name) : undefined;\n out(\"\");\n if (!info) {\n // Exit 1, like `delete` on a branch that is not there.\n // These two answered the same question — \"is there a branch\n // called this?\" — and disagreed about how to say no: delete\n // failed, info printed `✗ Branch \"x\" not found.` and exited\n // 0. Anything reading the status saw success, so\n // `rebase db branch info \"$b\" && deploy_against \"$b\"` ran\n // the deploy against a branch that does not exist.\n outError(chalk.red(` ✗ Branch \"${name}\" not found.`));\n out(\"\");\n process.exit(1);\n } else {\n out(chalk.bold(` 🌿 Branch: ${info.name}`));\n out(chalk.gray(` Database: rb_${info.name}`));\n out(chalk.gray(` Parent: ${info.parentDatabase}`));\n out(chalk.gray(` Created: ${info.createdAt.toISOString()}`));\n if (info.sizeBytes != null) {\n out(chalk.gray(` Size: ${formatBytes(info.sizeBytes)}`));\n }\n }\n out(\"\");\n break;\n }\n\n case \"prune\": {\n const parsed = arg(BRANCH_FLAGS, { argv: rawArgs.slice(3), permissive: true });\n const olderThanRaw = parsed[\"--older-than\"] ?? null;\n const olderThanDays = olderThanRaw == null ? null : parseOlderThan(olderThanRaw);\n if (olderThanRaw != null && olderThanDays == null) {\n outError(chalk.red(` ✗ --older-than \"${olderThanRaw}\" is not a duration.`));\n out(chalk.gray(\" Use a number of days (14), or 14d / 2w.\"));\n process.exit(1);\n }\n\n const includeDevDiff = parsed[\"--include-dev-diff\"] === true;\n const { rows, databases } = await branchService.pruneCandidates();\n const plan = planPrune({ rows, databases, branchPrefix: \"rb_\" }, {\n olderThanDays,\n activeDatabase: process.env[ACTIVE_BRANCH_DATABASE_ENV]?.trim() || null\n });\n // Kept as `delete` keeps it, and said, whichever way the plan goes.\n const keptActive = (): void => {\n if (!plan.active) return;\n out(` ${chalk.gray(\"○\")} ${chalk.bold(plan.active.name)} ${chalk.gray(\"— this checkout is switched to it, so it is kept\")}`);\n out(chalk.gray(` To prune it, leave it first: ${chalk.cyan(\"rebase db branch switch --off\")}`));\n };\n\n out(\"\");\n if (planIsEmpty(plan, includeDevDiff)) {\n keptActive();\n out(chalk.gray(\" Nothing to prune.\"));\n if (!olderThanDays && rows.length > 0) {\n out(chalk.gray(` ${rows.length} branch(es) are healthy — --older-than 14 also removes old ones.`));\n }\n if (!includeDevDiff && plan.devDiff.length > 0) {\n out(chalk.gray(` ${plan.devDiff.length} Atlas scratch database(s) left over from db push;`));\n out(chalk.gray(\" --include-dev-diff removes those too.\"));\n }\n out(\"\");\n break;\n }\n\n out(chalk.bold(\" 🧹 Prune plan\"));\n out(\"\");\n for (const row of plan.staleRows) {\n out(` ${chalk.yellow(\"○\")} ${chalk.bold(row.name)} ${chalk.gray(\"— registered, but its database is gone; the entry will be removed\")}`);\n }\n for (const dbName of plan.orphanDatabases) {\n out(` ${chalk.yellow(\"○\")} ${chalk.bold(dbName)} ${chalk.gray(\"— a branch database with no entry; the database will be dropped\")}`);\n }\n for (const { branch, ageDays } of plan.expired) {\n out(` ${chalk.red(\"●\")} ${chalk.bold(branch.name)} ${chalk.gray(`— ${ageDays} days old; branch and database will be dropped`)}`);\n }\n keptActive();\n if (includeDevDiff) {\n for (const dbName of plan.devDiff) {\n out(` ${chalk.red(\"●\")} ${chalk.bold(dbName)} ${chalk.gray(\"— Atlas scratch database; will be dropped\")}`);\n }\n } else if (plan.devDiff.length > 0) {\n out(chalk.gray(` (${plan.devDiff.length} Atlas scratch database(s) not listed — --include-dev-diff)`));\n }\n out(\"\");\n\n if (parsed[\"--yes\"] !== true) {\n // Without a terminal nobody can answer, and \"Nothing was\n // changed.\" with exit 0 read as a prune that found nothing\n // to do. Refused, as `db reset` and `db pull` refuse.\n if (!process.stdin.isTTY) {\n outError(chalk.red(\" ✗ Nothing was pruned: there is no terminal to confirm on.\"));\n outError(chalk.gray(\" Re-run with --yes to remove what is listed above.\"));\n outError(\"\");\n process.exit(1);\n }\n // Dropping a database is not undoable and a branch may be\n // the only copy of an afternoon's work.\n const confirmed = await promptConfirm(\" Remove these? (y/N) \");\n if (!confirmed) {\n out(chalk.gray(\" Nothing was changed.\"));\n out(\"\");\n break;\n }\n }\n\n let removed = 0;\n for (const row of plan.staleRows) {\n await branchService.forgetBranchRow(row.name);\n removed += 1;\n }\n for (const dbName of plan.orphanDatabases) {\n await branchService.dropDatabase(dbName);\n removed += 1;\n }\n for (const { branch } of plan.expired) {\n await branchService.deleteBranch(branch.name);\n removed += 1;\n }\n if (includeDevDiff) {\n for (const dbName of plan.devDiff) {\n await branchService.dropDatabase(dbName);\n removed += 1;\n }\n }\n\n out(chalk.green(` ✓ Pruned ${removed} item(s).`));\n out(\"\");\n break;\n }\n\n default:\n outError(chalk.red(`Unknown branch action: \"${branchAction}\".`));\n printBranchHelp();\n process.exit(1);\n }\n } finally {\n await poolManager.shutdown();\n await pool.end();\n }\n}\n\nfunction printBranchHelp() {\n out(`\n${chalk.bold(\"rebase db branch\")} — Database branching commands\n\n${chalk.green.bold(\"Usage\")}\n rebase db branch ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.blue.bold(\"create\")} <name> [--from <source>] Create a new branch\n ${chalk.blue.bold(\"list\")} List all branches\n ${chalk.blue.bold(\"switch\")} [<name>|--off] Point this checkout at a branch\n ${chalk.blue.bold(\"delete\")} <name> Delete a branch\n ${chalk.blue.bold(\"info\")} <name> Show branch details\n ${chalk.blue.bold(\"prune\")} [--older-than <14|14d|2w>] Remove branches nothing is using\n\n${chalk.green.bold(\"Why prune\")}\n Every branch is a full-size copy — CREATE DATABASE ... TEMPLATE duplicates the\n files on disk, so five branches of a 100GB database cost 500GB. Prune also\n finds the two ways branches drift: an entry whose database was dropped\n outside Rebase, and a branch database whose entry never got written.\n\n${chalk.green.bold(\"Options\")}\n ${chalk.blue.bold(\"--force\")} Disconnect other sessions first.\n Postgres refuses to copy or drop a database\n anything else is connected to — usually your\n own \\`rebase dev\\`.\n ${chalk.blue.bold(\"--include-dev-diff\")} Also prune the Atlas scratch databases\n \\`db push\\` leaves behind.\n ${chalk.blue.bold(\"--yes, -y\")} Skip prune's confirmation prompt. Dropping a\n branch is not undoable, so this is the flag\n a CI job passes and a person usually should not.\n\n${chalk.green.bold(\"Examples\")}\n ${chalk.gray(\"# Create a branch and work on it\")}\n rebase db branch create feature_auth\n rebase db branch switch feature_auth\n\n ${chalk.gray(\"# Create a branch from a specific source\")}\n rebase db branch create staging --from production\n\n ${chalk.gray(\"# Remove branches older than two weeks, and anything orphaned\")}\n rebase db branch prune --older-than 2w\n\n ${chalk.gray(\"# List all branches\")}\n rebase db branch list\n\n ${chalk.gray(\"# Delete a branch\")}\n rebase db branch delete feature_auth\n`);\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\n/** A branch's age, for \"…created 6d ago\". */\nfunction timeAgo(date: Date): string {\n // No horizon: a branch created a year ago should still report an age here,\n // rather than fall back to a bare date in a one-line list entry.\n return formatRelativeTime(date, { maxMs: Number.POSITIVE_INFINITY }) ?? \"unknown\";\n}\n\n\n\n/**\n * Whether DATABASE_URL is the managed development database (PGlite), as the\n * CLI resolved it and says in `REBASE_DEV_DATABASE_KIND`.\n */\nfunction managedDatabase(): boolean {\n return process.env.REBASE_DEV_DATABASE_KIND === \"managed\";\n}\n\n/**\n * The Atlas scratch database this process created, dropped once the db\n * command that needed it succeeds — see `ScratchDatabase`.\n */\nconst scratchDatabase = new ScratchDatabase({ create: ensureDevDatabaseExists, drop: dropDevDatabase });\n\nasync function runAtlas(\n domain: \"schema\" | \"migrate\",\n args: string[],\n collectionsPath?: string,\n opts: {\n captureStdout?: boolean;\n /**\n * Throw instead of exiting once the failure has been explained, so a\n * caller with something to put back — the generated columns a push\n * dropped out of Atlas's way — gets to do it. The error is marked\n * `alreadyReported`: everything worth saying is on stderr already.\n */\n throwOnFailure?: boolean;\n /**\n * Show the apply's report without the plan Atlas prints before it —\n * see `schema/atlas-apply-report.ts`. For the apply a push has already\n * planned, which otherwise shows each statement twice.\n */\n omitPlanEcho?: boolean;\n } = {}\n): Promise<string> {\n const atlasBin = resolveLocalBin(\"atlas\");\n if (!atlasBin) {\n // Two very different causes, and the advice for one is a loop for the\n // other — see `diagnoseMissingBin`. This used to say \"Install it with:\n // pnpm add -D @ariga/atlas\" unconditionally, which is the exact command\n // that produces the far more common of the two states.\n outError(chalk.red(\"\\n✗ The atlas binary is missing, so the schema cannot be applied.\\n\"));\n\n // Every remedy below is package-manager specific, and this used to print\n // pnpm's unconditionally. npm 12 blocks a dependency's install scripts\n // the same way pnpm 10 does, so an npm reader was handed `pnpm\n // approve-builds` and a `\"pnpm\"` package.json key — correct advice, for\n // somebody else. Read the lockfile and answer the reader in front of us.\n const manager = detectProjectPackageManager();\n\n const diagnosis = diagnoseMissingBin(\"@ariga/atlas\");\n\n if (diagnosis === \"bin-link-missing\") {\n // The binary IS on disk; only the `node_modules/.bin` shim that\n // points at it is not. pnpm produces this when it writes the link\n // before the script that creates the target (\"Failed to create bin\n // … ENOENT\"), and so does a tree copied without its symlinks.\n // Sending this reader to `approve-builds` does nothing: nothing is\n // blocked.\n outError(chalk.yellow(\" @ariga/atlas and its binary are both on disk — only the\\n\"\n + \" node_modules/.bin/atlas link that puts it on PATH is missing.\\n\"));\n outError(chalk.gray(\n \" Usually a half-written install: the link is created before the script that\\n\"\n + \" downloads the target, so an interrupted or copied tree keeps the binary and\\n\"\n + \" loses the shim.\\n\"\n ));\n outError(\" Fix it with:\\n\");\n outError(chalk.bold(` ${describeReinstallCommand(manager)}\\n`));\n } else if (diagnosis === \"build-script-blocked\") {\n outError(chalk.yellow(\" @ariga/atlas IS installed — only its binary is missing.\\n\"));\n outError(chalk.gray(\n \" It downloads that binary in a `preinstall` script, and pnpm 10+ and npm 12+\\n\" +\n \" do not run a dependency's scripts unless you allow it. The install still\\n\" +\n \" exits 0, so the only sign is a line several screens up: pnpm's\\n\" +\n \" `Ignored build scripts: @ariga/atlas`, or npm's `install scripts blocked`.\\n\"\n ));\n outError(\" Fix it with either:\\n\");\n for (const line of describeBuildScriptRemedy(\"@ariga/atlas\", manager)) {\n outError(line ? chalk.bold(line) : \"\");\n }\n outError(\"\");\n } else {\n outError(chalk.gray(\" It is not installed in this project.\\n\"));\n const member = workspaceMemberDir();\n outError(member === null ? \" Install it with:\\n\" : \" Install it with (from the project root):\\n\");\n outError(chalk.bold(` ${describeDevAddCommand(\"@ariga/atlas\", manager, member)}\\n`));\n outError(chalk.gray(\n \" If the install then reports blocked or ignored build scripts, allow them too —\\n\" +\n \" the package carries a `preinstall` script that fetches the binary.\\n\"\n ));\n }\n process.exit(1);\n }\n\n const env = { ...process.env as Record<string, string> };\n try {\n const dotenv = await import(\"dotenv\");\n const envPaths = [\n process.env.DOTENV_CONFIG_PATH,\n path.resolve(process.cwd(), \".env\"),\n path.resolve(process.cwd(), \"../.env\"),\n path.resolve(process.cwd(), \"../../.env\")\n ].filter(Boolean) as string[];\n\n for (const p of envPaths) {\n if (fs.existsSync(p)) {\n const parsed = dotenv.config({ path: p, quiet: true });\n if (parsed.parsed) {\n for (const [key, val] of Object.entries(parsed.parsed)) {\n if (env[key] === undefined) {\n env[key] = val;\n }\n }\n break;\n }\n }\n }\n } catch {\n // ignore\n }\n\n const databaseUrl = env.DATABASE_URL;\n if (!databaseUrl) {\n outError(chalk.red(\"✗ DATABASE_URL is not set. Make sure your .env file is configured.\"));\n process.exit(1);\n }\n\n // Pre-flight: verify the database is reachable before running Atlas.\n // This catches ECONNREFUSED / auth failures with a friendly banner\n // instead of letting Atlas surface a raw error.\n await checkDatabaseConnectivity(databaseUrl);\n\n let devDatabase: { url: string; named: boolean };\n try {\n devDatabase = atlasDevDatabaseUrl(databaseUrl, env);\n } catch (err) {\n outError(chalk.red(`✗ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n const devDatabaseUrl = devDatabase.url;\n // Only for the calls that plan against it: `migrate apply`, `hash` and\n // `status` never read `--dev-url`, so `db migrate` makes no scratch copy.\n // A database `REBASE_ATLAS_DEV_URL` names is someone else's: not made here.\n if (takesDevUrl(domain, args) && !devDatabase.named) await scratchDatabase.ensure(databaseUrl, devDatabaseUrl);\n\n // Atlas speaks libpq, which rejects the `sslmode=no-verify` that\n // node-postgres accepts, and defaults to `require` where node-postgres\n // asks for no SSL — see `forAtlas`. Rewritten only for the argv, so\n // everything above still connects with the URL as configured.\n const atlasUrl = forAtlas(databaseUrl);\n const atlasDevUrl = forAtlas(devDatabaseUrl);\n\n // Everything Atlas must keep its hands off, in one list.\n //\n // Gathered only for the invocations that accept the flag — which is\n // `schema apply` and nothing else. `atlas migrate diff` and `migrate apply`\n // both reject `--exclude` outright with `unknown flag`, and passing it there\n // took `rebase db generate` and `rebase db migrate` down for every project\n // declaring a `search` block; the diff keeps the same objects out of the\n // migration afterwards instead, with `stripCarvedOutStatements`. See\n // `acceptsExcludeFlag`.\n const excludes: string[] = [];\n if (collectionsPath && acceptsExcludeFlag(domain, args)) {\n // Search and vector objects are Rebase's, not Atlas's: the desired state\n // does not carry them, so an apply left to itself would drop them.\n excludes.push(...await getSearchExcludes(collectionsPath));\n excludes.push(...await getVectorExcludes(collectionsPath));\n excludes.push(...await getTriggerExcludes(collectionsPath));\n\n // Fail CLOSED: the exclude list is the only thing shielding\n // non-collection tables from the auto-approved apply. If we can't\n // introspect the database to build it, abort rather than proceed with\n // a partial list that would let Atlas drop unmanaged tables.\n try {\n excludes.push(...await getTableExcludes(databaseUrl, collectionsPath));\n } catch (err) {\n if (err instanceof ExcludeIntrospectionError) {\n outError(chalk.red(\"\\n✗ Aborting push: could not determine which tables to protect.\"));\n outError(chalk.gray(` ${err.message}`));\n outError(chalk.gray(\" Refusing to apply — a partial exclude list could drop tables Rebase does not manage.\"));\n const hint = diagnoseDbError(err.cause ?? err, databaseUrl);\n if (hint) outError(hint);\n throw new CommandStopped(\"Could not determine which tables to protect.\");\n }\n throw err;\n }\n\n // And the indexes on those tables that Rebase did not create. Same\n // fail-closed contract as the table list above, for the same reason: a\n // partial answer here silently drops somebody's index.\n try {\n excludes.push(...await getForeignIndexExcludes(databaseUrl, collectionsPath));\n } catch (err) {\n if (err instanceof ExcludeIntrospectionError) {\n outError(chalk.red(\"\\n✗ Aborting push: could not determine which indexes to protect.\"));\n outError(chalk.gray(` ${err.message}`));\n outError(chalk.gray(\" Refusing to apply — a partial exclude list could drop an index Rebase does not manage.\"));\n const hint = diagnoseDbError(err.cause ?? err, databaseUrl);\n if (hint) outError(hint);\n throw new CommandStopped(\"Could not determine which indexes to protect.\");\n }\n throw err;\n }\n\n // And the CHECK and EXCLUDE constraints, which a collection cannot\n // declare: left out of the plan, Atlas drops every one of them in the\n // first push after `schema introspect`. Same fail-closed contract.\n try {\n const desiredSqlFile = path.join(generatedSqlDir(), \"schema.sql\");\n const desiredSql = fs.existsSync(desiredSqlFile) ? fs.readFileSync(desiredSqlFile, \"utf-8\") : \"\";\n excludes.push(...await getUndeclaredConstraintExcludes(databaseUrl, desiredSql));\n } catch (err) {\n if (err instanceof ExcludeIntrospectionError) {\n outError(chalk.red(\"\\n✗ Aborting push: could not determine which constraints to protect.\"));\n outError(chalk.gray(` ${err.message}`));\n outError(chalk.gray(\" Refusing to apply — a partial exclude list could drop a CHECK or EXCLUDE constraint the database enforces.\"));\n const hint = diagnoseDbError(err.cause ?? err, databaseUrl);\n if (hint) outError(hint);\n throw new CommandStopped(\"Could not determine which constraints to protect.\");\n }\n throw err;\n }\n }\n\n const atlasArgs = buildAtlasArgs({\n domain, args, url: atlasUrl, devUrl: atlasDevUrl, excludes, singleSession: managedDatabase()\n });\n\n // The managed database is one session every connection shares, so the\n // `search_path` Atlas gives the connection it creates its revisions table\n // on is never applied, and the table lands in `public` while Atlas reads it\n // from `rebase`. Made here, qualified, Atlas finds it where it looks — see\n // `schema/atlas-revisions.ts`.\n if (managedDatabase() && readsRevisions(domain, args)) await ensureAtlasRevisionsTable(databaseUrl);\n\n // On the managed database a connection is the scarce thing. PGlite is one\n // session behind a socket server that accepts only a few, a running\n // `rebase dev` holds some of them, and `schema apply` and `migrate apply`\n // open two each. The one over the limit is closed unanswered, and Atlas\n // says only `Error: EOF`. So the connection this process keeps between\n // steps is let go while Atlas runs; the next step opens another, which\n // locally costs milliseconds.\n if (managedDatabase()) await closeAppClients();\n\n // Stream stdout live but tee stderr so we can inspect Atlas's error text\n // for known, actionable failure modes (e.g. a dependency-drop that leaves\n // the schema half-applied) after the process exits. When capturing (used\n // for the destructive-change dry-run), pipe stdout and collect it instead.\n const subprocess = execa(atlasBin, atlasArgs, {\n cwd: process.cwd(),\n stdout: opts.captureStdout || opts.omitPlanEcho ? \"pipe\" : \"inherit\",\n stderr: \"pipe\",\n env\n });\n let stdoutText = \"\";\n if (opts.captureStdout) {\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n stdoutText += chunk.toString();\n });\n } else if (opts.omitPlanEcho) {\n const report = createApplyReportFilter();\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => process.stdout.write(report.push(chunk.toString())));\n subprocess.stdout?.on(\"end\", () => process.stdout.write(report.flush()));\n }\n let stderrText = \"\";\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stderrText += text;\n // Atlas has the URLs on its command line, and an error such as a URL\n // it cannot parse quotes one back, password and all.\n process.stderr.write(redactConnectionPasswords(text));\n });\n try {\n await subprocess;\n } catch {\n // What Atlas was planning against is the one thing worth reading after\n // its own failure, so the scratch database outlives this command —\n // unless Atlas never got as far as planning, when it holds nothing.\n await scratchDatabase.afterAtlasFailure(stderrText);\n outError(chalk.red(`\\n✗ atlas ${domain} ${args.join(\" \")} failed.\\n`));\n // Surface actionable recovery guidance for recognized failures. The\n // Atlas-shaped ones first: they read the invocation as well as the\n // text, so they can tell `migrate apply` hitting an already-provisioned\n // database (which wants a baseline) from `schema apply` hitting a real\n // conflict. `diagnoseDbError` is the connection-level fallback, shared\n // with the boot path.\n const atlasHint = await diagnoseAtlasFailure({\n domain,\n args,\n stderr: stderrText,\n databaseUrl,\n latestMigrationVersion: latestMigrationVersion(),\n managedDatabase: managedDatabase()\n });\n const hint = atlasHint ?? diagnoseDbError({ message: stderrText }, databaseUrl);\n if (hint) {\n outError(hint);\n }\n if (opts.throwOnFailure) {\n throw Object.assign(new Error(`atlas ${domain} ${args.join(\" \")} failed`), { alreadyReported: true });\n }\n process.exit(1);\n }\n // Atlas prints the plan to stdout, but fall back to stderr so the\n // destructive-change detector never misses a plan on a version/build that\n // routes it differently.\n if (opts.captureStdout) {\n return stdoutText.trim().length > 0 ? stdoutText : stderrText;\n }\n return \"\";\n}\n\nasync function generatePostgresDdlCommand(\n rawArgs: string[],\n options: { retireLegacyCopies?: boolean } = {}\n): Promise<void> {\n const argsList = arg(\n {\n \"--collections\": String,\n \"--output\": String,\n \"-c\": \"--collections\",\n \"-o\": \"--output\"\n },\n {\n argv: rawArgs.slice(2),\n permissive: true\n }\n );\n\n const inProcess = generatesInProcess();\n const ddl = inProcess ? undefined : resolveChildScript(\"generate-postgres-ddl\");\n if (ddl && !ddl.ok) {\n outError(chalk.red(childScriptError(\"DDL generator\", ddl.reason)));\n process.exit(1);\n }\n\n const collectionsPath = argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n const outputPath = argsList[\"--output\"] || path.join(GENERATED_SQL_DIR, \"schema.sql\");\n\n // Only for the default location: an explicit `--output` is somebody's own\n // arrangement, and its directory is theirs to manage.\n if (!argsList[\"--output\"]) {\n const retire = options.retireLegacyCopies !== false;\n const retired = prepareGeneratedSqlDir(process.cwd(), { retire });\n if (retired.length > 0 && !retire) {\n out(chalk.gray(\n ` The next \\`rebase db push\\` or \\`rebase db generate\\` removes the old copies an earlier ` +\n `release committed:\\n ${retired.join(\", \")}`\n ));\n } else if (retired.length > 0) {\n out(chalk.gray(\n ` Generated SQL is written to ${GENERATED_SQL_DIR}/ now, which is not committed. ` +\n `Removed the old copies — commit the deletion:\\n ${retired.join(\", \")}`\n ));\n }\n }\n\n if (!ddl) {\n await generateInProcess(\"Postgres DDL generator\", \"Postgres DDL\", async ({ writePostgresDdl }) => {\n await writePostgresDdl({\n collectionsPath: path.resolve(process.cwd(), collectionsPath),\n outputPath: path.resolve(process.cwd(), outputPath)\n });\n });\n return;\n }\n\n const cmdParts = [\n ddl.bin,\n ...ddl.args,\n `--collections=${collectionsPath}`,\n `--output=${outputPath}`\n ];\n\n try {\n await execa(cmdParts[0], cmdParts.slice(1), {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: { ...process.env as Record<string, string> }\n });\n } catch (err: unknown) {\n // The generator runs with inherited stdio, so on a non-zero exit its\n // own message is already the last useful thing on the terminal and\n // execa's wrapper (\"Command failed with exit code 1: …/tsx …\") would\n // bury it. Repeat it only when the child never got as far as speaking.\n if (typeof (err as { exitCode?: number }).exitCode === \"number\") {\n outError(chalk.red(\"✗ Postgres DDL generation failed — nothing was applied.\"));\n } else {\n outError(chalk.red(`✗ Failed to run Postgres DDL generator: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n}\n\n/**\n * `schema stale [--fix]` — is the generated Drizzle schema older than the rule\n * that derives its foreign-key names?\n *\n * This exists for one upgrade path and is worth the command. 0.13 derives\n * `category_id` where 0.12 derived `categorie_id`; boot-ensure renames the\n * database column to match, and the project's checked-in\n * `backend/src/schema.generated.ts` is then wrong in a way nothing the developer\n * did would explain. Relation validation refuses to boot on it, permanently,\n * because the rename has already been applied and will not run again.\n *\n * `rebase dev` calls this with `--fix` before starting the backend, so the\n * upgrade behaves the way the release note says it does: the column moves and the\n * project keeps working. Without `--fix` it reports and exits non-zero, which is\n * what a build or a CI step wants.\n */\nasync function schemaStaleCommand(rawArgs: string[]): Promise<void> {\n const argsList = arg(\n {\n \"--collections\": String,\n \"--output\": String,\n \"--fix\": Boolean,\n \"-c\": \"--collections\",\n \"-o\": \"--output\",\n // Both spellings, on every command that writes a file. See\n // `OUTPUT_FLAG_ALIASES` in cli-flags.ts.\n \"--out\": \"--output\"\n },\n { argv: rawArgs.slice(2), permissive: true }\n );\n\n const collectionsPath = argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n const outputPath = argsList[\"--output\"] || path.join(\"src\", \"schema.generated.ts\");\n const schemaFile = path.resolve(process.cwd(), outputPath);\n\n const fix = Boolean(argsList[\"--fix\"]);\n const generatedExists = fs.existsSync(schemaFile);\n\n const { loadCollections } = await import(\"./schema/doctor\");\n const { findLegacyForeignKeyNames, compareGeneratedDeclarations, staleVerdict } =\n await import(\"./schema/generated-schema-staleness\");\n const { generateSchema } = await import(\"./schema/generate-drizzle-schema-logic\");\n const { relationalCollections } = await import(\"@rebasepro/common\");\n\n let stale: ReturnType<typeof findLegacyForeignKeyNames> = [];\n let differences: ReturnType<typeof compareGeneratedDeclarations> = [];\n let unreadable: string | undefined;\n if (generatedExists) {\n try {\n const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));\n const onDisk = fs.readFileSync(schemaFile, \"utf8\");\n stale = findLegacyForeignKeyNames(onDisk, collections);\n // The check the command's own summary promises, and the one it did\n // not make: render what these collections generate and compare it,\n // declaration by declaration, with the file on disk. Without this\n // the verdict rested entirely on `findLegacyForeignKeyNames`, which\n // looks for one historical naming defect — so a file the generator\n // visibly rewrites was reported as a match.\n const postgresCollections = relationalCollections(collections);\n if (postgresCollections.length > 0) {\n differences = compareGeneratedDeclarations(generateSchema(postgresCollections), onDisk);\n }\n } catch (err) {\n // Best-effort by design: a collections directory that will not load\n // is a real error, but it is one the boot reports far better than\n // this does. Said out loud all the same — this command used to exit\n // 0 in silence here, which is indistinguishable from a clean run.\n unreadable = err instanceof Error ? err.message : String(err);\n // Imported here, not at the top: the server is a 1.2 MB bundle plus\n // hono, drizzle and zod, and every driver command — `db push`, the\n // two runs in each `rebase dev` start — paid ~0.4 s under tsx to\n // load it before parsing its argv, for this one debug line.\n const { logger } = await import(\"@rebasepro/server\");\n logger.debug(`schema stale: skipped (${unreadable})`);\n }\n }\n\n // The decision lives in `generated-schema-staleness.ts` so it can be tested:\n // this file uses `import.meta`, which the driver's jest suite cannot load,\n // and three of this command's four paths were silent because of it.\n const verdict = staleVerdict({ outputPath, generatedExists, stale, differences, unreadable, fix });\n\n for (const line of verdict.lines) {\n if (!line) out(\"\");\n else if (line.includes(\"⚠️\")) outWarn(chalk.yellow(line));\n else if (verdict.exitCode !== 0) outError(chalk.red(line));\n else if (line.includes(\"✓\")) out(chalk.green(line));\n else out(chalk.gray(line));\n }\n\n if (verdict.exitCode !== 0) process.exit(verdict.exitCode);\n if (!verdict.regenerate) return;\n\n await schemaCommand(\"generate\", [\"schema\", \"generate\", `--collections=${collectionsPath}`, `--output=${outputPath}`]);\n}\n\nasync function schemaCommand(\n subcommand: string,\n rawArgs: string[],\n options: { nextStep?: boolean } = {}\n): Promise<void> {\n // The same second line of defence `dbCommand` above carries, for the same\n // reason: this file is also its own CLI, spawned directly by\n // `resolvePluginCliScript` and executable on its own. Nothing here had a\n // `--help` case, so `schema generate --help` regenerated the schema and\n // `schema introspect --help` rewrote the collection files — a flag whose\n // entire job is to print text, overwriting authored source.\n //\n // Guarded by a real subcommand: the internal callers below re-enter this\n // function with a synthesised argv, and none of them can carry `--help`.\n if (subcommand && (rawArgs.includes(\"--help\") || rawArgs.includes(\"-h\"))) {\n out(\"\");\n out(chalk.bold(` rebase schema ${subcommand}`));\n out(chalk.gray(\" Run `rebase schema --help` for the full page — this is the driver's own entry point.\"));\n out(\"\");\n return;\n }\n\n if (subcommand === \"stale\") {\n await schemaStaleCommand(rawArgs);\n return;\n }\n\n if (subcommand === \"generate\") {\n const argsList = arg(\n {\n \"--collections\": String,\n \"--output\": String,\n \"--watch\": Boolean,\n \"-c\": \"--collections\",\n \"-o\": \"--output\",\n \"--out\": \"--output\",\n \"-w\": \"--watch\"\n },\n {\n argv: rawArgs.slice(2), // db generate ... or schema generate ...\n permissive: true\n }\n );\n\n const collectionsPath = argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n const outputPath = argsList[\"--output\"] || path.join(\"src\", \"schema.generated.ts\");\n const watch = argsList[\"--watch\"] || false;\n\n // One-shot generation runs here, in this process: see `generate-files.ts`.\n // `--watch` keeps its own process, which re-imports the collections on\n // every save — this process's module cache would not.\n if (!watch && generatesInProcess()) {\n out(\"\");\n out(chalk.bold(\" 🔧 Rebase Schema Generator\"));\n out(\"\");\n await generateInProcess(\"schema generator\", \"Drizzle schema\", async ({ writeDrizzleSchema }) => {\n await writeDrizzleSchema({\n collectionsPath: path.resolve(process.cwd(), collectionsPath),\n outputPath: path.resolve(process.cwd(), outputPath),\n nextStep: options.nextStep\n });\n });\n return;\n }\n\n // Here we just invoke the local generate-drizzle-schema.ts since we are inside the postgresql-backend\n // If installed in node_modules, __cliDirname is node_modules/@rebasepro/server-postgres/dist or src.\n const generator = resolveChildScript(\"generate-drizzle-schema\");\n if (!generator.ok) {\n outError(chalk.red(childScriptError(\"schema generator\", generator.reason)));\n process.exit(1);\n }\n\n out(\"\");\n out(chalk.bold(\" 🔧 Rebase Schema Generator\"));\n out(\"\");\n\n const cmdParts = [\n generator.bin,\n ...generator.args,\n `--collections=${collectionsPath}`,\n `--output=${outputPath}`\n ];\n if (watch) {\n cmdParts.push(\"--watch\");\n }\n if (options.nextStep === false) {\n cmdParts.push(\"--no-next-step\");\n }\n\n try {\n await execa(cmdParts[0], cmdParts.slice(1), {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: { ...process.env as Record<string, string> }\n });\n } catch (err: unknown) {\n // Same contract as the DDL generator above: a child that exited\n // non-zero has already printed the cause on inherited stdio.\n if (typeof (err as { exitCode?: number }).exitCode === \"number\") {\n outError(chalk.red(\"✗ Drizzle schema generation failed — nothing was applied.\"));\n } else {\n outError(chalk.red(`✗ Failed to run schema generator: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n } else if (subcommand === \"introspect\") {\n const argsList = arg(\n {\n \"--output\": String,\n \"--collections\": String,\n \"--force\": Boolean,\n \"--schema\": String,\n \"--data-inference\": Boolean,\n \"--no-data-inference\": Boolean,\n \"-o\": \"--output\",\n \"--out\": \"--output\",\n \"-c\": \"--collections\",\n \"-f\": \"--force\"\n },\n {\n argv: rawArgs.slice(2),\n permissive: true\n }\n );\n\n const introspect = resolveChildScript(\"introspect-db\");\n if (!introspect.ok) {\n outError(chalk.red(childScriptError(\"introspection script\", introspect.reason)));\n process.exit(1);\n }\n\n const outputPath = argsList[\"--output\"] || argsList[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n\n out(\"\");\n out(chalk.bold(\" 🔍 Rebase Schema Introspector\"));\n out(\"\");\n\n const cmdParts = [\n introspect.bin,\n ...introspect.args,\n `--output=${outputPath}`,\n ...(argsList[\"--force\"] ? [\"--force\"] : []),\n ...(argsList[\"--schema\"] ? [`--schema=${argsList[\"--schema\"]}`] : []),\n // The introspector reads these itself; without one it asks.\n ...(argsList[\"--data-inference\"] ? [\"--data-inference\"] : []),\n ...(argsList[\"--no-data-inference\"] ? [\"--no-data-inference\"] : [])\n ];\n\n try {\n await execa(cmdParts[0], cmdParts.slice(1), {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: { ...process.env as Record<string, string> }\n });\n } catch (err: unknown) {\n // A child that ran and exited non-zero already said why, through\n // the inherited stdio; repeating execa's \"Command failed with exit\n // code 1: node --import …\" under it only buried that. A child that\n // never started printed nothing, so that one is said here.\n const exitCode = typeof err === \"object\" && err !== null ? Reflect.get(err, \"exitCode\") : undefined;\n if (typeof exitCode !== \"number\") {\n outError(chalk.red(`✗ Failed to run schema introspector: ${err instanceof Error ? err.message : String(err)}`));\n }\n process.exit(1);\n }\n } else {\n outError(chalk.red(\"Unknown schema command.\"));\n process.exit(1);\n }\n}\n\nasync function doctorPluginCommand(rawArgs: string[]): Promise<void> {\n const parsedArgs = arg(\n {\n \"--collections\": String,\n \"--schema\": String,\n \"--sdk\": String,\n \"--policies\": Boolean,\n \"-c\": \"--collections\",\n \"-s\": \"--schema\",\n \"-k\": \"--sdk\"\n },\n {\n argv: rawArgs.slice(1), // skip \"doctor\"\n permissive: true\n }\n );\n\n const doctor = resolveChildScript(\"doctor-cli\");\n if (!doctor.ok) {\n outError(chalk.red(childScriptError(\"doctor script\", doctor.reason)));\n process.exit(1);\n }\n\n const collectionsPath = parsedArgs[\"--collections\"] || path.join(\"..\", \"config\", \"collections\");\n const schemaPath = parsedArgs[\"--schema\"] || path.join(\"src\", \"schema.generated.ts\");\n const sdkPath = parsedArgs[\"--sdk\"] || path.join(\"..\", \"generated\", \"sdk\", \"database.types.ts\");\n\n const cmdParts = [\n doctor.bin,\n ...doctor.args,\n `--collections=${collectionsPath}`,\n `--schema=${schemaPath}`,\n `--sdk=${sdkPath}`,\n // Only the RLS checks: skips the schema/SDK diff, so it can run against\n // a deployed database as a CI gate.\n ...(parsedArgs[\"--policies\"] ? [\"--policies\"] : [])\n ];\n\n try {\n await execa(cmdParts[0], cmdParts.slice(1), {\n cwd: process.cwd(),\n stdio: \"inherit\",\n env: { ...process.env as Record<string, string> }\n });\n } catch {\n process.exit(1);\n }\n}\n\n\n// Entry point when called directly\nconst argv1Real = process.argv[1] ? fs.realpathSync(process.argv[1]) : \"\";\nif (import.meta.url === `file://${argv1Real}`) {\n // Drop node and script path\n runPluginCommand(process.argv.slice(2)).catch((error: unknown) => {\n reportCommandFailure(error);\n process.exit(1);\n });\n}\n"],"mappings":"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"}