prisma-next 0.11.0-dev.7 → 0.11.0-dev.70

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 (146) hide show
  1. package/dist/cli.mjs +10 -11
  2. package/dist/cli.mjs.map +1 -1
  3. package/dist/{client-oXO2WCPD.mjs → client-6WehTnUh.mjs} +72 -60
  4. package/dist/client-6WehTnUh.mjs.map +1 -0
  5. package/dist/{command-helpers-DtavI0wJ.mjs → command-helpers-CoceqqMl.mjs} +642 -45
  6. package/dist/command-helpers-CoceqqMl.mjs.map +1 -0
  7. package/dist/commands/contract-emit.d.mts.map +1 -1
  8. package/dist/commands/contract-emit.mjs +1 -1
  9. package/dist/commands/contract-infer.d.mts.map +1 -1
  10. package/dist/commands/contract-infer.mjs +1 -1
  11. package/dist/commands/db-init.d.mts.map +1 -1
  12. package/dist/commands/db-init.mjs +32 -7
  13. package/dist/commands/db-init.mjs.map +1 -1
  14. package/dist/commands/db-schema.d.mts.map +1 -1
  15. package/dist/commands/db-schema.mjs +3 -4
  16. package/dist/commands/db-schema.mjs.map +1 -1
  17. package/dist/commands/db-sign.d.mts.map +1 -1
  18. package/dist/commands/db-sign.mjs +12 -10
  19. package/dist/commands/db-sign.mjs.map +1 -1
  20. package/dist/commands/db-update.d.mts.map +1 -1
  21. package/dist/commands/db-update.mjs +41 -11
  22. package/dist/commands/db-update.mjs.map +1 -1
  23. package/dist/commands/db-verify.d.mts.map +1 -1
  24. package/dist/commands/db-verify.mjs +1 -1
  25. package/dist/commands/migrate.d.mts +6 -2
  26. package/dist/commands/migrate.d.mts.map +1 -1
  27. package/dist/commands/migrate.mjs +75 -40
  28. package/dist/commands/migrate.mjs.map +1 -1
  29. package/dist/commands/migration-check.d.mts +4 -3
  30. package/dist/commands/migration-check.d.mts.map +1 -1
  31. package/dist/commands/migration-check.mjs +1 -280
  32. package/dist/commands/migration-graph.d.mts +13 -2
  33. package/dist/commands/migration-graph.d.mts.map +1 -1
  34. package/dist/commands/migration-graph.mjs +2 -137
  35. package/dist/commands/migration-list.d.mts +67 -4
  36. package/dist/commands/migration-list.d.mts.map +1 -1
  37. package/dist/commands/migration-list.mjs +2 -103
  38. package/dist/commands/migration-log.d.mts +10 -1
  39. package/dist/commands/migration-log.d.mts.map +1 -1
  40. package/dist/commands/migration-log.mjs +10 -15
  41. package/dist/commands/migration-log.mjs.map +1 -1
  42. package/dist/commands/migration-new.d.mts.map +1 -1
  43. package/dist/commands/migration-new.mjs +32 -38
  44. package/dist/commands/migration-new.mjs.map +1 -1
  45. package/dist/commands/migration-plan.d.mts +3 -2
  46. package/dist/commands/migration-plan.d.mts.map +1 -1
  47. package/dist/commands/migration-plan.mjs +1 -1
  48. package/dist/commands/migration-show.d.mts +4 -55
  49. package/dist/commands/migration-show.d.mts.map +1 -1
  50. package/dist/commands/migration-show.mjs +61 -153
  51. package/dist/commands/migration-show.mjs.map +1 -1
  52. package/dist/commands/migration-status.d.mts +12 -49
  53. package/dist/commands/migration-status.d.mts.map +1 -1
  54. package/dist/commands/migration-status.mjs +85 -81
  55. package/dist/commands/migration-status.mjs.map +1 -1
  56. package/dist/commands/ref.d.mts +1 -1
  57. package/dist/commands/ref.d.mts.map +1 -1
  58. package/dist/commands/ref.mjs +38 -10
  59. package/dist/commands/ref.mjs.map +1 -1
  60. package/dist/config-loader-B6sJjXTv.mjs.map +1 -1
  61. package/dist/config-loader.d.mts.map +1 -1
  62. package/dist/contract-at-errors-Bhf2jnkp.mjs +42 -0
  63. package/dist/contract-at-errors-Bhf2jnkp.mjs.map +1 -0
  64. package/dist/{contract-emit-CmsklifJ.mjs → contract-emit-C47r1loe.mjs} +4 -6
  65. package/dist/{contract-emit-CmsklifJ.mjs.map → contract-emit-C47r1loe.mjs.map} +1 -1
  66. package/dist/{contract-emit-o-8VmdQX.mjs → contract-emit-DxEfEc-M.mjs} +21 -7
  67. package/dist/{contract-emit-o-8VmdQX.mjs.map → contract-emit-DxEfEc-M.mjs.map} +1 -1
  68. package/dist/{contract-enrichment-Dani0mMW.mjs → contract-enrichment-a0V5Y_mL.mjs} +4 -25
  69. package/dist/contract-enrichment-a0V5Y_mL.mjs.map +1 -0
  70. package/dist/{contract-infer-pKkiCt7C.mjs → contract-infer-BLiomU8g.mjs} +3 -4
  71. package/dist/{contract-infer-pKkiCt7C.mjs.map → contract-infer-BLiomU8g.mjs.map} +1 -1
  72. package/dist/contract-space-aggregate-loader-lafgkTwG.mjs +247 -0
  73. package/dist/contract-space-aggregate-loader-lafgkTwG.mjs.map +1 -0
  74. package/dist/{db-verify-AoIUriL4.mjs → db-verify-D44Qj3w9.mjs} +5 -7
  75. package/dist/{db-verify-AoIUriL4.mjs.map → db-verify-D44Qj3w9.mjs.map} +1 -1
  76. package/dist/exports/control-api.d.mts +3 -3
  77. package/dist/exports/control-api.d.mts.map +1 -1
  78. package/dist/exports/control-api.mjs +3 -3
  79. package/dist/exports/index.d.mts.map +1 -1
  80. package/dist/exports/index.mjs +1 -1
  81. package/dist/exports/index.mjs.map +1 -1
  82. package/dist/exports/init-output.d.mts.map +1 -1
  83. package/dist/exports/init-output.mjs +1 -1
  84. package/dist/extension-pack-inputs-IDvjRCi3.mjs +62 -0
  85. package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +1 -0
  86. package/dist/{framework-components-65gOHkHB.mjs → framework-components-R_O3y5IW.mjs} +2 -2
  87. package/dist/{framework-components-65gOHkHB.mjs.map → framework-components-R_O3y5IW.mjs.map} +1 -1
  88. package/dist/global-flags-DG4uY5tV.d.mts +34 -0
  89. package/dist/global-flags-DG4uY5tV.d.mts.map +1 -0
  90. package/dist/{graph-render-DJVv0_uf.mjs → graph-render-rFAqZujX.mjs} +2 -2
  91. package/dist/{graph-render-DJVv0_uf.mjs.map → graph-render-rFAqZujX.mjs.map} +1 -1
  92. package/dist/{init-Db5Itt5r.mjs → init-DE-phHWK.mjs} +4 -5
  93. package/dist/{init-Db5Itt5r.mjs.map → init-DE-phHWK.mjs.map} +1 -1
  94. package/dist/{inspect-live-schema-LeWvkZVz.mjs → inspect-live-schema-Ccnmg5bz.mjs} +4 -5
  95. package/dist/{inspect-live-schema-LeWvkZVz.mjs.map → inspect-live-schema-Ccnmg5bz.mjs.map} +1 -1
  96. package/dist/migration-check-CKfQlAWR.mjs +341 -0
  97. package/dist/migration-check-CKfQlAWR.mjs.map +1 -0
  98. package/dist/migration-cli.d.mts.map +1 -1
  99. package/dist/migration-cli.mjs +4 -4
  100. package/dist/migration-cli.mjs.map +1 -1
  101. package/dist/{migration-command-scaffold-BtkunvFQ.mjs → migration-command-scaffold-C_KuV0Gm.mjs} +4 -5
  102. package/dist/{migration-command-scaffold-BtkunvFQ.mjs.map → migration-command-scaffold-C_KuV0Gm.mjs.map} +1 -1
  103. package/dist/migration-graph-kPluRdF2.mjs +1232 -0
  104. package/dist/migration-graph-kPluRdF2.mjs.map +1 -0
  105. package/dist/migration-list-CE35R5Ag.mjs +505 -0
  106. package/dist/migration-list-CE35R5Ag.mjs.map +1 -0
  107. package/dist/migration-list-styler-DeAwACt3.mjs +402 -0
  108. package/dist/migration-list-styler-DeAwACt3.mjs.map +1 -0
  109. package/dist/{migration-plan-C2jeH1J5.mjs → migration-plan-DHLa2Khm.mjs} +372 -133
  110. package/dist/migration-plan-DHLa2Khm.mjs.map +1 -0
  111. package/dist/{migration-types-BXWvz12q.d.mts → migration-types-CAQ-0TEE.d.mts} +1 -1
  112. package/dist/{migration-types-BXWvz12q.d.mts.map → migration-types-CAQ-0TEE.d.mts.map} +1 -1
  113. package/dist/{migrations-CwZMa1Ck.mjs → migrations-CjO1DsYe.mjs} +12 -13
  114. package/dist/migrations-CjO1DsYe.mjs.map +1 -0
  115. package/dist/{output-BlsrGMEF.mjs → output-CF_hqzI-.mjs} +1 -1
  116. package/dist/{output-BlsrGMEF.mjs.map → output-CF_hqzI-.mjs.map} +1 -1
  117. package/dist/{progress-adapter-DFfvZcYL.mjs → progress-adapter-C644QK8l.mjs} +1 -1
  118. package/dist/{progress-adapter-DFfvZcYL.mjs.map → progress-adapter-C644QK8l.mjs.map} +1 -1
  119. package/dist/ref-advancement-DUZqsue6.mjs +50 -0
  120. package/dist/ref-advancement-DUZqsue6.mjs.map +1 -0
  121. package/dist/terminal-ui-BbtqsQYY.d.mts +133 -0
  122. package/dist/terminal-ui-BbtqsQYY.d.mts.map +1 -0
  123. package/dist/{types-C9FfXb1l.d.mts → types-Ci7TndCS.d.mts} +21 -28
  124. package/dist/types-Ci7TndCS.d.mts.map +1 -0
  125. package/dist/{verify-Bom75OYI.mjs → verify-vl983Ed-.mjs} +2 -2
  126. package/dist/{verify-Bom75OYI.mjs.map → verify-vl983Ed-.mjs.map} +1 -1
  127. package/package.json +11 -11
  128. package/dist/cli-errors-Czmx92Zy.d.mts +0 -3
  129. package/dist/cli-errors-Djtz98Vm.mjs +0 -71
  130. package/dist/cli-errors-Djtz98Vm.mjs.map +0 -1
  131. package/dist/client-oXO2WCPD.mjs.map +0 -1
  132. package/dist/command-helpers-DtavI0wJ.mjs.map +0 -1
  133. package/dist/commands/migration-check.mjs.map +0 -1
  134. package/dist/commands/migration-graph.mjs.map +0 -1
  135. package/dist/commands/migration-list.mjs.map +0 -1
  136. package/dist/contract-enrichment-Dani0mMW.mjs.map +0 -1
  137. package/dist/contract-space-aggregate-loader-BmNQwlws.mjs +0 -160
  138. package/dist/contract-space-aggregate-loader-BmNQwlws.mjs.map +0 -1
  139. package/dist/global-flags-CdE7M0d9.d.mts +0 -15
  140. package/dist/global-flags-CdE7M0d9.d.mts.map +0 -1
  141. package/dist/migration-plan-C2jeH1J5.mjs.map +0 -1
  142. package/dist/migrations-CwZMa1Ck.mjs.map +0 -1
  143. package/dist/rolldown-runtime-twds-ZHy.mjs +0 -14
  144. package/dist/terminal-ui-BiB_8KNo.mjs +0 -379
  145. package/dist/terminal-ui-BiB_8KNo.mjs.map +0 -1
  146. package/dist/types-C9FfXb1l.d.mts.map +0 -1
@@ -0,0 +1,402 @@
1
+ import { bold, cyan, cyanBright, dim, green, yellow } from "colorette";
2
+ import { EMPTY_CONTRACT_HASH } from "@prisma-next/migration-tools/constants";
3
+ //#region src/utils/formatters/migration-list-graph-topology.ts
4
+ function compareDirNameDesc(a, b) {
5
+ return b.dirName.localeCompare(a.dirName);
6
+ }
7
+ function bumpDegree(map, key) {
8
+ map.set(key, (map.get(key) ?? 0) + 1);
9
+ }
10
+ function forwardRootsForDepth(nodes, candidates) {
11
+ const inDegree = /* @__PURE__ */ new Map();
12
+ for (const node of nodes) inDegree.set(node, 0);
13
+ for (const edge of candidates) bumpDegree(inDegree, edge.to);
14
+ const roots = [];
15
+ for (const node of nodes) if ((inDegree.get(node) ?? 0) === 0) roots.push(node);
16
+ roots.sort((a, b) => {
17
+ if (a === EMPTY_CONTRACT_HASH) return -1;
18
+ if (b === EMPTY_CONTRACT_HASH) return 1;
19
+ return a.localeCompare(b);
20
+ });
21
+ if (roots.length > 0) return roots;
22
+ return [...nodes].sort((a, b) => {
23
+ if (a === EMPTY_CONTRACT_HASH) return -1;
24
+ if (b === EMPTY_CONTRACT_HASH) return 1;
25
+ return a.localeCompare(b);
26
+ });
27
+ }
28
+ function longestPathDepths(nodes, candidates) {
29
+ const depth = /* @__PURE__ */ new Map();
30
+ for (const root of forwardRootsForDepth(nodes, candidates)) depth.set(root, 0);
31
+ const maxPasses = nodes.size;
32
+ for (let pass = 0; pass < maxPasses; pass++) {
33
+ let changed = false;
34
+ for (const edge of candidates) {
35
+ const base = depth.get(edge.from);
36
+ if (base === void 0) continue;
37
+ const next = base + 1;
38
+ if (next > (depth.get(edge.to) ?? -1)) {
39
+ depth.set(edge.to, next);
40
+ changed = true;
41
+ }
42
+ }
43
+ if (!changed) break;
44
+ }
45
+ for (const node of nodes) if (!depth.has(node)) depth.set(node, 0);
46
+ return depth;
47
+ }
48
+ function canReachForward(start, goal, candidates) {
49
+ if (start === goal) return true;
50
+ const outgoing = /* @__PURE__ */ new Map();
51
+ for (const edge of candidates) {
52
+ const bucket = outgoing.get(edge.from);
53
+ if (bucket) bucket.push(edge.to);
54
+ else outgoing.set(edge.from, [edge.to]);
55
+ }
56
+ const visited = new Set([start]);
57
+ const queue = [start];
58
+ while (queue.length > 0) {
59
+ const node = queue.shift();
60
+ if (node === void 0) continue;
61
+ for (const next of outgoing.get(node) ?? []) {
62
+ if (next === goal) return true;
63
+ if (!visited.has(next)) {
64
+ visited.add(next);
65
+ queue.push(next);
66
+ }
67
+ }
68
+ }
69
+ return false;
70
+ }
71
+ function isMarginalForwardEdge(nodes, candidates, edge) {
72
+ const depthWithout = longestPathDepths(nodes, candidates.filter((candidate) => candidate !== edge));
73
+ const depthWith = longestPathDepths(nodes, candidates);
74
+ const fromDepth = depthWithout.get(edge.from) ?? 0;
75
+ return (depthWith.get(edge.to) ?? 0) > fromDepth;
76
+ }
77
+ function shouldPeelForwardEdge(nodes, candidates, edge) {
78
+ const without = candidates.filter((candidate) => candidate !== edge);
79
+ const depthWithout = longestPathDepths(nodes, without);
80
+ const fromDepth = depthWithout.get(edge.from) ?? 0;
81
+ const toWithout = depthWithout.get(edge.to) ?? 0;
82
+ if (canReachForward(edge.to, edge.from, without) && fromDepth > toWithout + 1) return true;
83
+ return !isMarginalForwardEdge(nodes, candidates, edge);
84
+ }
85
+ function peelNonMarginalForwardEdges(nodes, kindByMigrationHash, nonSelf) {
86
+ let candidates = nonSelf.filter((edge) => kindByMigrationHash.get(edge.hash) === "forward");
87
+ while (candidates.length > 0) {
88
+ const rollbackCandidates = candidates.filter((edge) => shouldPeelForwardEdge(nodes, candidates, edge));
89
+ if (rollbackCandidates.length === 0) break;
90
+ rollbackCandidates.sort(compareDirNameDesc);
91
+ const rollback = rollbackCandidates[0];
92
+ if (rollback === void 0) break;
93
+ kindByMigrationHash.set(rollback.hash, "rollback");
94
+ candidates = candidates.filter((edge) => edge !== rollback);
95
+ }
96
+ }
97
+ /**
98
+ * DFS with dirName-descending traversal. A GRAY target is a rollback only when it
99
+ * is the immediate DFS parent of the source — cross-links to other GRAY nodes
100
+ * stay forward. A follow-up peel pass drops node-skipping rollbacks (target can
101
+ * reach the source on the forward subgraph and sits more than one rank below).
102
+ */
103
+ function classifyNormalizedEdges(edges) {
104
+ const nodes = /* @__PURE__ */ new Set();
105
+ const kindByMigrationHash = /* @__PURE__ */ new Map();
106
+ const outgoingByFrom = /* @__PURE__ */ new Map();
107
+ const nonSelf = [];
108
+ for (const edge of edges) {
109
+ nodes.add(edge.from);
110
+ nodes.add(edge.to);
111
+ if (edge.from === edge.to) {
112
+ kindByMigrationHash.set(edge.hash, "self");
113
+ continue;
114
+ }
115
+ nonSelf.push(edge);
116
+ const bucket = outgoingByFrom.get(edge.from);
117
+ if (bucket) bucket.push(edge);
118
+ else outgoingByFrom.set(edge.from, [edge]);
119
+ }
120
+ for (const bucket of outgoingByFrom.values()) bucket.sort(compareDirNameDesc);
121
+ const nonSelfInDegree = /* @__PURE__ */ new Map();
122
+ for (const node of nodes) nonSelfInDegree.set(node, 0);
123
+ for (const bucket of outgoingByFrom.values()) for (const edge of bucket) bumpDegree(nonSelfInDegree, edge.to);
124
+ const dfsRoots = [];
125
+ for (const node of nodes) if ((nonSelfInDegree.get(node) ?? 0) === 0) dfsRoots.push(node);
126
+ dfsRoots.sort((a, b) => {
127
+ if (a === EMPTY_CONTRACT_HASH) return -1;
128
+ if (b === EMPTY_CONTRACT_HASH) return 1;
129
+ return a.localeCompare(b);
130
+ });
131
+ if (dfsRoots.length === 0) dfsRoots.push(...[...nodes].sort((a, b) => a.localeCompare(b)));
132
+ const WHITE = 0;
133
+ const GRAY = 1;
134
+ const BLACK = 2;
135
+ const color = /* @__PURE__ */ new Map();
136
+ const dfsParent = /* @__PURE__ */ new Map();
137
+ for (const node of nodes) color.set(node, WHITE);
138
+ const stack = [];
139
+ function isImmediateDfsParent(ancestor, node) {
140
+ return dfsParent.get(node) === ancestor;
141
+ }
142
+ function pushFrame(node, parent) {
143
+ color.set(node, GRAY);
144
+ dfsParent.set(node, parent);
145
+ stack.push({
146
+ node,
147
+ outgoing: outgoingByFrom.get(node) ?? [],
148
+ index: 0
149
+ });
150
+ }
151
+ function runDfsFrom(root) {
152
+ if (color.get(root) !== WHITE) return;
153
+ pushFrame(root, void 0);
154
+ while (stack.length > 0) {
155
+ const frame = stack[stack.length - 1];
156
+ if (frame === void 0) break;
157
+ if (frame.index >= frame.outgoing.length) {
158
+ color.set(frame.node, BLACK);
159
+ stack.pop();
160
+ continue;
161
+ }
162
+ const edge = frame.outgoing[frame.index];
163
+ frame.index += 1;
164
+ if (edge === void 0) continue;
165
+ const v = edge.to;
166
+ const vColor = color.get(v);
167
+ if (vColor === GRAY && isImmediateDfsParent(v, frame.node)) kindByMigrationHash.set(edge.hash, "rollback");
168
+ else {
169
+ kindByMigrationHash.set(edge.hash, "forward");
170
+ if (vColor === WHITE) pushFrame(v, frame.node);
171
+ }
172
+ }
173
+ }
174
+ for (const root of dfsRoots) runDfsFrom(root);
175
+ const remainingWhite = [...nodes].filter((node) => color.get(node) === WHITE);
176
+ remainingWhite.sort((a, b) => a.localeCompare(b));
177
+ for (const root of remainingWhite) runDfsFrom(root);
178
+ peelNonMarginalForwardEdges(nodes, kindByMigrationHash, nonSelf);
179
+ const forwardInDegree = /* @__PURE__ */ new Map();
180
+ const forwardOutDegree = /* @__PURE__ */ new Map();
181
+ for (const edge of edges) {
182
+ if (kindByMigrationHash.get(edge.hash) !== "forward") continue;
183
+ bumpDegree(forwardOutDegree, edge.from);
184
+ bumpDegree(forwardInDegree, edge.to);
185
+ }
186
+ return {
187
+ kindByMigrationHash,
188
+ forwardInDegree,
189
+ forwardOutDegree
190
+ };
191
+ }
192
+ function canonicalFrom(from) {
193
+ return from ?? EMPTY_CONTRACT_HASH;
194
+ }
195
+ /**
196
+ * Classify forward/rollback/self for a Tier-2 `MigrationListEntry[]` edge set.
197
+ * Returns the kind of each migration plus the forward in/out degree of each
198
+ * contract node. This is the established Tier-2 surface; its behaviour is
199
+ * unchanged — only its implementation now delegates to the shared classifier.
200
+ */
201
+ function classifyMigrationListGraphTopology(entries) {
202
+ return classifyNormalizedEdges(entries.map((entry) => ({
203
+ hash: entry.migrationHash,
204
+ from: canonicalFrom(entry.from),
205
+ to: entry.to,
206
+ dirName: entry.dirName
207
+ })));
208
+ }
209
+ /**
210
+ * Classify forward/rollback/self for a `MigrationGraph` edge set (Tier-3).
211
+ * Delegates to the same shared classifier as `classifyMigrationListGraphTopology`
212
+ * so both tiers agree on forward/rollback/self without duplicating logic.
213
+ */
214
+ function classifyMigrationGraphTopology(graph) {
215
+ const normalized = [];
216
+ for (const edges of graph.forwardChain.values()) for (const edge of edges) normalized.push({
217
+ hash: edge.migrationHash,
218
+ from: edge.from,
219
+ to: edge.to,
220
+ dirName: edge.dirName
221
+ });
222
+ return classifyNormalizedEdges(normalized);
223
+ }
224
+ const MIGRATION_LIST_UNICODE_KIND_GLYPH = {
225
+ forward: "*",
226
+ rollback: "↩",
227
+ self: "⟲"
228
+ };
229
+ const MIGRATION_LIST_ASCII_KIND_GLYPH = {
230
+ forward: "*",
231
+ rollback: "<",
232
+ self: "~"
233
+ };
234
+ function migrationListKindGlyph(glyphMode, edgeKind) {
235
+ return glyphMode === "ascii" ? MIGRATION_LIST_ASCII_KIND_GLYPH[edgeKind] : MIGRATION_LIST_UNICODE_KIND_GLYPH[edgeKind];
236
+ }
237
+ function migrationListForwardArrow(glyphMode) {
238
+ return glyphMode === "ascii" ? "->" : "→";
239
+ }
240
+ function migrationListEmptySource(glyphMode) {
241
+ return glyphMode === "ascii" ? "-" : "∅";
242
+ }
243
+ function abbreviateContractHash(hash) {
244
+ return (hash.startsWith("sha256:") ? hash.slice(7) : hash).slice(0, 7);
245
+ }
246
+ function computeMigrationDirNameWidth(migrations) {
247
+ if (migrations.length === 0) return 0;
248
+ return Math.max(...migrations.map((entry) => entry.dirName.length)) + 2;
249
+ }
250
+ function formatSourceColumn(from, style, emptySource) {
251
+ if (from === null) return style.glyph(emptySource) + " ".repeat(7 - emptySource.length);
252
+ return style.sourceHash(abbreviateContractHash(from));
253
+ }
254
+ function formatDecorations(providedInvariants, refs, style) {
255
+ const blocks = [];
256
+ if (providedInvariants.length > 0) blocks.push(style.invariants(providedInvariants));
257
+ if (refs.length > 0) blocks.push(style.refs(refs));
258
+ if (blocks.length === 0) return "";
259
+ return ` ${blocks.join(" ")}`;
260
+ }
261
+ function formatMigrationDataColumn(migration, options) {
262
+ const { dirNameWidth, edgeKind, style, forwardArrow = "→", emptySource = "∅" } = options;
263
+ const dirNamePadding = " ".repeat(Math.max(0, dirNameWidth - migration.dirName.length));
264
+ const dirName = `${style.dirName(migration.dirName)}${dirNamePadding}`;
265
+ const decorations = formatDecorations(migration.providedInvariants, migration.refs, style);
266
+ if (edgeKind === "self") {
267
+ const contractHash = migration.from ?? migration.to;
268
+ return `${dirName}${style.sourceHash(abbreviateContractHash(contractHash))}${decorations}`;
269
+ }
270
+ return `${dirName}${formatSourceColumn(migration.from, style, emptySource)} ${style.glyph(forwardArrow)} ${style.destHash(abbreviateContractHash(migration.to))}${decorations}`;
271
+ }
272
+ function formatNodeLineDataColumn(contractHash, style) {
273
+ return style.sourceHash(abbreviateContractHash(contractHash));
274
+ }
275
+ //#endregion
276
+ //#region src/utils/formatters/migration-list-render.ts
277
+ const IDENTITY_MIGRATION_LIST_STYLER = {
278
+ kind: (text) => text,
279
+ dirName: (text) => text,
280
+ sourceHash: (text) => text,
281
+ destHash: (text) => text,
282
+ glyph: (text) => text,
283
+ lane: (text) => text,
284
+ invariants: (ids) => `{${ids.join(", ")}}`,
285
+ refs: (names) => `(${names.join(", ")})`,
286
+ spaceHeading: (text) => text,
287
+ summary: (text) => text,
288
+ emptyState: (text) => text
289
+ };
290
+ function resolveEdgeKind(migrationHash, kindByMigrationHash) {
291
+ return kindByMigrationHash.get(migrationHash) ?? "forward";
292
+ }
293
+ function formatMigrationRow(migration, dirNameWidth, edgeKind, glyphMode, style) {
294
+ return `${`${style.kind(migrationListKindGlyph(glyphMode, edgeKind))} `}${formatMigrationDataColumn(migration, {
295
+ dirNameWidth,
296
+ edgeKind,
297
+ style,
298
+ forwardArrow: migrationListForwardArrow(glyphMode),
299
+ emptySource: migrationListEmptySource(glyphMode)
300
+ })}`;
301
+ }
302
+ function formatEmptyStateLine(spaceId, style) {
303
+ return style.emptyState(`There are no migrations in migrations/${spaceId}/ yet`);
304
+ }
305
+ function renderSpaceBlock(spaceId, migrations, multiSpace, glyphMode, kindByMigrationHash, style) {
306
+ if (migrations.length === 0) {
307
+ const emptyLine = formatEmptyStateLine(spaceId, style);
308
+ if (!multiSpace) return [emptyLine];
309
+ return [style.spaceHeading(`${spaceId}:`), ` ${emptyLine}`];
310
+ }
311
+ const dirNameWidth = computeMigrationDirNameWidth(migrations);
312
+ const rows = migrations.map((entry) => formatMigrationRow(entry, dirNameWidth, resolveEdgeKind(entry.migrationHash, kindByMigrationHash), glyphMode, style));
313
+ if (!multiSpace) return rows;
314
+ return [style.spaceHeading(`${spaceId}:`), ...rows.map((row) => ` ${row}`)];
315
+ }
316
+ function buildMigrationListTopologyBySpace(result) {
317
+ const topologyBySpaceId = /* @__PURE__ */ new Map();
318
+ for (const space of result.spaces) topologyBySpaceId.set(space.spaceId, classifyMigrationListGraphTopology(space.migrations));
319
+ return topologyBySpaceId;
320
+ }
321
+ /**
322
+ * Compose the styled `migration list` output. The renderer is
323
+ * presentation-neutral — every token passes through `style` before
324
+ * landing in the output, so the same composition serves the pure-text
325
+ * path ({@link renderMigrationList} via
326
+ * {@link IDENTITY_MIGRATION_LIST_STYLER}) and the ANSI-styled CLI path
327
+ * (via the ANSI styler the CLI shell wires up).
328
+ */
329
+ function renderMigrationListWithStyle(result, style, glyphMode = "unicode", topologyBySpaceId = buildMigrationListTopologyBySpace(result)) {
330
+ const multiSpace = result.spaces.length > 1;
331
+ const lines = [];
332
+ for (let index = 0; index < result.spaces.length; index++) {
333
+ const space = result.spaces[index];
334
+ if (index > 0) lines.push("");
335
+ const kindByMigrationHash = topologyBySpaceId.get(space.spaceId)?.kindByMigrationHash ?? classifyMigrationListGraphTopology(space.migrations).kindByMigrationHash;
336
+ lines.push(...renderSpaceBlock(space.spaceId, space.migrations, multiSpace, glyphMode, kindByMigrationHash, style));
337
+ }
338
+ if (result.spaces.reduce((count, space) => count + space.migrations.length, 0) > 0) {
339
+ lines.push("");
340
+ lines.push(style.summary(result.summary));
341
+ }
342
+ return lines.join("\n");
343
+ }
344
+ //#endregion
345
+ //#region src/utils/formatters/migration-list-styler.ts
346
+ /**
347
+ * The current contract overlay marker. Unlike user refs, this names the user's
348
+ * declared desired state — the implicit base/target for `plan` / `migrate` —
349
+ * not a stored label. It is emphasized (bold) so it stands out from plain refs
350
+ * (including the live-database `db` marker, which is just another ref).
351
+ */
352
+ const CONTRACT_MARKER_NAME = "contract";
353
+ function styleRefName(name) {
354
+ return name === "contract" ? bold(green(name)) : green(name);
355
+ }
356
+ /**
357
+ * Build a {@link MigrationListStyler} that decorates `migration list`
358
+ * tokens with ANSI SGR codes. When `useColor` is `false` (non-TTY,
359
+ * `--no-color`, `NO_COLOR=1`, piped output) the function returns the
360
+ * shared identity styler so callers get plain text with zero ANSI
361
+ * bytes — pipe-friendly by construction.
362
+ *
363
+ * Palette:
364
+ *
365
+ * - `dirName`: bold
366
+ * - `sourceHash`: dim cyan
367
+ * - `destHash`: bright cyan
368
+ * - `kind` (`*` / `↩` / `⟲`): bright — the signal; lanes and arrows dim
369
+ * - `glyph` (`→` / `⟲` / `∅`): dim
370
+ * - `lane` (graph gutter lines `│` and fan/join connectors `├─┐` / `├─┘`): dim
371
+ * - `invariants` (`{...}`): yellow
372
+ * - `refs` (`(...)`): green; the `contract` desired-state marker inside is
373
+ * green-bold (the active ref is bolded separately by the tree styler)
374
+ * - `spaceHeading` (`<spaceId>:`): bold
375
+ * - `summary`: dim
376
+ * - `emptyState`: dim
377
+ */
378
+ function createAnsiMigrationListStyler(opts) {
379
+ if (!opts.useColor) return IDENTITY_MIGRATION_LIST_STYLER;
380
+ return {
381
+ kind: (text) => text,
382
+ dirName: (text) => bold(text),
383
+ sourceHash: (text) => dim(cyan(text)),
384
+ destHash: (text) => cyanBright(text),
385
+ glyph: (text) => dim(text),
386
+ lane: (text) => dim(text),
387
+ invariants: (ids) => yellow(`{${ids.join(", ")}}`),
388
+ refs: (names) => {
389
+ const open = green("(");
390
+ const close = green(")");
391
+ const separator = green(", ");
392
+ return open + names.map(styleRefName).join(separator) + close;
393
+ },
394
+ spaceHeading: (text) => bold(text),
395
+ summary: (text) => dim(text),
396
+ emptyState: (text) => dim(text)
397
+ };
398
+ }
399
+ //#endregion
400
+ export { MIGRATION_LIST_ASCII_KIND_GLYPH as a, formatMigrationDataColumn as c, migrationListForwardArrow as d, classifyMigrationGraphTopology as f, renderMigrationListWithStyle as i, formatNodeLineDataColumn as l, createAnsiMigrationListStyler as n, MIGRATION_LIST_UNICODE_KIND_GLYPH as o, classifyMigrationListGraphTopology as p, buildMigrationListTopologyBySpace as r, computeMigrationDirNameWidth as s, CONTRACT_MARKER_NAME as t, migrationListEmptySource as u };
401
+
402
+ //# sourceMappingURL=migration-list-styler-DeAwACt3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-list-styler-DeAwACt3.mjs","names":[],"sources":["../src/utils/formatters/migration-list-graph-topology.ts","../src/utils/formatters/migration-list-data-column.ts","../src/utils/formatters/migration-list-render.ts","../src/utils/formatters/migration-list-styler.ts"],"sourcesContent":["import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';\nimport type { MigrationGraph } from '@prisma-next/migration-tools/graph';\nimport type { MigrationListEntry } from './migration-list-types';\n\nexport type MigrationEdgeKind = 'forward' | 'rollback' | 'self';\n\nexport interface MigrationListGraphTopology {\n readonly kindByMigrationHash: ReadonlyMap<string, MigrationEdgeKind>;\n readonly forwardInDegree: ReadonlyMap<string, number>;\n readonly forwardOutDegree: ReadonlyMap<string, number>;\n}\n\n// ---------------------------------------------------------------------------\n// Shared classifier — operates on a normalized edge shape common to both\n// MigrationListEntry (Tier-2) and MigrationEdge / MigrationGraph (Tier-3).\n// ---------------------------------------------------------------------------\n\ninterface NormalizedEdge {\n readonly hash: string;\n readonly from: string;\n readonly to: string;\n readonly dirName: string;\n}\n\nfunction compareDirNameDesc(a: NormalizedEdge, b: NormalizedEdge): number {\n return b.dirName.localeCompare(a.dirName);\n}\n\nfunction bumpDegree(map: Map<string, number>, key: string): void {\n map.set(key, (map.get(key) ?? 0) + 1);\n}\n\nfunction forwardRootsForDepth(\n nodes: ReadonlySet<string>,\n candidates: readonly NormalizedEdge[],\n): readonly string[] {\n const inDegree = new Map<string, number>();\n for (const node of nodes) {\n inDegree.set(node, 0);\n }\n for (const edge of candidates) {\n bumpDegree(inDegree, edge.to);\n }\n\n const roots: string[] = [];\n for (const node of nodes) {\n if ((inDegree.get(node) ?? 0) === 0) {\n roots.push(node);\n }\n }\n roots.sort((a, b) => {\n if (a === EMPTY_CONTRACT_HASH) return -1;\n if (b === EMPTY_CONTRACT_HASH) return 1;\n return a.localeCompare(b);\n });\n if (roots.length > 0) return roots;\n\n return [...nodes].sort((a, b) => {\n if (a === EMPTY_CONTRACT_HASH) return -1;\n if (b === EMPTY_CONTRACT_HASH) return 1;\n return a.localeCompare(b);\n });\n}\n\nfunction longestPathDepths(\n nodes: ReadonlySet<string>,\n candidates: readonly NormalizedEdge[],\n): Map<string, number> {\n const depth = new Map<string, number>();\n for (const root of forwardRootsForDepth(nodes, candidates)) {\n depth.set(root, 0);\n }\n\n const maxPasses = nodes.size;\n for (let pass = 0; pass < maxPasses; pass++) {\n let changed = false;\n for (const edge of candidates) {\n const base = depth.get(edge.from);\n if (base === undefined) continue;\n const next = base + 1;\n if (next > (depth.get(edge.to) ?? -1)) {\n depth.set(edge.to, next);\n changed = true;\n }\n }\n if (!changed) break;\n }\n\n for (const node of nodes) {\n if (!depth.has(node)) {\n depth.set(node, 0);\n }\n }\n\n return depth;\n}\n\nfunction canReachForward(\n start: string,\n goal: string,\n candidates: readonly NormalizedEdge[],\n): boolean {\n if (start === goal) return true;\n\n const outgoing = new Map<string, string[]>();\n for (const edge of candidates) {\n const bucket = outgoing.get(edge.from);\n if (bucket) bucket.push(edge.to);\n else outgoing.set(edge.from, [edge.to]);\n }\n\n const visited = new Set<string>([start]);\n const queue = [start];\n while (queue.length > 0) {\n const node = queue.shift();\n if (node === undefined) continue;\n for (const next of outgoing.get(node) ?? []) {\n if (next === goal) return true;\n if (!visited.has(next)) {\n visited.add(next);\n queue.push(next);\n }\n }\n }\n\n return false;\n}\n\nfunction isMarginalForwardEdge(\n nodes: ReadonlySet<string>,\n candidates: readonly NormalizedEdge[],\n edge: NormalizedEdge,\n): boolean {\n const without = candidates.filter((candidate) => candidate !== edge);\n const depthWithout = longestPathDepths(nodes, without);\n const depthWith = longestPathDepths(nodes, candidates);\n const fromDepth = depthWithout.get(edge.from) ?? 0;\n const toWith = depthWith.get(edge.to) ?? 0;\n return toWith > fromDepth;\n}\n\n// The first branch is the load-bearing one: a forward edge `from → to` is a\n// disguised node-skipping rollback when, after removing it, `to` can still\n// reach `from` and `from` sits strictly deeper than `to + 1` (a longer path\n// already connects them). This branch fires on every cycle-closing edge, and\n// the caller peels exactly one edge (dirName-max) per iteration before\n// recomputing — so cycles are broken deterministically regardless of edge\n// order. `isMarginalForwardEdge` is only a fallback for the residual case and\n// is reached only while the candidate set is still cyclic.\nfunction shouldPeelForwardEdge(\n nodes: ReadonlySet<string>,\n candidates: readonly NormalizedEdge[],\n edge: NormalizedEdge,\n): boolean {\n const without = candidates.filter((candidate) => candidate !== edge);\n const depthWithout = longestPathDepths(nodes, without);\n const fromDepth = depthWithout.get(edge.from) ?? 0;\n const toWithout = depthWithout.get(edge.to) ?? 0;\n\n if (canReachForward(edge.to, edge.from, without) && fromDepth > toWithout + 1) {\n return true;\n }\n\n return !isMarginalForwardEdge(nodes, candidates, edge);\n}\n\nfunction peelNonMarginalForwardEdges(\n nodes: ReadonlySet<string>,\n kindByMigrationHash: Map<string, MigrationEdgeKind>,\n nonSelf: readonly NormalizedEdge[],\n): void {\n let candidates = nonSelf.filter((edge) => kindByMigrationHash.get(edge.hash) === 'forward');\n\n while (candidates.length > 0) {\n const rollbackCandidates = candidates.filter((edge) =>\n shouldPeelForwardEdge(nodes, candidates, edge),\n );\n if (rollbackCandidates.length === 0) break;\n\n rollbackCandidates.sort(compareDirNameDesc);\n const rollback = rollbackCandidates[0];\n if (rollback === undefined) break;\n\n kindByMigrationHash.set(rollback.hash, 'rollback');\n candidates = candidates.filter((edge) => edge !== rollback);\n }\n}\n\n/**\n * DFS with dirName-descending traversal. A GRAY target is a rollback only when it\n * is the immediate DFS parent of the source — cross-links to other GRAY nodes\n * stay forward. A follow-up peel pass drops node-skipping rollbacks (target can\n * reach the source on the forward subgraph and sits more than one rank below).\n */\nfunction classifyNormalizedEdges(edges: readonly NormalizedEdge[]): MigrationListGraphTopology {\n const nodes = new Set<string>();\n const kindByMigrationHash = new Map<string, MigrationEdgeKind>();\n const outgoingByFrom = new Map<string, NormalizedEdge[]>();\n const nonSelf: NormalizedEdge[] = [];\n\n for (const edge of edges) {\n nodes.add(edge.from);\n nodes.add(edge.to);\n\n if (edge.from === edge.to) {\n kindByMigrationHash.set(edge.hash, 'self');\n continue;\n }\n\n nonSelf.push(edge);\n const bucket = outgoingByFrom.get(edge.from);\n if (bucket) bucket.push(edge);\n else outgoingByFrom.set(edge.from, [edge]);\n }\n\n for (const bucket of outgoingByFrom.values()) {\n bucket.sort(compareDirNameDesc);\n }\n\n const nonSelfInDegree = new Map<string, number>();\n for (const node of nodes) {\n nonSelfInDegree.set(node, 0);\n }\n for (const bucket of outgoingByFrom.values()) {\n for (const edge of bucket) {\n bumpDegree(nonSelfInDegree, edge.to);\n }\n }\n\n const dfsRoots: string[] = [];\n for (const node of nodes) {\n if ((nonSelfInDegree.get(node) ?? 0) === 0) {\n dfsRoots.push(node);\n }\n }\n dfsRoots.sort((a, b) => {\n if (a === EMPTY_CONTRACT_HASH) return -1;\n if (b === EMPTY_CONTRACT_HASH) return 1;\n return a.localeCompare(b);\n });\n if (dfsRoots.length === 0) {\n dfsRoots.push(...[...nodes].sort((a, b) => a.localeCompare(b)));\n }\n\n const WHITE = 0;\n const GRAY = 1;\n const BLACK = 2;\n const color = new Map<string, number>();\n const dfsParent = new Map<string, string | undefined>();\n for (const node of nodes) {\n color.set(node, WHITE);\n }\n\n interface Frame {\n node: string;\n outgoing: readonly NormalizedEdge[];\n index: number;\n }\n const stack: Frame[] = [];\n\n function isImmediateDfsParent(ancestor: string, node: string): boolean {\n return dfsParent.get(node) === ancestor;\n }\n\n function pushFrame(node: string, parent: string | undefined): void {\n color.set(node, GRAY);\n dfsParent.set(node, parent);\n stack.push({ node, outgoing: outgoingByFrom.get(node) ?? [], index: 0 });\n }\n\n function runDfsFrom(root: string): void {\n if (color.get(root) !== WHITE) return;\n pushFrame(root, undefined);\n\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n if (frame === undefined) break;\n if (frame.index >= frame.outgoing.length) {\n color.set(frame.node, BLACK);\n stack.pop();\n continue;\n }\n\n const edge = frame.outgoing[frame.index];\n frame.index += 1;\n if (edge === undefined) continue;\n\n const v = edge.to;\n const vColor = color.get(v);\n if (vColor === GRAY && isImmediateDfsParent(v, frame.node)) {\n kindByMigrationHash.set(edge.hash, 'rollback');\n } else {\n kindByMigrationHash.set(edge.hash, 'forward');\n if (vColor === WHITE) {\n pushFrame(v, frame.node);\n }\n }\n }\n }\n\n for (const root of dfsRoots) {\n runDfsFrom(root);\n }\n const remainingWhite = [...nodes].filter((node) => color.get(node) === WHITE);\n remainingWhite.sort((a, b) => a.localeCompare(b));\n for (const root of remainingWhite) {\n runDfsFrom(root);\n }\n\n peelNonMarginalForwardEdges(nodes, kindByMigrationHash, nonSelf);\n\n const forwardInDegree = new Map<string, number>();\n const forwardOutDegree = new Map<string, number>();\n\n for (const edge of edges) {\n if (kindByMigrationHash.get(edge.hash) !== 'forward') continue;\n bumpDegree(forwardOutDegree, edge.from);\n bumpDegree(forwardInDegree, edge.to);\n }\n\n return {\n kindByMigrationHash,\n forwardInDegree,\n forwardOutDegree,\n };\n}\n\nfunction canonicalFrom(from: string | null): string {\n return from ?? EMPTY_CONTRACT_HASH;\n}\n\n/**\n * Classify forward/rollback/self for a Tier-2 `MigrationListEntry[]` edge set.\n * Returns the kind of each migration plus the forward in/out degree of each\n * contract node. This is the established Tier-2 surface; its behaviour is\n * unchanged — only its implementation now delegates to the shared classifier.\n */\nexport function classifyMigrationListGraphTopology(\n entries: readonly MigrationListEntry[],\n): MigrationListGraphTopology {\n const normalized: NormalizedEdge[] = entries.map((entry) => ({\n hash: entry.migrationHash,\n from: canonicalFrom(entry.from),\n to: entry.to,\n dirName: entry.dirName,\n }));\n return classifyNormalizedEdges(normalized);\n}\n\n/**\n * Classify forward/rollback/self for a `MigrationGraph` edge set (Tier-3).\n * Delegates to the same shared classifier as `classifyMigrationListGraphTopology`\n * so both tiers agree on forward/rollback/self without duplicating logic.\n */\nexport function classifyMigrationGraphTopology(graph: MigrationGraph): MigrationListGraphTopology {\n const normalized: NormalizedEdge[] = [];\n for (const edges of graph.forwardChain.values()) {\n for (const edge of edges) {\n normalized.push({\n hash: edge.migrationHash,\n from: edge.from,\n to: edge.to,\n dirName: edge.dirName,\n });\n }\n }\n return classifyNormalizedEdges(normalized);\n}\n","import type { GlyphMode } from '../glyph-mode';\nimport type { MigrationEdgeKind } from './migration-list-graph-topology';\nimport type { MigrationListStyler } from './migration-list-render';\nimport type { MigrationListEntry } from './migration-list-types';\n\nexport const MIGRATION_LIST_HASH_WIDTH = 7;\nexport const MIGRATION_LIST_EMPTY_SOURCE = '∅';\nexport const MIGRATION_LIST_ASCII_EMPTY_SOURCE = '-';\nexport const MIGRATION_LIST_FORWARD_EDGE_GLYPH = '→';\nexport const MIGRATION_LIST_ASCII_FORWARD_EDGE_GLYPH = '->';\nexport const MIGRATION_LIST_DECORATION_PREFIX = ' ';\n\nexport const MIGRATION_LIST_UNICODE_KIND_GLYPH: Record<MigrationEdgeKind, string> = {\n forward: '*',\n rollback: '↩',\n self: '⟲',\n};\n\nexport const MIGRATION_LIST_ASCII_KIND_GLYPH: Record<MigrationEdgeKind, string> = {\n forward: '*',\n rollback: '<',\n self: '~',\n};\n\nexport function migrationListKindGlyph(glyphMode: GlyphMode, edgeKind: MigrationEdgeKind): string {\n return glyphMode === 'ascii'\n ? MIGRATION_LIST_ASCII_KIND_GLYPH[edgeKind]\n : MIGRATION_LIST_UNICODE_KIND_GLYPH[edgeKind];\n}\n\nexport function migrationListForwardArrow(glyphMode: GlyphMode): string {\n return glyphMode === 'ascii'\n ? MIGRATION_LIST_ASCII_FORWARD_EDGE_GLYPH\n : MIGRATION_LIST_FORWARD_EDGE_GLYPH;\n}\n\nexport function migrationListEmptySource(glyphMode: GlyphMode): string {\n return glyphMode === 'ascii' ? MIGRATION_LIST_ASCII_EMPTY_SOURCE : MIGRATION_LIST_EMPTY_SOURCE;\n}\n\nexport function abbreviateContractHash(hash: string): string {\n const stripped = hash.startsWith('sha256:') ? hash.slice(7) : hash;\n return stripped.slice(0, MIGRATION_LIST_HASH_WIDTH);\n}\n\nexport function computeMigrationDirNameWidth(migrations: readonly MigrationListEntry[]): number {\n if (migrations.length === 0) return 0;\n return Math.max(...migrations.map((entry) => entry.dirName.length)) + 2;\n}\n\nfunction formatSourceColumn(\n from: string | null,\n style: MigrationListStyler,\n emptySource: string,\n): string {\n if (from === null) {\n return style.glyph(emptySource) + ' '.repeat(MIGRATION_LIST_HASH_WIDTH - emptySource.length);\n }\n return style.sourceHash(abbreviateContractHash(from));\n}\n\nexport function formatDecorations(\n providedInvariants: readonly string[],\n refs: readonly string[],\n style: MigrationListStyler,\n): string {\n const blocks: string[] = [];\n if (providedInvariants.length > 0) {\n blocks.push(style.invariants(providedInvariants));\n }\n if (refs.length > 0) {\n blocks.push(style.refs(refs));\n }\n if (blocks.length === 0) return '';\n return `${MIGRATION_LIST_DECORATION_PREFIX}${blocks.join(' ')}`;\n}\n\nexport interface MigrationDataColumnOptions {\n readonly dirNameWidth: number;\n readonly edgeKind: MigrationEdgeKind;\n readonly style: MigrationListStyler;\n readonly forwardArrow?: string;\n readonly emptySource?: string;\n}\n\nexport function formatMigrationDataColumn(\n migration: MigrationListEntry,\n options: MigrationDataColumnOptions,\n): string {\n const {\n dirNameWidth,\n edgeKind,\n style,\n forwardArrow = MIGRATION_LIST_FORWARD_EDGE_GLYPH,\n emptySource = MIGRATION_LIST_EMPTY_SOURCE,\n } = options;\n const dirNamePadding = ' '.repeat(Math.max(0, dirNameWidth - migration.dirName.length));\n const dirName = `${style.dirName(migration.dirName)}${dirNamePadding}`;\n const decorations = formatDecorations(migration.providedInvariants, migration.refs, style);\n\n if (edgeKind === 'self') {\n const contractHash = migration.from ?? migration.to;\n const hash = style.sourceHash(abbreviateContractHash(contractHash));\n return `${dirName}${hash}${decorations}`;\n }\n\n const source = formatSourceColumn(migration.from, style, emptySource);\n const arrow = style.glyph(forwardArrow);\n const dest = style.destHash(abbreviateContractHash(migration.to));\n return `${dirName}${source} ${arrow} ${dest}${decorations}`;\n}\n\nexport function formatNodeLineDataColumn(contractHash: string, style: MigrationListStyler): string {\n return style.sourceHash(abbreviateContractHash(contractHash));\n}\n","import type { GlyphMode } from '../glyph-mode';\nimport {\n computeMigrationDirNameWidth,\n formatMigrationDataColumn,\n migrationListEmptySource,\n migrationListForwardArrow,\n migrationListKindGlyph,\n} from './migration-list-data-column';\nimport {\n classifyMigrationListGraphTopology,\n type MigrationEdgeKind,\n type MigrationListGraphTopology,\n} from './migration-list-graph-topology';\nimport type { MigrationListEntry, MigrationListResult } from './migration-list-types';\n\nexport type { GlyphMode } from '../glyph-mode';\nexport type { MigrationEdgeKind } from './migration-list-graph-topology';\nexport type {\n MigrationListEntry,\n MigrationListResult,\n MigrationSpaceListEntry,\n} from './migration-list-types';\n\n/**\n * Semantic styler for `migration list` output tokens. Token-typed so\n * the renderer composes presentation-neutral fragments and the styler\n * decides how each token kind is decorated (ANSI codes, plain text,\n * etc.). The renderer pads with raw spaces *outside* styled tokens so\n * visible column widths stay stable regardless of what the styler\n * emits — adding ANSI escape sequences never disturbs alignment.\n *\n * `invariants` and `refs` receive the underlying string arrays rather\n * than a pre-joined string so per-element styling (e.g. distinguishing\n * the live-DB `db` marker from user-named refs) is possible without\n * having to re-parse a joined block.\n */\nexport interface MigrationListStyler {\n kind(text: string): string;\n dirName(text: string): string;\n sourceHash(text: string): string;\n destHash(text: string): string;\n glyph(text: string): string;\n lane(text: string): string;\n invariants(ids: readonly string[]): string;\n refs(names: readonly string[]): string;\n spaceHeading(text: string): string;\n summary(text: string): string;\n emptyState(text: string): string;\n}\n\nexport const IDENTITY_MIGRATION_LIST_STYLER: MigrationListStyler = {\n kind: (text) => text,\n dirName: (text) => text,\n sourceHash: (text) => text,\n destHash: (text) => text,\n glyph: (text) => text,\n lane: (text) => text,\n invariants: (ids) => `{${ids.join(', ')}}`,\n refs: (names) => `(${names.join(', ')})`,\n spaceHeading: (text) => text,\n summary: (text) => text,\n emptyState: (text) => text,\n};\n\nfunction resolveEdgeKind(\n migrationHash: string,\n kindByMigrationHash: ReadonlyMap<string, MigrationEdgeKind>,\n): MigrationEdgeKind {\n return kindByMigrationHash.get(migrationHash) ?? 'forward';\n}\n\nfunction formatMigrationRow(\n migration: MigrationListEntry,\n dirNameWidth: number,\n edgeKind: MigrationEdgeKind,\n glyphMode: GlyphMode,\n style: MigrationListStyler,\n): string {\n const kindColumn = `${style.kind(migrationListKindGlyph(glyphMode, edgeKind))} `;\n const data = formatMigrationDataColumn(migration, {\n dirNameWidth,\n edgeKind,\n style,\n forwardArrow: migrationListForwardArrow(glyphMode),\n emptySource: migrationListEmptySource(glyphMode),\n });\n return `${kindColumn}${data}`;\n}\n\nfunction formatEmptyStateLine(spaceId: string, style: MigrationListStyler): string {\n return style.emptyState(`There are no migrations in migrations/${spaceId}/ yet`);\n}\n\nfunction renderSpaceBlock(\n spaceId: string,\n migrations: readonly MigrationListEntry[],\n multiSpace: boolean,\n glyphMode: GlyphMode,\n kindByMigrationHash: ReadonlyMap<string, MigrationEdgeKind>,\n style: MigrationListStyler,\n): readonly string[] {\n if (migrations.length === 0) {\n const emptyLine = formatEmptyStateLine(spaceId, style);\n if (!multiSpace) {\n return [emptyLine];\n }\n return [style.spaceHeading(`${spaceId}:`), ` ${emptyLine}`];\n }\n\n const dirNameWidth = computeMigrationDirNameWidth(migrations);\n const rows = migrations.map((entry) =>\n formatMigrationRow(\n entry,\n dirNameWidth,\n resolveEdgeKind(entry.migrationHash, kindByMigrationHash),\n glyphMode,\n style,\n ),\n );\n if (!multiSpace) {\n return rows;\n }\n return [style.spaceHeading(`${spaceId}:`), ...rows.map((row) => ` ${row}`)];\n}\n\nexport function buildMigrationListTopologyBySpace(\n result: MigrationListResult,\n): ReadonlyMap<string, MigrationListGraphTopology> {\n const topologyBySpaceId = new Map<string, MigrationListGraphTopology>();\n for (const space of result.spaces) {\n topologyBySpaceId.set(space.spaceId, classifyMigrationListGraphTopology(space.migrations));\n }\n return topologyBySpaceId;\n}\n\n/**\n * Compose the styled `migration list` output. The renderer is\n * presentation-neutral — every token passes through `style` before\n * landing in the output, so the same composition serves the pure-text\n * path ({@link renderMigrationList} via\n * {@link IDENTITY_MIGRATION_LIST_STYLER}) and the ANSI-styled CLI path\n * (via the ANSI styler the CLI shell wires up).\n */\nexport function renderMigrationListWithStyle(\n result: MigrationListResult,\n style: MigrationListStyler,\n glyphMode: GlyphMode = 'unicode',\n topologyBySpaceId: ReadonlyMap<\n string,\n MigrationListGraphTopology\n > = buildMigrationListTopologyBySpace(result),\n): string {\n const multiSpace = result.spaces.length > 1;\n const lines: string[] = [];\n\n for (let index = 0; index < result.spaces.length; index++) {\n const space = result.spaces[index]!;\n if (index > 0) {\n lines.push('');\n }\n const topology = topologyBySpaceId.get(space.spaceId);\n const kindByMigrationHash =\n topology?.kindByMigrationHash ??\n classifyMigrationListGraphTopology(space.migrations).kindByMigrationHash;\n lines.push(\n ...renderSpaceBlock(\n space.spaceId,\n space.migrations,\n multiSpace,\n glyphMode,\n kindByMigrationHash,\n style,\n ),\n );\n }\n\n const totalMigrations = result.spaces.reduce(\n (count, space) => count + space.migrations.length,\n 0,\n );\n if (totalMigrations > 0) {\n lines.push('');\n lines.push(style.summary(result.summary));\n }\n\n return lines.join('\\n');\n}\n\nexport function renderMigrationList(result: MigrationListResult): string {\n return renderMigrationListWithStyle(result, IDENTITY_MIGRATION_LIST_STYLER);\n}\n","import { bold, cyan, cyanBright, dim, green, yellow } from 'colorette';\nimport { IDENTITY_MIGRATION_LIST_STYLER, type MigrationListStyler } from './migration-list-render';\n\n/**\n * The current contract overlay marker. Unlike user refs, this names the user's\n * declared desired state — the implicit base/target for `plan` / `migrate` —\n * not a stored label. It is emphasized (bold) so it stands out from plain refs\n * (including the live-database `db` marker, which is just another ref).\n */\nexport const CONTRACT_MARKER_NAME = 'contract';\n\nfunction styleRefName(name: string): string {\n return name === CONTRACT_MARKER_NAME ? bold(green(name)) : green(name);\n}\n\n/**\n * Build a {@link MigrationListStyler} that decorates `migration list`\n * tokens with ANSI SGR codes. When `useColor` is `false` (non-TTY,\n * `--no-color`, `NO_COLOR=1`, piped output) the function returns the\n * shared identity styler so callers get plain text with zero ANSI\n * bytes — pipe-friendly by construction.\n *\n * Palette:\n *\n * - `dirName`: bold\n * - `sourceHash`: dim cyan\n * - `destHash`: bright cyan\n * - `kind` (`*` / `↩` / `⟲`): bright — the signal; lanes and arrows dim\n * - `glyph` (`→` / `⟲` / `∅`): dim\n * - `lane` (graph gutter lines `│` and fan/join connectors `├─┐` / `├─┘`): dim\n * - `invariants` (`{...}`): yellow\n * - `refs` (`(...)`): green; the `contract` desired-state marker inside is\n * green-bold (the active ref is bolded separately by the tree styler)\n * - `spaceHeading` (`<spaceId>:`): bold\n * - `summary`: dim\n * - `emptyState`: dim\n */\nexport function createAnsiMigrationListStyler(opts: {\n readonly useColor: boolean;\n}): MigrationListStyler {\n if (!opts.useColor) {\n return IDENTITY_MIGRATION_LIST_STYLER;\n }\n return {\n // Kind glyphs stay bright in both flat and graph views; lanes carry the dim gutter.\n kind: (text) => text,\n dirName: (text) => bold(text),\n sourceHash: (text) => dim(cyan(text)),\n destHash: (text) => cyanBright(text),\n glyph: (text) => dim(text),\n lane: (text) => dim(text),\n invariants: (ids) => yellow(`{${ids.join(', ')}}`),\n refs: (names) => {\n const open = green('(');\n const close = green(')');\n const separator = green(', ');\n return open + names.map(styleRefName).join(separator) + close;\n },\n spaceHeading: (text) => bold(text),\n summary: (text) => dim(text),\n emptyState: (text) => dim(text),\n };\n}\n"],"mappings":"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"}