@rebasepro/server-postgres 0.25.1 → 0.26.0
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.
- package/dist/{BranchService-ClklxyAQ.js → BranchService-CWBnDhcv.js} +25 -9
- package/dist/BranchService-CWBnDhcv.js.map +1 -0
- package/dist/PostgresBackendDriver.d.ts +13 -0
- package/dist/PostgresBootstrapper.d.ts +7 -0
- package/dist/auth/services.d.ts +8 -1
- package/dist/auth/verify-auth-tables.d.ts +21 -0
- package/dist/{backup-cli-gijeXe0u.js → backup-cli-PoRG-zEq.js} +3 -3
- package/dist/{backup-cli-gijeXe0u.js.map → backup-cli-PoRG-zEq.js.map} +1 -1
- package/dist/{boot-ddl-DYH95Qeg.js → boot-ddl-EsgqDkx0.js} +2 -2
- package/dist/{boot-ddl-DYH95Qeg.js.map → boot-ddl-EsgqDkx0.js.map} +1 -1
- package/dist/branch-diff-CxE4VlxT.js +1396 -0
- package/dist/branch-diff-CxE4VlxT.js.map +1 -0
- package/dist/branch-diff-report-DpvVf7hR.js +48 -0
- package/dist/branch-diff-report-DpvVf7hR.js.map +1 -0
- package/dist/branching/branch-diff-report.d.ts +7 -0
- package/dist/branching/branch-diff.d.ts +115 -0
- package/dist/{cli-console-CQrQ0lAY.js → cli-console-f0k6_TsJ.js} +38 -5
- package/dist/cli-console-f0k6_TsJ.js.map +1 -0
- package/dist/cli-console.d.ts +17 -1
- package/dist/{cli-errors-DiA0XFIS.js → cli-errors-DsYyNYzd.js} +53 -2
- package/dist/cli-errors-DsYyNYzd.js.map +1 -0
- package/dist/cli.js +102 -122
- package/dist/cli.js.map +1 -1
- package/dist/{collections-schema-version-T6cGvrDi.js → collections-schema-version-D7bDI0PJ.js} +13 -9
- package/dist/collections-schema-version-D7bDI0PJ.js.map +1 -0
- package/dist/{deferred-index-build-BE0I6sYU.js → deferred-index-build-CqaOv1Xx.js} +3 -3
- package/dist/{deferred-index-build-BE0I6sYU.js.map → deferred-index-build-CqaOv1Xx.js.map} +1 -1
- package/dist/{doctor-BT--1kq3.js → doctor-DW_mlTzz.js} +81 -33
- package/dist/doctor-DW_mlTzz.js.map +1 -0
- package/dist/{ensure-collection-policies-BnGOURpG.js → ensure-collection-policies-DLWgabQ2.js} +5 -5
- package/dist/{ensure-collection-policies-BnGOURpG.js.map → ensure-collection-policies-DLWgabQ2.js.map} +1 -1
- package/dist/{ensure-collection-tables-Cet4650m.js → ensure-collection-tables-CFIRq8ni.js} +5 -5
- package/dist/{ensure-collection-tables-Cet4650m.js.map → ensure-collection-tables-CFIRq8ni.js.map} +1 -1
- package/dist/{ensure-tables-l_OgFQjN.js → ensure-tables-4nA-tfwi.js} +4 -4
- package/dist/{ensure-tables-l_OgFQjN.js.map → ensure-tables-4nA-tfwi.js.map} +1 -1
- package/dist/{enum-labels-kept-nheku1pB.js → enum-labels-kept-PcPW65xy.js} +2 -2
- package/dist/{enum-labels-kept-nheku1pB.js.map → enum-labels-kept-PcPW65xy.js.map} +1 -1
- package/dist/history/HistoryService.d.ts +7 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.es.js +226 -8
- package/dist/index.es.js.map +1 -1
- package/dist/{db-subcommands-BPoHCxJR.js → migrate-baseline-B-2Ef4Mv.js} +266 -41
- package/dist/migrate-baseline-B-2Ef4Mv.js.map +1 -0
- package/dist/{migrate-policy-stamps-3eqfhes6.js → migrate-policy-stamps-BQtFHApx.js} +5 -5
- package/dist/{migrate-policy-stamps-3eqfhes6.js.map → migrate-policy-stamps-BQtFHApx.js.map} +1 -1
- package/dist/{open-rebase-EmqVmS14.js → open-rebase-C8jQ6s5a.js} +292 -46
- package/dist/open-rebase-C8jQ6s5a.js.map +1 -0
- package/dist/open-rebase.d.ts +9 -1
- package/dist/{pg-error-utils-CFEnm2m9.js → pg-error-utils-DhiUTlVx.js} +2 -2
- package/dist/{pg-error-utils-CFEnm2m9.js.map → pg-error-utils-DhiUTlVx.js.map} +1 -1
- package/dist/{push-index-prebuild-COd7i6wm.js → push-index-prebuild-UTvB5pqH.js} +3 -3
- package/dist/{push-index-prebuild-COd7i6wm.js.map → push-index-prebuild-UTvB5pqH.js.map} +1 -1
- package/dist/push-kept-defaults-BGOlOqRQ.js +137 -0
- package/dist/push-kept-defaults-BGOlOqRQ.js.map +1 -0
- package/dist/{push-legacy-renames-CLgYYwPE.js → push-legacy-renames-BwaKi8xF.js} +3 -3
- package/dist/{push-legacy-renames-CLgYYwPE.js.map → push-legacy-renames-BwaKi8xF.js.map} +1 -1
- package/dist/{push-policy-plan-D2gpQsdv.js → push-policy-plan-DQ2tWceD.js} +2 -2
- package/dist/{push-policy-plan-D2gpQsdv.js.map → push-policy-plan-DQ2tWceD.js.map} +1 -1
- package/dist/{rls-enforcement-DDyNoOSy.js → rls-enforcement-BOHuHVlc.js} +42 -3
- package/dist/rls-enforcement-BOHuHVlc.js.map +1 -0
- package/dist/schema/destructive-sql.d.ts +16 -0
- package/dist/schema/doctor-cli.js +3 -3
- package/dist/schema/introspect-db.js +1 -1
- package/dist/schema/migration-freshness.d.ts +69 -0
- package/dist/schema/push-kept-defaults.d.ts +57 -0
- package/dist/schema/rls-bootstrap-sql.d.ts +47 -10
- package/dist/security/rls-enforcement.d.ts +18 -0
- package/dist/services/FetchService.d.ts +12 -0
- package/dist/services/channel-presence.d.ts +3 -1
- package/dist/services/nested-path.d.ts +16 -0
- package/dist/services/realtimeService.d.ts +18 -1
- package/dist/{websocket-BKZwsjmf.js → websocket-CKYc3V4N.js} +41 -12
- package/dist/websocket-CKYc3V4N.js.map +1 -0
- package/package.json +7 -7
- package/dist/BranchService-ClklxyAQ.js.map +0 -1
- package/dist/cli-console-CQrQ0lAY.js.map +0 -1
- package/dist/cli-errors-DiA0XFIS.js.map +0 -1
- package/dist/collections-schema-version-T6cGvrDi.js.map +0 -1
- package/dist/db-subcommands-BPoHCxJR.js.map +0 -1
- package/dist/doctor-BT--1kq3.js.map +0 -1
- package/dist/open-rebase-EmqVmS14.js.map +0 -1
- package/dist/rls-enforcement-DDyNoOSy.js.map +0 -1
- package/dist/websocket-BKZwsjmf.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "module";
|
|
2
2
|
__createRequire(import.meta.url);
|
|
3
3
|
import { n as require_arg, o as __toESM, t as promptConfirm } from "./cli-prompt-DXG0yk-h.js";
|
|
4
|
-
import { A as getUndeclaredConstraintExcludes, B as withAppClient, C as dropDevDatabase, D as getSearchExcludes, E as getForeignIndexExcludes, F as queryUndeclarableConstraints, G as prepareGeneratedSqlDir, H as DESIRED_STATE_URL, I as readSearchDdl, J as detectDestructiveStatements, K as decidePushSafety, L as readTriggersDdl, M as loadCollectionsForCli, N as queryColumnTypes, O as getTableExcludes, P as queryGeneratedColumnDependencies, Q as
|
|
4
|
+
import { $ as forAtlas, A as getUndeclaredConstraintExcludes, B as withAppClient, C as dropDevDatabase, D as getSearchExcludes, E as getForeignIndexExcludes, F as queryUndeclarableConstraints, G as prepareGeneratedSqlDir, H as DESIRED_STATE_URL, I as readSearchDdl, J as detectDestructiveStatements, K as decidePushSafety, L as readTriggersDdl, M as loadCollectionsForCli, N as queryColumnTypes, O as getTableExcludes, P as queryGeneratedColumnDependencies, Q as warnIfYesApprovedDestructive, R as readVectorDdl, S as diagnoseMissingBin, T as ensureDevDatabaseExists, U as GENERATED_SQL_DIR, V as workspaceMemberDir, W as generatedSqlDir, X as fromAlterTable, Y as extractPlanStatements, Z as isSyncedPlan, _ as closeAppClients, a as diagnoseDbError, b as describeReinstallCommand, c as isEconnrefused, d as reportCommandFailure, f as ExcludeIntrospectionError, g as atlasDevDatabaseUrl, h as applyVectorDdl, i as diagnoseAtlasFailure, j as getVectorExcludes, k as getTriggerExcludes, l as isSslNotEnabled, m as applyTriggersDdl, o as formatForeignGeneratedColumnBanner, p as applySearchDdl, q as destructiveOptInFlag, s as isAuthFailure, t as checkDatabaseConnectivity, tt as redactConnectionPasswords, v as describeBuildScriptRemedy, w as dropGeneratedColumns, x as detectProjectPackageManager, y as describeDevAddCommand, z as resolveLocalBin } from "./cli-errors-DsYyNYzd.js";
|
|
5
5
|
import { a as outWarn, i as outError, o as atlasExcludePattern, r as out, s as excludePatternParts, t as chalk } from "./source-fZb92pN8.js";
|
|
6
6
|
import { t as nextStepAfterDbGenerate } from "./generate-next-step-DgK5BlBn.js";
|
|
7
|
-
import {
|
|
7
|
+
import { S as dropLegacyAuthSchema, T as execa, b as RLS_BOOTSTRAP_SQL, c as isDriverDbSubcommand, d as resolveBranchSwitches, f as unexpectedBranchArgs, g as collectionsPathIn, i as latestRecordedMigration, l as backupActionOf, m as assertKnownFlags, o as planBaseline, r as describeBaselinePlan, s as DRIVER_DB_SUBCOMMANDS, t as baselineVersionProblem, v as parseDriverLine, y as resolveDriverSwitches } from "./migrate-baseline-B-2Ef4Mv.js";
|
|
8
8
|
import { formatRelativeTime } from "@rebasepro/utils";
|
|
9
9
|
import path from "path";
|
|
10
10
|
import fs from "fs";
|
|
@@ -890,102 +890,6 @@ var CommandStopped = class extends Error {
|
|
|
890
890
|
}
|
|
891
891
|
};
|
|
892
892
|
//#endregion
|
|
893
|
-
//#region src/schema/migrate-baseline.ts
|
|
894
|
-
/**
|
|
895
|
-
* What `rebase db migrate --baseline <version>` does, given the history the
|
|
896
|
-
* database already has.
|
|
897
|
-
*
|
|
898
|
-
* The flag promises to record `<version>` as applied and migrate from the next
|
|
899
|
-
* one. Atlas's own `migrate apply --baseline` keeps that promise only on a
|
|
900
|
-
* database with no revision history: once one row exists it ignores the flag
|
|
901
|
-
* without a word, applies the migration anyway, and the CLI had already printed
|
|
902
|
-
* "Recording … as already applied". That is the normal second time: a project
|
|
903
|
-
* baselines once, then `rebase dev` adds a column at boot, `db generate` writes
|
|
904
|
-
* the migration for it, and `db migrate` fails on `column … already exists
|
|
905
|
-
* (42701)` however the baseline is spelled.
|
|
906
|
-
*
|
|
907
|
-
* So the history is read first. With none, Atlas's baseline does the work.
|
|
908
|
-
* Behind `<version>`, `atlas migrate set` marks every migration up to it as
|
|
909
|
-
* applied, which is what a baseline means. At or past it, there is nothing to
|
|
910
|
-
* record, and the command says so instead of claiming it recorded something.
|
|
911
|
-
*/
|
|
912
|
-
/**
|
|
913
|
-
* Atlas's version order for the versions Rebase writes: numeric timestamps,
|
|
914
|
-
* compared as numbers so a shorter one is not read as later; anything else as
|
|
915
|
-
* text.
|
|
916
|
-
*/
|
|
917
|
-
function compareMigrationVersions(a, b) {
|
|
918
|
-
if (/^\d+$/.test(a) && /^\d+$/.test(b)) {
|
|
919
|
-
const x = BigInt(a);
|
|
920
|
-
const y = BigInt(b);
|
|
921
|
-
return x === y ? 0 : x < y ? -1 : 1;
|
|
922
|
-
}
|
|
923
|
-
return a.localeCompare(b);
|
|
924
|
-
}
|
|
925
|
-
/**
|
|
926
|
-
* The version Atlas records for a migration file: its numeric prefix
|
|
927
|
-
* (`20260906101530_init.sql` → `20260906101530`), or the name without `.sql`.
|
|
928
|
-
*/
|
|
929
|
-
function migrationVersionOf(file) {
|
|
930
|
-
return /^(\d+)/.exec(file)?.[1] ?? file.replace(/\.sql$/, "");
|
|
931
|
-
}
|
|
932
|
-
/** How many versions a refused baseline names, newest last. */
|
|
933
|
-
var VERSIONS_NAMED = 5;
|
|
934
|
-
/**
|
|
935
|
-
* Why `--baseline <version>` cannot run, or `null` when it names a migration
|
|
936
|
-
* file in `drizzle/migrations`.
|
|
937
|
-
*
|
|
938
|
-
* Asked before anything else, the database included. A version no file has
|
|
939
|
-
* was refused only by Atlas, after the command had said "Marking every
|
|
940
|
-
* migration up to abc as applied…"; and one older than every file read
|
|
941
|
-
* "Nothing to record" and migrated on, though it named nothing to baseline.
|
|
942
|
-
*
|
|
943
|
-
* @param files the migration files, sorted oldest first.
|
|
944
|
-
* @returns the refusal, its first line the error and the rest the detail.
|
|
945
|
-
*/
|
|
946
|
-
function baselineVersionProblem(version, files) {
|
|
947
|
-
const versions = files.map(migrationVersionOf);
|
|
948
|
-
if (versions.length === 0) return `--baseline ${version}: There are no migrations in drizzle/migrations to baseline. Nothing was run.\nRun \`rebase db generate\` to write the first one.`;
|
|
949
|
-
if (versions.includes(version)) return null;
|
|
950
|
-
const named = versions.slice(-5).join(", ");
|
|
951
|
-
return `--baseline ${version} names no migration in drizzle/migrations. Nothing was run.\n${versions.length > VERSIONS_NAMED ? `The newest ${VERSIONS_NAMED} of the ${versions.length} versions there` : "The versions there"}: ${named}. A baseline is one of them: the newest migration the database already holds.`;
|
|
952
|
-
}
|
|
953
|
-
/** How to keep `--baseline <version>`'s promise, given the newest recorded version. */
|
|
954
|
-
function planBaseline(version, latestRecorded) {
|
|
955
|
-
if (latestRecorded === null) return { kind: "atlas-baseline" };
|
|
956
|
-
if (compareMigrationVersions(version, latestRecorded) > 0) return {
|
|
957
|
-
kind: "set",
|
|
958
|
-
latest: latestRecorded
|
|
959
|
-
};
|
|
960
|
-
return {
|
|
961
|
-
kind: "already-recorded",
|
|
962
|
-
latest: latestRecorded
|
|
963
|
-
};
|
|
964
|
-
}
|
|
965
|
-
/** What the command says before it migrates, for each plan. */
|
|
966
|
-
function describeBaselinePlan(version, plan) {
|
|
967
|
-
switch (plan.kind) {
|
|
968
|
-
case "atlas-baseline": return `Recording ${version} as already applied, then migrating from the next one.`;
|
|
969
|
-
case "set": return `This database already records migrations up to ${plan.latest}, and Atlas applies --baseline only to a database with none.\n Marking every migration up to ${version} as applied with \`atlas migrate set\`, then migrating from the next one.`;
|
|
970
|
-
case "already-recorded": return `Nothing to record: this database already records migrations up to ${plan.latest}, which includes ${version}.\n Migrating from the next one.`;
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
/**
|
|
974
|
-
* The newest version Atlas has recorded on this database, or `null` when it
|
|
975
|
-
* has recorded none (no revisions table yet included).
|
|
976
|
-
*
|
|
977
|
-
* The table is `rebase.atlas_schema_revisions`: the CLI passes
|
|
978
|
-
* `--revisions-schema rebase` to every `migrate apply`.
|
|
979
|
-
*/
|
|
980
|
-
async function latestRecordedMigration(databaseUrl) {
|
|
981
|
-
return withAppClient(databaseUrl, async (client) => {
|
|
982
|
-
if (!(await client.query("SELECT to_regclass('rebase.atlas_schema_revisions') IS NOT NULL AS present")).rows[0]?.present) return null;
|
|
983
|
-
const versions = (await client.query("SELECT version FROM rebase.atlas_schema_revisions WHERE version NOT LIKE '.%'")).rows.map((row) => row.version);
|
|
984
|
-
if (versions.length === 0) return null;
|
|
985
|
-
return versions.reduce((latest, version) => compareMigrationVersions(version, latest) > 0 ? version : latest);
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
//#endregion
|
|
989
893
|
//#region src/cli-push.ts
|
|
990
894
|
/**
|
|
991
895
|
* Apply a planned push.
|
|
@@ -1348,7 +1252,7 @@ async function runPluginCommand(args) {
|
|
|
1348
1252
|
else if (domain === "schema") await schemaCommand(subcommand, args);
|
|
1349
1253
|
else if (domain === "doctor") await doctorPluginCommand(args);
|
|
1350
1254
|
else if (domain === "console") {
|
|
1351
|
-
const { consoleCommand } = await import("./cli-console-
|
|
1255
|
+
const { consoleCommand } = await import("./cli-console-f0k6_TsJ.js");
|
|
1352
1256
|
process.exitCode = await consoleCommand(args);
|
|
1353
1257
|
} else {
|
|
1354
1258
|
outError(chalk.red(`Unknown domain command: ${domain}`));
|
|
@@ -1515,7 +1419,7 @@ async function dbCommand(subcommand, rawArgs) {
|
|
|
1515
1419
|
return;
|
|
1516
1420
|
}
|
|
1517
1421
|
if (subcommand === "backup" || subcommand === "restore" || subcommand === "backups") {
|
|
1518
|
-
const { backupCommand, restoreCommand, backupsCommand } = await import("./backup-cli-
|
|
1422
|
+
const { backupCommand, restoreCommand, backupsCommand } = await import("./backup-cli-PoRG-zEq.js").then((n) => n.t);
|
|
1519
1423
|
if (subcommand === "backup" && backupActionOf(rawArgs) === "list") await backupsCommand(rawArgs);
|
|
1520
1424
|
else if (subcommand === "backup") await backupCommand(rawArgs);
|
|
1521
1425
|
else if (subcommand === "restore") await restoreCommand(rawArgs);
|
|
@@ -1636,6 +1540,7 @@ async function dbCommand(subcommand, rawArgs) {
|
|
|
1636
1540
|
if (databaseUrl && !dryRun) await ensureAuthSchemaAndFunctions(databaseUrl);
|
|
1637
1541
|
if (databaseUrl) await renameLegacyForeignKeys(databaseUrl, collectionsPath, dryRun);
|
|
1638
1542
|
const prebuilt = databaseUrl ? await prebuildForeignKeyIndexes(databaseUrl, collectionsPath, dryRun) : [];
|
|
1543
|
+
if (databaseUrl) await keepDatabaseOwnedDefaults(databaseUrl, collectionsPath);
|
|
1639
1544
|
const plan = await runAtlas("schema", [
|
|
1640
1545
|
"apply",
|
|
1641
1546
|
"--to",
|
|
@@ -1700,6 +1605,7 @@ async function dbCommand(subcommand, rawArgs) {
|
|
|
1700
1605
|
for (const line of destructiveLines(destructive)) outWarn(line);
|
|
1701
1606
|
outWarn("");
|
|
1702
1607
|
outWarn(chalk.yellow(" Applying them needs `rebase db push --allow-destructive`. Back up first: rebase db backup"));
|
|
1608
|
+
outWarn(chalk.gray(" (`--yes` still approves them in this release, with a deprecation warning; from the next it will not.)"));
|
|
1703
1609
|
outWarn("");
|
|
1704
1610
|
}
|
|
1705
1611
|
out(chalk.gray(" The auth schema step was skipped, because it writes. A real push runs it first."));
|
|
@@ -1734,7 +1640,10 @@ async function dbCommand(subcommand, rawArgs) {
|
|
|
1734
1640
|
out(chalk.gray(" Aborted. No changes were made."));
|
|
1735
1641
|
throw new CommandStopped("The destructive push was declined.");
|
|
1736
1642
|
}
|
|
1737
|
-
} else
|
|
1643
|
+
} else {
|
|
1644
|
+
outWarn(chalk.yellow(` Proceeding because ${optIn ?? "--allow-destructive"} was passed.`));
|
|
1645
|
+
warnIfYesApprovedDestructive(optIn, destructive.length);
|
|
1646
|
+
}
|
|
1738
1647
|
}
|
|
1739
1648
|
if (policyPlan?.summary) {
|
|
1740
1649
|
out(chalk.gray(policyPlan.summary));
|
|
@@ -1825,7 +1734,7 @@ async function dbCommand(subcommand, rawArgs) {
|
|
|
1825
1734
|
if (databaseUrl) {
|
|
1826
1735
|
await ensureRlsUserRole(databaseUrl);
|
|
1827
1736
|
await retireLegacyAuthSchema(databaseUrl);
|
|
1828
|
-
const { stampMigratedPolicies } = await import("./migrate-policy-stamps-
|
|
1737
|
+
const { stampMigratedPolicies } = await import("./migrate-policy-stamps-BQtFHApx.js");
|
|
1829
1738
|
await stampMigratedPolicies(databaseUrl, collectionsPath);
|
|
1830
1739
|
}
|
|
1831
1740
|
}
|
|
@@ -1844,12 +1753,43 @@ async function dbCommand(subcommand, rawArgs) {
|
|
|
1844
1753
|
*
|
|
1845
1754
|
* @returns `schema.index` of each one missing when this started.
|
|
1846
1755
|
*/
|
|
1756
|
+
/**
|
|
1757
|
+
* Appends to `schema.sql` the live DEFAULT of every column declared
|
|
1758
|
+
* `databaseDefault: true`, so Atlas plans no `DROP DEFAULT` for it.
|
|
1759
|
+
*
|
|
1760
|
+
* Fails CLOSED, like the exclude lists: without the catalogue the desired state
|
|
1761
|
+
* says "no DEFAULT", and the push would drop each of them. A project declaring
|
|
1762
|
+
* no such column reads nothing.
|
|
1763
|
+
*/
|
|
1764
|
+
async function keepDatabaseOwnedDefaults(databaseUrl, collectionsPath) {
|
|
1765
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
1766
|
+
const { databaseOwnedDefaultColumns, readKeptDefaults, withKeptDefaults } = await import("./push-kept-defaults-BGOlOqRQ.js");
|
|
1767
|
+
const columns = databaseOwnedDefaultColumns(await loadCollections(path.resolve(process.cwd(), collectionsPath)));
|
|
1768
|
+
if (columns.length === 0) return;
|
|
1769
|
+
let kept;
|
|
1770
|
+
try {
|
|
1771
|
+
kept = await withAppClient(databaseUrl, (client) => readKeptDefaults({ query: async (text) => ({ rows: (await client.query(text)).rows }) }, columns));
|
|
1772
|
+
} catch (err) {
|
|
1773
|
+
outError(chalk.red("\n✗ Aborting push: could not read the DEFAULTs of the columns declared `databaseDefault: true`."));
|
|
1774
|
+
outError(chalk.gray(` ${err instanceof Error ? err.message : String(err)}`));
|
|
1775
|
+
outError(chalk.gray(" Refusing to plan without them: the push would drop each of those DEFAULTs."));
|
|
1776
|
+
const hint = diagnoseDbError(err, databaseUrl);
|
|
1777
|
+
if (hint) outError(hint);
|
|
1778
|
+
throw new CommandStopped("Could not read the DEFAULTs to keep.");
|
|
1779
|
+
}
|
|
1780
|
+
if (kept.length === 0) return;
|
|
1781
|
+
const desiredSqlFile = path.join(generatedSqlDir(), "schema.sql");
|
|
1782
|
+
fs.writeFileSync(desiredSqlFile, withKeptDefaults(fs.readFileSync(desiredSqlFile, "utf-8"), kept));
|
|
1783
|
+
out(chalk.gray(` Keeping ${kept.length} DEFAULT(s) the database holds, for columns declared \`databaseDefault: true\`:`));
|
|
1784
|
+
for (const each of kept) out(chalk.gray(` ${each.table}.${each.column} DEFAULT ${each.expression}`));
|
|
1785
|
+
out("");
|
|
1786
|
+
}
|
|
1847
1787
|
/** Renames relation columns that carry their pre-0.13 derived name, as boot does; a dry-run only names them. */
|
|
1848
1788
|
async function renameLegacyForeignKeys(databaseUrl, collectionsPath, dryRun) {
|
|
1849
1789
|
let renames;
|
|
1850
1790
|
try {
|
|
1851
|
-
const { loadCollections } = await import("./doctor-
|
|
1852
|
-
const { legacyForeignKeyRenames } = await import("./push-legacy-renames-
|
|
1791
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
1792
|
+
const { legacyForeignKeyRenames } = await import("./push-legacy-renames-BwaKi8xF.js");
|
|
1853
1793
|
const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));
|
|
1854
1794
|
renames = await withAppClient(databaseUrl, (client) => legacyForeignKeyRenames({ query: async (text) => ({ rows: (await client.query(text)).rows }) }, collections));
|
|
1855
1795
|
} catch {
|
|
@@ -1868,8 +1808,8 @@ async function renameLegacyForeignKeys(databaseUrl, collectionsPath, dryRun) {
|
|
|
1868
1808
|
/** Names the enum labels the database keeps after the collections dropped them. See `schema/enum-labels-kept.ts`. */
|
|
1869
1809
|
async function reportKeptEnumLabels(databaseUrl, collectionsPath) {
|
|
1870
1810
|
try {
|
|
1871
|
-
const { loadCollections } = await import("./doctor-
|
|
1872
|
-
const { keptEnumLabels, formatKeptEnumLabelsNotice } = await import("./enum-labels-kept-
|
|
1811
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
1812
|
+
const { keptEnumLabels, formatKeptEnumLabelsNotice } = await import("./enum-labels-kept-PcPW65xy.js");
|
|
1873
1813
|
const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));
|
|
1874
1814
|
const kept = await withAppClient(databaseUrl, (client) => keptEnumLabels({ query: async (text) => ({ rows: (await client.query(text)).rows }) }, collections));
|
|
1875
1815
|
if (kept.length > 0) outWarn(chalk.yellow(formatKeptEnumLabelsNotice(kept)));
|
|
@@ -1878,8 +1818,8 @@ async function reportKeptEnumLabels(databaseUrl, collectionsPath) {
|
|
|
1878
1818
|
async function prebuildForeignKeyIndexes(databaseUrl, collectionsPath, dryRun) {
|
|
1879
1819
|
let missing;
|
|
1880
1820
|
try {
|
|
1881
|
-
const { loadCollections } = await import("./doctor-
|
|
1882
|
-
const { missingForeignKeyIndexes } = await import("./push-index-prebuild-
|
|
1821
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
1822
|
+
const { missingForeignKeyIndexes } = await import("./push-index-prebuild-UTvB5pqH.js");
|
|
1883
1823
|
const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));
|
|
1884
1824
|
missing = await withAppClient(databaseUrl, (client) => missingForeignKeyIndexes({ query: async (text) => ({ rows: (await client.query(text)).rows }) }, collections));
|
|
1885
1825
|
} catch {
|
|
@@ -1889,7 +1829,7 @@ async function prebuildForeignKeyIndexes(databaseUrl, collectionsPath, dryRun) {
|
|
|
1889
1829
|
if (missing.length === 0 || dryRun) return names;
|
|
1890
1830
|
out(chalk.gray(` Building ${missing.length} foreign-key index(es) on existing tables first — CONCURRENTLY, so writes go on:`));
|
|
1891
1831
|
try {
|
|
1892
|
-
const { buildDeferredIndexes } = await import("./deferred-index-build-
|
|
1832
|
+
const { buildDeferredIndexes } = await import("./deferred-index-build-CqaOv1Xx.js").then((n) => n.r);
|
|
1893
1833
|
const outcome = await withAppClient(databaseUrl, (client) => buildDeferredIndexes(async () => ({
|
|
1894
1834
|
dedicated: true,
|
|
1895
1835
|
query: async (text) => ({ rows: (await client.query(text)).rows }),
|
|
@@ -1937,9 +1877,9 @@ async function lockManagedTables(databaseUrl, collectionsPath) {
|
|
|
1937
1877
|
let unsecured;
|
|
1938
1878
|
let userRole;
|
|
1939
1879
|
try {
|
|
1940
|
-
const { lockCollectionTables } = await import("./ensure-collection-policies-
|
|
1941
|
-
const { loadCollections } = await import("./doctor-
|
|
1942
|
-
userRole = (await import("./rls-enforcement-
|
|
1880
|
+
const { lockCollectionTables } = await import("./ensure-collection-policies-DLWgabQ2.js");
|
|
1881
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
1882
|
+
userRole = (await import("./rls-enforcement-BOHuHVlc.js").then((n) => n.l)).REBASE_USER_ROLE;
|
|
1943
1883
|
const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));
|
|
1944
1884
|
({unsecured} = await withAppClient(databaseUrl, (client) => lockCollectionTables({ query: async (text) => ({ rows: (await client.query(text)).rows }) }, collections)));
|
|
1945
1885
|
} catch (err) {
|
|
@@ -1974,8 +1914,8 @@ async function lockManagedTables(databaseUrl, collectionsPath) {
|
|
|
1974
1914
|
async function ensureAuthTables(databaseUrl, collectionsPath) {
|
|
1975
1915
|
try {
|
|
1976
1916
|
const { drizzle } = await import("drizzle-orm/node-postgres");
|
|
1977
|
-
const { ensureAuthTablesExist } = await import("./ensure-tables-
|
|
1978
|
-
const { loadCollections } = await import("./doctor-
|
|
1917
|
+
const { ensureAuthTablesExist } = await import("./ensure-tables-4nA-tfwi.js").then((n) => n.n);
|
|
1918
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
1979
1919
|
const authCollection = (await loadCollections(path.resolve(process.cwd(), collectionsPath))).find((c) => {
|
|
1980
1920
|
const a = c.auth;
|
|
1981
1921
|
return a === true || typeof a === "object" && a !== null && a.enabled === true;
|
|
@@ -1995,7 +1935,7 @@ async function ensureRlsUserRole(databaseUrl) {
|
|
|
1995
1935
|
const schemas = ["public", "rebase"];
|
|
1996
1936
|
let rls;
|
|
1997
1937
|
try {
|
|
1998
|
-
rls = await import("./rls-enforcement-
|
|
1938
|
+
rls = await import("./rls-enforcement-BOHuHVlc.js").then((n) => n.l);
|
|
1999
1939
|
} catch (err) {
|
|
2000
1940
|
outError(chalk.red(`\n ✗ Could not load the RLS provisioning module: ${err instanceof Error ? err.message : String(err)}`));
|
|
2001
1941
|
return;
|
|
@@ -2055,9 +1995,9 @@ async function applyPolicies(databaseUrl, collectionsPath) {
|
|
|
2055
1995
|
*/
|
|
2056
1996
|
async function policyStamping(databaseUrl, collectionsPath, policiesSql) {
|
|
2057
1997
|
try {
|
|
2058
|
-
const { loadCollections } = await import("./doctor-
|
|
1998
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
2059
1999
|
const { planCollectionPolicies } = await import("./generate-postgres-ddl-logic-DPl1oH_z.js").then((n) => n.o);
|
|
2060
|
-
const { policyStampSql } = await import("./ensure-collection-policies-
|
|
2000
|
+
const { policyStampSql } = await import("./ensure-collection-policies-DLWgabQ2.js");
|
|
2061
2001
|
const { pinSearchPath } = await import("./connection-czvI7TZL.js").then((n) => n.n);
|
|
2062
2002
|
return {
|
|
2063
2003
|
statements: stampableTables(planCollectionPolicies(await loadCollections(path.resolve(process.cwd(), collectionsPath))), policiesSql).map((plan) => policyStampSql(plan)).filter((statement) => statement !== void 0),
|
|
@@ -2075,8 +2015,8 @@ async function policyStamping(databaseUrl, collectionsPath, policiesSql) {
|
|
|
2075
2015
|
*/
|
|
2076
2016
|
async function readPolicyPushPlan(databaseUrl, collectionsPath) {
|
|
2077
2017
|
try {
|
|
2078
|
-
const { formatPolicyPushPlan, planPolicyPush, summarizePolicyPushPlan } = await import("./push-policy-plan-
|
|
2079
|
-
const { loadCollections } = await import("./doctor-
|
|
2018
|
+
const { formatPolicyPushPlan, planPolicyPush, summarizePolicyPushPlan } = await import("./push-policy-plan-DQ2tWceD.js");
|
|
2019
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
2080
2020
|
const { pinSearchPath } = await import("./connection-czvI7TZL.js").then((n) => n.n);
|
|
2081
2021
|
const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));
|
|
2082
2022
|
const plan = await withAppClient(databaseUrl, (client) => planPolicyPush({ query: async (text, values) => ({ rows: (await client.query(text, values)).rows }) }, collections, { searchPath: pinSearchPath(databaseUrl) === databaseUrl ? void 0 : "public" }));
|
|
@@ -2105,7 +2045,7 @@ async function readPolicyPushPlan(databaseUrl, collectionsPath) {
|
|
|
2105
2045
|
async function reconcilePolicies(databaseUrl, collectionsPath) {
|
|
2106
2046
|
try {
|
|
2107
2047
|
const { checkPolicyDrift, dropOrphanedPolicies, formatPolicyDrift, hasDrift } = await import("./policy-drift-X4A-xAzv.js").then((n) => n.s);
|
|
2108
|
-
const { loadCollections } = await import("./doctor-
|
|
2048
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
2109
2049
|
const collections = await loadCollections(path.resolve(process.cwd(), collectionsPath));
|
|
2110
2050
|
await withAppClient(databaseUrl, async (client) => {
|
|
2111
2051
|
const drift = await checkPolicyDrift(client, collections);
|
|
@@ -2148,6 +2088,8 @@ var BRANCH_FLAGS = {
|
|
|
2148
2088
|
"--older-than": String,
|
|
2149
2089
|
"--include-dev-diff": Boolean,
|
|
2150
2090
|
"--from": String,
|
|
2091
|
+
"--json": Boolean,
|
|
2092
|
+
"--sample-limit": Number,
|
|
2151
2093
|
"--yes": Boolean,
|
|
2152
2094
|
"-y": "--yes"
|
|
2153
2095
|
};
|
|
@@ -2189,7 +2131,7 @@ async function branchCommand(rawArgs) {
|
|
|
2189
2131
|
process.exit(1);
|
|
2190
2132
|
}
|
|
2191
2133
|
const { DatabasePoolManager } = await import("./databasePoolManager-3stMNFL-.js").then((n) => n.n);
|
|
2192
|
-
const { BranchService, reopenClosedDatabases, reopenedDatabasesNotice } = await import("./BranchService-
|
|
2134
|
+
const { BranchService, reopenClosedDatabases, reopenedDatabasesNotice } = await import("./BranchService-CWBnDhcv.js").then((n) => n.n);
|
|
2193
2135
|
const { drizzle } = await import("drizzle-orm/node-postgres");
|
|
2194
2136
|
const { Pool } = await import("pg");
|
|
2195
2137
|
const healed = await reopenClosedDatabases(databaseUrl, [branchAction === "create" ? createSource(rawArgs) : void 0, process.env[ACTIVE_BRANCH_DATABASE_ENV]]);
|
|
@@ -2287,6 +2229,41 @@ async function branchCommand(rawArgs) {
|
|
|
2287
2229
|
out("");
|
|
2288
2230
|
break;
|
|
2289
2231
|
}
|
|
2232
|
+
case "diff": {
|
|
2233
|
+
const name = rawArgs[3];
|
|
2234
|
+
if (!name || name.startsWith("-")) {
|
|
2235
|
+
outError(chalk.red("✗ Branch name is required."));
|
|
2236
|
+
out(chalk.gray(" Usage: rebase db branch diff <name> [--json] [--sample-limit <n>]"));
|
|
2237
|
+
process.exit(1);
|
|
2238
|
+
}
|
|
2239
|
+
const parsed = (0, import_arg.default)(BRANCH_FLAGS, {
|
|
2240
|
+
argv: rawArgs.slice(4),
|
|
2241
|
+
permissive: true
|
|
2242
|
+
});
|
|
2243
|
+
const { diffDatabaseBranch } = await import("./branch-diff-CxE4VlxT.js").then((n) => n.r);
|
|
2244
|
+
const { branchDiffReport } = await import("./branch-diff-report-DpvVf7hR.js");
|
|
2245
|
+
const admin = {
|
|
2246
|
+
executeSql: async (text, options) => (await poolManager.getPool(options?.database ?? poolManager.defaultDatabaseName).query(text, options?.params)).rows,
|
|
2247
|
+
createBranch: (branchName, options) => branchService.createBranch(branchName, options),
|
|
2248
|
+
deleteBranch: (branchName) => branchService.deleteBranch(branchName),
|
|
2249
|
+
listBranches: () => branchService.listBranches(),
|
|
2250
|
+
getBranchInfo: async (branchName) => await branchService.hasBranchRegistry() ? branchService.getBranchInfo(branchName) : void 0
|
|
2251
|
+
};
|
|
2252
|
+
let diff;
|
|
2253
|
+
try {
|
|
2254
|
+
diff = await diffDatabaseBranch(admin, name, { sampleLimit: parsed["--sample-limit"] });
|
|
2255
|
+
} catch (error) {
|
|
2256
|
+
outError(chalk.red(` ✗ ${error instanceof Error ? error.message : String(error)}`));
|
|
2257
|
+
process.exit(1);
|
|
2258
|
+
}
|
|
2259
|
+
if (parsed["--json"] === true) out(JSON.stringify(diff, null, 2));
|
|
2260
|
+
else {
|
|
2261
|
+
out("");
|
|
2262
|
+
for (const line of branchDiffReport(diff)) out(` ${line}`);
|
|
2263
|
+
out("");
|
|
2264
|
+
}
|
|
2265
|
+
break;
|
|
2266
|
+
}
|
|
2290
2267
|
case "prune": {
|
|
2291
2268
|
const parsed = (0, import_arg.default)(BRANCH_FLAGS, {
|
|
2292
2269
|
argv: rawArgs.slice(3),
|
|
@@ -2392,6 +2369,7 @@ ${chalk.green.bold("Commands")}
|
|
|
2392
2369
|
${chalk.blue.bold("switch")} [<name>|--off] Point this checkout at a branch
|
|
2393
2370
|
${chalk.blue.bold("delete")} <name> Delete a branch
|
|
2394
2371
|
${chalk.blue.bold("info")} <name> Show branch details
|
|
2372
|
+
${chalk.blue.bold("diff")} <name> [--json] What the branch changed: schema, policies, rows
|
|
2395
2373
|
${chalk.blue.bold("prune")} [--older-than <14|14d|2w>] Remove branches nothing is using
|
|
2396
2374
|
|
|
2397
2375
|
${chalk.green.bold("Why prune")}
|
|
@@ -2405,6 +2383,8 @@ ${chalk.green.bold("Options")}
|
|
|
2405
2383
|
Postgres refuses to copy or drop a database
|
|
2406
2384
|
anything else is connected to — usually your
|
|
2407
2385
|
own \`rebase dev\`.
|
|
2386
|
+
${chalk.blue.bold("--json")} diff: print the whole diff as JSON, with up
|
|
2387
|
+
to --sample-limit rows a table (default 100).
|
|
2408
2388
|
${chalk.blue.bold("--include-dev-diff")} Also prune the Atlas scratch databases
|
|
2409
2389
|
\`db push\` leaves behind.
|
|
2410
2390
|
${chalk.blue.bold("--yes, -y")} Skip prune's confirmation prompt. Dropping a
|
|
@@ -2698,7 +2678,7 @@ async function schemaStaleCommand(rawArgs) {
|
|
|
2698
2678
|
const schemaFile = path.resolve(process.cwd(), outputPath);
|
|
2699
2679
|
const fix = Boolean(argsList["--fix"]);
|
|
2700
2680
|
const generatedExists = fs.existsSync(schemaFile);
|
|
2701
|
-
const { loadCollections } = await import("./doctor-
|
|
2681
|
+
const { loadCollections } = await import("./doctor-DW_mlTzz.js").then((n) => n.t);
|
|
2702
2682
|
const { findLegacyForeignKeyNames, compareGeneratedDeclarations, staleVerdict } = await import("./generated-schema-staleness-BvNF3i-s.js").then((n) => n.r);
|
|
2703
2683
|
const { generateSchema } = await import("./generate-drizzle-schema-logic-CPzCRD-8.js").then((n) => n.n);
|
|
2704
2684
|
const { relationalCollections } = await import("@rebasepro/common");
|