@prisma-next/cli 0.16.0-dev.3 → 0.16.0-dev.30
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 +44 -45
- package/dist/cli.mjs +13 -13
- package/dist/{client-KuBQftxz.mjs → client-CMusjGV5.mjs} +24 -25
- package/dist/client-CMusjGV5.mjs.map +1 -0
- package/dist/{command-helpers-Cpq44aVa.mjs → command-helpers-CVn3U9Uz.mjs} +12 -4
- package/dist/command-helpers-CVn3U9Uz.mjs.map +1 -0
- 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 +5 -4
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.d.mts.map +1 -1
- package/dist/commands/db-sign.mjs +9 -11
- 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 +11 -13
- package/dist/commands/db-update.mjs.map +1 -1
- 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 +13 -13
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +4 -2
- package/dist/commands/migration-check.d.mts.map +1 -1
- package/dist/commands/migration-check.mjs +1 -1
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.mjs +4 -4
- package/dist/commands/migration-list.d.mts +1 -1
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +1 -1
- package/dist/commands/migration-log.d.mts +1 -1
- package/dist/commands/migration-log.mjs +1 -1
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +16 -40
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +3 -4
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.mjs +5 -5
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +1 -1
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +13 -18
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/commands/telemetry/index.mjs +1 -1
- package/dist/contract-at-errors-C-l4-JEY.mjs +36 -0
- package/dist/contract-at-errors-C-l4-JEY.mjs.map +1 -0
- package/dist/{contract-emit-cJQBlvGb.mjs → contract-emit-CfIbTnsR.mjs} +6 -7
- package/dist/{contract-emit-cJQBlvGb.mjs.map → contract-emit-CfIbTnsR.mjs.map} +1 -1
- package/dist/{contract-emit-CgnXSANN.mjs → contract-emit-PaY3qRdN.mjs} +3 -3
- package/dist/{contract-emit-CgnXSANN.mjs.map → contract-emit-PaY3qRdN.mjs.map} +1 -1
- package/dist/{contract-enrichment-gn9sWbPw.mjs → contract-enrichment-JUhLv-BX.mjs} +8 -8
- package/dist/{contract-enrichment-gn9sWbPw.mjs.map → contract-enrichment-JUhLv-BX.mjs.map} +1 -1
- package/dist/{contract-infer-Cg8evbeg.mjs → contract-infer-DCju2fTk.mjs} +3 -3
- package/dist/{contract-infer-Cg8evbeg.mjs.map → contract-infer-DCju2fTk.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-D_3VeHVb.mjs → contract-space-aggregate-loader-B6E9LGa6.mjs} +14 -14
- package/dist/contract-space-aggregate-loader-B6E9LGa6.mjs.map +1 -0
- package/dist/{db-verify-BEclUzki.mjs → db-verify-B_dKu6Yp.mjs} +5 -5
- package/dist/db-verify-B_dKu6Yp.mjs.map +1 -0
- package/dist/exports/control-api.d.mts +4 -4
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +3 -3
- package/dist/exports/index.mjs +2 -2
- package/dist/exports/init-output.d.mts.map +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{format-DAUAZqPt.mjs → format-cCyDfmRE.mjs} +8 -7
- package/dist/format-cCyDfmRE.mjs.map +1 -0
- package/dist/{framework-components-CnbUbiJw.mjs → framework-components-DUN-TYDg.mjs} +3 -3
- package/dist/framework-components-DUN-TYDg.mjs.map +1 -0
- package/dist/{init-C3JhkHg-.mjs → init-C9U3ffHH.mjs} +55 -47
- package/dist/init-C9U3ffHH.mjs.map +1 -0
- package/dist/{inspect-live-schema-CX7EA5C3.mjs → inspect-live-schema-DHXE7skX.mjs} +4 -4
- package/dist/{inspect-live-schema-CX7EA5C3.mjs.map → inspect-live-schema-DHXE7skX.mjs.map} +1 -1
- package/dist/{migration-check-MHT3w7_v.mjs → migration-check-W5XEx4d-.mjs} +58 -30
- package/dist/migration-check-W5XEx4d-.mjs.map +1 -0
- package/dist/{migration-command-scaffold-CRyYrHZ9.mjs → migration-command-scaffold-hI5cnoGe.mjs} +4 -4
- package/dist/{migration-command-scaffold-CRyYrHZ9.mjs.map → migration-command-scaffold-hI5cnoGe.mjs.map} +1 -1
- package/dist/{migration-graph-command-render-B83xrnNy.mjs → migration-graph-command-render-DgQg5App.mjs} +3 -3
- package/dist/migration-graph-command-render-DgQg5App.mjs.map +1 -0
- package/dist/{migration-list-BAKujUjh.mjs → migration-list-ClkEaoL8.mjs} +6 -6
- package/dist/migration-list-ClkEaoL8.mjs.map +1 -0
- package/dist/{migration-log-C_xam2HZ.mjs → migration-log-CjafbZ2Z.mjs} +5 -5
- package/dist/{migration-log-C_xam2HZ.mjs.map → migration-log-CjafbZ2Z.mjs.map} +1 -1
- package/dist/{migration-path-target-DpPTsRCg.mjs → migration-path-target-C0TQuV5n.mjs} +2 -2
- package/dist/{migration-path-target-DpPTsRCg.mjs.map → migration-path-target-C0TQuV5n.mjs.map} +1 -1
- package/dist/{migration-plan-CreSVtWZ.mjs → migration-plan-Pc4hCF1H.mjs} +64 -74
- package/dist/migration-plan-Pc4hCF1H.mjs.map +1 -0
- package/dist/{migration-status-YgEvXf-u.mjs → migration-status-CqAdRzs8.mjs} +13 -12
- package/dist/migration-status-CqAdRzs8.mjs.map +1 -0
- package/dist/{output-mEQ74_nd.mjs → output-DWNYqZGc.mjs} +5 -6
- package/dist/output-DWNYqZGc.mjs.map +1 -0
- package/dist/{ref-advancement-BkXlikCA.mjs → ref-advancement-BCz7X7qJ.mjs} +13 -6
- package/dist/ref-advancement-BCz7X7qJ.mjs.map +1 -0
- package/dist/{telemetry-DVr6RFnq.mjs → telemetry-BEyNMfco.mjs} +2 -2
- package/dist/{telemetry-DVr6RFnq.mjs.map → telemetry-BEyNMfco.mjs.map} +1 -1
- package/dist/{types-D4r_HI9-.d.mts → types-DgXprE3w.d.mts} +3 -3
- package/dist/types-DgXprE3w.d.mts.map +1 -0
- package/dist/{verify-CgDVZjhc.mjs → verify-C4RazDE1.mjs} +2 -2
- package/dist/{verify-CgDVZjhc.mjs.map → verify-C4RazDE1.mjs.map} +1 -1
- package/package.json +21 -21
- package/src/commands/db-init.ts +1 -0
- package/src/commands/db-sign.ts +7 -5
- package/src/commands/db-update.ts +14 -6
- package/src/commands/db-verify.ts +1 -1
- package/src/commands/format.ts +1 -1
- package/src/commands/init/hygiene-gitattributes.ts +37 -21
- package/src/commands/init/init.ts +6 -6
- package/src/commands/init/output.ts +4 -5
- package/src/commands/init/reinit-cleanup.ts +16 -17
- package/src/commands/inspect-live-schema.ts +1 -1
- package/src/commands/migrate.ts +6 -5
- package/src/commands/migration-check.ts +72 -34
- package/src/commands/migration-list.ts +1 -5
- package/src/commands/migration-log.ts +1 -1
- package/src/commands/migration-new.ts +17 -41
- package/src/commands/migration-plan.ts +64 -88
- package/src/commands/migration-show.ts +2 -2
- package/src/commands/migration-status.ts +6 -7
- package/src/commands/ref.ts +19 -14
- package/src/control-api/client.ts +7 -8
- package/src/control-api/contract-enrichment.ts +7 -7
- package/src/control-api/operations/contract-emit.ts +2 -3
- package/src/control-api/operations/db-init.ts +3 -3
- package/src/control-api/operations/db-run.ts +6 -6
- package/src/control-api/operations/db-update.ts +2 -2
- package/src/control-api/operations/db-verify.ts +4 -4
- package/src/control-api/operations/format.ts +5 -4
- package/src/control-api/operations/migrate.ts +3 -3
- package/src/control-api/types.ts +1 -1
- package/src/utils/cli-errors.ts +15 -7
- package/src/utils/contract-at-errors.ts +13 -22
- package/src/utils/contract-space-aggregate-loader.ts +8 -8
- package/src/utils/contract-space-seed-phase.ts +11 -9
- package/src/utils/extension-pack-inputs.ts +8 -8
- package/src/utils/formatters/migration-graph-labels.ts +1 -2
- package/src/utils/formatters/migration-list-data-column.ts +1 -2
- package/src/utils/framework-components.ts +9 -9
- package/src/utils/integrity-violation-to-check-failure.ts +3 -3
- package/src/utils/migration-command-scaffold.ts +1 -1
- package/src/utils/plan-resolution.ts +7 -10
- package/src/utils/ref-advancement.ts +22 -3
- package/dist/client-KuBQftxz.mjs.map +0 -1
- package/dist/command-helpers-Cpq44aVa.mjs.map +0 -1
- package/dist/contract-at-errors-D9gEjYtg.mjs +0 -42
- package/dist/contract-at-errors-D9gEjYtg.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-D_3VeHVb.mjs.map +0 -1
- package/dist/db-verify-BEclUzki.mjs.map +0 -1
- package/dist/format-DAUAZqPt.mjs.map +0 -1
- package/dist/framework-components-CnbUbiJw.mjs.map +0 -1
- package/dist/init-C3JhkHg-.mjs.map +0 -1
- package/dist/migration-check-MHT3w7_v.mjs.map +0 -1
- package/dist/migration-graph-command-render-B83xrnNy.mjs.map +0 -1
- package/dist/migration-list-BAKujUjh.mjs.map +0 -1
- package/dist/migration-plan-CreSVtWZ.mjs.map +0 -1
- package/dist/migration-status-YgEvXf-u.mjs.map +0 -1
- package/dist/output-mEQ74_nd.mjs.map +0 -1
- package/dist/ref-advancement-BkXlikCA.mjs.map +0 -1
- package/dist/types-D4r_HI9-.d.mts.map +0 -1
|
@@ -2,7 +2,7 @@ import { materialiseExtensionMigrationPackageIfMissing } from '@prisma-next/migr
|
|
|
2
2
|
import type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';
|
|
3
3
|
import type { MigrationOps } from '@prisma-next/migration-tools/package';
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
emitContractSpaceArtifacts,
|
|
6
6
|
planAllSpaces,
|
|
7
7
|
readContractSpaceHeadRef,
|
|
8
8
|
type SpacePlanOutput,
|
|
@@ -39,7 +39,7 @@ export interface SeedPhaseExtensionInput {
|
|
|
39
39
|
|
|
40
40
|
export interface ContractSpaceSeedPhaseInputs {
|
|
41
41
|
readonly migrationsDir: string;
|
|
42
|
-
readonly
|
|
42
|
+
readonly extensions: ReadonlyArray<SeedPhaseExtensionInput>;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
@@ -53,7 +53,7 @@ export interface ContractSpaceSeedPhaseInputs {
|
|
|
53
53
|
* - `action: 'unchanged'` — the on-disk head already matched the
|
|
54
54
|
* descriptor and no new migration packages needed to be written.
|
|
55
55
|
*
|
|
56
|
-
* Either way, the
|
|
56
|
+
* Either way, the artifacts (`contract.json`, `contract.d.ts`,
|
|
57
57
|
* `refs/head.json`) are re-emitted: the framework owns those files and
|
|
58
58
|
* makes the re-emit observably idempotent at the byte level.
|
|
59
59
|
*/
|
|
@@ -75,9 +75,11 @@ export interface ContractSpaceSeedPhaseResult {
|
|
|
75
75
|
* For every extension that exposes a `contractSpace`:
|
|
76
76
|
*
|
|
77
77
|
* 1. Read the on-disk head ref (returns `null` on first emit).
|
|
78
|
-
* 2.
|
|
79
|
-
*
|
|
80
|
-
*
|
|
78
|
+
* 2. Write the head contract into the migrations-root snapshot store
|
|
79
|
+
* (write-if-absent, keyed by hash) and unconditionally re-emit
|
|
80
|
+
* `refs/head.json`, via {@link emitContractSpaceArtifacts}. The
|
|
81
|
+
* framework owns `refs/head.json`; re-emit is the contract for that
|
|
82
|
+
* file. The snapshot itself is only written once per distinct hash.
|
|
81
83
|
* 3. Materialise any descriptor-shipped migration packages not yet on
|
|
82
84
|
* disk via {@link materialiseExtensionMigrationPackageIfMissing}.
|
|
83
85
|
* Existing packages are left untouched (by-existence skip).
|
|
@@ -96,7 +98,7 @@ export interface ContractSpaceSeedPhaseResult {
|
|
|
96
98
|
export async function runContractSpaceSeedPhase(
|
|
97
99
|
inputs: ContractSpaceSeedPhaseInputs,
|
|
98
100
|
): Promise<ContractSpaceSeedPhaseResult> {
|
|
99
|
-
const planInputs = inputs.
|
|
101
|
+
const planInputs = inputs.extensions
|
|
100
102
|
.filter(
|
|
101
103
|
(
|
|
102
104
|
pack,
|
|
@@ -132,7 +134,7 @@ export async function runContractSpaceSeedPhase(
|
|
|
132
134
|
string,
|
|
133
135
|
NonNullable<SeedPhaseExtensionInput['contractSpace']>
|
|
134
136
|
>();
|
|
135
|
-
for (const pack of inputs.
|
|
137
|
+
for (const pack of inputs.extensions) {
|
|
136
138
|
if (pack.contractSpace !== undefined) descriptorBySpace.set(pack.id, pack.contractSpace);
|
|
137
139
|
}
|
|
138
140
|
|
|
@@ -144,7 +146,7 @@ export async function runContractSpaceSeedPhase(
|
|
|
144
146
|
const onDiskHeadRef = await readContractSpaceHeadRef(inputs.migrationsDir, space.spaceId);
|
|
145
147
|
const priorHash = onDiskHeadRef?.hash ?? null;
|
|
146
148
|
|
|
147
|
-
await
|
|
149
|
+
await emitContractSpaceArtifacts(inputs.migrationsDir, space.spaceId, {
|
|
148
150
|
contract: descriptor.contractJson,
|
|
149
151
|
contractDts: buildPlaceholderContractDts(space.spaceId),
|
|
150
152
|
headRef: { hash: descriptor.headRef.hash, invariants: descriptor.headRef.invariants },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Single descriptor-import boundary for CLI consumers of `Config.
|
|
2
|
+
* Single descriptor-import boundary for CLI consumers of `Config.extensions`.
|
|
3
3
|
*
|
|
4
4
|
* Every CLI command / utility that reads an extension descriptor's
|
|
5
5
|
* `contractSpace` projection (loader, migrate-pass, extension-migrations
|
|
@@ -54,9 +54,9 @@ export interface ExtensionPackInput {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* Structural shape we read off each `Config.
|
|
57
|
+
* Structural shape we read off each `Config.extensions` entry.
|
|
58
58
|
*
|
|
59
|
-
* The CLI is the descriptor-import boundary; `
|
|
59
|
+
* The CLI is the descriptor-import boundary; `extensions` is the only
|
|
60
60
|
* surface where the SQL-family-typed `ControlExtensionDescriptor` flows
|
|
61
61
|
* into framework-neutral helpers. The structural cast lives here, and
|
|
62
62
|
* here alone — every other CLI consumer reads the canonical
|
|
@@ -76,14 +76,14 @@ type ExtensionPackLike = {
|
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* Project the CLI's `Config.
|
|
79
|
+
* Project the CLI's `Config.extensions` array into the canonical
|
|
80
80
|
* {@link ExtensionPackInput} shape. The single `as ExtensionPackLike`
|
|
81
81
|
* structural cast in the CLI lives inside this function.
|
|
82
82
|
*/
|
|
83
83
|
export function toExtensionInputs(
|
|
84
|
-
|
|
84
|
+
extensions: ReadonlyArray<unknown>,
|
|
85
85
|
): readonly ExtensionPackInput[] {
|
|
86
|
-
return
|
|
86
|
+
return extensions.map((raw) => {
|
|
87
87
|
const pack = raw as ExtensionPackLike;
|
|
88
88
|
if (pack.contractSpace === undefined) {
|
|
89
89
|
return { id: pack.id, targetId: pack.targetId };
|
|
@@ -147,10 +147,10 @@ export function toDeclaredExtensions(
|
|
|
147
147
|
* always reads the contract from on-disk artefacts instead.
|
|
148
148
|
*/
|
|
149
149
|
export function toDeclaredExtensionsFromRaw(
|
|
150
|
-
|
|
150
|
+
extensions: ReadonlyArray<unknown>,
|
|
151
151
|
): readonly DeclaredExtensionEntry[] {
|
|
152
152
|
const entries: DeclaredExtensionEntry[] = [];
|
|
153
|
-
for (const raw of
|
|
153
|
+
for (const raw of extensions) {
|
|
154
154
|
if (typeof raw !== 'object' || raw === null) continue;
|
|
155
155
|
const descriptor = Object.getOwnPropertyDescriptor(raw, 'contractSpace');
|
|
156
156
|
if (descriptor === undefined) continue;
|
|
@@ -104,8 +104,7 @@ function abbreviateHash(hash: string, hashLength: number, emptySource: string):
|
|
|
104
104
|
if (hash === EMPTY_CONTRACT_HASH) {
|
|
105
105
|
return emptySource;
|
|
106
106
|
}
|
|
107
|
-
|
|
108
|
-
return stripped.slice(0, hashLength);
|
|
107
|
+
return hash.slice(0, hashLength);
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
interface ContractOverlayNames {
|
|
@@ -18,8 +18,7 @@ export function migrationListEmptySource(glyphMode: GlyphMode): string {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export function abbreviateContractHash(hash: string): string {
|
|
21
|
-
|
|
22
|
-
return stripped.slice(0, MIGRATION_LIST_HASH_WIDTH);
|
|
21
|
+
return hash.slice(0, MIGRATION_LIST_HASH_WIDTH);
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
export function padFromHashColumn(text: string, width: number): string {
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
type TargetBoundComponentDescriptor,
|
|
5
5
|
} from '@prisma-next/framework-components/components';
|
|
6
6
|
import type { ControlStack } from '@prisma-next/framework-components/control';
|
|
7
|
-
import { errorConfigValidation,
|
|
7
|
+
import { errorConfigValidation, errorContractMissingExtensions } from './cli-errors';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Asserts that all framework components are compatible with the expected family and target.
|
|
@@ -27,7 +27,7 @@ import { errorConfigValidation, errorContractMissingExtensionPacks } from './cli
|
|
|
27
27
|
* @example
|
|
28
28
|
* ```ts
|
|
29
29
|
* const config = await loadConfig();
|
|
30
|
-
* const frameworkComponents = [config.target, config.adapter, ...(config.
|
|
30
|
+
* const frameworkComponents = [config.target, config.adapter, ...(config.extensions ?? [])];
|
|
31
31
|
*
|
|
32
32
|
* // Validate and type-narrow components before passing to planner
|
|
33
33
|
* const typedComponents = assertFrameworkComponentsCompatible(
|
|
@@ -114,12 +114,12 @@ export function assertFrameworkComponentsCompatible<
|
|
|
114
114
|
* This check ensures the emitted contract matches the CLI config before running
|
|
115
115
|
* commands that depend on the contract (e.g., db verify, db sign).
|
|
116
116
|
*
|
|
117
|
-
* @param contract - The contract to validate (must include targetFamily, target,
|
|
118
|
-
* @param stack - The control plane stack (target, adapter, driver,
|
|
117
|
+
* @param contract - The contract to validate (must include targetFamily, target, extensions).
|
|
118
|
+
* @param stack - The control plane stack (target, adapter, driver, extensions).
|
|
119
119
|
*
|
|
120
120
|
* @throws {CliStructuredError} errorConfigValidation when contract.targetFamily or contract.target
|
|
121
121
|
* doesn't match the configured family/target.
|
|
122
|
-
* @throws {CliStructuredError}
|
|
122
|
+
* @throws {CliStructuredError} errorContractMissingExtensions when the contract requires
|
|
123
123
|
* extension packs that are not provided in the config (includes all missing packs in error.meta).
|
|
124
124
|
*
|
|
125
125
|
* @example
|
|
@@ -141,14 +141,14 @@ export function assertContractRequirementsSatisfied<
|
|
|
141
141
|
contract,
|
|
142
142
|
stack,
|
|
143
143
|
}: {
|
|
144
|
-
readonly contract: Pick<Contract, 'targetFamily' | 'target' | '
|
|
144
|
+
readonly contract: Pick<Contract, 'targetFamily' | 'target' | 'extensions'>;
|
|
145
145
|
readonly stack: ControlStack<TFamilyId, TTargetId>;
|
|
146
146
|
}): void {
|
|
147
147
|
const providedComponentIds = new Set<string>([
|
|
148
148
|
stack.target.id,
|
|
149
149
|
...(stack.adapter ? [stack.adapter.id] : []),
|
|
150
150
|
]);
|
|
151
|
-
for (const extension of stack.
|
|
151
|
+
for (const extension of stack.extensions) {
|
|
152
152
|
providedComponentIds.add(extension.id);
|
|
153
153
|
}
|
|
154
154
|
|
|
@@ -172,8 +172,8 @@ export function assertContractRequirementsSatisfied<
|
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
if (result.missingExtensionPackIds.length > 0) {
|
|
175
|
-
throw
|
|
176
|
-
|
|
175
|
+
throw errorContractMissingExtensions({
|
|
176
|
+
missingExtensions: result.missingExtensionPackIds,
|
|
177
177
|
providedComponentIds: [...providedComponentIds],
|
|
178
178
|
});
|
|
179
179
|
}
|
|
@@ -69,15 +69,15 @@ export function integrityViolationToCheckFailure(
|
|
|
69
69
|
code: 'MIGRATION.CHECK_ORPHAN_SPACE_DIR',
|
|
70
70
|
where: spaceRelative(violation.spaceId),
|
|
71
71
|
why: `Contract-space directory "${violation.spaceId}" exists on disk but no extension declares it.`,
|
|
72
|
-
fix: 'Remove the orphan directory, or declare the extension in `
|
|
72
|
+
fix: 'Remove the orphan directory, or declare the extension in `extensions`.',
|
|
73
73
|
};
|
|
74
74
|
case 'declaredButUnmigrated':
|
|
75
75
|
return {
|
|
76
76
|
space: violation.spaceId,
|
|
77
77
|
code: 'MIGRATION.CHECK_DECLARED_BUT_UNMIGRATED',
|
|
78
78
|
where: spaceRelative(violation.spaceId),
|
|
79
|
-
why: `Extension "${violation.spaceId}" is declared in \`
|
|
80
|
-
fix: 'Re-emit the extension contract-space artefacts with `prisma-next contract emit` and migration planning, or remove the extension from `
|
|
79
|
+
why: `Extension "${violation.spaceId}" is declared in \`extensions\` but has no on-disk migrations directory.`,
|
|
80
|
+
fix: 'Re-emit the extension contract-space artefacts with `prisma-next contract emit` and migration planning, or remove the extension from `extensions` if it is unused.',
|
|
81
81
|
};
|
|
82
82
|
case 'headRefMissing':
|
|
83
83
|
return {
|
|
@@ -154,7 +154,7 @@ export async function prepareMigrationContext(
|
|
|
154
154
|
target: config.target,
|
|
155
155
|
adapter: config.adapter,
|
|
156
156
|
driver: config.driver,
|
|
157
|
-
|
|
157
|
+
extensions: config.extensions ?? [],
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
// Create progress adapter
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from './cli-errors';
|
|
20
20
|
import { mapContractAtError } from './contract-at-errors';
|
|
21
21
|
|
|
22
|
-
const FULL_HASH_PATTERN = /^
|
|
22
|
+
const FULL_HASH_PATTERN = /^([0-9a-f]{64}|empty)$/;
|
|
23
23
|
|
|
24
24
|
export function looksLikeFullHash(input: string): boolean {
|
|
25
25
|
return FULL_HASH_PATTERN.test(input);
|
|
@@ -27,9 +27,9 @@ export function looksLikeFullHash(input: string): boolean {
|
|
|
27
27
|
|
|
28
28
|
export type FromResolution =
|
|
29
29
|
| { kind: 'greenfield'; fromHash: null; fromContract: null }
|
|
30
|
-
| { kind: 'graph-node'; fromHash: string; fromContract: Contract
|
|
30
|
+
| { kind: 'graph-node'; fromHash: string; fromContract: Contract }
|
|
31
31
|
| {
|
|
32
|
-
kind: '
|
|
32
|
+
kind: 'ref';
|
|
33
33
|
fromHash: string;
|
|
34
34
|
fromContract: Contract;
|
|
35
35
|
contractDts: string;
|
|
@@ -81,7 +81,7 @@ export function assertFromIsGraphNode(
|
|
|
81
81
|
|
|
82
82
|
type RefContractResolution =
|
|
83
83
|
| {
|
|
84
|
-
kind: '
|
|
84
|
+
kind: 'ref';
|
|
85
85
|
hash: string;
|
|
86
86
|
contract: Contract;
|
|
87
87
|
contractJson: unknown;
|
|
@@ -93,7 +93,6 @@ type RefContractResolution =
|
|
|
93
93
|
contract: Contract;
|
|
94
94
|
contractJson: unknown;
|
|
95
95
|
contractDts: string;
|
|
96
|
-
sourceDir: string;
|
|
97
96
|
};
|
|
98
97
|
|
|
99
98
|
async function resolveContractRef(
|
|
@@ -107,9 +106,9 @@ async function resolveContractRef(
|
|
|
107
106
|
try {
|
|
108
107
|
const at = await space.contractAt(hash, refName !== undefined ? { refName } : undefined);
|
|
109
108
|
|
|
110
|
-
if (at.provenance === '
|
|
109
|
+
if (at.provenance === 'ref') {
|
|
111
110
|
return ok({
|
|
112
|
-
kind: '
|
|
111
|
+
kind: 'ref',
|
|
113
112
|
hash: at.hash,
|
|
114
113
|
contract: at.contract,
|
|
115
114
|
contractJson: at.contractJson,
|
|
@@ -123,7 +122,6 @@ async function resolveContractRef(
|
|
|
123
122
|
contract: at.contract,
|
|
124
123
|
contractJson: at.contractJson,
|
|
125
124
|
contractDts: at.contractDts,
|
|
126
|
-
sourceDir: at.sourceDir,
|
|
127
125
|
});
|
|
128
126
|
} catch (error) {
|
|
129
127
|
return mapContractAtError(
|
|
@@ -152,7 +150,6 @@ async function resolveFromPolicy(
|
|
|
152
150
|
kind: 'graph-node',
|
|
153
151
|
fromHash: resolution.value.hash,
|
|
154
152
|
fromContract: resolution.value.contract,
|
|
155
|
-
sourceDir: resolution.value.sourceDir,
|
|
156
153
|
});
|
|
157
154
|
}
|
|
158
155
|
|
|
@@ -178,7 +175,7 @@ async function resolveFromPolicy(
|
|
|
178
175
|
throw error;
|
|
179
176
|
}
|
|
180
177
|
return ok({
|
|
181
|
-
kind: '
|
|
178
|
+
kind: 'ref',
|
|
182
179
|
fromHash: hash,
|
|
183
180
|
fromContract: contract,
|
|
184
181
|
contractDts,
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
2
|
+
import { writeContractSnapshot } from '@prisma-next/migration-tools/contract-snapshot-store';
|
|
3
|
+
import { errorInvalidRefName } from '@prisma-next/migration-tools/errors';
|
|
4
|
+
import { validateRefName, writeRef } from '@prisma-next/migration-tools/refs';
|
|
4
5
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
5
6
|
|
|
7
|
+
export interface ContractIR {
|
|
8
|
+
readonly contract: unknown;
|
|
9
|
+
readonly contractDts: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
6
12
|
export interface RefAdvancementFields {
|
|
7
13
|
readonly advancedRef: { readonly name: string; readonly hash: string } | null;
|
|
8
14
|
readonly plannedAdvanceRef: { readonly name: string; readonly hash: string } | null;
|
|
@@ -32,11 +38,22 @@ export async function readContractIR(
|
|
|
32
38
|
|
|
33
39
|
export async function executeRefAdvancement(
|
|
34
40
|
refsDir: string,
|
|
41
|
+
migrationsDir: string,
|
|
35
42
|
name: string,
|
|
36
43
|
hash: string,
|
|
37
44
|
contractIR: ContractIR,
|
|
38
45
|
): Promise<{ name: string; hash: string }> {
|
|
39
|
-
|
|
46
|
+
// Validate the ref name before writing anything: writeRef validates it too,
|
|
47
|
+
// but only after the store write below, which would otherwise leave a
|
|
48
|
+
// (harmless, but pointless) orphan store entry on an invalid name.
|
|
49
|
+
if (!validateRefName(name)) {
|
|
50
|
+
throw errorInvalidRefName(name);
|
|
51
|
+
}
|
|
52
|
+
await writeContractSnapshot(migrationsDir, hash, {
|
|
53
|
+
contractJson: contractIR.contract,
|
|
54
|
+
contractDts: contractIR.contractDts,
|
|
55
|
+
});
|
|
56
|
+
await writeRef(refsDir, name, { hash, invariants: [] });
|
|
40
57
|
return { name, hash };
|
|
41
58
|
}
|
|
42
59
|
|
|
@@ -44,6 +61,7 @@ export async function buildRefAdvancementFields(options: {
|
|
|
44
61
|
readonly advanceRef?: string;
|
|
45
62
|
readonly db?: string;
|
|
46
63
|
readonly refsDir: string;
|
|
64
|
+
readonly migrationsDir: string;
|
|
47
65
|
readonly contractIR: ContractIR;
|
|
48
66
|
readonly mode: 'plan' | 'apply';
|
|
49
67
|
readonly hash: string;
|
|
@@ -60,6 +78,7 @@ export async function buildRefAdvancementFields(options: {
|
|
|
60
78
|
}
|
|
61
79
|
const advancedRef = await executeRefAdvancement(
|
|
62
80
|
options.refsDir,
|
|
81
|
+
options.migrationsDir,
|
|
63
82
|
name,
|
|
64
83
|
options.hash,
|
|
65
84
|
options.contractIR,
|