@prisma-next/cli 0.12.0 → 0.13.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cli.mjs +180 -163
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-KgJorIvG.mjs → client-CJzuo5wX.mjs} +222 -107
- package/dist/client-CJzuo5wX.mjs.map +1 -0
- package/dist/{command-helpers-Bbw1GbwL.mjs → command-helpers-DGMvGBeX.mjs} +318 -25
- package/dist/command-helpers-DGMvGBeX.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts.map +1 -1
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.d.mts.map +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.d.mts.map +1 -1
- package/dist/commands/db-init.mjs +4 -5
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.d.mts.map +1 -1
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-schema.mjs.map +1 -1
- package/dist/commands/db-sign.d.mts.map +1 -1
- package/dist/commands/db-sign.mjs +6 -6
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +10 -7
- package/dist/commands/db-update.mjs.map +1 -1
- package/dist/commands/db-verify.d.mts.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +37 -3
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +298 -12
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +55 -13
- package/dist/commands/migration-check.d.mts.map +1 -1
- package/dist/commands/migration-check.mjs +3 -2
- package/dist/commands/migration-graph.d.mts +17 -8
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +185 -2
- package/dist/commands/migration-graph.mjs.map +1 -0
- package/dist/commands/migration-list.d.mts +26 -27
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +2 -190
- package/dist/commands/migration-log.d.mts +9 -19
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +1 -137
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +6 -5
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +1 -1
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +17 -21
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +24 -36
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +42 -144
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +3 -759
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +4 -4
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/commands/telemetry/index.d.mts +7 -0
- package/dist/commands/telemetry/index.d.mts.map +1 -0
- package/dist/commands/telemetry/index.mjs +2 -0
- package/dist/{config-loader-B6sJjXTv.mjs → config-loader-p9JMrekQ.mjs} +1 -1
- package/dist/{config-loader-B6sJjXTv.mjs.map → config-loader-p9JMrekQ.mjs.map} +1 -1
- package/dist/config-loader.mjs +1 -1
- package/dist/{contract-at-errors-BxP-TOMl.mjs → contract-at-errors-CFXsstzm.mjs} +2 -2
- package/dist/{contract-at-errors-BxP-TOMl.mjs.map → contract-at-errors-CFXsstzm.mjs.map} +1 -1
- package/dist/{contract-emit-DxcGl4Uq.mjs → contract-emit-B_qriF8B.mjs} +5 -5
- package/dist/{contract-emit-DxcGl4Uq.mjs.map → contract-emit-B_qriF8B.mjs.map} +1 -1
- package/dist/{contract-emit-D-4jrNve.mjs → contract-emit-C8HmtboH.mjs} +12 -7
- package/dist/contract-emit-C8HmtboH.mjs.map +1 -0
- package/dist/{contract-enrichment-a0V5Y_mL.mjs → contract-enrichment-gn9sWbPw.mjs} +1 -1
- package/dist/{contract-enrichment-a0V5Y_mL.mjs.map → contract-enrichment-gn9sWbPw.mjs.map} +1 -1
- package/dist/{contract-infer-D8uEbJuu.mjs → contract-infer-BYT_ra_U.mjs} +5 -5
- package/dist/contract-infer-BYT_ra_U.mjs.map +1 -0
- package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs → contract-space-aggregate-loader-ClI1KN6d.mjs} +5 -5
- package/dist/{contract-space-aggregate-loader-DvZwdkrr.mjs.map → contract-space-aggregate-loader-ClI1KN6d.mjs.map} +1 -1
- package/dist/{db-verify-v_vUKXTU.mjs → db-verify-C24FKhb7.mjs} +6 -6
- package/dist/{db-verify-v_vUKXTU.mjs.map → db-verify-C24FKhb7.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +5 -3
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +3 -3
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/index.mjs.map +1 -1
- package/dist/exports/init-output.d.mts +1 -3
- package/dist/exports/init-output.d.mts.map +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{extension-pack-inputs-IDvjRCi3.mjs → extension-pack-inputs-1ySHqxKG.mjs} +1 -1
- package/dist/{extension-pack-inputs-IDvjRCi3.mjs.map → extension-pack-inputs-1ySHqxKG.mjs.map} +1 -1
- package/dist/{framework-components-fYXjz_in.mjs → framework-components-YVQHhPH7.mjs} +2 -2
- package/dist/{framework-components-fYXjz_in.mjs.map → framework-components-YVQHhPH7.mjs.map} +1 -1
- package/dist/{global-flags-DEHjV8_s.d.mts → global-flags-BpoOYtNZ.d.mts} +1 -1
- package/dist/{global-flags-DEHjV8_s.d.mts.map → global-flags-BpoOYtNZ.d.mts.map} +1 -1
- package/dist/{init-Cv9UzWL5.mjs → init-0HwB-Vh8.mjs} +5 -58
- package/dist/init-0HwB-Vh8.mjs.map +1 -0
- package/dist/{inspect-live-schema-C6ohV_oQ.mjs → inspect-live-schema-DF6IwcDl.mjs} +7 -5
- package/dist/inspect-live-schema-DF6IwcDl.mjs.map +1 -0
- package/dist/migration-check-VwM8xCZV.mjs +574 -0
- package/dist/migration-check-VwM8xCZV.mjs.map +1 -0
- package/dist/migration-cli.mjs +1 -1
- package/dist/migration-cli.mjs.map +1 -1
- package/dist/{migration-command-scaffold-CjvwO6at.mjs → migration-command-scaffold-DA-Lhx6o.mjs} +5 -5
- package/dist/{migration-command-scaffold-CjvwO6at.mjs.map → migration-command-scaffold-DA-Lhx6o.mjs.map} +1 -1
- package/dist/migration-graph-command-render-CEez7YUK.mjs +1960 -0
- package/dist/migration-graph-command-render-CEez7YUK.mjs.map +1 -0
- package/dist/migration-list-DlJJ_38Z.mjs +230 -0
- package/dist/migration-list-DlJJ_38Z.mjs.map +1 -0
- package/dist/migration-log-CG0qQAFm.mjs +222 -0
- package/dist/migration-log-CG0qQAFm.mjs.map +1 -0
- package/dist/migration-path-target-Ce6OZImp.mjs +38 -0
- package/dist/migration-path-target-Ce6OZImp.mjs.map +1 -0
- package/dist/{migration-plan-9DJ7q7_z.mjs → migration-plan-z5Ing-TD.mjs} +9 -8
- package/dist/migration-plan-z5Ing-TD.mjs.map +1 -0
- package/dist/migration-status-CD-LC2Ip.mjs +447 -0
- package/dist/migration-status-CD-LC2Ip.mjs.map +1 -0
- package/dist/{output-B60Gw5fu.mjs → output-mEQ74_nd.mjs} +1 -1
- package/dist/{output-B60Gw5fu.mjs.map → output-mEQ74_nd.mjs.map} +1 -1
- package/dist/{progress-adapter-C644QK8l.mjs → progress-adapter-CjAeTxY_.mjs} +1 -1
- package/dist/{progress-adapter-C644QK8l.mjs.map → progress-adapter-CjAeTxY_.mjs.map} +1 -1
- package/dist/{ref-advancement-DUZqsue6.mjs → ref-advancement-BkXlikCA.mjs} +1 -1
- package/dist/{ref-advancement-DUZqsue6.mjs.map → ref-advancement-BkXlikCA.mjs.map} +1 -1
- package/dist/schemas-CeGMYFYX.d.mts +191 -0
- package/dist/schemas-CeGMYFYX.d.mts.map +1 -0
- package/dist/schemas-KhXMzNA_.mjs +112 -0
- package/dist/schemas-KhXMzNA_.mjs.map +1 -0
- package/dist/telemetry-BIM4beEO.mjs +122 -0
- package/dist/telemetry-BIM4beEO.mjs.map +1 -0
- package/dist/{terminal-ui-5Y6mrg93.d.mts → terminal-ui-DGRNFWna.d.mts} +1 -1
- package/dist/terminal-ui-DGRNFWna.d.mts.map +1 -0
- package/dist/{types-Dt_SfqFm.d.mts → types-C_tYiJYx.d.mts} +53 -31
- package/dist/types-C_tYiJYx.d.mts.map +1 -0
- package/dist/{verify-DCA9Sldu.mjs → verify-DcOYZ1tH.mjs} +2 -2
- package/dist/{verify-DCA9Sldu.mjs.map → verify-DcOYZ1tH.mjs.map} +1 -1
- package/package.json +26 -22
- package/src/cli.ts +5 -0
- package/src/commands/contract-infer.ts +2 -2
- package/src/commands/db-update.ts +7 -1
- package/src/commands/init/index.ts +6 -35
- package/src/commands/init/init.ts +1 -14
- package/src/commands/init/inputs.ts +0 -75
- package/src/commands/inspect-live-schema.ts +10 -0
- package/src/commands/json/schemas.ts +195 -0
- package/src/commands/migrate.ts +527 -8
- package/src/commands/migration-check.ts +469 -134
- package/src/commands/migration-graph.ts +164 -91
- package/src/commands/migration-list.ts +72 -39
- package/src/commands/migration-log.ts +52 -102
- package/src/commands/migration-new.ts +2 -1
- package/src/commands/migration-plan.ts +2 -1
- package/src/commands/migration-show.ts +31 -66
- package/src/commands/migration-status-overlay.ts +61 -0
- package/src/commands/migration-status.ts +458 -1066
- package/src/commands/telemetry/index.ts +107 -0
- package/src/commands/telemetry/status.ts +67 -0
- package/src/control-api/client.ts +70 -9
- package/src/control-api/operations/contract-emit.ts +22 -2
- package/src/control-api/operations/db-init.ts +6 -3
- package/src/control-api/operations/{db-apply.ts → db-run.ts} +55 -14
- package/src/control-api/operations/db-update.ts +7 -4
- package/src/control-api/operations/db-verify.ts +15 -5
- package/src/control-api/operations/{migration-apply.ts → migrate.ts} +181 -80
- package/src/control-api/operations/{apply.ts → run-migration.ts} +33 -27
- package/src/control-api/types.ts +56 -29
- package/src/utils/cli-errors.ts +70 -2
- package/src/utils/formatters/errors.ts +11 -0
- package/src/utils/formatters/migration-graph-command-render.ts +239 -0
- package/src/utils/formatters/migration-graph-grid-layout.ts +1134 -0
- package/src/utils/formatters/migration-graph-labels.ts +408 -0
- package/src/utils/formatters/migration-graph-model.ts +103 -0
- package/src/utils/formatters/migration-graph-occlusion-render.ts +258 -0
- package/src/utils/formatters/migration-graph-rows.ts +128 -15
- package/src/utils/formatters/migration-graph-space-render.ts +188 -0
- package/src/utils/formatters/migration-list-data-column.ts +4 -91
- package/src/utils/formatters/migration-list-graph-topology.ts +72 -94
- package/src/utils/formatters/migration-list-render.ts +135 -71
- package/src/utils/formatters/migration-list-styler.ts +46 -5
- package/src/utils/formatters/migration-list-types.ts +5 -21
- package/src/utils/formatters/migration-log-table.ts +205 -0
- package/src/utils/formatters/migrations.ts +33 -11
- package/src/utils/global-flags.ts +35 -0
- package/src/utils/integrity-violation-to-check-failure.ts +28 -19
- package/src/utils/legend.ts +38 -0
- package/src/utils/migration-path-target.ts +60 -0
- package/src/utils/telemetry.ts +68 -32
- package/dist/client-KgJorIvG.mjs.map +0 -1
- package/dist/command-helpers-Bbw1GbwL.mjs.map +0 -1
- package/dist/commands/migration-list.mjs.map +0 -1
- package/dist/commands/migration-log.mjs.map +0 -1
- package/dist/commands/migration-status.mjs.map +0 -1
- package/dist/contract-emit-D-4jrNve.mjs.map +0 -1
- package/dist/contract-infer-D8uEbJuu.mjs.map +0 -1
- package/dist/graph-render-rFAqZujX.mjs +0 -1081
- package/dist/graph-render-rFAqZujX.mjs.map +0 -1
- package/dist/init-Cv9UzWL5.mjs.map +0 -1
- package/dist/inspect-live-schema-C6ohV_oQ.mjs.map +0 -1
- package/dist/migration-check-BiBJoYYW.mjs +0 -341
- package/dist/migration-check-BiBJoYYW.mjs.map +0 -1
- package/dist/migration-graph-D7DVUElV.mjs +0 -1232
- package/dist/migration-graph-D7DVUElV.mjs.map +0 -1
- package/dist/migration-list-styler-BRwF4-gy.mjs +0 -399
- package/dist/migration-list-styler-BRwF4-gy.mjs.map +0 -1
- package/dist/migration-plan-9DJ7q7_z.mjs.map +0 -1
- package/dist/migration-types-D2FW63pr.d.mts +0 -15
- package/dist/migration-types-D2FW63pr.d.mts.map +0 -1
- package/dist/migrations-Cv2jxNNK.mjs +0 -228
- package/dist/migrations-Cv2jxNNK.mjs.map +0 -1
- package/dist/terminal-ui-5Y6mrg93.d.mts.map +0 -1
- package/dist/types-Dt_SfqFm.d.mts.map +0 -1
- package/src/utils/formatters/graph-migration-mapper.ts +0 -235
- package/src/utils/formatters/graph-render.ts +0 -1323
- package/src/utils/formatters/graph-types.ts +0 -120
- package/src/utils/formatters/migration-graph-layout.ts +0 -1119
- package/src/utils/formatters/migration-graph-tree-render.ts +0 -459
|
@@ -1,459 +0,0 @@
|
|
|
1
|
-
import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';
|
|
2
|
-
import { bold } from 'colorette';
|
|
3
|
-
import stringWidth from 'string-width';
|
|
4
|
-
import type { GlyphMode } from '../glyph-mode';
|
|
5
|
-
import type {
|
|
6
|
-
MigrationGraphGridModel,
|
|
7
|
-
MigrationGraphGridRow,
|
|
8
|
-
StructuralCell,
|
|
9
|
-
} from './migration-graph-layout';
|
|
10
|
-
import type { ClassifiedEdge } from './migration-graph-rows';
|
|
11
|
-
import {
|
|
12
|
-
MIGRATION_LIST_HASH_WIDTH,
|
|
13
|
-
migrationListEmptySource,
|
|
14
|
-
migrationListForwardArrow,
|
|
15
|
-
} from './migration-list-data-column';
|
|
16
|
-
import type { MigrationEdgeKind } from './migration-list-graph-topology';
|
|
17
|
-
import type { MigrationListStyler } from './migration-list-render';
|
|
18
|
-
import { CONTRACT_MARKER_NAME, createAnsiMigrationListStyler } from './migration-list-styler';
|
|
19
|
-
|
|
20
|
-
const LABEL_GAP = 2;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* The live-database overlay marker. Just another ref as far as styling goes —
|
|
24
|
-
* the only emphasized markers are the active ref and the `contract`
|
|
25
|
-
* desired-state marker (see {@link CONTRACT_MARKER_NAME}).
|
|
26
|
-
*/
|
|
27
|
-
const DB_MARKER_NAME = 'db';
|
|
28
|
-
|
|
29
|
-
export interface RenderMigrationGraphTreeOptions {
|
|
30
|
-
readonly refsByHash?: ReadonlyMap<string, readonly string[]>;
|
|
31
|
-
readonly dbHash?: string;
|
|
32
|
-
readonly contractHash?: string;
|
|
33
|
-
readonly activeRefName?: string;
|
|
34
|
-
readonly hashLength?: number;
|
|
35
|
-
readonly colorize: boolean;
|
|
36
|
-
readonly glyphMode?: GlyphMode;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
interface MigrationGraphTreeGlyphPalette {
|
|
40
|
-
readonly node: string;
|
|
41
|
-
readonly arcLand: string;
|
|
42
|
-
readonly arcTee: string;
|
|
43
|
-
readonly verticalPass: string;
|
|
44
|
-
readonly branchTee: string;
|
|
45
|
-
readonly mergeTee: string;
|
|
46
|
-
readonly branchCorner: string;
|
|
47
|
-
readonly mergeCorner: string;
|
|
48
|
-
readonly arcBranchCorner: string;
|
|
49
|
-
readonly arcBranchTee: string;
|
|
50
|
-
readonly arcLandCorner: string;
|
|
51
|
-
readonly arcCrossing: string;
|
|
52
|
-
readonly arcLandBridge: string;
|
|
53
|
-
readonly horizontalPass: string;
|
|
54
|
-
readonly connectorBranchTee: string;
|
|
55
|
-
readonly connectorBranchTeeCo: string;
|
|
56
|
-
readonly connectorMergeTeeCo: string;
|
|
57
|
-
readonly edgeArrow: Readonly<Record<MigrationEdgeKind, string>>;
|
|
58
|
-
readonly forwardArrow: string;
|
|
59
|
-
readonly emptySource: string;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const UNICODE_PALETTE: MigrationGraphTreeGlyphPalette = {
|
|
63
|
-
node: '○ ',
|
|
64
|
-
arcLand: '○◂',
|
|
65
|
-
arcTee: '○─',
|
|
66
|
-
verticalPass: '│ ',
|
|
67
|
-
branchTee: '├─',
|
|
68
|
-
mergeTee: '├─',
|
|
69
|
-
branchCorner: '╮ ',
|
|
70
|
-
mergeCorner: '╯ ',
|
|
71
|
-
arcBranchCorner: '╮ ',
|
|
72
|
-
arcBranchTee: '┬─',
|
|
73
|
-
arcLandCorner: '╯ ',
|
|
74
|
-
arcCrossing: '┼─',
|
|
75
|
-
arcLandBridge: '──',
|
|
76
|
-
horizontalPass: '──',
|
|
77
|
-
connectorBranchTee: '├─',
|
|
78
|
-
connectorBranchTeeCo: '┬─',
|
|
79
|
-
connectorMergeTeeCo: '┴─',
|
|
80
|
-
edgeArrow: { forward: '↑', rollback: '↓', self: '⟲' },
|
|
81
|
-
forwardArrow: migrationListForwardArrow('unicode'),
|
|
82
|
-
emptySource: migrationListEmptySource('unicode'),
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const ASCII_PALETTE: MigrationGraphTreeGlyphPalette = {
|
|
86
|
-
node: '* ',
|
|
87
|
-
arcLand: '*<',
|
|
88
|
-
arcTee: '*-',
|
|
89
|
-
verticalPass: '| ',
|
|
90
|
-
branchTee: '+-',
|
|
91
|
-
mergeTee: '+-',
|
|
92
|
-
branchCorner: '\\ ',
|
|
93
|
-
mergeCorner: '/ ',
|
|
94
|
-
arcBranchCorner: '\\ ',
|
|
95
|
-
arcBranchTee: '+-',
|
|
96
|
-
arcLandCorner: '/ ',
|
|
97
|
-
arcCrossing: '+-',
|
|
98
|
-
arcLandBridge: '--',
|
|
99
|
-
horizontalPass: '--',
|
|
100
|
-
connectorBranchTee: '+-',
|
|
101
|
-
connectorBranchTeeCo: '+-',
|
|
102
|
-
connectorMergeTeeCo: '+-',
|
|
103
|
-
edgeArrow: { forward: '^', rollback: 'v', self: '@' },
|
|
104
|
-
forwardArrow: migrationListForwardArrow('ascii'),
|
|
105
|
-
emptySource: migrationListEmptySource('ascii'),
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
function paletteFor(mode: GlyphMode): MigrationGraphTreeGlyphPalette {
|
|
109
|
-
return mode === 'ascii' ? ASCII_PALETTE : UNICODE_PALETTE;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function arrowForEdgeKind(
|
|
113
|
-
kind: MigrationEdgeKind,
|
|
114
|
-
palette: MigrationGraphTreeGlyphPalette,
|
|
115
|
-
): string {
|
|
116
|
-
return palette.edgeArrow[kind];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* A node-marker glyph pair (`○◂`, `○─`, `*<`, `*-`) is the contract node
|
|
121
|
-
* marker (`○` / `*`) followed by an arc connector (`◂` / `─` / `<` / `-`).
|
|
122
|
-
* The marker is the signal and stays bright (`style.kind`); the connector is
|
|
123
|
-
* gutter and stays dim (`style.lane`) — consistent with the plain node marker,
|
|
124
|
-
* which is never dimmed.
|
|
125
|
-
*/
|
|
126
|
-
function renderNodeMarkerPair(pair: string, style: MigrationListStyler): string {
|
|
127
|
-
return style.kind(pair.slice(0, 1)) + style.lane(pair.slice(1));
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function renderCellPair(
|
|
131
|
-
cell: StructuralCell,
|
|
132
|
-
style: MigrationListStyler,
|
|
133
|
-
palette: MigrationGraphTreeGlyphPalette,
|
|
134
|
-
): string {
|
|
135
|
-
switch (cell.kind) {
|
|
136
|
-
case 'node':
|
|
137
|
-
if (cell.arcLand === true) return renderNodeMarkerPair(palette.arcLand, style);
|
|
138
|
-
if (cell.arcTee === true) return renderNodeMarkerPair(palette.arcTee, style);
|
|
139
|
-
return style.kind(palette.node);
|
|
140
|
-
case 'vertical-pass':
|
|
141
|
-
return style.lane(palette.verticalPass);
|
|
142
|
-
case 'edge-lane':
|
|
143
|
-
// The lane stays dim; the direction arrow (↑ / ↓ / ⟲) is the signal and
|
|
144
|
-
// stays bright, like the contract-node marker.
|
|
145
|
-
return cell.ownsLabel
|
|
146
|
-
? style.lane(palette.verticalPass.trimEnd()) +
|
|
147
|
-
style.kind(arrowForEdgeKind(cell.edgeKind, palette))
|
|
148
|
-
: style.lane(palette.verticalPass);
|
|
149
|
-
case 'branch-tee':
|
|
150
|
-
return style.lane(palette.branchTee);
|
|
151
|
-
case 'merge-tee':
|
|
152
|
-
return style.lane(palette.mergeTee);
|
|
153
|
-
case 'branch-corner':
|
|
154
|
-
return style.lane(palette.branchCorner);
|
|
155
|
-
case 'merge-corner':
|
|
156
|
-
return style.lane(palette.mergeCorner);
|
|
157
|
-
case 'arc-branch-corner':
|
|
158
|
-
return style.lane(palette.arcBranchCorner);
|
|
159
|
-
case 'arc-branch-tee':
|
|
160
|
-
return style.lane(palette.arcBranchTee);
|
|
161
|
-
case 'arc-land-corner':
|
|
162
|
-
return style.lane(palette.arcLandCorner);
|
|
163
|
-
case 'arc-crossing':
|
|
164
|
-
return style.lane(palette.arcCrossing);
|
|
165
|
-
case 'arc-land-bridge':
|
|
166
|
-
return style.lane(palette.arcLandBridge);
|
|
167
|
-
case 'horizontal-pass':
|
|
168
|
-
return style.lane(palette.horizontalPass);
|
|
169
|
-
case 'empty':
|
|
170
|
-
return ' ';
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
function renderConnectorRow(
|
|
175
|
-
row: MigrationGraphGridRow,
|
|
176
|
-
gridWidth: number,
|
|
177
|
-
style: MigrationListStyler,
|
|
178
|
-
palette: MigrationGraphTreeGlyphPalette,
|
|
179
|
-
): string {
|
|
180
|
-
const isMerge = row.kind === 'merge-connector';
|
|
181
|
-
if (row.cells.length > 0) {
|
|
182
|
-
let seenTee = false;
|
|
183
|
-
let out = '';
|
|
184
|
-
for (const cell of row.cells) {
|
|
185
|
-
switch (cell.kind) {
|
|
186
|
-
case 'branch-tee':
|
|
187
|
-
out += style.lane(seenTee ? palette.connectorBranchTeeCo : palette.connectorBranchTee);
|
|
188
|
-
seenTee = true;
|
|
189
|
-
break;
|
|
190
|
-
case 'merge-tee':
|
|
191
|
-
out += style.lane(seenTee ? palette.connectorMergeTeeCo : palette.connectorBranchTee);
|
|
192
|
-
seenTee = true;
|
|
193
|
-
break;
|
|
194
|
-
case 'branch-corner':
|
|
195
|
-
out += style.lane(palette.branchCorner);
|
|
196
|
-
break;
|
|
197
|
-
case 'merge-corner':
|
|
198
|
-
out += style.lane(palette.mergeCorner);
|
|
199
|
-
break;
|
|
200
|
-
case 'vertical-pass':
|
|
201
|
-
out += style.lane(palette.verticalPass);
|
|
202
|
-
break;
|
|
203
|
-
case 'horizontal-pass':
|
|
204
|
-
out += style.lane(palette.horizontalPass);
|
|
205
|
-
break;
|
|
206
|
-
default:
|
|
207
|
-
out += ' ';
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
// The cells array is sized to the grid width at emit time; a back-arc lane
|
|
211
|
-
// allocated by a later row can push the grid wider afterwards, so pad any
|
|
212
|
-
// trailing columns rather than dropping the lanes that pass through here.
|
|
213
|
-
for (let column = row.cells.length; column < gridWidth; column++) {
|
|
214
|
-
out += ' ';
|
|
215
|
-
}
|
|
216
|
-
return out;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const start = row.startLane ?? 0;
|
|
220
|
-
const end = row.endLane ?? start;
|
|
221
|
-
let out = '';
|
|
222
|
-
for (let column = 0; column < gridWidth; column++) {
|
|
223
|
-
if (column < start || column > end) out += ' ';
|
|
224
|
-
else if (column === start) out += style.lane(palette.connectorBranchTee);
|
|
225
|
-
else if (column === end)
|
|
226
|
-
out += style.lane(isMerge ? palette.mergeCorner : palette.branchCorner);
|
|
227
|
-
else out += style.lane(isMerge ? palette.connectorMergeTeeCo : palette.connectorBranchTeeCo);
|
|
228
|
-
}
|
|
229
|
-
return out;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function abbreviateHash(hash: string, hashLength: number, emptySource: string): string {
|
|
233
|
-
if (hash === EMPTY_CONTRACT_HASH) {
|
|
234
|
-
return emptySource;
|
|
235
|
-
}
|
|
236
|
-
const stripped = hash.startsWith('sha256:') ? hash.slice(7) : hash;
|
|
237
|
-
return stripped.slice(0, hashLength);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const MIN_HASH_DATA_COLUMN = 25;
|
|
241
|
-
|
|
242
|
-
function overlayNamesForContract(
|
|
243
|
-
contractHash: string,
|
|
244
|
-
opts: RenderMigrationGraphTreeOptions,
|
|
245
|
-
): readonly string[] {
|
|
246
|
-
const names: string[] = [];
|
|
247
|
-
const userRefs = opts.refsByHash?.get(contractHash);
|
|
248
|
-
if (userRefs) {
|
|
249
|
-
names.push(...[...userRefs].sort((a, b) => a.localeCompare(b)));
|
|
250
|
-
}
|
|
251
|
-
if (opts.dbHash === contractHash) {
|
|
252
|
-
names.push(DB_MARKER_NAME);
|
|
253
|
-
}
|
|
254
|
-
if (opts.contractHash === contractHash && contractHash !== EMPTY_CONTRACT_HASH) {
|
|
255
|
-
names.push(CONTRACT_MARKER_NAME);
|
|
256
|
-
}
|
|
257
|
-
return names;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
function createTreeStyler(opts: RenderMigrationGraphTreeOptions): MigrationListStyler {
|
|
261
|
-
const base = createAnsiMigrationListStyler({ useColor: opts.colorize });
|
|
262
|
-
const activeRefName = opts.activeRefName;
|
|
263
|
-
if (!opts.colorize || activeRefName === undefined) {
|
|
264
|
-
return base;
|
|
265
|
-
}
|
|
266
|
-
return {
|
|
267
|
-
...base,
|
|
268
|
-
refs: (names) => {
|
|
269
|
-
const styledNames = names.map((name) => (name === activeRefName ? bold(name) : name));
|
|
270
|
-
return base.refs(styledNames);
|
|
271
|
-
},
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
function formatEdgeHashColumn(
|
|
276
|
-
edge: ClassifiedEdge,
|
|
277
|
-
style: MigrationListStyler,
|
|
278
|
-
hashLength: number,
|
|
279
|
-
palette: MigrationGraphTreeGlyphPalette,
|
|
280
|
-
): string {
|
|
281
|
-
if (edge.kind === 'self') {
|
|
282
|
-
const hash = abbreviateHash(edge.from, hashLength, palette.emptySource);
|
|
283
|
-
return `${style.sourceHash(hash)} ${style.glyph(palette.forwardArrow)} ${style.destHash(hash)}`;
|
|
284
|
-
}
|
|
285
|
-
const source =
|
|
286
|
-
edge.from === EMPTY_CONTRACT_HASH
|
|
287
|
-
? style.glyph(palette.emptySource) +
|
|
288
|
-
' '.repeat(Math.max(0, hashLength - palette.emptySource.length))
|
|
289
|
-
: style.sourceHash(abbreviateHash(edge.from, hashLength, palette.emptySource));
|
|
290
|
-
const arrow = style.glyph(palette.forwardArrow);
|
|
291
|
-
const dest = style.destHash(abbreviateHash(edge.to, hashLength, palette.emptySource));
|
|
292
|
-
return `${source} ${arrow} ${dest}`;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
function padVisible(text: string, targetWidth: number): string {
|
|
296
|
-
const padding = Math.max(0, targetWidth - stringWidth(text));
|
|
297
|
-
return text + ' '.repeat(padding);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
function gridWidthForModel(rows: readonly MigrationGraphGridRow[]): number {
|
|
301
|
-
return rows.reduce(
|
|
302
|
-
(max, row) =>
|
|
303
|
-
row.kind === 'node' || row.kind === 'edge' ? Math.max(max, row.cells.length) : max,
|
|
304
|
-
1,
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
function maxDirNameLength(edges: readonly ClassifiedEdge[]): number {
|
|
309
|
-
if (edges.length === 0) return 0;
|
|
310
|
-
return Math.max(...edges.map((edge) => edge.dirName.length));
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
function rowDirNameWidth(labelColumn: number, maxDirNameLen: number, dirNameGap: number): number {
|
|
314
|
-
return Math.max(maxDirNameLen + dirNameGap, MIN_HASH_DATA_COLUMN - labelColumn);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
function gridUsesSkipRollbackArcs(rows: readonly MigrationGraphGridRow[]): boolean {
|
|
318
|
-
return rows.some((row) =>
|
|
319
|
-
row.cells.some(
|
|
320
|
-
(cell) => cell.kind === 'edge-lane' && cell.adjacency === 'node-skipping-rollback',
|
|
321
|
-
),
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
function edgeLabelColumn(row: MigrationGraphGridRow, wideLabelColumn: number | undefined): number {
|
|
326
|
-
if (wideLabelColumn !== undefined) {
|
|
327
|
-
return wideLabelColumn;
|
|
328
|
-
}
|
|
329
|
-
const laneIndex = row.laneIndex ?? 0;
|
|
330
|
-
if (row.edge?.from === EMPTY_CONTRACT_HASH && laneIndex === 0) {
|
|
331
|
-
return (laneIndex + 1) * 2 + LABEL_GAP;
|
|
332
|
-
}
|
|
333
|
-
const usesFullRowGutter = row.cells.some(
|
|
334
|
-
(cell, index) => index > laneIndex && cell.kind === 'vertical-pass',
|
|
335
|
-
);
|
|
336
|
-
return usesFullRowGutter ? row.cells.length * 2 + LABEL_GAP : (laneIndex + 1) * 2 + LABEL_GAP;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function nodeHasArcDecoration(row: MigrationGraphGridRow): boolean {
|
|
340
|
-
return row.cells.some(
|
|
341
|
-
(cell) => cell.kind === 'node' && (cell.arcTee === true || cell.arcLand === true),
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
export function renderMigrationGraphTree(
|
|
346
|
-
model: MigrationGraphGridModel,
|
|
347
|
-
opts: RenderMigrationGraphTreeOptions,
|
|
348
|
-
): string {
|
|
349
|
-
const glyphMode = opts.glyphMode ?? 'unicode';
|
|
350
|
-
const palette = paletteFor(glyphMode);
|
|
351
|
-
const style = createTreeStyler(opts);
|
|
352
|
-
const hashLength = opts.hashLength ?? MIGRATION_LIST_HASH_WIDTH;
|
|
353
|
-
const gridWidth = gridWidthForModel(model.rows);
|
|
354
|
-
const wideLabelColumn = gridUsesSkipRollbackArcs(model.rows) ? gridWidth * 2 + 4 : undefined;
|
|
355
|
-
const dirNameGap = wideLabelColumn !== undefined ? 3 : LABEL_GAP;
|
|
356
|
-
const allEdges = model.rows
|
|
357
|
-
.filter(
|
|
358
|
-
(row): row is MigrationGraphGridRow & { edge: ClassifiedEdge } =>
|
|
359
|
-
row.kind === 'edge' && row.edge !== undefined,
|
|
360
|
-
)
|
|
361
|
-
.map((row) => row.edge);
|
|
362
|
-
const maxDirNameLen = maxDirNameLength(allEdges);
|
|
363
|
-
|
|
364
|
-
const lines: string[] = [];
|
|
365
|
-
|
|
366
|
-
for (let rowIndex = 0; rowIndex < model.rows.length; rowIndex++) {
|
|
367
|
-
const row = model.rows[rowIndex];
|
|
368
|
-
if (row === undefined) continue;
|
|
369
|
-
|
|
370
|
-
if (row.kind === 'component-separator') {
|
|
371
|
-
lines.push('');
|
|
372
|
-
continue;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (row.kind === 'branch-connector' || row.kind === 'merge-connector') {
|
|
376
|
-
lines.push(renderConnectorRow(row, gridWidth, style, palette).replace(/\s+$/, ''));
|
|
377
|
-
continue;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
let gutter = row.cells.map((cell) => renderCellPair(cell, style, palette)).join('');
|
|
381
|
-
const prevRow = model.rows[rowIndex - 1];
|
|
382
|
-
let laneSpan = row.cells.length;
|
|
383
|
-
if (row.kind === 'node') {
|
|
384
|
-
const contractHash = row.contractHash ?? EMPTY_CONTRACT_HASH;
|
|
385
|
-
if (prevRow?.kind === 'merge-connector' || contractHash === EMPTY_CONTRACT_HASH) {
|
|
386
|
-
laneSpan = 1;
|
|
387
|
-
} else {
|
|
388
|
-
laneSpan = row.cells.length;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
const labelColumn =
|
|
392
|
-
row.kind === 'edge'
|
|
393
|
-
? edgeLabelColumn(row, wideLabelColumn)
|
|
394
|
-
: wideLabelColumn !== undefined &&
|
|
395
|
-
(nodeHasArcDecoration(row) || row.contractHash !== undefined)
|
|
396
|
-
? wideLabelColumn
|
|
397
|
-
: laneSpan * 2 + LABEL_GAP;
|
|
398
|
-
if (
|
|
399
|
-
row.kind === 'edge' &&
|
|
400
|
-
row.edge?.from === EMPTY_CONTRACT_HASH &&
|
|
401
|
-
(row.laneIndex ?? 0) === 0
|
|
402
|
-
) {
|
|
403
|
-
gutter = row.cells
|
|
404
|
-
.slice(0, 1)
|
|
405
|
-
.map((cell) => renderCellPair(cell, style, palette))
|
|
406
|
-
.join('');
|
|
407
|
-
} else if (row.kind === 'node' && laneSpan < row.cells.length && !nodeHasArcDecoration(row)) {
|
|
408
|
-
gutter = row.cells
|
|
409
|
-
.slice(0, laneSpan)
|
|
410
|
-
.map((cell) => renderCellPair(cell, style, palette))
|
|
411
|
-
.join('');
|
|
412
|
-
} else if (gutter.length < laneSpan * 2) {
|
|
413
|
-
gutter = gutter.padEnd(laneSpan * 2, ' ');
|
|
414
|
-
}
|
|
415
|
-
const dirNameWidth = rowDirNameWidth(labelColumn, maxDirNameLen, dirNameGap);
|
|
416
|
-
const dataColumn = labelColumn + dirNameWidth;
|
|
417
|
-
const gutterPad = padVisible(gutter, labelColumn);
|
|
418
|
-
|
|
419
|
-
if (row.kind === 'node') {
|
|
420
|
-
const contractHash = row.contractHash ?? EMPTY_CONTRACT_HASH;
|
|
421
|
-
if (contractHash === EMPTY_CONTRACT_HASH) {
|
|
422
|
-
const trailingLanes = row.cells
|
|
423
|
-
.slice(1)
|
|
424
|
-
.map((cell) => renderCellPair(cell, style, palette))
|
|
425
|
-
.join('');
|
|
426
|
-
const emptyGutter = palette.emptySource.padEnd(2, ' ') + trailingLanes;
|
|
427
|
-
const overlayNames = overlayNamesForContract(contractHash, opts);
|
|
428
|
-
if (overlayNames.length === 0) {
|
|
429
|
-
lines.push(emptyGutter.replace(/\s+$/, ''));
|
|
430
|
-
continue;
|
|
431
|
-
}
|
|
432
|
-
const overlay = style.refs(overlayNames);
|
|
433
|
-
lines.push(`${padVisible(emptyGutter, dataColumn)}${overlay}`.replace(/\s+$/, ''));
|
|
434
|
-
continue;
|
|
435
|
-
}
|
|
436
|
-
const hashText = style.sourceHash(
|
|
437
|
-
abbreviateHash(contractHash, hashLength, palette.emptySource),
|
|
438
|
-
);
|
|
439
|
-
const overlayNames = overlayNamesForContract(contractHash, opts);
|
|
440
|
-
const overlayPad =
|
|
441
|
-
overlayNames.length > 0
|
|
442
|
-
? ' '.repeat(Math.max(0, dataColumn - labelColumn - stringWidth(hashText)))
|
|
443
|
-
: '';
|
|
444
|
-
const overlay = overlayNames.length > 0 ? style.refs(overlayNames) : '';
|
|
445
|
-
lines.push(`${gutterPad}${hashText}${overlayPad}${overlay}`.replace(/\s+$/, ''));
|
|
446
|
-
continue;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
const edge = row.edge;
|
|
450
|
-
if (edge === undefined) continue;
|
|
451
|
-
|
|
452
|
-
const dirNamePadding = ' '.repeat(Math.max(0, dirNameWidth - edge.dirName.length));
|
|
453
|
-
const dirName = `${style.dirName(edge.dirName)}${dirNamePadding}`;
|
|
454
|
-
const hashColumn = formatEdgeHashColumn(edge, style, hashLength, palette);
|
|
455
|
-
lines.push(`${gutterPad}${dirName}${hashColumn}`.replace(/\s+$/, ''));
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
return lines.join('\n');
|
|
459
|
-
}
|