@prisma-next/cli 0.14.0 → 0.15.0-dev.10
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 +2 -2
- package/dist/cli.mjs +33 -14
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-CJzuo5wX.mjs → client-DwOyZz0a.mjs} +141 -123
- package/dist/client-DwOyZz0a.mjs.map +1 -0
- package/dist/{command-helpers-DGMvGBeX.mjs → command-helpers-CNwURRf9.mjs} +30 -11
- package/dist/command-helpers-CNwURRf9.mjs.map +1 -0
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.mjs +3 -3
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +5 -5
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.mjs +4 -4
- package/dist/commands/db-verify.d.mts.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +37 -38
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +1 -1
- package/dist/commands/migration-check.mjs +1 -1
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.mjs +9 -9
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.d.mts +6 -6
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +1 -1
- package/dist/commands/migration-log.d.mts +1 -1
- package/dist/commands/migration-log.mjs +1 -1
- package/dist/commands/migration-new.mjs +4 -4
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.mjs +4 -4
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +1 -1
- package/dist/commands/migration-status.mjs +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +3 -3
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/commands/telemetry/index.mjs +1 -1
- package/dist/{contract-at-errors-CFXsstzm.mjs → contract-at-errors-BHbY04pl.mjs} +2 -2
- package/dist/{contract-at-errors-CFXsstzm.mjs.map → contract-at-errors-BHbY04pl.mjs.map} +1 -1
- package/dist/{contract-emit-C8HmtboH.mjs → contract-emit-BeidkyUC.mjs} +9 -11
- package/dist/contract-emit-BeidkyUC.mjs.map +1 -0
- package/dist/{contract-emit-B_qriF8B.mjs → contract-emit-IQBYv351.mjs} +6 -6
- package/dist/contract-emit-IQBYv351.mjs.map +1 -0
- package/dist/{contract-infer-BYT_ra_U.mjs → contract-infer-B3Wq2cu1.mjs} +3 -3
- package/dist/{contract-infer-BYT_ra_U.mjs.map → contract-infer-B3Wq2cu1.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-ClI1KN6d.mjs → contract-space-aggregate-loader-BirzMmW1.mjs} +63 -5
- package/dist/contract-space-aggregate-loader-BirzMmW1.mjs.map +1 -0
- package/dist/{db-verify-C24FKhb7.mjs → db-verify-DpRrecs7.mjs} +57 -61
- package/dist/db-verify-DpRrecs7.mjs.map +1 -0
- 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 +2 -2
- package/dist/exports/index.d.mts +5 -1
- package/dist/exports/index.d.mts.map +1 -1
- package/dist/exports/index.mjs +4 -3
- package/dist/exports/index.mjs.map +1 -1
- package/dist/format-CaCF63ld.mjs +102 -0
- package/dist/format-CaCF63ld.mjs.map +1 -0
- package/dist/{framework-components-YVQHhPH7.mjs → framework-components-CnBcJDmF.mjs} +2 -2
- package/dist/{framework-components-YVQHhPH7.mjs.map → framework-components-CnBcJDmF.mjs.map} +1 -1
- package/dist/{init-0HwB-Vh8.mjs → init-Boa0LzeJ.mjs} +27 -19
- package/dist/init-Boa0LzeJ.mjs.map +1 -0
- package/dist/{inspect-live-schema-DF6IwcDl.mjs → inspect-live-schema-CldSQjVI.mjs} +4 -4
- package/dist/inspect-live-schema-CldSQjVI.mjs.map +1 -0
- package/dist/{migration-check-VwM8xCZV.mjs → migration-check-CGtYnR9k.mjs} +10 -11
- package/dist/migration-check-CGtYnR9k.mjs.map +1 -0
- package/dist/migration-cli.mjs +1 -1
- package/dist/migration-cli.mjs.map +1 -1
- package/dist/{migration-command-scaffold-DA-Lhx6o.mjs → migration-command-scaffold-B3m-MMAx.mjs} +4 -4
- package/dist/migration-command-scaffold-B3m-MMAx.mjs.map +1 -0
- package/dist/{migration-graph-command-render-CEez7YUK.mjs → migration-graph-command-render-B83xrnNy.mjs} +24 -24
- package/dist/{migration-graph-command-render-CEez7YUK.mjs.map → migration-graph-command-render-B83xrnNy.mjs.map} +1 -1
- package/dist/{migration-list-DlJJ_38Z.mjs → migration-list-DBU6Pneg.mjs} +16 -16
- package/dist/migration-list-DBU6Pneg.mjs.map +1 -0
- package/dist/{migration-log-CG0qQAFm.mjs → migration-log-BYngyvXa.mjs} +5 -5
- package/dist/migration-log-BYngyvXa.mjs.map +1 -0
- package/dist/{migration-path-target-Ce6OZImp.mjs → migration-path-target-DQa4Caoc.mjs} +2 -2
- package/dist/{migration-path-target-Ce6OZImp.mjs.map → migration-path-target-DQa4Caoc.mjs.map} +1 -1
- package/dist/{migration-plan-W_E8FQOk.mjs → migration-plan-D6bHpCzE.mjs} +30 -30
- package/dist/migration-plan-D6bHpCzE.mjs.map +1 -0
- package/dist/{migration-status-CD-LC2Ip.mjs → migration-status-CpQ5UhcU.mjs} +14 -14
- package/dist/migration-status-CpQ5UhcU.mjs.map +1 -0
- package/dist/{telemetry-BIM4beEO.mjs → telemetry-BQJ_XHa9.mjs} +2 -2
- package/dist/{telemetry-BIM4beEO.mjs.map → telemetry-BQJ_XHa9.mjs.map} +1 -1
- package/dist/{types-C_tYiJYx.d.mts → types-DFoqNIcQ.d.mts} +27 -21
- package/dist/types-DFoqNIcQ.d.mts.map +1 -0
- package/dist/{verify-DcOYZ1tH.mjs → verify-CInGyt4U.mjs} +58 -159
- package/dist/verify-CInGyt4U.mjs.map +1 -0
- package/package.json +28 -30
- package/src/cli.ts +7 -0
- package/src/commands/contract-emit.ts +1 -1
- package/src/commands/db-sign.ts +1 -1
- package/src/commands/db-verify.ts +34 -20
- package/src/commands/format.ts +75 -0
- package/src/commands/init/detect-package-manager.ts +8 -4
- package/src/commands/init/hygiene-package-scripts.ts +16 -3
- package/src/commands/inspect-live-schema.ts +1 -1
- package/src/commands/lsp.ts +32 -0
- package/src/commands/migrate.ts +47 -44
- package/src/commands/migration-check.ts +6 -6
- package/src/commands/migration-graph.ts +5 -5
- package/src/commands/migration-list.ts +13 -13
- package/src/commands/migration-log.ts +1 -1
- package/src/commands/migration-new.ts +1 -1
- package/src/commands/migration-plan.ts +15 -4
- package/src/commands/migration-show.ts +1 -1
- package/src/commands/migration-status.ts +10 -10
- package/src/commands/ref.ts +1 -1
- package/src/control-api/client.ts +8 -23
- package/src/control-api/operations/contract-emit.ts +9 -27
- package/src/control-api/operations/db-init.ts +2 -2
- package/src/control-api/operations/db-run.ts +18 -17
- package/src/control-api/operations/db-verify.ts +52 -44
- package/src/control-api/operations/format.ts +98 -0
- package/src/control-api/operations/migrate.ts +139 -95
- package/src/control-api/operations/run-migration.ts +6 -5
- package/src/control-api/types.ts +8 -8
- package/src/exports/index.ts +1 -0
- package/src/migration-cli.ts +1 -1
- package/src/utils/cli-errors.ts +14 -1
- package/src/utils/combine-verify-results.ts +94 -0
- package/src/utils/extension-pack-inputs.ts +1 -1
- package/src/utils/formatters/errors.ts +34 -5
- package/src/utils/formatters/verify.ts +89 -227
- package/src/utils/migration-command-scaffold.ts +1 -1
- package/src/utils/plan-resolution.ts +18 -18
- package/dist/client-CJzuo5wX.mjs.map +0 -1
- package/dist/command-helpers-DGMvGBeX.mjs.map +0 -1
- package/dist/config-loader-p9JMrekQ.mjs +0 -88
- package/dist/config-loader-p9JMrekQ.mjs.map +0 -1
- package/dist/config-loader.d.mts +0 -16
- package/dist/config-loader.d.mts.map +0 -1
- package/dist/config-loader.mjs +0 -2
- package/dist/contract-emit-B_qriF8B.mjs.map +0 -1
- package/dist/contract-emit-C8HmtboH.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-ClI1KN6d.mjs.map +0 -1
- package/dist/db-verify-C24FKhb7.mjs.map +0 -1
- package/dist/extension-pack-inputs-1ySHqxKG.mjs +0 -62
- package/dist/extension-pack-inputs-1ySHqxKG.mjs.map +0 -1
- package/dist/init-0HwB-Vh8.mjs.map +0 -1
- package/dist/inspect-live-schema-DF6IwcDl.mjs.map +0 -1
- package/dist/migration-check-VwM8xCZV.mjs.map +0 -1
- package/dist/migration-command-scaffold-DA-Lhx6o.mjs.map +0 -1
- package/dist/migration-list-DlJJ_38Z.mjs.map +0 -1
- package/dist/migration-log-CG0qQAFm.mjs.map +0 -1
- package/dist/migration-plan-W_E8FQOk.mjs.map +0 -1
- package/dist/migration-status-CD-LC2Ip.mjs.map +0 -1
- package/dist/types-C_tYiJYx.d.mts.map +0 -1
- package/dist/verify-DcOYZ1tH.mjs.map +0 -1
- package/src/config-loader.ts +0 -92
- package/src/config-path-validation.ts +0 -74
- package/src/utils/combine-schema-results.ts +0 -84
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { F as CliStructuredError } from "./command-helpers-
|
|
2
|
-
import {
|
|
3
|
-
import { t as assertFrameworkComponentsCompatible } from "./framework-components-YVQHhPH7.mjs";
|
|
1
|
+
import { F as CliStructuredError } from "./command-helpers-CNwURRf9.mjs";
|
|
2
|
+
import { t as assertFrameworkComponentsCompatible } from "./framework-components-CnBcJDmF.mjs";
|
|
4
3
|
import { t as enrichContract } from "./contract-enrichment-gn9sWbPw.mjs";
|
|
5
|
-
import { t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-
|
|
4
|
+
import { t as buildContractSpaceAggregate } from "./contract-space-aggregate-loader-BirzMmW1.mjs";
|
|
6
5
|
import { emit } from "@prisma-next/emitter";
|
|
7
6
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
8
7
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
9
|
-
import { APP_SPACE_ID, createControlStack, hasMigrations, hasOperationPreview, hasPslContractInfer, hasSchemaView } from "@prisma-next/framework-components/control";
|
|
8
|
+
import { APP_SPACE_ID, createControlStack, hasMigrations, hasOperationPreview, hasPslContractInfer, hasSchemaSubjectClassifier, hasSchemaView } from "@prisma-next/framework-components/control";
|
|
10
9
|
import { blindCast, castAs } from "@prisma-next/utils/casts";
|
|
11
|
-
import {
|
|
10
|
+
import { allStorageElementsExternal, buildFabricatedMigrationEdge, collectAggregateNamespaces, planMigration, requireHeadRef, resolveRecordedPath, verifyMigration } from "@prisma-next/migration-tools/aggregate";
|
|
12
11
|
import { EMPTY_CONTRACT_HASH } from "@prisma-next/migration-tools/constants";
|
|
13
12
|
import { errorNoInvariantPath } from "@prisma-next/migration-tools/errors";
|
|
14
13
|
import { findPathWithDecision } from "@prisma-next/migration-tools/migration-graph";
|
|
@@ -144,7 +143,7 @@ function buildPerSpaceBreakdown(orderedResolutions, appSpaceId, options) {
|
|
|
144
143
|
}
|
|
145
144
|
/**
|
|
146
145
|
* Materialise the `applyOrder` ordering into resolved per-space
|
|
147
|
-
* entries. Throws if the planner output is missing a
|
|
146
|
+
* entries. Throws if the planner output is missing a contract space listed
|
|
148
147
|
* in `applyOrder` — a wiring bug that should never reach runtime.
|
|
149
148
|
*
|
|
150
149
|
* Exported so callers building their own success envelopes after a
|
|
@@ -196,10 +195,11 @@ const SPAN_IDS$1 = {
|
|
|
196
195
|
* integrity violation short-circuits with a structured error.
|
|
197
196
|
* 2. **Read DB state**: marker rows (`familyInstance.readAllMarkers`)
|
|
198
197
|
* + introspected schema (`familyInstance.introspect`).
|
|
199
|
-
* 3. **Plan**: {@link planMigration} chooses
|
|
200
|
-
*
|
|
201
|
-
* is forced through
|
|
202
|
-
* extension
|
|
198
|
+
* 3. **Plan**: {@link planMigration} chooses `resolveRecordedPath` vs
|
|
199
|
+
* `planFromDiff` per space according to `callerPolicy.ignoreGraphFor`.
|
|
200
|
+
* The app space is forced through `planFromDiff` (today's daily-driver
|
|
201
|
+
* behaviour); every extension space walks its on-disk graph via
|
|
202
|
+
* `resolveRecordedPath`.
|
|
203
203
|
* 4. **Apply** (when `mode === 'apply'`): every per-space `MigrationPlan`
|
|
204
204
|
* feeds into the runner's `execute` — one outer
|
|
205
205
|
* transaction across every space; failure on any space rolls back
|
|
@@ -252,7 +252,7 @@ async function executeRun(options) {
|
|
|
252
252
|
adapter,
|
|
253
253
|
migrations,
|
|
254
254
|
frameworkComponents,
|
|
255
|
-
callerPolicy: { ignoreGraphFor: new Set([aggregate.app.spaceId]) },
|
|
255
|
+
callerPolicy: { ignoreGraphFor: /* @__PURE__ */ new Set([aggregate.app.spaceId]) },
|
|
256
256
|
operationPolicy: policy
|
|
257
257
|
});
|
|
258
258
|
if (!planResult.ok) {
|
|
@@ -273,7 +273,7 @@ async function executeRun(options) {
|
|
|
273
273
|
const orderedResolutions = collectOrdered(planResult.value.applyOrder, planResult.value.perSpace);
|
|
274
274
|
const plannerWarnings = aggregatePlannerWarnings(orderedResolutions);
|
|
275
275
|
const appResolution = orderedResolutions.find((r) => r.spaceId === aggregate.app.spaceId);
|
|
276
|
-
if (!appResolution) throw new Error("Aggregate planner returned no plan for the app
|
|
276
|
+
if (!appResolution) throw new Error("Aggregate planner returned no plan for the app space — the planner is supposed to always emit one.");
|
|
277
277
|
const appPlan = appResolution.entry.plan;
|
|
278
278
|
if (mode === "plan") {
|
|
279
279
|
const aggregateOps = orderedResolutions.flatMap((r) => r.entry.displayOps);
|
|
@@ -325,22 +325,22 @@ function aggregatePlannerWarnings(orderedResolutions) {
|
|
|
325
325
|
}
|
|
326
326
|
/**
|
|
327
327
|
* Compare the live `_prisma_marker` rows against the aggregate's
|
|
328
|
-
* declared
|
|
328
|
+
* declared contract spaces. Any marker row whose `space` is not a space of
|
|
329
329
|
* the aggregate is an "orphan" — typically a marker left behind by
|
|
330
330
|
* an extension that was removed from `extensionPacks` without first
|
|
331
331
|
* cleaning up its on-disk migrations / database tables.
|
|
332
332
|
*
|
|
333
333
|
* Returns a {@link CliStructuredError} envelope (code `5002`,
|
|
334
334
|
* `kind: 'orphanMarker'`) for the first orphan it finds, or `null`
|
|
335
|
-
* when every marker row maps to a declared
|
|
335
|
+
* when every marker row maps to a declared contract space. Mirrors the M2
|
|
336
336
|
* `runContractSpaceVerifierMarkerCheck` envelope so downstream
|
|
337
337
|
* tooling (integration tests, JSON consumers) keeps asserting on the
|
|
338
338
|
* same shape.
|
|
339
339
|
*/
|
|
340
340
|
function detectOrphanMarkers(aggregate, markerRows) {
|
|
341
|
-
const
|
|
341
|
+
const aggregateSpaceIds = /* @__PURE__ */ new Set([aggregate.app.spaceId, ...aggregate.extensions.map((m) => m.spaceId)]);
|
|
342
342
|
const orphans = [];
|
|
343
|
-
for (const [spaceId, row] of markerRows) if (row !== null && row !== void 0 && !
|
|
343
|
+
for (const [spaceId, row] of markerRows) if (row !== null && row !== void 0 && !aggregateSpaceIds.has(spaceId)) orphans.push(spaceId);
|
|
344
344
|
if (orphans.length === 0) return null;
|
|
345
345
|
orphans.sort((a, b) => a.localeCompare(b));
|
|
346
346
|
return new CliStructuredError("5002", orphans.length === 1 ? `Orphan contract-space marker detected for "${orphans[0]}"` : `Orphan contract-space markers detected for ${orphans.length} spaces`, {
|
|
@@ -355,7 +355,7 @@ function detectOrphanMarkers(aggregate, markerRows) {
|
|
|
355
355
|
});
|
|
356
356
|
}
|
|
357
357
|
function mapPlannerError(error) {
|
|
358
|
-
if (error.kind === "
|
|
358
|
+
if (error.kind === "planFromDiffFailed") return blindCast(notOk({
|
|
359
359
|
code: "PLANNING_FAILED",
|
|
360
360
|
summary: "Migration planning failed due to conflicts",
|
|
361
361
|
conflicts: error.conflicts,
|
|
@@ -544,11 +544,11 @@ const SPAN_IDS = {
|
|
|
544
544
|
* structured CLI error.
|
|
545
545
|
* 2. **Read DB state**: marker rows + (when `skipSchema` is `false`)
|
|
546
546
|
* schema introspection.
|
|
547
|
-
* 3. **Verify**: {@link verifyMigration} returns per-space
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
* callers (CLI command) can render
|
|
551
|
-
* returned to the caller verbatim.
|
|
547
|
+
* 3. **Verify**: {@link verifyMigration} returns per-space `markerCheck` +
|
|
548
|
+
* per-space `schemaCheck` (each contract space verified against the full schema,
|
|
549
|
+
* then scoped to its own contract space). Marker mismatches map to
|
|
550
|
+
* `CliStructuredError` (code `5002`) so callers (CLI command) can render
|
|
551
|
+
* and exit. Verify results are returned to the caller verbatim.
|
|
552
552
|
*/
|
|
553
553
|
async function executeDbVerify(options) {
|
|
554
554
|
const { driver, familyInstance, onProgress, skipSchema, skipMarker } = options;
|
|
@@ -562,6 +562,8 @@ async function executeDbVerify(options) {
|
|
|
562
562
|
onProgress,
|
|
563
563
|
contract: collectAggregateNamespaces(aggregate)
|
|
564
564
|
});
|
|
565
|
+
const classifySubjectGranularity = hasSchemaSubjectClassifier(familyInstance) ? (issue) => familyInstance.classifySubjectGranularity(issue) : void 0;
|
|
566
|
+
const classifyEntityKind = hasSchemaSubjectClassifier(familyInstance) ? (issue) => familyInstance.classifyEntityKind(issue) : void 0;
|
|
565
567
|
emitVerifySpan(onProgress, "spanStart");
|
|
566
568
|
return finaliseVerifyResult({
|
|
567
569
|
verifyResult: verifyMigration({
|
|
@@ -569,7 +571,9 @@ async function executeDbVerify(options) {
|
|
|
569
571
|
markersBySpaceId,
|
|
570
572
|
schemaIntrospection,
|
|
571
573
|
mode: options.mode,
|
|
572
|
-
|
|
574
|
+
verifySchemaForSpace: createPerSpaceVerifier(options),
|
|
575
|
+
...ifDefined("classifySubjectGranularity", classifySubjectGranularity),
|
|
576
|
+
...ifDefined("classifyEntityKind", classifyEntityKind)
|
|
573
577
|
}),
|
|
574
578
|
aggregate,
|
|
575
579
|
skipMarker,
|
|
@@ -616,18 +620,18 @@ async function runIntrospection(args) {
|
|
|
616
620
|
}
|
|
617
621
|
}
|
|
618
622
|
/**
|
|
619
|
-
* Build the per-
|
|
623
|
+
* Build the per-space schema callback handed to the aggregate verifier.
|
|
620
624
|
* When `skipSchema` is true the callback short-circuits with a synthetic
|
|
621
625
|
* `ok` result so the verifier still runs the (cheap) schemaCheck loop
|
|
622
626
|
* without invoking the family's verification path.
|
|
623
627
|
*/
|
|
624
|
-
function
|
|
628
|
+
function createPerSpaceVerifier(options) {
|
|
625
629
|
const { skipSchema, familyInstance, frameworkComponents } = options;
|
|
626
|
-
return (
|
|
627
|
-
if (skipSchema) return buildSkippedSchemaResult(
|
|
630
|
+
return (schema, space, verifyMode) => {
|
|
631
|
+
if (skipSchema) return buildSkippedSchemaResult(space);
|
|
628
632
|
return familyInstance.verifySchema({
|
|
629
|
-
contract:
|
|
630
|
-
schema
|
|
633
|
+
contract: space.contract(),
|
|
634
|
+
schema,
|
|
631
635
|
strict: verifyMode === "strict",
|
|
632
636
|
frameworkComponents
|
|
633
637
|
});
|
|
@@ -674,13 +678,14 @@ function finaliseVerifyResult(args) {
|
|
|
674
678
|
emitVerifySpan(onProgress, "spanEndOk");
|
|
675
679
|
return ok({
|
|
676
680
|
schemaResults: verifyResult.value.schemaCheck.perSpace,
|
|
677
|
-
|
|
681
|
+
unclaimed: verifyResult.value.schemaCheck.unclaimed,
|
|
682
|
+
spaceOrder: [aggregate.app.spaceId, ...aggregate.extensions.map((e) => e.spaceId)],
|
|
678
683
|
appSpaceId: aggregate.app.spaceId
|
|
679
684
|
});
|
|
680
685
|
}
|
|
681
|
-
function buildSkippedSchemaResult(
|
|
682
|
-
const contract =
|
|
683
|
-
const headRef = requireHeadRef(
|
|
686
|
+
function buildSkippedSchemaResult(space) {
|
|
687
|
+
const contract = space.contract();
|
|
688
|
+
const headRef = requireHeadRef(space);
|
|
684
689
|
const profileHash = castAs(contract).profileHash;
|
|
685
690
|
return {
|
|
686
691
|
ok: true,
|
|
@@ -690,26 +695,7 @@ function buildSkippedSchemaResult(member) {
|
|
|
690
695
|
...profileHash ? { profileHash } : {}
|
|
691
696
|
},
|
|
692
697
|
target: { expected: contract.target },
|
|
693
|
-
schema: {
|
|
694
|
-
issues: [],
|
|
695
|
-
root: {
|
|
696
|
-
status: "pass",
|
|
697
|
-
kind: "skipped",
|
|
698
|
-
name: member.spaceId,
|
|
699
|
-
contractPath: "",
|
|
700
|
-
code: "SKIPPED",
|
|
701
|
-
message: "Schema verification skipped",
|
|
702
|
-
expected: void 0,
|
|
703
|
-
actual: void 0,
|
|
704
|
-
children: []
|
|
705
|
-
},
|
|
706
|
-
counts: {
|
|
707
|
-
pass: 0,
|
|
708
|
-
warn: 0,
|
|
709
|
-
fail: 0,
|
|
710
|
-
totalNodes: 0
|
|
711
|
-
}
|
|
712
|
-
},
|
|
698
|
+
schema: { issues: [] },
|
|
713
699
|
timings: { total: 0 }
|
|
714
700
|
};
|
|
715
701
|
}
|
|
@@ -756,22 +742,26 @@ function mapMarkerCheckFailures(appSpaceId, section) {
|
|
|
756
742
|
/**
|
|
757
743
|
* Apply pending migrations across every contract space (app +
|
|
758
744
|
* extensions). Replay-only: graph-walk against the on-disk graph for
|
|
759
|
-
* every
|
|
745
|
+
* every contract space; no synth, no introspection.
|
|
760
746
|
*
|
|
761
747
|
* Pipeline:
|
|
762
748
|
*
|
|
763
749
|
* 1. Load aggregate from disk (loader hydrates extension graphs;
|
|
764
750
|
* caller provides app-space packages).
|
|
765
751
|
* 2. Read live marker rows per space (`familyInstance.readAllMarkers`).
|
|
766
|
-
* 3. Per
|
|
767
|
-
* marker to `
|
|
768
|
-
*
|
|
769
|
-
*
|
|
752
|
+
* 3. Per space: `resolveRecordedPath` plots the path from the live
|
|
753
|
+
* marker to `space.headRef.hash` (or `refHash` for the app
|
|
754
|
+
* space when provided). An empty-graph space whose elements are ALL
|
|
755
|
+
* externally managed resolves declaratively (marker to head, zero
|
|
756
|
+
* ops), mirroring the db-init aggregate planner: such a space ships
|
|
757
|
+
* no DDL and has nothing to author. Every other empty-graph space
|
|
758
|
+
* fails loudly — "never planned" is a user-error condition for
|
|
759
|
+
* replay.
|
|
770
760
|
* 4. Hand off to {@link runMigration} (the runner-driving tail
|
|
771
761
|
* shared with `db init` / `db update`). Marker advancement is
|
|
772
762
|
* inside the per-space transaction.
|
|
773
763
|
*
|
|
774
|
-
* Encodes the replay-only contract:
|
|
764
|
+
* Encodes the replay-only contract: the app contract space must have an
|
|
775
765
|
* authored migration graph on disk before this operation can advance it.
|
|
776
766
|
*/
|
|
777
767
|
async function executeMigrate(options) {
|
|
@@ -786,29 +776,29 @@ async function executeMigrate(options) {
|
|
|
786
776
|
if (!loaded.ok) throw loaded.failure;
|
|
787
777
|
const aggregate = loaded.value;
|
|
788
778
|
const markerRows = await familyInstance.readAllMarkers({ driver });
|
|
789
|
-
const
|
|
779
|
+
const allSpaces = [aggregate.app, ...aggregate.extensions];
|
|
790
780
|
const perSpacePlans = /* @__PURE__ */ new Map();
|
|
791
781
|
const atHeadResolutions = /* @__PURE__ */ new Map();
|
|
792
|
-
for (const
|
|
793
|
-
const
|
|
794
|
-
const headRef = requireHeadRef(
|
|
795
|
-
const
|
|
796
|
-
const outcome =
|
|
797
|
-
|
|
782
|
+
for (const space of allSpaces) {
|
|
783
|
+
const isAppSpace = space.spaceId === aggregate.app.spaceId;
|
|
784
|
+
const headRef = requireHeadRef(space);
|
|
785
|
+
const spaceTargetHash = isAppSpace && refHash !== void 0 ? refHash : headRef.hash;
|
|
786
|
+
const outcome = planSpacePath({
|
|
787
|
+
space,
|
|
798
788
|
aggregate,
|
|
799
|
-
targetHash:
|
|
800
|
-
refInvariants:
|
|
801
|
-
liveMarker: markerRows.get(
|
|
802
|
-
...
|
|
789
|
+
targetHash: spaceTargetHash,
|
|
790
|
+
refInvariants: isAppSpace && refHash !== void 0 ? refInvariants : void 0,
|
|
791
|
+
liveMarker: markerRows.get(space.spaceId) ?? null,
|
|
792
|
+
...isAppSpace ? { refName } : {}
|
|
803
793
|
});
|
|
804
794
|
if (outcome.kind === "at-head") {
|
|
805
|
-
atHeadResolutions.set(
|
|
795
|
+
atHeadResolutions.set(space.spaceId, outcome.plan);
|
|
806
796
|
continue;
|
|
807
797
|
}
|
|
808
798
|
if (outcome.kind === "never-planned") return notOk(buildNeverPlannedFailure(outcome.spaceId, outcome.targetHash));
|
|
809
799
|
if (outcome.kind === "unreachable") return notOk(buildPathNotFoundFailure(outcome.spaceId, outcome.liveMarker, outcome.targetHash));
|
|
810
800
|
if (outcome.kind === "unsatisfiable") {
|
|
811
|
-
const structural = findPathWithDecision(outcome.
|
|
801
|
+
const structural = findPathWithDecision(outcome.targetSpace.graph(), outcome.liveHash, spaceTargetHash, { required: /* @__PURE__ */ new Set() });
|
|
812
802
|
const structuralPath = structural.kind === "ok" ? structural.decision.selectedPath.map((edge) => ({
|
|
813
803
|
dirName: edge.dirName,
|
|
814
804
|
migrationHash: edge.migrationHash,
|
|
@@ -823,11 +813,14 @@ async function executeMigrate(options) {
|
|
|
823
813
|
structuralPath
|
|
824
814
|
});
|
|
825
815
|
}
|
|
826
|
-
perSpacePlans.set(
|
|
816
|
+
perSpacePlans.set(space.spaceId, outcome.plan);
|
|
827
817
|
}
|
|
828
818
|
const canonicalOrder = [...aggregate.extensions.map((m) => m.spaceId), aggregate.app.spaceId];
|
|
829
819
|
const applyOrder = canonicalOrder.filter((spaceId) => perSpacePlans.has(spaceId));
|
|
830
|
-
if (
|
|
820
|
+
if (!applyOrder.some((spaceId) => {
|
|
821
|
+
const entry = perSpacePlans.get(spaceId);
|
|
822
|
+
return entry !== void 0 && planRequiresExecution(entry);
|
|
823
|
+
})) {
|
|
831
824
|
const ordered = canonicalOrder.filter((spaceId) => perSpacePlans.has(spaceId) || atHeadResolutions.has(spaceId)).map((spaceId) => {
|
|
832
825
|
const entry = perSpacePlans.get(spaceId) ?? atHeadResolutions.get(spaceId);
|
|
833
826
|
if (entry === void 0) throw new Error(`Unreachable: missing per-space plan for "${spaceId}"`);
|
|
@@ -892,7 +885,7 @@ async function executeMigrate(options) {
|
|
|
892
885
|
}));
|
|
893
886
|
}
|
|
894
887
|
/**
|
|
895
|
-
* Compute the graph-walk path for one contract
|
|
888
|
+
* Compute the graph-walk path for one contract space.
|
|
896
889
|
*
|
|
897
890
|
* Encapsulates the invariant-correct input assembly that both
|
|
898
891
|
* `executeMigrate` and `executeMigrateShowCommand` must use:
|
|
@@ -901,48 +894,69 @@ async function executeMigrate(options) {
|
|
|
901
894
|
* - `targetInvariants` uses the caller-supplied `refInvariants` when a
|
|
902
895
|
* `--to` ref was resolved (not always the file head ref's invariants).
|
|
903
896
|
*
|
|
904
|
-
* Both callers map the returned `
|
|
897
|
+
* Both callers map the returned `SpacePathOutcome` to their own error
|
|
905
898
|
* representation; the path-compute logic is shared and identical.
|
|
906
899
|
*
|
|
907
900
|
* @internal Exported for `executeMigrateShowCommand`.
|
|
908
901
|
*/
|
|
909
|
-
function
|
|
910
|
-
const
|
|
911
|
-
const headRef = requireHeadRef(
|
|
912
|
-
if (
|
|
902
|
+
function planSpacePath({ space, aggregate, targetHash, refInvariants, liveMarker, refName }) {
|
|
903
|
+
const isAppSpace = space.spaceId === aggregate.app.spaceId;
|
|
904
|
+
const headRef = requireHeadRef(space);
|
|
905
|
+
if (space.graph().nodes.size === 0) {
|
|
913
906
|
const liveHash = liveMarker?.storageHash;
|
|
914
907
|
if (targetHash === liveHash || liveHash === void 0 && targetHash === EMPTY_CONTRACT_HASH) return {
|
|
915
908
|
kind: "at-head",
|
|
916
909
|
plan: buildAtHeadResolution({
|
|
917
910
|
aggregateTargetId: aggregate.targetId,
|
|
918
|
-
|
|
911
|
+
space,
|
|
919
912
|
targetHash,
|
|
920
913
|
liveMarker
|
|
921
914
|
})
|
|
922
915
|
};
|
|
916
|
+
if (!isAppSpace && allStorageElementsExternal(space.contract())) {
|
|
917
|
+
if (headRef.invariants.length > 0) return {
|
|
918
|
+
kind: "unsatisfiable",
|
|
919
|
+
spaceId: space.spaceId,
|
|
920
|
+
isAppSpace,
|
|
921
|
+
missing: [...headRef.invariants].sort(),
|
|
922
|
+
targetInvariants: headRef.invariants,
|
|
923
|
+
targetSpace: space,
|
|
924
|
+
liveHash: liveHash ?? EMPTY_CONTRACT_HASH,
|
|
925
|
+
refName: void 0
|
|
926
|
+
};
|
|
927
|
+
return {
|
|
928
|
+
kind: "ok",
|
|
929
|
+
plan: buildAtHeadResolution({
|
|
930
|
+
aggregateTargetId: aggregate.targetId,
|
|
931
|
+
space,
|
|
932
|
+
targetHash,
|
|
933
|
+
liveMarker
|
|
934
|
+
})
|
|
935
|
+
};
|
|
936
|
+
}
|
|
923
937
|
return {
|
|
924
938
|
kind: "never-planned",
|
|
925
|
-
spaceId:
|
|
939
|
+
spaceId: space.spaceId,
|
|
926
940
|
targetHash
|
|
927
941
|
};
|
|
928
942
|
}
|
|
929
|
-
const targetInvariants =
|
|
930
|
-
const
|
|
931
|
-
...
|
|
943
|
+
const targetInvariants = isAppSpace && refInvariants !== void 0 ? refInvariants : headRef.invariants;
|
|
944
|
+
const targetSpace = targetHash === headRef.hash && targetInvariants === headRef.invariants ? space : {
|
|
945
|
+
...space,
|
|
932
946
|
headRef: {
|
|
933
947
|
hash: targetHash,
|
|
934
948
|
invariants: targetInvariants
|
|
935
949
|
}
|
|
936
950
|
};
|
|
937
|
-
const walked =
|
|
951
|
+
const walked = resolveRecordedPath({
|
|
938
952
|
aggregateTargetId: aggregate.targetId,
|
|
939
|
-
|
|
953
|
+
space: targetSpace,
|
|
940
954
|
currentMarker: liveMarker,
|
|
941
|
-
...
|
|
955
|
+
...isAppSpace && refName !== void 0 ? { refName } : {}
|
|
942
956
|
});
|
|
943
957
|
if (walked.kind === "unreachable") return {
|
|
944
958
|
kind: "unreachable",
|
|
945
|
-
spaceId:
|
|
959
|
+
spaceId: space.spaceId,
|
|
946
960
|
liveMarker,
|
|
947
961
|
targetHash
|
|
948
962
|
};
|
|
@@ -950,11 +964,11 @@ function planMemberPath({ member, aggregate, targetHash, refInvariants, liveMark
|
|
|
950
964
|
const liveHash = liveMarker?.storageHash ?? EMPTY_CONTRACT_HASH;
|
|
951
965
|
return {
|
|
952
966
|
kind: "unsatisfiable",
|
|
953
|
-
spaceId:
|
|
954
|
-
|
|
967
|
+
spaceId: space.spaceId,
|
|
968
|
+
isAppSpace,
|
|
955
969
|
missing: walked.missing,
|
|
956
970
|
targetInvariants,
|
|
957
|
-
|
|
971
|
+
targetSpace,
|
|
958
972
|
liveHash,
|
|
959
973
|
refName
|
|
960
974
|
};
|
|
@@ -965,41 +979,43 @@ function planMemberPath({ member, aggregate, targetHash, refInvariants, liveMark
|
|
|
965
979
|
};
|
|
966
980
|
}
|
|
967
981
|
/**
|
|
968
|
-
* Build a zero-op {@link PerSpacePlan} for an empty-graph
|
|
969
|
-
*
|
|
970
|
-
*
|
|
971
|
-
*
|
|
972
|
-
*
|
|
982
|
+
* Build a zero-op {@link PerSpacePlan} for an empty-graph space —
|
|
983
|
+
* either one whose live marker already matches the target (at-head), or
|
|
984
|
+
* an all-external extension space whose marker must advance to the head
|
|
985
|
+
* ref with no DDL (declared-state). Lets the apply pipeline thread the
|
|
986
|
+
* space through `perSpacePlans` -> `applyOrder` -> the success
|
|
987
|
+
* envelope's `perSpace[]` block so the result reflects every loaded
|
|
988
|
+
* space, even when there is nothing to execute.
|
|
973
989
|
*/
|
|
974
990
|
function buildAtHeadResolution(args) {
|
|
975
|
-
const { aggregateTargetId,
|
|
991
|
+
const { aggregateTargetId, space, targetHash, liveMarker } = args;
|
|
976
992
|
return {
|
|
977
993
|
plan: {
|
|
978
994
|
targetId: aggregateTargetId,
|
|
979
|
-
spaceId:
|
|
995
|
+
spaceId: space.spaceId,
|
|
980
996
|
origin: liveMarker === null ? null : { storageHash: liveMarker.storageHash },
|
|
981
997
|
destination: { storageHash: targetHash },
|
|
982
998
|
operations: [],
|
|
983
999
|
providedInvariants: []
|
|
984
1000
|
},
|
|
985
1001
|
displayOps: [],
|
|
986
|
-
destinationContract:
|
|
987
|
-
strategy: "
|
|
988
|
-
migrationEdges: [
|
|
1002
|
+
destinationContract: space.contract(),
|
|
1003
|
+
strategy: "declared-state",
|
|
1004
|
+
migrationEdges: [buildFabricatedMigrationEdge({
|
|
989
1005
|
currentMarkerStorageHash: liveMarker?.storageHash,
|
|
990
1006
|
destinationStorageHash: targetHash,
|
|
991
1007
|
operationCount: 0
|
|
992
1008
|
})]
|
|
993
1009
|
};
|
|
994
1010
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
return
|
|
1011
|
+
/**
|
|
1012
|
+
* A plan needs the runner when it executes operations or advances the
|
|
1013
|
+
* space's marker (a declared-state resolution has zero operations but a
|
|
1014
|
+
* destination hash the live marker doesn't carry yet).
|
|
1015
|
+
*/
|
|
1016
|
+
function planRequiresExecution(entry) {
|
|
1017
|
+
if (entry.plan.operations.length > 0) return true;
|
|
1018
|
+
return entry.plan.origin?.storageHash !== entry.plan.destination.storageHash;
|
|
1003
1019
|
}
|
|
1004
1020
|
function buildSuccess(args) {
|
|
1005
1021
|
const appResolution = args.orderedResolutions.find((r) => r.spaceId === args.aggregate.app.spaceId);
|
|
@@ -1041,10 +1057,12 @@ function buildSuccess(args) {
|
|
|
1041
1057
|
};
|
|
1042
1058
|
}
|
|
1043
1059
|
/**
|
|
1044
|
-
* Build the `neverPlanned` failure raised when a contract space
|
|
1045
|
-
*
|
|
1046
|
-
*
|
|
1047
|
-
*
|
|
1060
|
+
* Build the `neverPlanned` failure raised when a contract space that
|
|
1061
|
+
* declares managed storage elements has no on-disk migration graph but
|
|
1062
|
+
* migrate was asked to reach a target hash. All-external spaces never reach
|
|
1063
|
+
* this: they resolve declaratively (marker advances to the head ref with
|
|
1064
|
+
* zero operations). The `why` states only the condition; the recovery
|
|
1065
|
+
* sequence is composed by `errorPathUnreachable`'s `fix`.
|
|
1048
1066
|
*
|
|
1049
1067
|
* @internal Exported for testing only.
|
|
1050
1068
|
*/
|
|
@@ -1052,7 +1070,7 @@ function buildNeverPlannedFailure(spaceId, targetHash) {
|
|
|
1052
1070
|
return {
|
|
1053
1071
|
code: "MIGRATION_PATH_NOT_FOUND",
|
|
1054
1072
|
summary: `No on-disk migrations for contract space "${spaceId}"`,
|
|
1055
|
-
why: `migrate is replay-only:
|
|
1073
|
+
why: `migrate is replay-only: a contract space that declares managed storage elements must have an authored migration graph on disk. Space "${spaceId}" has no migrations under \`migrations/${spaceId}/\` but its head ref targets "${targetHash}".`,
|
|
1056
1074
|
meta: {
|
|
1057
1075
|
spaceId,
|
|
1058
1076
|
target: targetHash,
|
|
@@ -1494,16 +1512,15 @@ var ControlClientImpl = class {
|
|
|
1494
1512
|
});
|
|
1495
1513
|
try {
|
|
1496
1514
|
const stack = this.stack;
|
|
1497
|
-
const extensionInputs = toExtensionInputs(blindCast(stack.extensionPacks));
|
|
1498
|
-
const composedExtensionContracts = new Map(extensionInputs.filter((p) => p.contractSpace !== void 0).map((p) => [p.id, blindCast(p.contractSpace.contractJson)]));
|
|
1499
1515
|
const sourceContext = {
|
|
1500
1516
|
composedExtensionPacks: stack.extensionPacks.map((p) => p.id),
|
|
1501
|
-
composedExtensionContracts,
|
|
1517
|
+
composedExtensionContracts: stack.extensionContracts,
|
|
1502
1518
|
scalarTypeDescriptors: stack.scalarTypeDescriptors,
|
|
1503
1519
|
authoringContributions: stack.authoringContributions,
|
|
1504
1520
|
codecLookup: stack.codecLookup,
|
|
1505
1521
|
controlMutationDefaults: stack.controlMutationDefaults,
|
|
1506
|
-
resolvedInputs: contractConfig.source.inputs ?? []
|
|
1522
|
+
resolvedInputs: contractConfig.source.inputs ?? [],
|
|
1523
|
+
capabilities: stack.capabilities
|
|
1507
1524
|
};
|
|
1508
1525
|
const providerResult = await contractConfig.source.load(sourceContext);
|
|
1509
1526
|
if (!providerResult.ok) {
|
|
@@ -1558,9 +1575,10 @@ var ControlClientImpl = class {
|
|
|
1558
1575
|
});
|
|
1559
1576
|
try {
|
|
1560
1577
|
const enrichedIR = enrichContract(contractRaw, this.frameworkComponents ?? []);
|
|
1578
|
+
const rawContractJson = this.options.target.contractSerializer.serializeContract(enrichedIR);
|
|
1561
1579
|
let deserializedContract;
|
|
1562
1580
|
try {
|
|
1563
|
-
deserializedContract = this.familyInstance.deserializeContract(
|
|
1581
|
+
deserializedContract = this.familyInstance.deserializeContract(rawContractJson);
|
|
1564
1582
|
} catch (error) {
|
|
1565
1583
|
onProgress?.({
|
|
1566
1584
|
action: "emit",
|
|
@@ -1606,6 +1624,6 @@ var ControlClientImpl = class {
|
|
|
1606
1624
|
}
|
|
1607
1625
|
};
|
|
1608
1626
|
//#endregion
|
|
1609
|
-
export { executeDbInit as a, executeDbUpdate as i,
|
|
1627
|
+
export { executeDbInit as a, executeDbUpdate as i, planSpacePath as n, ContractValidationError as o, executeDbVerify as r, createControlClient as t };
|
|
1610
1628
|
|
|
1611
|
-
//# sourceMappingURL=client-
|
|
1629
|
+
//# sourceMappingURL=client-DwOyZz0a.mjs.map
|