@prisma/orm-toolchain 8.0.0-rc.1-dev.32 → 8.0.0-rc.1-dev.34
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/dist/bin__prisma-next.mjs +24 -24
- package/dist/bin__prisma-next.mjs.map +1 -1
- package/dist/{caught-errors-B_oGFiYw-BqX49eW0.mjs → caught-errors-BZ-9WASe-DH4DaDha.mjs} +3 -3
- package/dist/{caught-errors-B_oGFiYw-BqX49eW0.mjs.map → caught-errors-BZ-9WASe-DH4DaDha.mjs.map} +1 -1
- package/dist/{cli-errors-CihMAEVj-C1uUYBop.mjs → cli-errors-C6_pH59O-CzD4SYcJ.mjs} +4 -3
- package/dist/{cli-errors-CihMAEVj-C1uUYBop.mjs.map → cli-errors-C6_pH59O-CzD4SYcJ.mjs.map} +1 -1
- package/dist/{cli-errors-C8DGzS94-CPP3UmRT.d.mts → cli-errors-f5PRtVdm-C6xVKeQn.d.mts} +8 -3
- package/dist/cli-errors-f5PRtVdm-C6xVKeQn.d.mts.map +1 -0
- package/dist/cli.mjs +961 -27
- package/dist/cli.mjs.map +1 -1
- package/dist/cli__commands__contract-emit.mjs +1 -1
- package/dist/cli__commands__contract-infer.mjs +1 -1
- package/dist/cli__commands__db-init.mjs +1 -1
- package/dist/cli__commands__db-schema.mjs +1 -1
- package/dist/cli__commands__db-sign.mjs +1 -1
- package/dist/cli__commands__db-update.mjs +1 -1
- package/dist/cli__commands__db-verify.mjs +1 -1
- package/dist/cli__commands__migrate.d.mts +2 -2
- package/dist/cli__commands__migrate.mjs +1 -1
- package/dist/cli__commands__migration-check.mjs +1 -1
- package/dist/cli__commands__migration-graph.d.mts +1 -1
- package/dist/cli__commands__migration-graph.mjs +1 -1
- package/dist/cli__commands__migration-list.d.mts +1 -1
- package/dist/cli__commands__migration-list.mjs +1 -1
- package/dist/cli__commands__migration-log.d.mts +1 -1
- package/dist/cli__commands__migration-log.mjs +1 -1
- package/dist/cli__commands__migration-new.mjs +1 -1
- package/dist/cli__commands__migration-plan.d.mts +1 -1
- package/dist/cli__commands__migration-plan.mjs +1 -1
- package/dist/cli__commands__migration-show.mjs +1 -1
- package/dist/cli__commands__migration-status.d.mts +1 -1
- package/dist/cli__commands__migration-status.mjs +1 -1
- package/dist/cli__commands__ref.mjs +1 -1
- package/dist/cli__commands__telemetry.mjs +1 -1
- package/dist/cli__control-api.d.mts +3 -3
- package/dist/cli__control-api.mjs +15 -15
- package/dist/cli__control-api__testing.d.mts +1 -1
- package/dist/{client-C4Gh4PBz-BMUlBcuE.mjs → client-BqhVohc5-DFRVWFps.mjs} +5 -5
- package/dist/{client-C4Gh4PBz-BMUlBcuE.mjs.map → client-BqhVohc5-DFRVWFps.mjs.map} +1 -1
- package/dist/{command-helpers-Dw3LDEu_-B4AETH4D.mjs → command-helpers-kD9CO1hd-BPhnkBin.mjs} +4 -4
- package/dist/{command-helpers-Dw3LDEu_-B4AETH4D.mjs.map → command-helpers-kD9CO1hd-BPhnkBin.mjs.map} +1 -1
- package/dist/{contract-at-errors-BsQiGdZC-D8l9-WWt.mjs → contract-at-errors-CLFX1-Gc-MNPXDx1t.mjs} +3 -3
- package/dist/{contract-at-errors-BsQiGdZC-D8l9-WWt.mjs.map → contract-at-errors-CLFX1-Gc-MNPXDx1t.mjs.map} +1 -1
- package/dist/{contract-emit-CIdgw3Kq-BcfYaUfn.mjs → contract-emit-BlvUNMHM-BEioUVR5.mjs} +6 -6
- package/dist/{contract-emit-CIdgw3Kq-BcfYaUfn.mjs.map → contract-emit-BlvUNMHM-BEioUVR5.mjs.map} +1 -1
- package/dist/{contract-emit-WIAaN0lC-DKOdtrUQ.mjs → contract-emit-CrYO0A8x-60BOqXFr.mjs} +5 -5
- package/dist/{contract-emit-WIAaN0lC-DKOdtrUQ.mjs.map → contract-emit-CrYO0A8x-60BOqXFr.mjs.map} +1 -1
- package/dist/contract-emit-Csa6R0gt-DvxFlS0O.mjs +2 -0
- package/dist/{contract-infer-xOEwVWds-CE5gw1PF.mjs → contract-infer-C8kLphsm-C7-AIYMc.mjs} +5 -5
- package/dist/{contract-infer-xOEwVWds-CE5gw1PF.mjs.map → contract-infer-C8kLphsm-C7-AIYMc.mjs.map} +1 -1
- package/dist/{contract-snapshot-resolution-BnH6_mw7-BrzAsS93.mjs → contract-snapshot-resolution-BUUdIcgG-8mbs6-OD.mjs} +4 -4
- package/dist/{contract-snapshot-resolution-BnH6_mw7-BrzAsS93.mjs.map → contract-snapshot-resolution-BUUdIcgG-8mbs6-OD.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-1wG1OiDk-D75luh5-.mjs → contract-space-aggregate-loader-BpdB-mHG-BiU0IUeb.mjs} +4 -4
- package/dist/{contract-space-aggregate-loader-1wG1OiDk-D75luh5-.mjs.map → contract-space-aggregate-loader-BpdB-mHG-BiU0IUeb.mjs.map} +1 -1
- package/dist/{db-init-CEk9Utl4-vGmJajwZ.mjs → db-init-CyNsXRAB-D3xWQ-vy.mjs} +7 -39
- package/dist/db-init-CyNsXRAB-D3xWQ-vy.mjs.map +1 -0
- package/dist/db-init-failure-XYOVL4o7-BitY_JYn.mjs +44 -0
- package/dist/db-init-failure-XYOVL4o7-BitY_JYn.mjs.map +1 -0
- package/dist/{db-schema-D_PJvBI3-BTnfCqbX.mjs → db-schema-7zNGHgYN-BVaRHPxg.mjs} +6 -6
- package/dist/{db-schema-D_PJvBI3-BTnfCqbX.mjs.map → db-schema-7zNGHgYN-BVaRHPxg.mjs.map} +1 -1
- package/dist/{db-sign-Bparnnii-Yd5pb4VF.mjs → db-sign-DAs6J3XG-xxP2CCnO.mjs} +8 -8
- package/dist/{db-sign-Bparnnii-Yd5pb4VF.mjs.map → db-sign-DAs6J3XG-xxP2CCnO.mjs.map} +1 -1
- package/dist/{db-update-CsKZyDYp-B8Zl7W4k.mjs → db-update-BX1sOuQk-CpeLgPeN.mjs} +7 -7
- package/dist/{db-update-CsKZyDYp-B8Zl7W4k.mjs.map → db-update-BX1sOuQk-CpeLgPeN.mjs.map} +1 -1
- package/dist/{db-verify-B33E7HXH-D87fiNt3.mjs → db-verify-CN4nmxxF-DSRWae0u.mjs} +7 -7
- package/dist/{db-verify-B33E7HXH-D87fiNt3.mjs.map → db-verify-CN4nmxxF-DSRWae0u.mjs.map} +1 -1
- package/dist/{format-CYdgHub4-Cs6VcFje.mjs → format-D5x0jz7q-xalz6Fkn.mjs} +5 -5
- package/dist/{format-CYdgHub4-Cs6VcFje.mjs.map → format-D5x0jz7q-xalz6Fkn.mjs.map} +1 -1
- package/dist/{framework-components-CXxMNF8E-C-g2cchI.mjs → framework-components-CPFWl2Ix-CrIZL3jG.mjs} +3 -3
- package/dist/{framework-components-CXxMNF8E-C-g2cchI.mjs.map → framework-components-CPFWl2Ix-CrIZL3jG.mjs.map} +1 -1
- package/dist/{init-B8U_9kn7-CdhTYHfO.mjs → init-BvLCfVjC-DOPO-TLF.mjs} +5 -5
- package/dist/{init-B8U_9kn7-CdhTYHfO.mjs.map → init-BvLCfVjC-DOPO-TLF.mjs.map} +1 -1
- package/dist/{inspect-live-schema-BAiaX0n9-DBQFEsMC.mjs → inspect-live-schema-BaLAtOgO-Bs0gs_yP.mjs} +5 -5
- package/dist/{inspect-live-schema-BAiaX0n9-DBQFEsMC.mjs.map → inspect-live-schema-BaLAtOgO-Bs0gs_yP.mjs.map} +1 -1
- package/dist/{invariants-CsxL0lbZ-B9Hfpj2R.mjs → invariants-1L2zfc6--BpedlAbF.mjs} +4 -4
- package/dist/{invariants-CsxL0lbZ-B9Hfpj2R.mjs.map → invariants-1L2zfc6--BpedlAbF.mjs.map} +1 -1
- package/dist/{legend-QYDKKevn-DCIlAPn4.mjs → legend-aXC5H1jH-Dg1yWonK.mjs} +3 -3
- package/dist/{legend-QYDKKevn-DCIlAPn4.mjs.map → legend-aXC5H1jH-Dg1yWonK.mjs.map} +1 -1
- package/dist/{migrate-DYx_CSbN-BuQ0lk-0.mjs → migrate-DRiUHRCS-Cci6EEZv.mjs} +32 -79
- package/dist/migrate-DRiUHRCS-Cci6EEZv.mjs.map +1 -0
- package/dist/migrate-failure-Bdr3AJee-C9yNeQXy.mjs +96 -0
- package/dist/migrate-failure-Bdr3AJee-C9yNeQXy.mjs.map +1 -0
- package/dist/{migrate-show-DWIvU6Y_-BQyWhZD1.d.mts → migrate-show-DutwCc2F-BhGfH7D-.d.mts} +5 -3
- package/dist/migrate-show-DutwCc2F-BhGfH7D-.d.mts.map +1 -0
- package/dist/{migrate-show-CPZEq35I-DeL3WVjs.mjs → migrate-show-bdXjSFgh-CQxl5yNp.mjs} +7 -7
- package/dist/migrate-show-bdXjSFgh-CQxl5yNp.mjs.map +1 -0
- package/dist/{migration-check-COMRj5eu-DbJgriA8.mjs → migration-check-aoZ8kXNA-DX2J84Cv.mjs} +7 -7
- package/dist/{migration-check-COMRj5eu-DbJgriA8.mjs.map → migration-check-aoZ8kXNA-DX2J84Cv.mjs.map} +1 -1
- package/dist/{migration-check-BUAcSrvA-DSS5Yvco.mjs → migration-check-of-RPYRk-HuXtDO8i.mjs} +6 -6
- package/dist/{migration-check-BUAcSrvA-DSS5Yvco.mjs.map → migration-check-of-RPYRk-HuXtDO8i.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-CIMPoR6f-Ba-S9gXa.mjs → migration-command-scaffold-zJFTGn5k-5AGczeSx.mjs} +5 -5
- package/dist/{migration-command-scaffold-CIMPoR6f-Ba-S9gXa.mjs.map → migration-command-scaffold-zJFTGn5k-5AGczeSx.mjs.map} +1 -1
- package/dist/{migration-graph-BsGstA5L-BQiNbrkP.mjs → migration-graph-D0KHjNJ--CWzX9Zzc.mjs} +10 -10
- package/dist/{migration-graph-BsGstA5L-BQiNbrkP.mjs.map → migration-graph-D0KHjNJ--CWzX9Zzc.mjs.map} +1 -1
- package/dist/{migration-graph-BtP1Va3T-C8PpuaYw.mjs → migration-graph-DmdVVJoZ-DDBKjUMz.mjs} +3 -3
- package/dist/{migration-graph-BtP1Va3T-C8PpuaYw.mjs.map → migration-graph-DmdVVJoZ-DDBKjUMz.mjs.map} +1 -1
- package/dist/{migration-graph-command-render-CgdHruiZ-B6V4gmUe.mjs → migration-graph-command-render-BeuEyf2B-BNH9oUB_.mjs} +5 -5
- package/dist/{migration-graph-command-render-CgdHruiZ-B6V4gmUe.mjs.map → migration-graph-command-render-BeuEyf2B-BNH9oUB_.mjs.map} +1 -1
- package/dist/{migration-graph-sections-CceYWPCP-LqImOaK1.mjs → migration-graph-sections-BWcFCOL6-_G0Wb4QR.mjs} +4 -4
- package/dist/{migration-graph-sections-CceYWPCP-LqImOaK1.mjs.map → migration-graph-sections-BWcFCOL6-_G0Wb4QR.mjs.map} +1 -1
- package/dist/{migration-list-BiVyonwG-CdMbBV5Z.mjs → migration-list-B0SANIeM-DiXQ9LyS.mjs} +8 -8
- package/dist/{migration-list-BiVyonwG-CdMbBV5Z.mjs.map → migration-list-B0SANIeM-DiXQ9LyS.mjs.map} +1 -1
- package/dist/{migration-list-AKRIIovW-BN-Zrwk0.mjs → migration-list-W0dqabIj-Dc2NH_LY.mjs} +3 -3
- package/dist/{migration-list-AKRIIovW-BN-Zrwk0.mjs.map → migration-list-W0dqabIj-Dc2NH_LY.mjs.map} +1 -1
- package/dist/{migration-log-Z3-L172x-CvQTNJvI.mjs → migration-log-B3iiP8ns-B4tdLSye.mjs} +9 -9
- package/dist/{migration-log-Z3-L172x-CvQTNJvI.mjs.map → migration-log-B3iiP8ns-B4tdLSye.mjs.map} +1 -1
- package/dist/{migration-log-table-JR7fFVbE-DR2mom6h.mjs → migration-log-table-DRiOnvzf-zTQBThqe.mjs} +3 -3
- package/dist/{migration-log-table-JR7fFVbE-DR2mom6h.mjs.map → migration-log-table-DRiOnvzf-zTQBThqe.mjs.map} +1 -1
- package/dist/{migration-new-DDnQd7Ql-1WT_J_zf.mjs → migration-new-Bf5K9fNK-Cd90rYmm.mjs} +5 -5
- package/dist/{migration-new-DDnQd7Ql-1WT_J_zf.mjs.map → migration-new-Bf5K9fNK-Cd90rYmm.mjs.map} +1 -1
- package/dist/{migration-new-ZlgxFcbH-CxlZs2hr.mjs → migration-new-YSdtJTRp-Dc06LNJe.mjs} +7 -7
- package/dist/{migration-new-ZlgxFcbH-CxlZs2hr.mjs.map → migration-new-YSdtJTRp-Dc06LNJe.mjs.map} +1 -1
- package/dist/{migration-path-target-yA4h5Zc6-DlzBblBG.mjs → migration-path-target-5r1leSW5-B0EMgvEv.mjs} +3 -3
- package/dist/{migration-path-target-yA4h5Zc6-DlzBblBG.mjs.map → migration-path-target-5r1leSW5-B0EMgvEv.mjs.map} +1 -1
- package/dist/{migration-plan-s94qwFHi-86F_Aklp.d.mts → migration-plan-4cnnP6yM-DXzRfi_A.d.mts} +3 -3
- package/dist/{migration-plan-s94qwFHi-86F_Aklp.d.mts.map → migration-plan-4cnnP6yM-DXzRfi_A.d.mts.map} +1 -1
- package/dist/{migration-plan-DiLJTAep-2B463CwW.mjs → migration-plan-CZY8HVCh-BbfQvxnb.mjs} +8 -8
- package/dist/{migration-plan-DiLJTAep-2B463CwW.mjs.map → migration-plan-CZY8HVCh-BbfQvxnb.mjs.map} +1 -1
- package/dist/{migration-plan-CROSunPS-B66Rh_6T.mjs → migration-plan-oterbw8h-_GrKbsRb.mjs} +5 -5
- package/dist/{migration-plan-CROSunPS-B66Rh_6T.mjs.map → migration-plan-oterbw8h-_GrKbsRb.mjs.map} +1 -1
- package/dist/{migration-show-mJD52S2d-DiD-rCBB.mjs → migration-show-iX2cduR4-C3-FENR4.mjs} +9 -9
- package/dist/{migration-show-mJD52S2d-DiD-rCBB.mjs.map → migration-show-iX2cduR4-C3-FENR4.mjs.map} +1 -1
- package/dist/{migration-status-7Zawokrj-BwTcRAjf.mjs → migration-status-DCAQ3_C1-ofDvCvUk.mjs} +12 -12
- package/dist/{migration-status-7Zawokrj-BwTcRAjf.mjs.map → migration-status-DCAQ3_C1-ofDvCvUk.mjs.map} +1 -1
- package/dist/{project-import-root-Bkz1gPB2-jhrMFebo.mjs → project-import-root-BPuwl2j1-DTX9G73z.mjs} +3 -3
- package/dist/{project-import-root-Bkz1gPB2-jhrMFebo.mjs.map → project-import-root-BPuwl2j1-DTX9G73z.mjs.map} +1 -1
- package/dist/{ref-DftuSibc-CasZ6LgA.mjs → ref-CVD6j3jA-BAgpZLNM.mjs} +5 -5
- package/dist/{ref-DftuSibc-CasZ6LgA.mjs.map → ref-CVD6j3jA-BAgpZLNM.mjs.map} +1 -1
- package/dist/{ref-Cycefq_T-DQE5AM66.mjs → ref-CaqNqeRF-cjWFAueu.mjs} +5 -5
- package/dist/{ref-Cycefq_T-DQE5AM66.mjs.map → ref-CaqNqeRF-cjWFAueu.mjs.map} +1 -1
- package/dist/{ref-resolution-Bi4lpxM8-BbfL_yv8.mjs → ref-resolution-D4fAdXo8-Dfaky0yw.mjs} +3 -3
- package/dist/{ref-resolution-Bi4lpxM8-BbfL_yv8.mjs.map → ref-resolution-D4fAdXo8-Dfaky0yw.mjs.map} +1 -1
- package/dist/{telemetry-LP1Suxsf-CY1l7lD0.mjs → telemetry-fKuZOFpu-DNUWfIHo.mjs} +4 -4
- package/dist/{telemetry-LP1Suxsf-CY1l7lD0.mjs.map → telemetry-fKuZOFpu-DNUWfIHo.mjs.map} +1 -1
- package/dist/{terminal-ui-JJKxvT0q-CPDEJqqU.mjs → terminal-ui-Cqz4LVL7-B0mcVdLy.mjs} +3 -3
- package/dist/{terminal-ui-JJKxvT0q-CPDEJqqU.mjs.map → terminal-ui-Cqz4LVL7-B0mcVdLy.mjs.map} +1 -1
- package/dist/{verify-wUSBDQwh-Bv3NV9WG.mjs → verify-Cogr_Fj9-D3lCWA6t.mjs} +3 -3
- package/dist/{verify-wUSBDQwh-Bv3NV9WG.mjs.map → verify-Cogr_Fj9-D3lCWA6t.mjs.map} +1 -1
- package/dist/vite-plugin-contract-emit.mjs +1 -1
- package/package.json +12 -12
- package/dist/cli-errors-C8DGzS94-CPP3UmRT.d.mts.map +0 -1
- package/dist/contract-emit-BAfPwP3y-DfV1Stry.mjs +0 -2
- package/dist/db-init-CEk9Utl4-vGmJajwZ.mjs.map +0 -1
- package/dist/migrate-DYx_CSbN-BuQ0lk-0.mjs.map +0 -1
- package/dist/migrate-show-CPZEq35I-DeL3WVjs.mjs.map +0 -1
- package/dist/migrate-show-DWIvU6Y_-BQyWhZD1.d.mts.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import { i as loadConfig } from "./exports-BZLNbtkY.mjs";
|
|
2
|
-
import { F as requireLiveDatabase, N as errorUnexpected, a as errorConfigValidation$1, b as errorNoMigrations, d as errorFileNotFound, h as errorLegendHumanOnly, j as errorTargetMigrationNotSupported, s as errorContractValidationFailed, v as errorMigrationPackageNotFound } from "./cli-errors-
|
|
2
|
+
import { F as requireLiveDatabase, I as runCommandAction, N as errorUnexpected, a as errorConfigValidation$1, b as errorNoMigrations, c as errorDatabaseConnectionRequired, d as errorFileNotFound, h as errorLegendHumanOnly, j as errorTargetMigrationNotSupported, s as errorContractValidationFailed, t as CliStructuredError$1$1, u as errorDriverRequired, v as errorMigrationPackageNotFound } from "./cli-errors-C6_pH59O-CzD4SYcJ.mjs";
|
|
3
3
|
import { r as getEmittedArtifactPaths } from "./exports-BCLg4CiV-05kuwcb0.mjs";
|
|
4
|
-
import { m as previewBlockHeader } from "./terminal-ui-
|
|
4
|
+
import { h as renderPreviewStatement, m as previewBlockHeader } from "./terminal-ui-Cqz4LVL7-B0mcVdLy.mjs";
|
|
5
5
|
import { c as spaceMigrationDirectory } from "./verify-contract-spaces-DhJTb0zM-_oh6W6lp.mjs";
|
|
6
|
-
import { S as targetSupportsMigrations, f as maskConnectionUrl, n as closeQuietly } from "./command-helpers-
|
|
7
|
-
import { t as createContractEmitCommand } from "./contract-emit-
|
|
8
|
-
import { t as createFormatCommand } from "./format-
|
|
9
|
-
import { a as loadContractSpaceAggregateForCli, r as buildReadAggregate } from "./contract-space-aggregate-loader-
|
|
10
|
-
import { t as createControlClient } from "./client-
|
|
11
|
-
import { t as
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { t as
|
|
17
|
-
import { n as
|
|
18
|
-
import {
|
|
6
|
+
import { S as targetSupportsMigrations, f as maskConnectionUrl, n as closeQuietly, v as sanitizeErrorMessage } from "./command-helpers-kD9CO1hd-BPhnkBin.mjs";
|
|
7
|
+
import { t as createContractEmitCommand } from "./contract-emit-BlvUNMHM-BEioUVR5.mjs";
|
|
8
|
+
import { t as createFormatCommand } from "./format-D5x0jz7q-xalz6Fkn.mjs";
|
|
9
|
+
import { a as loadContractSpaceAggregateForCli, r as buildReadAggregate, s as refuseContractSpaceIntegrity, u as toDeclaredExtensionsFromRaw } from "./contract-space-aggregate-loader-BpdB-mHG-BiU0IUeb.mjs";
|
|
10
|
+
import { t as createControlClient } from "./client-BqhVohc5-DFRVWFps.mjs";
|
|
11
|
+
import { a as readContractIR, o as resolveRefAdvancementFields, t as advanceRefSafely } from "./ref-advancement-DaZBzm7m-WoqnFAyr.mjs";
|
|
12
|
+
import { t as mapDbInitFailure } from "./db-init-failure-XYOVL4o7-BitY_JYn.mjs";
|
|
13
|
+
import { t as mapCaughtMigrationError } from "./caught-errors-BZ-9WASe-DH4DaDha.mjs";
|
|
14
|
+
import { t as mapContractAtError } from "./contract-at-errors-CLFX1-Gc-MNPXDx1t.mjs";
|
|
15
|
+
import { i as refuseUnknownInvariants, n as refuseMarkerOutsideGraph } from "./invariants-1L2zfc6--BpedlAbF.mjs";
|
|
16
|
+
import { t as executeMigrateShowPlan } from "./migrate-show-bdXjSFgh-CQxl5yNp.mjs";
|
|
17
|
+
import { n as resolveMigrationRef, t as resolveContractRef } from "./ref-resolution-D4fAdXo8-Dfaky0yw.mjs";
|
|
18
|
+
import { n as migrationSpaceListEntriesFromAggregate, r as runMigrationList } from "./migration-list-W0dqabIj-Dc2NH_LY.mjs";
|
|
19
|
+
import { S as toneSpans, b as renderMigrationListWithStyle, d as createToneMigrationListStyler, n as TONE_MIGRATION_GRAPH_PALETTE, v as renderMigrationGraphLegend, x as toneDrawing } from "./migration-graph-command-render-BeuEyf2B-BNH9oUB_.mjs";
|
|
20
|
+
import { n as migrateShowRunListRows, r as renderMigrateShowGraph, t as mapMigrateFailure } from "./migrate-failure-Bdr3AJee-C9yNeQXy.mjs";
|
|
21
|
+
import { n as looksLikePath, r as resolveAppTargetPath, t as findPackageByDirPath } from "./migration-path-target-5r1leSW5-B0EMgvEv.mjs";
|
|
22
|
+
import { t as buildMigrationSpaceGraphEntries } from "./migration-graph-DmdVVJoZ-DDBKjUMz.mjs";
|
|
23
|
+
import { n as renderMigrationGraphDot, r as renderMigrationGraphSections, t as buildMigrationGraphTreeSections } from "./migration-graph-sections-BWcFCOL6-_G0Wb4QR.mjs";
|
|
24
|
+
import { a as sortLedgerEntries, i as serializeLedgerEntriesForJson, n as formatLedgerAppliedAt, o as styleHashTransition, t as MIGRATION_LOG_EMPTY_MESSAGE } from "./migration-log-table-DRiOnvzf-zTQBThqe.mjs";
|
|
19
25
|
import { CliStructuredError } from "@prisma/orm-framework/errors/control";
|
|
20
26
|
import { ifDefined } from "@prisma/orm-framework/utils/defined";
|
|
21
27
|
import { join, normalize, relative, resolve } from "pathe";
|
|
@@ -31,7 +37,7 @@ import { defineCommand, defineCommandFamily, defineConfigSection, flag, position
|
|
|
31
37
|
import { CliStructuredError as CliStructuredError$1, notOk, ok } from "@prisma/cli-engine/protocol";
|
|
32
38
|
import { pathToFileURL } from "node:url";
|
|
33
39
|
import { build } from "esbuild";
|
|
34
|
-
//#region ../../../1-framework/3-tooling/cli/dist/load-config-
|
|
40
|
+
//#region ../../../1-framework/3-tooling/cli/dist/load-config-BQgwPvgu.mjs
|
|
35
41
|
const MISSING_CONFIG_ACTION = {
|
|
36
42
|
kind: "run-command",
|
|
37
43
|
label: "Create a configuration file",
|
|
@@ -255,6 +261,229 @@ function defineOrmCommand(def) {
|
|
|
255
261
|
});
|
|
256
262
|
}
|
|
257
263
|
/**
|
|
264
|
+
* The database connection override, declared from here by every command that
|
|
265
|
+
* accepts one so its brief and placeholder cannot drift apart. Resolution
|
|
266
|
+
* order is the flag, then `config.db.connection`, then
|
|
267
|
+
* `CONFIG.DB_CONNECTION_REQUIRED`.
|
|
268
|
+
*/
|
|
269
|
+
const dbFlag = flag.string({
|
|
270
|
+
brief: "Database connection string",
|
|
271
|
+
placeholder: "url"
|
|
272
|
+
});
|
|
273
|
+
const OUTCOMES = {
|
|
274
|
+
ok: "ok",
|
|
275
|
+
skipped: "skipped",
|
|
276
|
+
error: "failed"
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* The control API's spans as engine events. A span's label is remembered when
|
|
280
|
+
* it starts so the finishing event names the step with the same words.
|
|
281
|
+
*/
|
|
282
|
+
function controlProgressReporter(report) {
|
|
283
|
+
const labels = /* @__PURE__ */ new Map();
|
|
284
|
+
return (event) => {
|
|
285
|
+
if (event.kind === "spanStart") {
|
|
286
|
+
labels.set(event.spanId, event.label);
|
|
287
|
+
report({
|
|
288
|
+
kind: "step-started",
|
|
289
|
+
step: event.label,
|
|
290
|
+
id: event.spanId,
|
|
291
|
+
...ifDefined("parentId", event.parentSpanId)
|
|
292
|
+
});
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const step = labels.get(event.spanId) ?? event.spanId;
|
|
296
|
+
labels.delete(event.spanId);
|
|
297
|
+
report({
|
|
298
|
+
kind: "step-finished",
|
|
299
|
+
step,
|
|
300
|
+
id: event.spanId,
|
|
301
|
+
outcome: OUTCOMES[event.outcome]
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function operationNode(operation) {
|
|
306
|
+
return operation.operationClass === "destructive" ? {
|
|
307
|
+
label: operation.label,
|
|
308
|
+
status: "warn"
|
|
309
|
+
} : { label: operation.label };
|
|
310
|
+
}
|
|
311
|
+
function spaceLabel(space) {
|
|
312
|
+
return space.kind === "app" ? "App space" : `Extension space: ${space.spaceId}`;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* One root per contract space, in the schedule order the runner used. A
|
|
316
|
+
* space's post-apply marker is the last child of its own space, so the engine
|
|
317
|
+
* draws it under the operations it signs.
|
|
318
|
+
*/
|
|
319
|
+
function spaceNodes(perSpace, mode) {
|
|
320
|
+
return perSpace.map((space) => ({
|
|
321
|
+
label: [{
|
|
322
|
+
text: spaceLabel(space),
|
|
323
|
+
tone: "identifier"
|
|
324
|
+
}],
|
|
325
|
+
children: [...space.operations.length === 0 ? [{ label: [{
|
|
326
|
+
text: "(no operations)",
|
|
327
|
+
tone: "muted"
|
|
328
|
+
}] }] : space.operations.map(operationNode), ...mode === "apply" && space.marker !== void 0 ? [{ label: [{
|
|
329
|
+
text: "marker ",
|
|
330
|
+
tone: "muted"
|
|
331
|
+
}, {
|
|
332
|
+
text: space.marker.storageHash,
|
|
333
|
+
tone: "identifier"
|
|
334
|
+
}] }] : []]
|
|
335
|
+
}));
|
|
336
|
+
}
|
|
337
|
+
function destructiveWarningBlocks(hasDestructive) {
|
|
338
|
+
return hasDestructive ? [{
|
|
339
|
+
kind: "summary",
|
|
340
|
+
status: "warn",
|
|
341
|
+
text: "This migration contains destructive operations that may cause data loss."
|
|
342
|
+
}] : [];
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* The planned or executed operations. The per-space breakdown is the shape the
|
|
346
|
+
* aggregate flow produces; the flat tree is the fallback for a result that
|
|
347
|
+
* carries no breakdown.
|
|
348
|
+
*/
|
|
349
|
+
function perSpaceBlocks(perSpace, mode) {
|
|
350
|
+
const hasDestructive = perSpace.some((space) => space.operations.some((operation) => operation.operationClass === "destructive"));
|
|
351
|
+
return [{
|
|
352
|
+
kind: "tree",
|
|
353
|
+
roots: spaceNodes(perSpace, mode)
|
|
354
|
+
}, ...destructiveWarningBlocks(hasDestructive)];
|
|
355
|
+
}
|
|
356
|
+
function operationBlocks$1(result) {
|
|
357
|
+
const perSpace = result.perSpace;
|
|
358
|
+
if (perSpace !== void 0 && perSpace.length > 0) return perSpaceBlocks(perSpace, result.mode);
|
|
359
|
+
if (result.plan.operations.length === 0) return [];
|
|
360
|
+
const hasDestructive = result.plan.operations.some((operation) => operation.operationClass === "destructive");
|
|
361
|
+
return [{
|
|
362
|
+
kind: "tree",
|
|
363
|
+
roots: result.plan.operations.map(operationNode)
|
|
364
|
+
}, ...destructiveWarningBlocks(hasDestructive)];
|
|
365
|
+
}
|
|
366
|
+
/** The statements a database would run, printed verbatim rather than laid out. */
|
|
367
|
+
function previewBlocks$1(preview) {
|
|
368
|
+
if (preview === void 0) return [];
|
|
369
|
+
const header = {
|
|
370
|
+
kind: "summary",
|
|
371
|
+
status: "info",
|
|
372
|
+
tone: "muted",
|
|
373
|
+
text: previewBlockHeader(preview)
|
|
374
|
+
};
|
|
375
|
+
const statements = preview.statements.map((statement) => renderPreviewStatement(statement.text, statement.language)).filter((text) => text !== void 0);
|
|
376
|
+
return statements.length === 0 ? [header, {
|
|
377
|
+
kind: "summary",
|
|
378
|
+
status: "info",
|
|
379
|
+
tone: "muted",
|
|
380
|
+
text: "No operations."
|
|
381
|
+
}] : [header, {
|
|
382
|
+
kind: "drawing",
|
|
383
|
+
lines: statements
|
|
384
|
+
}];
|
|
385
|
+
}
|
|
386
|
+
function planSummaryText(result) {
|
|
387
|
+
const operations = result.plan.operations.length;
|
|
388
|
+
const spaces = result.perSpace?.length ?? 0;
|
|
389
|
+
return spaces > 0 ? `Planned ${operations} operation(s) across ${spaces} contract space${spaces === 1 ? "" : "s"}` : `Planned ${operations} operation(s)`;
|
|
390
|
+
}
|
|
391
|
+
function applySummaryText(result) {
|
|
392
|
+
const executed = result.execution?.operationsExecuted ?? 0;
|
|
393
|
+
const spaces = result.perSpace?.length ?? 0;
|
|
394
|
+
const across = spaces > 0 ? ` across ${spaces} contract space${spaces === 1 ? "" : "s"}` : "";
|
|
395
|
+
if (executed === 0) return `Database already matches contract${across}`;
|
|
396
|
+
return `Applied ${executed} operation(s)${across}`;
|
|
397
|
+
}
|
|
398
|
+
function planBlocks(result) {
|
|
399
|
+
const planned = result.plannedAdvanceRef;
|
|
400
|
+
return [
|
|
401
|
+
{
|
|
402
|
+
kind: "summary",
|
|
403
|
+
status: "ok",
|
|
404
|
+
text: planSummaryText(result)
|
|
405
|
+
},
|
|
406
|
+
...operationBlocks$1(result),
|
|
407
|
+
{
|
|
408
|
+
kind: "fields",
|
|
409
|
+
rows: [{
|
|
410
|
+
label: "destination",
|
|
411
|
+
value: [{
|
|
412
|
+
text: result.plan.destination.storageHash,
|
|
413
|
+
tone: "identifier"
|
|
414
|
+
}]
|
|
415
|
+
}]
|
|
416
|
+
},
|
|
417
|
+
...planned === null || planned === void 0 ? [] : [{
|
|
418
|
+
kind: "summary",
|
|
419
|
+
status: "info",
|
|
420
|
+
text: [{ text: `Would advance ref "${planned.name}" → ` }, {
|
|
421
|
+
text: planned.hash,
|
|
422
|
+
tone: "identifier"
|
|
423
|
+
}]
|
|
424
|
+
}],
|
|
425
|
+
...previewBlocks$1(result.plan.preview),
|
|
426
|
+
{
|
|
427
|
+
kind: "summary",
|
|
428
|
+
status: "info",
|
|
429
|
+
tone: "muted",
|
|
430
|
+
text: "This is a dry run. No changes were applied."
|
|
431
|
+
}
|
|
432
|
+
];
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* The app-space marker, for a result that carried no per-space breakdown. The
|
|
436
|
+
* label names what the marker covers rather than calling it "the" signature.
|
|
437
|
+
*/
|
|
438
|
+
function fallbackMarkerBlocks(result) {
|
|
439
|
+
const marker = result.marker;
|
|
440
|
+
if (marker === void 0 || result.perSpace !== void 0 && result.perSpace.length > 0) return [];
|
|
441
|
+
return [{
|
|
442
|
+
kind: "fields",
|
|
443
|
+
rows: [{
|
|
444
|
+
label: "App-space marker",
|
|
445
|
+
value: [{
|
|
446
|
+
text: marker.storageHash,
|
|
447
|
+
tone: "identifier"
|
|
448
|
+
}]
|
|
449
|
+
}, ...marker.profileHash === void 0 ? [] : [{
|
|
450
|
+
label: "Profile hash",
|
|
451
|
+
value: [{
|
|
452
|
+
text: marker.profileHash,
|
|
453
|
+
tone: "identifier"
|
|
454
|
+
}]
|
|
455
|
+
}]]
|
|
456
|
+
}];
|
|
457
|
+
}
|
|
458
|
+
function applyBlocks(result) {
|
|
459
|
+
const advanced = result.advancedRef;
|
|
460
|
+
return [
|
|
461
|
+
{
|
|
462
|
+
kind: "summary",
|
|
463
|
+
status: "ok",
|
|
464
|
+
text: applySummaryText(result)
|
|
465
|
+
},
|
|
466
|
+
...operationBlocks$1(result),
|
|
467
|
+
...fallbackMarkerBlocks(result),
|
|
468
|
+
...advanced === null || advanced === void 0 ? [] : [{
|
|
469
|
+
kind: "summary",
|
|
470
|
+
status: "ok",
|
|
471
|
+
text: [{ text: `Advanced ref "${advanced.name}" → ` }, {
|
|
472
|
+
text: advanced.hash,
|
|
473
|
+
tone: "identifier"
|
|
474
|
+
}]
|
|
475
|
+
}]
|
|
476
|
+
];
|
|
477
|
+
}
|
|
478
|
+
/** What a `db init` / `db update` result looks like in human mode. */
|
|
479
|
+
function migrationResultBlocks(result) {
|
|
480
|
+
return result.mode === "plan" ? planBlocks(result) : applyBlocks(result);
|
|
481
|
+
}
|
|
482
|
+
/** Where the user goes next, as typed actions rather than trailing prose. */
|
|
483
|
+
function migrationResultNextActions(result, applyCommand) {
|
|
484
|
+
return result.mode === "plan" ? [runCommandAction("Apply the planned operations", applyCommand)] : [runCommandAction(result.perSpace !== void 0 && result.perSpace.length === 1 ? "Confirm the space is up to date" : "Confirm every space is up to date", "prisma-next migration status")];
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
258
487
|
* Where migrations live for this project. Resolved against the invocation
|
|
259
488
|
* directory, which is also the config file's directory for every default
|
|
260
489
|
* invocation.
|
|
@@ -267,6 +496,13 @@ function appMigrationsDirFor(config, cwd) {
|
|
|
267
496
|
return spaceMigrationDirectory(migrationsDirFor(config, cwd), APP_SPACE_ID);
|
|
268
497
|
}
|
|
269
498
|
/**
|
|
499
|
+
* Where refs live. The framework keeps them under the app subspace rather than
|
|
500
|
+
* at the migrations root.
|
|
501
|
+
*/
|
|
502
|
+
function appRefsDirFor(config, cwd) {
|
|
503
|
+
return resolve(appMigrationsDirFor(config, cwd), "refs");
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
270
506
|
* The emitted contract. The config loader has already resolved
|
|
271
507
|
* `contract.output` against the config file's directory, so this only has an
|
|
272
508
|
* effect for a config handed in raw, as tests do.
|
|
@@ -282,6 +518,711 @@ function contractPathFor(config, cwd) {
|
|
|
282
518
|
function displayPath(path, cwd) {
|
|
283
519
|
return relative(cwd, path);
|
|
284
520
|
}
|
|
521
|
+
/** Reads the emitted contract as the raw document the control API validates. */
|
|
522
|
+
async function readContractDocument(contractPath) {
|
|
523
|
+
let content;
|
|
524
|
+
try {
|
|
525
|
+
content = await readFile(contractPath, "utf-8");
|
|
526
|
+
} catch (error) {
|
|
527
|
+
return notOk(normalizeError(Reflect.get(Object(error), "code") === "ENOENT" ? errorFileNotFound(contractPath, {
|
|
528
|
+
why: `Contract file not found at ${contractPath}`,
|
|
529
|
+
fix: "Run `prisma-next contract emit` to generate contract.json, or update `contract.output` in prisma-next.config.ts"
|
|
530
|
+
}) : errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}` })));
|
|
531
|
+
}
|
|
532
|
+
try {
|
|
533
|
+
return ok(castAs(JSON.parse(content)));
|
|
534
|
+
} catch (error) {
|
|
535
|
+
return notOk(normalizeError(errorContractValidationFailed(`Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`, { where: { path: contractPath } })));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
async function prepareMigrationRun(inputs) {
|
|
539
|
+
const { config, cwd, commandName } = inputs;
|
|
540
|
+
const contractPath = contractPathFor(config, cwd);
|
|
541
|
+
if (contractPath === void 0) return notOk(normalizeError(errorConfigValidation$1("contract.output", {
|
|
542
|
+
why: `${commandName} reads the emitted contract from config.contract.output; the config has no value to read.`,
|
|
543
|
+
section: "contract"
|
|
544
|
+
})));
|
|
545
|
+
const contract = await readContractDocument(contractPath);
|
|
546
|
+
if (!contract.ok) return notOk(contract.failure);
|
|
547
|
+
const dbConnection = inputs.db ?? config.db?.connection;
|
|
548
|
+
if (dbConnection === void 0) return notOk(normalizeError(errorDatabaseConnectionRequired({
|
|
549
|
+
why: `Database connection is required for ${commandName} (set db.connection in prisma-next.config.ts, or pass --db <url>)`,
|
|
550
|
+
commandName,
|
|
551
|
+
missingFlags: ["--db"]
|
|
552
|
+
})));
|
|
553
|
+
if (config.driver === void 0) return notOk(normalizeError(errorDriverRequired({ why: `Config.driver is required for ${commandName}` })));
|
|
554
|
+
if (!targetSupportsMigrations(config.target)) return notOk(normalizeError(errorTargetMigrationNotSupported({ why: `Target "${config.target.id}" does not support migrations` })));
|
|
555
|
+
return ok({
|
|
556
|
+
client: inputs.createClient({
|
|
557
|
+
family: config.family,
|
|
558
|
+
target: config.target,
|
|
559
|
+
adapter: config.adapter,
|
|
560
|
+
driver: config.driver,
|
|
561
|
+
extensions: config.extensions ?? []
|
|
562
|
+
}),
|
|
563
|
+
contractJson: contract.value,
|
|
564
|
+
contractPath,
|
|
565
|
+
contractDisplayPath: displayPath(contractPath, cwd),
|
|
566
|
+
dbConnection,
|
|
567
|
+
database: typeof dbConnection === "string" ? maskConnectionUrl(dbConnection) : void 0,
|
|
568
|
+
migrationsDir: migrationsDirFor(config, cwd),
|
|
569
|
+
refsDir: appRefsDirFor(config, cwd)
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
function initPresentations(inputs) {
|
|
573
|
+
const { document, database, dryRun } = inputs;
|
|
574
|
+
return {
|
|
575
|
+
human: () => [{
|
|
576
|
+
kind: "fields",
|
|
577
|
+
rail: true,
|
|
578
|
+
rows: [
|
|
579
|
+
{
|
|
580
|
+
label: "contract",
|
|
581
|
+
value: inputs.contractPath
|
|
582
|
+
},
|
|
583
|
+
...database === void 0 ? [] : [{
|
|
584
|
+
label: "database",
|
|
585
|
+
value: database
|
|
586
|
+
}],
|
|
587
|
+
...dryRun ? [{
|
|
588
|
+
label: "mode",
|
|
589
|
+
value: "dry run"
|
|
590
|
+
}] : []
|
|
591
|
+
]
|
|
592
|
+
}, ...migrationResultBlocks(document)],
|
|
593
|
+
json: () => document,
|
|
594
|
+
next: () => migrationResultNextActions(document, "prisma-next db init")
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function initDocument(inputs) {
|
|
598
|
+
const { value } = inputs;
|
|
599
|
+
return {
|
|
600
|
+
ok: true,
|
|
601
|
+
mode: value.mode,
|
|
602
|
+
plan: {
|
|
603
|
+
targetId: inputs.targetId,
|
|
604
|
+
destination: {
|
|
605
|
+
storageHash: value.destination.storageHash,
|
|
606
|
+
...ifDefined("profileHash", value.destination.profileHash)
|
|
607
|
+
},
|
|
608
|
+
operations: value.plan.operations.map((operation) => ({
|
|
609
|
+
id: operation.id,
|
|
610
|
+
label: operation.label,
|
|
611
|
+
operationClass: operation.operationClass
|
|
612
|
+
})),
|
|
613
|
+
...ifDefined("preview", value.plan.preview)
|
|
614
|
+
},
|
|
615
|
+
...value.execution === void 0 ? {} : { execution: {
|
|
616
|
+
operationsPlanned: value.execution.operationsPlanned,
|
|
617
|
+
operationsExecuted: value.execution.operationsExecuted
|
|
618
|
+
} },
|
|
619
|
+
...value.marker === void 0 ? {} : { marker: {
|
|
620
|
+
storageHash: value.marker.storageHash,
|
|
621
|
+
...ifDefined("profileHash", value.marker.profileHash)
|
|
622
|
+
} },
|
|
623
|
+
...ifDefined("perSpace", value.perSpace),
|
|
624
|
+
advancedRef: inputs.advancedRef,
|
|
625
|
+
plannedAdvanceRef: inputs.plannedAdvanceRef,
|
|
626
|
+
summary: value.summary,
|
|
627
|
+
timings: { total: Date.now() - inputs.startedAt }
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
function createDbInitCommand(createClient) {
|
|
631
|
+
return defineOrmCommand({
|
|
632
|
+
help: {
|
|
633
|
+
summary: "Bootstrap a database to match the current contract and sign it",
|
|
634
|
+
description: "Creates everything the emitted contract declares and the database does not\nhave yet, using additive operations only. Structures already in place and\ncompatible are left alone, a conflict that would need a destructive change\nstops the run, and the database is signed with the contract it now matches.\nUse --dry-run to see the operations without applying them.",
|
|
635
|
+
examples: [
|
|
636
|
+
"db init",
|
|
637
|
+
"db init --db $DATABASE_URL",
|
|
638
|
+
"db init --dry-run",
|
|
639
|
+
"db init --advance-ref production"
|
|
640
|
+
]
|
|
641
|
+
},
|
|
642
|
+
args: { flags: {
|
|
643
|
+
db: dbFlag,
|
|
644
|
+
dryRun: flag.boolean({ brief: "Preview the planned operations without applying them" }),
|
|
645
|
+
advanceRef: flag.string({
|
|
646
|
+
brief: "Advance the named ref to the post-command contract hash",
|
|
647
|
+
placeholder: "name"
|
|
648
|
+
})
|
|
649
|
+
} },
|
|
650
|
+
needs: { config: ormConfigSection },
|
|
651
|
+
handler: async (args, ctx) => {
|
|
652
|
+
const startedAt = Date.now();
|
|
653
|
+
const prepared = await prepareMigrationRun({
|
|
654
|
+
config: ctx.config,
|
|
655
|
+
cwd: ctx.cwd,
|
|
656
|
+
db: args.flags.db,
|
|
657
|
+
commandName: "db init",
|
|
658
|
+
createClient
|
|
659
|
+
});
|
|
660
|
+
if (!prepared.ok) return notOk(prepared.failure);
|
|
661
|
+
const { client, contractJson, contractPath, dbConnection, migrationsDir, refsDir } = prepared.value;
|
|
662
|
+
let document;
|
|
663
|
+
try {
|
|
664
|
+
await client.connect(dbConnection);
|
|
665
|
+
const result = await client.dbInit({
|
|
666
|
+
contract: contractJson,
|
|
667
|
+
mode: args.flags.dryRun ? "plan" : "apply",
|
|
668
|
+
migrationsDir,
|
|
669
|
+
onProgress: controlProgressReporter(ctx.report)
|
|
670
|
+
});
|
|
671
|
+
if (!result.ok) return notOk(normalizeError(mapDbInitFailure(result.failure)));
|
|
672
|
+
const advancementHash = result.value.mode === "apply" ? result.value.marker?.storageHash ?? result.value.destination.storageHash : result.value.destination.storageHash;
|
|
673
|
+
const advancement = await resolveRefAdvancementFields({
|
|
674
|
+
...ifDefined("advanceRef", args.flags.advanceRef),
|
|
675
|
+
...ifDefined("db", args.flags.db),
|
|
676
|
+
refsDir,
|
|
677
|
+
migrationsDir,
|
|
678
|
+
contractJson,
|
|
679
|
+
contractJsonPath: contractPath,
|
|
680
|
+
mode: result.value.mode,
|
|
681
|
+
hash: advancementHash
|
|
682
|
+
});
|
|
683
|
+
if (!advancement.ok) return notOk(normalizeError(advancement.failure));
|
|
684
|
+
document = initDocument({
|
|
685
|
+
value: result.value,
|
|
686
|
+
targetId: ctx.config.target.targetId,
|
|
687
|
+
advancedRef: advancement.value.advancedRef,
|
|
688
|
+
plannedAdvanceRef: advancement.value.plannedAdvanceRef,
|
|
689
|
+
startedAt
|
|
690
|
+
});
|
|
691
|
+
} catch (error) {
|
|
692
|
+
if (CliStructuredError$1$1.is(error)) return notOk(normalizeError(error));
|
|
693
|
+
if (isStructuredError(error) && error.code === "CONTRACT.VALIDATION_FAILED") return notOk(normalizeError(errorContractValidationFailed(`Contract validation failed: ${error.message}`, { where: { path: contractPath } })));
|
|
694
|
+
const safeMessage = sanitizeErrorMessage(error instanceof Error ? error.message : String(error), typeof dbConnection === "string" ? dbConnection : void 0);
|
|
695
|
+
return notOk(normalizeError(errorUnexpected(safeMessage, { why: `Unexpected error during db init: ${safeMessage}` })));
|
|
696
|
+
} finally {
|
|
697
|
+
await closeQuietly(client);
|
|
698
|
+
}
|
|
699
|
+
ctx.report({
|
|
700
|
+
kind: "message",
|
|
701
|
+
severity: "verbose",
|
|
702
|
+
text: `Total time: ${document.timings.total}ms`
|
|
703
|
+
});
|
|
704
|
+
return ok(ctx.present({ data: document }, initPresentations({
|
|
705
|
+
document,
|
|
706
|
+
contractPath: prepared.value.contractDisplayPath,
|
|
707
|
+
database: prepared.value.database,
|
|
708
|
+
dryRun: args.flags.dryRun
|
|
709
|
+
})));
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
const dbInitCommand = createDbInitCommand(createControlClient);
|
|
714
|
+
const SUMMARY = "Schema read successfully";
|
|
715
|
+
/**
|
|
716
|
+
* A leading keyword and the name it introduces: `<keyword> <name>`, or
|
|
717
|
+
* `<keyword>: <name>`. The keyword recedes and the name is the identifier.
|
|
718
|
+
*/
|
|
719
|
+
function keywordThenName(label) {
|
|
720
|
+
const colon = label.match(/^(.+?):\s*(\S.*)$/);
|
|
721
|
+
if (colon?.[1] !== void 0 && colon[2] !== void 0) return [
|
|
722
|
+
{
|
|
723
|
+
text: colon[1],
|
|
724
|
+
tone: "muted"
|
|
725
|
+
},
|
|
726
|
+
{ text: ": " },
|
|
727
|
+
{
|
|
728
|
+
text: colon[2],
|
|
729
|
+
tone: "identifier"
|
|
730
|
+
}
|
|
731
|
+
];
|
|
732
|
+
const spaced = label.match(/^(\S.*\S|\S+)\s+(\S+)$/);
|
|
733
|
+
if (spaced?.[1] !== void 0 && spaced[2] !== void 0) return [
|
|
734
|
+
{
|
|
735
|
+
text: spaced[1],
|
|
736
|
+
tone: "muted"
|
|
737
|
+
},
|
|
738
|
+
{ text: " " },
|
|
739
|
+
{
|
|
740
|
+
text: spaced[2],
|
|
741
|
+
tone: "identifier"
|
|
742
|
+
}
|
|
743
|
+
];
|
|
744
|
+
}
|
|
745
|
+
/** `<name>: <detail> (<qualifier>)` — the name leads and the qualifier recedes. */
|
|
746
|
+
function namedDetail(label) {
|
|
747
|
+
const parts = label.match(/^([^:]+):\s*(.+)$/);
|
|
748
|
+
if (parts?.[1] === void 0 || parts[2] === void 0) return;
|
|
749
|
+
const [, name, rest] = parts;
|
|
750
|
+
const qualified = rest.match(/^([^\s(]+)\s*(\([^)]+\))$/);
|
|
751
|
+
if (qualified?.[1] !== void 0 && qualified[2] !== void 0) return [
|
|
752
|
+
{
|
|
753
|
+
text: name,
|
|
754
|
+
tone: "identifier"
|
|
755
|
+
},
|
|
756
|
+
{ text: `: ${qualified[1]} ` },
|
|
757
|
+
{
|
|
758
|
+
text: qualified[2],
|
|
759
|
+
tone: "muted"
|
|
760
|
+
}
|
|
761
|
+
];
|
|
762
|
+
return [{
|
|
763
|
+
text: name,
|
|
764
|
+
tone: "identifier"
|
|
765
|
+
}, { text: `: ${rest}` }];
|
|
766
|
+
}
|
|
767
|
+
/** `<name> <rest>` — the name leads and the prose behind it recedes. */
|
|
768
|
+
function nameThenProse(label) {
|
|
769
|
+
const parts = label.match(/^(\S+)\s+(\S.*)$/);
|
|
770
|
+
if (parts?.[1] === void 0 || parts[2] === void 0) return;
|
|
771
|
+
return [
|
|
772
|
+
{
|
|
773
|
+
text: parts[1],
|
|
774
|
+
tone: "identifier"
|
|
775
|
+
},
|
|
776
|
+
{ text: " " },
|
|
777
|
+
{
|
|
778
|
+
text: parts[2],
|
|
779
|
+
tone: "muted"
|
|
780
|
+
}
|
|
781
|
+
];
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* What a schema node's label means, said in tones.
|
|
785
|
+
*
|
|
786
|
+
* The families phrase these labels themselves, so the shapes recognised here
|
|
787
|
+
* are positional (`<keyword> <name>`, `<name>: <detail>`) rather than a list of
|
|
788
|
+
* words: a family that renames a keyword keeps its colouring, and no family's
|
|
789
|
+
* vocabulary is written down in the framework layer.
|
|
790
|
+
*/
|
|
791
|
+
function labelSpans(node) {
|
|
792
|
+
switch (node.kind) {
|
|
793
|
+
case "root": return [{
|
|
794
|
+
text: node.label,
|
|
795
|
+
tone: "emphasis"
|
|
796
|
+
}];
|
|
797
|
+
case "collection": return [{
|
|
798
|
+
text: node.label,
|
|
799
|
+
tone: "muted"
|
|
800
|
+
}];
|
|
801
|
+
case "entity":
|
|
802
|
+
case "index": return keywordThenName(node.label) ?? [{
|
|
803
|
+
text: node.label,
|
|
804
|
+
tone: "identifier"
|
|
805
|
+
}];
|
|
806
|
+
case "field": return namedDetail(node.label) ?? [{ text: node.label }];
|
|
807
|
+
case "dependency": return nameThenProse(node.label) ?? [{
|
|
808
|
+
text: node.label,
|
|
809
|
+
tone: "identifier"
|
|
810
|
+
}];
|
|
811
|
+
default: return [{ text: node.label }];
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
function treeNode(node) {
|
|
815
|
+
return {
|
|
816
|
+
label: labelSpans(node),
|
|
817
|
+
...ifDefined("children", node.children === void 0 || node.children.length === 0 ? void 0 : node.children.map(treeNode))
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
function schemaPresentations(inputs) {
|
|
821
|
+
const { document, schemaView, database } = inputs;
|
|
822
|
+
return {
|
|
823
|
+
human: () => [...database === void 0 ? [] : [{
|
|
824
|
+
kind: "fields",
|
|
825
|
+
rail: true,
|
|
826
|
+
rows: [{
|
|
827
|
+
label: "database",
|
|
828
|
+
value: database
|
|
829
|
+
}]
|
|
830
|
+
}], schemaView === void 0 ? {
|
|
831
|
+
kind: "summary",
|
|
832
|
+
status: "ok",
|
|
833
|
+
text: document.summary
|
|
834
|
+
} : {
|
|
835
|
+
kind: "tree",
|
|
836
|
+
roots: [treeNode(schemaView.root)]
|
|
837
|
+
}],
|
|
838
|
+
json: () => document
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
function createDbSchemaCommand(createClient) {
|
|
842
|
+
return defineOrmCommand({
|
|
843
|
+
help: {
|
|
844
|
+
summary: "Inspect the live database schema",
|
|
845
|
+
description: "Reads the live database schema and prints it as a tree, or as the result\ndocument with --json. Always read-only: it never writes a file and never\nchanges the database.",
|
|
846
|
+
examples: [
|
|
847
|
+
"db schema",
|
|
848
|
+
"db schema --db $DATABASE_URL",
|
|
849
|
+
"db schema --json"
|
|
850
|
+
]
|
|
851
|
+
},
|
|
852
|
+
args: { flags: { db: dbFlag } },
|
|
853
|
+
needs: { config: ormConfigSection },
|
|
854
|
+
handler: async (args, ctx) => {
|
|
855
|
+
const startedAt = Date.now();
|
|
856
|
+
const dbConnection = args.flags.db ?? ctx.config.db?.connection;
|
|
857
|
+
if (dbConnection === void 0) return notOk(normalizeError(errorDatabaseConnectionRequired({
|
|
858
|
+
why: "Database connection is required for db schema (set db.connection in prisma-next.config.ts, or pass --db <url>)",
|
|
859
|
+
commandName: "db schema",
|
|
860
|
+
missingFlags: ["--db"]
|
|
861
|
+
})));
|
|
862
|
+
if (ctx.config.driver === void 0) return notOk(normalizeError(errorDriverRequired({ why: "Config.driver is required for db schema" })));
|
|
863
|
+
const client = createClient({
|
|
864
|
+
family: ctx.config.family,
|
|
865
|
+
target: ctx.config.target,
|
|
866
|
+
adapter: ctx.config.adapter,
|
|
867
|
+
driver: ctx.config.driver,
|
|
868
|
+
extensions: ctx.config.extensions ?? []
|
|
869
|
+
});
|
|
870
|
+
let schema;
|
|
871
|
+
let schemaView;
|
|
872
|
+
try {
|
|
873
|
+
schema = await client.introspect({
|
|
874
|
+
connection: dbConnection,
|
|
875
|
+
onProgress: controlProgressReporter(ctx.report)
|
|
876
|
+
});
|
|
877
|
+
schemaView = client.toSchemaView(schema);
|
|
878
|
+
} catch (error) {
|
|
879
|
+
if (CliStructuredError$1$1.is(error)) return notOk(normalizeError(error));
|
|
880
|
+
const safeMessage = sanitizeErrorMessage(error instanceof Error ? error.message : String(error), typeof dbConnection === "string" ? dbConnection : void 0);
|
|
881
|
+
return notOk(normalizeError(errorUnexpected(safeMessage, { why: `Unexpected error during db schema: ${safeMessage}` })));
|
|
882
|
+
} finally {
|
|
883
|
+
await closeQuietly(client);
|
|
884
|
+
}
|
|
885
|
+
const database = typeof dbConnection === "string" ? maskConnectionUrl(dbConnection) : void 0;
|
|
886
|
+
const document = {
|
|
887
|
+
ok: true,
|
|
888
|
+
summary: SUMMARY,
|
|
889
|
+
target: {
|
|
890
|
+
familyId: ctx.config.family.familyId,
|
|
891
|
+
id: ctx.config.target.targetId
|
|
892
|
+
},
|
|
893
|
+
schema,
|
|
894
|
+
meta: { ...ifDefined("dbUrl", database) },
|
|
895
|
+
timings: { total: Date.now() - startedAt }
|
|
896
|
+
};
|
|
897
|
+
return ok(ctx.present({ data: document }, schemaPresentations({
|
|
898
|
+
document,
|
|
899
|
+
schemaView,
|
|
900
|
+
database
|
|
901
|
+
})));
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
const dbSchemaCommand = createDbSchemaCommand(createControlClient);
|
|
906
|
+
const STATUS_ACTION = runCommandAction("Check every space against the database", "prisma-next migration status");
|
|
907
|
+
/**
|
|
908
|
+
* The route the migration will take. The graph is a drawing — the engine cannot
|
|
909
|
+
* derive a lane gutter — and the ordered list under it is drawn with the same
|
|
910
|
+
* widths so every arrow lands in one column.
|
|
911
|
+
*/
|
|
912
|
+
function showPresentations$1(inputs) {
|
|
913
|
+
const { document, graph, runList } = inputs;
|
|
914
|
+
const count = document.migrations.length;
|
|
915
|
+
return {
|
|
916
|
+
human: () => [
|
|
917
|
+
{
|
|
918
|
+
kind: "fields",
|
|
919
|
+
rail: true,
|
|
920
|
+
rows: [
|
|
921
|
+
{
|
|
922
|
+
label: "migrations",
|
|
923
|
+
value: inputs.migrationsDir
|
|
924
|
+
},
|
|
925
|
+
...inputs.database === void 0 ? [] : [{
|
|
926
|
+
label: "database",
|
|
927
|
+
value: inputs.database
|
|
928
|
+
}],
|
|
929
|
+
...inputs.from === void 0 ? [] : [{
|
|
930
|
+
label: "from",
|
|
931
|
+
value: inputs.from
|
|
932
|
+
}],
|
|
933
|
+
...inputs.to === void 0 ? [] : [{
|
|
934
|
+
label: "to",
|
|
935
|
+
value: inputs.to
|
|
936
|
+
}]
|
|
937
|
+
]
|
|
938
|
+
},
|
|
939
|
+
...graph.length === 0 ? [] : [{
|
|
940
|
+
kind: "drawing",
|
|
941
|
+
lines: toneDrawing(graph)
|
|
942
|
+
}],
|
|
943
|
+
...count === 0 ? [{
|
|
944
|
+
kind: "summary",
|
|
945
|
+
status: "info",
|
|
946
|
+
text: document.summary
|
|
947
|
+
}] : [{
|
|
948
|
+
kind: "summary",
|
|
949
|
+
status: "info",
|
|
950
|
+
text: `The following ${count} migration${count === 1 ? "" : "s"} will run:`
|
|
951
|
+
}, {
|
|
952
|
+
kind: "drawing",
|
|
953
|
+
lines: toneDrawing(runList.join("\n"))
|
|
954
|
+
}]
|
|
955
|
+
],
|
|
956
|
+
json: () => document
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
function applyPresentations(inputs) {
|
|
960
|
+
const { document } = inputs;
|
|
961
|
+
const advanced = document.advancedRef;
|
|
962
|
+
return {
|
|
963
|
+
human: () => [
|
|
964
|
+
{
|
|
965
|
+
kind: "fields",
|
|
966
|
+
rail: true,
|
|
967
|
+
rows: [
|
|
968
|
+
{
|
|
969
|
+
label: "migrations",
|
|
970
|
+
value: inputs.migrationsDir
|
|
971
|
+
},
|
|
972
|
+
...inputs.database === void 0 ? [] : [{
|
|
973
|
+
label: "database",
|
|
974
|
+
value: inputs.database
|
|
975
|
+
}],
|
|
976
|
+
...inputs.to === void 0 ? [] : [{
|
|
977
|
+
label: "to",
|
|
978
|
+
value: inputs.to
|
|
979
|
+
}]
|
|
980
|
+
]
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
kind: "summary",
|
|
984
|
+
status: "ok",
|
|
985
|
+
text: document.summary
|
|
986
|
+
},
|
|
987
|
+
...document.perSpace.length === 0 ? [] : perSpaceBlocks(document.perSpace, "apply"),
|
|
988
|
+
...advanced === null || advanced === void 0 ? [] : [{
|
|
989
|
+
kind: "summary",
|
|
990
|
+
status: "ok",
|
|
991
|
+
text: [{ text: `Advanced ref "${advanced.name}" → ` }, {
|
|
992
|
+
text: advanced.hash,
|
|
993
|
+
tone: "identifier"
|
|
994
|
+
}]
|
|
995
|
+
}]
|
|
996
|
+
],
|
|
997
|
+
json: () => document,
|
|
998
|
+
next: () => [STATUS_ACTION]
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* `--to` as a contract the app graph knows. A ref target keeps the invariants
|
|
1003
|
+
* the ref declares; a bare hash carries none. Omitting `--to` targets the
|
|
1004
|
+
* emitted contract, which needs no resolution at all.
|
|
1005
|
+
*/
|
|
1006
|
+
function resolveRequestedTarget(to, refs, graph) {
|
|
1007
|
+
if (to === void 0) return ok({
|
|
1008
|
+
entry: void 0,
|
|
1009
|
+
refName: void 0
|
|
1010
|
+
});
|
|
1011
|
+
const resolved = resolveContractRef(to, {
|
|
1012
|
+
graph,
|
|
1013
|
+
refs
|
|
1014
|
+
});
|
|
1015
|
+
if (!resolved.ok) return notOk(normalizeError(resolved.failure));
|
|
1016
|
+
if (resolved.value.provenance.kind !== "ref") return ok({
|
|
1017
|
+
entry: {
|
|
1018
|
+
hash: resolved.value.hash,
|
|
1019
|
+
invariants: []
|
|
1020
|
+
},
|
|
1021
|
+
refName: void 0
|
|
1022
|
+
});
|
|
1023
|
+
const refName = resolved.value.provenance.refName;
|
|
1024
|
+
return ok({
|
|
1025
|
+
entry: refs[refName],
|
|
1026
|
+
refName
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
function createMigrateCommand(createClient) {
|
|
1030
|
+
return defineOrmCommand({
|
|
1031
|
+
help: {
|
|
1032
|
+
summary: "Apply planned migrations to advance the database",
|
|
1033
|
+
description: "Walks every contract space (app + extensions) and applies pending on-disk\nmigrations in canonical order (extensions alphabetically, then app). It\nreplays the on-disk migration graph and never invents an edge. Use --to to\ntarget a specific contract (hash, ref name, or migration directory) and\n--show for a read-only preview of the route it would take.",
|
|
1034
|
+
examples: [
|
|
1035
|
+
"migrate",
|
|
1036
|
+
"migrate --db $DATABASE_URL",
|
|
1037
|
+
"migrate --to production",
|
|
1038
|
+
"migrate --show",
|
|
1039
|
+
"migrate --show --from @contract --to production"
|
|
1040
|
+
]
|
|
1041
|
+
},
|
|
1042
|
+
args: { flags: {
|
|
1043
|
+
db: dbFlag,
|
|
1044
|
+
to: flag.string({
|
|
1045
|
+
brief: "Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)",
|
|
1046
|
+
placeholder: "contract"
|
|
1047
|
+
}),
|
|
1048
|
+
advanceRef: flag.string({
|
|
1049
|
+
brief: "Advance the named ref to the post-apply marker after success",
|
|
1050
|
+
placeholder: "name"
|
|
1051
|
+
}),
|
|
1052
|
+
show: flag.boolean({ brief: "Preview the migration route without applying (read-only)" }),
|
|
1053
|
+
from: flag.string({
|
|
1054
|
+
brief: "From-state for the --show preview (@contract, @db, hash, ref name, or dir)",
|
|
1055
|
+
placeholder: "contract"
|
|
1056
|
+
})
|
|
1057
|
+
} },
|
|
1058
|
+
needs: { config: ormConfigSection },
|
|
1059
|
+
handler: async (args, ctx) => {
|
|
1060
|
+
const migrationsRelative = displayPath(migrationsDirFor(ctx.config, ctx.cwd), ctx.cwd);
|
|
1061
|
+
if (args.flags.show) {
|
|
1062
|
+
const planned = await executeMigrateShowPlan({
|
|
1063
|
+
config: ctx.config,
|
|
1064
|
+
cwd: ctx.cwd,
|
|
1065
|
+
createClient,
|
|
1066
|
+
...ifDefined("db", args.flags.db),
|
|
1067
|
+
...ifDefined("to", args.flags.to),
|
|
1068
|
+
...ifDefined("from", args.flags.from)
|
|
1069
|
+
});
|
|
1070
|
+
if (!planned.ok) return notOk(normalizeError(planned.failure));
|
|
1071
|
+
const plan = planned.value;
|
|
1072
|
+
const paint = {
|
|
1073
|
+
colorize: true,
|
|
1074
|
+
glyphMode: "unicode",
|
|
1075
|
+
styler: createToneMigrationListStyler(),
|
|
1076
|
+
palette: TONE_MIGRATION_GRAPH_PALETTE
|
|
1077
|
+
};
|
|
1078
|
+
const rendering = renderMigrateShowGraph(plan, paint);
|
|
1079
|
+
const document = {
|
|
1080
|
+
ok: true,
|
|
1081
|
+
migrations: plan.migrations,
|
|
1082
|
+
summary: plan.summary
|
|
1083
|
+
};
|
|
1084
|
+
const dbConnection = args.flags.db ?? ctx.config.db?.connection;
|
|
1085
|
+
return ok(ctx.present({ data: document }, showPresentations$1({
|
|
1086
|
+
document,
|
|
1087
|
+
graph: rendering.graphOutput,
|
|
1088
|
+
runList: migrateShowRunListRows(plan.migrations, rendering, paint),
|
|
1089
|
+
migrationsDir: migrationsRelative,
|
|
1090
|
+
database: args.flags.from === void 0 && typeof dbConnection === "string" ? maskConnectionUrl(dbConnection) : void 0,
|
|
1091
|
+
from: args.flags.from,
|
|
1092
|
+
to: args.flags.to
|
|
1093
|
+
})));
|
|
1094
|
+
}
|
|
1095
|
+
const startedAt = Date.now();
|
|
1096
|
+
const prepared = await prepareMigrationRun({
|
|
1097
|
+
config: ctx.config,
|
|
1098
|
+
cwd: ctx.cwd,
|
|
1099
|
+
db: args.flags.db,
|
|
1100
|
+
commandName: "migrate",
|
|
1101
|
+
createClient
|
|
1102
|
+
});
|
|
1103
|
+
if (!prepared.ok) return notOk(prepared.failure);
|
|
1104
|
+
const { client, contractJson, contractPath, dbConnection, migrationsDir, refsDir } = prepared.value;
|
|
1105
|
+
const familyInstance = ctx.config.family.create(createControlStack(ctx.config));
|
|
1106
|
+
let appContract;
|
|
1107
|
+
try {
|
|
1108
|
+
appContract = familyInstance.deserializeContract(contractJson);
|
|
1109
|
+
} catch (error) {
|
|
1110
|
+
return notOk(normalizeError(errorContractValidationFailed(`Contract at ${contractPath} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`, { where: { path: contractPath } })));
|
|
1111
|
+
}
|
|
1112
|
+
const loaded = await loadContractSpaceAggregateForCli({
|
|
1113
|
+
targetId: ctx.config.target.targetId,
|
|
1114
|
+
migrationsDir,
|
|
1115
|
+
appContract,
|
|
1116
|
+
extensions: ctx.config.extensions ?? [],
|
|
1117
|
+
deserializeContract: (json) => familyInstance.deserializeContract(json)
|
|
1118
|
+
});
|
|
1119
|
+
if (!loaded.ok) return notOk(normalizeError(loaded.failure));
|
|
1120
|
+
const aggregate = loaded.value;
|
|
1121
|
+
const integrityFailure = refuseContractSpaceIntegrity(aggregate, {
|
|
1122
|
+
declaredExtensions: toDeclaredExtensionsFromRaw(castAs(ctx.config.extensions ?? [])),
|
|
1123
|
+
checkContracts: true
|
|
1124
|
+
});
|
|
1125
|
+
if (integrityFailure) return notOk(normalizeError(integrityFailure));
|
|
1126
|
+
const target = resolveRequestedTarget(args.flags.to, aggregate.app.refs, aggregate.app.graph());
|
|
1127
|
+
if (!target.ok) return notOk(target.failure);
|
|
1128
|
+
let document;
|
|
1129
|
+
try {
|
|
1130
|
+
await client.connect(dbConnection);
|
|
1131
|
+
const appGraph = aggregate.app.graph();
|
|
1132
|
+
const appMarker = (await client.readAllMarkers()).get("app") ?? null;
|
|
1133
|
+
if (appMarker !== null) {
|
|
1134
|
+
const markerRefusal = refuseMarkerOutsideGraph({
|
|
1135
|
+
markerHash: appMarker.storageHash,
|
|
1136
|
+
graph: appGraph
|
|
1137
|
+
});
|
|
1138
|
+
if (markerRefusal) return notOk(normalizeError(markerRefusal));
|
|
1139
|
+
}
|
|
1140
|
+
const refEntry = target.value.entry;
|
|
1141
|
+
if (refEntry !== void 0 && refEntry.invariants.length > 0) {
|
|
1142
|
+
const invariantRefusal = refuseUnknownInvariants({
|
|
1143
|
+
graph: appGraph,
|
|
1144
|
+
markerInvariants: appMarker?.invariants ?? [],
|
|
1145
|
+
refInvariants: refEntry.invariants,
|
|
1146
|
+
...ifDefined("refName", args.flags.to)
|
|
1147
|
+
});
|
|
1148
|
+
if (invariantRefusal) return notOk(normalizeError(invariantRefusal));
|
|
1149
|
+
}
|
|
1150
|
+
let applyContract = appContract;
|
|
1151
|
+
let snapshotContractJson = contractJson;
|
|
1152
|
+
let snapshotContractDts;
|
|
1153
|
+
if (args.flags.to !== void 0 && refEntry !== void 0) {
|
|
1154
|
+
if (aggregate.app.packages.find((p) => p.metadata.to === refEntry.hash) !== void 0) try {
|
|
1155
|
+
const at = await aggregate.app.contractAt(refEntry.hash, target.value.refName === void 0 ? void 0 : { refName: target.value.refName });
|
|
1156
|
+
applyContract = at.contract;
|
|
1157
|
+
snapshotContractJson = blindCast(at.contractJson);
|
|
1158
|
+
snapshotContractDts = at.contractDts;
|
|
1159
|
+
} catch (error) {
|
|
1160
|
+
const mapped = mapContractAtError(error, { artifactRole: "to" });
|
|
1161
|
+
if (!mapped.ok) return notOk(normalizeError(mapped.failure));
|
|
1162
|
+
throw error;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
const applied = await client.migrate({
|
|
1166
|
+
contract: applyContract,
|
|
1167
|
+
migrationsDir,
|
|
1168
|
+
onProgress: controlProgressReporter(ctx.report),
|
|
1169
|
+
...ifDefined("refHash", refEntry?.hash),
|
|
1170
|
+
...refEntry?.invariants === void 0 ? {} : { refInvariants: refEntry.invariants },
|
|
1171
|
+
...refEntry === void 0 ? {} : ifDefined("refName", args.flags.to)
|
|
1172
|
+
});
|
|
1173
|
+
if (!applied.ok) return notOk(normalizeError(mapMigrateFailure(applied.failure)));
|
|
1174
|
+
const { value } = applied;
|
|
1175
|
+
let advancedRef = null;
|
|
1176
|
+
if (args.flags.advanceRef !== void 0) {
|
|
1177
|
+
const contractIR = snapshotContractDts === void 0 ? await readContractIR(snapshotContractJson, contractPath) : {
|
|
1178
|
+
contract: snapshotContractJson,
|
|
1179
|
+
contractDts: snapshotContractDts
|
|
1180
|
+
};
|
|
1181
|
+
const advanced = await advanceRefSafely({
|
|
1182
|
+
refsDir,
|
|
1183
|
+
migrationsDir,
|
|
1184
|
+
name: args.flags.advanceRef,
|
|
1185
|
+
hash: value.markerHash,
|
|
1186
|
+
contractIR
|
|
1187
|
+
});
|
|
1188
|
+
if (!advanced.ok) return notOk(normalizeError(advanced.failure));
|
|
1189
|
+
advancedRef = {
|
|
1190
|
+
name: advanced.value.name,
|
|
1191
|
+
hash: advanced.value.hash
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
document = {
|
|
1195
|
+
ok: true,
|
|
1196
|
+
migrationsApplied: value.migrationsApplied,
|
|
1197
|
+
migrationsTotal: value.applied.length,
|
|
1198
|
+
markerHash: value.markerHash,
|
|
1199
|
+
applied: value.applied,
|
|
1200
|
+
summary: value.summary,
|
|
1201
|
+
perSpace: value.perSpace,
|
|
1202
|
+
...ifDefined("pathDecision", value.pathDecision),
|
|
1203
|
+
timings: { total: Date.now() - startedAt },
|
|
1204
|
+
advancedRef
|
|
1205
|
+
};
|
|
1206
|
+
} catch (error) {
|
|
1207
|
+
return notOk(normalizeError(mapCaughtMigrationError(error) ?? errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Unexpected error during migrate: ${error instanceof Error ? error.message : String(error)}` })));
|
|
1208
|
+
} finally {
|
|
1209
|
+
await closeQuietly(client);
|
|
1210
|
+
}
|
|
1211
|
+
ctx.report({
|
|
1212
|
+
kind: "message",
|
|
1213
|
+
severity: "verbose",
|
|
1214
|
+
text: `Total time: ${document.timings.total}ms`
|
|
1215
|
+
});
|
|
1216
|
+
return ok(ctx.present({ data: document }, applyPresentations({
|
|
1217
|
+
document,
|
|
1218
|
+
migrationsDir: migrationsRelative,
|
|
1219
|
+
database: prepared.value.database,
|
|
1220
|
+
to: args.flags.to
|
|
1221
|
+
})));
|
|
1222
|
+
}
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1225
|
+
const migrateCommand = createMigrateCommand(createControlClient);
|
|
285
1226
|
/**
|
|
286
1227
|
* The tree is a drawing for a reader; the DOT document is a graph description
|
|
287
1228
|
* for another program, so it is the one thing here that belongs on stdout.
|
|
@@ -478,16 +1419,6 @@ const migrationListCommand = defineOrmCommand({
|
|
|
478
1419
|
})));
|
|
479
1420
|
}
|
|
480
1421
|
});
|
|
481
|
-
/**
|
|
482
|
-
* The database connection override, declared from here by every command that
|
|
483
|
-
* accepts one so its brief and placeholder cannot drift apart. Resolution
|
|
484
|
-
* order is the flag, then `config.db.connection`, then
|
|
485
|
-
* `CONFIG.DB_CONNECTION_REQUIRED`.
|
|
486
|
-
*/
|
|
487
|
-
const dbFlag = flag.string({
|
|
488
|
-
brief: "Database connection string",
|
|
489
|
-
placeholder: "url"
|
|
490
|
-
});
|
|
491
1422
|
const HEADING_APPLIED_AT = "Applied at";
|
|
492
1423
|
const HEADING_SPACE = "Space";
|
|
493
1424
|
const HEADING_MIGRATION = "Migration";
|
|
@@ -627,7 +1558,7 @@ function operationBlocks(migration) {
|
|
|
627
1558
|
* than laid out, so nothing is re-wrapped between here and the reader.
|
|
628
1559
|
*/
|
|
629
1560
|
function previewBlocks(migration) {
|
|
630
|
-
const statements = migration.preview.statements.map((statement) => statement.text.
|
|
1561
|
+
const statements = migration.preview.statements.map((statement) => renderPreviewStatement(statement.text, statement.language)).filter((text) => text !== void 0);
|
|
631
1562
|
if (statements.length === 0) return [];
|
|
632
1563
|
return [{
|
|
633
1564
|
kind: "summary",
|
|
@@ -843,6 +1774,9 @@ const DOCS_BASE_URL = `${DOCS_BASE}/`;
|
|
|
843
1774
|
const ormCommandFamily = defineCommandFamily({
|
|
844
1775
|
configSection: ormConfigSection,
|
|
845
1776
|
commands: {
|
|
1777
|
+
"db init": dbInitCommand,
|
|
1778
|
+
"db schema": dbSchemaCommand,
|
|
1779
|
+
migrate: migrateCommand,
|
|
846
1780
|
"migration graph": migrationGraphCommand,
|
|
847
1781
|
"migration list": migrationListCommand,
|
|
848
1782
|
"migration log": migrationLogCommand,
|