@prisma-next/cli 0.11.0-dev.6 → 0.11.0-dev.61
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 +13 -9
- package/dist/cli.mjs +9 -10
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-oXO2WCPD.mjs → client-CD3om3R0.mjs} +44 -24
- package/dist/client-CD3om3R0.mjs.map +1 -0
- package/dist/{command-helpers-DtavI0wJ.mjs → command-helpers-CoceqqMl.mjs} +642 -45
- package/dist/command-helpers-CoceqqMl.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 +32 -7
- 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 -4
- 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 +12 -10
- 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 +41 -11
- 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 +5 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +75 -40
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +4 -3
- package/dist/commands/migration-check.d.mts.map +1 -1
- package/dist/commands/migration-check.mjs +1 -280
- package/dist/commands/migration-graph.d.mts +11 -2
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +15 -30
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.d.mts +66 -4
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +2 -103
- package/dist/commands/migration-log.d.mts +10 -1
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +10 -15
- package/dist/commands/migration-log.mjs.map +1 -1
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +32 -38
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +2 -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 +4 -55
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +61 -153
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +5 -40
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +81 -76
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +38 -10
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/config-loader-B6sJjXTv.mjs.map +1 -1
- package/dist/config-loader.d.mts.map +1 -1
- package/dist/contract-at-errors-Bhf2jnkp.mjs +42 -0
- package/dist/contract-at-errors-Bhf2jnkp.mjs.map +1 -0
- package/dist/{contract-emit-CmsklifJ.mjs → contract-emit-C47r1loe.mjs} +4 -6
- package/dist/{contract-emit-CmsklifJ.mjs.map → contract-emit-C47r1loe.mjs.map} +1 -1
- package/dist/{contract-emit-o-8VmdQX.mjs → contract-emit-DxEfEc-M.mjs} +21 -7
- package/dist/{contract-emit-o-8VmdQX.mjs.map → contract-emit-DxEfEc-M.mjs.map} +1 -1
- package/dist/{contract-enrichment-Dani0mMW.mjs → contract-enrichment-a0V5Y_mL.mjs} +4 -25
- package/dist/contract-enrichment-a0V5Y_mL.mjs.map +1 -0
- package/dist/{contract-infer-pKkiCt7C.mjs → contract-infer-B5EhTqdR.mjs} +3 -4
- package/dist/{contract-infer-pKkiCt7C.mjs.map → contract-infer-B5EhTqdR.mjs.map} +1 -1
- package/dist/contract-space-aggregate-loader-lafgkTwG.mjs +247 -0
- package/dist/contract-space-aggregate-loader-lafgkTwG.mjs.map +1 -0
- package/dist/{db-verify-AoIUriL4.mjs → db-verify-B7fbkGnp.mjs} +5 -7
- package/dist/{db-verify-AoIUriL4.mjs.map → db-verify-B7fbkGnp.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +3 -3
- package/dist/exports/index.d.mts.map +1 -1
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/index.mjs.map +1 -1
- 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 +62 -0
- package/dist/extension-pack-inputs-IDvjRCi3.mjs.map +1 -0
- package/dist/{framework-components-65gOHkHB.mjs → framework-components-R_O3y5IW.mjs} +2 -2
- package/dist/{framework-components-65gOHkHB.mjs.map → framework-components-R_O3y5IW.mjs.map} +1 -1
- package/dist/global-flags-2SPgqWma.d.mts +34 -0
- package/dist/global-flags-2SPgqWma.d.mts.map +1 -0
- package/dist/{graph-render-DJVv0_uf.mjs → graph-render-rFAqZujX.mjs} +2 -2
- package/dist/{graph-render-DJVv0_uf.mjs.map → graph-render-rFAqZujX.mjs.map} +1 -1
- package/dist/{init-Db5Itt5r.mjs → init-BQNpPozW.mjs} +4 -5
- package/dist/{init-Db5Itt5r.mjs.map → init-BQNpPozW.mjs.map} +1 -1
- package/dist/{inspect-live-schema-LeWvkZVz.mjs → inspect-live-schema-CQJnuPgD.mjs} +4 -5
- package/dist/{inspect-live-schema-LeWvkZVz.mjs.map → inspect-live-schema-CQJnuPgD.mjs.map} +1 -1
- package/dist/migration-check-CKfQlAWR.mjs +341 -0
- package/dist/migration-check-CKfQlAWR.mjs.map +1 -0
- package/dist/migration-cli.d.mts.map +1 -1
- package/dist/migration-cli.mjs +4 -4
- package/dist/migration-cli.mjs.map +1 -1
- package/dist/{migration-command-scaffold-BtkunvFQ.mjs → migration-command-scaffold-CE931d1-.mjs} +4 -5
- package/dist/{migration-command-scaffold-BtkunvFQ.mjs.map → migration-command-scaffold-CE931d1-.mjs.map} +1 -1
- package/dist/migration-list-A3bJ4j5e.mjs +780 -0
- package/dist/migration-list-A3bJ4j5e.mjs.map +1 -0
- package/dist/{migration-plan-C2jeH1J5.mjs → migration-plan-ZZm8C0s-.mjs} +372 -133
- package/dist/migration-plan-ZZm8C0s-.mjs.map +1 -0
- package/dist/{migration-types-BXWvz12q.d.mts → migration-types-q64xAI_J.d.mts} +1 -1
- package/dist/{migration-types-BXWvz12q.d.mts.map → migration-types-q64xAI_J.d.mts.map} +1 -1
- package/dist/{migrations-CwZMa1Ck.mjs → migrations-CjO1DsYe.mjs} +12 -13
- package/dist/migrations-CjO1DsYe.mjs.map +1 -0
- package/dist/{output-BlsrGMEF.mjs → output-DEg3SSnJ.mjs} +1 -1
- package/dist/{output-BlsrGMEF.mjs.map → output-DEg3SSnJ.mjs.map} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs → progress-adapter-C644QK8l.mjs} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs.map → progress-adapter-C644QK8l.mjs.map} +1 -1
- package/dist/ref-advancement-DUZqsue6.mjs +50 -0
- package/dist/ref-advancement-DUZqsue6.mjs.map +1 -0
- package/dist/terminal-ui-sLZt2cxc.d.mts +133 -0
- package/dist/terminal-ui-sLZt2cxc.d.mts.map +1 -0
- package/dist/{types-C9FfXb1l.d.mts → types-DK-ge7eR.d.mts} +5 -11
- package/dist/types-DK-ge7eR.d.mts.map +1 -0
- package/dist/{verify-Bom75OYI.mjs → verify-vl983Ed-.mjs} +2 -2
- package/dist/{verify-Bom75OYI.mjs.map → verify-vl983Ed-.mjs.map} +1 -1
- package/package.json +19 -19
- package/src/commands/db-init.ts +48 -2
- package/src/commands/db-sign.ts +9 -5
- package/src/commands/db-update.ts +54 -8
- package/src/commands/migrate.ts +123 -42
- package/src/commands/migration-check.ts +43 -83
- package/src/commands/migration-graph.ts +15 -41
- package/src/commands/migration-list.ts +231 -74
- package/src/commands/migration-log.ts +8 -14
- package/src/commands/migration-new.ts +44 -48
- package/src/commands/migration-plan.ts +411 -196
- package/src/commands/migration-show.ts +65 -284
- package/src/commands/migration-status.ts +116 -110
- package/src/commands/ref.ts +53 -8
- package/src/control-api/client.ts +0 -1
- package/src/control-api/contract-enrichment.ts +6 -42
- package/src/control-api/operations/contract-emit.ts +7 -2
- package/src/control-api/operations/db-verify.ts +9 -5
- package/src/control-api/operations/migration-apply.ts +36 -23
- package/src/control-api/types.ts +3 -10
- package/src/migration-cli.ts +4 -4
- package/src/utils/cli-errors.ts +234 -0
- package/src/utils/command-helpers.ts +1 -20
- package/src/utils/contract-at-errors.ts +96 -0
- package/src/utils/contract-space-aggregate-loader.ts +336 -117
- package/src/utils/formatters/migration-list-data-column.ts +115 -0
- package/src/utils/formatters/migration-list-graph-layout.ts +268 -0
- package/src/utils/formatters/migration-list-graph-render.ts +311 -0
- package/src/utils/formatters/migration-list-graph-topology.ts +158 -0
- package/src/utils/formatters/migration-list-render.ts +191 -0
- package/src/utils/formatters/migration-list-styler.ts +61 -0
- package/src/utils/formatters/migration-list-types.ts +21 -0
- package/src/utils/formatters/migrations.ts +29 -38
- package/src/utils/glyph-mode.ts +22 -0
- package/src/utils/integrity-violation-to-check-failure.ts +130 -0
- package/src/utils/plan-resolution.ts +258 -0
- package/src/utils/ref-advancement.ts +68 -0
- package/src/utils/terminal-ui.ts +42 -1
- package/dist/cli-errors-Czmx92Zy.d.mts +0 -3
- package/dist/cli-errors-Djtz98Vm.mjs +0 -71
- package/dist/cli-errors-Djtz98Vm.mjs.map +0 -1
- package/dist/client-oXO2WCPD.mjs.map +0 -1
- package/dist/command-helpers-DtavI0wJ.mjs.map +0 -1
- package/dist/commands/migration-check.mjs.map +0 -1
- package/dist/commands/migration-list.mjs.map +0 -1
- package/dist/contract-enrichment-Dani0mMW.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs +0 -160
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs.map +0 -1
- package/dist/global-flags-CdE7M0d9.d.mts +0 -15
- package/dist/global-flags-CdE7M0d9.d.mts.map +0 -1
- package/dist/migration-plan-C2jeH1J5.mjs.map +0 -1
- package/dist/migrations-CwZMa1Ck.mjs.map +0 -1
- package/dist/rolldown-runtime-twds-ZHy.mjs +0 -14
- package/dist/terminal-ui-BiB_8KNo.mjs +0 -379
- package/dist/terminal-ui-BiB_8KNo.mjs.map +0 -1
- package/dist/types-C9FfXb1l.d.mts.map +0 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { IntegrityViolation } from '@prisma-next/migration-tools/aggregate';
|
|
2
|
+
import { join, relative } from 'pathe';
|
|
3
|
+
|
|
4
|
+
export interface CheckFailure {
|
|
5
|
+
readonly pnCode: string;
|
|
6
|
+
readonly where: string;
|
|
7
|
+
readonly why: string;
|
|
8
|
+
readonly fix: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function migrationPathRelative(dirPath: string): string {
|
|
12
|
+
return relative(process.cwd(), dirPath);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function migrationFileRelative(dirPath: string, fileName: string): string {
|
|
16
|
+
return join(migrationPathRelative(dirPath), fileName);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Map one {@link IntegrityViolation} onto a `migration check` failure row.
|
|
21
|
+
* Sole catalogue mapping from integrity violations to `PN-MIG-CHECK-*`.
|
|
22
|
+
*/
|
|
23
|
+
export function integrityViolationToCheckFailure(
|
|
24
|
+
violation: IntegrityViolation,
|
|
25
|
+
migrationsDir: string,
|
|
26
|
+
): CheckFailure {
|
|
27
|
+
const spaceRelative = (spaceId: string): string =>
|
|
28
|
+
migrationPathRelative(join(migrationsDir, spaceId));
|
|
29
|
+
const packageRelative = (spaceId: string, dirName: string): string =>
|
|
30
|
+
migrationPathRelative(join(migrationsDir, spaceId, dirName));
|
|
31
|
+
const refRelative = (spaceId: string, refName: string): string =>
|
|
32
|
+
migrationPathRelative(join(migrationsDir, spaceId, 'refs', `${refName}.json`));
|
|
33
|
+
|
|
34
|
+
switch (violation.kind) {
|
|
35
|
+
case 'hashMismatch':
|
|
36
|
+
return {
|
|
37
|
+
pnCode: 'PN-MIG-CHECK-001',
|
|
38
|
+
where: migrationFileRelative(
|
|
39
|
+
join(migrationsDir, violation.spaceId, violation.dirName),
|
|
40
|
+
'migration.json',
|
|
41
|
+
),
|
|
42
|
+
why: `Stored hash ${violation.stored} does not match recomputed hash ${violation.computed}`,
|
|
43
|
+
fix: 'Re-emit the migration package or restore from version control.',
|
|
44
|
+
};
|
|
45
|
+
case 'providedInvariantsMismatch':
|
|
46
|
+
return {
|
|
47
|
+
pnCode: 'PN-MIG-CHECK-002',
|
|
48
|
+
where: packageRelative(violation.spaceId, violation.dirName),
|
|
49
|
+
why: `Migration "${violation.dirName}" providedInvariants in migration.json disagrees with ops.json.`,
|
|
50
|
+
fix: 'Re-emit the migration package so migration.json and ops.json agree.',
|
|
51
|
+
};
|
|
52
|
+
case 'packageUnloadable':
|
|
53
|
+
return {
|
|
54
|
+
pnCode: 'PN-MIG-CHECK-002',
|
|
55
|
+
where: packageRelative(violation.spaceId, violation.dirName),
|
|
56
|
+
why: `Migration "${violation.dirName}" could not be loaded: ${violation.detail}`,
|
|
57
|
+
fix: 'Re-emit the migration package or restore from version control.',
|
|
58
|
+
};
|
|
59
|
+
case 'sameSourceAndTarget':
|
|
60
|
+
return {
|
|
61
|
+
pnCode: 'PN-MIG-CHECK-007',
|
|
62
|
+
where: packageRelative(violation.spaceId, violation.dirName),
|
|
63
|
+
why: `Migration "${violation.dirName}" in space "${violation.spaceId}" has source equal to target (${violation.hash}) with no data invariant — a true no-op self-edge.`,
|
|
64
|
+
fix: 'Add a data operation if this self-edge was meant to carry a data invariant, or delete the migration if it is a true no-op.',
|
|
65
|
+
};
|
|
66
|
+
case 'orphanSpaceDir':
|
|
67
|
+
return {
|
|
68
|
+
pnCode: 'PN-MIG-CHECK-008',
|
|
69
|
+
where: spaceRelative(violation.spaceId),
|
|
70
|
+
why: `Contract-space directory "${violation.spaceId}" exists on disk but no extension declares it.`,
|
|
71
|
+
fix: 'Remove the orphan directory, or declare the extension in `extensionPacks`.',
|
|
72
|
+
};
|
|
73
|
+
case 'declaredButUnmigrated':
|
|
74
|
+
return {
|
|
75
|
+
pnCode: 'PN-MIG-CHECK-009',
|
|
76
|
+
where: spaceRelative(violation.spaceId),
|
|
77
|
+
why: `Extension "${violation.spaceId}" is declared in \`extensionPacks\` but has no on-disk migrations directory.`,
|
|
78
|
+
fix: 'Re-emit the extension contract-space artefacts with `prisma-next contract emit` and migration planning, or remove the extension from `extensionPacks` if it is unused.',
|
|
79
|
+
};
|
|
80
|
+
case 'headRefMissing':
|
|
81
|
+
return {
|
|
82
|
+
pnCode: 'PN-MIG-CHECK-010',
|
|
83
|
+
where: refRelative(violation.spaceId, 'head'),
|
|
84
|
+
why: `Head ref \`refs/head.json\` is missing for contract space "${violation.spaceId}".`,
|
|
85
|
+
fix: 'Re-emit the contract-space migrations and head ref artefacts, or restore `refs/head.json` from version control.',
|
|
86
|
+
};
|
|
87
|
+
case 'headRefNotInGraph':
|
|
88
|
+
return {
|
|
89
|
+
pnCode: 'PN-MIG-CHECK-011',
|
|
90
|
+
where: refRelative(violation.spaceId, 'head'),
|
|
91
|
+
why: `Head ref ${violation.hash} for contract space "${violation.spaceId}" is not present in its migration graph.`,
|
|
92
|
+
fix: 'Re-emit the contract space migrations, or restore the missing migration package.',
|
|
93
|
+
};
|
|
94
|
+
case 'refUnreadable':
|
|
95
|
+
return {
|
|
96
|
+
pnCode: 'PN-MIG-CHECK-012',
|
|
97
|
+
where: refRelative(violation.spaceId, violation.refName),
|
|
98
|
+
why: `Ref "${violation.refName}" for contract space "${violation.spaceId}" is unreadable: ${violation.detail}`,
|
|
99
|
+
fix: 'Repair or remove the corrupt ref file.',
|
|
100
|
+
};
|
|
101
|
+
case 'targetMismatch':
|
|
102
|
+
return {
|
|
103
|
+
pnCode: 'PN-MIG-CHECK-013',
|
|
104
|
+
where: spaceRelative(violation.spaceId),
|
|
105
|
+
why: `Contract space "${violation.spaceId}" targets "${violation.actual}" but the project targets "${violation.expected}".`,
|
|
106
|
+
fix: 'Update the extension to target the configured database, or change the project target.',
|
|
107
|
+
};
|
|
108
|
+
case 'disjointness':
|
|
109
|
+
return {
|
|
110
|
+
pnCode: 'PN-MIG-CHECK-014',
|
|
111
|
+
where: migrationPathRelative(migrationsDir),
|
|
112
|
+
why: `Storage element "${violation.element}" is claimed by multiple contract spaces: ${violation.claimedBy.join(', ')}.`,
|
|
113
|
+
fix: 'Update the contracts so each storage element is owned by exactly one contract space.',
|
|
114
|
+
};
|
|
115
|
+
case 'contractUnreadable':
|
|
116
|
+
return {
|
|
117
|
+
pnCode: 'PN-MIG-CHECK-015',
|
|
118
|
+
where: migrationFileRelative(join(migrationsDir, violation.spaceId), 'contract.json'),
|
|
119
|
+
why: `Contract for space "${violation.spaceId}" is unreadable: ${violation.detail}`,
|
|
120
|
+
fix: 'Re-emit the extension contract artefacts, or fix the descriptor producing the invalid contract.',
|
|
121
|
+
};
|
|
122
|
+
case 'duplicateMigrationHash':
|
|
123
|
+
return {
|
|
124
|
+
pnCode: 'PN-MIG-CHECK-016',
|
|
125
|
+
where: spaceRelative(violation.spaceId),
|
|
126
|
+
why: `Multiple migrations in space "${violation.spaceId}" share migrationHash "${violation.migrationHash}" (${violation.dirNames.join(', ')}).`,
|
|
127
|
+
fix: 'Re-emit one of the conflicting packages so each migrationHash is unique.',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import type { Contract } from '@prisma-next/contract/types';
|
|
2
|
+
import type { ContractSpaceMember } from '@prisma-next/migration-tools/aggregate';
|
|
3
|
+
import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
4
|
+
import type { MigrationGraph } from '@prisma-next/migration-tools/graph';
|
|
5
|
+
import {
|
|
6
|
+
assertHashIsGraphNode,
|
|
7
|
+
findLatestMigration,
|
|
8
|
+
isGraphNode,
|
|
9
|
+
} from '@prisma-next/migration-tools/migration-graph';
|
|
10
|
+
import type { ContractRef } from '@prisma-next/migration-tools/ref-resolution';
|
|
11
|
+
import { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';
|
|
12
|
+
import type { Refs } from '@prisma-next/migration-tools/refs';
|
|
13
|
+
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
14
|
+
import {
|
|
15
|
+
CliStructuredError,
|
|
16
|
+
errorPlanForgotTheFlag,
|
|
17
|
+
errorSnapshotMissing,
|
|
18
|
+
mapRefResolutionError,
|
|
19
|
+
} from './cli-errors';
|
|
20
|
+
import { mapContractAtError } from './contract-at-errors';
|
|
21
|
+
|
|
22
|
+
const FULL_HASH_PATTERN = /^sha256:([0-9a-f]{64}|empty)$/;
|
|
23
|
+
|
|
24
|
+
export function looksLikeFullHash(input: string): boolean {
|
|
25
|
+
return FULL_HASH_PATTERN.test(input);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type FromResolution =
|
|
29
|
+
| { kind: 'greenfield'; fromHash: null; fromContract: null }
|
|
30
|
+
| { kind: 'graph-node'; fromHash: string; fromContract: Contract; sourceDir: string }
|
|
31
|
+
| {
|
|
32
|
+
kind: 'snapshot';
|
|
33
|
+
fromHash: string;
|
|
34
|
+
fromContract: Contract;
|
|
35
|
+
contractDts: string;
|
|
36
|
+
contractJson: unknown;
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
kind: 'auto-baseline';
|
|
40
|
+
fromHash: string;
|
|
41
|
+
fromContract: Contract;
|
|
42
|
+
contractDts: string;
|
|
43
|
+
contractJson: unknown;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export interface ResolveFromForPlanInput {
|
|
47
|
+
readonly optionsFrom?: string | undefined;
|
|
48
|
+
readonly member: ContractSpaceMember;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function graphIsEmpty(member: ContractSpaceMember): boolean {
|
|
52
|
+
return member.packages.length === 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getReachableRefs(
|
|
56
|
+
refs: Refs,
|
|
57
|
+
graph: MigrationGraph,
|
|
58
|
+
): ReadonlyArray<{ name: string; hash: string }> {
|
|
59
|
+
return Object.entries(refs)
|
|
60
|
+
.flatMap(([name, entry]) =>
|
|
61
|
+
entry && isGraphNode(entry.hash, graph) ? [{ name, hash: entry.hash }] : [],
|
|
62
|
+
)
|
|
63
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function assertFromIsGraphNode(
|
|
67
|
+
fromHash: string,
|
|
68
|
+
graph: MigrationGraph,
|
|
69
|
+
refs: Refs,
|
|
70
|
+
graphTipHash: string | null,
|
|
71
|
+
): void {
|
|
72
|
+
try {
|
|
73
|
+
assertHashIsGraphNode(fromHash, graph);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (MigrationToolsError.is(error) && error.code === 'MIGRATION.HASH_NOT_IN_GRAPH') {
|
|
76
|
+
throw errorPlanForgotTheFlag(fromHash, getReachableRefs(refs, graph), graphTipHash);
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type RefContractResolution =
|
|
83
|
+
| {
|
|
84
|
+
kind: 'snapshot';
|
|
85
|
+
hash: string;
|
|
86
|
+
contract: Contract;
|
|
87
|
+
contractJson: unknown;
|
|
88
|
+
contractDts: string;
|
|
89
|
+
}
|
|
90
|
+
| {
|
|
91
|
+
kind: 'graph-node';
|
|
92
|
+
hash: string;
|
|
93
|
+
contract: Contract;
|
|
94
|
+
contractJson: unknown;
|
|
95
|
+
contractDts: string;
|
|
96
|
+
sourceDir: string;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
async function resolveContractRef(
|
|
100
|
+
parsed: ContractRef,
|
|
101
|
+
member: ContractSpaceMember,
|
|
102
|
+
options?: { readonly explicitLabel?: string; readonly artifactRole?: 'from' | 'to' },
|
|
103
|
+
): Promise<Result<RefContractResolution, CliStructuredError>> {
|
|
104
|
+
const { hash, provenance } = parsed;
|
|
105
|
+
const refName = provenance.kind === 'ref' ? provenance.refName : undefined;
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
const at = await member.contractAt(hash, refName !== undefined ? { refName } : undefined);
|
|
109
|
+
|
|
110
|
+
if (at.provenance === 'snapshot') {
|
|
111
|
+
return ok({
|
|
112
|
+
kind: 'snapshot',
|
|
113
|
+
hash: at.hash,
|
|
114
|
+
contract: at.contract,
|
|
115
|
+
contractJson: at.contractJson,
|
|
116
|
+
contractDts: at.contractDts,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return ok({
|
|
121
|
+
kind: 'graph-node',
|
|
122
|
+
hash: at.hash,
|
|
123
|
+
contract: at.contract,
|
|
124
|
+
contractJson: at.contractJson,
|
|
125
|
+
contractDts: at.contractDts,
|
|
126
|
+
sourceDir: at.sourceDir,
|
|
127
|
+
});
|
|
128
|
+
} catch (error) {
|
|
129
|
+
return mapContractAtError(
|
|
130
|
+
error,
|
|
131
|
+
options?.artifactRole !== undefined ? { artifactRole: options.artifactRole } : undefined,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function resolveFromPolicy(
|
|
137
|
+
parsed: ContractRef,
|
|
138
|
+
input: ResolveFromForPlanInput,
|
|
139
|
+
refs: Refs,
|
|
140
|
+
explicitFromLabel?: string,
|
|
141
|
+
): Promise<Result<FromResolution, CliStructuredError>> {
|
|
142
|
+
const resolution = await resolveContractRef(parsed, input.member, {
|
|
143
|
+
...(explicitFromLabel !== undefined ? { explicitLabel: explicitFromLabel } : {}),
|
|
144
|
+
artifactRole: 'from',
|
|
145
|
+
});
|
|
146
|
+
if (!resolution.ok) {
|
|
147
|
+
return resolution;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (resolution.value.kind === 'graph-node') {
|
|
151
|
+
return ok({
|
|
152
|
+
kind: 'graph-node',
|
|
153
|
+
fromHash: resolution.value.hash,
|
|
154
|
+
fromContract: resolution.value.contract,
|
|
155
|
+
sourceDir: resolution.value.sourceDir,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const { hash, contract, contractJson, contractDts } = resolution.value;
|
|
160
|
+
if (graphIsEmpty(input.member)) {
|
|
161
|
+
return ok({
|
|
162
|
+
kind: 'auto-baseline',
|
|
163
|
+
fromHash: hash,
|
|
164
|
+
fromContract: contract,
|
|
165
|
+
contractDts,
|
|
166
|
+
contractJson,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const graph = input.member.graph();
|
|
171
|
+
const graphTip = findLatestMigration(graph)?.to ?? null;
|
|
172
|
+
try {
|
|
173
|
+
assertFromIsGraphNode(hash, graph, refs, graphTip);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
if (CliStructuredError.is(error)) {
|
|
176
|
+
return notOk(error);
|
|
177
|
+
}
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
return ok({
|
|
181
|
+
kind: 'snapshot',
|
|
182
|
+
fromHash: hash,
|
|
183
|
+
fromContract: contract,
|
|
184
|
+
contractDts,
|
|
185
|
+
contractJson,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export async function resolveFromForPlan(
|
|
190
|
+
input: ResolveFromForPlanInput,
|
|
191
|
+
): Promise<Result<FromResolution, CliStructuredError>> {
|
|
192
|
+
const { optionsFrom, member } = input;
|
|
193
|
+
const graph = member.graph();
|
|
194
|
+
const refs = member.refs;
|
|
195
|
+
|
|
196
|
+
if (optionsFrom === undefined) {
|
|
197
|
+
const dbRef = refs['db'];
|
|
198
|
+
if (!dbRef) {
|
|
199
|
+
return ok({ kind: 'greenfield', fromHash: null, fromContract: null });
|
|
200
|
+
}
|
|
201
|
+
return resolveFromPolicy(
|
|
202
|
+
{ hash: dbRef.hash, provenance: { kind: 'ref', refName: 'db' } },
|
|
203
|
+
input,
|
|
204
|
+
refs,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const refResult = parseContractRef(optionsFrom, { graph, refs });
|
|
209
|
+
if (!refResult.ok) {
|
|
210
|
+
if (looksLikeFullHash(optionsFrom)) {
|
|
211
|
+
const empty = graphIsEmpty(member);
|
|
212
|
+
const graphTip = findLatestMigration(graph)?.to ?? null;
|
|
213
|
+
if (empty) {
|
|
214
|
+
return notOk(errorSnapshotMissing(optionsFrom, { viaRef: false }));
|
|
215
|
+
}
|
|
216
|
+
return notOk(errorPlanForgotTheFlag(optionsFrom, getReachableRefs(refs, graph), graphTip));
|
|
217
|
+
}
|
|
218
|
+
return notOk(mapRefResolutionError(refResult.failure));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return resolveFromPolicy(refResult.value, input, refs, optionsFrom);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface ResolveToForPlanInput {
|
|
225
|
+
readonly member: ContractSpaceMember;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export interface ResolvedContractRef {
|
|
229
|
+
readonly hash: string;
|
|
230
|
+
readonly contract: Contract;
|
|
231
|
+
readonly contractJson: unknown;
|
|
232
|
+
readonly contractDts: string;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export async function resolveToForPlan(
|
|
236
|
+
optionsTo: string,
|
|
237
|
+
input: ResolveToForPlanInput,
|
|
238
|
+
): Promise<Result<ResolvedContractRef, CliStructuredError>> {
|
|
239
|
+
const { member } = input;
|
|
240
|
+
const graph = member.graph();
|
|
241
|
+
const refs = member.refs;
|
|
242
|
+
|
|
243
|
+
const refResult = parseContractRef(optionsTo, { graph, refs });
|
|
244
|
+
if (!refResult.ok) {
|
|
245
|
+
return notOk(mapRefResolutionError(refResult.failure));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const resolution = await resolveContractRef(refResult.value, member, {
|
|
249
|
+
explicitLabel: optionsTo,
|
|
250
|
+
artifactRole: 'to',
|
|
251
|
+
});
|
|
252
|
+
if (!resolution.ok) {
|
|
253
|
+
return resolution;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const { hash, contract, contractJson, contractDts } = resolution.value;
|
|
257
|
+
return ok({ hash, contract, contractJson, contractDts });
|
|
258
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import type { ContractIR } from '@prisma-next/migration-tools/refs';
|
|
3
|
+
import { writeRefPaired } from '@prisma-next/migration-tools/refs';
|
|
4
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
5
|
+
|
|
6
|
+
export interface RefAdvancementFields {
|
|
7
|
+
readonly advancedRef: { readonly name: string; readonly hash: string } | null;
|
|
8
|
+
readonly plannedAdvanceRef: { readonly name: string; readonly hash: string } | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function computeRefAdvancementName(options: {
|
|
12
|
+
readonly advanceRef?: string;
|
|
13
|
+
readonly db?: string;
|
|
14
|
+
}): string | null {
|
|
15
|
+
if (options.advanceRef !== undefined) {
|
|
16
|
+
return options.advanceRef;
|
|
17
|
+
}
|
|
18
|
+
if (options.db === undefined) {
|
|
19
|
+
return 'db';
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function readContractIR(
|
|
25
|
+
contractJson: Record<string, unknown>,
|
|
26
|
+
contractJsonPath: string,
|
|
27
|
+
): Promise<ContractIR> {
|
|
28
|
+
const contractDtsPath = contractJsonPath.replace(/\.json$/i, '.d.ts');
|
|
29
|
+
const contractDts = await readFile(contractDtsPath, 'utf-8');
|
|
30
|
+
return { contract: contractJson, contractDts };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function executeRefAdvancement(
|
|
34
|
+
refsDir: string,
|
|
35
|
+
name: string,
|
|
36
|
+
hash: string,
|
|
37
|
+
contractIR: ContractIR,
|
|
38
|
+
): Promise<{ name: string; hash: string }> {
|
|
39
|
+
await writeRefPaired(refsDir, name, { hash, invariants: [] }, contractIR);
|
|
40
|
+
return { name, hash };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function buildRefAdvancementFields(options: {
|
|
44
|
+
readonly advanceRef?: string;
|
|
45
|
+
readonly db?: string;
|
|
46
|
+
readonly refsDir: string;
|
|
47
|
+
readonly contractIR: ContractIR;
|
|
48
|
+
readonly mode: 'plan' | 'apply';
|
|
49
|
+
readonly hash: string;
|
|
50
|
+
}): Promise<RefAdvancementFields> {
|
|
51
|
+
const name = computeRefAdvancementName({
|
|
52
|
+
...ifDefined('advanceRef', options.advanceRef),
|
|
53
|
+
...ifDefined('db', options.db),
|
|
54
|
+
});
|
|
55
|
+
if (name === null) {
|
|
56
|
+
return { advancedRef: null, plannedAdvanceRef: null };
|
|
57
|
+
}
|
|
58
|
+
if (options.mode === 'plan') {
|
|
59
|
+
return { advancedRef: null, plannedAdvanceRef: { name, hash: options.hash } };
|
|
60
|
+
}
|
|
61
|
+
const advancedRef = await executeRefAdvancement(
|
|
62
|
+
options.refsDir,
|
|
63
|
+
name,
|
|
64
|
+
options.hash,
|
|
65
|
+
options.contractIR,
|
|
66
|
+
);
|
|
67
|
+
return { advancedRef, plannedAdvanceRef: null };
|
|
68
|
+
}
|
package/src/utils/terminal-ui.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as clack from '@clack/prompts';
|
|
2
2
|
import { bold, cyan, dim, green, red, yellow } from 'colorette';
|
|
3
3
|
import type { GlobalFlags } from './global-flags';
|
|
4
|
+
import { detectGlyphMode, type GlyphMode, type GlyphModeInput } from './glyph-mode';
|
|
4
5
|
import { shutdownSignal } from './shutdown';
|
|
5
6
|
|
|
7
|
+
export interface TerminalUIRuntime extends GlyphModeInput {}
|
|
8
|
+
|
|
6
9
|
/**
|
|
7
10
|
* Composable CLI output abstraction.
|
|
8
11
|
*
|
|
@@ -36,17 +39,50 @@ export class TerminalUI {
|
|
|
36
39
|
*/
|
|
37
40
|
readonly forcePretty: boolean;
|
|
38
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Whether stdout is a TTY — used for migration-list graph glyph detection.
|
|
44
|
+
*/
|
|
45
|
+
readonly stdoutIsTTY: boolean;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Process environment snapshot for locale-aware glyph detection.
|
|
49
|
+
*/
|
|
50
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
51
|
+
|
|
39
52
|
private static readonly stderrOpts = { output: process.stderr } as const;
|
|
40
53
|
|
|
41
54
|
constructor(options?: {
|
|
42
55
|
readonly color?: boolean | undefined;
|
|
43
56
|
readonly interactive?: boolean | undefined;
|
|
44
57
|
readonly forcePretty?: boolean | undefined;
|
|
58
|
+
readonly stdoutIsTTY?: boolean | undefined;
|
|
59
|
+
readonly env?: Readonly<Record<string, string | undefined>> | undefined;
|
|
45
60
|
}) {
|
|
46
61
|
// --interactive/--no-interactive override TTY detection
|
|
47
62
|
this.isInteractive = options?.interactive ?? !!process.stdout.isTTY;
|
|
48
63
|
this.forcePretty = options?.forcePretty ?? false;
|
|
49
64
|
this.useColor = options?.color ?? (this.isInteractive || this.forcePretty);
|
|
65
|
+
this.stdoutIsTTY = options?.stdoutIsTTY ?? !!process.stdout.isTTY;
|
|
66
|
+
this.env = options?.env ?? process.env;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get isTTY(): boolean {
|
|
70
|
+
return this.stdoutIsTTY;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Resolve graph glyph mode for `migration list --graph`. `--ascii` forces
|
|
75
|
+
* ASCII; otherwise delegates to the pure {@link detectGlyphMode} helper.
|
|
76
|
+
*/
|
|
77
|
+
resolveGlyphMode(forceAscii: boolean): GlyphMode {
|
|
78
|
+
if (forceAscii) {
|
|
79
|
+
return 'ascii';
|
|
80
|
+
}
|
|
81
|
+
return detectGlyphMode(this.glyphModeInput());
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
glyphModeInput(): GlyphModeInput {
|
|
85
|
+
return { isTTY: this.stdoutIsTTY, env: this.env };
|
|
50
86
|
}
|
|
51
87
|
|
|
52
88
|
private get shouldDecorate(): boolean {
|
|
@@ -288,10 +324,15 @@ export class TerminalUI {
|
|
|
288
324
|
}
|
|
289
325
|
}
|
|
290
326
|
|
|
291
|
-
export function createTerminalUI(
|
|
327
|
+
export function createTerminalUI(
|
|
328
|
+
flags: GlobalFlags,
|
|
329
|
+
runtime?: Partial<TerminalUIRuntime>,
|
|
330
|
+
): TerminalUI {
|
|
292
331
|
return new TerminalUI({
|
|
293
332
|
color: flags.color,
|
|
294
333
|
interactive: flags.interactive,
|
|
295
334
|
forcePretty: flags.format === 'pretty' && flags.explicitFormat,
|
|
335
|
+
stdoutIsTTY: runtime?.isTTY,
|
|
336
|
+
env: runtime?.env,
|
|
296
337
|
});
|
|
297
338
|
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { CliStructuredError as CliStructuredError$1, errorConfigValidation as errorConfigValidation$1, errorContractConfigMissing as errorContractConfigMissing$1, errorContractValidationFailed, errorDatabaseConnectionRequired, errorDriverRequired, errorFileNotFound, errorInvalidOutputFormat, errorMigrationPlanningFailed, errorOutputFormatMutex, errorTargetMigrationNotSupported, errorUnexpected as errorUnexpected$1 } from "@prisma-next/errors/control";
|
|
2
|
-
import { ERROR_CODE_DESTRUCTIVE_CHANGES, errorDestructiveChanges, errorHashMismatch, errorMarkerMissing, errorRunnerFailed, errorRuntime, errorRuntime as errorRuntime$1, errorTargetMismatch } from "@prisma-next/errors/execution";
|
|
3
|
-
import "@prisma-next/errors/migration";
|
|
4
|
-
//#region src/utils/cli-errors.ts
|
|
5
|
-
/**
|
|
6
|
-
* Maps a `MigrationToolsError` raised by the migration-tools loader/graph
|
|
7
|
-
* surface (`readMigrationPackage`, `readMigrationsDir`, `readRefs`,
|
|
8
|
-
* `resolveRef`, `reconstructGraph`, ...) into a CLI `errorRuntime` envelope.
|
|
9
|
-
*
|
|
10
|
-
* The full `error.details` payload is forwarded into `meta` so machine
|
|
11
|
-
* consumers (`--json`) see structural fields like `dir`, `storedHash`,
|
|
12
|
-
* `computedHash` (for `MIGRATION.HASH_MISMATCH`) alongside the stable
|
|
13
|
-
* `code`. The user-visible `summary`/`why`/`fix` text is unchanged.
|
|
14
|
-
*
|
|
15
|
-
* Callers are expected to gate on `MigrationToolsError.is(error)` first
|
|
16
|
-
* (mirroring the original inline pattern); non-`MigrationToolsError`
|
|
17
|
-
* values are caller-classified (rethrow, wrap with command-specific
|
|
18
|
-
* `errorUnexpected`, etc.).
|
|
19
|
-
*/
|
|
20
|
-
function mapMigrationToolsError(error) {
|
|
21
|
-
return errorRuntime(error.message, {
|
|
22
|
-
why: error.why,
|
|
23
|
-
fix: error.fix,
|
|
24
|
-
meta: {
|
|
25
|
-
code: error.code,
|
|
26
|
-
...error.details ?? {}
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Maps a `RefResolutionError` from the contract/migration reference
|
|
32
|
-
* resolver into a CLI structured error envelope.
|
|
33
|
-
*/
|
|
34
|
-
function mapRefResolutionError(error) {
|
|
35
|
-
switch (error.kind) {
|
|
36
|
-
case "not-found": return errorRuntime(`Not a known ${error.grammar} reference: "${error.input}"`, {
|
|
37
|
-
why: `No ${error.grammar} matching "${error.input}" exists in the migration graph or refs index.`,
|
|
38
|
-
fix: error.grammar === "contract" ? "Provide a valid contract hash, ref name, or migration directory name." : "Provide a valid migration directory name or migration hash.",
|
|
39
|
-
meta: {
|
|
40
|
-
input: error.input,
|
|
41
|
-
grammar: error.grammar
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
case "ambiguous": return errorRuntime(`Ambiguous ${error.grammar} reference: "${error.input}"`, {
|
|
45
|
-
why: `"${error.input}" matches multiple ${error.grammar}s: ${error.candidates.join(", ")}`,
|
|
46
|
-
fix: "Provide a longer prefix or use the full hash to disambiguate.",
|
|
47
|
-
meta: {
|
|
48
|
-
input: error.input,
|
|
49
|
-
candidates: error.candidates,
|
|
50
|
-
grammar: error.grammar
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
case "wrong-grammar": return errorRuntime(error.message, {
|
|
54
|
-
why: error.message,
|
|
55
|
-
fix: error.fix,
|
|
56
|
-
meta: {
|
|
57
|
-
input: error.input,
|
|
58
|
-
expectedGrammar: error.expectedGrammar
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
case "invalid-format": return errorRuntime(`Invalid reference format: "${error.input}"`, {
|
|
62
|
-
why: error.reason,
|
|
63
|
-
fix: "Provide a valid contract hash, ref name, or migration directory name.",
|
|
64
|
-
meta: { input: error.input }
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
//#endregion
|
|
69
|
-
export { errorTargetMigrationNotSupported as _, errorContractValidationFailed as a, mapMigrationToolsError as b, errorDriverRequired as c, errorInvalidOutputFormat as d, errorMarkerMissing as f, errorRuntime$1 as g, errorRunnerFailed as h, errorContractConfigMissing$1 as i, errorFileNotFound as l, errorOutputFormatMutex as m, ERROR_CODE_DESTRUCTIVE_CHANGES as n, errorDatabaseConnectionRequired as o, errorMigrationPlanningFailed as p, errorConfigValidation$1 as r, errorDestructiveChanges as s, CliStructuredError$1 as t, errorHashMismatch as u, errorTargetMismatch as v, mapRefResolutionError as x, errorUnexpected$1 as y };
|
|
70
|
-
|
|
71
|
-
//# sourceMappingURL=cli-errors-Djtz98Vm.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-errors-Djtz98Vm.mjs","names":[],"sources":["../src/utils/cli-errors.ts"],"sourcesContent":["/**\n * Re-export all domain error factories from @prisma-next/errors for convenience.\n * CLI-specific errors (e.g., Commander argument validation in the main CLI, or\n * clipanion parse errors in the migration-file CLI) can be added here if needed.\n */\nexport type { CliErrorConflict, CliErrorEnvelope } from '@prisma-next/errors/control';\n\nimport {\n CliStructuredError,\n errorConfigFileNotFound,\n errorConfigValidation,\n errorContractConfigMissing,\n errorContractMissingExtensionPacks,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFamilyReadMarkerSqlRequired,\n errorFileNotFound,\n errorInvalidOutputFormat,\n errorMigrationCliInvalidConfigArg,\n errorMigrationCliUnknownFlag,\n errorMigrationPlanningFailed,\n errorOutputFormatMutex,\n errorQueryRunnerFactoryRequired,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from '@prisma-next/errors/control';\nimport { errorRuntime } from '@prisma-next/errors/execution';\nimport type { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport type { RefResolutionError } from '@prisma-next/migration-tools/ref-resolution';\n\nexport {\n ERROR_CODE_DESTRUCTIVE_CHANGES,\n errorDestructiveChanges,\n errorHashMismatch,\n errorMarkerMissing,\n errorMarkerRequired,\n errorRunnerFailed,\n errorRuntime,\n errorSchemaVerificationFailed,\n errorTargetMismatch,\n} from '@prisma-next/errors/execution';\nexport {\n errorMigrationFileMissing,\n errorMigrationInvalidDefaultExport,\n errorMigrationPlanNotArray,\n errorUnfilledPlaceholder,\n placeholder,\n} from '@prisma-next/errors/migration';\nexport {\n CliStructuredError,\n errorConfigFileNotFound,\n errorConfigValidation,\n errorContractConfigMissing,\n errorContractMissingExtensionPacks,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFamilyReadMarkerSqlRequired,\n errorFileNotFound,\n errorInvalidOutputFormat,\n errorMigrationCliInvalidConfigArg,\n errorMigrationCliUnknownFlag,\n errorMigrationPlanningFailed,\n errorOutputFormatMutex,\n errorQueryRunnerFactoryRequired,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n};\n\n/**\n * Maps a `MigrationToolsError` raised by the migration-tools loader/graph\n * surface (`readMigrationPackage`, `readMigrationsDir`, `readRefs`,\n * `resolveRef`, `reconstructGraph`, ...) into a CLI `errorRuntime` envelope.\n *\n * The full `error.details` payload is forwarded into `meta` so machine\n * consumers (`--json`) see structural fields like `dir`, `storedHash`,\n * `computedHash` (for `MIGRATION.HASH_MISMATCH`) alongside the stable\n * `code`. The user-visible `summary`/`why`/`fix` text is unchanged.\n *\n * Callers are expected to gate on `MigrationToolsError.is(error)` first\n * (mirroring the original inline pattern); non-`MigrationToolsError`\n * values are caller-classified (rethrow, wrap with command-specific\n * `errorUnexpected`, etc.).\n */\nexport function mapMigrationToolsError(error: MigrationToolsError): CliStructuredError {\n return errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n });\n}\n\n/**\n * Maps a `RefResolutionError` from the contract/migration reference\n * resolver into a CLI structured error envelope.\n */\nexport function mapRefResolutionError(error: RefResolutionError): CliStructuredError {\n switch (error.kind) {\n case 'not-found':\n return errorRuntime(`Not a known ${error.grammar} reference: \"${error.input}\"`, {\n why: `No ${error.grammar} matching \"${error.input}\" exists in the migration graph or refs index.`,\n fix:\n error.grammar === 'contract'\n ? 'Provide a valid contract hash, ref name, or migration directory name.'\n : 'Provide a valid migration directory name or migration hash.',\n meta: { input: error.input, grammar: error.grammar },\n });\n case 'ambiguous':\n return errorRuntime(`Ambiguous ${error.grammar} reference: \"${error.input}\"`, {\n why: `\"${error.input}\" matches multiple ${error.grammar}s: ${error.candidates.join(', ')}`,\n fix: 'Provide a longer prefix or use the full hash to disambiguate.',\n meta: { input: error.input, candidates: error.candidates, grammar: error.grammar },\n });\n case 'wrong-grammar':\n return errorRuntime(error.message, {\n why: error.message,\n fix: error.fix,\n meta: { input: error.input, expectedGrammar: error.expectedGrammar },\n });\n case 'invalid-format':\n return errorRuntime(`Invalid reference format: \"${error.input}\"`, {\n why: error.reason,\n fix: 'Provide a valid contract hash, ref name, or migration directory name.',\n meta: { input: error.input },\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqFA,SAAgB,uBAAuB,OAAgD;CACrF,OAAO,aAAa,MAAM,SAAS;EACjC,KAAK,MAAM;EACX,KAAK,MAAM;EACX,MAAM;GAAE,MAAM,MAAM;GAAM,GAAI,MAAM,WAAW,EAAE;GAAG;EACrD,CAAC;;;;;;AAOJ,SAAgB,sBAAsB,OAA+C;CACnF,QAAQ,MAAM,MAAd;EACE,KAAK,aACH,OAAO,aAAa,eAAe,MAAM,QAAQ,eAAe,MAAM,MAAM,IAAI;GAC9E,KAAK,MAAM,MAAM,QAAQ,aAAa,MAAM,MAAM;GAClD,KACE,MAAM,YAAY,aACd,0EACA;GACN,MAAM;IAAE,OAAO,MAAM;IAAO,SAAS,MAAM;IAAS;GACrD,CAAC;EACJ,KAAK,aACH,OAAO,aAAa,aAAa,MAAM,QAAQ,eAAe,MAAM,MAAM,IAAI;GAC5E,KAAK,IAAI,MAAM,MAAM,qBAAqB,MAAM,QAAQ,KAAK,MAAM,WAAW,KAAK,KAAK;GACxF,KAAK;GACL,MAAM;IAAE,OAAO,MAAM;IAAO,YAAY,MAAM;IAAY,SAAS,MAAM;IAAS;GACnF,CAAC;EACJ,KAAK,iBACH,OAAO,aAAa,MAAM,SAAS;GACjC,KAAK,MAAM;GACX,KAAK,MAAM;GACX,MAAM;IAAE,OAAO,MAAM;IAAO,iBAAiB,MAAM;IAAiB;GACrE,CAAC;EACJ,KAAK,kBACH,OAAO,aAAa,8BAA8B,MAAM,MAAM,IAAI;GAChE,KAAK,MAAM;GACX,KAAK;GACL,MAAM,EAAE,OAAO,MAAM,OAAO;GAC7B,CAAC"}
|