@prisma-next/cli 0.11.0 → 0.12.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/README.md +13 -9
- package/dist/cli.mjs +259 -12
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-oXO2WCPD.mjs → client-KgJorIvG.mjs} +72 -60
- package/dist/client-KgJorIvG.mjs.map +1 -0
- package/dist/{command-helpers-BSb0tRC8.mjs → command-helpers-Bbw1GbwL.mjs} +646 -46
- package/dist/command-helpers-Bbw1GbwL.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts.map +1 -1
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.d.mts.map +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.d.mts.map +1 -1
- package/dist/commands/db-init.mjs +32 -7
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.d.mts.map +1 -1
- package/dist/commands/db-schema.mjs +3 -4
- package/dist/commands/db-schema.mjs.map +1 -1
- package/dist/commands/db-sign.d.mts.map +1 -1
- package/dist/commands/db-sign.mjs +12 -10
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +41 -11
- package/dist/commands/db-update.mjs.map +1 -1
- package/dist/commands/db-verify.d.mts.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +6 -2
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +75 -40
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +4 -3
- package/dist/commands/migration-check.d.mts.map +1 -1
- package/dist/commands/migration-check.mjs +1 -280
- package/dist/commands/migration-graph.d.mts +13 -2
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +2 -137
- package/dist/commands/migration-list.d.mts +64 -4
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +143 -56
- package/dist/commands/migration-list.mjs.map +1 -1
- package/dist/commands/migration-log.d.mts +10 -1
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +10 -15
- package/dist/commands/migration-log.mjs.map +1 -1
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +32 -38
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +3 -2
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +4 -55
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +61 -153
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +12 -49
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +85 -81
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +38 -10
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/config-loader-B6sJjXTv.mjs.map +1 -1
- package/dist/config-loader.d.mts.map +1 -1
- package/dist/contract-at-errors-BxP-TOMl.mjs +42 -0
- package/dist/contract-at-errors-BxP-TOMl.mjs.map +1 -0
- package/dist/{contract-emit-bcrpT-wD.mjs → contract-emit-D-4jrNve.mjs} +25 -10
- package/dist/contract-emit-D-4jrNve.mjs.map +1 -0
- package/dist/{contract-emit-r4y8Zhf1.mjs → contract-emit-DxcGl4Uq.mjs} +19 -14
- package/dist/contract-emit-DxcGl4Uq.mjs.map +1 -0
- package/dist/{contract-enrichment-Dani0mMW.mjs → contract-enrichment-a0V5Y_mL.mjs} +4 -25
- package/dist/contract-enrichment-a0V5Y_mL.mjs.map +1 -0
- package/dist/{contract-infer-BmySmqVT.mjs → contract-infer-D8uEbJuu.mjs} +4 -5
- package/dist/{contract-infer-BmySmqVT.mjs.map → contract-infer-D8uEbJuu.mjs.map} +1 -1
- package/dist/contract-space-aggregate-loader-DvZwdkrr.mjs +247 -0
- package/dist/contract-space-aggregate-loader-DvZwdkrr.mjs.map +1 -0
- package/dist/{db-verify-BClPs3ph.mjs → db-verify-v_vUKXTU.mjs} +5 -7
- package/dist/{db-verify-BClPs3ph.mjs.map → db-verify-v_vUKXTU.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +3 -3
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +3 -3
- package/dist/exports/index.d.mts.map +1 -1
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/index.mjs.map +1 -1
- package/dist/exports/init-output.d.mts.map +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/extension-pack-inputs-IDvjRCi3.mjs +62 -0
- package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +1 -0
- package/dist/{framework-components-65gOHkHB.mjs → framework-components-fYXjz_in.mjs} +2 -2
- package/dist/{framework-components-65gOHkHB.mjs.map → framework-components-fYXjz_in.mjs.map} +1 -1
- package/dist/global-flags-DEHjV8_s.d.mts +34 -0
- package/dist/global-flags-DEHjV8_s.d.mts.map +1 -0
- package/dist/{graph-render-DJVv0_uf.mjs → graph-render-rFAqZujX.mjs} +2 -2
- package/dist/{graph-render-DJVv0_uf.mjs.map → graph-render-rFAqZujX.mjs.map} +1 -1
- package/dist/{init-BCJZPWE1.mjs → init-Cv9UzWL5.mjs} +20 -269
- package/dist/init-Cv9UzWL5.mjs.map +1 -0
- package/dist/{inspect-live-schema-DSRbFoOL.mjs → inspect-live-schema-C6ohV_oQ.mjs} +4 -5
- package/dist/{inspect-live-schema-DSRbFoOL.mjs.map → inspect-live-schema-C6ohV_oQ.mjs.map} +1 -1
- package/dist/migration-check-BiBJoYYW.mjs +341 -0
- package/dist/migration-check-BiBJoYYW.mjs.map +1 -0
- package/dist/migration-cli.d.mts.map +1 -1
- package/dist/migration-cli.mjs +4 -4
- package/dist/migration-cli.mjs.map +1 -1
- package/dist/{migration-command-scaffold-Bzd9La5c.mjs → migration-command-scaffold-CjvwO6at.mjs} +4 -5
- package/dist/{migration-command-scaffold-Bzd9La5c.mjs.map → migration-command-scaffold-CjvwO6at.mjs.map} +1 -1
- package/dist/migration-graph-D7DVUElV.mjs +1232 -0
- package/dist/migration-graph-D7DVUElV.mjs.map +1 -0
- package/dist/migration-list-styler-BRwF4-gy.mjs +399 -0
- package/dist/migration-list-styler-BRwF4-gy.mjs.map +1 -0
- package/dist/{migration-plan-CFwqw3Gk.mjs → migration-plan-9DJ7q7_z.mjs} +372 -133
- package/dist/migration-plan-9DJ7q7_z.mjs.map +1 -0
- package/dist/{migration-types-BXWvz12q.d.mts → migration-types-D2FW63pr.d.mts} +1 -1
- package/dist/{migration-types-BXWvz12q.d.mts.map → migration-types-D2FW63pr.d.mts.map} +1 -1
- package/dist/{migrations-CwZMa1Ck.mjs → migrations-Cv2jxNNK.mjs} +12 -13
- package/dist/migrations-Cv2jxNNK.mjs.map +1 -0
- package/dist/{output-BlsrGMEF.mjs → output-B60Gw5fu.mjs} +1 -1
- package/dist/{output-BlsrGMEF.mjs.map → output-B60Gw5fu.mjs.map} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs → progress-adapter-C644QK8l.mjs} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs.map → progress-adapter-C644QK8l.mjs.map} +1 -1
- package/dist/ref-advancement-DUZqsue6.mjs +50 -0
- package/dist/ref-advancement-DUZqsue6.mjs.map +1 -0
- package/dist/terminal-ui-5Y6mrg93.d.mts +133 -0
- package/dist/terminal-ui-5Y6mrg93.d.mts.map +1 -0
- package/dist/{types--CqjMdk0.d.mts → types-Dt_SfqFm.d.mts} +28 -28
- package/dist/types-Dt_SfqFm.d.mts.map +1 -0
- package/dist/{verify-Bom75OYI.mjs → verify-DCA9Sldu.mjs} +2 -2
- package/dist/{verify-Bom75OYI.mjs.map → verify-DCA9Sldu.mjs.map} +1 -1
- package/package.json +35 -24
- package/src/commands/contract-emit.ts +19 -7
- package/src/commands/contract-infer.ts +1 -1
- package/src/commands/db-init.ts +48 -2
- package/src/commands/db-sign.ts +9 -5
- package/src/commands/db-update.ts +54 -8
- package/src/commands/init/hygiene-gitattributes.ts +2 -2
- package/src/commands/init/index.ts +2 -1
- package/src/commands/init/templates/code-templates.ts +4 -2
- package/src/commands/init/templates/env.ts +13 -14
- package/src/commands/migrate.ts +125 -44
- package/src/commands/migration-check.ts +43 -83
- package/src/commands/migration-graph.ts +75 -60
- package/src/commands/migration-list.ts +220 -74
- package/src/commands/migration-log.ts +8 -14
- package/src/commands/migration-new.ts +44 -48
- package/src/commands/migration-plan.ts +412 -197
- package/src/commands/migration-show.ts +65 -284
- package/src/commands/migration-status.ts +127 -124
- package/src/commands/ref.ts +53 -8
- package/src/control-api/client.ts +0 -1
- package/src/control-api/contract-enrichment.ts +6 -42
- package/src/control-api/operations/{apply-aggregate.ts → apply.ts} +44 -75
- package/src/control-api/operations/contract-emit.ts +14 -6
- package/src/control-api/operations/{db-apply-aggregate.ts → db-apply.ts} +19 -19
- package/src/control-api/operations/db-init.ts +4 -4
- package/src/control-api/operations/db-update.ts +4 -4
- package/src/control-api/operations/db-verify.ts +15 -11
- package/src/control-api/operations/migration-apply.ts +56 -47
- package/src/control-api/types.ts +26 -27
- package/src/migration-cli.ts +4 -4
- package/src/utils/cli-errors.ts +234 -0
- package/src/utils/command-helpers.ts +9 -24
- package/src/utils/contract-at-errors.ts +96 -0
- package/src/utils/contract-space-aggregate-loader.ts +336 -117
- package/src/utils/formatters/migration-graph-layout.ts +1119 -0
- package/src/utils/formatters/migration-graph-rows.ts +336 -0
- package/src/utils/formatters/migration-graph-tree-render.ts +459 -0
- package/src/utils/formatters/migration-list-data-column.ts +115 -0
- package/src/utils/formatters/migration-list-graph-topology.ts +368 -0
- package/src/utils/formatters/migration-list-render.ts +191 -0
- package/src/utils/formatters/migration-list-styler.ts +63 -0
- package/src/utils/formatters/migration-list-types.ts +21 -0
- package/src/utils/formatters/migrations.ts +37 -46
- package/src/utils/glyph-mode.ts +22 -0
- package/src/utils/integrity-violation-to-check-failure.ts +130 -0
- package/src/utils/plan-resolution.ts +258 -0
- package/src/utils/ref-advancement.ts +68 -0
- package/src/utils/terminal-ui.ts +42 -1
- package/dist/cli-errors-Czmx92Zy.d.mts +0 -3
- package/dist/cli-errors-Djtz98Vm.mjs +0 -71
- package/dist/cli-errors-Djtz98Vm.mjs.map +0 -1
- package/dist/client-oXO2WCPD.mjs.map +0 -1
- package/dist/command-helpers-BSb0tRC8.mjs.map +0 -1
- package/dist/commands/migration-check.mjs.map +0 -1
- package/dist/commands/migration-graph.mjs.map +0 -1
- package/dist/contract-emit-bcrpT-wD.mjs.map +0 -1
- package/dist/contract-emit-r4y8Zhf1.mjs.map +0 -1
- package/dist/contract-enrichment-Dani0mMW.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs +0 -160
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs.map +0 -1
- package/dist/global-flags-CdE7M0d9.d.mts +0 -15
- package/dist/global-flags-CdE7M0d9.d.mts.map +0 -1
- package/dist/init-BCJZPWE1.mjs.map +0 -1
- package/dist/migration-plan-CFwqw3Gk.mjs.map +0 -1
- package/dist/migrations-CwZMa1Ck.mjs.map +0 -1
- package/dist/rolldown-runtime-twds-ZHy.mjs +0 -14
- package/dist/terminal-ui-BiB_8KNo.mjs +0 -379
- package/dist/terminal-ui-BiB_8KNo.mjs.map +0 -1
- package/dist/types--CqjMdk0.d.mts.map +0 -1
|
@@ -3,19 +3,12 @@ import type {
|
|
|
3
3
|
ControlDriverInstance,
|
|
4
4
|
ControlFamilyInstance,
|
|
5
5
|
MigrationOperationPolicy,
|
|
6
|
-
MultiSpaceCapableRunner,
|
|
7
|
-
MultiSpaceRunnerPerSpaceOptions,
|
|
8
6
|
TargetMigrationsCapability,
|
|
9
7
|
} from '@prisma-next/framework-components/control';
|
|
10
|
-
import {
|
|
11
|
-
import type {
|
|
12
|
-
AggregatePerSpacePlan,
|
|
13
|
-
ContractSpaceAggregate,
|
|
14
|
-
} from '@prisma-next/migration-tools/aggregate';
|
|
8
|
+
import type { ContractSpaceAggregate, PerSpacePlan } from '@prisma-next/migration-tools/aggregate';
|
|
15
9
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
16
10
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
17
|
-
import {
|
|
18
|
-
import type { AggregatePerSpaceExecutionEntry, OnControlProgress } from '../types';
|
|
11
|
+
import type { OnControlProgress, PerSpaceExecutionEntry } from '../types';
|
|
19
12
|
|
|
20
13
|
/**
|
|
21
14
|
* Span id emitted via `onProgress` for the apply phase. Stable
|
|
@@ -28,35 +21,35 @@ const APPLY_SPAN_ID = 'apply' as const;
|
|
|
28
21
|
* events so the parent CLI command can attribute the span correctly,
|
|
29
22
|
* and used to compose action-specific summary phrasing.
|
|
30
23
|
*/
|
|
31
|
-
export type
|
|
24
|
+
export type ApplyAction = 'dbInit' | 'dbUpdate' | 'migrationApply';
|
|
32
25
|
|
|
33
26
|
/**
|
|
34
|
-
* Failure variant emitted by {@link
|
|
35
|
-
*
|
|
27
|
+
* Failure variant emitted by {@link applyMigration} when the runner
|
|
28
|
+
* itself rejects the apply. Mirrors the failure shape callers
|
|
36
29
|
* already wrap into their own action-specific failure envelopes
|
|
37
30
|
* (`DbInitFailure`, `DbUpdateFailure`, `MigrationApplyFailure`) so each
|
|
38
31
|
* caller keeps owning its own discriminated failure code.
|
|
39
32
|
*/
|
|
40
|
-
export interface
|
|
33
|
+
export interface ApplyRunnerFailure {
|
|
41
34
|
readonly summary: string;
|
|
42
35
|
readonly why?: string;
|
|
43
36
|
readonly meta: Record<string, unknown>;
|
|
44
37
|
}
|
|
45
38
|
|
|
46
|
-
export interface
|
|
39
|
+
export interface ApplyMigrationInputs<TFamilyId extends string, TTargetId extends string> {
|
|
47
40
|
readonly aggregate: ContractSpaceAggregate;
|
|
48
41
|
/**
|
|
49
42
|
* Per-space plans, keyed by `spaceId`. Produced by either the full
|
|
50
|
-
* {@link
|
|
43
|
+
* {@link planMigration} pipeline (`db init` / `db update` — synth
|
|
51
44
|
* for the app, graph-walk for extensions) or by direct
|
|
52
45
|
* {@link graphWalkStrategy} calls (`migrate` — graph-walk
|
|
53
46
|
* for every member). Either way, the runner consumes the same shape.
|
|
54
47
|
*/
|
|
55
|
-
readonly perSpacePlans: ReadonlyMap<string,
|
|
48
|
+
readonly perSpacePlans: ReadonlyMap<string, PerSpacePlan>;
|
|
56
49
|
/**
|
|
57
50
|
* Canonical schedule order — extensions alphabetically by `spaceId`,
|
|
58
51
|
* then app. Mirrors {@link import('@prisma-next/migration-tools/concatenate-space-apply-inputs').concatenateSpaceApplyInputs}'s
|
|
59
|
-
* convention so `
|
|
52
|
+
* convention so `MigrationRunnerFailure.failingSpace` attribution
|
|
60
53
|
* stays byte-for-byte stable across callers.
|
|
61
54
|
*/
|
|
62
55
|
readonly applyOrder: readonly string[];
|
|
@@ -69,22 +62,22 @@ export interface ApplyAggregateInputs<TFamilyId extends string, TTargetId extend
|
|
|
69
62
|
>;
|
|
70
63
|
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
|
|
71
64
|
readonly policy: MigrationOperationPolicy;
|
|
72
|
-
readonly action:
|
|
65
|
+
readonly action: ApplyAction;
|
|
73
66
|
readonly onProgress?: OnControlProgress;
|
|
74
67
|
}
|
|
75
68
|
|
|
76
69
|
/**
|
|
77
70
|
* Resolved per-space plan in canonical schedule order. Surfaced from
|
|
78
|
-
* {@link
|
|
71
|
+
* {@link applyMigration} to callers so each one can build its own
|
|
79
72
|
* action-specific success envelope (e.g. `DbInitSuccess` vs
|
|
80
73
|
* `MigrationApplySuccess`) without re-deriving the ordering.
|
|
81
74
|
*/
|
|
82
75
|
export interface OrderedResolution {
|
|
83
76
|
readonly spaceId: string;
|
|
84
|
-
readonly entry:
|
|
77
|
+
readonly entry: PerSpacePlan;
|
|
85
78
|
}
|
|
86
79
|
|
|
87
|
-
export interface
|
|
80
|
+
export interface ApplyMigrationValue {
|
|
88
81
|
readonly orderedResolutions: readonly OrderedResolution[];
|
|
89
82
|
readonly totalOpsPlanned: number;
|
|
90
83
|
readonly totalOpsExecuted: number;
|
|
@@ -93,30 +86,30 @@ export interface ApplyAggregateValue {
|
|
|
93
86
|
* envelopes. Each entry carries the post-apply marker (live storage hash
|
|
94
87
|
* plus invariants) so callers can render it directly without re-reading.
|
|
95
88
|
*/
|
|
96
|
-
readonly perSpace: readonly
|
|
89
|
+
readonly perSpace: readonly PerSpaceExecutionEntry[];
|
|
97
90
|
}
|
|
98
91
|
|
|
99
|
-
export type
|
|
92
|
+
export type ApplyMigrationResult = Result<ApplyMigrationValue, ApplyRunnerFailure>;
|
|
100
93
|
|
|
101
94
|
/**
|
|
102
|
-
* Runner-driving tail shared by every
|
|
95
|
+
* Runner-driving tail shared by every apply caller — `db init`,
|
|
103
96
|
* `db update`, and `migrate`. Consumes already-resolved per-space
|
|
104
97
|
* plans (the planner-vs-replay distinction is owned by the caller) and
|
|
105
|
-
* dispatches them to the
|
|
98
|
+
* dispatches them to the runner in canonical order.
|
|
106
99
|
*
|
|
107
100
|
* Marker advancement is part of the runner's per-space transaction
|
|
108
101
|
* (the SQL family runner writes the marker as the last step of each
|
|
109
102
|
* space's transaction), so this primitive does not advance markers
|
|
110
|
-
* separately — by the time `
|
|
103
|
+
* separately — by the time `execute` returns ok, every
|
|
111
104
|
* space's marker has been advanced to its plan's destination.
|
|
112
105
|
*
|
|
113
106
|
* Span emission (`spanStart 'apply'` / `spanEnd 'apply'`) is owned here
|
|
114
107
|
* so callers don't have to duplicate it; the `action` field on each
|
|
115
108
|
* progress event is taken from the caller's `action` argument.
|
|
116
109
|
*/
|
|
117
|
-
export async function
|
|
118
|
-
inputs:
|
|
119
|
-
): Promise<
|
|
110
|
+
export async function applyMigration<TFamilyId extends string, TTargetId extends string>(
|
|
111
|
+
inputs: ApplyMigrationInputs<TFamilyId, TTargetId>,
|
|
112
|
+
): Promise<ApplyMigrationResult> {
|
|
120
113
|
const {
|
|
121
114
|
aggregate,
|
|
122
115
|
perSpacePlans,
|
|
@@ -133,14 +126,6 @@ export async function applyAggregate<TFamilyId extends string, TTargetId extends
|
|
|
133
126
|
const orderedResolutions = collectOrdered(applyOrder, perSpacePlans);
|
|
134
127
|
|
|
135
128
|
const runner = migrations.createRunner(familyInstance);
|
|
136
|
-
if (!hasMultiSpaceRunner(runner)) {
|
|
137
|
-
throw errorRunnerFailed(
|
|
138
|
-
`Runner for target "${aggregate.targetId}" does not implement \`executeAcrossSpaces\``,
|
|
139
|
-
{
|
|
140
|
-
why: `${labelForAction(action)} requires multi-space-capable runners (today: every SQL family runner).`,
|
|
141
|
-
},
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
129
|
|
|
145
130
|
onProgress?.({
|
|
146
131
|
action,
|
|
@@ -149,26 +134,21 @@ export async function applyAggregate<TFamilyId extends string, TTargetId extends
|
|
|
149
134
|
label: progressLabelForAction(action),
|
|
150
135
|
});
|
|
151
136
|
|
|
152
|
-
const perSpaceOptions
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
// typing.
|
|
166
|
-
strictVerification: false,
|
|
167
|
-
})) as MultiSpaceRunnerPerSpaceOptions<TFamilyId, TTargetId>[];
|
|
137
|
+
const perSpaceOptions = orderedResolutions.map((r) => ({
|
|
138
|
+
space: r.spaceId,
|
|
139
|
+
plan: r.entry.plan,
|
|
140
|
+
driver,
|
|
141
|
+
destinationContract: r.entry.destinationContract,
|
|
142
|
+
policy,
|
|
143
|
+
frameworkComponents,
|
|
144
|
+
// Per-space post-apply schema verification is non-strict: each
|
|
145
|
+
// space's `destinationContract` describes only its own slice; a
|
|
146
|
+
// strict verifier would treat every other space's tables as
|
|
147
|
+
// `extras`. Tolerant mode still catches missing tables / columns.
|
|
148
|
+
strictVerification: false,
|
|
149
|
+
}));
|
|
168
150
|
|
|
169
|
-
const runnerResult = await (
|
|
170
|
-
runner as MultiSpaceCapableRunner<TFamilyId, TTargetId>
|
|
171
|
-
).executeAcrossSpaces({ driver, perSpaceOptions });
|
|
151
|
+
const runnerResult = await runner.execute({ driver, perSpaceOptions });
|
|
172
152
|
|
|
173
153
|
if (!runnerResult.ok) {
|
|
174
154
|
onProgress?.({ action, kind: 'spanEnd', spanId: APPLY_SPAN_ID, outcome: 'error' });
|
|
@@ -207,28 +187,28 @@ export async function applyAggregate<TFamilyId extends string, TTargetId extends
|
|
|
207
187
|
|
|
208
188
|
/**
|
|
209
189
|
* Project the planner's per-space resolutions into the
|
|
210
|
-
* `
|
|
190
|
+
* `PerSpaceExecutionEntry[]` shape the CLI surfaces.
|
|
211
191
|
*
|
|
212
192
|
* `includeMarkers` is `true` for apply-mode (each space's marker is
|
|
213
193
|
* the `destination.storageHash` of its plan, which the runner
|
|
214
194
|
* advances as the last step of each space's transaction) and `false`
|
|
215
195
|
* for plan-mode (no marker has been written yet).
|
|
216
196
|
*
|
|
217
|
-
* Exported alongside {@link
|
|
197
|
+
* Exported alongside {@link applyMigration} so plan-mode callers can
|
|
218
198
|
* assemble the same per-space block without going through the runner.
|
|
219
199
|
*/
|
|
220
200
|
export function buildPerSpaceBreakdown(
|
|
221
201
|
orderedResolutions: readonly OrderedResolution[],
|
|
222
202
|
appSpaceId: string,
|
|
223
203
|
options: { readonly includeMarkers: boolean },
|
|
224
|
-
): readonly
|
|
204
|
+
): readonly PerSpaceExecutionEntry[] {
|
|
225
205
|
return orderedResolutions.map((r) => {
|
|
226
206
|
const operations = r.entry.displayOps.map((op) => ({
|
|
227
207
|
id: op.id,
|
|
228
208
|
label: op.label,
|
|
229
209
|
operationClass: op.operationClass,
|
|
230
210
|
}));
|
|
231
|
-
const base:
|
|
211
|
+
const base: PerSpaceExecutionEntry = {
|
|
232
212
|
spaceId: r.spaceId,
|
|
233
213
|
kind: r.spaceId === appSpaceId ? 'app' : 'extension',
|
|
234
214
|
operations,
|
|
@@ -251,12 +231,12 @@ export function buildPerSpaceBreakdown(
|
|
|
251
231
|
*/
|
|
252
232
|
export function collectOrdered(
|
|
253
233
|
applyOrder: readonly string[],
|
|
254
|
-
perSpace: ReadonlyMap<string,
|
|
234
|
+
perSpace: ReadonlyMap<string, PerSpacePlan>,
|
|
255
235
|
): readonly OrderedResolution[] {
|
|
256
236
|
return applyOrder.map((spaceId) => {
|
|
257
237
|
const entry = perSpace.get(spaceId);
|
|
258
238
|
if (!entry) {
|
|
259
|
-
throw new Error(`
|
|
239
|
+
throw new Error(`planner output missing per-space plan for "${spaceId}"`);
|
|
260
240
|
}
|
|
261
241
|
return { spaceId, entry };
|
|
262
242
|
});
|
|
@@ -264,11 +244,11 @@ export function collectOrdered(
|
|
|
264
244
|
|
|
265
245
|
/**
|
|
266
246
|
* Action-appropriate label for the `spanStart` event the apply
|
|
267
|
-
* primitive emits. `
|
|
247
|
+
* primitive emits. `applyMigration` is shared by `db init`, `db update`,
|
|
268
248
|
* and `migrate`; the span label tracks the user-visible action
|
|
269
249
|
* so structured-progress output reads naturally for each surface.
|
|
270
250
|
*/
|
|
271
|
-
export function progressLabelForAction(action:
|
|
251
|
+
export function progressLabelForAction(action: ApplyAction): string {
|
|
272
252
|
switch (action) {
|
|
273
253
|
case 'dbInit':
|
|
274
254
|
return 'Initialising database across spaces';
|
|
@@ -278,14 +258,3 @@ export function progressLabelForAction(action: AggregateApplyAction): string {
|
|
|
278
258
|
return 'Applying migration plan across spaces';
|
|
279
259
|
}
|
|
280
260
|
}
|
|
281
|
-
|
|
282
|
-
function labelForAction(action: AggregateApplyAction): string {
|
|
283
|
-
switch (action) {
|
|
284
|
-
case 'dbInit':
|
|
285
|
-
return 'db init';
|
|
286
|
-
case 'dbUpdate':
|
|
287
|
-
return 'db update';
|
|
288
|
-
case 'migrationApply':
|
|
289
|
-
return 'migrate';
|
|
290
|
-
}
|
|
291
|
-
}
|
|
@@ -5,7 +5,7 @@ import { createControlStack } from '@prisma-next/framework-components/control';
|
|
|
5
5
|
import { abortable } from '@prisma-next/utils/abortable';
|
|
6
6
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
7
7
|
import type { JsonObject } from '@prisma-next/utils/json';
|
|
8
|
-
import { dirname } from 'pathe';
|
|
8
|
+
import { dirname, join } from 'pathe';
|
|
9
9
|
import { loadConfig } from '../../config-loader';
|
|
10
10
|
import { errorContractConfigMissing, errorRuntime } from '../../utils/cli-errors';
|
|
11
11
|
import { queueEmitByOutput } from '../../utils/emit-queue';
|
|
@@ -153,7 +153,7 @@ function validateProviderResult(providerResult: unknown): ValidatedProviderResul
|
|
|
153
153
|
export async function executeContractEmit(
|
|
154
154
|
options: ContractEmitOptions,
|
|
155
155
|
): Promise<ContractEmitResult> {
|
|
156
|
-
const { configPath, signal = new AbortController().signal, onProgress } = options;
|
|
156
|
+
const { configPath, outputPath, signal = new AbortController().signal, onProgress } = options;
|
|
157
157
|
const unlessAborted = abortable(signal);
|
|
158
158
|
|
|
159
159
|
const config = await unlessAborted(loadConfig(configPath));
|
|
@@ -166,7 +166,10 @@ export async function executeContractEmit(
|
|
|
166
166
|
|
|
167
167
|
const contractConfig = config.contract;
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
const effectiveOutput =
|
|
170
|
+
outputPath !== undefined ? join(outputPath, 'contract.json') : contractConfig.output;
|
|
171
|
+
|
|
172
|
+
if (!effectiveOutput) {
|
|
170
173
|
throw errorContractConfigMissing({
|
|
171
174
|
why: 'Contract config must have output path. This should not happen if defineConfig() was used.',
|
|
172
175
|
});
|
|
@@ -180,7 +183,7 @@ export async function executeContractEmit(
|
|
|
180
183
|
|
|
181
184
|
let outputPaths: ReturnType<typeof getEmittedArtifactPaths>;
|
|
182
185
|
try {
|
|
183
|
-
outputPaths = getEmittedArtifactPaths(
|
|
186
|
+
outputPaths = getEmittedArtifactPaths(effectiveOutput);
|
|
184
187
|
} catch (error) {
|
|
185
188
|
throw errorContractConfigMissing({
|
|
186
189
|
why: error instanceof Error ? error.message : String(error),
|
|
@@ -250,13 +253,18 @@ export async function executeContractEmit(
|
|
|
250
253
|
// on-disk JSON envelope is constructed by target-owned code
|
|
251
254
|
// rather than by walking the in-memory contract with
|
|
252
255
|
// `Object.entries` (which would leak runtime-only class API
|
|
253
|
-
// fields into the persisted shape).
|
|
256
|
+
// fields into the persisted shape). The optional `shouldPreserveEmpty`
|
|
257
|
+
// and `sortStorage` hooks let the family contribute storage-specific
|
|
258
|
+
// canonicalization rules without the framework importing family code.
|
|
259
|
+
const { contractSerializer } = config.target;
|
|
254
260
|
const serializeContract = (c: Contract): JsonObject =>
|
|
255
|
-
|
|
261
|
+
contractSerializer.serializeContract(c);
|
|
256
262
|
emitResult = await unlessAborted(
|
|
257
263
|
emit(enrichedIR, stack, config.family.emission, {
|
|
258
264
|
outputJsonPath,
|
|
259
265
|
serializeContract,
|
|
266
|
+
...ifDefined('shouldPreserveEmpty', contractSerializer.shouldPreserveEmpty),
|
|
267
|
+
...ifDefined('sortStorage', contractSerializer.sortStorage),
|
|
260
268
|
}),
|
|
261
269
|
);
|
|
262
270
|
} catch (error) {
|
|
@@ -11,9 +11,9 @@ import type {
|
|
|
11
11
|
} from '@prisma-next/framework-components/control';
|
|
12
12
|
import { hasOperationPreview } from '@prisma-next/framework-components/control';
|
|
13
13
|
import {
|
|
14
|
-
type AggregatePlannerError,
|
|
15
14
|
type ContractSpaceAggregate,
|
|
16
|
-
|
|
15
|
+
type PlannerError,
|
|
16
|
+
planMigration,
|
|
17
17
|
} from '@prisma-next/migration-tools/aggregate';
|
|
18
18
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
19
19
|
import { notOk, ok } from '@prisma-next/utils/result';
|
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
buildContractSpaceAggregate,
|
|
24
24
|
} from '../../utils/contract-space-aggregate-loader';
|
|
25
25
|
import type {
|
|
26
|
-
AggregatePerSpaceExecutionEntry,
|
|
27
26
|
DbInitFailure,
|
|
28
27
|
DbInitResult,
|
|
29
28
|
DbInitSuccess,
|
|
@@ -31,15 +30,16 @@ import type {
|
|
|
31
30
|
DbUpdateResult,
|
|
32
31
|
DbUpdateSuccess,
|
|
33
32
|
OnControlProgress,
|
|
33
|
+
PerSpaceExecutionEntry,
|
|
34
34
|
} from '../types';
|
|
35
|
-
import {
|
|
35
|
+
import { applyMigration, buildPerSpaceBreakdown, collectOrdered } from './apply';
|
|
36
36
|
import { stripOperations } from './migration-helpers';
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* Span IDs emitted via `onProgress` during the
|
|
39
|
+
* Span IDs emitted via `onProgress` during the apply flow.
|
|
40
40
|
* Stable identifiers consumed by the structured-output renderer and by
|
|
41
41
|
* tests asserting on span ids. The `apply` span itself is owned by
|
|
42
|
-
* the {@link
|
|
42
|
+
* the {@link applyMigration} primitive — only the introspect / plan
|
|
43
43
|
* spans are emitted directly here.
|
|
44
44
|
*/
|
|
45
45
|
const SPAN_IDS = {
|
|
@@ -48,13 +48,13 @@ const SPAN_IDS = {
|
|
|
48
48
|
} as const;
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
* Inputs shared by `db init` and `db update`
|
|
51
|
+
* Inputs shared by `db init` and `db update` apply flows.
|
|
52
52
|
*
|
|
53
53
|
* Accepts the already-validated app contract + descriptor list — the
|
|
54
54
|
* loader gathers the rest from disk + descriptors. The CLI is the
|
|
55
55
|
* descriptor-import boundary; everything downstream is descriptor-free.
|
|
56
56
|
*/
|
|
57
|
-
export interface
|
|
57
|
+
export interface ExecuteApplyOptions<TFamilyId extends string, TTargetId extends string> {
|
|
58
58
|
readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;
|
|
59
59
|
readonly familyInstance: ControlFamilyInstance<TFamilyId, unknown>;
|
|
60
60
|
readonly contract: Contract;
|
|
@@ -83,17 +83,17 @@ export interface ExecuteAggregateApplyOptions<TFamilyId extends string, TTargetI
|
|
|
83
83
|
* integrity violation short-circuits with a structured error.
|
|
84
84
|
* 2. **Read DB state**: marker rows (`familyInstance.readAllMarkers`)
|
|
85
85
|
* + introspected schema (`familyInstance.introspect`).
|
|
86
|
-
* 3. **Plan**: {@link
|
|
86
|
+
* 3. **Plan**: {@link planMigration} chooses graph-walk vs synth per
|
|
87
87
|
* member according to `callerPolicy.ignoreGraphFor`. The app member
|
|
88
88
|
* is forced through synth (today's daily-driver behaviour); every
|
|
89
89
|
* extension member walks its on-disk graph.
|
|
90
90
|
* 4. **Apply** (when `mode === 'apply'`): every per-space `MigrationPlan`
|
|
91
|
-
* feeds into the runner's `
|
|
91
|
+
* feeds into the runner's `execute` — one outer
|
|
92
92
|
* transaction across every space; failure on any space rolls back
|
|
93
93
|
* every space's writes.
|
|
94
94
|
*/
|
|
95
|
-
export async function
|
|
96
|
-
options:
|
|
95
|
+
export async function executeApply<TFamilyId extends string, TTargetId extends string>(
|
|
96
|
+
options: ExecuteApplyOptions<TFamilyId, TTargetId>,
|
|
97
97
|
): Promise<DbInitResult | DbUpdateResult> {
|
|
98
98
|
const {
|
|
99
99
|
driver,
|
|
@@ -159,7 +159,7 @@ export async function executeAggregateApply<TFamilyId extends string, TTargetId
|
|
|
159
159
|
spanId: SPAN_IDS.plan,
|
|
160
160
|
label: 'Planning migration',
|
|
161
161
|
});
|
|
162
|
-
const planResult = await
|
|
162
|
+
const planResult = await planMigration<TFamilyId, TTargetId>({
|
|
163
163
|
aggregate,
|
|
164
164
|
currentDBState: { markersBySpaceId: markerRows, schemaIntrospection: schemaIR },
|
|
165
165
|
familyInstance,
|
|
@@ -205,13 +205,13 @@ export async function executeAggregateApply<TFamilyId extends string, TTargetId
|
|
|
205
205
|
});
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
// 5. Apply mode: hand off to the shared `
|
|
208
|
+
// 5. Apply mode: hand off to the shared `applyMigration` primitive.
|
|
209
209
|
// The runner-driving tail is identical for `db init` / `db update` /
|
|
210
210
|
// `migrate` — only how each caller produces `perSpacePlans`
|
|
211
|
-
// differs (synth + graph-walk via
|
|
211
|
+
// differs (synth + graph-walk via planMigration here; graph-walk
|
|
212
212
|
// only for migrate). Each caller produces perSpacePlans differently;
|
|
213
213
|
// this helper handles the shared apply tail.
|
|
214
|
-
const applied = await
|
|
214
|
+
const applied = await applyMigration({
|
|
215
215
|
aggregate,
|
|
216
216
|
perSpacePlans: planResult.value.perSpace,
|
|
217
217
|
applyOrder: planResult.value.applyOrder,
|
|
@@ -298,7 +298,7 @@ function detectOrphanMarkers(
|
|
|
298
298
|
});
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
function mapPlannerError(error:
|
|
301
|
+
function mapPlannerError(error: PlannerError): DbInitResult | DbUpdateResult {
|
|
302
302
|
if (error.kind === 'appSynthFailure') {
|
|
303
303
|
const failure: DbInitFailure | DbUpdateFailure = {
|
|
304
304
|
code: 'PLANNING_FAILED',
|
|
@@ -337,7 +337,7 @@ function wrapPlanResult(args: {
|
|
|
337
337
|
readonly operations: readonly MigrationPlanOperation[];
|
|
338
338
|
readonly destination: { readonly storageHash: string; readonly profileHash?: string };
|
|
339
339
|
readonly preview: OperationPreview | undefined;
|
|
340
|
-
readonly perSpace: readonly
|
|
340
|
+
readonly perSpace: readonly PerSpaceExecutionEntry[];
|
|
341
341
|
readonly summary: string;
|
|
342
342
|
}): DbInitResult | DbUpdateResult {
|
|
343
343
|
const success: DbInitSuccess | DbUpdateSuccess = {
|
|
@@ -361,7 +361,7 @@ function wrapApplyResult(args: {
|
|
|
361
361
|
readonly destination: { readonly storageHash: string; readonly profileHash?: string };
|
|
362
362
|
readonly operationsPlanned: number;
|
|
363
363
|
readonly operationsExecuted: number;
|
|
364
|
-
readonly perSpace: readonly
|
|
364
|
+
readonly perSpace: readonly PerSpaceExecutionEntry[];
|
|
365
365
|
readonly summary: string;
|
|
366
366
|
}): DbInitResult | DbUpdateResult {
|
|
367
367
|
const success: DbInitSuccess | DbUpdateSuccess = {
|
|
@@ -8,20 +8,20 @@ import type {
|
|
|
8
8
|
} from '@prisma-next/framework-components/control';
|
|
9
9
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
10
10
|
import type { DbInitResult, OnControlProgress } from '../types';
|
|
11
|
-
import {
|
|
11
|
+
import { executeApply } from './db-apply';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Options for executing the `db init` operation.
|
|
15
15
|
*
|
|
16
16
|
* `db init` runs the loader → planner → runner pipeline:
|
|
17
17
|
*
|
|
18
|
-
* 1. {@link
|
|
18
|
+
* 1. {@link executeApply} loads a `ContractSpaceAggregate` via
|
|
19
19
|
* {@link import('@prisma-next/migration-tools/aggregate').loadContractSpaceAggregate}
|
|
20
20
|
* from the supplied descriptor set + on-disk on-disk artefacts.
|
|
21
21
|
* 2. The aggregate planner runs with `callerPolicy.ignoreGraphFor`
|
|
22
22
|
* locked to the app member — synth strategy for the app, graph-walk
|
|
23
23
|
* for every extension.
|
|
24
|
-
* 3. The runner's `
|
|
24
|
+
* 3. The runner's `execute` applies the per-space plans
|
|
25
25
|
* inside one outer transaction.
|
|
26
26
|
*
|
|
27
27
|
* `extensionPacks` mirrors `Config.extensionPacks` (descriptor list).
|
|
@@ -68,7 +68,7 @@ export interface ExecuteDbInitOptions<TFamilyId extends string, TTargetId extend
|
|
|
68
68
|
export async function executeDbInit<TFamilyId extends string, TTargetId extends string>(
|
|
69
69
|
options: ExecuteDbInitOptions<TFamilyId, TTargetId>,
|
|
70
70
|
): Promise<DbInitResult> {
|
|
71
|
-
const result = await
|
|
71
|
+
const result = await executeApply<TFamilyId, TTargetId>({
|
|
72
72
|
driver: options.driver,
|
|
73
73
|
familyInstance: options.familyInstance,
|
|
74
74
|
contract: options.contract,
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
10
10
|
import { notOk } from '@prisma-next/utils/result';
|
|
11
11
|
import type { DbUpdateResult, OnControlProgress } from '../types';
|
|
12
|
-
import {
|
|
12
|
+
import { executeApply } from './db-apply';
|
|
13
13
|
|
|
14
14
|
const DB_UPDATE_POLICY = {
|
|
15
15
|
allowedOperationClasses: ['additive', 'widening', 'destructive'] as const,
|
|
@@ -71,7 +71,7 @@ export async function executeDbUpdate<TFamilyId extends string, TTargetId extend
|
|
|
71
71
|
const gate = await guardDestructiveChanges<TFamilyId, TTargetId>(sharedInputs);
|
|
72
72
|
if (gate !== null) return gate;
|
|
73
73
|
}
|
|
74
|
-
return (await
|
|
74
|
+
return (await executeApply<TFamilyId, TTargetId>({
|
|
75
75
|
...sharedInputs,
|
|
76
76
|
mode: options.mode,
|
|
77
77
|
})) as DbUpdateResult;
|
|
@@ -85,9 +85,9 @@ export async function executeDbUpdate<TFamilyId extends string, TTargetId extend
|
|
|
85
85
|
* run.
|
|
86
86
|
*/
|
|
87
87
|
async function guardDestructiveChanges<TFamilyId extends string, TTargetId extends string>(
|
|
88
|
-
sharedInputs: Omit<Parameters<typeof
|
|
88
|
+
sharedInputs: Omit<Parameters<typeof executeApply<TFamilyId, TTargetId>>[0], 'mode'>,
|
|
89
89
|
): Promise<DbUpdateResult | null> {
|
|
90
|
-
const planResult = (await
|
|
90
|
+
const planResult = (await executeApply<TFamilyId, TTargetId>({
|
|
91
91
|
...sharedInputs,
|
|
92
92
|
mode: 'plan',
|
|
93
93
|
})) as DbUpdateResult;
|
|
@@ -7,10 +7,12 @@ import type {
|
|
|
7
7
|
VerifyDatabaseSchemaResult,
|
|
8
8
|
} from '@prisma-next/framework-components/control';
|
|
9
9
|
import {
|
|
10
|
-
type AggregateVerifierOutput,
|
|
11
10
|
type ContractSpaceMember,
|
|
12
|
-
|
|
11
|
+
requireHeadRef,
|
|
12
|
+
type VerifierOutput,
|
|
13
|
+
verifyMigration,
|
|
13
14
|
} from '@prisma-next/migration-tools/aggregate';
|
|
15
|
+
import { castAs } from '@prisma-next/utils/casts';
|
|
14
16
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
15
17
|
import { CliStructuredError } from '../../utils/cli-errors';
|
|
16
18
|
import {
|
|
@@ -82,7 +84,7 @@ export type ExecuteDbVerifyResult = Result<ExecuteDbVerifySuccess, CliStructured
|
|
|
82
84
|
* structured CLI error.
|
|
83
85
|
* 2. **Read DB state**: marker rows + (when `skipSchema` is `false`)
|
|
84
86
|
* schema introspection.
|
|
85
|
-
* 3. **Verify**: {@link
|
|
87
|
+
* 3. **Verify**: {@link verifyMigration} returns per-space
|
|
86
88
|
* `markerCheck` + per-space pre-projected `schemaCheck` (closes F23).
|
|
87
89
|
* Marker mismatches map to `CliStructuredError` (code `5002`) so
|
|
88
90
|
* callers (CLI command) can render and exit. Schema results are
|
|
@@ -102,7 +104,7 @@ export async function executeDbVerify<TFamilyId extends string, TTargetId extend
|
|
|
102
104
|
: await runIntrospection({ driver, familyInstance, onProgress });
|
|
103
105
|
|
|
104
106
|
emitVerifySpan(onProgress, 'spanStart');
|
|
105
|
-
const verifyResult =
|
|
107
|
+
const verifyResult = verifyMigration({
|
|
106
108
|
aggregate,
|
|
107
109
|
markersBySpaceId,
|
|
108
110
|
schemaIntrospection,
|
|
@@ -162,7 +164,7 @@ async function runIntrospection<TFamilyId extends string, TTargetId extends stri
|
|
|
162
164
|
* `ok` result so the verifier still runs the (cheap) schemaCheck loop
|
|
163
165
|
* without invoking the family's verification path.
|
|
164
166
|
*/
|
|
165
|
-
function createPerMemberVerifier<TFamilyId extends string, TTargetId extends string>(
|
|
167
|
+
export function createPerMemberVerifier<TFamilyId extends string, TTargetId extends string>(
|
|
166
168
|
options: ExecuteDbVerifyOptions<TFamilyId, TTargetId>,
|
|
167
169
|
): (
|
|
168
170
|
projectedSchema: unknown,
|
|
@@ -173,7 +175,7 @@ function createPerMemberVerifier<TFamilyId extends string, TTargetId extends str
|
|
|
173
175
|
return (projectedSchema, member, verifyMode) => {
|
|
174
176
|
if (skipSchema) return buildSkippedSchemaResult(member);
|
|
175
177
|
return familyInstance.verifySchema({
|
|
176
|
-
contract: member.contract,
|
|
178
|
+
contract: member.contract(),
|
|
177
179
|
// The family's `TSchemaIR` is opaque to migration-tools; the
|
|
178
180
|
// aggregate verifier passes through whatever we hand it. The
|
|
179
181
|
// family expects its own IR shape on the way back.
|
|
@@ -206,12 +208,12 @@ function emitVerifySpan(
|
|
|
206
208
|
}
|
|
207
209
|
|
|
208
210
|
/**
|
|
209
|
-
* Map an {@link
|
|
211
|
+
* Map an {@link VerifierOutput} to the operation's
|
|
210
212
|
* {@link ExecuteDbVerifyResult}, applying the `skipMarker` policy used
|
|
211
213
|
* by the CLI's `--schema-only` mode.
|
|
212
214
|
*/
|
|
213
215
|
function finaliseVerifyResult(args: {
|
|
214
|
-
verifyResult:
|
|
216
|
+
verifyResult: VerifierOutput<VerifyDatabaseSchemaResult>;
|
|
215
217
|
aggregate: {
|
|
216
218
|
readonly app: { readonly spaceId: string };
|
|
217
219
|
readonly extensions: ReadonlyArray<{ readonly spaceId: string }>;
|
|
@@ -247,15 +249,17 @@ function finaliseVerifyResult(args: {
|
|
|
247
249
|
}
|
|
248
250
|
|
|
249
251
|
function buildSkippedSchemaResult(member: ContractSpaceMember): VerifyDatabaseSchemaResult {
|
|
250
|
-
const
|
|
252
|
+
const contract = member.contract();
|
|
253
|
+
const headRef = requireHeadRef(member);
|
|
254
|
+
const profileHash = castAs<{ profileHash?: string }>(contract).profileHash;
|
|
251
255
|
return {
|
|
252
256
|
ok: true,
|
|
253
257
|
summary: 'Schema verification skipped',
|
|
254
258
|
contract: {
|
|
255
|
-
storageHash:
|
|
259
|
+
storageHash: headRef.hash,
|
|
256
260
|
...(profileHash ? { profileHash } : {}),
|
|
257
261
|
},
|
|
258
|
-
target: { expected:
|
|
262
|
+
target: { expected: contract.target },
|
|
259
263
|
schema: {
|
|
260
264
|
issues: [],
|
|
261
265
|
root: {
|