@prisma-next/cli 0.11.0-dev.46 → 0.11.0-dev.47
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.mjs +9 -9
- package/dist/{client-a5NJce0-.mjs → client-5uvDppD8.mjs} +20 -18
- package/dist/client-5uvDppD8.mjs.map +1 -0
- package/dist/{command-helpers-yLuA78TP.mjs → command-helpers-CI8P5Xyd.mjs} +4 -4
- package/dist/{command-helpers-yLuA78TP.mjs.map → command-helpers-CI8P5Xyd.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.mjs +5 -5
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +3 -3
- package/dist/commands/db-update.mjs +5 -5
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +42 -37
- 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 -279
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.mjs +2 -2
- package/dist/commands/migration-list.d.mts +2 -2
- package/dist/commands/migration-list.mjs +1 -1
- package/dist/commands/migration-log.mjs +2 -2
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +32 -30
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +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 +62 -152
- 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 +91 -64
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +2 -2
- package/dist/{contract-emit-FtDVFs2Q.mjs → contract-emit-DmBG2Nnc.mjs} +2 -2
- package/dist/{contract-emit-FtDVFs2Q.mjs.map → contract-emit-DmBG2Nnc.mjs.map} +1 -1
- package/dist/{contract-infer-CVMuoJKk.mjs → contract-infer-BSWFKgI1.mjs} +3 -3
- package/dist/{contract-infer-CVMuoJKk.mjs.map → contract-infer-BSWFKgI1.mjs.map} +1 -1
- package/dist/contract-space-aggregate-loader-CVHGuA35.mjs +170 -0
- package/dist/contract-space-aggregate-loader-CVHGuA35.mjs.map +1 -0
- package/dist/{db-verify-B00o3LuC.mjs → db-verify-BzpwFyLg.mjs} +4 -4
- package/dist/{db-verify-B00o3LuC.mjs.map → db-verify-BzpwFyLg.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +1 -1
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/extension-pack-inputs-BiY86HbQ.mjs +62 -0
- package/dist/extension-pack-inputs-BiY86HbQ.mjs.map +1 -0
- package/dist/{global-flags-Dvibm2yu.d.mts → global-flags-DWsQ6SSI.d.mts} +1 -1
- package/dist/{global-flags-Dvibm2yu.d.mts.map → global-flags-DWsQ6SSI.d.mts.map} +1 -1
- package/dist/{graph-render-DJVv0_uf.mjs → graph-render-D2FnLpuK.mjs} +1 -1
- package/dist/{graph-render-DJVv0_uf.mjs.map → graph-render-D2FnLpuK.mjs.map} +1 -1
- package/dist/{init-BKgB6EKw.mjs → init-DEssiJ8j.mjs} +3 -3
- package/dist/{init-BKgB6EKw.mjs.map → init-DEssiJ8j.mjs.map} +1 -1
- package/dist/{inspect-live-schema-BXUd6RfS.mjs → inspect-live-schema-DlBM84nh.mjs} +3 -3
- package/dist/{inspect-live-schema-BXUd6RfS.mjs.map → inspect-live-schema-DlBM84nh.mjs.map} +1 -1
- package/dist/migration-check-CzLbAqIQ.mjs +341 -0
- package/dist/migration-check-CzLbAqIQ.mjs.map +1 -0
- package/dist/{migration-command-scaffold-3l3EdmSD.mjs → migration-command-scaffold-Bp8UHnvJ.mjs} +3 -3
- package/dist/{migration-command-scaffold-3l3EdmSD.mjs.map → migration-command-scaffold-Bp8UHnvJ.mjs.map} +1 -1
- package/dist/{migration-list-DopkAG7L.mjs → migration-list-C2xnaYsT.mjs} +2 -2
- package/dist/{migration-list-DopkAG7L.mjs.map → migration-list-C2xnaYsT.mjs.map} +1 -1
- package/dist/{migration-list-graph-render-C-daUZLU.d.mts → migration-list-graph-render-DKw1AT-e.d.mts} +1 -1
- package/dist/migration-list-graph-render-DKw1AT-e.d.mts.map +1 -0
- package/dist/{migration-plan-BHoeET4O.mjs → migration-plan-BLvOmNCu.mjs} +6 -5
- package/dist/{migration-plan-BHoeET4O.mjs.map → migration-plan-BLvOmNCu.mjs.map} +1 -1
- 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-D-UCOGtk.mjs → migrations-vzQt9LI2.mjs} +3 -13
- package/dist/migrations-vzQt9LI2.mjs.map +1 -0
- package/dist/{output-CUIdfYo5.mjs → output-B60Gw5fu.mjs} +1 -1
- package/dist/{output-CUIdfYo5.mjs.map → output-B60Gw5fu.mjs.map} +1 -1
- package/dist/{ref-advancement-CHJ_8HxQ.mjs → ref-advancement-DRh5Nquq.mjs} +1 -1
- package/dist/{ref-advancement-CHJ_8HxQ.mjs.map → ref-advancement-DRh5Nquq.mjs.map} +1 -1
- package/dist/{types-UWB2-rrw.d.mts → types-CEtm6v6a.d.mts} +1 -8
- package/dist/types-CEtm6v6a.d.mts.map +1 -0
- package/dist/{verify-9gDJz6cm.mjs → verify-ktSRQvIS.mjs} +2 -2
- package/dist/{verify-9gDJz6cm.mjs.map → verify-ktSRQvIS.mjs.map} +1 -1
- package/package.json +18 -18
- package/src/commands/migrate.ts +52 -42
- package/src/commands/migration-check.ts +43 -83
- package/src/commands/migration-new.ts +44 -42
- package/src/commands/migration-plan.ts +2 -2
- package/src/commands/migration-show.ts +65 -284
- package/src/commands/migration-status.ts +131 -99
- package/src/control-api/client.ts +0 -1
- package/src/control-api/operations/db-verify.ts +9 -5
- package/src/control-api/operations/migration-apply.ts +11 -19
- package/src/control-api/types.ts +0 -7
- package/src/utils/command-helpers.ts +8 -3
- package/src/utils/contract-space-aggregate-loader.ts +221 -117
- package/src/utils/formatters/migrations.ts +4 -38
- package/src/utils/integrity-violation-to-check-failure.ts +130 -0
- package/dist/client-a5NJce0-.mjs.map +0 -1
- package/dist/commands/migration-check.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-EVU3n9YE.mjs +0 -160
- package/dist/contract-space-aggregate-loader-EVU3n9YE.mjs.map +0 -1
- package/dist/migration-list-graph-render-C-daUZLU.d.mts.map +0 -1
- package/dist/migrations-D-UCOGtk.mjs.map +0 -1
- package/dist/types-UWB2-rrw.d.mts.map +0 -1
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
-
import {
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { createControlStack } from '@prisma-next/framework-components/control';
|
|
4
|
+
import type { IntegrityViolation } from '@prisma-next/migration-tools/aggregate';
|
|
5
|
+
import { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';
|
|
3
6
|
import { verifyMigrationHash } from '@prisma-next/migration-tools/hash';
|
|
7
|
+
import { readMigrationsDir } from '@prisma-next/migration-tools/io';
|
|
8
|
+
import { reconstructGraph } from '@prisma-next/migration-tools/migration-graph';
|
|
4
9
|
import type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';
|
|
5
10
|
import { parseMigrationRef } from '@prisma-next/migration-tools/ref-resolution';
|
|
6
11
|
import { readRefs } from '@prisma-next/migration-tools/refs';
|
|
@@ -9,15 +14,20 @@ import { join, relative } from 'pathe';
|
|
|
9
14
|
import { loadConfig } from '../config-loader';
|
|
10
15
|
import {
|
|
11
16
|
addGlobalOptions,
|
|
12
|
-
|
|
17
|
+
resolveContractPath,
|
|
13
18
|
resolveMigrationPaths,
|
|
14
19
|
setCommandDescriptions,
|
|
15
20
|
setCommandExamples,
|
|
16
21
|
setCommandSeeAlso,
|
|
17
22
|
} from '../utils/command-helpers';
|
|
23
|
+
import { toDeclaredExtensionsFromRaw } from '../utils/extension-pack-inputs';
|
|
18
24
|
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
19
25
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
20
26
|
import { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
27
|
+
import {
|
|
28
|
+
type CheckFailure,
|
|
29
|
+
integrityViolationToCheckFailure,
|
|
30
|
+
} from '../utils/integrity-violation-to-check-failure';
|
|
21
31
|
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
22
32
|
import { INTEGRITY_FAILED, OK, PRECONDITION } from './migration-check/exit-codes';
|
|
23
33
|
|
|
@@ -25,12 +35,7 @@ interface MigrationCheckOptions extends CommonCommandOptions {
|
|
|
25
35
|
readonly config?: string;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
|
-
export
|
|
29
|
-
readonly pnCode: string;
|
|
30
|
-
readonly where: string;
|
|
31
|
-
readonly why: string;
|
|
32
|
-
readonly fix: string;
|
|
33
|
-
}
|
|
38
|
+
export type { CheckFailure } from '../utils/integrity-violation-to-check-failure';
|
|
34
39
|
|
|
35
40
|
export interface MigrationCheckResult {
|
|
36
41
|
readonly ok: boolean;
|
|
@@ -38,11 +43,6 @@ export interface MigrationCheckResult {
|
|
|
38
43
|
readonly summary: string;
|
|
39
44
|
}
|
|
40
45
|
|
|
41
|
-
/**
|
|
42
|
-
* Canonical user-facing locator for a check failure: the cwd-relative path
|
|
43
|
-
* to the migration package directory. Surfacing the same shape across every
|
|
44
|
-
* PN code means `--json` consumers can branch uniformly on `where`.
|
|
45
|
-
*/
|
|
46
46
|
function migrationPathRelative(dirPath: string): string {
|
|
47
47
|
return relative(process.cwd(), dirPath);
|
|
48
48
|
}
|
|
@@ -63,21 +63,6 @@ function checkFileExists(dirPath: string, dirName: string, fileName: string): Ch
|
|
|
63
63
|
return null;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
/**
|
|
67
|
-
* Within-migration snapshot-consistency check (PN-MIG-CHECK-005).
|
|
68
|
-
*
|
|
69
|
-
* Compares the migration's stored `metadata.to` against the `storageHash`
|
|
70
|
-
* recorded in its on-disk `end-contract.json` snapshot. The two values are
|
|
71
|
-
* independent on-disk records of the same fact (the migration's destination
|
|
72
|
-
* contract); drift between them indicates the package is internally
|
|
73
|
-
* corrupt. Cross-migration consistency (one migration's end-contract.json
|
|
74
|
-
* agreeing with the next migration's start-contract.json) is a separate
|
|
75
|
-
* check that requires shadow execution and is deferred to
|
|
76
|
-
* `migration preflight`.
|
|
77
|
-
*
|
|
78
|
-
* Shared between the graph-wide and per-migration code paths so both report
|
|
79
|
-
* the same failure for the same on-disk state.
|
|
80
|
-
*/
|
|
81
66
|
function checkSnapshotConsistency(pkg: OnDiskMigrationPackage): CheckFailure | null {
|
|
82
67
|
const endContractPath = join(pkg.dirPath, 'end-contract.json');
|
|
83
68
|
if (!existsSync(endContractPath)) return null;
|
|
@@ -104,6 +89,27 @@ function checkSnapshotConsistency(pkg: OnDiskMigrationPackage): CheckFailure | n
|
|
|
104
89
|
return null;
|
|
105
90
|
}
|
|
106
91
|
|
|
92
|
+
async function loadAggregateIntegrityViolations(
|
|
93
|
+
config: Awaited<ReturnType<typeof loadConfig>>,
|
|
94
|
+
migrationsDir: string,
|
|
95
|
+
): Promise<readonly IntegrityViolation[]> {
|
|
96
|
+
try {
|
|
97
|
+
const contractJsonContent = await readFile(resolveContractPath(config), 'utf-8');
|
|
98
|
+
const familyInstance = config.family.create(createControlStack(config));
|
|
99
|
+
const declaredExtensions = toDeclaredExtensionsFromRaw(config.extensionPacks ?? []);
|
|
100
|
+
|
|
101
|
+
const parsedAppContract: unknown = JSON.parse(contractJsonContent);
|
|
102
|
+
const aggregate = await loadContractSpaceAggregate({
|
|
103
|
+
migrationsDir,
|
|
104
|
+
deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),
|
|
105
|
+
appContract: familyInstance.deserializeContract(parsedAppContract),
|
|
106
|
+
});
|
|
107
|
+
return aggregate.checkIntegrity({ declaredExtensions, checkContracts: true });
|
|
108
|
+
} catch {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
107
113
|
async function executeMigrationCheckCommand(
|
|
108
114
|
target: string | undefined,
|
|
109
115
|
options: MigrationCheckOptions,
|
|
@@ -111,10 +117,8 @@ async function executeMigrationCheckCommand(
|
|
|
111
117
|
ui: TerminalUI,
|
|
112
118
|
): Promise<{ result: MigrationCheckResult; exitCode: number }> {
|
|
113
119
|
const config = await loadConfig(options.config);
|
|
114
|
-
const { configPath, appMigrationsDir, appMigrationsRelative, refsDir } =
|
|
115
|
-
options.config,
|
|
116
|
-
config,
|
|
117
|
-
);
|
|
120
|
+
const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative, refsDir } =
|
|
121
|
+
resolveMigrationPaths(options.config, config);
|
|
118
122
|
|
|
119
123
|
if (!flags.json && !flags.quiet) {
|
|
120
124
|
const details: Array<{ label: string; value: string }> = [
|
|
@@ -135,37 +139,9 @@ async function executeMigrationCheckCommand(
|
|
|
135
139
|
|
|
136
140
|
const failures: CheckFailure[] = [];
|
|
137
141
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const loaded = await loadMigrationPackages(appMigrationsDir);
|
|
142
|
-
bundles = loaded.bundles;
|
|
143
|
-
graph = loaded.graph;
|
|
144
|
-
} catch (error) {
|
|
145
|
-
if (MigrationToolsError.is(error)) {
|
|
146
|
-
const pnCode =
|
|
147
|
-
error.code === 'MIGRATION.HASH_MISMATCH' ? 'PN-MIG-CHECK-001' : 'PN-MIG-CHECK-002';
|
|
148
|
-
// Normalise to a cwd-relative path. `error.details.dir` is absolute
|
|
149
|
-
// (the migration-tools layer doesn't know the caller's cwd); the
|
|
150
|
-
// `filePath` fallback is also absolute. Surfacing the relative form
|
|
151
|
-
// matches the rest of the command's `where` shape and keeps `--json`
|
|
152
|
-
// consumers from having to special-case the bootstrap-failure path.
|
|
153
|
-
const rawWhere =
|
|
154
|
-
(error.details?.['dir'] as string) ?? (error.details?.['filePath'] as string) ?? null;
|
|
155
|
-
const where = rawWhere ? relative(process.cwd(), rawWhere) : 'unknown';
|
|
156
|
-
failures.push({
|
|
157
|
-
pnCode,
|
|
158
|
-
where,
|
|
159
|
-
why: error.why,
|
|
160
|
-
fix: error.fix,
|
|
161
|
-
});
|
|
162
|
-
return {
|
|
163
|
-
result: { ok: false, failures, summary: `${failures.length} integrity failure(s)` },
|
|
164
|
-
exitCode: INTEGRITY_FAILED,
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
throw error;
|
|
168
|
-
}
|
|
142
|
+
const loaded = await readMigrationsDir(appMigrationsDir);
|
|
143
|
+
const bundles: readonly OnDiskMigrationPackage[] = loaded.packages;
|
|
144
|
+
const graph = reconstructGraph(bundles);
|
|
169
145
|
|
|
170
146
|
if (existsSync(appMigrationsDir)) {
|
|
171
147
|
const loadedDirNames = new Set(bundles.map((p) => p.dirName));
|
|
@@ -236,29 +212,9 @@ async function executeMigrationCheckCommand(
|
|
|
236
212
|
});
|
|
237
213
|
}
|
|
238
214
|
|
|
239
|
-
// PN-MIG-CHECK-005 must fire per-migration as well as graph-wide; both
|
|
240
|
-
// call sites delegate to the shared helper so the same on-disk drift
|
|
241
|
-
// produces the same failure regardless of how the user invoked check.
|
|
242
215
|
const snapshotFailure = checkSnapshotConsistency(matchedPkg);
|
|
243
216
|
if (snapshotFailure) failures.push(snapshotFailure);
|
|
244
217
|
} else {
|
|
245
|
-
for (const pkg of bundles) {
|
|
246
|
-
for (const f of ['migration.json', 'ops.json']) {
|
|
247
|
-
const fail = checkFileExists(pkg.dirPath, pkg.dirName, f);
|
|
248
|
-
if (fail) failures.push(fail);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const verification = verifyMigrationHash(pkg);
|
|
252
|
-
if (!verification.ok) {
|
|
253
|
-
failures.push({
|
|
254
|
-
pnCode: 'PN-MIG-CHECK-001',
|
|
255
|
-
where: migrationFileRelative(pkg.dirPath, 'migration.json'),
|
|
256
|
-
why: `Stored hash ${verification.storedHash} does not match recomputed hash ${verification.computedHash}`,
|
|
257
|
-
fix: 'Re-emit the migration package or restore from version control.',
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
218
|
for (const pkg of bundles) {
|
|
263
219
|
const snapshotFailure = checkSnapshotConsistency(pkg);
|
|
264
220
|
if (snapshotFailure) failures.push(snapshotFailure);
|
|
@@ -295,6 +251,10 @@ async function executeMigrationCheckCommand(
|
|
|
295
251
|
} catch {
|
|
296
252
|
// Refs unreadable — skip ref checks
|
|
297
253
|
}
|
|
254
|
+
|
|
255
|
+
for (const violation of await loadAggregateIntegrityViolations(config, migrationsDir)) {
|
|
256
|
+
failures.push(integrityViolationToCheckFailure(violation, migrationsDir));
|
|
257
|
+
}
|
|
298
258
|
}
|
|
299
259
|
|
|
300
260
|
if (failures.length === 0) {
|
|
@@ -12,19 +12,15 @@ import { readFile } from 'node:fs/promises';
|
|
|
12
12
|
import type { Contract } from '@prisma-next/contract/types';
|
|
13
13
|
import { getEmittedArtifactPaths } from '@prisma-next/emitter';
|
|
14
14
|
import { APP_SPACE_ID, createControlStack } from '@prisma-next/framework-components/control';
|
|
15
|
-
import {
|
|
15
|
+
import { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';
|
|
16
16
|
import { computeMigrationHash } from '@prisma-next/migration-tools/hash';
|
|
17
17
|
import {
|
|
18
18
|
copyFilesWithRename,
|
|
19
19
|
formatMigrationDirName,
|
|
20
|
-
readMigrationsDir,
|
|
21
20
|
writeMigrationPackage,
|
|
22
21
|
} from '@prisma-next/migration-tools/io';
|
|
23
22
|
import type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';
|
|
24
|
-
import {
|
|
25
|
-
findLatestMigration,
|
|
26
|
-
reconstructGraph,
|
|
27
|
-
} from '@prisma-next/migration-tools/migration-graph';
|
|
23
|
+
import { findLatestMigration } from '@prisma-next/migration-tools/migration-graph';
|
|
28
24
|
import { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';
|
|
29
25
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
30
26
|
import { Command } from 'commander';
|
|
@@ -36,7 +32,6 @@ import {
|
|
|
36
32
|
errorRuntime,
|
|
37
33
|
errorTargetMigrationNotSupported,
|
|
38
34
|
errorUnexpected,
|
|
39
|
-
mapMigrationToolsError,
|
|
40
35
|
} from '../utils/cli-errors';
|
|
41
36
|
import {
|
|
42
37
|
addGlobalOptions,
|
|
@@ -46,6 +41,7 @@ import {
|
|
|
46
41
|
setCommandDescriptions,
|
|
47
42
|
setCommandExamples,
|
|
48
43
|
} from '../utils/command-helpers';
|
|
44
|
+
import { refusePackageCorruptionOnAggregate } from '../utils/contract-space-aggregate-loader';
|
|
49
45
|
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
50
46
|
import { assertFrameworkComponentsCompatible } from '../utils/framework-components';
|
|
51
47
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
@@ -71,7 +67,10 @@ async function executeMigrationNewCommand(
|
|
|
71
67
|
options: MigrationNewOptions,
|
|
72
68
|
): Promise<Result<MigrationNewResult, CliStructuredError>> {
|
|
73
69
|
const config = await loadConfig(options.config);
|
|
74
|
-
const { appMigrationsDir, appMigrationsRelative } = resolveMigrationPaths(
|
|
70
|
+
const { migrationsDir, appMigrationsDir, appMigrationsRelative } = resolveMigrationPaths(
|
|
71
|
+
options.config,
|
|
72
|
+
config,
|
|
73
|
+
);
|
|
75
74
|
|
|
76
75
|
// Construct the family instance up-front so the on-disk contract read
|
|
77
76
|
// below crosses the serializer seam (`familyInstance.deserializeContract`)
|
|
@@ -98,7 +97,8 @@ async function executeMigrationNewCommand(
|
|
|
98
97
|
|
|
99
98
|
let toContract: Contract;
|
|
100
99
|
try {
|
|
101
|
-
|
|
100
|
+
const parsedContract: unknown = JSON.parse(contractJsonContent);
|
|
101
|
+
toContract = familyInstance.deserializeContract(parsedContract);
|
|
102
102
|
} catch (error) {
|
|
103
103
|
return notOk(
|
|
104
104
|
errorRuntime('Contract JSON is invalid', {
|
|
@@ -118,45 +118,47 @@ async function executeMigrationNewCommand(
|
|
|
118
118
|
);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
const aggregate = await loadContractSpaceAggregate({
|
|
122
|
+
migrationsDir,
|
|
123
|
+
deserializeContract: (json) => familyInstance.deserializeContract(json),
|
|
124
|
+
appContract: toContract,
|
|
125
|
+
});
|
|
126
|
+
const packageCorruptionFailure = refusePackageCorruptionOnAggregate(aggregate);
|
|
127
|
+
if (packageCorruptionFailure) {
|
|
128
|
+
return notOk(packageCorruptionFailure);
|
|
129
|
+
}
|
|
123
130
|
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
const packages = aggregate.app.packages;
|
|
132
|
+
const graph = aggregate.app.graph();
|
|
126
133
|
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
let fromHash: string | null = null;
|
|
135
|
+
let fromContractSourceDir: string | null = null;
|
|
129
136
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
137
|
+
if (packages.length > 0) {
|
|
138
|
+
if (options.from) {
|
|
139
|
+
const match = packages.find((p) => p.metadata.to.startsWith(options.from!));
|
|
140
|
+
if (!match) {
|
|
141
|
+
return notOk(
|
|
142
|
+
errorRuntime('Starting contract not found', {
|
|
143
|
+
why: `No migration with to hash matching "${options.from}" exists in ${appMigrationsRelative}`,
|
|
144
|
+
fix: 'Check that the --from hash matches a known migration target hash.',
|
|
145
|
+
}),
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
fromHash = match.metadata.to;
|
|
149
|
+
fromContractSourceDir = match.dirPath;
|
|
150
|
+
} else {
|
|
151
|
+
const latestMigration = findLatestMigration(graph);
|
|
152
|
+
if (latestMigration) {
|
|
153
|
+
fromHash = latestMigration.to;
|
|
154
|
+
const leafPkg = packages.find(
|
|
155
|
+
(p) => p.metadata.migrationHash === latestMigration.migrationHash,
|
|
156
|
+
);
|
|
157
|
+
if (leafPkg) {
|
|
158
|
+
fromContractSourceDir = leafPkg.dirPath;
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
161
|
}
|
|
155
|
-
} catch (error) {
|
|
156
|
-
if (MigrationToolsError.is(error)) {
|
|
157
|
-
return notOk(mapMigrationToolsError(error));
|
|
158
|
-
}
|
|
159
|
-
throw error;
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
if (fromHash === toStorageHash && !options.from) {
|
|
@@ -576,7 +576,7 @@ async function executeMigrationPlanCommand(
|
|
|
576
576
|
planner,
|
|
577
577
|
migrations,
|
|
578
578
|
frameworkComponents,
|
|
579
|
-
aggregate.app.contract,
|
|
579
|
+
aggregate.app.contract(),
|
|
580
580
|
fromContract,
|
|
581
581
|
aggregate.app.spaceId,
|
|
582
582
|
);
|
|
@@ -653,7 +653,7 @@ async function executeMigrationPlanCommand(
|
|
|
653
653
|
planner,
|
|
654
654
|
migrations,
|
|
655
655
|
frameworkComponents,
|
|
656
|
-
aggregate.app.contract,
|
|
656
|
+
aggregate.app.contract(),
|
|
657
657
|
fromContract,
|
|
658
658
|
aggregate.app.spaceId,
|
|
659
659
|
);
|