Skip to content
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
6473a98
refactor(migration-tools): brand ValidSpaceId for compile-time tracking
wmadden May 8, 2026
630db76
feat(family-sql): codec onFieldEvent lifecycle hook (T2.1)
wmadden May 7, 2026
5a70193
feat(target-postgres): wire codec onFieldEvent into postgres planner …
wmadden May 7, 2026
8b5f7ea
feat(target-sqlite): wire codec onFieldEvent into sqlite planner (T2.2)
wmadden May 7, 2026
d842f89
docs(extension-contract-spaces): M2 R1 doc-pass — codec hook concrete…
wmadden May 7, 2026
8391ea9
test(target-sqlite): add RawSqlCall round-trip fixture (F4)
wmadden May 8, 2026
daf151f
feat(migration-tools,family-sql): assert descriptor self-consistency …
wmadden May 8, 2026
928ad13
feat(cli,migration-tools): wire contract-space verifier into db init …
wmadden May 8, 2026
9effde1
feat(cli): drift detection + pinned re-emit at migrate time
wmadden May 8, 2026
8077b4a
docs(extension-contract-spaces): M2 R2 doc-pass — descriptor self-con…
wmadden May 8, 2026
48499ca
feat(verifier): wire marker-aware contract-space verifier into db verify
wmadden May 8, 2026
375dd63
feat(migrate): materialise extension migration packages on disk via p…
wmadden May 8, 2026
f2e3773
docs(extension-contract-spaces): M2 R3 doc-pass — marker-aware verifi…
wmadden May 8, 2026
387fc27
feat(sql-runner): add executeOnConnection + executeAcrossSpaces for m…
wmadden May 8, 2026
8686df1
docs(extension-contract-spaces): M2 R4 doc-pass — runner externally-m…
wmadden May 8, 2026
55b2e06
feat(cli,migration-tools): per-space db init/update via executeAcross…
wmadden May 8, 2026
2013e02
test(adapter-sqlite,cli): T2.5 multi-space db init/update/rollback e2…
wmadden May 8, 2026
522339c
docs(extension-contract-spaces): mark T2.3 + T2.4 + T2.5 completed (M…
wmadden May 8, 2026
f65606e
test(adapter-sqlite): codec onFieldEvent fires through per-space db i…
wmadden May 8, 2026
a4326d9
docs(extension-contract-spaces): T2.5 — point at the e2e codec-hook +…
wmadden May 8, 2026
75ba002
docs(extension-contract-spaces): M2 R5 close-out doc-pass — app-space…
wmadden May 8, 2026
fc7837b
feat(cli): wire marker-aware contract-space verifier into db init + d…
wmadden May 8, 2026
b523134
refactor(cli): unify per-space orchestrator on a path-resolver seam
wmadden May 8, 2026
3c685af
refactor(cli): collapse the dual `db init` path onto the per-space or…
wmadden May 8, 2026
15a38dc
docs(extension-contract-spaces): record M2 orchestrator-consolidation…
wmadden May 8, 2026
110c59e
docs(extension-contract-spaces): plan amendments for M2 R6 polish + r…
wmadden May 8, 2026
998f4d7
test(cli): unit-test pruneSchemaByOtherSpaceContracts duck-typing con…
wmadden May 8, 2026
c95f053
docs(framework): refresh post-consolidation comments + AC references
wmadden May 8, 2026
e837251
refactor(framework): drop dead edgesByHash + extract span-id constants
wmadden May 8, 2026
f8e5711
refactor(cli): collapse identical action ternaries in result builders
wmadden May 8, 2026
1a80bfa
refactor(cli): replace per-space O(N^2) lookups with Map indices
wmadden May 8, 2026
0506f91
docs(extension-contract-spaces): record round-2-polish review escapee…
wmadden May 8, 2026
e121e87
docs(projects/extension-contract-spaces): add M2.5 contract-space-agg…
wmadden May 9, 2026
bc35b9b
chore(packages): scrub transient project-artefact references from sou…
wmadden May 9, 2026
463661f
docs(projects/extension-contract-spaces): mark T2.7 (F29) complete
wmadden May 9, 2026
004555f
feat(migration-tools): introduce ContractSpaceAggregate types and loader
wmadden May 9, 2026
0bb8ac2
feat(migration-tools): add aggregate planner with graph-walk and synt…
wmadden May 9, 2026
b0e1a73
feat(migration-tools): add aggregate verifier bundling markerCheck an…
wmadden May 9, 2026
1b24140
feat(cli): rewire db init/update/verify through aggregate pipeline
wmadden May 9, 2026
d0034c7
refactor: delete deprecated per-space CLI surfaces
wmadden May 9, 2026
b4daa5d
fix(cli): re-add orphan-marker preflight to aggregate apply pipeline
wmadden May 9, 2026
96bee1f
test(integration): lock aggregate schema verification, drift, and Pos…
wmadden May 9, 2026
52f0cc5
docs(projects/extension-contract-spaces): mark M2.5 tasks complete; d…
wmadden May 9, 2026
50737e9
refactor(cli, migration-tools): tighten executeDbVerify, add orphanEl…
wmadden May 9, 2026
11a16a7
test(migration-tools): walk loader → verifier with deleted node_modules
wmadden May 9, 2026
e3a9891
docs(projects/extension-contract-spaces): mark M2.5 SATISFIED with R2…
wmadden May 9, 2026
00ace23
fix(rebase): adopt M1-cleanup conventions across M2/M2.5 surfaces
wmadden May 9, 2026
e90b522
docs(extension-contract-spaces): add contract-space-on-disk-shape sub…
wmadden May 9, 2026
2c39210
docs(extension-contract-spaces): introduce M6 — promote migration CLI…
wmadden May 9, 2026
2f45471
docs(extension-contract-spaces): add Milestone 2.5b plan entry for th…
wmadden May 9, 2026
c3eeac6
fix(migration): unify on-disk layout — app subspaces under <appSpaceI…
wmadden May 9, 2026
afada63
docs(extension-contract-spaces): record M2.5b cascade-rebase fixture-…
wmadden May 9, 2026
715ae36
fix(cli): scope contract import-allowlist to entry-direct imports
wmadden May 10, 2026
c6871f5
test(cli): cover combine-schema-results edge cases; remove dead summa…
wmadden May 10, 2026
05b91f8
fix(cli): unblock M2 typecheck + coverage CI gates
wmadden May 10, 2026
2fef140
chore(comments): strip transient milestone tokens from test comments
wmadden May 10, 2026
1f8554e
fix(cli): tag dbVerify progress events with the operation name
wmadden May 10, 2026
b96e089
refactor(cli): make disallowed-import error fully allowlist-driven
wmadden May 10, 2026
4aaff4e
test(cli): tighten contract-space-migrate-pass setup and drift assertion
wmadden May 10, 2026
894ce6e
docs(cli): drop transitional db-update aggregate-loader comment
wmadden May 10, 2026
a82635d
fix(mongo/control-instance): key the bridged marker map by APP_SPACE_ID
wmadden May 10, 2026
c74ce77
docs(sql/field-event-planner): align isAlteration docstring with impl…
wmadden May 10, 2026
2f5afa3
refactor(sql/control-instance): require readAllMarkers via type guard…
wmadden May 10, 2026
9fdfe22
fix(sql/runners): drop silent app default for marker-write space
wmadden May 10, 2026
46fbe71
test(integration): filter migrations/app entries to real migration di…
wmadden May 10, 2026
9f43f10
test(migration): drop unused APP_HEAD_HASH placeholder
wmadden May 10, 2026
c6e76e5
test(cli): group combine-schema-results assertions into toMatchObject
wmadden May 10, 2026
2189ced
docs(project): centralise descriptor-import boundary as M6 task
wmadden May 10, 2026
7084c48
chore: nudge CI after stale concurrency cancellations on PR #438
wmadden May 10, 2026
104d09a
fix(migration): stamp spaceId on graph-walk plans so runner-invariant…
wmadden May 10, 2026
fd34b3c
test(integration): drop obsolete db-migrate guard; harden verifier JS…
wmadden May 10, 2026
2174dc8
fix(migration): preserve verifyAggregate Result contract on introspec…
wmadden May 10, 2026
e71e353
test(migration): rename loader→verifier suite to match what it exercises
wmadden May 10, 2026
964e70a
test(e2e): isolate dbInit migrationsDir per run with mkdtemp + cleanup
wmadden May 10, 2026
58a85a0
docs: strip transient milestone/spec tokens from source comments
wmadden May 10, 2026
a986aee
split mixed value+type import in aggregate/verifier.ts
wmadden May 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cursor/rules/doc-maintenance.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ alwaysApply: true
- **User-facing packages**: keep `README.md` focused on what the package does, when to use it, and a few concrete examples. Avoid internal implementation detail unless it materially affects usage.
- **Contributor details**: put responsibilities/dependencies/architecture diagrams/internal exports in `DEVELOPING.md` (or `CONTRIBUTING.md`) within that package, and add a short link from `README.md`.
- Docs must not link to transient project artifacts under `projects/` (link to durable `docs/` or package READMEs instead)
- **Source-code comments must not reference transient project artefacts.** This includes: `projects/<x>/...` paths, milestone-task IDs (e.g. `T1.7`, `T2.5.3`, `R4 design choice`), milestone-named acceptance criteria (e.g. `AM12`, `AC-13`), and prose attributions like "M2 review", "out of scope", "sub-spec § 4", "sub-spec OQ3". When a comment needs to explain *why* something is the way it is, describe the constraint or behaviour itself; do not attribute it to the transient project artefact that introduced it. After close-out, durable docs under `docs/architecture docs/` can be linked. Stable references (Linear ticket IDs like `TML-2397`, ADR numbers like `ADR 211`) are fine.
- If you establish a new design decision, update the architecture docs in `docs/architecture docs`
7 changes: 5 additions & 2 deletions examples/mongo-demo/test/manual-migration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { type Db, MongoClient } from 'mongodb';
import { MongoMemoryReplSet } from 'mongodb-memory-server';
import { resolve } from 'pathe';
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest';
import AddPostsAuthorIndex from '../migrations/20260415_add-posts-author-index/migration';
import AddPostsAuthorIndex from '../migrations/app/20260415_add-posts-author-index/migration';

const ALL_POLICY = {
allowedOperationClasses: ['additive', 'widening', 'destructive'] as const,
Expand All @@ -23,7 +23,10 @@ function makeFamily(): ReturnType<typeof createMongoFamilyInstance> {
);
}

const migrationDir = resolve(import.meta.dirname, '../migrations/20260415_add-posts-author-index');
const migrationDir = resolve(
import.meta.dirname,
'../migrations/app/20260415_add-posts-author-index',
);

describe(
'hand-authored migration (20260415_add-posts-author-index)',
Expand Down
13 changes: 12 additions & 1 deletion examples/prisma-next-demo/test/utils/control-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,22 @@ export function createPrismaNextControlClient(options: TestControlClientOptions)
export async function initTestDatabase(options: {
readonly connection: string;
readonly contract: unknown;
/**
* On-disk migrations directory. The demo app does not declare any
* extension contract spaces, so the per-space `db init` flow runs
* with the n=1 (app-only) resolver list and does not actually read
* from this path — but `migrationsDir` is required by the API.
*/
readonly migrationsDir?: string;
}): Promise<void> {
const client = createPrismaNextControlClient({ connection: options.connection });

try {
const initResult = await client.dbInit({ contract: options.contract, mode: 'apply' });
const initResult = await client.dbInit({
contract: options.contract,
mode: 'apply',
migrationsDir: options.migrationsDir ?? '/tmp/__prisma-next-test-migrations',
});
if (!initResult.ok) {
throw new Error(
`dbInit failed: ${initResult.failure.summary}\n\n${JSON.stringify(initResult.failure, null, 2)}`,
Expand Down
7 changes: 5 additions & 2 deletions examples/retail-store/test/manual-migration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { type Db, MongoClient } from 'mongodb';
import { MongoMemoryReplSet } from 'mongodb-memory-server';
import { resolve } from 'pathe';
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest';
import AddProductValidation from '../migrations/20260415_add-product-validation/migration';
import AddProductValidation from '../migrations/app/20260415_add-product-validation/migration';

const ALL_POLICY = {
allowedOperationClasses: ['additive', 'widening', 'destructive'] as const,
Expand All @@ -23,7 +23,10 @@ function makeFamily(): ReturnType<typeof createMongoFamilyInstance> {
);
}

const migrationDir = resolve(import.meta.dirname, '../migrations/20260415_add-product-validation');
const migrationDir = resolve(
import.meta.dirname,
'../migrations/app/20260415_add-product-validation',
);

describe(
'hand-authored migration (20260415_add-product-validation)',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import type { ControlTargetDescriptor } from './control-descriptors';
import type { ControlFamilyInstance } from './control-instances';
import type { MigrationPlanOperation, TargetMigrationsCapability } from './control-migration-types';
import type {
MigrationPlanOperation,
MigrationRunner,
MultiSpaceCapableRunner,
TargetMigrationsCapability,
} from './control-migration-types';
import type { OperationPreview } from './control-operation-preview';
import type { CoreSchemaView } from './control-schema-view';
import type { PslDocumentAst } from './psl-ast';
Expand Down Expand Up @@ -69,3 +74,22 @@ export function hasOperationPreview<TFamilyId extends string, TSchemaIR>(
typeof (instance as Record<string, unknown>)['toOperationPreview'] === 'function'
);
}

/**
* Capability declaring that a runner can apply per-space plans inside a
* single outer transaction. Today's only implementer is the SQL family
* (`SqlMigrationRunner`); Mongo per-space is a non-goal per the project
* spec for extension contract spaces (TML-2397).
*
* The CLI uses this guard to route `db init` / `db update` through a
* per-space wiring when extensions expose a `contractSpace`, falling back
* to the single-space path when no multi-space capability is present.
*/
export function hasMultiSpaceRunner<TFamilyId extends string, TTargetId extends string>(
runner: MigrationRunner<TFamilyId, TTargetId>,
): runner is MigrationRunner<TFamilyId, TTargetId> & MultiSpaceCapableRunner<TFamilyId, TTargetId> {
return (
'executeAcrossSpaces' in runner &&
typeof (runner as Record<string, unknown>)['executeAcrossSpaces'] === 'function'
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ export interface ControlFamilyInstance<TFamilyId extends string, TSchemaIR>
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, string>>;
}): Promise<VerifyDatabaseSchemaResult>;

/**
* Verify a contract against an already-introspected schema slice.
*
* Difference from {@link schemaVerify}: no `driver`, no introspection
* — the caller hands over the schema directly. Used by the aggregate
* verifier to invoke the family's verification logic per member,
* with the schema **pre-projected** to that member's claimed slice
* via {@link import('@prisma-next/migration-tools/aggregate').projectSchemaToSpace}.
*
* Synchronous — no I/O. Idempotent.
*/
schemaVerifyAgainstSchema(options: {
readonly contract: unknown;
readonly schema: TSchemaIR;
readonly strict: boolean;
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, string>>;
}): VerifyDatabaseSchemaResult;

sign(options: {
readonly driver: ControlDriverInstance<TFamilyId, string>;
readonly contract: unknown;
Expand Down Expand Up @@ -64,6 +82,15 @@ export interface ControlFamilyInstance<TFamilyId extends string, TSchemaIR>
readonly space: string;
}): Promise<ContractMarkerRecord | null>;

/**
* Reads every marker row keyed by `space`. Used by the per-space
* verifier to detect orphan marker rows and marker-vs-on-disk drift.
* Returns an empty map when the marker table does not yet exist.
*/
readAllMarkers(options: {
readonly driver: ControlDriverInstance<TFamilyId, string>;
}): Promise<ReadonlyMap<string, ContractMarkerRecord>>;

introspect(options: {
readonly driver: ControlDriverInstance<TFamilyId, string>;
readonly contract?: unknown;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ export interface OpFactoryCall {
export interface MigrationPlan {
/** The target ID this plan is for (e.g., 'postgres'). */
readonly targetId: string;
/**
* Contract space this plan applies to. Runners cross-check
* `options.space` against `plan.spaceId` so the marker row gets keyed
* by the right space when applying via `executeAcrossSpaces`.
*
* Optional for backward compatibility with single-space callers that
* pre-date the contract-space aggregate; when present, runners
* enforce that it matches `options.space`.
*/
readonly spaceId?: string;
/**
* Origin contract identity that the plan expects the database to currently be at.
* If omitted or null, the runner skips origin validation entirely.
Expand Down Expand Up @@ -425,6 +435,71 @@ export interface MigrationRunner<
}): Promise<MigrationRunnerResult>;
}

// ============================================================================
// Multi-space runner protocol (extension contract spaces, TML-2397)
// ============================================================================

/**
* Per-space input for {@link MultiSpaceCapableRunner.executeAcrossSpaces}.
*
* Mirrors the single-space `MigrationRunner.execute` options, extended with a
* required `space` identifier. Each entry's `driver` must reference the same
* connection the outer transaction is opened on (typically the same value as
* the top-level `driver` on `executeAcrossSpaces`).
*
* Family-specific runners (e.g. the SQL family's `SqlMigrationRunner`) define
* a richer per-space option shape that is structurally compatible with this
* one — additional optional fields (e.g. SQL's `strictVerification`,
* `schemaName`, `callbacks`) are tolerated by the underlying runner without
* affecting cross-target wiring.
*/
export interface MultiSpaceRunnerPerSpaceOptions<
TFamilyId extends string = string,
TTargetId extends string = string,
> {
readonly space: string;
readonly plan: MigrationPlan;
readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;
readonly destinationContract: unknown;
readonly policy: MigrationOperationPolicy;
readonly executionChecks?: MigrationRunnerExecutionChecks;
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
}

export interface MultiSpaceRunnerSuccessValue {
readonly perSpaceResults: ReadonlyArray<{
readonly space: string;
readonly value: MigrationRunnerSuccessValue;
}>;
}

export interface MultiSpaceRunnerFailure extends MigrationRunnerFailure {
/** Identifier of the space whose plan caused the rollback. */
readonly failingSpace: string;
}

export type MultiSpaceRunnerResult = Result<MultiSpaceRunnerSuccessValue, MultiSpaceRunnerFailure>;

/**
* Optional capability for runners that can apply a list of per-space plans
* inside a single outer transaction. A failure on any space rolls back every
* space's writes.
*
* Today's only implementer is the SQL family (`SqlMigrationRunner`); Mongo
* per-space is a non-goal per the project spec. The capability is declared
* at the framework layer so CLI utilities can route through it without
* importing the SQL family directly.
*/
export interface MultiSpaceCapableRunner<
TFamilyId extends string = string,
TTargetId extends string = string,
> {
executeAcrossSpaces(options: {
readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;
readonly perSpaceOptions: ReadonlyArray<MultiSpaceRunnerPerSpaceOptions<TFamilyId, TTargetId>>;
}): Promise<MultiSpaceRunnerResult>;
}

// ============================================================================
// Target Migrations Capability
// ============================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import type { MigrationMetadata, MigrationPlanOperation } from './control-migrat
export const APP_SPACE_ID = 'app' as const;

/**
* Pinned head ref for a contract space — the `(hash, invariants)` tuple
* Head ref for a contract space — the `(hash, invariants)` tuple
* a runner targets when applying that space's migration graph. Identical
* in shape to the on-disk `migrations/<space-id>/refs/head.json` the
* framework writes per loaded extension, and to the app-space
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type {
} from '../control/control-capabilities';
export {
hasMigrations,
hasMultiSpaceRunner,
hasOperationPreview,
hasPslContractInfer,
hasSchemaView,
Expand Down Expand Up @@ -43,6 +44,11 @@ export type {
MigrationRunnerResult,
MigrationRunnerSuccessValue,
MigrationScaffoldContext,
MultiSpaceCapableRunner,
MultiSpaceRunnerFailure,
MultiSpaceRunnerPerSpaceOptions,
MultiSpaceRunnerResult,
MultiSpaceRunnerSuccessValue,
OpFactoryCall,
SerializedQueryPlan,
TargetMigrationsCapability,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ test('encode/decode call sites accept an explicit ctx (signal optional inside th
void decodeWithEmptyCtx;
});

// ADR 204 walk-back constraints — pinned here so future refactors cannot reintroduce a `TRuntime` generic, a discriminator field, conditional return types, or other shape complications on the public Codec.
// ADR 204 walk-back constraints — captured here so future refactors cannot reintroduce a `TRuntime` generic, a discriminator field, conditional return types, or other shape complications on the public Codec.

test('Codec carries no `runtime` or `kind` discriminator field', () => {
type CodecKeys = keyof Codec;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ test('CodecImpl.id proxies through descriptor.codecId (parameterized)', ({ expec
});

test('alias descriptor produces codec whose id reads the alias codecId', ({ expect }) => {
// Spec § Class hierarchy aliasing: an alias descriptor instantiates the same concrete codec class (`Int4FixtureCodec`) but passes itself as the descriptor reference. `CodecImpl.id` proxies through `this.descriptor.codecId`, so the runtime id reads the alias's id even though the codec class hardcodes `'demo/int4@1'` in its type-level `Id` parameter. This test pins that regression vector — a future change that pinned `id` to the codec class's `Id` type literal would silently break aliasing.
// Spec § Class hierarchy aliasing: an alias descriptor instantiates the same concrete codec class (`Int4FixtureCodec`) but passes itself as the descriptor reference. `CodecImpl.id` proxies through `this.descriptor.codecId`, so the runtime id reads the alias's id even though the codec class hardcodes `'demo/int4@1'` in its type-level `Id` parameter. This test locks that regression vector — a future change that locked `id` to the codec class's `Id` type literal would silently break aliasing.
//
// The alias extends `CodecDescriptorImpl<void>` directly (not `Int4FixtureDescriptor`) because `Int4FixtureDescriptor.codecId` is narrowed to the literal `'demo/int4@1'`; subclasses can't override it with a different literal under TypeScript's structural overrides.
class AliasedInt4Descriptor extends CodecDescriptorImpl<void> {
Expand Down
16 changes: 13 additions & 3 deletions packages/1-framework/3-tooling/cli/src/commands/db-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '../utils/cli-errors';
import type { MigrationCommandOptions } from '../utils/command-helpers';
import {
resolveMigrationPaths,
sanitizeErrorMessage,
setCommandDescriptions,
setCommandExamples,
Expand Down Expand Up @@ -111,14 +112,23 @@ async function executeDbInitCommand(
if (!ctxResult.ok) {
return ctxResult;
}
const { client, contractJson, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;
const { client, config, contractJson, dbConnection, onProgress, contractPathAbsolute } =
ctxResult.value;

// The aggregate loader (loader → planner → runner pipeline) catches
// layout / drift / disjointness violations on its own; the legacy
// per-space precheck + marker-check helpers are no longer needed at
// this surface. Marker-vs-on-disk drift surfaces through the planner's
// graph-walk strategy.
const { migrationsDir } = resolveMigrationPaths(options.config, config);

try {
// Call dbInit with connection and progress callback
await client.connect(dbConnection);

const result = await client.dbInit({
contract: contractJson,
mode: options.dryRun ? 'plan' : 'apply',
connection: dbConnection,
migrationsDir,
onProgress,
});

Expand Down
10 changes: 7 additions & 3 deletions packages/1-framework/3-tooling/cli/src/commands/db-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '../utils/cli-errors';
import type { MigrationCommandOptions } from '../utils/command-helpers';
import {
resolveMigrationPaths,
sanitizeErrorMessage,
setCommandDescriptions,
setCommandExamples,
Expand Down Expand Up @@ -80,14 +81,17 @@ async function executeDbUpdateCommand(
if (!ctxResult.ok) {
return ctxResult;
}
const { client, contractJson, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;
const { client, config, contractJson, dbConnection, onProgress, contractPathAbsolute } =
ctxResult.value;
const { migrationsDir } = resolveMigrationPaths(options.config, config);

try {
// Call dbUpdate with connection and progress callback
await client.connect(dbConnection);

const result = await client.dbUpdate({
contract: contractJson,
mode: options.dryRun ? 'plan' : 'apply',
connection: dbConnection,
migrationsDir,
...(flags.yes ? { acceptDataLoss: true } : {}),
onProgress,
});
Expand Down
Loading
Loading