feat: add transactional module migration runner
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { ModuleMigrationAggregate } from "../modules/index.js";
|
||||
import type { MigrationApplyResult, MigrationPlanResult } from "../migrations/index.js";
|
||||
|
||||
function plural(count: number, singular: string): string {
|
||||
return count === 1 ? singular : `${singular}s`;
|
||||
@@ -26,3 +27,36 @@ export function formatMigrationValidationReport(
|
||||
|
||||
return Object.freeze(lines);
|
||||
}
|
||||
|
||||
export function formatMigrationPlanReport(plan: MigrationPlanResult): readonly string[] {
|
||||
const readyCount = plan.pendingCount - plan.approvalRequiredCount;
|
||||
const lines = [
|
||||
`Migration plan (${plan.appliedCount} applied, ${readyCount} pending, ${plan.approvalRequiredCount} approval-blocked):`,
|
||||
];
|
||||
|
||||
for (const entry of plan.entries) {
|
||||
lines.push(`- [${entry.status}] ${entry.identity} sha256=${entry.checksum}`);
|
||||
}
|
||||
if (plan.entries.length === 0) {
|
||||
lines.push("- No installed module migrations.");
|
||||
}
|
||||
lines.push(
|
||||
"Informational only: this plan is read-only and may become stale; apply revalidates history under the migration lock.",
|
||||
);
|
||||
|
||||
return Object.freeze(lines);
|
||||
}
|
||||
|
||||
export function formatMigrationApplyReport(result: MigrationApplyResult): readonly string[] {
|
||||
if (result.noOp) {
|
||||
return Object.freeze(["Migration apply completed: database is already current (no changes)."]);
|
||||
}
|
||||
|
||||
const lines = [
|
||||
`Migration apply completed (${result.appliedCount} ${plural(result.appliedCount, "migration")} applied):`,
|
||||
];
|
||||
for (const migration of result.applied) {
|
||||
lines.push(`- ${migration.identity} sha256=${migration.checksum}`);
|
||||
}
|
||||
return Object.freeze(lines);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user