@prisma-next/cli 0.5.0-dev.2 → 0.5.0-dev.21
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 +54 -21
- package/dist/agent-skill-mongo.md +63 -31
- package/dist/agent-skill-postgres.md +1 -1
- package/dist/{cli-errors-C0JhVj0c.d.mts → cli-errors-BJLUczXT.d.mts} +1 -0
- package/dist/cli-errors-By1iVE3z.mjs +34 -0
- package/dist/cli-errors-By1iVE3z.mjs.map +1 -0
- package/dist/cli.mjs +127 -13
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-TG7rbCWT.mjs → client-enZIahga.mjs} +20 -5
- package/dist/client-enZIahga.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts.map +1 -1
- package/dist/commands/contract-emit.mjs +7 -2
- package/dist/commands/contract-infer.mjs +8 -2
- package/dist/commands/db-init.mjs +9 -8
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +8 -5
- package/dist/commands/db-schema.mjs.map +1 -1
- package/dist/commands/db-sign.mjs +8 -7
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.mjs +9 -8
- package/dist/commands/db-update.mjs.map +1 -1
- package/dist/commands/db-verify.mjs +10 -9
- package/dist/commands/db-verify.mjs.map +1 -1
- package/dist/commands/migration-apply.d.mts +1 -1
- package/dist/commands/migration-apply.d.mts.map +1 -1
- package/dist/commands/migration-apply.mjs +15 -38
- package/dist/commands/migration-apply.mjs.map +1 -1
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +24 -28
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +6 -3
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +38 -38
- package/dist/commands/migration-plan.mjs.map +1 -1
- package/dist/commands/migration-ref.d.mts +6 -4
- package/dist/commands/migration-ref.d.mts.map +1 -1
- package/dist/commands/migration-ref.mjs +31 -40
- package/dist/commands/migration-ref.mjs.map +1 -1
- package/dist/commands/migration-show.d.mts +4 -4
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +19 -26
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +5 -4
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +7 -2
- package/dist/{config-loader-_W4T21X1.mjs → config-loader-ih8ViDb_.mjs} +2 -2
- package/dist/config-loader-ih8ViDb_.mjs.map +1 -0
- package/dist/config-loader.mjs +1 -1
- package/dist/contract-emit-DS5NzZh2.mjs +6 -0
- package/dist/contract-emit-DWtGQYCD.mjs +150 -0
- package/dist/contract-emit-DWtGQYCD.mjs.map +1 -0
- package/dist/contract-emit-RZBWzkop.mjs +329 -0
- package/dist/contract-emit-RZBWzkop.mjs.map +1 -0
- package/dist/{contract-enrichment-CGW6mm-E.mjs → contract-enrichment-4Ptgw3Pe.mjs} +1 -1
- package/dist/{contract-enrichment-CGW6mm-E.mjs.map → contract-enrichment-4Ptgw3Pe.mjs.map} +1 -1
- package/dist/{contract-infer-BP3DrGgz.mjs → contract-infer-BjzkcwQt.mjs} +5 -5
- package/dist/{contract-infer-BP3DrGgz.mjs.map → contract-infer-BjzkcwQt.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +41 -16
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +7 -5
- package/dist/exports/index.mjs +8 -3
- package/dist/exports/index.mjs.map +1 -1
- package/dist/exports/init-output.d.mts +39 -0
- package/dist/exports/init-output.d.mts.map +1 -0
- package/dist/exports/init-output.mjs +3 -0
- package/dist/{extract-operation-statements-DZUJNmL3.mjs → extract-operation-statements-CU-Pp4-N.mjs} +2 -2
- package/dist/{extract-operation-statements-DZUJNmL3.mjs.map → extract-operation-statements-CU-Pp4-N.mjs.map} +1 -1
- package/dist/{extract-sql-ddl-DDMX-9mz.mjs → extract-sql-ddl-Bm0Mm0IT.mjs} +1 -1
- package/dist/{extract-sql-ddl-DDMX-9mz.mjs.map → extract-sql-ddl-Bm0Mm0IT.mjs.map} +1 -1
- package/dist/{framework-components-DfZKQBQ2.mjs → framework-components-Bgcre3Z6.mjs} +2 -2
- package/dist/{framework-components-DfZKQBQ2.mjs.map → framework-components-Bgcre3Z6.mjs.map} +1 -1
- package/dist/init-C-H-if1m.mjs +2062 -0
- package/dist/init-C-H-if1m.mjs.map +1 -0
- package/dist/{inspect-live-schema-DWzf4Q_m.mjs → inspect-live-schema-QklSDLt_.mjs} +6 -6
- package/dist/{inspect-live-schema-DWzf4Q_m.mjs.map → inspect-live-schema-QklSDLt_.mjs.map} +1 -1
- package/dist/migration-cli.mjs +15 -8
- package/dist/migration-cli.mjs.map +1 -1
- package/dist/{migration-command-scaffold-CLMD302g.mjs → migration-command-scaffold-BfloSWPZ.mjs} +7 -7
- package/dist/{migration-command-scaffold-CLMD302g.mjs.map → migration-command-scaffold-BfloSWPZ.mjs.map} +1 -1
- package/dist/{migration-status-B0HLF7So.mjs → migration-status-C5VYA5r9.mjs} +21 -35
- package/dist/migration-status-C5VYA5r9.mjs.map +1 -0
- package/dist/{migrations-B0dOQlk0.mjs → migrations-CSaDHNpB.mjs} +3 -3
- package/dist/migrations-CSaDHNpB.mjs.map +1 -0
- package/dist/output-BiO7kt87.mjs +103 -0
- package/dist/output-BiO7kt87.mjs.map +1 -0
- package/dist/{progress-adapter-B-YvmcDu.mjs → progress-adapter-DgRGldpT.mjs} +1 -1
- package/dist/{progress-adapter-B-YvmcDu.mjs.map → progress-adapter-DgRGldpT.mjs.map} +1 -1
- package/dist/quick-reference-mongo.md +34 -13
- package/dist/quick-reference-postgres.md +11 -9
- package/dist/{result-handler-CIyu0Pdt.mjs → result-handler-BmVh8AeV.mjs} +12 -93
- package/dist/result-handler-BmVh8AeV.mjs.map +1 -0
- package/dist/{terminal-ui-C5k88MmW.mjs → terminal-ui-u2YgKghu.mjs} +76 -2
- package/dist/terminal-ui-u2YgKghu.mjs.map +1 -0
- package/dist/{verify-BxiVp50b.mjs → verify-BumcH6Ry.mjs} +2 -2
- package/dist/{verify-BxiVp50b.mjs.map → verify-BumcH6Ry.mjs.map} +1 -1
- package/package.json +20 -15
- package/src/commands/contract-emit.ts +67 -163
- package/src/commands/init/detect-pnpm-catalog.ts +141 -0
- package/src/commands/init/errors.ts +254 -0
- package/src/commands/init/exit-codes.ts +62 -0
- package/src/commands/init/hygiene-gitattributes.ts +97 -0
- package/src/commands/init/hygiene-gitignore.ts +48 -0
- package/src/commands/init/hygiene-package-scripts.ts +91 -0
- package/src/commands/init/index.ts +112 -7
- package/src/commands/init/init.ts +766 -144
- package/src/commands/init/inputs.ts +421 -0
- package/src/commands/init/output.ts +147 -0
- package/src/commands/init/probe-db.ts +308 -0
- package/src/commands/init/reinit-cleanup.ts +83 -0
- package/src/commands/init/templates/agent-skill-mongo.md +63 -31
- package/src/commands/init/templates/agent-skill-postgres.md +1 -1
- package/src/commands/init/templates/agent-skill.ts +25 -3
- package/src/commands/init/templates/code-templates.ts +125 -32
- package/src/commands/init/templates/env.ts +80 -0
- package/src/commands/init/templates/quick-reference-mongo.md +34 -13
- package/src/commands/init/templates/quick-reference-postgres.md +11 -9
- package/src/commands/init/templates/quick-reference.ts +42 -3
- package/src/commands/init/templates/tsconfig.ts +167 -5
- package/src/commands/migration-apply.ts +15 -50
- package/src/commands/migration-new.ts +24 -28
- package/src/commands/migration-plan.ts +58 -42
- package/src/commands/migration-ref.ts +40 -54
- package/src/commands/migration-show.ts +27 -28
- package/src/commands/migration-status.ts +33 -50
- package/src/config-path-validation.ts +0 -1
- package/src/control-api/operations/contract-emit.ts +198 -115
- package/src/control-api/operations/migration-apply.ts +15 -0
- package/src/control-api/types.ts +22 -3
- package/src/exports/control-api.ts +2 -1
- package/src/exports/init-output.ts +10 -0
- package/src/migration-cli.ts +16 -9
- package/src/utils/cli-errors.ts +45 -1
- package/src/utils/command-helpers.ts +13 -26
- package/src/utils/emit-queue.ts +26 -0
- package/src/utils/formatters/graph-migration-mapper.ts +2 -2
- package/src/utils/formatters/migrations.ts +2 -2
- package/src/utils/publish-contract-artifact-pair.ts +134 -0
- package/dist/cli-errors-DHq6GQGu.mjs +0 -5
- package/dist/client-TG7rbCWT.mjs.map +0 -1
- package/dist/config-loader-_W4T21X1.mjs.map +0 -1
- package/dist/contract-emit-CNYyzJwF.mjs +0 -195
- package/dist/contract-emit-CNYyzJwF.mjs.map +0 -1
- package/dist/contract-emit-CQfj7xJn.mjs +0 -122
- package/dist/contract-emit-CQfj7xJn.mjs.map +0 -1
- package/dist/contract-emit-fhNwwhkQ.mjs +0 -4
- package/dist/init-CQfo_4Ro.mjs +0 -430
- package/dist/init-CQfo_4Ro.mjs.map +0 -1
- package/dist/migration-status-B0HLF7So.mjs.map +0 -1
- package/dist/migrations-B0dOQlk0.mjs.map +0 -1
- package/dist/result-handler-CIyu0Pdt.mjs.map +0 -1
- package/dist/terminal-ui-C5k88MmW.mjs.map +0 -1
- package/dist/validate-contract-deps-esa-VQ0h.mjs +0 -37
- package/dist/validate-contract-deps-esa-VQ0h.mjs.map +0 -1
|
@@ -1,17 +1,27 @@
|
|
|
1
|
+
import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
2
|
+
import type { RefEntry } from '@prisma-next/migration-tools/refs';
|
|
1
3
|
import {
|
|
4
|
+
deleteRef,
|
|
5
|
+
readRef,
|
|
2
6
|
readRefs,
|
|
3
|
-
resolveRef,
|
|
4
7
|
validateRefName,
|
|
5
8
|
validateRefValue,
|
|
6
|
-
|
|
9
|
+
writeRef,
|
|
7
10
|
} from '@prisma-next/migration-tools/refs';
|
|
8
|
-
import { MigrationToolsError } from '@prisma-next/migration-tools/types';
|
|
9
11
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
10
12
|
import { Command } from 'commander';
|
|
11
|
-
import { resolve } from 'pathe';
|
|
12
13
|
import { loadConfig } from '../config-loader';
|
|
13
|
-
import {
|
|
14
|
-
|
|
14
|
+
import {
|
|
15
|
+
CliStructuredError,
|
|
16
|
+
errorRuntime,
|
|
17
|
+
errorUnexpected,
|
|
18
|
+
mapMigrationToolsError,
|
|
19
|
+
} from '../utils/cli-errors';
|
|
20
|
+
import {
|
|
21
|
+
addGlobalOptions,
|
|
22
|
+
resolveMigrationPaths,
|
|
23
|
+
setCommandDescriptions,
|
|
24
|
+
} from '../utils/command-helpers';
|
|
15
25
|
import { formatCommandHelp } from '../utils/formatters/help';
|
|
16
26
|
import { parseGlobalFlags } from '../utils/global-flags';
|
|
17
27
|
import { handleResult } from '../utils/result-handler';
|
|
@@ -21,12 +31,14 @@ interface RefSetResult {
|
|
|
21
31
|
readonly ok: true;
|
|
22
32
|
readonly ref: string;
|
|
23
33
|
readonly hash: string;
|
|
34
|
+
readonly invariants: readonly string[];
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
interface RefGetResult {
|
|
27
38
|
readonly ok: true;
|
|
28
39
|
readonly ref: string;
|
|
29
40
|
readonly hash: string;
|
|
41
|
+
readonly invariants: readonly string[];
|
|
30
42
|
}
|
|
31
43
|
|
|
32
44
|
interface RefDeleteResult {
|
|
@@ -37,21 +49,12 @@ interface RefDeleteResult {
|
|
|
37
49
|
|
|
38
50
|
interface RefListResult {
|
|
39
51
|
readonly ok: true;
|
|
40
|
-
readonly refs: Record<string,
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function resolveRefsPath(configPath?: string, config?: { migrations?: { dir?: string } }): string {
|
|
44
|
-
const base = configPath ? resolve(configPath, '..') : process.cwd();
|
|
45
|
-
return resolve(base, config?.migrations?.dir ?? 'migrations', 'refs.json');
|
|
52
|
+
readonly refs: Record<string, RefEntry>;
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
function mapError(error: unknown): CliStructuredError {
|
|
49
56
|
if (MigrationToolsError.is(error)) {
|
|
50
|
-
return
|
|
51
|
-
why: error.why,
|
|
52
|
-
fix: error.fix,
|
|
53
|
-
meta: { code: error.code },
|
|
54
|
-
});
|
|
57
|
+
return mapMigrationToolsError(error);
|
|
55
58
|
}
|
|
56
59
|
return errorUnexpected(error instanceof Error ? error.message : String(error));
|
|
57
60
|
}
|
|
@@ -70,13 +73,6 @@ function cliErrorInvalidRefValue(hash: string): CliStructuredError {
|
|
|
70
73
|
});
|
|
71
74
|
}
|
|
72
75
|
|
|
73
|
-
function errorRefNotFound(name: string): CliStructuredError {
|
|
74
|
-
return errorRuntime(`Ref "${name}" does not exist`, {
|
|
75
|
-
why: `No ref named "${name}" found in refs.json`,
|
|
76
|
-
fix: `Run \`prisma-next migration ref list\` to see available refs, or \`prisma-next migration ref set ${name} <hash>\` to create it`,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
76
|
async function executeRefSetCommand(
|
|
81
77
|
name: string,
|
|
82
78
|
hash: string,
|
|
@@ -91,11 +87,10 @@ async function executeRefSetCommand(
|
|
|
91
87
|
|
|
92
88
|
try {
|
|
93
89
|
const config = await loadConfig(options.config);
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return ok({ ok: true as const, ref: name, hash });
|
|
90
|
+
const { refsDir } = resolveMigrationPaths(options.config, config);
|
|
91
|
+
const entry: RefEntry = { hash, invariants: [] };
|
|
92
|
+
await writeRef(refsDir, name, entry);
|
|
93
|
+
return ok({ ok: true as const, ref: name, hash, invariants: [] });
|
|
99
94
|
} catch (error) {
|
|
100
95
|
if (error instanceof CliStructuredError) return notOk(error);
|
|
101
96
|
return notOk(mapError(error));
|
|
@@ -108,10 +103,9 @@ async function executeRefGetCommand(
|
|
|
108
103
|
): Promise<Result<RefGetResult, CliStructuredError>> {
|
|
109
104
|
try {
|
|
110
105
|
const config = await loadConfig(options.config);
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
const hash
|
|
114
|
-
return ok({ ok: true as const, ref: name, hash });
|
|
106
|
+
const { refsDir } = resolveMigrationPaths(options.config, config);
|
|
107
|
+
const entry = await readRef(refsDir, name);
|
|
108
|
+
return ok({ ok: true as const, ref: name, hash: entry.hash, invariants: entry.invariants });
|
|
115
109
|
} catch (error) {
|
|
116
110
|
if (error instanceof CliStructuredError) return notOk(error);
|
|
117
111
|
return notOk(mapError(error));
|
|
@@ -124,13 +118,8 @@ async function executeRefDeleteCommand(
|
|
|
124
118
|
): Promise<Result<RefDeleteResult, CliStructuredError>> {
|
|
125
119
|
try {
|
|
126
120
|
const config = await loadConfig(options.config);
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
if (!Object.hasOwn(refs, name)) {
|
|
130
|
-
return notOk(errorRefNotFound(name));
|
|
131
|
-
}
|
|
132
|
-
const { [name]: _, ...remaining } = refs;
|
|
133
|
-
await writeRefs(refsPath, remaining);
|
|
121
|
+
const { refsDir } = resolveMigrationPaths(options.config, config);
|
|
122
|
+
await deleteRef(refsDir, name);
|
|
134
123
|
return ok({ ok: true as const, ref: name, deleted: true as const });
|
|
135
124
|
} catch (error) {
|
|
136
125
|
if (error instanceof CliStructuredError) return notOk(error);
|
|
@@ -143,8 +132,8 @@ async function executeRefListCommand(options: {
|
|
|
143
132
|
}): Promise<Result<RefListResult, CliStructuredError>> {
|
|
144
133
|
try {
|
|
145
134
|
const config = await loadConfig(options.config);
|
|
146
|
-
const
|
|
147
|
-
const refs = await readRefs(
|
|
135
|
+
const { refsDir } = resolveMigrationPaths(options.config, config);
|
|
136
|
+
const refs = await readRefs(refsDir);
|
|
148
137
|
return ok({ ok: true as const, refs });
|
|
149
138
|
} catch (error) {
|
|
150
139
|
if (error instanceof CliStructuredError) return notOk(error);
|
|
@@ -157,7 +146,7 @@ function createRefSetCommand(): Command {
|
|
|
157
146
|
setCommandDescriptions(
|
|
158
147
|
command,
|
|
159
148
|
'Set a ref to a contract hash',
|
|
160
|
-
'Sets a named ref to point to a contract hash in migrations/refs
|
|
149
|
+
'Sets a named ref to point to a contract hash in migrations/refs/.',
|
|
161
150
|
);
|
|
162
151
|
addGlobalOptions(command)
|
|
163
152
|
.argument('<name>', 'Ref name (e.g., staging, production)')
|
|
@@ -190,7 +179,7 @@ function createRefGetCommand(): Command {
|
|
|
190
179
|
setCommandDescriptions(
|
|
191
180
|
command,
|
|
192
181
|
'Get the hash for a ref',
|
|
193
|
-
'Reads a named ref from migrations/refs
|
|
182
|
+
'Reads a named ref from migrations/refs/ and prints its contract hash.',
|
|
194
183
|
);
|
|
195
184
|
addGlobalOptions(command)
|
|
196
185
|
.argument('<name>', 'Ref name to look up')
|
|
@@ -218,7 +207,7 @@ function createRefGetCommand(): Command {
|
|
|
218
207
|
|
|
219
208
|
function createRefDeleteCommand(): Command {
|
|
220
209
|
const command = new Command('delete');
|
|
221
|
-
setCommandDescriptions(command, 'Delete a ref', 'Removes a named ref from migrations/refs
|
|
210
|
+
setCommandDescriptions(command, 'Delete a ref', 'Removes a named ref from migrations/refs/.');
|
|
222
211
|
addGlobalOptions(command)
|
|
223
212
|
.argument('<name>', 'Ref name to delete')
|
|
224
213
|
.option('--config <path>', 'Path to prisma-next.config.ts')
|
|
@@ -245,11 +234,7 @@ function createRefDeleteCommand(): Command {
|
|
|
245
234
|
|
|
246
235
|
function createRefListCommand(): Command {
|
|
247
236
|
const command = new Command('list');
|
|
248
|
-
setCommandDescriptions(
|
|
249
|
-
command,
|
|
250
|
-
'List all refs',
|
|
251
|
-
'Lists all named refs from migrations/refs.json.',
|
|
252
|
-
);
|
|
237
|
+
setCommandDescriptions(command, 'List all refs', 'Lists all named refs from migrations/refs/.');
|
|
253
238
|
addGlobalOptions(command)
|
|
254
239
|
.option('--config <path>', 'Path to prisma-next.config.ts')
|
|
255
240
|
.action(async (options: { config?: string; json?: string | boolean; quiet?: boolean }) => {
|
|
@@ -264,8 +249,10 @@ function createRefListCommand(): Command {
|
|
|
264
249
|
if (entries.length === 0) {
|
|
265
250
|
ui.output('No refs defined');
|
|
266
251
|
} else {
|
|
267
|
-
for (const [refName,
|
|
268
|
-
|
|
252
|
+
for (const [refName, entry] of entries) {
|
|
253
|
+
const invariantsSuffix =
|
|
254
|
+
entry.invariants.length > 0 ? ` [invariants: ${entry.invariants.join(', ')}]` : '';
|
|
255
|
+
ui.output(`${refName} → ${entry.hash}${invariantsSuffix}`);
|
|
269
256
|
}
|
|
270
257
|
}
|
|
271
258
|
}
|
|
@@ -282,7 +269,6 @@ export {
|
|
|
282
269
|
executeRefListCommand,
|
|
283
270
|
cliErrorInvalidRefName,
|
|
284
271
|
cliErrorInvalidRefValue,
|
|
285
|
-
errorRefNotFound,
|
|
286
272
|
};
|
|
287
273
|
|
|
288
274
|
export function createMigrationRefCommand(): Command {
|
|
@@ -290,7 +276,7 @@ export function createMigrationRefCommand(): Command {
|
|
|
290
276
|
setCommandDescriptions(
|
|
291
277
|
command,
|
|
292
278
|
'Manage migration refs',
|
|
293
|
-
'Manage named refs in migrations/refs
|
|
279
|
+
'Manage named refs in migrations/refs/. Refs map logical environment\n' +
|
|
294
280
|
'names (e.g., staging, production) to contract hashes.',
|
|
295
281
|
);
|
|
296
282
|
addGlobalOptions(command).configureHelp({
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';
|
|
2
|
-
import {
|
|
2
|
+
import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
3
3
|
import { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';
|
|
4
|
-
import
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
findLatestMigration,
|
|
6
|
+
reconstructGraph,
|
|
7
|
+
} from '@prisma-next/migration-tools/migration-graph';
|
|
8
|
+
import type { MigrationPackage } from '@prisma-next/migration-tools/package';
|
|
6
9
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
7
10
|
import { Command } from 'commander';
|
|
8
11
|
import { relative, resolve } from 'pathe';
|
|
9
12
|
import { loadConfig } from '../config-loader';
|
|
10
13
|
import { extractOperationStatements } from '../control-api/operations/extract-operation-statements';
|
|
11
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
type CliStructuredError,
|
|
16
|
+
errorRuntime,
|
|
17
|
+
errorUnexpected,
|
|
18
|
+
mapMigrationToolsError,
|
|
19
|
+
} from '../utils/cli-errors';
|
|
12
20
|
import {
|
|
13
21
|
addGlobalOptions,
|
|
14
22
|
setCommandDescriptions,
|
|
@@ -31,7 +39,7 @@ export interface MigrationShowResult {
|
|
|
31
39
|
readonly dirPath: string;
|
|
32
40
|
readonly from: string;
|
|
33
41
|
readonly to: string;
|
|
34
|
-
readonly
|
|
42
|
+
readonly migrationHash: string;
|
|
35
43
|
readonly kind: string;
|
|
36
44
|
readonly createdAt: string;
|
|
37
45
|
readonly operations: readonly {
|
|
@@ -48,11 +56,11 @@ function looksLikePath(target: string): boolean {
|
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
export function resolveByHashPrefix(
|
|
51
|
-
packages: readonly
|
|
59
|
+
packages: readonly MigrationPackage[],
|
|
52
60
|
prefix: string,
|
|
53
|
-
): Result<
|
|
61
|
+
): Result<MigrationPackage, CliStructuredError> {
|
|
54
62
|
const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;
|
|
55
|
-
const matches = packages.filter((p) => p.
|
|
63
|
+
const matches = packages.filter((p) => p.metadata.migrationHash.startsWith(normalizedPrefix));
|
|
56
64
|
|
|
57
65
|
if (matches.length === 1) {
|
|
58
66
|
return ok(matches[0]!);
|
|
@@ -61,13 +69,13 @@ export function resolveByHashPrefix(
|
|
|
61
69
|
if (matches.length === 0) {
|
|
62
70
|
return notOk(
|
|
63
71
|
errorRuntime('No migration found matching prefix', {
|
|
64
|
-
why: `No migration has a
|
|
72
|
+
why: `No migration has a migrationHash starting with "${normalizedPrefix}"`,
|
|
65
73
|
fix: 'Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages.',
|
|
66
74
|
}),
|
|
67
75
|
);
|
|
68
76
|
}
|
|
69
77
|
|
|
70
|
-
const candidates = matches.map((p) => ` ${p.dirName} ${p.
|
|
78
|
+
const candidates = matches.map((p) => ` ${p.dirName} ${p.metadata.migrationHash}`).join('\n');
|
|
71
79
|
return notOk(
|
|
72
80
|
errorRuntime('Ambiguous hash prefix', {
|
|
73
81
|
why: `Multiple migrations match prefix "${normalizedPrefix}":\n${candidates}`,
|
|
@@ -110,7 +118,7 @@ async function executeMigrationShowCommand(
|
|
|
110
118
|
ui.stderr(header);
|
|
111
119
|
}
|
|
112
120
|
|
|
113
|
-
let pkg:
|
|
121
|
+
let pkg: MigrationPackage;
|
|
114
122
|
|
|
115
123
|
try {
|
|
116
124
|
if (target && looksLikePath(target)) {
|
|
@@ -142,7 +150,7 @@ async function executeMigrationShowCommand(
|
|
|
142
150
|
);
|
|
143
151
|
}
|
|
144
152
|
const leafPkg = allPackages.find(
|
|
145
|
-
(p) => p.
|
|
153
|
+
(p) => p.metadata.migrationHash === latestMigration.migrationHash,
|
|
146
154
|
);
|
|
147
155
|
if (!leafPkg) {
|
|
148
156
|
return notOk(
|
|
@@ -157,13 +165,7 @@ async function executeMigrationShowCommand(
|
|
|
157
165
|
}
|
|
158
166
|
} catch (error) {
|
|
159
167
|
if (MigrationToolsError.is(error)) {
|
|
160
|
-
return notOk(
|
|
161
|
-
errorRuntime(error.message, {
|
|
162
|
-
why: error.why,
|
|
163
|
-
fix: error.fix,
|
|
164
|
-
meta: { code: error.code, ...(error.details ?? {}) },
|
|
165
|
-
}),
|
|
166
|
-
);
|
|
168
|
+
return notOk(mapMigrationToolsError(error));
|
|
167
169
|
}
|
|
168
170
|
return notOk(
|
|
169
171
|
errorUnexpected(error instanceof Error ? error.message : String(error), {
|
|
@@ -179,11 +181,11 @@ async function executeMigrationShowCommand(
|
|
|
179
181
|
ok: true,
|
|
180
182
|
dirName: pkg.dirName,
|
|
181
183
|
dirPath: relative(process.cwd(), pkg.dirPath),
|
|
182
|
-
from: pkg.
|
|
183
|
-
to: pkg.
|
|
184
|
-
|
|
185
|
-
kind: pkg.
|
|
186
|
-
createdAt: pkg.
|
|
184
|
+
from: pkg.metadata.from,
|
|
185
|
+
to: pkg.metadata.to,
|
|
186
|
+
migrationHash: pkg.metadata.migrationHash,
|
|
187
|
+
kind: pkg.metadata.kind,
|
|
188
|
+
createdAt: pkg.metadata.createdAt,
|
|
187
189
|
operations: ops.map((op) => ({
|
|
188
190
|
id: op.id,
|
|
189
191
|
label: op.label,
|
|
@@ -209,10 +211,7 @@ export function createMigrationShowCommand(): Command {
|
|
|
209
211
|
'prisma-next migration show sha256:a1b2c3',
|
|
210
212
|
]);
|
|
211
213
|
addGlobalOptions(command)
|
|
212
|
-
.argument(
|
|
213
|
-
'[target]',
|
|
214
|
-
'Migration directory path or migrationId hash prefix (defaults to latest)',
|
|
215
|
-
)
|
|
214
|
+
.argument('[target]', 'Migration directory path or migrationHash prefix (defaults to latest)')
|
|
216
215
|
.option('--config <path>', 'Path to prisma-next.config.ts')
|
|
217
216
|
.action(async (target: string | undefined, options: MigrationShowOptions) => {
|
|
218
217
|
const flags = parseGlobalFlags(options);
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';
|
|
2
2
|
import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';
|
|
3
|
+
import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
4
|
+
import type { MigrationEdge, MigrationGraph } from '@prisma-next/migration-tools/graph';
|
|
3
5
|
import {
|
|
4
6
|
findPath,
|
|
5
7
|
findPathWithDecision,
|
|
6
8
|
findReachableLeaves,
|
|
7
|
-
} from '@prisma-next/migration-tools/
|
|
9
|
+
} from '@prisma-next/migration-tools/migration-graph';
|
|
10
|
+
import type { MigrationPackage } from '@prisma-next/migration-tools/package';
|
|
8
11
|
import type { Refs } from '@prisma-next/migration-tools/refs';
|
|
9
12
|
import { readRefs, resolveRef } from '@prisma-next/migration-tools/refs';
|
|
10
|
-
import type {
|
|
11
|
-
MigrationBundle,
|
|
12
|
-
MigrationChainEntry,
|
|
13
|
-
MigrationGraph,
|
|
14
|
-
} from '@prisma-next/migration-tools/types';
|
|
15
|
-
import { MigrationToolsError } from '@prisma-next/migration-tools/types';
|
|
16
13
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
17
14
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
18
15
|
import { cyan, dim, magenta, yellow } from 'colorette';
|
|
@@ -20,10 +17,15 @@ import { Command } from 'commander';
|
|
|
20
17
|
|
|
21
18
|
import { loadConfig } from '../config-loader';
|
|
22
19
|
import { createControlClient } from '../control-api/client';
|
|
23
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
type CliStructuredError,
|
|
22
|
+
errorRuntime,
|
|
23
|
+
errorUnexpected,
|
|
24
|
+
mapMigrationToolsError,
|
|
25
|
+
} from '../utils/cli-errors';
|
|
24
26
|
import {
|
|
25
27
|
addGlobalOptions,
|
|
26
|
-
|
|
28
|
+
loadMigrationPackages,
|
|
27
29
|
maskConnectionUrl,
|
|
28
30
|
readContractEnvelope,
|
|
29
31
|
resolveMigrationPaths,
|
|
@@ -61,7 +63,7 @@ export interface MigrationStatusEntry {
|
|
|
61
63
|
readonly dirName: string;
|
|
62
64
|
readonly from: string;
|
|
63
65
|
readonly to: string;
|
|
64
|
-
readonly
|
|
66
|
+
readonly migrationHash: string;
|
|
65
67
|
readonly operationCount: number;
|
|
66
68
|
readonly operationSummary: string;
|
|
67
69
|
readonly hasDestructive: boolean;
|
|
@@ -86,7 +88,7 @@ export interface MigrationStatusResult {
|
|
|
86
88
|
readonly refName?: string;
|
|
87
89
|
readonly selectedPath: readonly {
|
|
88
90
|
readonly dirName: string;
|
|
89
|
-
readonly
|
|
91
|
+
readonly migrationHash: string;
|
|
90
92
|
readonly from: string;
|
|
91
93
|
readonly to: string;
|
|
92
94
|
}[];
|
|
@@ -94,7 +96,7 @@ export interface MigrationStatusResult {
|
|
|
94
96
|
readonly summary: string;
|
|
95
97
|
readonly diagnostics: readonly StatusDiagnostic[];
|
|
96
98
|
readonly graph?: MigrationGraph;
|
|
97
|
-
readonly bundles?: readonly
|
|
99
|
+
readonly bundles?: readonly MigrationPackage[];
|
|
98
100
|
readonly edgeStatuses?: readonly EdgeStatus[];
|
|
99
101
|
readonly activeRefHash?: string;
|
|
100
102
|
readonly activeRefName?: string;
|
|
@@ -154,7 +156,7 @@ export function deriveEdgeStatuses(
|
|
|
154
156
|
): EdgeStatus[] {
|
|
155
157
|
if (mode === 'offline') return [];
|
|
156
158
|
|
|
157
|
-
const edgeKey = (e:
|
|
159
|
+
const edgeKey = (e: MigrationEdge) => `${e.from}\0${e.to}`;
|
|
158
160
|
|
|
159
161
|
// No marker = empty DB — treat root as the marker (nothing applied, everything pending)
|
|
160
162
|
const effectiveMarker = markerHash ?? EMPTY_CONTRACT_HASH;
|
|
@@ -224,8 +226,8 @@ export function deriveEdgeStatuses(
|
|
|
224
226
|
* @param markerHash — the marker hash from the database, or undefined if no marker row / offline
|
|
225
227
|
*/
|
|
226
228
|
function buildMigrationEntries(
|
|
227
|
-
chain: readonly
|
|
228
|
-
packages: readonly
|
|
229
|
+
chain: readonly MigrationEdge[],
|
|
230
|
+
packages: readonly MigrationPackage[],
|
|
229
231
|
mode: 'online' | 'offline',
|
|
230
232
|
markerHash: string | undefined,
|
|
231
233
|
edgeStatuses?: readonly EdgeStatus[],
|
|
@@ -261,7 +263,7 @@ function buildMigrationEntries(
|
|
|
261
263
|
dirName: migration.dirName,
|
|
262
264
|
from: migration.from,
|
|
263
265
|
to: migration.to,
|
|
264
|
-
|
|
266
|
+
migrationHash: migration.migrationHash,
|
|
265
267
|
operationCount: ops.length,
|
|
266
268
|
operationSummary: summary,
|
|
267
269
|
hasDestructive,
|
|
@@ -294,7 +296,7 @@ function resolveDisplayChain(
|
|
|
294
296
|
graph: MigrationGraph,
|
|
295
297
|
targetHash: string,
|
|
296
298
|
markerHash: string | undefined,
|
|
297
|
-
): readonly
|
|
299
|
+
): readonly MigrationEdge[] | null {
|
|
298
300
|
if (markerHash === undefined) {
|
|
299
301
|
return findPath(graph, EMPTY_CONTRACT_HASH, targetHash);
|
|
300
302
|
}
|
|
@@ -345,7 +347,7 @@ async function executeMigrationStatusCommand(
|
|
|
345
347
|
ui: TerminalUI,
|
|
346
348
|
): Promise<Result<MigrationStatusResult, CliStructuredError>> {
|
|
347
349
|
const config = await loadConfig(options.config);
|
|
348
|
-
const { configPath, migrationsDir, migrationsRelative,
|
|
350
|
+
const { configPath, migrationsDir, migrationsRelative, refsDir } = resolveMigrationPaths(
|
|
349
351
|
options.config,
|
|
350
352
|
config,
|
|
351
353
|
);
|
|
@@ -357,46 +359,29 @@ async function executeMigrationStatusCommand(
|
|
|
357
359
|
let activeRefHash: string | undefined;
|
|
358
360
|
let allRefs: Refs = {};
|
|
359
361
|
try {
|
|
360
|
-
allRefs = await readRefs(
|
|
362
|
+
allRefs = await readRefs(refsDir);
|
|
361
363
|
} catch (error) {
|
|
362
364
|
if (MigrationToolsError.is(error)) {
|
|
363
|
-
return notOk(
|
|
364
|
-
errorRuntime(error.message, {
|
|
365
|
-
why: error.why,
|
|
366
|
-
fix: error.fix,
|
|
367
|
-
meta: { code: error.code },
|
|
368
|
-
}),
|
|
369
|
-
);
|
|
365
|
+
return notOk(mapMigrationToolsError(error));
|
|
370
366
|
}
|
|
371
367
|
throw error;
|
|
372
368
|
}
|
|
373
369
|
|
|
374
370
|
if (options.ref) {
|
|
375
371
|
activeRefName = options.ref;
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
activeRefHash = resolveRef(allRefs, activeRefName);
|
|
382
|
-
} catch (error) {
|
|
383
|
-
if (MigrationToolsError.is(error)) {
|
|
384
|
-
return notOk(
|
|
385
|
-
errorRuntime(error.message, {
|
|
386
|
-
why: error.why,
|
|
387
|
-
fix: error.fix,
|
|
388
|
-
meta: { code: error.code },
|
|
389
|
-
}),
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
throw error;
|
|
372
|
+
try {
|
|
373
|
+
activeRefHash = resolveRef(allRefs, activeRefName).hash;
|
|
374
|
+
} catch (error) {
|
|
375
|
+
if (MigrationToolsError.is(error)) {
|
|
376
|
+
return notOk(mapMigrationToolsError(error));
|
|
393
377
|
}
|
|
378
|
+
throw error;
|
|
394
379
|
}
|
|
395
380
|
}
|
|
396
381
|
|
|
397
|
-
const statusRefs: StatusRef[] = Object.entries(allRefs).map(([name,
|
|
382
|
+
const statusRefs: StatusRef[] = Object.entries(allRefs).map(([name, entry]) => ({
|
|
398
383
|
name,
|
|
399
|
-
hash,
|
|
384
|
+
hash: entry.hash,
|
|
400
385
|
active: name === activeRefName,
|
|
401
386
|
}));
|
|
402
387
|
|
|
@@ -434,15 +419,13 @@ async function executeMigrationStatusCommand(
|
|
|
434
419
|
});
|
|
435
420
|
}
|
|
436
421
|
|
|
437
|
-
let bundles: readonly
|
|
422
|
+
let bundles: readonly MigrationPackage[];
|
|
438
423
|
let graph: MigrationGraph;
|
|
439
424
|
try {
|
|
440
|
-
({ bundles, graph } = await
|
|
425
|
+
({ bundles, graph } = await loadMigrationPackages(migrationsDir));
|
|
441
426
|
} catch (error) {
|
|
442
427
|
if (MigrationToolsError.is(error)) {
|
|
443
|
-
return notOk(
|
|
444
|
-
errorRuntime(error.message, { why: error.why, fix: error.fix, meta: { code: error.code } }),
|
|
445
|
-
);
|
|
428
|
+
return notOk(mapMigrationToolsError(error));
|
|
446
429
|
}
|
|
447
430
|
return notOk(
|
|
448
431
|
errorUnexpected(error instanceof Error ? error.message : String(error), {
|
|
@@ -57,7 +57,6 @@ export function finalizeConfig(config: PrismaNextConfig, configDir: string): Pri
|
|
|
57
57
|
if (!config.contract) {
|
|
58
58
|
return config;
|
|
59
59
|
}
|
|
60
|
-
|
|
61
60
|
const contract = normalizeContractConfig(config.contract);
|
|
62
61
|
const source = finalizeContractSource(contract.source, configDir);
|
|
63
62
|
const output = resolve(configDir, contract.output);
|