prisma-next 0.12.0-dev.4 → 0.12.0-dev.40

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 (122) hide show
  1. package/dist/cli.mjs +180 -163
  2. package/dist/cli.mjs.map +1 -1
  3. package/dist/{client-KgJorIvG.mjs → client-BNdG504y.mjs} +80 -56
  4. package/dist/client-BNdG504y.mjs.map +1 -0
  5. package/dist/{command-helpers-Bbw1GbwL.mjs → command-helpers-xvg9oq4T.mjs} +301 -23
  6. package/dist/command-helpers-xvg9oq4T.mjs.map +1 -0
  7. package/dist/commands/contract-emit.mjs +1 -1
  8. package/dist/commands/contract-infer.mjs +1 -1
  9. package/dist/commands/db-init.mjs +4 -5
  10. package/dist/commands/db-init.mjs.map +1 -1
  11. package/dist/commands/db-schema.mjs +3 -3
  12. package/dist/commands/db-sign.mjs +4 -4
  13. package/dist/commands/db-update.d.mts.map +1 -1
  14. package/dist/commands/db-update.mjs +10 -7
  15. package/dist/commands/db-update.mjs.map +1 -1
  16. package/dist/commands/db-verify.mjs +1 -1
  17. package/dist/commands/migrate.d.mts +2 -2
  18. package/dist/commands/migrate.d.mts.map +1 -1
  19. package/dist/commands/migrate.mjs +6 -8
  20. package/dist/commands/migrate.mjs.map +1 -1
  21. package/dist/commands/migration-check.d.mts +55 -1
  22. package/dist/commands/migration-check.d.mts.map +1 -1
  23. package/dist/commands/migration-check.mjs +2 -2
  24. package/dist/commands/migration-graph.d.mts +25 -7
  25. package/dist/commands/migration-graph.d.mts.map +1 -1
  26. package/dist/commands/migration-graph.mjs +170 -2
  27. package/dist/commands/migration-graph.mjs.map +1 -0
  28. package/dist/commands/migration-list.d.mts +24 -26
  29. package/dist/commands/migration-list.d.mts.map +1 -1
  30. package/dist/commands/migration-list.mjs +2 -190
  31. package/dist/commands/migration-log.d.mts +20 -15
  32. package/dist/commands/migration-log.d.mts.map +1 -1
  33. package/dist/commands/migration-log.mjs +1 -137
  34. package/dist/commands/migration-new.mjs +3 -3
  35. package/dist/commands/migration-plan.d.mts +1 -1
  36. package/dist/commands/migration-plan.mjs +1 -1
  37. package/dist/commands/migration-show.d.mts +1 -4
  38. package/dist/commands/migration-show.d.mts.map +1 -1
  39. package/dist/commands/migration-show.mjs +13 -25
  40. package/dist/commands/migration-show.mjs.map +1 -1
  41. package/dist/commands/migration-status.d.mts +41 -141
  42. package/dist/commands/migration-status.d.mts.map +1 -1
  43. package/dist/commands/migration-status.mjs +2 -759
  44. package/dist/commands/ref.d.mts +1 -1
  45. package/dist/commands/ref.mjs +3 -3
  46. package/dist/commands/telemetry/index.d.mts +7 -0
  47. package/dist/commands/telemetry/index.d.mts.map +1 -0
  48. package/dist/commands/telemetry/index.mjs +2 -0
  49. package/dist/{contract-at-errors-BxP-TOMl.mjs → contract-at-errors-Wj3u4Xco.mjs} +2 -2
  50. package/dist/{contract-at-errors-BxP-TOMl.mjs.map → contract-at-errors-Wj3u4Xco.mjs.map} +1 -1
  51. package/dist/{contract-emit-DxcGl4Uq.mjs → contract-emit-COg18szA.mjs} +3 -3
  52. package/dist/{contract-emit-DxcGl4Uq.mjs.map → contract-emit-COg18szA.mjs.map} +1 -1
  53. package/dist/{contract-emit-D-4jrNve.mjs → contract-emit-KyJNQK5-.mjs} +3 -3
  54. package/dist/{contract-emit-D-4jrNve.mjs.map → contract-emit-KyJNQK5-.mjs.map} +1 -1
  55. package/dist/{contract-infer-D8uEbJuu.mjs → contract-infer-IEp0227u.mjs} +3 -3
  56. package/dist/{contract-infer-D8uEbJuu.mjs.map → contract-infer-IEp0227u.mjs.map} +1 -1
  57. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs → contract-space-aggregate-loader-BdRPfM3Q.mjs} +63 -5
  58. package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs.map → contract-space-aggregate-loader-BdRPfM3Q.mjs.map} +1 -1
  59. package/dist/{db-verify-v_vUKXTU.mjs → db-verify-C9k5KAyI.mjs} +4 -4
  60. package/dist/{db-verify-v_vUKXTU.mjs.map → db-verify-C9k5KAyI.mjs.map} +1 -1
  61. package/dist/exports/control-api.d.mts +2 -2
  62. package/dist/exports/control-api.d.mts.map +1 -1
  63. package/dist/exports/control-api.mjs +2 -2
  64. package/dist/exports/index.mjs +1 -1
  65. package/dist/exports/init-output.mjs +1 -1
  66. package/dist/{framework-components-fYXjz_in.mjs → framework-components-Be4inY3I.mjs} +2 -2
  67. package/dist/{framework-components-fYXjz_in.mjs.map → framework-components-Be4inY3I.mjs.map} +1 -1
  68. package/dist/{global-flags-DEHjV8_s.d.mts → global-flags-DG4uY5tV.d.mts} +1 -1
  69. package/dist/{global-flags-DEHjV8_s.d.mts.map → global-flags-DG4uY5tV.d.mts.map} +1 -1
  70. package/dist/{init-Cv9UzWL5.mjs → init-BIxw3l7t.mjs} +5 -58
  71. package/dist/init-BIxw3l7t.mjs.map +1 -0
  72. package/dist/{inspect-live-schema-C6ohV_oQ.mjs → inspect-live-schema-DXUFGQDe.mjs} +3 -3
  73. package/dist/{inspect-live-schema-C6ohV_oQ.mjs.map → inspect-live-schema-DXUFGQDe.mjs.map} +1 -1
  74. package/dist/{migration-check-BiBJoYYW.mjs → migration-check-CUavU7U9.mjs} +236 -88
  75. package/dist/migration-check-CUavU7U9.mjs.map +1 -0
  76. package/dist/{migration-command-scaffold-CjvwO6at.mjs → migration-command-scaffold-omgKpt3K.mjs} +3 -3
  77. package/dist/{migration-command-scaffold-CjvwO6at.mjs.map → migration-command-scaffold-omgKpt3K.mjs.map} +1 -1
  78. package/dist/migration-graph-space-render-ByJ83gxp.mjs +1966 -0
  79. package/dist/migration-graph-space-render-ByJ83gxp.mjs.map +1 -0
  80. package/dist/migration-list-jK6QeczE.mjs +228 -0
  81. package/dist/migration-list-jK6QeczE.mjs.map +1 -0
  82. package/dist/migration-list-types-DS63IdFd.d.mts +23 -0
  83. package/dist/migration-list-types-DS63IdFd.d.mts.map +1 -0
  84. package/dist/migration-log-CW0EjxSr.mjs +215 -0
  85. package/dist/migration-log-CW0EjxSr.mjs.map +1 -0
  86. package/dist/migration-path-target-DqcrbOis.mjs +24 -0
  87. package/dist/migration-path-target-DqcrbOis.mjs.map +1 -0
  88. package/dist/{migration-plan-9DJ7q7_z.mjs → migration-plan-NHdlUwPG.mjs} +5 -6
  89. package/dist/{migration-plan-9DJ7q7_z.mjs.map → migration-plan-NHdlUwPG.mjs.map} +1 -1
  90. package/dist/migration-status-GZ6XfbWs.mjs +439 -0
  91. package/dist/migration-status-GZ6XfbWs.mjs.map +1 -0
  92. package/dist/{output-B60Gw5fu.mjs → output-CF_hqzI-.mjs} +1 -1
  93. package/dist/{output-B60Gw5fu.mjs.map → output-CF_hqzI-.mjs.map} +1 -1
  94. package/dist/{ref-advancement-DUZqsue6.mjs → ref-advancement-CJY9zOv7.mjs} +1 -1
  95. package/dist/{ref-advancement-DUZqsue6.mjs.map → ref-advancement-CJY9zOv7.mjs.map} +1 -1
  96. package/dist/telemetry-DQP0BvKv.mjs +122 -0
  97. package/dist/telemetry-DQP0BvKv.mjs.map +1 -0
  98. package/dist/{types-Dt_SfqFm.d.mts → types-Cculk5KV.d.mts} +44 -31
  99. package/dist/types-Cculk5KV.d.mts.map +1 -0
  100. package/dist/{verify-DCA9Sldu.mjs → verify-tvHRBBVP.mjs} +2 -2
  101. package/dist/{verify-DCA9Sldu.mjs.map → verify-tvHRBBVP.mjs.map} +1 -1
  102. package/package.json +11 -12
  103. package/dist/client-KgJorIvG.mjs.map +0 -1
  104. package/dist/command-helpers-Bbw1GbwL.mjs.map +0 -1
  105. package/dist/commands/migration-list.mjs.map +0 -1
  106. package/dist/commands/migration-log.mjs.map +0 -1
  107. package/dist/commands/migration-status.mjs.map +0 -1
  108. package/dist/extension-pack-inputs-IDvjRCi3.mjs +0 -62
  109. package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +0 -1
  110. package/dist/graph-render-rFAqZujX.mjs +0 -1081
  111. package/dist/graph-render-rFAqZujX.mjs.map +0 -1
  112. package/dist/init-Cv9UzWL5.mjs.map +0 -1
  113. package/dist/migration-check-BiBJoYYW.mjs.map +0 -1
  114. package/dist/migration-graph-D7DVUElV.mjs +0 -1232
  115. package/dist/migration-graph-D7DVUElV.mjs.map +0 -1
  116. package/dist/migration-list-styler-BRwF4-gy.mjs +0 -399
  117. package/dist/migration-list-styler-BRwF4-gy.mjs.map +0 -1
  118. package/dist/migration-types-D2FW63pr.d.mts +0 -15
  119. package/dist/migration-types-D2FW63pr.d.mts.map +0 -1
  120. package/dist/migrations-Cv2jxNNK.mjs +0 -228
  121. package/dist/migrations-Cv2jxNNK.mjs.map +0 -1
  122. package/dist/types-Dt_SfqFm.d.mts.map +0 -1
@@ -12,6 +12,7 @@ import wrapAnsi from "wrap-ansi";
12
12
  import stringWidth from "string-width";
13
13
  import stripAnsi from "strip-ansi";
14
14
  import { isCI } from "ci-info";
15
+ import { blindCast } from "@prisma-next/utils/casts";
15
16
  import * as clack from "@clack/prompts";
16
17
  //#region src/utils/cli-errors.ts
17
18
  function errorRefSetHashNotInGraph(resolvedHash, reachableHashes, graphTipHash) {
@@ -39,6 +40,20 @@ function errorRefSetEmptySentinel(hash) {
39
40
  });
40
41
  }
41
42
  /**
43
+ * `--legend` was combined with a machine-readable or silent output flag.
44
+ * The legend is human-only decoration on stderr.
45
+ */
46
+ function errorLegendHumanOnly(conflictingFlag) {
47
+ return errorRuntime("`--legend` is only available for human-readable output", {
48
+ why: `\`--legend\` prints a glyph key to stderr and cannot be combined with ${conflictingFlag}.`,
49
+ fix: `Omit ${conflictingFlag} to print the legend alongside the tree, or omit --legend when using ${conflictingFlag}.`,
50
+ meta: {
51
+ code: "MIGRATION.LEGEND_HUMAN_ONLY",
52
+ conflictingFlag
53
+ }
54
+ });
55
+ }
56
+ /**
42
57
  * `--space <id>` was given a value that doesn't satisfy the contract-space
43
58
  * naming rule (`[a-z][a-z0-9_-]{0,63}` per `isValidSpaceId`). Fires before
44
59
  * any fs work — the input is syntactically rejected the same way an on-disk
@@ -189,6 +204,24 @@ function mapMigrationToolsError(error) {
189
204
  });
190
205
  }
191
206
  /**
207
+ * Shared "needs a live database" precondition for read verbs that consult the
208
+ * marker/ledger (`migration log`, `migration status`). A command needs both a
209
+ * connection string and a control-plane driver; either missing yields the same
210
+ * `PN-CLI-4005` envelope with `meta.missingFlags` (canonical long-form flags
211
+ * per CLI Style Guide §Errors) so callers can react programmatically. Returns
212
+ * `null` when both are present.
213
+ */
214
+ function requireLiveDatabase(args) {
215
+ if (args.dbConnection && args.hasDriver) return null;
216
+ const missingFlags = args.dbConnection ? [] : ["--db"];
217
+ return errorDatabaseConnectionRequired({
218
+ why: args.why,
219
+ missingFlags,
220
+ ...ifDefined("commandName", args.commandName),
221
+ ...ifDefined("retryCommand", args.retryCommand)
222
+ });
223
+ }
224
+ /**
192
225
  * Maps a `RefResolutionError` from the contract/migration reference
193
226
  * resolver into a CLI structured error envelope.
194
227
  */
@@ -670,6 +703,237 @@ function isCI$1() {
670
703
  return isCI;
671
704
  }
672
705
  //#endregion
706
+ //#region src/utils/formatters/migrations.ts
707
+ /**
708
+ * Render a single statement of an `OperationPreview` for the human-readable
709
+ * preview block. SQL statements get a trailing `;` if missing so the rendered
710
+ * preview is byte-identical to the legacy `string[]`-based renderer for SQL
711
+ * targets. Other languages (`'mongodb-shell'`) render verbatim.
712
+ */
713
+ function renderPreviewStatement(text, language) {
714
+ const trimmed = text.trim();
715
+ if (!trimmed) return void 0;
716
+ if (language === "sql") return trimmed.endsWith(";") ? trimmed : `${trimmed};`;
717
+ return trimmed;
718
+ }
719
+ /**
720
+ * Choose the header label for a preview block. SQL-only previews keep the
721
+ * legacy `DDL preview` label so the rendered output is byte-identical to the
722
+ * pre-aggregate SQL CLI; previews from any other family — or a mix that
723
+ * includes any non-SQL language — use the family-agnostic `Operation preview`
724
+ * label.
725
+ *
726
+ * An empty `statements` array deliberately renders as `Operation preview`
727
+ * rather than `DDL preview`: `Array.prototype.every` is vacuously true for
728
+ * empty arrays, but we have no evidence the preview is SQL-only when no
729
+ * statements are present, so the family-agnostic label is the safer default.
730
+ */
731
+ function previewBlockHeader(preview) {
732
+ return preview.statements.length > 0 && preview.statements.every((s) => s.language === "sql") ? "DDL preview" : "Operation preview";
733
+ }
734
+ function formatPlannerWarningsBlock(warnings, useColor) {
735
+ const formatDimText = (text) => formatDim(useColor, text);
736
+ const lines = ["", "Warnings:"];
737
+ for (const warning of warnings) lines.push(` ${formatDimText(`- ${warning.summary}`)}`);
738
+ return lines;
739
+ }
740
+ /**
741
+ * Render the shared per-space execution block consumed by the `db init`
742
+ * / `db update` / `migrate` summaries. Always shows: space
743
+ * label (`Extension space: <id>` or `App space`) → per-op lines under
744
+ * each space → per-space marker hash (when known).
745
+ *
746
+ * `mode` controls the marker label phrasing — `'apply'` shows
747
+ * `marker → <hash>` (post-apply), `'plan'` omits the marker line
748
+ * entirely (no marker has been written yet).
749
+ */
750
+ function formatPerSpaceBlock(perSpace, mode, useColor) {
751
+ const formatYellow = createColorFormatter(useColor, yellow);
752
+ const formatCyan = createColorFormatter(useColor, cyan);
753
+ const formatDimText = (text) => formatDim(useColor, text);
754
+ const lines = [];
755
+ for (let s = 0; s < perSpace.length; s++) {
756
+ const space = perSpace[s];
757
+ if (s > 0) lines.push("");
758
+ const header = space.kind === "app" ? formatCyan("App space") : formatCyan(`Extension space: ${space.spaceId}`);
759
+ lines.push(header);
760
+ if (space.operations.length === 0) lines.push(` ${formatDimText("(no operations)")}`);
761
+ else for (let i = 0; i < space.operations.length; i++) {
762
+ const op = space.operations[i];
763
+ const treeChar = i === space.operations.length - 1 ? "└" : "├";
764
+ const destructiveMarker = op.operationClass === "destructive" ? ` ${formatYellow("(destructive)")}` : "";
765
+ lines.push(` ${formatDimText(treeChar)}─ ${op.label}${destructiveMarker}`);
766
+ }
767
+ if (mode === "apply" && space.marker) lines.push(` ${formatDimText(`marker: ${space.marker.storageHash}`)}`);
768
+ }
769
+ return lines;
770
+ }
771
+ /**
772
+ * Formats human-readable output for migration commands (db init, db update) in plan mode.
773
+ */
774
+ function formatMigrationPlanOutput(result, flags) {
775
+ if (flags.quiet) return "";
776
+ const lines = [];
777
+ const useColor = flags.color !== false;
778
+ const formatGreen = createColorFormatter(useColor, green);
779
+ const formatDimText = (text) => formatDim(useColor, text);
780
+ const operationCount = result.plan?.operations.length ?? 0;
781
+ const spaceCount = result.perSpace?.length ?? 0;
782
+ if (spaceCount > 0) lines.push(`${formatGreen("✔")} Planned ${operationCount} operation(s) across ${spaceCount} contract space${spaceCount === 1 ? "" : "s"}`);
783
+ else lines.push(`${formatGreen("✔")} Planned ${operationCount} operation(s)`);
784
+ if (result.warnings && result.warnings.length > 0) lines.push(...formatPlannerWarningsBlock(result.warnings, useColor));
785
+ const formatYellow = createColorFormatter(useColor, yellow);
786
+ if (result.perSpace && result.perSpace.length > 0) {
787
+ lines.push("");
788
+ lines.push(...formatPerSpaceBlock(result.perSpace, "plan", useColor));
789
+ if (result.perSpace.some((s) => s.operations.some((op) => op.operationClass === "destructive"))) {
790
+ lines.push("");
791
+ lines.push(`${formatYellow("⚠")} This migration contains destructive operations that may cause data loss.`);
792
+ }
793
+ } else if (result.plan?.operations && result.plan.operations.length > 0) {
794
+ lines.push(`${formatDimText("│")}`);
795
+ for (let i = 0; i < result.plan.operations.length; i++) {
796
+ const op = result.plan.operations[i];
797
+ if (!op) continue;
798
+ const treeChar = i === result.plan.operations.length - 1 ? "└" : "├";
799
+ const destructiveMarker = op.operationClass === "destructive" ? ` ${formatYellow("(destructive)")}` : "";
800
+ lines.push(`${formatDimText(treeChar)}─ ${op.label}${destructiveMarker}`);
801
+ }
802
+ if (result.plan.operations.some((op) => op.operationClass === "destructive")) {
803
+ lines.push("");
804
+ lines.push(`${formatYellow("⚠")} This migration contains destructive operations that may cause data loss.`);
805
+ }
806
+ }
807
+ if (result.plan?.destination) {
808
+ lines.push("");
809
+ lines.push(`${formatDimText(`Destination hash: ${result.plan.destination.storageHash}`)}`);
810
+ }
811
+ if (result.plannedAdvanceRef) {
812
+ lines.push("");
813
+ lines.push(formatDimText(`Would advance ref "${result.plannedAdvanceRef.name}" → ${result.plannedAdvanceRef.hash}`));
814
+ }
815
+ const preview = result.plan?.preview;
816
+ if (preview) {
817
+ lines.push("");
818
+ lines.push(`${formatDimText(previewBlockHeader(preview))}`);
819
+ if (preview.statements.length === 0) lines.push(`${formatDimText("No operations.")}`);
820
+ else {
821
+ lines.push("");
822
+ for (const statement of preview.statements) {
823
+ const rendered = renderPreviewStatement(statement.text, statement.language);
824
+ if (rendered) lines.push(rendered);
825
+ }
826
+ }
827
+ }
828
+ if (isVerbose(flags, 1)) lines.push(`${formatDimText(`Total time: ${result.timings.total}ms`)}`);
829
+ lines.push("");
830
+ lines.push(`${formatDimText("This is a dry run. No changes were applied.")}`);
831
+ lines.push(`${formatDimText("Run without --dry-run to apply changes.")}`);
832
+ return lines.join("\n");
833
+ }
834
+ function formatMigrationApplyCommandOutput(result, flags) {
835
+ if (flags.quiet) return "";
836
+ const lines = [];
837
+ const useColor = flags.color !== false;
838
+ const formatGreen = createColorFormatter(useColor, green);
839
+ const formatDimText = (text) => formatDim(useColor, text);
840
+ lines.push(`${formatGreen("✔")} ${result.summary}`);
841
+ if (result.perSpace.length > 0) {
842
+ lines.push("");
843
+ for (const line of formatPerSpaceBlock(result.perSpace, "apply", useColor)) lines.push(line);
844
+ }
845
+ if (result.advancedRef) {
846
+ lines.push("");
847
+ lines.push(formatDimText(`Advanced ref "${result.advancedRef.name}" → ${result.advancedRef.hash}`));
848
+ }
849
+ lines.push("");
850
+ lines.push(formatDimText("Next: prisma-next migration status"));
851
+ if (isVerbose(flags, 1) && result.timings) {
852
+ lines.push("");
853
+ lines.push(formatDimText(`Total time: ${result.timings.total}ms`));
854
+ }
855
+ return lines.join("\n");
856
+ }
857
+ function formatSpaceShowBlock(space, useColor) {
858
+ const formatGreen = createColorFormatter(useColor, green);
859
+ const formatYellow = createColorFormatter(useColor, yellow);
860
+ const formatDimText = (text) => formatDim(useColor, text);
861
+ const lines = [];
862
+ lines.push(`${formatGreen("✔")} ${space.dirName}`);
863
+ lines.push(`${formatDimText(` from: ${space.from ?? "(baseline)"}`)}`);
864
+ lines.push(`${formatDimText(` to: ${space.to}`)}`);
865
+ lines.push(`${formatDimText(` migrationHash: ${space.migrationHash}`)}`);
866
+ lines.push(`${formatDimText(` created: ${space.createdAt}`)}`);
867
+ lines.push("");
868
+ lines.push(`${space.operations.length} operation(s)`);
869
+ if (space.operations.length > 0) {
870
+ lines.push(`${formatDimText("│")}`);
871
+ for (let i = 0; i < space.operations.length; i++) {
872
+ const op = space.operations[i];
873
+ const treeChar = i === space.operations.length - 1 ? "└" : "├";
874
+ const destructiveMarker = op.operationClass === "destructive" ? ` ${formatYellow("(destructive)")}` : "";
875
+ lines.push(`${formatDimText(treeChar)}─ ${op.label}${destructiveMarker}`);
876
+ }
877
+ if (space.operations.some((op) => op.operationClass === "destructive")) {
878
+ lines.push("");
879
+ lines.push(`${formatYellow("⚠")} This migration contains destructive operations that may cause data loss.`);
880
+ }
881
+ }
882
+ if (space.preview.statements.length > 0) {
883
+ lines.push("");
884
+ lines.push(`${formatDimText(previewBlockHeader(space.preview))}`);
885
+ lines.push("");
886
+ for (const statement of space.preview.statements) {
887
+ const rendered = renderPreviewStatement(statement.text, statement.language);
888
+ if (rendered) lines.push(rendered);
889
+ }
890
+ }
891
+ return lines;
892
+ }
893
+ function formatMigrationShowOutput(result, flags) {
894
+ if (flags.quiet) return "";
895
+ const useColor = flags.color !== false;
896
+ return formatSpaceShowBlock(result.migration, useColor).join("\n");
897
+ }
898
+ /**
899
+ * Formats human-readable output for migration commands (db init, db update) in apply mode.
900
+ */
901
+ function formatMigrationApplyOutput(result, flags) {
902
+ if (flags.quiet) return "";
903
+ const lines = [];
904
+ const useColor = flags.color !== false;
905
+ const formatGreen = createColorFormatter(useColor, green);
906
+ const formatDimText = (text) => formatDim(useColor, text);
907
+ if (result.ok) {
908
+ const executed = result.execution?.operationsExecuted ?? 0;
909
+ const spaceCount = result.perSpace?.length ?? 0;
910
+ if (executed === 0) {
911
+ const acrossClause = spaceCount > 0 ? ` across ${spaceCount} contract space${spaceCount === 1 ? "" : "s"}` : "";
912
+ lines.push(`${formatGreen("✔")} Database already matches contract${acrossClause}`);
913
+ } else if (spaceCount > 0) lines.push(`${formatGreen("✔")} Applied ${executed} operation(s) across ${spaceCount} contract space${spaceCount === 1 ? "" : "s"}`);
914
+ else lines.push(`${formatGreen("✔")} Applied ${executed} operation(s)`);
915
+ if (result.warnings && result.warnings.length > 0) lines.push(...formatPlannerWarningsBlock(result.warnings, useColor));
916
+ if (result.perSpace && result.perSpace.length > 0) {
917
+ lines.push("");
918
+ lines.push(...formatPerSpaceBlock(result.perSpace, "apply", useColor));
919
+ lines.push("");
920
+ lines.push(formatDimText(`Run 'prisma-next migration status' to confirm ${spaceCount === 1 ? "the space is" : "all spaces are"} up to date.`));
921
+ } else if (result.marker) {
922
+ lines.push(`${formatDimText(` App-space marker: ${result.marker.storageHash}`)}`);
923
+ if (result.marker.profileHash) lines.push(`${formatDimText(` Profile hash: ${result.marker.profileHash}`)}`);
924
+ }
925
+ if (isVerbose(flags, 1)) lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);
926
+ if (result.advancedRef) lines.push(formatDimText(`Advanced ref "${result.advancedRef.name}" → ${result.advancedRef.hash}`));
927
+ }
928
+ return lines.join("\n");
929
+ }
930
+ /**
931
+ * Formats JSON output for migration commands (db init, db update).
932
+ */
933
+ function formatMigrationJson(result) {
934
+ return JSON.stringify(result, null, 2);
935
+ }
936
+ //#endregion
673
937
  //#region src/utils/formatters/errors.ts
674
938
  /**
675
939
  * Formats error output for human-readable display.
@@ -711,6 +975,11 @@ function formatErrorOutput(error, flags) {
711
975
  }
712
976
  }
713
977
  if (error.docsUrl && isVerbose(flags, 1)) lines.push(formatDimText(error.docsUrl));
978
+ const plannerWarnings = error.meta?.["plannerWarnings"];
979
+ if (Array.isArray(plannerWarnings) && plannerWarnings.length > 0) {
980
+ const typedWarnings = blindCast(plannerWarnings);
981
+ lines.push(...formatPlannerWarningsBlock(typedWarnings, useColor));
982
+ }
714
983
  if (isVerbose(flags, 2) && error.meta) lines.push(`${formatDimText(` Meta: ${JSON.stringify(error.meta, null, 2)}`)}`);
715
984
  return lines.join("\n");
716
985
  }
@@ -1163,6 +1432,36 @@ function parseGlobalFlags(options) {
1163
1432
  if (options.yes || options.y) flags.yes = true;
1164
1433
  return flags;
1165
1434
  }
1435
+ /**
1436
+ * Bridges the two TTY checks (stdout via `flags`, stdin via
1437
+ * `process.stdin.isTTY`) into the `canPrompt` boolean the interactive
1438
+ * `init` flow consumes.
1439
+ *
1440
+ * Per the [Style Guide § Interactivity](../../../../../../../docs/CLI%20Style%20Guide.md#interactivity):
1441
+ *
1442
+ * - `flags.interactive` governs *decoration* (TerminalUI, intro/outro,
1443
+ * spinners) and is derived from stdout-TTY by `parseGlobalFlags`,
1444
+ * honouring `--interactive` / `--no-interactive`.
1445
+ * - Prompting additionally requires a stdin TTY — closing stdin is a
1446
+ * common signal in CI / agent environments even when stdout stays
1447
+ * attached.
1448
+ * - `--interactive` is the explicit override: when the user passes it,
1449
+ * we honour it (e.g. testing flows where stdin is stubbed).
1450
+ *
1451
+ * Single source of truth for the interactive-prompt decision: both the
1452
+ * `init` action handler and the preAction telemetry bridge derive
1453
+ * prompt-eligibility from this helper so they cannot drift. Lives in
1454
+ * `global-flags` (alongside `parseGlobalFlags`) to keep
1455
+ * `utils/telemetry` and `commands/init/index` free of an import cycle.
1456
+ *
1457
+ * Exported so callers and tests can derive the same value without
1458
+ * touching `process` globals.
1459
+ */
1460
+ function deriveCanPrompt(opts) {
1461
+ if (opts.optionInteractive === true) return true;
1462
+ if (opts.flagsInteractive === false) return false;
1463
+ return opts.stdinIsTTY;
1464
+ }
1166
1465
  //#endregion
1167
1466
  //#region src/utils/command-helpers.ts
1168
1467
  const longDescriptions = /* @__PURE__ */ new WeakMap();
@@ -1269,27 +1568,6 @@ function toStructuralEdge(edge) {
1269
1568
  invariants: edge.invariants
1270
1569
  };
1271
1570
  }
1272
- /**
1273
- * Maps a PathDecision to the slim CLI output representation.
1274
- */
1275
- function toPathDecisionResult(decision) {
1276
- return {
1277
- fromHash: decision.fromHash,
1278
- toHash: decision.toHash,
1279
- alternativeCount: decision.alternativeCount,
1280
- tieBreakReasons: decision.tieBreakReasons,
1281
- requiredInvariants: decision.requiredInvariants ?? [],
1282
- satisfiedInvariants: decision.satisfiedInvariants ?? [],
1283
- ...ifDefined("refName", decision.refName),
1284
- selectedPath: decision.selectedPath.map((entry) => ({
1285
- dirName: entry.dirName,
1286
- migrationHash: entry.migrationHash,
1287
- from: entry.from,
1288
- to: entry.to,
1289
- invariants: entry.invariants
1290
- }))
1291
- };
1292
- }
1293
1571
  function targetSupportsMigrations(target) {
1294
1572
  return hasMigrations(target);
1295
1573
  }
@@ -1370,6 +1648,6 @@ function addGlobalOptions(command) {
1370
1648
  } }).option("--format <pretty|json>", "Output format (default: pretty, or json when stdout is not a TTY)").option("--json", "Output as JSON (alias for --format json)").option("-q, --quiet", "Quiet mode: errors only").option("-v, --verbose", "Verbose output: debug info, timings").option("--trace", "Trace output: deep internals, stack traces").option("--color", "Force color output").option("--no-color", "Disable color output").option("--interactive", "Force interactive mode").option("--no-interactive", "Disable interactive prompts").option("-y, --yes", "Auto-accept prompts");
1371
1649
  }
1372
1650
  //#endregion
1373
- export { errorTargetMigrationNotSupported as $, CliStructuredError$1 as A, errorInvalidSpaceId as B, formatCommandHelp as C, createColorFormatter as D, formatSuccessMessage as E, errorDatabaseConnectionRequired as F, errorPlanForgotTheFlag as G, errorMarkerMissing as H, errorDestructiveChanges as I, errorRefSetHashNotInGraph as J, errorRefSetBundleNotFound as K, errorDriverRequired as L, errorConfigValidation$1 as M, errorContractConfigMissing$1 as N, formatDim as O, errorContractValidationFailed as P, errorSpaceNotFound as Q, errorFileNotFound as R, isCI$1 as S, formatStyledHeader as T, errorMigrationPlanningFailed as U, errorMarkerMismatch as V, errorPathUnreachable as W, errorRuntime$1 as X, errorRunnerFailed as Y, errorSnapshotMissing as Z, createTerminalUI as _, readContractEnvelope as a, formatErrorJson as b, sanitizeErrorMessage as c, setCommandSeeAlso as d, errorTargetMismatch as et, targetSupportsMigrations as f, parseGlobalFlagsOrExit as g, parseGlobalFlags as h, maskConnectionUrl as i, ERROR_CODE_DESTRUCTIVE_CHANGES as j, isVerbose as k, setCommandDescriptions as l, toStructuralEdge as m, collectDeclaredInvariants as n, mapMigrationToolsError as nt, resolveContractPath as o, toPathDecisionResult as p, errorRefSetEmptySentinel as q, getTargetMigrations as r, mapRefResolutionError as rt, resolveMigrationPaths as s, addGlobalOptions as t, errorUnexpected$1 as tt, setCommandExamples as u, installShutdownHandlers as v, formatRootHelp as w, formatErrorOutput as x, handleResult as y, errorHashMismatch as z };
1651
+ export { errorRefSetEmptySentinel as $, formatStyledHeader as A, errorDatabaseConnectionRequired as B, formatMigrationApplyOutput as C, isCI$1 as D, formatMigrationShowOutput as E, CliStructuredError$1 as F, errorInvalidSpaceId as G, errorDriverRequired as H, ERROR_CODE_DESTRUCTIVE_CHANGES as I, errorMarkerMissing as J, errorLegendHumanOnly as K, errorConfigValidation$1 as L, createColorFormatter as M, formatDim as N, formatCommandHelp as O, isVerbose as P, errorRefSetBundleNotFound as Q, errorContractConfigMissing$1 as R, formatMigrationApplyCommandOutput as S, formatMigrationPlanOutput as T, errorFileNotFound as U, errorDestructiveChanges as V, errorHashMismatch as W, errorPathUnreachable as X, errorMigrationPlanningFailed as Y, errorPlanForgotTheFlag as Z, createTerminalUI as _, readContractEnvelope as a, errorTargetMigrationNotSupported as at, formatErrorJson as b, sanitizeErrorMessage as c, mapMigrationToolsError as ct, setCommandSeeAlso as d, errorRefSetHashNotInGraph as et, targetSupportsMigrations as f, parseGlobalFlagsOrExit as g, parseGlobalFlags as h, maskConnectionUrl as i, errorSpaceNotFound as it, formatSuccessMessage as j, formatRootHelp as k, setCommandDescriptions as l, mapRefResolutionError as lt, deriveCanPrompt as m, collectDeclaredInvariants as n, errorRuntime$1 as nt, resolveContractPath as o, errorTargetMismatch as ot, toStructuralEdge as p, errorMarkerMismatch as q, getTargetMigrations as r, errorSnapshotMissing as rt, resolveMigrationPaths as s, errorUnexpected$1 as st, addGlobalOptions as t, errorRunnerFailed as tt, setCommandExamples as u, requireLiveDatabase as ut, installShutdownHandlers as v, formatMigrationJson as w, formatErrorOutput as x, handleResult as y, errorContractValidationFailed as z };
1374
1652
 
1375
- //# sourceMappingURL=command-helpers-Bbw1GbwL.mjs.map
1653
+ //# sourceMappingURL=command-helpers-xvg9oq4T.mjs.map