@prisma-next/cli 0.11.0-dev.6 → 0.11.0-dev.8
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/dist/cli-errors-Bw2GlweY.mjs +175 -0
- package/dist/cli-errors-Bw2GlweY.mjs.map +1 -0
- package/dist/cli.mjs +7 -7
- package/dist/{client-oXO2WCPD.mjs → client-UnIveZxZ.mjs} +4 -4
- package/dist/{client-oXO2WCPD.mjs.map → client-UnIveZxZ.mjs.map} +1 -1
- package/dist/{command-helpers-DtavI0wJ.mjs → command-helpers-CRfjbZRz.mjs} +2 -2
- package/dist/{command-helpers-DtavI0wJ.mjs.map → command-helpers-CRfjbZRz.mjs.map} +1 -1
- package/dist/commands/contract-emit.mjs +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 +33 -6
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +5 -5
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +36 -7
- package/dist/commands/db-update.mjs.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 +44 -8
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.mjs +2 -2
- package/dist/commands/migration-graph.mjs +3 -3
- package/dist/commands/migration-list.mjs +2 -2
- package/dist/commands/migration-log.mjs +3 -3
- package/dist/commands/migration-new.mjs +3 -3
- package/dist/commands/migration-plan.d.mts +1 -0
- 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 +1 -1
- package/dist/commands/migration-show.mjs +6 -6
- package/dist/commands/migration-status.mjs +7 -7
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +34 -8
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/{contract-emit-o-8VmdQX.mjs → contract-emit-C6rlsljO.mjs} +3 -3
- package/dist/{contract-emit-o-8VmdQX.mjs.map → contract-emit-C6rlsljO.mjs.map} +1 -1
- package/dist/{contract-emit-CmsklifJ.mjs → contract-emit-mqXmapxB.mjs} +4 -4
- package/dist/{contract-emit-CmsklifJ.mjs.map → contract-emit-mqXmapxB.mjs.map} +1 -1
- package/dist/{contract-infer-pKkiCt7C.mjs → contract-infer-C4jxc1aZ.mjs} +3 -3
- package/dist/{contract-infer-pKkiCt7C.mjs.map → contract-infer-C4jxc1aZ.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-BmNQwlws.mjs → contract-space-aggregate-loader-CGakRlKM.mjs} +2 -2
- package/dist/{contract-space-aggregate-loader-BmNQwlws.mjs.map → contract-space-aggregate-loader-CGakRlKM.mjs.map} +1 -1
- package/dist/{db-verify-AoIUriL4.mjs → db-verify-1d8tDoFN.mjs} +5 -5
- package/dist/{db-verify-AoIUriL4.mjs.map → db-verify-1d8tDoFN.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{framework-components-65gOHkHB.mjs → framework-components-Bexd0f4E.mjs} +2 -2
- package/dist/{framework-components-65gOHkHB.mjs.map → framework-components-Bexd0f4E.mjs.map} +1 -1
- package/dist/{graph-render-DJVv0_uf.mjs → graph-render-BE8vmJ_7.mjs} +1 -1
- package/dist/{graph-render-DJVv0_uf.mjs.map → graph-render-BE8vmJ_7.mjs.map} +1 -1
- package/dist/{init-Db5Itt5r.mjs → init-ByoeQphC.mjs} +4 -4
- package/dist/{init-Db5Itt5r.mjs.map → init-ByoeQphC.mjs.map} +1 -1
- package/dist/{inspect-live-schema-LeWvkZVz.mjs → inspect-live-schema-B1Q49RF0.mjs} +4 -4
- package/dist/{inspect-live-schema-LeWvkZVz.mjs.map → inspect-live-schema-B1Q49RF0.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-BtkunvFQ.mjs → migration-command-scaffold-oY4P1Qto.mjs} +4 -4
- package/dist/{migration-command-scaffold-BtkunvFQ.mjs.map → migration-command-scaffold-oY4P1Qto.mjs.map} +1 -1
- package/dist/{migration-plan-C2jeH1J5.mjs → migration-plan-jdAHg_gK.mjs} +346 -87
- package/dist/migration-plan-jdAHg_gK.mjs.map +1 -0
- package/dist/{migrations-CwZMa1Ck.mjs → migrations-B7n518mT.mjs} +10 -1
- package/dist/migrations-B7n518mT.mjs.map +1 -0
- package/dist/{output-BlsrGMEF.mjs → output-CUIdfYo5.mjs} +1 -1
- package/dist/{output-BlsrGMEF.mjs.map → output-CUIdfYo5.mjs.map} +1 -1
- package/dist/ref-advancement-DRh5Nquq.mjs +50 -0
- package/dist/ref-advancement-DRh5Nquq.mjs.map +1 -0
- package/dist/{types-C9FfXb1l.d.mts → types-UWB2-rrw.d.mts} +5 -4
- package/dist/types-UWB2-rrw.d.mts.map +1 -0
- package/dist/{verify-Bom75OYI.mjs → verify-C5UvbrF1.mjs} +1 -1
- package/dist/{verify-Bom75OYI.mjs.map → verify-C5UvbrF1.mjs.map} +1 -1
- package/package.json +18 -18
- package/src/commands/db-init.ts +48 -2
- package/src/commands/db-update.ts +45 -0
- package/src/commands/migrate.ts +73 -3
- package/src/commands/migration-plan.ts +365 -128
- package/src/commands/ref.ts +46 -6
- package/src/utils/cli-errors.ts +173 -0
- package/src/utils/formatters/migrations.ts +25 -0
- package/src/utils/plan-resolution.ts +257 -0
- package/src/utils/ref-advancement.ts +68 -0
- 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/migration-plan-C2jeH1J5.mjs.map +0 -1
- package/dist/migrations-CwZMa1Ck.mjs.map +0 -1
- package/dist/types-C9FfXb1l.d.mts.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/cli",
|
|
3
|
-
"version": "0.11.0-dev.
|
|
3
|
+
"version": "0.11.0-dev.8",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@clack/prompts": "^1.4.0",
|
|
16
16
|
"@dagrejs/dagre": "^3.0.0",
|
|
17
|
-
"@prisma-next/config": "0.11.0-dev.
|
|
18
|
-
"@prisma-next/contract": "0.11.0-dev.
|
|
19
|
-
"@prisma-next/emitter": "0.11.0-dev.
|
|
20
|
-
"@prisma-next/errors": "0.11.0-dev.
|
|
21
|
-
"@prisma-next/framework-components": "0.11.0-dev.
|
|
22
|
-
"@prisma-next/migration-tools": "0.11.0-dev.
|
|
23
|
-
"@prisma-next/psl-printer": "0.11.0-dev.
|
|
24
|
-
"@prisma-next/cli-telemetry": "0.11.0-dev.
|
|
25
|
-
"@prisma-next/utils": "0.11.0-dev.
|
|
17
|
+
"@prisma-next/config": "0.11.0-dev.8",
|
|
18
|
+
"@prisma-next/contract": "0.11.0-dev.8",
|
|
19
|
+
"@prisma-next/emitter": "0.11.0-dev.8",
|
|
20
|
+
"@prisma-next/errors": "0.11.0-dev.8",
|
|
21
|
+
"@prisma-next/framework-components": "0.11.0-dev.8",
|
|
22
|
+
"@prisma-next/migration-tools": "0.11.0-dev.8",
|
|
23
|
+
"@prisma-next/psl-printer": "0.11.0-dev.8",
|
|
24
|
+
"@prisma-next/cli-telemetry": "0.11.0-dev.8",
|
|
25
|
+
"@prisma-next/utils": "0.11.0-dev.8",
|
|
26
26
|
"arktype": "^2.2.0",
|
|
27
27
|
"c12": "^3.3.4",
|
|
28
28
|
"ci-info": "^4.3.1",
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
"wrap-ansi": "^10.0.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@prisma-next/sql-contract": "0.11.0-dev.
|
|
43
|
-
"@prisma-next/sql-contract-emitter": "0.11.0-dev.
|
|
44
|
-
"@prisma-next/sql-contract-ts": "0.11.0-dev.
|
|
45
|
-
"@prisma-next/sql-operations": "0.11.0-dev.
|
|
46
|
-
"@prisma-next/sql-runtime": "0.11.0-dev.
|
|
47
|
-
"@prisma-next/test-utils": "0.11.0-dev.
|
|
48
|
-
"@prisma-next/tsconfig": "0.11.0-dev.
|
|
49
|
-
"@prisma-next/tsdown": "0.11.0-dev.
|
|
42
|
+
"@prisma-next/sql-contract": "0.11.0-dev.8",
|
|
43
|
+
"@prisma-next/sql-contract-emitter": "0.11.0-dev.8",
|
|
44
|
+
"@prisma-next/sql-contract-ts": "0.11.0-dev.8",
|
|
45
|
+
"@prisma-next/sql-operations": "0.11.0-dev.8",
|
|
46
|
+
"@prisma-next/sql-runtime": "0.11.0-dev.8",
|
|
47
|
+
"@prisma-next/test-utils": "0.11.0-dev.8",
|
|
48
|
+
"@prisma-next/tsconfig": "0.11.0-dev.8",
|
|
49
|
+
"@prisma-next/tsdown": "0.11.0-dev.8",
|
|
50
50
|
"@types/node": "24.10.4",
|
|
51
51
|
"tsdown": "0.22.0",
|
|
52
52
|
"typescript": "5.9.3",
|
package/src/commands/db-init.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
1
2
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
2
3
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
3
4
|
import { Command } from 'commander';
|
|
@@ -10,6 +11,7 @@ import {
|
|
|
10
11
|
errorRunnerFailed,
|
|
11
12
|
errorRuntime,
|
|
12
13
|
errorUnexpected,
|
|
14
|
+
mapMigrationToolsError,
|
|
13
15
|
} from '../utils/cli-errors';
|
|
14
16
|
import type { MigrationCommandOptions } from '../utils/command-helpers';
|
|
15
17
|
import {
|
|
@@ -29,10 +31,18 @@ import {
|
|
|
29
31
|
addMigrationCommandOptions,
|
|
30
32
|
prepareMigrationContext,
|
|
31
33
|
} from '../utils/migration-command-scaffold';
|
|
34
|
+
import {
|
|
35
|
+
buildRefAdvancementFields,
|
|
36
|
+
computeRefAdvancementName,
|
|
37
|
+
type RefAdvancementFields,
|
|
38
|
+
readContractIR,
|
|
39
|
+
} from '../utils/ref-advancement';
|
|
32
40
|
import { handleResult } from '../utils/result-handler';
|
|
33
41
|
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
34
42
|
|
|
35
|
-
|
|
43
|
+
interface DbInitOptions extends MigrationCommandOptions {
|
|
44
|
+
readonly advanceRef?: string;
|
|
45
|
+
}
|
|
36
46
|
|
|
37
47
|
/**
|
|
38
48
|
* Maps a DbInitFailure to a CliStructuredError for consistent error handling.
|
|
@@ -128,7 +138,7 @@ async function executeDbInitCommand(
|
|
|
128
138
|
// per-space precheck + marker-check helpers are no longer needed at
|
|
129
139
|
// this surface. Marker-vs-on-disk drift surfaces through the planner's
|
|
130
140
|
// graph-walk strategy.
|
|
131
|
-
const { migrationsDir } = resolveMigrationPaths(options.config, config);
|
|
141
|
+
const { migrationsDir, refsDir } = resolveMigrationPaths(options.config, config);
|
|
132
142
|
|
|
133
143
|
try {
|
|
134
144
|
await client.connect(dbConnection);
|
|
@@ -145,6 +155,39 @@ async function executeDbInitCommand(
|
|
|
145
155
|
return notOk(mapDbInitFailure(result.failure));
|
|
146
156
|
}
|
|
147
157
|
|
|
158
|
+
const advancementHash =
|
|
159
|
+
result.value.mode === 'apply'
|
|
160
|
+
? (result.value.marker?.storageHash ?? result.value.destination.storageHash)
|
|
161
|
+
: result.value.destination.storageHash;
|
|
162
|
+
|
|
163
|
+
let refAdvancementFields: RefAdvancementFields = {
|
|
164
|
+
advancedRef: null,
|
|
165
|
+
plannedAdvanceRef: null,
|
|
166
|
+
};
|
|
167
|
+
if (
|
|
168
|
+
computeRefAdvancementName({
|
|
169
|
+
...ifDefined('advanceRef', options.advanceRef),
|
|
170
|
+
...ifDefined('db', options.db),
|
|
171
|
+
}) !== null
|
|
172
|
+
) {
|
|
173
|
+
try {
|
|
174
|
+
const contractIR = await readContractIR(contractJson, contractPathAbsolute);
|
|
175
|
+
refAdvancementFields = await buildRefAdvancementFields({
|
|
176
|
+
...ifDefined('advanceRef', options.advanceRef),
|
|
177
|
+
...ifDefined('db', options.db),
|
|
178
|
+
refsDir,
|
|
179
|
+
contractIR,
|
|
180
|
+
mode: result.value.mode,
|
|
181
|
+
hash: advancementHash,
|
|
182
|
+
});
|
|
183
|
+
} catch (error) {
|
|
184
|
+
if (MigrationToolsError.is(error)) {
|
|
185
|
+
return notOk(mapMigrationToolsError(error));
|
|
186
|
+
}
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
148
191
|
// Convert success result to CLI output format
|
|
149
192
|
const dbInitResult: MigrationCommandResult = {
|
|
150
193
|
ok: true,
|
|
@@ -179,6 +222,8 @@ async function executeDbInitCommand(
|
|
|
179
222
|
}
|
|
180
223
|
: {}),
|
|
181
224
|
...ifDefined('perSpace', result.value.perSpace),
|
|
225
|
+
advancedRef: refAdvancementFields.advancedRef,
|
|
226
|
+
plannedAdvanceRef: refAdvancementFields.plannedAdvanceRef,
|
|
182
227
|
summary: result.value.summary,
|
|
183
228
|
timings: { total: Date.now() - startTime },
|
|
184
229
|
};
|
|
@@ -229,6 +274,7 @@ export function createDbInitCommand(): Command {
|
|
|
229
274
|
'prisma-next db init --db $DATABASE_URL --dry-run',
|
|
230
275
|
]);
|
|
231
276
|
addMigrationCommandOptions(command);
|
|
277
|
+
command.option('--advance-ref <name>', 'Ref to advance to the post-command contract hash');
|
|
232
278
|
command.action(async (options: DbInitOptions) => {
|
|
233
279
|
const flags = parseGlobalFlagsOrExit(options);
|
|
234
280
|
const startTime = Date.now();
|
|
@@ -38,11 +38,18 @@ import {
|
|
|
38
38
|
addMigrationCommandOptions,
|
|
39
39
|
prepareMigrationContext,
|
|
40
40
|
} from '../utils/migration-command-scaffold';
|
|
41
|
+
import {
|
|
42
|
+
buildRefAdvancementFields,
|
|
43
|
+
computeRefAdvancementName,
|
|
44
|
+
type RefAdvancementFields,
|
|
45
|
+
readContractIR,
|
|
46
|
+
} from '../utils/ref-advancement';
|
|
41
47
|
import { handleResult } from '../utils/result-handler';
|
|
42
48
|
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
43
49
|
|
|
44
50
|
interface DbUpdateOptions extends MigrationCommandOptions {
|
|
45
51
|
readonly to?: string;
|
|
52
|
+
readonly advanceRef?: string;
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
/**
|
|
@@ -101,6 +108,7 @@ async function executeDbUpdateCommand(
|
|
|
101
108
|
}
|
|
102
109
|
const { client, config, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;
|
|
103
110
|
let { contractJson } = ctxResult.value;
|
|
111
|
+
let contractJsonPathForSnapshot = contractPathAbsolute;
|
|
104
112
|
const { migrationsDir, appMigrationsDir, refsDir } = resolveMigrationPaths(
|
|
105
113
|
options.config,
|
|
106
114
|
config,
|
|
@@ -130,6 +138,7 @@ async function executeDbUpdateCommand(
|
|
|
130
138
|
const endContractPath = join(matchingBundle.dirPath, 'end-contract.json');
|
|
131
139
|
const raw = await readFile(endContractPath, 'utf-8');
|
|
132
140
|
contractJson = JSON.parse(raw) as Record<string, unknown>;
|
|
141
|
+
contractJsonPathForSnapshot = endContractPath;
|
|
133
142
|
} catch (error) {
|
|
134
143
|
if (MigrationToolsError.is(error)) {
|
|
135
144
|
return notOk(mapMigrationToolsError(error));
|
|
@@ -157,6 +166,39 @@ async function executeDbUpdateCommand(
|
|
|
157
166
|
return notOk(mapDbUpdateFailure(result.failure));
|
|
158
167
|
}
|
|
159
168
|
|
|
169
|
+
const advancementHash =
|
|
170
|
+
result.value.mode === 'apply'
|
|
171
|
+
? (result.value.marker?.storageHash ?? result.value.destination.storageHash)
|
|
172
|
+
: result.value.destination.storageHash;
|
|
173
|
+
|
|
174
|
+
let refAdvancementFields: RefAdvancementFields = {
|
|
175
|
+
advancedRef: null,
|
|
176
|
+
plannedAdvanceRef: null,
|
|
177
|
+
};
|
|
178
|
+
if (
|
|
179
|
+
computeRefAdvancementName({
|
|
180
|
+
...ifDefined('advanceRef', options.advanceRef),
|
|
181
|
+
...ifDefined('db', options.db),
|
|
182
|
+
}) !== null
|
|
183
|
+
) {
|
|
184
|
+
try {
|
|
185
|
+
const contractIR = await readContractIR(contractJson, contractJsonPathForSnapshot);
|
|
186
|
+
refAdvancementFields = await buildRefAdvancementFields({
|
|
187
|
+
...ifDefined('advanceRef', options.advanceRef),
|
|
188
|
+
...ifDefined('db', options.db),
|
|
189
|
+
refsDir,
|
|
190
|
+
contractIR,
|
|
191
|
+
mode: result.value.mode,
|
|
192
|
+
hash: advancementHash,
|
|
193
|
+
});
|
|
194
|
+
} catch (error) {
|
|
195
|
+
if (MigrationToolsError.is(error)) {
|
|
196
|
+
return notOk(mapMigrationToolsError(error));
|
|
197
|
+
}
|
|
198
|
+
throw error;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
160
202
|
// Convert success result to CLI output format
|
|
161
203
|
const dbUpdateResult: MigrationCommandResult = {
|
|
162
204
|
ok: true,
|
|
@@ -193,6 +235,8 @@ async function executeDbUpdateCommand(
|
|
|
193
235
|
: undefined,
|
|
194
236
|
),
|
|
195
237
|
...ifDefined('perSpace', result.value.perSpace),
|
|
238
|
+
advancedRef: refAdvancementFields.advancedRef,
|
|
239
|
+
plannedAdvanceRef: refAdvancementFields.plannedAdvanceRef,
|
|
196
240
|
summary: result.value.summary,
|
|
197
241
|
timings: { total: Date.now() - startTime },
|
|
198
242
|
};
|
|
@@ -245,6 +289,7 @@ export function createDbUpdateCommand(): Command {
|
|
|
245
289
|
'--to <contract>',
|
|
246
290
|
'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',
|
|
247
291
|
);
|
|
292
|
+
command.option('--advance-ref <name>', 'Ref to advance to the post-command contract hash');
|
|
248
293
|
command.action(async (options: DbUpdateOptions) => {
|
|
249
294
|
const flags = parseGlobalFlagsOrExit(options);
|
|
250
295
|
const startTime = Date.now();
|
package/src/commands/migrate.ts
CHANGED
|
@@ -2,13 +2,14 @@ import { readFile } from 'node:fs/promises';
|
|
|
2
2
|
import type { Contract } from '@prisma-next/contract/types';
|
|
3
3
|
import { createControlStack } from '@prisma-next/framework-components/control';
|
|
4
4
|
import { errorUnknownInvariant, MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
5
|
+
import { findLatestMigration, isGraphNode } from '@prisma-next/migration-tools/migration-graph';
|
|
5
6
|
import { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';
|
|
6
7
|
import type { RefEntry } from '@prisma-next/migration-tools/refs';
|
|
7
8
|
import { readRefs } from '@prisma-next/migration-tools/refs';
|
|
8
9
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
9
10
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
10
11
|
import { Command } from 'commander';
|
|
11
|
-
|
|
12
|
+
import { join } from 'pathe';
|
|
12
13
|
import { loadConfig } from '../config-loader';
|
|
13
14
|
import { createControlClient } from '../control-api/client';
|
|
14
15
|
import type {
|
|
@@ -23,6 +24,8 @@ import {
|
|
|
23
24
|
errorDatabaseConnectionRequired,
|
|
24
25
|
errorDriverRequired,
|
|
25
26
|
errorFileNotFound,
|
|
27
|
+
errorMarkerMismatch,
|
|
28
|
+
errorPathUnreachable,
|
|
26
29
|
errorRuntime,
|
|
27
30
|
errorTargetMigrationNotSupported,
|
|
28
31
|
errorUnexpected,
|
|
@@ -44,6 +47,7 @@ import { formatMigrationApplyCommandOutput } from '../utils/formatters/migration
|
|
|
44
47
|
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
45
48
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
46
49
|
import { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
50
|
+
import { executeRefAdvancement, readContractIR } from '../utils/ref-advancement';
|
|
47
51
|
import { handleResult } from '../utils/result-handler';
|
|
48
52
|
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
49
53
|
|
|
@@ -51,6 +55,7 @@ interface MigrateCommandOptions extends CommonCommandOptions {
|
|
|
51
55
|
readonly db?: string;
|
|
52
56
|
readonly config?: string;
|
|
53
57
|
readonly to?: string;
|
|
58
|
+
readonly advanceRef?: string;
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
export interface MigrateResult {
|
|
@@ -72,9 +77,13 @@ export interface MigrateResult {
|
|
|
72
77
|
readonly timings: {
|
|
73
78
|
readonly total: number;
|
|
74
79
|
};
|
|
80
|
+
readonly advancedRef?: { readonly name: string; readonly hash: string } | null;
|
|
75
81
|
}
|
|
76
82
|
|
|
77
83
|
function mapApplyFailure(failure: MigrationApplyFailure): CliStructuredErrorType {
|
|
84
|
+
if (failure.code === 'MIGRATION_PATH_NOT_FOUND') {
|
|
85
|
+
return errorPathUnreachable(failure);
|
|
86
|
+
}
|
|
78
87
|
return errorRuntime(failure.summary, {
|
|
79
88
|
why: failure.why ?? 'Migration runner failed',
|
|
80
89
|
fix: 'Fix the issue and re-run `prisma-next migrate --to <contract>` — previously applied migrations are preserved.',
|
|
@@ -229,9 +238,21 @@ async function executeMigrateCommand(
|
|
|
229
238
|
try {
|
|
230
239
|
await client.connect(dbConnection);
|
|
231
240
|
|
|
241
|
+
const allMarkers = await client.readAllMarkers();
|
|
242
|
+
const appMarker = allMarkers.get('app') ?? null;
|
|
243
|
+
const { graph } = appPackages;
|
|
244
|
+
|
|
245
|
+
if (appMarker !== null && !isGraphNode(appMarker.storageHash, graph)) {
|
|
246
|
+
return notOk(
|
|
247
|
+
errorMarkerMismatch(
|
|
248
|
+
appMarker.storageHash,
|
|
249
|
+
[...graph.nodes].sort(),
|
|
250
|
+
findLatestMigration(graph)?.to ?? null,
|
|
251
|
+
),
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
232
255
|
if (refEntry && refEntry.invariants.length > 0) {
|
|
233
|
-
const allMarkers = await client.readAllMarkers();
|
|
234
|
-
const appMarker = allMarkers.get('app') ?? null;
|
|
235
256
|
const declared = collectDeclaredInvariants(appPackages.graph);
|
|
236
257
|
const known = new Set<string>(declared);
|
|
237
258
|
for (const id of appMarker?.invariants ?? []) known.add(id);
|
|
@@ -268,6 +289,53 @@ async function executeMigrateCommand(
|
|
|
268
289
|
|
|
269
290
|
const { value } = applyResult;
|
|
270
291
|
|
|
292
|
+
let advancedRef: { name: string; hash: string } | null = null;
|
|
293
|
+
if (options.advanceRef !== undefined) {
|
|
294
|
+
let contractJsonPathForSnapshot = contractPathAbsolute;
|
|
295
|
+
let contractJsonForSnapshot: Record<string, unknown> = JSON.parse(contractContent) as Record<
|
|
296
|
+
string,
|
|
297
|
+
unknown
|
|
298
|
+
>;
|
|
299
|
+
if (toArg && refEntry) {
|
|
300
|
+
const matchingBundle = appPackages.bundles.find((p) => p.metadata.to === refEntry.hash);
|
|
301
|
+
if (matchingBundle) {
|
|
302
|
+
const endContractPath = join(matchingBundle.dirPath, 'end-contract.json');
|
|
303
|
+
contractJsonPathForSnapshot = endContractPath;
|
|
304
|
+
try {
|
|
305
|
+
const raw = await readFile(endContractPath, 'utf-8');
|
|
306
|
+
contractJsonForSnapshot = JSON.parse(raw) as Record<string, unknown>;
|
|
307
|
+
} catch (error) {
|
|
308
|
+
if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {
|
|
309
|
+
return notOk(
|
|
310
|
+
errorFileNotFound(endContractPath, {
|
|
311
|
+
why: `Bundle end-contract not found at ${endContractPath}`,
|
|
312
|
+
fix: 'Re-emit the migration bundle or pick a different --to target.',
|
|
313
|
+
}),
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
try {
|
|
321
|
+
const contractIR = await readContractIR(
|
|
322
|
+
contractJsonForSnapshot,
|
|
323
|
+
contractJsonPathForSnapshot,
|
|
324
|
+
);
|
|
325
|
+
advancedRef = await executeRefAdvancement(
|
|
326
|
+
refsDir,
|
|
327
|
+
options.advanceRef,
|
|
328
|
+
value.markerHash,
|
|
329
|
+
contractIR,
|
|
330
|
+
);
|
|
331
|
+
} catch (error) {
|
|
332
|
+
if (MigrationToolsError.is(error)) {
|
|
333
|
+
return notOk(mapMigrationToolsError(error));
|
|
334
|
+
}
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
271
339
|
return ok({
|
|
272
340
|
ok: true,
|
|
273
341
|
migrationsApplied: value.migrationsApplied,
|
|
@@ -278,6 +346,7 @@ async function executeMigrateCommand(
|
|
|
278
346
|
perSpace: value.perSpace,
|
|
279
347
|
...ifDefined('pathDecision', value.pathDecision),
|
|
280
348
|
timings: { total: Date.now() - startTime },
|
|
349
|
+
advancedRef,
|
|
281
350
|
});
|
|
282
351
|
} catch (error) {
|
|
283
352
|
if (CliStructuredError.is(error)) {
|
|
@@ -318,6 +387,7 @@ export function createMigrateCommand(): Command {
|
|
|
318
387
|
'--to <contract>',
|
|
319
388
|
'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',
|
|
320
389
|
)
|
|
390
|
+
.option('--advance-ref <name>', 'Advance the named ref to the post-apply marker after success')
|
|
321
391
|
.action(async (options: MigrateCommandOptions) => {
|
|
322
392
|
const flags = parseGlobalFlagsOrExit(options);
|
|
323
393
|
const startTime = Date.now();
|