prisma-next 0.11.0-dev.46 → 0.11.0-dev.47

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.
Files changed (91) hide show
  1. package/dist/cli.mjs +9 -9
  2. package/dist/{client-a5NJce0-.mjs → client-5uvDppD8.mjs} +20 -18
  3. package/dist/client-5uvDppD8.mjs.map +1 -0
  4. package/dist/{command-helpers-yLuA78TP.mjs → command-helpers-CI8P5Xyd.mjs} +4 -4
  5. package/dist/{command-helpers-yLuA78TP.mjs.map → command-helpers-CI8P5Xyd.mjs.map} +1 -1
  6. package/dist/commands/contract-emit.mjs +1 -1
  7. package/dist/commands/contract-infer.mjs +1 -1
  8. package/dist/commands/db-init.mjs +5 -5
  9. package/dist/commands/db-schema.mjs +3 -3
  10. package/dist/commands/db-sign.mjs +3 -3
  11. package/dist/commands/db-update.mjs +5 -5
  12. package/dist/commands/db-verify.mjs +1 -1
  13. package/dist/commands/migrate.d.mts +1 -1
  14. package/dist/commands/migrate.d.mts.map +1 -1
  15. package/dist/commands/migrate.mjs +42 -37
  16. package/dist/commands/migrate.mjs.map +1 -1
  17. package/dist/commands/migration-check.d.mts +4 -3
  18. package/dist/commands/migration-check.d.mts.map +1 -1
  19. package/dist/commands/migration-check.mjs +1 -279
  20. package/dist/commands/migration-graph.d.mts +1 -1
  21. package/dist/commands/migration-graph.mjs +2 -2
  22. package/dist/commands/migration-list.d.mts +2 -2
  23. package/dist/commands/migration-list.mjs +1 -1
  24. package/dist/commands/migration-log.mjs +2 -2
  25. package/dist/commands/migration-new.d.mts.map +1 -1
  26. package/dist/commands/migration-new.mjs +32 -30
  27. package/dist/commands/migration-new.mjs.map +1 -1
  28. package/dist/commands/migration-plan.d.mts +1 -1
  29. package/dist/commands/migration-plan.mjs +1 -1
  30. package/dist/commands/migration-show.d.mts +4 -55
  31. package/dist/commands/migration-show.d.mts.map +1 -1
  32. package/dist/commands/migration-show.mjs +62 -152
  33. package/dist/commands/migration-show.mjs.map +1 -1
  34. package/dist/commands/migration-status.d.mts +5 -40
  35. package/dist/commands/migration-status.d.mts.map +1 -1
  36. package/dist/commands/migration-status.mjs +91 -64
  37. package/dist/commands/migration-status.mjs.map +1 -1
  38. package/dist/commands/ref.d.mts +1 -1
  39. package/dist/commands/ref.mjs +2 -2
  40. package/dist/{contract-emit-FtDVFs2Q.mjs → contract-emit-DmBG2Nnc.mjs} +2 -2
  41. package/dist/{contract-emit-FtDVFs2Q.mjs.map → contract-emit-DmBG2Nnc.mjs.map} +1 -1
  42. package/dist/{contract-infer-CVMuoJKk.mjs → contract-infer-BSWFKgI1.mjs} +3 -3
  43. package/dist/{contract-infer-CVMuoJKk.mjs.map → contract-infer-BSWFKgI1.mjs.map} +1 -1
  44. package/dist/contract-space-aggregate-loader-CVHGuA35.mjs +170 -0
  45. package/dist/contract-space-aggregate-loader-CVHGuA35.mjs.map +1 -0
  46. package/dist/{db-verify-B00o3LuC.mjs → db-verify-BzpwFyLg.mjs} +4 -4
  47. package/dist/{db-verify-B00o3LuC.mjs.map → db-verify-BzpwFyLg.mjs.map} +1 -1
  48. package/dist/exports/control-api.d.mts +1 -1
  49. package/dist/exports/control-api.mjs +1 -1
  50. package/dist/exports/index.mjs +1 -1
  51. package/dist/exports/init-output.mjs +1 -1
  52. package/dist/extension-pack-inputs-BiY86HbQ.mjs +62 -0
  53. package/dist/extension-pack-inputs-BiY86HbQ.mjs.map +1 -0
  54. package/dist/{global-flags-Dvibm2yu.d.mts → global-flags-DWsQ6SSI.d.mts} +1 -1
  55. package/dist/{global-flags-Dvibm2yu.d.mts.map → global-flags-DWsQ6SSI.d.mts.map} +1 -1
  56. package/dist/{graph-render-DJVv0_uf.mjs → graph-render-D2FnLpuK.mjs} +1 -1
  57. package/dist/{graph-render-DJVv0_uf.mjs.map → graph-render-D2FnLpuK.mjs.map} +1 -1
  58. package/dist/{init-BKgB6EKw.mjs → init-DEssiJ8j.mjs} +3 -3
  59. package/dist/{init-BKgB6EKw.mjs.map → init-DEssiJ8j.mjs.map} +1 -1
  60. package/dist/{inspect-live-schema-BXUd6RfS.mjs → inspect-live-schema-DlBM84nh.mjs} +3 -3
  61. package/dist/{inspect-live-schema-BXUd6RfS.mjs.map → inspect-live-schema-DlBM84nh.mjs.map} +1 -1
  62. package/dist/migration-check-CzLbAqIQ.mjs +341 -0
  63. package/dist/migration-check-CzLbAqIQ.mjs.map +1 -0
  64. package/dist/{migration-command-scaffold-3l3EdmSD.mjs → migration-command-scaffold-Bp8UHnvJ.mjs} +3 -3
  65. package/dist/{migration-command-scaffold-3l3EdmSD.mjs.map → migration-command-scaffold-Bp8UHnvJ.mjs.map} +1 -1
  66. package/dist/{migration-list-DopkAG7L.mjs → migration-list-C2xnaYsT.mjs} +2 -2
  67. package/dist/{migration-list-DopkAG7L.mjs.map → migration-list-C2xnaYsT.mjs.map} +1 -1
  68. package/dist/{migration-list-graph-render-C-daUZLU.d.mts → migration-list-graph-render-DKw1AT-e.d.mts} +1 -1
  69. package/dist/migration-list-graph-render-DKw1AT-e.d.mts.map +1 -0
  70. package/dist/{migration-plan-BHoeET4O.mjs → migration-plan-BLvOmNCu.mjs} +6 -5
  71. package/dist/{migration-plan-BHoeET4O.mjs.map → migration-plan-BLvOmNCu.mjs.map} +1 -1
  72. package/dist/{migration-types-BXWvz12q.d.mts → migration-types-q64xAI_J.d.mts} +1 -1
  73. package/dist/{migration-types-BXWvz12q.d.mts.map → migration-types-q64xAI_J.d.mts.map} +1 -1
  74. package/dist/{migrations-D-UCOGtk.mjs → migrations-vzQt9LI2.mjs} +3 -13
  75. package/dist/migrations-vzQt9LI2.mjs.map +1 -0
  76. package/dist/{output-CUIdfYo5.mjs → output-B60Gw5fu.mjs} +1 -1
  77. package/dist/{output-CUIdfYo5.mjs.map → output-B60Gw5fu.mjs.map} +1 -1
  78. package/dist/{ref-advancement-CHJ_8HxQ.mjs → ref-advancement-DRh5Nquq.mjs} +1 -1
  79. package/dist/{ref-advancement-CHJ_8HxQ.mjs.map → ref-advancement-DRh5Nquq.mjs.map} +1 -1
  80. package/dist/{types-UWB2-rrw.d.mts → types-CEtm6v6a.d.mts} +1 -8
  81. package/dist/types-CEtm6v6a.d.mts.map +1 -0
  82. package/dist/{verify-9gDJz6cm.mjs → verify-ktSRQvIS.mjs} +2 -2
  83. package/dist/{verify-9gDJz6cm.mjs.map → verify-ktSRQvIS.mjs.map} +1 -1
  84. package/package.json +11 -11
  85. package/dist/client-a5NJce0-.mjs.map +0 -1
  86. package/dist/commands/migration-check.mjs.map +0 -1
  87. package/dist/contract-space-aggregate-loader-EVU3n9YE.mjs +0 -160
  88. package/dist/contract-space-aggregate-loader-EVU3n9YE.mjs.map +0 -1
  89. package/dist/migration-list-graph-render-C-daUZLU.d.mts.map +0 -1
  90. package/dist/migrations-D-UCOGtk.mjs.map +0 -1
  91. package/dist/types-UWB2-rrw.d.mts.map +0 -1
@@ -0,0 +1,170 @@
1
+ import { t as CliStructuredError } from "./cli-errors-DFF1LlfU.mjs";
2
+ import { t as toDeclaredExtensionsFromRaw } from "./extension-pack-inputs-BiY86HbQ.mjs";
3
+ import { notOk, ok } from "@prisma-next/utils/result";
4
+ import { loadContractSpaceAggregate } from "@prisma-next/migration-tools/aggregate";
5
+ //#region src/utils/contract-space-aggregate-loader.ts
6
+ const CONTRACT_SPACES_DOCS_URL = "https://pris.ly/contract-spaces";
7
+ function contractSpaceError5002(summary, options) {
8
+ return new CliStructuredError("5002", summary, {
9
+ domain: "MIG",
10
+ why: options.why,
11
+ fix: options.fix,
12
+ docsUrl: CONTRACT_SPACES_DOCS_URL,
13
+ meta: { violations: options.violations }
14
+ });
15
+ }
16
+ /**
17
+ * Build the `5002` structured-error envelope for a contract-space
18
+ * target mismatch. Shared between the declared-extension precheck (the
19
+ * descriptor's configured target disagrees with the project target) and
20
+ * the on-disk-contract check surfaced by `checkIntegrity`.
21
+ */
22
+ function targetMismatchError(spaceId, expected, actual) {
23
+ return contractSpaceError5002(`Contract-space target mismatch for "${spaceId}"`, {
24
+ why: `Space "${spaceId}" targets "${actual}" but the project's adapter targets "${expected}".`,
25
+ fix: "Update the extension descriptor to target the configured database, or change the project adapter.",
26
+ violations: [{
27
+ kind: "targetMismatch",
28
+ spaceId,
29
+ expected,
30
+ actual
31
+ }]
32
+ });
33
+ }
34
+ /**
35
+ * Human-readable detail for an integrity violation, used as the `why`
36
+ * of the `integrityFailure` envelope. Mirrors the messages the prior
37
+ * throw-on-load loader produced so downstream consumers see the same
38
+ * text for the same on-disk state.
39
+ */
40
+ function describeIntegrityViolation(violation) {
41
+ switch (violation.kind) {
42
+ case "hashMismatch": return `Migration "${violation.dirName}" stored hash "${violation.stored}" does not match computed hash "${violation.computed}".`;
43
+ case "providedInvariantsMismatch": return `Migration "${violation.dirName}" providedInvariants in migration.json disagrees with ops.json.`;
44
+ case "packageUnloadable": return `Migration "${violation.dirName}" could not be loaded: ${violation.detail}`;
45
+ case "sameSourceAndTarget": return `Migration "${violation.dirName}" has source equal to target (${violation.hash}) with no data invariant — a true no-op self-edge.`;
46
+ case "headRefMissing": return `Head ref \`refs/head.json\` is missing for contract space "${violation.spaceId}".`;
47
+ case "headRefNotInGraph": return `Head ref ${violation.hash} for contract space "${violation.spaceId}" is not present in the migration graph.`;
48
+ case "refUnreadable": return `Ref "${violation.refName}" for contract space "${violation.spaceId}" is unreadable: ${violation.detail}`;
49
+ case "duplicateMigrationHash": return `Multiple migrations in space "${violation.spaceId}" share migrationHash "${violation.migrationHash}" (${violation.dirNames.join(", ")}).`;
50
+ default: {
51
+ const spaceId = "spaceId" in violation ? violation.spaceId : "*";
52
+ return `Integrity violation "${violation.kind}" for contract space "${spaceId}".`;
53
+ }
54
+ }
55
+ }
56
+ /**
57
+ * Map the integrity violations `checkIntegrity` reports into a single
58
+ * CLI structured-error envelope, preserving the error codes the prior
59
+ * throw-on-load loader emitted: `5001` (layout drift, bundled) and
60
+ * `5002` (target / disjointness / contract-validation / structural
61
+ * integrity). Returns `null` when there is nothing to refuse on.
62
+ *
63
+ * Precedence reproduces the prior loader's first-failure ordering:
64
+ * layout drift first (every offence bundled into one envelope), then
65
+ * target mismatch, then disjointness, then a contract-validation
66
+ * failure, then any remaining structural integrity violation.
67
+ */
68
+ function mapIntegrityViolations(violations) {
69
+ if (violations.length === 0) return null;
70
+ const layout = violations.filter((v) => v.kind === "orphanSpaceDir" || v.kind === "declaredButUnmigrated");
71
+ if (layout.length > 0) {
72
+ const lines = layout.map((v) => `- [${v.kind}] ${v.spaceId}`);
73
+ return new CliStructuredError("5001", layout.length === 1 ? "Contract-space layout violation detected" : `Contract-space layout violations detected (${layout.length})`, {
74
+ domain: "MIG",
75
+ why: `The on-disk \`migrations/\` directory and your \`extensionPacks\` declaration are not in agreement.\n${lines.join("\n")}`,
76
+ fix: "Declare the extension in `extensionPacks` and re-emit its contract-space artefacts, or remove the orphan `migrations/<space>` directory.",
77
+ docsUrl: CONTRACT_SPACES_DOCS_URL,
78
+ meta: { violations: layout }
79
+ });
80
+ }
81
+ const targetMismatch = violations.find((v) => v.kind === "targetMismatch");
82
+ if (targetMismatch && targetMismatch.kind === "targetMismatch") return targetMismatchError(targetMismatch.spaceId, targetMismatch.expected, targetMismatch.actual);
83
+ const disjointness = violations.find((v) => v.kind === "disjointness");
84
+ if (disjointness && disjointness.kind === "disjointness") return contractSpaceError5002(`Contract-space disjointness violation: storage element "${disjointness.element}" claimed by multiple spaces`, {
85
+ why: `Spaces ${disjointness.claimedBy.map((s) => `"${s}"`).join(", ")} all claim the storage element "${disjointness.element}". Each storage element must be owned by exactly one contract space.`,
86
+ fix: "Update the conflicting contracts so each storage element is claimed by exactly one space.",
87
+ violations: [disjointness]
88
+ });
89
+ const contractUnreadable = violations.find((v) => v.kind === "contractUnreadable");
90
+ if (contractUnreadable && contractUnreadable.kind === "contractUnreadable") return contractSpaceError5002(`Contract-space contract validation failed for "${contractUnreadable.spaceId}"`, {
91
+ why: contractUnreadable.detail,
92
+ fix: "Re-emit the extension contract with `prisma-next contract emit`, or fix the extension pack descriptor producing the invalid contract.",
93
+ violations: [contractUnreadable]
94
+ });
95
+ const structural = violations[0];
96
+ return contractSpaceError5002(`Contract-space integrity failure for "${"spaceId" in structural ? structural.spaceId : "*"}"`, {
97
+ why: describeIntegrityViolation(structural),
98
+ fix: "Re-emit the affected migration package(s) or restore the on-disk `migrations/` directory from version control.",
99
+ violations: [structural]
100
+ });
101
+ }
102
+ function declaredExtensionsFromInputs(extensionPacks) {
103
+ return toDeclaredExtensionsFromRaw(extensionPacks);
104
+ }
105
+ /**
106
+ * Reject extension descriptors whose configured target disagrees with
107
+ * the project target before any on-disk read.
108
+ */
109
+ function refuseDeclaredExtensionTargetMismatch(inputs) {
110
+ for (const declared of declaredExtensionsFromInputs(inputs.extensionPacks)) if (declared.targetId !== inputs.targetId) return targetMismatchError(declared.id, inputs.targetId, declared.targetId);
111
+ return null;
112
+ }
113
+ /**
114
+ * Load the tolerant {@link ContractSpaceAggregate} once at the CLI
115
+ * surface. Construction never throws on disk content; callers query
116
+ * {@link ContractSpaceAggregate.app} / extension facets instead of
117
+ * re-reading `migrations/`.
118
+ */
119
+ async function loadContractSpaceAggregateForCli(inputs) {
120
+ const targetFailure = refuseDeclaredExtensionTargetMismatch(inputs);
121
+ if (targetFailure) return notOk(targetFailure);
122
+ return ok(await loadContractSpaceAggregate({
123
+ migrationsDir: inputs.migrationsDir,
124
+ deserializeContract: inputs.deserializeContract,
125
+ appContract: inputs.appContract
126
+ }));
127
+ }
128
+ /**
129
+ * Run `checkIntegrity` on a loaded aggregate and map violations into
130
+ * the contract-space refusal envelope, or return `null` when the model
131
+ * is acceptable for the requested check scope.
132
+ */
133
+ function refuseContractSpaceIntegrity(aggregate, options) {
134
+ return mapIntegrityViolations(aggregate.checkIntegrity(options));
135
+ }
136
+ const PACKAGE_CORRUPTION_KINDS = new Set([
137
+ "hashMismatch",
138
+ "providedInvariantsMismatch",
139
+ "packageUnloadable"
140
+ ]);
141
+ /**
142
+ * Reader-subset integrity refusal for `migration status`: package
143
+ * corruptions only (`hashMismatch`, `providedInvariantsMismatch`,
144
+ * `packageUnloadable`).
145
+ */
146
+ function refusePackageCorruptionOnAggregate(aggregate) {
147
+ return mapIntegrityViolations(aggregate.checkIntegrity().filter((v) => PACKAGE_CORRUPTION_KINDS.has(v.kind)));
148
+ }
149
+ /**
150
+ * Construct the tolerant {@link ContractSpaceAggregate} at the CLI
151
+ * surface and apply the explicit integrity refusal.
152
+ *
153
+ * App-space migration packages are read from `migrations/<app>/` by the
154
+ * loader itself; callers no longer thread them through.
155
+ */
156
+ async function buildContractSpaceAggregate(inputs) {
157
+ const declaredExtensions = declaredExtensionsFromInputs(inputs.extensionPacks);
158
+ const loaded = await loadContractSpaceAggregateForCli(inputs);
159
+ if (!loaded.ok) return loaded;
160
+ const failure = refuseContractSpaceIntegrity(loaded.value, {
161
+ declaredExtensions,
162
+ checkContracts: true
163
+ });
164
+ if (failure) return notOk(failure);
165
+ return ok(loaded.value);
166
+ }
167
+ //#endregion
168
+ export { refusePackageCorruptionOnAggregate as i, loadContractSpaceAggregateForCli as n, refuseContractSpaceIntegrity as r, buildContractSpaceAggregate as t };
169
+
170
+ //# sourceMappingURL=contract-space-aggregate-loader-CVHGuA35.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-space-aggregate-loader-CVHGuA35.mjs","names":[],"sources":["../src/utils/contract-space-aggregate-loader.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { ControlExtensionDescriptor } from '@prisma-next/framework-components/control';\nimport type {\n ContractSpaceAggregate,\n DeclaredExtensionEntry,\n IntegrityQueryOptions,\n IntegrityViolation,\n} from '@prisma-next/migration-tools/aggregate';\nimport { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { CliStructuredError } from './cli-errors';\nimport { toDeclaredExtensionsFromRaw } from './extension-pack-inputs';\n\nconst CONTRACT_SPACES_DOCS_URL = 'https://pris.ly/contract-spaces';\n\nfunction contractSpaceError5002(\n summary: string,\n options: {\n readonly why: string;\n readonly fix: string;\n readonly violations: readonly IntegrityViolation[];\n },\n): CliStructuredError {\n return new CliStructuredError('5002', summary, {\n domain: 'MIG',\n why: options.why,\n fix: options.fix,\n docsUrl: CONTRACT_SPACES_DOCS_URL,\n meta: { violations: options.violations },\n });\n}\n\n/**\n * Build the `5002` structured-error envelope for a contract-space\n * target mismatch. Shared between the declared-extension precheck (the\n * descriptor's configured target disagrees with the project target) and\n * the on-disk-contract check surfaced by `checkIntegrity`.\n */\nfunction targetMismatchError(\n spaceId: string,\n expected: string,\n actual: string,\n): CliStructuredError {\n return contractSpaceError5002(`Contract-space target mismatch for \"${spaceId}\"`, {\n why: `Space \"${spaceId}\" targets \"${actual}\" but the project's adapter targets \"${expected}\".`,\n fix: 'Update the extension descriptor to target the configured database, or change the project adapter.',\n violations: [{ kind: 'targetMismatch', spaceId, expected, actual }],\n });\n}\n\n/**\n * Human-readable detail for an integrity violation, used as the `why`\n * of the `integrityFailure` envelope. Mirrors the messages the prior\n * throw-on-load loader produced so downstream consumers see the same\n * text for the same on-disk state.\n */\nfunction describeIntegrityViolation(violation: IntegrityViolation): string {\n switch (violation.kind) {\n case 'hashMismatch':\n return `Migration \"${violation.dirName}\" stored hash \"${violation.stored}\" does not match computed hash \"${violation.computed}\".`;\n case 'providedInvariantsMismatch':\n return `Migration \"${violation.dirName}\" providedInvariants in migration.json disagrees with ops.json.`;\n case 'packageUnloadable':\n return `Migration \"${violation.dirName}\" could not be loaded: ${violation.detail}`;\n case 'sameSourceAndTarget':\n return `Migration \"${violation.dirName}\" has source equal to target (${violation.hash}) with no data invariant — a true no-op self-edge.`;\n case 'headRefMissing':\n return `Head ref \\`refs/head.json\\` is missing for contract space \"${violation.spaceId}\".`;\n case 'headRefNotInGraph':\n return `Head ref ${violation.hash} for contract space \"${violation.spaceId}\" is not present in the migration graph.`;\n case 'refUnreadable':\n return `Ref \"${violation.refName}\" for contract space \"${violation.spaceId}\" is unreadable: ${violation.detail}`;\n case 'duplicateMigrationHash':\n return `Multiple migrations in space \"${violation.spaceId}\" share migrationHash \"${violation.migrationHash}\" (${violation.dirNames.join(', ')}).`;\n default: {\n const spaceId = 'spaceId' in violation ? violation.spaceId : '*';\n return `Integrity violation \"${violation.kind}\" for contract space \"${spaceId}\".`;\n }\n }\n}\n\n/**\n * Map the integrity violations `checkIntegrity` reports into a single\n * CLI structured-error envelope, preserving the error codes the prior\n * throw-on-load loader emitted: `5001` (layout drift, bundled) and\n * `5002` (target / disjointness / contract-validation / structural\n * integrity). Returns `null` when there is nothing to refuse on.\n *\n * Precedence reproduces the prior loader's first-failure ordering:\n * layout drift first (every offence bundled into one envelope), then\n * target mismatch, then disjointness, then a contract-validation\n * failure, then any remaining structural integrity violation.\n */\nexport function mapIntegrityViolations(\n violations: readonly IntegrityViolation[],\n): CliStructuredError | null {\n if (violations.length === 0) return null;\n\n const layout = violations.filter(\n (v): v is Extract<IntegrityViolation, { kind: 'orphanSpaceDir' | 'declaredButUnmigrated' }> =>\n v.kind === 'orphanSpaceDir' || v.kind === 'declaredButUnmigrated',\n );\n if (layout.length > 0) {\n const lines = layout.map((v) => `- [${v.kind}] ${v.spaceId}`);\n const summary =\n layout.length === 1\n ? 'Contract-space layout violation detected'\n : `Contract-space layout violations detected (${layout.length})`;\n return new CliStructuredError('5001', summary, {\n domain: 'MIG',\n why: `The on-disk \\`migrations/\\` directory and your \\`extensionPacks\\` declaration are not in agreement.\\n${lines.join('\\n')}`,\n fix: 'Declare the extension in `extensionPacks` and re-emit its contract-space artefacts, or remove the orphan `migrations/<space>` directory.',\n docsUrl: CONTRACT_SPACES_DOCS_URL,\n meta: { violations: layout },\n });\n }\n\n const targetMismatch = violations.find((v) => v.kind === 'targetMismatch');\n if (targetMismatch && targetMismatch.kind === 'targetMismatch') {\n return targetMismatchError(\n targetMismatch.spaceId,\n targetMismatch.expected,\n targetMismatch.actual,\n );\n }\n\n const disjointness = violations.find((v) => v.kind === 'disjointness');\n if (disjointness && disjointness.kind === 'disjointness') {\n return contractSpaceError5002(\n `Contract-space disjointness violation: storage element \"${disjointness.element}\" claimed by multiple spaces`,\n {\n why: `Spaces ${disjointness.claimedBy.map((s) => `\"${s}\"`).join(', ')} all claim the storage element \"${disjointness.element}\". Each storage element must be owned by exactly one contract space.`,\n fix: 'Update the conflicting contracts so each storage element is claimed by exactly one space.',\n violations: [disjointness],\n },\n );\n }\n\n const contractUnreadable = violations.find((v) => v.kind === 'contractUnreadable');\n if (contractUnreadable && contractUnreadable.kind === 'contractUnreadable') {\n return contractSpaceError5002(\n `Contract-space contract validation failed for \"${contractUnreadable.spaceId}\"`,\n {\n why: contractUnreadable.detail,\n fix: 'Re-emit the extension contract with `prisma-next contract emit`, or fix the extension pack descriptor producing the invalid contract.',\n violations: [contractUnreadable],\n },\n );\n }\n\n // Any remaining recoverable structural violation refuses as an\n // integrity failure, surfacing the first one's detail (every violation\n // is still computed; the gate just renders one envelope).\n const structural = violations[0]!;\n const spaceId = 'spaceId' in structural ? structural.spaceId : '*';\n return contractSpaceError5002(`Contract-space integrity failure for \"${spaceId}\"`, {\n why: describeIntegrityViolation(structural),\n fix: 'Re-emit the affected migration package(s) or restore the on-disk `migrations/` directory from version control.',\n violations: [structural],\n });\n}\n\n/**\n * Inputs needed to compose the aggregate loader at the CLI surface.\n *\n * Keeps the loader framework-neutral (no `Config` import) by accepting\n * already-resolved structural inputs: validated app contract, target\n * id, migrations root directory, and the set of extension descriptors.\n */\nexport interface BuildAggregateInputs<TFamilyId extends string, TTargetId extends string> {\n readonly targetId: TTargetId;\n readonly migrationsDir: string;\n readonly appContract: Contract;\n readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;\n readonly deserializeContract: (contractJson: unknown) => Contract;\n}\n\nfunction declaredExtensionsFromInputs(\n extensionPacks: BuildAggregateInputs<string, string>['extensionPacks'],\n): readonly DeclaredExtensionEntry[] {\n return toDeclaredExtensionsFromRaw(extensionPacks as ReadonlyArray<unknown>);\n}\n\n/**\n * Reject extension descriptors whose configured target disagrees with\n * the project target before any on-disk read.\n */\nexport function refuseDeclaredExtensionTargetMismatch<\n TFamilyId extends string,\n TTargetId extends string,\n>(inputs: BuildAggregateInputs<TFamilyId, TTargetId>): CliStructuredError | null {\n for (const declared of declaredExtensionsFromInputs(inputs.extensionPacks)) {\n if (declared.targetId !== inputs.targetId) {\n return targetMismatchError(declared.id, inputs.targetId, declared.targetId);\n }\n }\n return null;\n}\n\n/**\n * Load the tolerant {@link ContractSpaceAggregate} once at the CLI\n * surface. Construction never throws on disk content; callers query\n * {@link ContractSpaceAggregate.app} / extension facets instead of\n * re-reading `migrations/`.\n */\nexport async function loadContractSpaceAggregateForCli<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n inputs: BuildAggregateInputs<TFamilyId, TTargetId>,\n): Promise<Result<ContractSpaceAggregate, CliStructuredError>> {\n const targetFailure = refuseDeclaredExtensionTargetMismatch(inputs);\n if (targetFailure) {\n return notOk(targetFailure);\n }\n\n const aggregate = await loadContractSpaceAggregate({\n migrationsDir: inputs.migrationsDir,\n deserializeContract: inputs.deserializeContract,\n appContract: inputs.appContract,\n });\n return ok(aggregate);\n}\n\n/**\n * Run `checkIntegrity` on a loaded aggregate and map violations into\n * the contract-space refusal envelope, or return `null` when the model\n * is acceptable for the requested check scope.\n */\nexport function refuseContractSpaceIntegrity(\n aggregate: ContractSpaceAggregate,\n options: IntegrityQueryOptions,\n): CliStructuredError | null {\n return mapIntegrityViolations(aggregate.checkIntegrity(options));\n}\n\nconst PACKAGE_CORRUPTION_KINDS = new Set<IntegrityViolation['kind']>([\n 'hashMismatch',\n 'providedInvariantsMismatch',\n 'packageUnloadable',\n]);\n\n/**\n * Reader-subset integrity refusal for `migration status`: package\n * corruptions only (`hashMismatch`, `providedInvariantsMismatch`,\n * `packageUnloadable`).\n */\nexport function refusePackageCorruptionOnAggregate(\n aggregate: ContractSpaceAggregate,\n): CliStructuredError | null {\n const corruption = aggregate.checkIntegrity().filter((v) => PACKAGE_CORRUPTION_KINDS.has(v.kind));\n return mapIntegrityViolations(corruption);\n}\n\n/**\n * Construct the tolerant {@link ContractSpaceAggregate} at the CLI\n * surface and apply the explicit integrity refusal.\n *\n * App-space migration packages are read from `migrations/<app>/` by the\n * loader itself; callers no longer thread them through.\n */\nexport async function buildContractSpaceAggregate<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n inputs: BuildAggregateInputs<TFamilyId, TTargetId>,\n): Promise<Result<ContractSpaceAggregate, CliStructuredError>> {\n const declaredExtensions = declaredExtensionsFromInputs(inputs.extensionPacks);\n const loaded = await loadContractSpaceAggregateForCli(inputs);\n if (!loaded.ok) {\n return loaded;\n }\n const failure = refuseContractSpaceIntegrity(loaded.value, {\n declaredExtensions,\n checkContracts: true,\n });\n if (failure) {\n return notOk(failure);\n }\n return ok(loaded.value);\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { t as loadConfig } from "./config-loader-B6sJjXTv.mjs";
2
2
  import { C as errorRuntime, D as errorTargetMismatch, O as errorUnexpected, a as errorContractValidationFailed, c as errorDriverRequired, l as errorFileNotFound, m as errorMarkerMissing, o as errorDatabaseConnectionRequired, t as CliStructuredError, u as errorHashMismatch } from "./cli-errors-DFF1LlfU.mjs";
3
- import { A as formatStyledHeader, c as resolveContractPath, d as setCommandDescriptions, f as setCommandExamples, l as resolveMigrationPaths, o as maskConnectionUrl, t as addGlobalOptions, v as parseGlobalFlagsOrExit, w as handleResult, y as createTerminalUI } from "./command-helpers-yLuA78TP.mjs";
3
+ import { A as formatStyledHeader, c as resolveContractPath, d as setCommandDescriptions, f as setCommandExamples, l as resolveMigrationPaths, o as maskConnectionUrl, t as addGlobalOptions, v as parseGlobalFlagsOrExit, w as handleResult, y as createTerminalUI } from "./command-helpers-CI8P5Xyd.mjs";
4
4
  import { t as createProgressAdapter } from "./progress-adapter-xASh41wr.mjs";
5
- import { a as ContractValidationError, t as createControlClient } from "./client-a5NJce0-.mjs";
6
- import { c as formatVerifyOutput, i as formatSchemaVerifyOutput, r as formatSchemaVerifyJson, s as formatVerifyJson } from "./verify-9gDJz6cm.mjs";
5
+ import { a as ContractValidationError, t as createControlClient } from "./client-5uvDppD8.mjs";
6
+ import { c as formatVerifyOutput, i as formatSchemaVerifyOutput, r as formatSchemaVerifyJson, s as formatVerifyJson } from "./verify-ktSRQvIS.mjs";
7
7
  import { Command } from "commander";
8
8
  import { ifDefined } from "@prisma-next/utils/defined";
9
9
  import { notOk, ok } from "@prisma-next/utils/result";
@@ -399,4 +399,4 @@ function createDbVerifyCommand() {
399
399
  //#endregion
400
400
  export { createDbVerifyCommand as t };
401
401
 
402
- //# sourceMappingURL=db-verify-B00o3LuC.mjs.map
402
+ //# sourceMappingURL=db-verify-BzpwFyLg.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"db-verify-B00o3LuC.mjs","names":[],"sources":["../src/utils/combine-schema-results.ts","../src/commands/db-verify.ts"],"sourcesContent":["import type { VerifyDatabaseSchemaResult } from '@prisma-next/framework-components/control';\n\n/**\n * Collapse the aggregate verifier's per-space schema results into a\n * single {@link VerifyDatabaseSchemaResult} for the existing CLI\n * display surface. Concatenates issues across members; sums counts;\n * uses the app member's result as the structural envelope (storage\n * hash, target).\n *\n * **Summary policy.** Preserve the per-family phrasing whenever the\n * combined `ok` flag agrees with the app member's `ok` flag — this is\n * the common case (single-family deployments, single-app deployments)\n * and the family's \"satisfies / does not satisfy contract\" phrasing\n * stays user-visible. When the app passes but an extension fails (or\n * vice versa) the app's summary contradicts the envelope, so fall back\n * to the first failing member's summary. This keeps family phrasing\n * intact and the envelope internally consistent (`ok: false` ↔ failure\n * summary).\n */\nexport function combineSchemaResults(\n perSpace: ReadonlyMap<string, VerifyDatabaseSchemaResult>,\n appSpaceId: string,\n strict: boolean,\n): VerifyDatabaseSchemaResult {\n const appResult = perSpace.get(appSpaceId) ?? perSpace.values().next().value;\n if (appResult === undefined) {\n throw new Error('Aggregate verifier returned no schema results — this is a wiring bug.');\n }\n\n let okAll = true;\n let firstFailure: VerifyDatabaseSchemaResult | undefined;\n let issues: VerifyDatabaseSchemaResult['schema']['issues'] = [];\n const counts = { pass: 0, warn: 0, fail: 0, totalNodes: 0 };\n const childRoots: Array<VerifyDatabaseSchemaResult['schema']['root']> = [];\n for (const [, result] of perSpace) {\n if (!result.ok) {\n okAll = false;\n if (firstFailure === undefined) firstFailure = result;\n }\n issues = [...issues, ...result.schema.issues];\n counts.pass += result.schema.counts.pass;\n counts.warn += result.schema.counts.warn;\n counts.fail += result.schema.counts.fail;\n counts.totalNodes += result.schema.counts.totalNodes;\n childRoots.push(result.schema.root);\n }\n\n // When `okAll !== appResult.ok`, exactly one shape is reachable: app passes\n // (`appResult.ok === true`) and at least one other member failed\n // (`okAll === false`). In that shape the failure was assigned to\n // `firstFailure` during iteration, so non-null assertion is safe. The mirror\n // shape (app fails while every member passes) is impossible because\n // `appResult` either *is* a member of `perSpace` or is the first iterator\n // value; either way its `ok` flag participates in `okAll`.\n const summary =\n okAll === appResult.ok\n ? appResult.summary\n : (firstFailure as VerifyDatabaseSchemaResult).summary;\n\n return {\n ok: okAll,\n ...(okAll ? {} : { code: appResult.code ?? 'PN-RUN-3010' }),\n summary,\n contract: appResult.contract,\n target: appResult.target,\n schema: {\n issues,\n root: {\n status: okAll ? 'pass' : 'fail',\n kind: 'aggregate',\n name: 'aggregate',\n contractPath: '',\n code: 'AGGREGATE',\n message: okAll ? 'Aggregate schema matches' : 'Aggregate schema mismatch',\n expected: undefined,\n actual: undefined,\n children: childRoots,\n },\n counts,\n },\n meta: { strict },\n timings: { total: 0 },\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type {\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n createControlStack,\n VERIFY_CODE_HASH_MISMATCH,\n VERIFY_CODE_MARKER_MISSING,\n VERIFY_CODE_TARGET_MISMATCH,\n} from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorHashMismatch,\n errorMarkerMissing,\n errorRuntime,\n errorTargetMismatch,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { combineSchemaResults } from '../utils/combine-schema-results';\nimport {\n addGlobalOptions,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport {\n type DbVerifyCommandSuccessResult,\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatVerifyJson,\n formatVerifyOutput,\n} from '../utils/formatters/verify';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface DbVerifyOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly markerOnly?: boolean;\n readonly schemaOnly?: boolean;\n readonly strict?: boolean;\n}\n\ntype DbVerifyMode = 'full' | 'marker-only' | 'schema-only';\n\n/**\n * Maps a VerifyDatabaseResult failure to a CliStructuredError.\n */\nfunction mapVerifyFailure(verifyResult: VerifyDatabaseResult): CliStructuredError {\n if (!verifyResult.ok && verifyResult.code) {\n if (verifyResult.code === VERIFY_CODE_MARKER_MISSING) {\n return errorMarkerMissing();\n }\n if (verifyResult.code === VERIFY_CODE_HASH_MISMATCH) {\n const storageMatch = verifyResult.marker?.storageHash === verifyResult.contract.storageHash;\n const profileMatch =\n !verifyResult.contract.profileHash ||\n verifyResult.marker?.profileHash === verifyResult.contract.profileHash;\n\n if (!storageMatch) {\n return errorHashMismatch({\n why: 'Contract storageHash does not match database marker',\n expected: verifyResult.contract.storageHash,\n ...ifDefined('actual', verifyResult.marker?.storageHash),\n });\n }\n\n return errorHashMismatch({\n why: profileMatch\n ? 'Contract hash does not match database marker'\n : 'Contract profileHash does not match database marker',\n ...ifDefined('expected', verifyResult.contract.profileHash),\n ...ifDefined('actual', verifyResult.marker?.profileHash),\n });\n }\n if (verifyResult.code === VERIFY_CODE_TARGET_MISMATCH) {\n return errorTargetMismatch(\n verifyResult.target.expected,\n verifyResult.target.actual ?? 'unknown',\n );\n }\n // Unknown code - fall through to runtime error\n }\n return errorRuntime(verifyResult.summary);\n}\n\ntype DbVerifyFailure = CliStructuredError | VerifyDatabaseSchemaResult;\n\nfunction errorInvalidVerifyMode(options: {\n readonly why: string;\n readonly fix: string;\n}): CliStructuredError {\n return new CliStructuredError('4012', 'Invalid verify mode', {\n domain: 'CLI',\n why: options.why,\n fix: options.fix,\n docsUrl: 'https://pris.ly/db-verify',\n });\n}\n\nfunction resolveDbVerifyMode(options: DbVerifyOptions): Result<DbVerifyMode, CliStructuredError> {\n if (options.markerOnly && options.schemaOnly) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--marker-only` and `--schema-only` cannot be used together',\n fix: 'Choose one mode: omit both to check the marker and schema, use `--marker-only` to check only the marker, or use `--schema-only` to check only the live schema.',\n }),\n );\n }\n\n if (options.markerOnly && options.strict) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--strict` requires schema verification, but `--marker-only` skips it',\n fix: 'Remove `--strict`, or use `db verify` / `db verify --schema-only` when you want to check the live schema in strict mode.',\n }),\n );\n }\n\n if (options.schemaOnly) {\n return ok('schema-only');\n }\n\n if (options.markerOnly) {\n return ok('marker-only');\n }\n\n return ok('full');\n}\n\nfunction formatDbVerifyModeLabel(mode: DbVerifyMode, strict: boolean): string {\n if (mode === 'marker-only') {\n return 'marker only';\n }\n\n if (mode === 'schema-only') {\n return `schema only (${strict ? 'strict' : 'tolerant'})`;\n }\n\n return `full (marker + schema, ${strict ? 'strict' : 'tolerant'})`;\n}\n\nfunction formatDbVerifyInvocation(mode: DbVerifyMode, strict: boolean): string {\n const args = ['db verify'];\n\n if (mode === 'marker-only') {\n args.push('--marker-only');\n }\n\n if (mode === 'schema-only') {\n args.push('--schema-only');\n }\n\n if (strict) {\n args.push('--strict');\n }\n\n return args.join(' ');\n}\n\nfunction createDbVerifyConnectionRequiredError(options: {\n readonly configPath: string;\n readonly mode: DbVerifyMode;\n readonly strict: boolean;\n}): CliStructuredError {\n const invocation = formatDbVerifyInvocation(options.mode, options.strict);\n return errorDatabaseConnectionRequired({\n why: `Database connection is required for ${invocation} (set db.connection in ${options.configPath}, or pass --db <url>)`,\n retryCommand: `prisma-next ${invocation} --db <url>`,\n });\n}\n\nfunction renderVerifyHeader(\n paths: { configPath: string; contractPath: string },\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n flags: GlobalFlags,\n ui: TerminalUI,\n): void {\n if (flags.json || flags.quiet) return;\n\n const description =\n mode === 'schema-only'\n ? 'Check whether the live database schema matches your contract'\n : mode === 'marker-only'\n ? 'Check whether the database marker matches your contract'\n : 'Check whether the database marker and live schema match your contract';\n\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: paths.configPath },\n { label: 'contract', value: paths.contractPath },\n { label: 'mode', value: formatDbVerifyModeLabel(mode, options.strict ?? false) },\n ];\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n }\n\n ui.stderr(\n formatStyledHeader({\n command: 'db verify',\n description,\n url: 'https://pris.ly/db-verify',\n details,\n flags,\n }),\n );\n}\n\nasync function resolveVerifyPaths(options: DbVerifyOptions) {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n return { config, configPath, contractPathAbsolute, contractPath };\n}\n\ntype VerifyPaths = Awaited<ReturnType<typeof resolveVerifyPaths>>;\n\ninterface VerifySetup extends VerifyPaths {\n readonly contractJson: Contract;\n readonly dbConnection: string;\n}\n\nasync function resolveVerifySetup(\n paths: VerifyPaths,\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n): Promise<Result<VerifySetup, CliStructuredError>> {\n const { config, configPath, contractPathAbsolute, contractPath } = paths;\n\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n // Cross the family `deserializeContract` seam at the read site, just\n // like every other CLI on-disk read (TML-2536). The downstream\n // `dbVerify` op accepts the hydrated `Contract` directly and no\n // longer re-deserializes.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let contractJson: Contract;\n try {\n contractJson = familyInstance.deserializeContract(JSON.parse(contractJsonContent) as unknown);\n } catch (error) {\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const dbConnection = options.db ?? config.db?.connection;\n if (typeof dbConnection !== 'string' || dbConnection.length === 0) {\n return notOk(\n createDbVerifyConnectionRequiredError({\n configPath,\n mode,\n strict: options.strict ?? false,\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: `Config.driver is required for ${formatDbVerifyInvocation(mode, options.strict ?? false)}`,\n }),\n );\n }\n\n return ok({ ...paths, contractJson, dbConnection });\n}\n\nfunction createVerifyClient(setup: VerifySetup) {\n return createControlClient({\n family: setup.config.family,\n target: setup.config.target,\n adapter: setup.config.adapter,\n driver: setup.config.driver!,\n extensionPacks: setup.config.extensionPacks ?? [],\n });\n}\n\nfunction wrapVerifyError(\n error: unknown,\n contractPathAbsolute: string,\n modeLabel: string,\n): Result<never, CliStructuredError> {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during ${modeLabel}: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n}\n\n/**\n * Executes the db verify command and returns a structured Result.\n */\nasync function executeDbVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n mode: Extract<DbVerifyMode, 'full' | 'marker-only'>,\n): Promise<Result<DbVerifyCommandSuccessResult, DbVerifyFailure>> {\n const startTime = Date.now();\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, mode, flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, mode);\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n // Single-contract marker verification preserved for the existing\n // marker / target / hash failure surface (`PN-RUN-3001/3002/3003`).\n // The aggregate verifier (run below for the per-space marker /\n // schema checks) does not duplicate this: it concerns itself with\n // marker-vs-on-disk and orphan-marker drift, not the\n // hash-mismatch-against-the-app-contract lane that today's\n // `client.verify` covers.\n const verifyResult = await client.verify({\n contract: contractJson,\n connection: dbConnection,\n onProgress,\n });\n\n if (!verifyResult.ok) {\n return notOk(mapVerifyFailure(verifyResult));\n }\n\n // Aggregate verifier (loader → verifier pipeline). Runs the layout\n // precheck, marker-aware per-space verifier, and (full mode only)\n // per-space pre-projected schema verification (closes F23).\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: mode === 'marker-only',\n skipMarker: false,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n if (mode === 'marker-only') {\n return ok({\n ok: true,\n mode: 'marker-only',\n summary: 'Database marker matches contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n warning: 'Schema verification skipped because --marker-only was provided',\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'skipped',\n },\n timings: { total: Date.now() - startTime },\n });\n }\n\n const combined = combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n );\n if (!combined.ok) {\n return notOk(combined);\n }\n\n return ok({\n ok: true,\n mode: 'full',\n summary: 'Database marker and schema match contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n schema: {\n summary: combined.summary,\n counts: combined.schema.counts,\n strict: combined.meta?.strict ?? false,\n },\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'performed',\n },\n timings: { total: Date.now() - startTime },\n });\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify');\n } finally {\n await client.close();\n }\n}\n\nasync function executeDbSchemaOnlyVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<VerifyDatabaseSchemaResult, CliStructuredError>> {\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, 'schema-only', flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, 'schema-only');\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n await client.connect(dbConnection);\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: false,\n skipMarker: true,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n return ok(\n combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n ),\n );\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify --schema-only');\n } finally {\n await client.close();\n }\n}\n\nexport function createDbVerifyCommand(): Command {\n const command = new Command('verify');\n setCommandDescriptions(\n command,\n 'Check whether the database marker and live schema match your contract',\n 'Verifies the database marker first, then checks the database schema matches your contract.\\n' +\n 'Use `--marker-only` for marker-only verification, `--schema-only` to skip marker checks and\\n' +\n 'inspect only the live schema, and `--strict` to fail if the database includes elements\\n' +\n 'not present in the contract.',\n );\n setCommandExamples(command, [\n 'prisma-next db verify --db $DATABASE_URL',\n 'prisma-next db verify --db $DATABASE_URL --strict',\n 'prisma-next db verify --db $DATABASE_URL --schema-only',\n 'prisma-next db verify --db $DATABASE_URL --schema-only --strict',\n 'prisma-next db verify --db $DATABASE_URL --marker-only',\n 'prisma-next db verify --db $DATABASE_URL --json',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--marker-only', 'Skip schema verification and only check the database marker')\n .option(\n '--schema-only',\n 'Skip marker verification and only check whether the live schema satisfies the contract',\n )\n .option(\n '--strict',\n 'Strict mode: schema elements not present in the contract are considered an error',\n false,\n )\n .action(async (options: DbVerifyOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n\n const modeResult = resolveDbVerifyMode(options);\n if (!modeResult.ok) {\n const exitCode = handleResult(modeResult as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n const mode = modeResult.value;\n\n if (mode === 'schema-only') {\n const result = await executeDbSchemaOnlyVerifyCommand(options, flags, ui);\n const exitCode = handleResult(result, flags, ui, (schemaVerifyResult) => {\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(schemaVerifyResult));\n } else {\n const output = formatSchemaVerifyOutput(schemaVerifyResult, flags);\n if (output) {\n ui.log(output);\n }\n }\n });\n\n if (result.ok && !result.value.ok) {\n process.exit(1);\n }\n\n process.exit(exitCode);\n }\n\n const result = await executeDbVerifyCommand(options, flags, ui, mode);\n\n if (result.ok) {\n if (flags.json) {\n ui.output(formatVerifyJson(result.value));\n } else {\n const output = formatVerifyOutput(result.value, flags);\n if (output) {\n ui.log(output);\n }\n }\n process.exit(0);\n }\n\n if (CliStructuredError.is(result.failure)) {\n const exitCode = handleResult(result as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(result.failure));\n } else {\n // Always show schema-drift failures, even in quiet mode — exiting 1 without\n // diagnostics is unhelpful.\n const output = formatSchemaVerifyOutput(result.failure, { ...flags, quiet: false });\n if (output) {\n ui.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"db-verify-BzpwFyLg.mjs","names":[],"sources":["../src/utils/combine-schema-results.ts","../src/commands/db-verify.ts"],"sourcesContent":["import type { VerifyDatabaseSchemaResult } from '@prisma-next/framework-components/control';\n\n/**\n * Collapse the aggregate verifier's per-space schema results into a\n * single {@link VerifyDatabaseSchemaResult} for the existing CLI\n * display surface. Concatenates issues across members; sums counts;\n * uses the app member's result as the structural envelope (storage\n * hash, target).\n *\n * **Summary policy.** Preserve the per-family phrasing whenever the\n * combined `ok` flag agrees with the app member's `ok` flag — this is\n * the common case (single-family deployments, single-app deployments)\n * and the family's \"satisfies / does not satisfy contract\" phrasing\n * stays user-visible. When the app passes but an extension fails (or\n * vice versa) the app's summary contradicts the envelope, so fall back\n * to the first failing member's summary. This keeps family phrasing\n * intact and the envelope internally consistent (`ok: false` ↔ failure\n * summary).\n */\nexport function combineSchemaResults(\n perSpace: ReadonlyMap<string, VerifyDatabaseSchemaResult>,\n appSpaceId: string,\n strict: boolean,\n): VerifyDatabaseSchemaResult {\n const appResult = perSpace.get(appSpaceId) ?? perSpace.values().next().value;\n if (appResult === undefined) {\n throw new Error('Aggregate verifier returned no schema results — this is a wiring bug.');\n }\n\n let okAll = true;\n let firstFailure: VerifyDatabaseSchemaResult | undefined;\n let issues: VerifyDatabaseSchemaResult['schema']['issues'] = [];\n const counts = { pass: 0, warn: 0, fail: 0, totalNodes: 0 };\n const childRoots: Array<VerifyDatabaseSchemaResult['schema']['root']> = [];\n for (const [, result] of perSpace) {\n if (!result.ok) {\n okAll = false;\n if (firstFailure === undefined) firstFailure = result;\n }\n issues = [...issues, ...result.schema.issues];\n counts.pass += result.schema.counts.pass;\n counts.warn += result.schema.counts.warn;\n counts.fail += result.schema.counts.fail;\n counts.totalNodes += result.schema.counts.totalNodes;\n childRoots.push(result.schema.root);\n }\n\n // When `okAll !== appResult.ok`, exactly one shape is reachable: app passes\n // (`appResult.ok === true`) and at least one other member failed\n // (`okAll === false`). In that shape the failure was assigned to\n // `firstFailure` during iteration, so non-null assertion is safe. The mirror\n // shape (app fails while every member passes) is impossible because\n // `appResult` either *is* a member of `perSpace` or is the first iterator\n // value; either way its `ok` flag participates in `okAll`.\n const summary =\n okAll === appResult.ok\n ? appResult.summary\n : (firstFailure as VerifyDatabaseSchemaResult).summary;\n\n return {\n ok: okAll,\n ...(okAll ? {} : { code: appResult.code ?? 'PN-RUN-3010' }),\n summary,\n contract: appResult.contract,\n target: appResult.target,\n schema: {\n issues,\n root: {\n status: okAll ? 'pass' : 'fail',\n kind: 'aggregate',\n name: 'aggregate',\n contractPath: '',\n code: 'AGGREGATE',\n message: okAll ? 'Aggregate schema matches' : 'Aggregate schema mismatch',\n expected: undefined,\n actual: undefined,\n children: childRoots,\n },\n counts,\n },\n meta: { strict },\n timings: { total: 0 },\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type {\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport {\n createControlStack,\n VERIFY_CODE_HASH_MISMATCH,\n VERIFY_CODE_MARKER_MISSING,\n VERIFY_CODE_TARGET_MISMATCH,\n} from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorHashMismatch,\n errorMarkerMissing,\n errorRuntime,\n errorTargetMismatch,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { combineSchemaResults } from '../utils/combine-schema-results';\nimport {\n addGlobalOptions,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport {\n type DbVerifyCommandSuccessResult,\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatVerifyJson,\n formatVerifyOutput,\n} from '../utils/formatters/verify';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface DbVerifyOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly markerOnly?: boolean;\n readonly schemaOnly?: boolean;\n readonly strict?: boolean;\n}\n\ntype DbVerifyMode = 'full' | 'marker-only' | 'schema-only';\n\n/**\n * Maps a VerifyDatabaseResult failure to a CliStructuredError.\n */\nfunction mapVerifyFailure(verifyResult: VerifyDatabaseResult): CliStructuredError {\n if (!verifyResult.ok && verifyResult.code) {\n if (verifyResult.code === VERIFY_CODE_MARKER_MISSING) {\n return errorMarkerMissing();\n }\n if (verifyResult.code === VERIFY_CODE_HASH_MISMATCH) {\n const storageMatch = verifyResult.marker?.storageHash === verifyResult.contract.storageHash;\n const profileMatch =\n !verifyResult.contract.profileHash ||\n verifyResult.marker?.profileHash === verifyResult.contract.profileHash;\n\n if (!storageMatch) {\n return errorHashMismatch({\n why: 'Contract storageHash does not match database marker',\n expected: verifyResult.contract.storageHash,\n ...ifDefined('actual', verifyResult.marker?.storageHash),\n });\n }\n\n return errorHashMismatch({\n why: profileMatch\n ? 'Contract hash does not match database marker'\n : 'Contract profileHash does not match database marker',\n ...ifDefined('expected', verifyResult.contract.profileHash),\n ...ifDefined('actual', verifyResult.marker?.profileHash),\n });\n }\n if (verifyResult.code === VERIFY_CODE_TARGET_MISMATCH) {\n return errorTargetMismatch(\n verifyResult.target.expected,\n verifyResult.target.actual ?? 'unknown',\n );\n }\n // Unknown code - fall through to runtime error\n }\n return errorRuntime(verifyResult.summary);\n}\n\ntype DbVerifyFailure = CliStructuredError | VerifyDatabaseSchemaResult;\n\nfunction errorInvalidVerifyMode(options: {\n readonly why: string;\n readonly fix: string;\n}): CliStructuredError {\n return new CliStructuredError('4012', 'Invalid verify mode', {\n domain: 'CLI',\n why: options.why,\n fix: options.fix,\n docsUrl: 'https://pris.ly/db-verify',\n });\n}\n\nfunction resolveDbVerifyMode(options: DbVerifyOptions): Result<DbVerifyMode, CliStructuredError> {\n if (options.markerOnly && options.schemaOnly) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--marker-only` and `--schema-only` cannot be used together',\n fix: 'Choose one mode: omit both to check the marker and schema, use `--marker-only` to check only the marker, or use `--schema-only` to check only the live schema.',\n }),\n );\n }\n\n if (options.markerOnly && options.strict) {\n return notOk(\n errorInvalidVerifyMode({\n why: '`--strict` requires schema verification, but `--marker-only` skips it',\n fix: 'Remove `--strict`, or use `db verify` / `db verify --schema-only` when you want to check the live schema in strict mode.',\n }),\n );\n }\n\n if (options.schemaOnly) {\n return ok('schema-only');\n }\n\n if (options.markerOnly) {\n return ok('marker-only');\n }\n\n return ok('full');\n}\n\nfunction formatDbVerifyModeLabel(mode: DbVerifyMode, strict: boolean): string {\n if (mode === 'marker-only') {\n return 'marker only';\n }\n\n if (mode === 'schema-only') {\n return `schema only (${strict ? 'strict' : 'tolerant'})`;\n }\n\n return `full (marker + schema, ${strict ? 'strict' : 'tolerant'})`;\n}\n\nfunction formatDbVerifyInvocation(mode: DbVerifyMode, strict: boolean): string {\n const args = ['db verify'];\n\n if (mode === 'marker-only') {\n args.push('--marker-only');\n }\n\n if (mode === 'schema-only') {\n args.push('--schema-only');\n }\n\n if (strict) {\n args.push('--strict');\n }\n\n return args.join(' ');\n}\n\nfunction createDbVerifyConnectionRequiredError(options: {\n readonly configPath: string;\n readonly mode: DbVerifyMode;\n readonly strict: boolean;\n}): CliStructuredError {\n const invocation = formatDbVerifyInvocation(options.mode, options.strict);\n return errorDatabaseConnectionRequired({\n why: `Database connection is required for ${invocation} (set db.connection in ${options.configPath}, or pass --db <url>)`,\n retryCommand: `prisma-next ${invocation} --db <url>`,\n });\n}\n\nfunction renderVerifyHeader(\n paths: { configPath: string; contractPath: string },\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n flags: GlobalFlags,\n ui: TerminalUI,\n): void {\n if (flags.json || flags.quiet) return;\n\n const description =\n mode === 'schema-only'\n ? 'Check whether the live database schema matches your contract'\n : mode === 'marker-only'\n ? 'Check whether the database marker matches your contract'\n : 'Check whether the database marker and live schema match your contract';\n\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: paths.configPath },\n { label: 'contract', value: paths.contractPath },\n { label: 'mode', value: formatDbVerifyModeLabel(mode, options.strict ?? false) },\n ];\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n }\n\n ui.stderr(\n formatStyledHeader({\n command: 'db verify',\n description,\n url: 'https://pris.ly/db-verify',\n details,\n flags,\n }),\n );\n}\n\nasync function resolveVerifyPaths(options: DbVerifyOptions) {\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n return { config, configPath, contractPathAbsolute, contractPath };\n}\n\ntype VerifyPaths = Awaited<ReturnType<typeof resolveVerifyPaths>>;\n\ninterface VerifySetup extends VerifyPaths {\n readonly contractJson: Contract;\n readonly dbConnection: string;\n}\n\nasync function resolveVerifySetup(\n paths: VerifyPaths,\n options: DbVerifyOptions,\n mode: DbVerifyMode,\n): Promise<Result<VerifySetup, CliStructuredError>> {\n const { config, configPath, contractPathAbsolute, contractPath } = paths;\n\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n // Cross the family `deserializeContract` seam at the read site, just\n // like every other CLI on-disk read (TML-2536). The downstream\n // `dbVerify` op accepts the hydrated `Contract` directly and no\n // longer re-deserializes.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let contractJson: Contract;\n try {\n contractJson = familyInstance.deserializeContract(JSON.parse(contractJsonContent) as unknown);\n } catch (error) {\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const dbConnection = options.db ?? config.db?.connection;\n if (typeof dbConnection !== 'string' || dbConnection.length === 0) {\n return notOk(\n createDbVerifyConnectionRequiredError({\n configPath,\n mode,\n strict: options.strict ?? false,\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: `Config.driver is required for ${formatDbVerifyInvocation(mode, options.strict ?? false)}`,\n }),\n );\n }\n\n return ok({ ...paths, contractJson, dbConnection });\n}\n\nfunction createVerifyClient(setup: VerifySetup) {\n return createControlClient({\n family: setup.config.family,\n target: setup.config.target,\n adapter: setup.config.adapter,\n driver: setup.config.driver!,\n extensionPacks: setup.config.extensionPacks ?? [],\n });\n}\n\nfunction wrapVerifyError(\n error: unknown,\n contractPathAbsolute: string,\n modeLabel: string,\n): Result<never, CliStructuredError> {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during ${modeLabel}: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n}\n\n/**\n * Executes the db verify command and returns a structured Result.\n */\nasync function executeDbVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n mode: Extract<DbVerifyMode, 'full' | 'marker-only'>,\n): Promise<Result<DbVerifyCommandSuccessResult, DbVerifyFailure>> {\n const startTime = Date.now();\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, mode, flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, mode);\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n // Single-contract marker verification preserved for the existing\n // marker / target / hash failure surface (`PN-RUN-3001/3002/3003`).\n // The aggregate verifier (run below for the per-space marker /\n // schema checks) does not duplicate this: it concerns itself with\n // marker-vs-on-disk and orphan-marker drift, not the\n // hash-mismatch-against-the-app-contract lane that today's\n // `client.verify` covers.\n const verifyResult = await client.verify({\n contract: contractJson,\n connection: dbConnection,\n onProgress,\n });\n\n if (!verifyResult.ok) {\n return notOk(mapVerifyFailure(verifyResult));\n }\n\n // Aggregate verifier (loader → verifier pipeline). Runs the layout\n // precheck, marker-aware per-space verifier, and (full mode only)\n // per-space pre-projected schema verification (closes F23).\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: mode === 'marker-only',\n skipMarker: false,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n if (mode === 'marker-only') {\n return ok({\n ok: true,\n mode: 'marker-only',\n summary: 'Database marker matches contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n warning: 'Schema verification skipped because --marker-only was provided',\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'skipped',\n },\n timings: { total: Date.now() - startTime },\n });\n }\n\n const combined = combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n );\n if (!combined.ok) {\n return notOk(combined);\n }\n\n return ok({\n ok: true,\n mode: 'full',\n summary: 'Database marker and schema match contract',\n contract: verifyResult.contract,\n marker: verifyResult.marker,\n target: verifyResult.target,\n ...ifDefined('missingCodecs', verifyResult.missingCodecs),\n ...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),\n schema: {\n summary: combined.summary,\n counts: combined.schema.counts,\n strict: combined.meta?.strict ?? false,\n },\n meta: {\n ...(verifyResult.meta ?? {}),\n schemaVerification: 'performed',\n },\n timings: { total: Date.now() - startTime },\n });\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify');\n } finally {\n await client.close();\n }\n}\n\nasync function executeDbSchemaOnlyVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<VerifyDatabaseSchemaResult, CliStructuredError>> {\n const paths = await resolveVerifyPaths(options);\n renderVerifyHeader(paths, options, 'schema-only', flags, ui);\n\n const setupResult = await resolveVerifySetup(paths, options, 'schema-only');\n if (!setupResult.ok) return setupResult;\n const { contractJson, dbConnection, contractPathAbsolute } = setupResult.value;\n const { migrationsDir } = resolveMigrationPaths(options.config, setupResult.value.config);\n\n const client = createVerifyClient(setupResult.value);\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n await client.connect(dbConnection);\n const aggregateResult = await client.dbVerify({\n contract: contractJson,\n migrationsDir,\n strict: options.strict ?? false,\n skipSchema: false,\n skipMarker: true,\n onProgress,\n });\n if (!aggregateResult.ok) return notOk(aggregateResult.failure);\n\n return ok(\n combineSchemaResults(\n aggregateResult.value.schemaResults,\n aggregateResult.value.appSpaceId,\n options.strict ?? false,\n ),\n );\n } catch (error) {\n return wrapVerifyError(error, contractPathAbsolute, 'db verify --schema-only');\n } finally {\n await client.close();\n }\n}\n\nexport function createDbVerifyCommand(): Command {\n const command = new Command('verify');\n setCommandDescriptions(\n command,\n 'Check whether the database marker and live schema match your contract',\n 'Verifies the database marker first, then checks the database schema matches your contract.\\n' +\n 'Use `--marker-only` for marker-only verification, `--schema-only` to skip marker checks and\\n' +\n 'inspect only the live schema, and `--strict` to fail if the database includes elements\\n' +\n 'not present in the contract.',\n );\n setCommandExamples(command, [\n 'prisma-next db verify --db $DATABASE_URL',\n 'prisma-next db verify --db $DATABASE_URL --strict',\n 'prisma-next db verify --db $DATABASE_URL --schema-only',\n 'prisma-next db verify --db $DATABASE_URL --schema-only --strict',\n 'prisma-next db verify --db $DATABASE_URL --marker-only',\n 'prisma-next db verify --db $DATABASE_URL --json',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--marker-only', 'Skip schema verification and only check the database marker')\n .option(\n '--schema-only',\n 'Skip marker verification and only check whether the live schema satisfies the contract',\n )\n .option(\n '--strict',\n 'Strict mode: schema elements not present in the contract are considered an error',\n false,\n )\n .action(async (options: DbVerifyOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n\n const modeResult = resolveDbVerifyMode(options);\n if (!modeResult.ok) {\n const exitCode = handleResult(modeResult as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n const mode = modeResult.value;\n\n if (mode === 'schema-only') {\n const result = await executeDbSchemaOnlyVerifyCommand(options, flags, ui);\n const exitCode = handleResult(result, flags, ui, (schemaVerifyResult) => {\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(schemaVerifyResult));\n } else {\n const output = formatSchemaVerifyOutput(schemaVerifyResult, flags);\n if (output) {\n ui.log(output);\n }\n }\n });\n\n if (result.ok && !result.value.ok) {\n process.exit(1);\n }\n\n process.exit(exitCode);\n }\n\n const result = await executeDbVerifyCommand(options, flags, ui, mode);\n\n if (result.ok) {\n if (flags.json) {\n ui.output(formatVerifyJson(result.value));\n } else {\n const output = formatVerifyOutput(result.value, flags);\n if (output) {\n ui.log(output);\n }\n }\n process.exit(0);\n }\n\n if (CliStructuredError.is(result.failure)) {\n const exitCode = handleResult(result as Result<never, CliStructuredError>, flags, ui);\n process.exit(exitCode);\n }\n\n if (flags.json) {\n ui.output(formatSchemaVerifyJson(result.failure));\n } else {\n // Always show schema-drift failures, even in quiet mode — exiting 1 without\n // diagnostics is unhelpful.\n const output = formatSchemaVerifyOutput(result.failure, { ...flags, quiet: false });\n if (output) {\n ui.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { A as ExecuteDbVerifyOptions, C as EmitSuccess, D as SchemaVerifyOptions, E as OnControlProgress, M as executeDbVerify, O as SignOptions, S as EmitResult, _ as DbUpdateSuccess, a as ControlClient, b as EmitFailureCode, c as DbInitFailure, d as DbInitResult, f as DbInitSuccess, g as DbUpdateResult, h as DbUpdateOptions, i as ControlActionName, j as ExecuteDbVerifyResult, k as VerifyOptions, l as DbInitFailureCode, m as DbUpdateFailureCode, n as ContractEmitOptions, o as ControlClientOptions, p as DbUpdateFailure, r as ContractEmitResult, s as ControlProgressEvent, u as DbInitOptions, v as EmitContractConfig, w as IntrospectOptions, x as EmitOptions, y as EmitFailure } from "../types-UWB2-rrw.mjs";
1
+ import { A as ExecuteDbVerifyOptions, C as EmitSuccess, D as SchemaVerifyOptions, E as OnControlProgress, M as executeDbVerify, O as SignOptions, S as EmitResult, _ as DbUpdateSuccess, a as ControlClient, b as EmitFailureCode, c as DbInitFailure, d as DbInitResult, f as DbInitSuccess, g as DbUpdateResult, h as DbUpdateOptions, i as ControlActionName, j as ExecuteDbVerifyResult, k as VerifyOptions, l as DbInitFailureCode, m as DbUpdateFailureCode, n as ContractEmitOptions, o as ControlClientOptions, p as DbUpdateFailure, r as ContractEmitResult, s as ControlProgressEvent, u as DbInitOptions, v as EmitContractConfig, w as IntrospectOptions, x as EmitOptions, y as EmitFailure } from "../types-CEtm6v6a.mjs";
2
2
  import { ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyInstance, ControlStack, SignDatabaseResult, TargetMigrationsCapability, VerifyDatabaseResult, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
3
3
  import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
4
4
  import { Contract } from "@prisma-next/contract/types";
@@ -1,4 +1,4 @@
1
1
  import { n as executeContractEmit, r as disposeEmitQueue } from "../contract-emit-DYBHfZqL.mjs";
2
2
  import { t as enrichContract } from "../contract-enrichment-XmUPhmsS.mjs";
3
- import { i as executeDbInit, n as executeDbVerify, r as executeDbUpdate, t as createControlClient } from "../client-a5NJce0-.mjs";
3
+ import { i as executeDbInit, n as executeDbVerify, r as executeDbUpdate, t as createControlClient } from "../client-5uvDppD8.mjs";
4
4
  export { createControlClient, disposeEmitQueue, enrichContract, executeContractEmit, executeDbInit, executeDbUpdate, executeDbVerify };
@@ -1,4 +1,4 @@
1
- import { t as createContractEmitCommand } from "../contract-emit-FtDVFs2Q.mjs";
1
+ import { t as createContractEmitCommand } from "../contract-emit-DmBG2Nnc.mjs";
2
2
  import { join, resolve } from "pathe";
3
3
  import { existsSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { pathToFileURL } from "node:url";
@@ -1,2 +1,2 @@
1
- import { t as InitOutputSchema } from "../output-CUIdfYo5.mjs";
1
+ import { t as InitOutputSchema } from "../output-B60Gw5fu.mjs";
2
2
  export { InitOutputSchema };
@@ -0,0 +1,62 @@
1
+ //#region src/utils/extension-pack-inputs.ts
2
+ /**
3
+ * Project the CLI's `Config.extensionPacks` array into the canonical
4
+ * {@link ExtensionPackInput} shape. The single `as ExtensionPackLike`
5
+ * structural cast in the CLI lives inside this function.
6
+ */
7
+ function toExtensionInputs(extensionPacks) {
8
+ return extensionPacks.map((raw) => {
9
+ const pack = raw;
10
+ if (pack.contractSpace === void 0) return {
11
+ id: pack.id,
12
+ targetId: pack.targetId
13
+ };
14
+ return {
15
+ id: pack.id,
16
+ targetId: pack.targetId,
17
+ contractSpace: {
18
+ contractJson: pack.contractSpace.contractJson,
19
+ headRef: pack.contractSpace.headRef,
20
+ migrations: pack.contractSpace.migrations ?? []
21
+ }
22
+ };
23
+ });
24
+ }
25
+ /**
26
+ * Minimal aggregate-loader projection that extracts `id` + `targetId`
27
+ * from raw extension pack descriptors **without invoking any
28
+ * `contractSpace` accessor**. Inspects the own-property descriptor so
29
+ * that getter-backed `contractSpace` declarations are detected but
30
+ * never called.
31
+ *
32
+ * Inclusion semantics match {@link toDeclaredExtensions}: a data
33
+ * property whose value is explicitly `undefined` is treated as "no
34
+ * contract-space declaration" and skipped, mirroring the
35
+ * `pack.contractSpace === undefined` check used on canonicalised
36
+ * inputs. Prototype-chain `contractSpace` properties (no own
37
+ * descriptor) are also skipped.
38
+ *
39
+ * This variant must be used by `buildContractSpaceAggregate` so that
40
+ * the aggregate path (including `db verify`) never reads
41
+ * `contractSpace.contractJson` from extension descriptors — the loader
42
+ * always reads the contract from on-disk artefacts instead.
43
+ */
44
+ function toDeclaredExtensionsFromRaw(extensionPacks) {
45
+ const entries = [];
46
+ for (const raw of extensionPacks) {
47
+ if (typeof raw !== "object" || raw === null) continue;
48
+ const descriptor = Object.getOwnPropertyDescriptor(raw, "contractSpace");
49
+ if (descriptor === void 0) continue;
50
+ if ("value" in descriptor && descriptor.value === void 0) continue;
51
+ const pack = raw;
52
+ entries.push({
53
+ id: pack.id,
54
+ targetId: pack.targetId
55
+ });
56
+ }
57
+ return entries;
58
+ }
59
+ //#endregion
60
+ export { toExtensionInputs as n, toDeclaredExtensionsFromRaw as t };
61
+
62
+ //# sourceMappingURL=extension-pack-inputs-BiY86HbQ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-pack-inputs-BiY86HbQ.mjs","names":[],"sources":["../src/utils/extension-pack-inputs.ts"],"sourcesContent":["/**\n * Single descriptor-import boundary for CLI consumers of `Config.extensionPacks`.\n *\n * Every CLI command / utility that reads an extension descriptor's\n * `contractSpace` projection (loader, migrate-pass, extension-migrations\n * pass, migration commands) goes through {@link toExtensionInputs}. The\n * structural cast `pack as { contractSpace?: ... }` lives **only** here —\n * downstream code consumes the canonical shape and maps it to its own\n * narrower shape via the per-consumer adapters below.\n *\n * The CLI receives extension descriptors typed against the SQL family\n * (or any other family in the future); this helper only depends on the\n * structural shape of `contractSpace`. SQL-family callers pass the same\n * `contractJson` / `headRef.hash` value through unchanged.\n */\nimport type { DeclaredExtensionEntry } from '@prisma-next/migration-tools/aggregate';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport type { MigrationOps } from '@prisma-next/migration-tools/package';\n\n/**\n * In-memory authored migration package shipped by an extension descriptor.\n * Mirrors the `MigrationPackage` shape from\n * `@prisma-next/framework-components/control` minus `dirPath`; redeclared\n * structurally here so the helper does not couple to the SQL family's\n * `ExtensionMigrationPackage` type.\n */\nexport interface DescriptorMigrationPackage {\n readonly dirName: string;\n readonly metadata: MigrationMetadata;\n readonly ops: MigrationOps;\n}\n\n/**\n * The most-general projection of a single declared extension pack\n * needed by the CLI's descriptor-import boundary.\n *\n * - `id` / `targetId` are always present.\n * - `contractSpace` is present only when the extension declares one.\n * When present, it carries the canonical inputs every downstream\n * consumer needs — `contractJson`, `headRef`, and the descriptor's\n * pre-built migration packages.\n */\nexport interface ExtensionPackInput {\n readonly id: string;\n readonly targetId: string;\n readonly contractSpace?: {\n readonly contractJson: unknown;\n readonly headRef: {\n readonly hash: string;\n readonly invariants: readonly string[];\n };\n readonly migrations: readonly DescriptorMigrationPackage[];\n };\n}\n\n/**\n * Structural shape we read off each `Config.extensionPacks` entry.\n *\n * The CLI is the descriptor-import boundary; `extensionPacks` is the only\n * surface where the SQL-family-typed `ControlExtensionDescriptor` flows\n * into framework-neutral helpers. The structural cast lives here, and\n * here alone — every other CLI consumer reads the canonical\n * {@link ExtensionPackInput} shape produced by {@link toExtensionInputs}.\n */\ntype ExtensionPackLike = {\n readonly id: string;\n readonly targetId: string;\n readonly contractSpace?: {\n readonly contractJson: unknown;\n readonly headRef: {\n readonly hash: string;\n readonly invariants: readonly string[];\n };\n readonly migrations?: readonly DescriptorMigrationPackage[];\n };\n};\n\n/**\n * Project the CLI's `Config.extensionPacks` array into the canonical\n * {@link ExtensionPackInput} shape. The single `as ExtensionPackLike`\n * structural cast in the CLI lives inside this function.\n */\nexport function toExtensionInputs(\n extensionPacks: ReadonlyArray<unknown>,\n): readonly ExtensionPackInput[] {\n return extensionPacks.map((raw) => {\n const pack = raw as ExtensionPackLike;\n if (pack.contractSpace === undefined) {\n return { id: pack.id, targetId: pack.targetId };\n }\n return {\n id: pack.id,\n targetId: pack.targetId,\n contractSpace: {\n contractJson: pack.contractSpace.contractJson,\n headRef: pack.contractSpace.headRef,\n migrations: pack.contractSpace.migrations ?? [],\n },\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Per-consumer adapters: take the canonical `ExtensionPackInput[]` and\n// project to whatever narrower shape the downstream primitive needs.\n// ---------------------------------------------------------------------------\n\n/**\n * Aggregate-loader projection. Surfaces `id` + `targetId` per\n * contract-space-bearing extension to\n * {@link import('./contract-space-aggregate-loader').buildContractSpaceAggregate}.\n *\n * Codec-only extensions (no `contractSpace` declaration) are filtered\n * out: they are not contract-space members, so the aggregate loader\n * has nothing to do with them. Filtering happens at this descriptor-\n * import boundary so the loader stays oblivious to that distinction —\n * every entry it sees expects an on-disk `migrations/<id>/` directory.\n */\nexport function toDeclaredExtensions(\n inputs: ReadonlyArray<ExtensionPackInput>,\n): readonly DeclaredExtensionEntry[] {\n const entries: DeclaredExtensionEntry[] = [];\n for (const pack of inputs) {\n if (pack.contractSpace === undefined) continue;\n entries.push({ id: pack.id, targetId: pack.targetId });\n }\n return entries;\n}\n\n/**\n * Minimal aggregate-loader projection that extracts `id` + `targetId`\n * from raw extension pack descriptors **without invoking any\n * `contractSpace` accessor**. Inspects the own-property descriptor so\n * that getter-backed `contractSpace` declarations are detected but\n * never called.\n *\n * Inclusion semantics match {@link toDeclaredExtensions}: a data\n * property whose value is explicitly `undefined` is treated as \"no\n * contract-space declaration\" and skipped, mirroring the\n * `pack.contractSpace === undefined` check used on canonicalised\n * inputs. Prototype-chain `contractSpace` properties (no own\n * descriptor) are also skipped.\n *\n * This variant must be used by `buildContractSpaceAggregate` so that\n * the aggregate path (including `db verify`) never reads\n * `contractSpace.contractJson` from extension descriptors — the loader\n * always reads the contract from on-disk artefacts instead.\n */\nexport function toDeclaredExtensionsFromRaw(\n extensionPacks: ReadonlyArray<unknown>,\n): readonly DeclaredExtensionEntry[] {\n const entries: DeclaredExtensionEntry[] = [];\n for (const raw of extensionPacks) {\n if (typeof raw !== 'object' || raw === null) continue;\n const descriptor = Object.getOwnPropertyDescriptor(raw, 'contractSpace');\n if (descriptor === undefined) continue;\n if ('value' in descriptor && descriptor.value === undefined) continue;\n const pack = raw as { readonly id: string; readonly targetId: string };\n entries.push({ id: pack.id, targetId: pack.targetId });\n }\n return entries;\n}\n"],"mappings":";;;;;;AAkFA,SAAgB,kBACd,gBAC+B;CAC/B,OAAO,eAAe,KAAK,QAAQ;EACjC,MAAM,OAAO;EACb,IAAI,KAAK,kBAAkB,KAAA,GACzB,OAAO;GAAE,IAAI,KAAK;GAAI,UAAU,KAAK;EAAS;EAEhD,OAAO;GACL,IAAI,KAAK;GACT,UAAU,KAAK;GACf,eAAe;IACb,cAAc,KAAK,cAAc;IACjC,SAAS,KAAK,cAAc;IAC5B,YAAY,KAAK,cAAc,cAAc,CAAC;GAChD;EACF;CACF,CAAC;AACH;;;;;;;;;;;;;;;;;;;;AAgDA,SAAgB,4BACd,gBACmC;CACnC,MAAM,UAAoC,CAAC;CAC3C,KAAK,MAAM,OAAO,gBAAgB;EAChC,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;EAC7C,MAAM,aAAa,OAAO,yBAAyB,KAAK,eAAe;EACvE,IAAI,eAAe,KAAA,GAAW;EAC9B,IAAI,WAAW,cAAc,WAAW,UAAU,KAAA,GAAW;EAC7D,MAAM,OAAO;EACb,QAAQ,KAAK;GAAE,IAAI,KAAK;GAAI,UAAU,KAAK;EAAS,CAAC;CACvD;CACA,OAAO;AACT"}
@@ -12,4 +12,4 @@ interface GlobalFlags {
12
12
  }
13
13
  //#endregion
14
14
  export { GlobalFlags as t };
15
- //# sourceMappingURL=global-flags-Dvibm2yu.d.mts.map
15
+ //# sourceMappingURL=global-flags-DWsQ6SSI.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"global-flags-Dvibm2yu.d.mts","names":[],"sources":["../src/utils/global-flags.ts"],"mappings":";KAMY,YAAA;AAAA,UAEK,WAAA;EAAA,SACN,MAAA,EAAQ,YAAY;EAAA,SACpB,cAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA;EAAA,SACA,WAAA;EAAA,SACA,GAAA;AAAA"}
1
+ {"version":3,"file":"global-flags-DWsQ6SSI.d.mts","names":[],"sources":["../src/utils/global-flags.ts"],"mappings":";KAMY,YAAA;AAAA,UAEK,WAAA;EAAA,SACN,MAAA,EAAQ,YAAY;EAAA,SACpB,cAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA;EAAA,SACA,WAAA;EAAA,SACA,GAAA;AAAA"}
@@ -1078,4 +1078,4 @@ function isLinearGraph(graph) {
1078
1078
  //#endregion
1079
1079
  export { migrationGraphToRenderInput as i, graphRenderer as n, isLinearGraph as r, extractRelevantSubgraph as t };
1080
1080
 
1081
- //# sourceMappingURL=graph-render-DJVv0_uf.mjs.map
1081
+ //# sourceMappingURL=graph-render-D2FnLpuK.mjs.map