@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
|
@@ -119,7 +119,7 @@ async function executeMigrationShowCommand(
|
|
|
119
119
|
target: config.target,
|
|
120
120
|
adapter: config.adapter,
|
|
121
121
|
...ifDefined('driver', config.driver),
|
|
122
|
-
|
|
122
|
+
extensions: config.extensions ?? [],
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
let contractJsonContent: string;
|
|
@@ -228,7 +228,7 @@ export function createMigrationShowCommand(): Command {
|
|
|
228
228
|
);
|
|
229
229
|
setCommandExamples(command, [
|
|
230
230
|
'prisma-next migration show 20260101_100000_add_user',
|
|
231
|
-
'prisma-next migration show
|
|
231
|
+
'prisma-next migration show a1b2c3',
|
|
232
232
|
'prisma-next migration show 20260101_100000_add_user --json',
|
|
233
233
|
]);
|
|
234
234
|
setCommandSeeAlso(command, [
|
|
@@ -111,8 +111,7 @@ interface MigrationStatusCommandResult {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
function shortDisplayHash(hash: string): string {
|
|
114
|
-
|
|
115
|
-
return stripped.slice(0, 12);
|
|
114
|
+
return hash.slice(0, 12);
|
|
116
115
|
}
|
|
117
116
|
|
|
118
117
|
function resolveTarget(contractHash: string, activeRefHash: string | undefined): string {
|
|
@@ -421,7 +420,7 @@ export async function executeMigrationStatusCommand(
|
|
|
421
420
|
target: config.target,
|
|
422
421
|
adapter: config.adapter,
|
|
423
422
|
driver: config.driver,
|
|
424
|
-
|
|
423
|
+
extensions: config.extensions ?? [],
|
|
425
424
|
});
|
|
426
425
|
try {
|
|
427
426
|
await client.connect(dbConnection);
|
|
@@ -660,10 +659,10 @@ export function createMigrationStatusCommand(): Command {
|
|
|
660
659
|
setCommandExamples(command, [
|
|
661
660
|
'prisma-next migration status --db $DATABASE_URL',
|
|
662
661
|
'prisma-next migration status --to production --db $DATABASE_URL',
|
|
663
|
-
'prisma-next migration status --from
|
|
664
|
-
'prisma-next migration status --from
|
|
665
|
-
'prisma-next migration status --ascii --from
|
|
666
|
-
'prisma-next migration status --legend --from
|
|
662
|
+
'prisma-next migration status --from abc123 --to production',
|
|
663
|
+
'prisma-next migration status --from abc123 --to production --json',
|
|
664
|
+
'prisma-next migration status --ascii --from abc123 --to production',
|
|
665
|
+
'prisma-next migration status --legend --from abc123 --to production',
|
|
667
666
|
]);
|
|
668
667
|
setCommandSeeAlso(command, [
|
|
669
668
|
{ verb: 'migration log', oneLiner: 'Show executed migration history' },
|
package/src/commands/ref.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
2
1
|
import { loadConfig } from '@prisma-next/config-loader';
|
|
3
2
|
import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';
|
|
3
|
+
import {
|
|
4
|
+
contractSnapshotDir,
|
|
5
|
+
readContractSnapshotJson,
|
|
6
|
+
} from '@prisma-next/migration-tools/contract-snapshot-store';
|
|
4
7
|
import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
5
8
|
import { findLatestMigration, isGraphNode } from '@prisma-next/migration-tools/migration-graph';
|
|
6
9
|
import { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';
|
|
7
10
|
import type { RefEntry } from '@prisma-next/migration-tools/refs';
|
|
8
11
|
import {
|
|
9
|
-
|
|
12
|
+
deleteRef,
|
|
10
13
|
readRefs,
|
|
11
14
|
validateRefName,
|
|
12
15
|
validateRefValue,
|
|
13
|
-
|
|
16
|
+
writeRef,
|
|
14
17
|
} from '@prisma-next/migration-tools/refs';
|
|
15
18
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
16
19
|
import { Command } from 'commander';
|
|
@@ -34,7 +37,6 @@ import {
|
|
|
34
37
|
import { buildReadAggregate } from '../utils/contract-space-aggregate-loader';
|
|
35
38
|
import { formatCommandHelp } from '../utils/formatters/help';
|
|
36
39
|
import { parseGlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
37
|
-
import { readContractIR } from '../utils/ref-advancement';
|
|
38
40
|
import { handleResult } from '../utils/result-handler';
|
|
39
41
|
import { createTerminalUI } from '../utils/terminal-ui';
|
|
40
42
|
|
|
@@ -114,26 +116,29 @@ export async function executeRefSetCommand(
|
|
|
114
116
|
return notOk(errorRefSetBundleNotFound(resolvedHash));
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
const contractJsonPath = join(
|
|
118
|
-
|
|
119
|
+
const contractJsonPath = join(
|
|
120
|
+
contractSnapshotDir(migrationsDir, resolvedHash),
|
|
121
|
+
'contract.json',
|
|
122
|
+
);
|
|
119
123
|
try {
|
|
120
|
-
|
|
121
|
-
contractJson = JSON.parse(raw) as Record<string, unknown>;
|
|
124
|
+
await readContractSnapshotJson(migrationsDir, resolvedHash);
|
|
122
125
|
} catch (readError) {
|
|
123
|
-
if (
|
|
126
|
+
if (
|
|
127
|
+
MigrationToolsError.is(readError) &&
|
|
128
|
+
readError.code === 'MIGRATION.CONTRACT_SNAPSHOT_MISSING'
|
|
129
|
+
) {
|
|
124
130
|
return notOk(
|
|
125
131
|
errorFileNotFound(contractJsonPath, {
|
|
126
|
-
why: `Migration bundle for hash ${resolvedHash} is missing its
|
|
127
|
-
fix: '
|
|
132
|
+
why: `Migration bundle for hash ${resolvedHash} is missing its contract snapshot at ${contractJsonPath}`,
|
|
133
|
+
fix: 'Restore migrations/snapshots/ from version control, or re-run the command that produced this migration to regenerate its snapshot.',
|
|
128
134
|
}),
|
|
129
135
|
);
|
|
130
136
|
}
|
|
131
137
|
throw readError;
|
|
132
138
|
}
|
|
133
139
|
|
|
134
|
-
const contractIR = await readContractIR(contractJson, contractJsonPath);
|
|
135
140
|
const entry: RefEntry = { hash: resolvedHash, invariants: [] };
|
|
136
|
-
await
|
|
141
|
+
await writeRef(refsDir, name, entry);
|
|
137
142
|
return ok({ ok: true as const, ref: name, hash: resolvedHash, invariants: [] });
|
|
138
143
|
} catch (error) {
|
|
139
144
|
if (error instanceof CliStructuredError) return notOk(error);
|
|
@@ -148,7 +153,7 @@ export async function executeRefDeleteCommand(
|
|
|
148
153
|
try {
|
|
149
154
|
const config = await loadConfig(options.config);
|
|
150
155
|
const { refsDir } = resolveMigrationPaths(options.config, config);
|
|
151
|
-
await
|
|
156
|
+
await deleteRef(refsDir, name);
|
|
152
157
|
return ok({ ok: true as const, ref: name, deleted: true as const });
|
|
153
158
|
} catch (error) {
|
|
154
159
|
if (error instanceof CliStructuredError) return notOk(error);
|
|
@@ -103,7 +103,7 @@ class ControlClientImpl implements ControlClient {
|
|
|
103
103
|
target: this.options.target,
|
|
104
104
|
adapter: this.options.adapter,
|
|
105
105
|
driver: this.options.driver,
|
|
106
|
-
|
|
106
|
+
extensions: this.options.extensions,
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
this.familyInstance = this.options.family.create(this.stack);
|
|
@@ -112,7 +112,7 @@ class ControlClientImpl implements ControlClient {
|
|
|
112
112
|
const rawComponents = [
|
|
113
113
|
this.options.target,
|
|
114
114
|
this.options.adapter,
|
|
115
|
-
...(this.options.
|
|
115
|
+
...(this.options.extensions ?? []),
|
|
116
116
|
];
|
|
117
117
|
this.frameworkComponents = assertFrameworkComponentsCompatible(
|
|
118
118
|
this.options.family.familyId,
|
|
@@ -404,7 +404,7 @@ class ControlClientImpl implements ControlClient {
|
|
|
404
404
|
frameworkComponents,
|
|
405
405
|
migrationsDir: options.migrationsDir,
|
|
406
406
|
targetId: this.options.target.targetId,
|
|
407
|
-
|
|
407
|
+
extensions: this.options.extensions ?? [],
|
|
408
408
|
...ifDefined('onProgress', onProgress),
|
|
409
409
|
});
|
|
410
410
|
}
|
|
@@ -438,7 +438,7 @@ class ControlClientImpl implements ControlClient {
|
|
|
438
438
|
frameworkComponents,
|
|
439
439
|
migrationsDir: options.migrationsDir,
|
|
440
440
|
targetId: this.options.target.targetId,
|
|
441
|
-
|
|
441
|
+
extensions: this.options.extensions ?? [],
|
|
442
442
|
...ifDefined('acceptDataLoss', options.acceptDataLoss),
|
|
443
443
|
...ifDefined('onProgress', onProgress),
|
|
444
444
|
});
|
|
@@ -455,7 +455,7 @@ class ControlClientImpl implements ControlClient {
|
|
|
455
455
|
contract: options.contract,
|
|
456
456
|
migrationsDir: options.migrationsDir,
|
|
457
457
|
targetId: this.options.target.targetId,
|
|
458
|
-
|
|
458
|
+
extensions: this.options.extensions ?? [],
|
|
459
459
|
frameworkComponents,
|
|
460
460
|
mode: options.strict ? 'strict' : 'lenient',
|
|
461
461
|
skipSchema: options.skipSchema,
|
|
@@ -508,7 +508,7 @@ class ControlClientImpl implements ControlClient {
|
|
|
508
508
|
migrations: this.options.target.migrations,
|
|
509
509
|
frameworkComponents,
|
|
510
510
|
migrationsDir: options.migrationsDir,
|
|
511
|
-
|
|
511
|
+
extensions: this.options.extensions ?? [],
|
|
512
512
|
targetId: this.options.target.targetId,
|
|
513
513
|
...ifDefined('refHash', options.refHash),
|
|
514
514
|
...ifDefined('refInvariants', options.refInvariants),
|
|
@@ -607,9 +607,8 @@ class ControlClientImpl implements ControlClient {
|
|
|
607
607
|
try {
|
|
608
608
|
const stack = this.stack!;
|
|
609
609
|
const sourceContext = {
|
|
610
|
-
|
|
610
|
+
composedExtensions: stack.extensions.map((p) => p.id),
|
|
611
611
|
composedExtensionContracts: stack.extensionContracts,
|
|
612
|
-
scalarTypeDescriptors: stack.scalarTypeDescriptors,
|
|
613
612
|
authoringContributions: stack.authoringContributions,
|
|
614
613
|
codecLookup: stack.codecLookup,
|
|
615
614
|
controlMutationDefaults: stack.controlMutationDefaults,
|
|
@@ -65,21 +65,21 @@ export function enrichContract(
|
|
|
65
65
|
): Contract {
|
|
66
66
|
const mergedCapabilities = mergeCapabilityMatrices(ir.capabilities, components);
|
|
67
67
|
|
|
68
|
-
const
|
|
68
|
+
const extensionsMeta: Record<string, unknown> = {};
|
|
69
69
|
for (const component of components) {
|
|
70
70
|
if (component.kind === 'extension') {
|
|
71
|
-
|
|
71
|
+
extensionsMeta[component.id] = extractExtensionPackMeta(component);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const
|
|
76
|
-
Object.keys(
|
|
77
|
-
? { ...ir.
|
|
78
|
-
: ir.
|
|
75
|
+
const extensions =
|
|
76
|
+
Object.keys(extensionsMeta).length > 0
|
|
77
|
+
? { ...ir.extensions, ...extensionsMeta }
|
|
78
|
+
: ir.extensions;
|
|
79
79
|
|
|
80
80
|
return {
|
|
81
81
|
...ir,
|
|
82
82
|
capabilities: sortDeepTyped(mergedCapabilities),
|
|
83
|
-
|
|
83
|
+
extensions: sortDeepTyped(extensions),
|
|
84
84
|
};
|
|
85
85
|
}
|
|
@@ -195,9 +195,8 @@ export async function executeContractEmit(
|
|
|
195
195
|
const stack = createControlStack(config);
|
|
196
196
|
|
|
197
197
|
const sourceContext = {
|
|
198
|
-
|
|
198
|
+
composedExtensions: stack.extensions.map((p) => p.id),
|
|
199
199
|
composedExtensionContracts: stack.extensionContracts,
|
|
200
|
-
scalarTypeDescriptors: stack.scalarTypeDescriptors,
|
|
201
200
|
authoringContributions: stack.authoringContributions,
|
|
202
201
|
codecLookup: stack.codecLookup,
|
|
203
202
|
controlMutationDefaults: stack.controlMutationDefaults,
|
|
@@ -231,7 +230,7 @@ export async function executeContractEmit(
|
|
|
231
230
|
let emitResult: Awaited<ReturnType<typeof emit>>;
|
|
232
231
|
try {
|
|
233
232
|
const familyInstance = config.family.create(stack);
|
|
234
|
-
const rawComponents = [config.target, config.adapter, ...(config.
|
|
233
|
+
const rawComponents = [config.target, config.adapter, ...(config.extensions ?? [])];
|
|
235
234
|
const frameworkComponents = assertFrameworkComponentsCompatible(
|
|
236
235
|
config.family.familyId,
|
|
237
236
|
config.target.targetId,
|
|
@@ -25,7 +25,7 @@ import { executeRun } from './db-run';
|
|
|
25
25
|
* 3. The runner's `execute` applies the per-space plans
|
|
26
26
|
* inside one outer transaction.
|
|
27
27
|
*
|
|
28
|
-
* `
|
|
28
|
+
* `extensions` mirrors `Config.extensions` (descriptor list).
|
|
29
29
|
* The loader (sub-spec § Loader) is the sole descriptor-import boundary.
|
|
30
30
|
*/
|
|
31
31
|
export interface ExecuteDbInitOptions<TFamilyId extends string, TTargetId extends string> {
|
|
@@ -55,7 +55,7 @@ export interface ExecuteDbInitOptions<TFamilyId extends string, TTargetId extend
|
|
|
55
55
|
* routes through the same loader → planner → runner pipeline with no
|
|
56
56
|
* extension spaces in the aggregate.
|
|
57
57
|
*/
|
|
58
|
-
readonly
|
|
58
|
+
readonly extensions?: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
|
|
59
59
|
/** Optional progress callback for observing operation progress */
|
|
60
60
|
readonly onProgress?: OnControlProgress;
|
|
61
61
|
}
|
|
@@ -80,7 +80,7 @@ export async function executeDbInit<TFamilyId extends string, TTargetId extends
|
|
|
80
80
|
frameworkComponents: options.frameworkComponents,
|
|
81
81
|
migrationsDir: options.migrationsDir,
|
|
82
82
|
targetId: options.targetId,
|
|
83
|
-
|
|
83
|
+
extensions: options.extensions ?? [],
|
|
84
84
|
policy: { allowedOperationClasses: ['additive'] },
|
|
85
85
|
action: 'dbInit',
|
|
86
86
|
...ifDefined('onProgress', options.onProgress),
|
|
@@ -80,7 +80,7 @@ export interface ExecuteRunOptions<TFamilyId extends string, TTargetId extends s
|
|
|
80
80
|
>;
|
|
81
81
|
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
|
|
82
82
|
readonly migrationsDir: string;
|
|
83
|
-
readonly
|
|
83
|
+
readonly extensions: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
|
|
84
84
|
readonly targetId: TTargetId;
|
|
85
85
|
readonly policy: MigrationOperationPolicy;
|
|
86
86
|
readonly action: 'dbInit' | 'dbUpdate';
|
|
@@ -119,7 +119,7 @@ export async function executeRun<TFamilyId extends string, TTargetId extends str
|
|
|
119
119
|
migrations,
|
|
120
120
|
frameworkComponents,
|
|
121
121
|
migrationsDir,
|
|
122
|
-
|
|
122
|
+
extensions,
|
|
123
123
|
targetId,
|
|
124
124
|
policy,
|
|
125
125
|
action,
|
|
@@ -131,7 +131,7 @@ export async function executeRun<TFamilyId extends string, TTargetId extends str
|
|
|
131
131
|
targetId,
|
|
132
132
|
migrationsDir,
|
|
133
133
|
appContract: contract,
|
|
134
|
-
|
|
134
|
+
extensions,
|
|
135
135
|
deserializeContract: (json) => familyInstance.deserializeContract(json),
|
|
136
136
|
};
|
|
137
137
|
const loaded = await buildContractSpaceAggregate(loadInputs);
|
|
@@ -283,7 +283,7 @@ function aggregatePlannerWarnings(
|
|
|
283
283
|
* Compare the live `_prisma_marker` rows against the aggregate's
|
|
284
284
|
* declared contract spaces. Any marker row whose `space` is not a space of
|
|
285
285
|
* the aggregate is an "orphan" — typically a marker left behind by
|
|
286
|
-
* an extension that was removed from `
|
|
286
|
+
* an extension that was removed from `extensions` without first
|
|
287
287
|
* cleaning up its on-disk migrations / database tables.
|
|
288
288
|
*
|
|
289
289
|
* Returns a {@link CliStructuredError} envelope (code
|
|
@@ -319,8 +319,8 @@ function detectOrphanMarkers(
|
|
|
319
319
|
.map((s) => `"${s}"`)
|
|
320
320
|
.join(
|
|
321
321
|
', ',
|
|
322
|
-
)}) that are not declared in the project's \`
|
|
323
|
-
fix: 'Either re-declare the missing extension(s) in `
|
|
322
|
+
)}) that are not declared in the project's \`extensions\`. The aggregate pipeline refuses to advance markers it cannot account for.`,
|
|
323
|
+
fix: 'Either re-declare the missing extension(s) in `extensions` (so the aggregate owns them again), or remove the orphan marker row(s) from `_prisma_marker` once you have confirmed the corresponding tables can be safely retired.',
|
|
324
324
|
docsUrl: 'https://pris.ly/contract-spaces',
|
|
325
325
|
meta: {
|
|
326
326
|
violations: orphans.map((spaceId) => ({ kind: 'orphanMarker', spaceId })),
|
|
@@ -40,7 +40,7 @@ export interface ExecuteDbUpdateOptions<TFamilyId extends string, TTargetId exte
|
|
|
40
40
|
readonly acceptDataLoss?: boolean;
|
|
41
41
|
readonly migrationsDir: string;
|
|
42
42
|
readonly targetId: TTargetId;
|
|
43
|
-
readonly
|
|
43
|
+
readonly extensions?: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
|
|
44
44
|
readonly onProgress?: OnControlProgress;
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -65,7 +65,7 @@ export async function executeDbUpdate<TFamilyId extends string, TTargetId extend
|
|
|
65
65
|
frameworkComponents: options.frameworkComponents,
|
|
66
66
|
migrationsDir: options.migrationsDir,
|
|
67
67
|
targetId: options.targetId,
|
|
68
|
-
|
|
68
|
+
extensions: options.extensions ?? [],
|
|
69
69
|
policy: DB_UPDATE_POLICY,
|
|
70
70
|
action: 'dbUpdate' as const,
|
|
71
71
|
...ifDefined('onProgress', options.onProgress),
|
|
@@ -50,7 +50,7 @@ export interface ExecuteDbVerifyOptions<TFamilyId extends string, TTargetId exte
|
|
|
50
50
|
readonly contract: Contract;
|
|
51
51
|
readonly migrationsDir: string;
|
|
52
52
|
readonly targetId: TTargetId;
|
|
53
|
-
readonly
|
|
53
|
+
readonly extensions: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
|
|
54
54
|
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
|
|
55
55
|
readonly mode: 'strict' | 'lenient';
|
|
56
56
|
readonly skipSchema: boolean;
|
|
@@ -149,7 +149,7 @@ function buildLoadInputs<TFamilyId extends string, TTargetId extends string>(
|
|
|
149
149
|
targetId: options.targetId,
|
|
150
150
|
migrationsDir: options.migrationsDir,
|
|
151
151
|
appContract: options.contract,
|
|
152
|
-
|
|
152
|
+
extensions: options.extensions,
|
|
153
153
|
deserializeContract: (json) => options.familyInstance.deserializeContract(json),
|
|
154
154
|
};
|
|
155
155
|
}
|
|
@@ -349,7 +349,7 @@ function mapMarkerCheckFailures(
|
|
|
349
349
|
violations.push({
|
|
350
350
|
kind: 'orphanMarker',
|
|
351
351
|
spaceId: orphan.spaceId,
|
|
352
|
-
remediation: `Add the corresponding extension to \`
|
|
352
|
+
remediation: `Add the corresponding extension to \`extensions\` in \`prisma-next.config.ts\`, or delete the orphan marker row for "${orphan.spaceId}".`,
|
|
353
353
|
});
|
|
354
354
|
}
|
|
355
355
|
if (violations.length === 0) return null;
|
|
@@ -359,7 +359,7 @@ function mapMarkerCheckFailures(
|
|
|
359
359
|
? 'Contract-space verifier found a violation'
|
|
360
360
|
: `Contract-space verifier found violations (${violations.length})`;
|
|
361
361
|
return new CliStructuredError('MIGRATION.CONTRACT_SPACE_VIOLATION', summary, {
|
|
362
|
-
why: `The on-disk \`migrations/\` directory, the \`
|
|
362
|
+
why: `The on-disk \`migrations/\` directory, the \`extensions\` declaration, and the live database marker rows are not in agreement.\n${lines.join('\n')}`,
|
|
363
363
|
fix: violations[0]?.remediation ?? 'Review and reconcile the violations listed above.',
|
|
364
364
|
docsUrl: 'https://pris.ly/contract-spaces',
|
|
365
365
|
meta: { violations },
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { EOL } from 'node:os';
|
|
3
3
|
import { loadConfig } from '@prisma-next/config-loader';
|
|
4
|
-
import { type FormatOptions, format
|
|
4
|
+
import { type FormatOptions, format } from '@prisma-next/psl-parser/format';
|
|
5
5
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
6
|
+
import { isStructuredError } from '@prisma-next/utils/structured-error';
|
|
6
7
|
import { CliStructuredError, errorRuntime, errorUnexpected } from '../../utils/cli-errors';
|
|
7
8
|
|
|
8
9
|
export interface FormatOperationOptions {
|
|
@@ -41,7 +42,7 @@ export async function executeFormat(
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
const source = config.contract?.source;
|
|
44
|
-
if (source?.
|
|
45
|
+
if (source?.format !== 'psl') {
|
|
45
46
|
return ok({ formatted: false });
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -71,12 +72,12 @@ export async function executeFormat(
|
|
|
71
72
|
try {
|
|
72
73
|
formatted = format(contents, formatOptions);
|
|
73
74
|
} catch (error) {
|
|
74
|
-
if (error
|
|
75
|
+
if (isStructuredError(error) && error.code === 'PSL.PARSE_FAILED') {
|
|
75
76
|
return notOk(
|
|
76
77
|
errorRuntime('Cannot format PSL with parse errors', {
|
|
77
78
|
why: error.message,
|
|
78
79
|
fix: 'Fix the parse errors in your schema and try again.',
|
|
79
|
-
meta: { diagnostics: error.diagnostics },
|
|
80
|
+
meta: { diagnostics: error.meta?.['diagnostics'] },
|
|
80
81
|
}),
|
|
81
82
|
);
|
|
82
83
|
}
|
|
@@ -60,7 +60,7 @@ export interface ExecuteMigrateOptions<TFamilyId extends string, TTargetId exten
|
|
|
60
60
|
>;
|
|
61
61
|
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;
|
|
62
62
|
readonly migrationsDir: string;
|
|
63
|
-
readonly
|
|
63
|
+
readonly extensions: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
|
|
64
64
|
readonly targetId: TTargetId;
|
|
65
65
|
/**
|
|
66
66
|
* Optional app-space ref override. When provided, the app space's
|
|
@@ -122,7 +122,7 @@ export async function executeMigrate<TFamilyId extends string, TTargetId extends
|
|
|
122
122
|
migrations,
|
|
123
123
|
frameworkComponents,
|
|
124
124
|
migrationsDir,
|
|
125
|
-
|
|
125
|
+
extensions,
|
|
126
126
|
targetId,
|
|
127
127
|
refHash,
|
|
128
128
|
refInvariants,
|
|
@@ -134,7 +134,7 @@ export async function executeMigrate<TFamilyId extends string, TTargetId extends
|
|
|
134
134
|
targetId,
|
|
135
135
|
migrationsDir,
|
|
136
136
|
appContract: contract,
|
|
137
|
-
|
|
137
|
+
extensions,
|
|
138
138
|
deserializeContract: (json) => familyInstance.deserializeContract(json),
|
|
139
139
|
};
|
|
140
140
|
const loaded = await buildContractSpaceAggregate(loadInputs);
|
package/src/control-api/types.ts
CHANGED
|
@@ -52,7 +52,7 @@ export interface ControlClientOptions {
|
|
|
52
52
|
// biome-ignore lint/suspicious/noExplicitAny: required for contravariance in driver.create()
|
|
53
53
|
readonly driver?: ControlDriverDescriptor<any, any, any, any>;
|
|
54
54
|
// biome-ignore lint/suspicious/noExplicitAny: required for contravariance in extension.create()
|
|
55
|
-
readonly
|
|
55
|
+
readonly extensions?: ReadonlyArray<ControlExtensionDescriptor<any, any, any>>;
|
|
56
56
|
/**
|
|
57
57
|
* Optional default connection for auto-connect.
|
|
58
58
|
* When provided, operations will auto-connect if not already connected.
|
package/src/utils/cli-errors.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
errorConfigFileNotFound,
|
|
11
11
|
errorConfigValidation,
|
|
12
12
|
errorContractConfigMissing,
|
|
13
|
-
|
|
13
|
+
errorContractMissingExtensions,
|
|
14
14
|
errorContractValidationFailed,
|
|
15
15
|
errorDatabaseConnectionRequired,
|
|
16
16
|
errorDriverRequired,
|
|
@@ -54,7 +54,7 @@ export {
|
|
|
54
54
|
errorConfigFileNotFound,
|
|
55
55
|
errorConfigValidation,
|
|
56
56
|
errorContractConfigMissing,
|
|
57
|
-
|
|
57
|
+
errorContractMissingExtensions,
|
|
58
58
|
errorContractValidationFailed,
|
|
59
59
|
errorDatabaseConnectionRequired,
|
|
60
60
|
errorDriverRequired,
|
|
@@ -215,22 +215,30 @@ export function errorPlanForgotTheFlag(
|
|
|
215
215
|
});
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
+
/**
|
|
219
|
+
* `viaRef: true` (the default) mirrors migration-tools' `errorRefNotResolvable`:
|
|
220
|
+
* a ref name with no pointer file, where the fallback hash isn't a graph
|
|
221
|
+
* node either — there's nothing to materialize a contract from.
|
|
222
|
+
* `viaRef: false` is a distinct, ref-independent case: an explicit `--from
|
|
223
|
+
* <hash>` that doesn't name a ref, on an empty migration graph, so there is
|
|
224
|
+
* no graph node and no ref to resolve a contract through.
|
|
225
|
+
*/
|
|
218
226
|
export function errorSnapshotMissing(
|
|
219
227
|
identifier: string,
|
|
220
228
|
options?: { readonly viaRef?: boolean },
|
|
221
229
|
): CliStructuredError {
|
|
222
230
|
const viaRef = options?.viaRef !== false;
|
|
223
231
|
const fix = viaRef
|
|
224
|
-
? `
|
|
225
|
-
: `No contract source exists for hash "${identifier}" on an empty migration graph. Use --from with a ref name
|
|
232
|
+
? `Create the ref with "prisma-next ref set ${identifier} <hash>" (or advance it via "prisma-next db update --advance-ref ${identifier}"), or pass a hash that is a node in the migration graph.`
|
|
233
|
+
: `No contract source exists for hash "${identifier}" on an empty migration graph. Use --from with a ref name (its contract resolves through the snapshot store), or run db update first.`;
|
|
226
234
|
return errorRuntime(
|
|
227
235
|
viaRef
|
|
228
|
-
? `Ref "${identifier}"
|
|
236
|
+
? `Ref "${identifier}" is not resolvable`
|
|
229
237
|
: `No contract source for from-hash "${identifier}"`,
|
|
230
238
|
{
|
|
231
239
|
why: viaRef
|
|
232
|
-
? `Ref "${identifier}"
|
|
233
|
-
: `Hash "${identifier}" is not a graph
|
|
240
|
+
? `Ref "${identifier}" has no pointer file, and the hash being resolved is not a node in the migration graph either.`
|
|
241
|
+
: `Hash "${identifier}" is not a node in the migration graph (the graph is empty), and it does not name a ref either.`,
|
|
234
242
|
fix,
|
|
235
243
|
meta: {
|
|
236
244
|
code: 'MIGRATION.SNAPSHOT_MISSING',
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
2
2
|
import { notOk, type Result } from '@prisma-next/utils/result';
|
|
3
|
-
import { join } from 'pathe';
|
|
4
3
|
import {
|
|
5
4
|
CliStructuredError,
|
|
6
5
|
errorContractValidationFailed,
|
|
@@ -16,7 +15,7 @@ export function mapContractAtError(
|
|
|
16
15
|
): Result<never, CliStructuredError> {
|
|
17
16
|
if (MigrationToolsError.is(error)) {
|
|
18
17
|
switch (error.code) {
|
|
19
|
-
case 'MIGRATION.
|
|
18
|
+
case 'MIGRATION.REF_NOT_RESOLVABLE': {
|
|
20
19
|
const refName =
|
|
21
20
|
typeof error.details?.['refName'] === 'string'
|
|
22
21
|
? error.details['refName']
|
|
@@ -27,18 +26,13 @@ export function mapContractAtError(
|
|
|
27
26
|
}
|
|
28
27
|
case 'MIGRATION.CONTRACT_DESERIALIZATION_FAILED': {
|
|
29
28
|
const filePath =
|
|
30
|
-
typeof error.details?.['filePath'] === 'string'
|
|
31
|
-
? error.details['filePath']
|
|
32
|
-
: 'ref-snapshot';
|
|
29
|
+
typeof error.details?.['filePath'] === 'string' ? error.details['filePath'] : 'unknown';
|
|
33
30
|
const message =
|
|
34
31
|
typeof error.details?.['message'] === 'string' ? error.details['message'] : error.message;
|
|
35
|
-
const isRefSnapshot = filePath.endsWith('.contract.json');
|
|
36
32
|
return notOk(
|
|
37
33
|
errorContractValidationFailed(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
: `Predecessor contract at ${filePath} failed to deserialize: ${message}`,
|
|
41
|
-
{ where: { path: isRefSnapshot ? 'ref-snapshot' : filePath } },
|
|
34
|
+
`Predecessor contract at ${filePath} failed to deserialize: ${message}`,
|
|
35
|
+
{ where: { path: filePath } },
|
|
42
36
|
),
|
|
43
37
|
);
|
|
44
38
|
}
|
|
@@ -66,22 +60,19 @@ export function mapContractAtError(
|
|
|
66
60
|
fix: error.fix,
|
|
67
61
|
}),
|
|
68
62
|
);
|
|
69
|
-
case 'MIGRATION.
|
|
70
|
-
const
|
|
71
|
-
typeof error.details?.['
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
case 'MIGRATION.CONTRACT_SNAPSHOT_MISSING': {
|
|
64
|
+
const expectedPath =
|
|
65
|
+
typeof error.details?.['expectedPath'] === 'string'
|
|
66
|
+
? error.details['expectedPath']
|
|
67
|
+
: 'migrations/snapshots/';
|
|
74
68
|
const role = options?.artifactRole ?? 'from';
|
|
75
69
|
return notOk(
|
|
76
|
-
errorFileNotFound(
|
|
70
|
+
errorFileNotFound(expectedPath, {
|
|
77
71
|
why:
|
|
78
72
|
role === 'to'
|
|
79
|
-
? `Target migration is missing its
|
|
80
|
-
: `Predecessor migration is missing its
|
|
81
|
-
fix:
|
|
82
|
-
role === 'to'
|
|
83
|
-
? 'Re-emit the target migration so its sibling `end-contract.json` / `end-contract.d.ts` are restored, then re-run this command.'
|
|
84
|
-
: 'Re-emit the predecessor migration (`prisma-next migration plan` from its source) so its sibling `end-contract.json` is restored, then re-run this command.',
|
|
73
|
+
? `Target migration is missing its contract snapshot at ${expectedPath}`
|
|
74
|
+
: `Predecessor migration is missing its contract snapshot at ${expectedPath}`,
|
|
75
|
+
fix: 'Restore migrations/snapshots/ from version control, or re-run the command that produced this migration to regenerate its snapshot.',
|
|
85
76
|
}),
|
|
86
77
|
);
|
|
87
78
|
}
|
|
@@ -114,8 +114,8 @@ export function mapIntegrityViolations(
|
|
|
114
114
|
? 'Contract-space layout violation detected'
|
|
115
115
|
: `Contract-space layout violations detected (${layout.length})`;
|
|
116
116
|
return new CliStructuredError('MIGRATION.CONTRACT_SPACE_LAYOUT_VIOLATION', summary, {
|
|
117
|
-
why: `The on-disk \`migrations/\` directory and your \`
|
|
118
|
-
fix: 'Declare the extension in `
|
|
117
|
+
why: `The on-disk \`migrations/\` directory and your \`extensions\` declaration are not in agreement.\n${lines.join('\n')}`,
|
|
118
|
+
fix: 'Declare the extension in `extensions` and re-emit its contract-space artefacts, or remove the orphan `migrations/<space>` directory.',
|
|
119
119
|
docsUrl: CONTRACT_SPACES_DOCS_URL,
|
|
120
120
|
meta: { violations: layout },
|
|
121
121
|
});
|
|
@@ -177,14 +177,14 @@ export interface BuildAggregateInputs<TFamilyId extends string, TTargetId extend
|
|
|
177
177
|
readonly targetId: TTargetId;
|
|
178
178
|
readonly migrationsDir: string;
|
|
179
179
|
readonly appContract: Contract;
|
|
180
|
-
readonly
|
|
180
|
+
readonly extensions: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
|
|
181
181
|
readonly deserializeContract: (contractJson: unknown) => Contract;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
function declaredExtensionsFromInputs(
|
|
185
|
-
|
|
185
|
+
extensions: BuildAggregateInputs<string, string>['extensions'],
|
|
186
186
|
): readonly DeclaredExtensionEntry[] {
|
|
187
|
-
return toDeclaredExtensionsFromRaw(
|
|
187
|
+
return toDeclaredExtensionsFromRaw(extensions as ReadonlyArray<unknown>);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
/**
|
|
@@ -195,7 +195,7 @@ export function refuseDeclaredExtensionTargetMismatch<
|
|
|
195
195
|
TFamilyId extends string,
|
|
196
196
|
TTargetId extends string,
|
|
197
197
|
>(inputs: BuildAggregateInputs<TFamilyId, TTargetId>): CliStructuredError | null {
|
|
198
|
-
for (const declared of declaredExtensionsFromInputs(inputs.
|
|
198
|
+
for (const declared of declaredExtensionsFromInputs(inputs.extensions)) {
|
|
199
199
|
if (declared.targetId !== inputs.targetId) {
|
|
200
200
|
return targetMismatchError(declared.id, inputs.targetId, declared.targetId);
|
|
201
201
|
}
|
|
@@ -271,7 +271,7 @@ export async function buildContractSpaceAggregate<
|
|
|
271
271
|
>(
|
|
272
272
|
inputs: BuildAggregateInputs<TFamilyId, TTargetId>,
|
|
273
273
|
): Promise<Result<ContractSpaceAggregate, CliStructuredError>> {
|
|
274
|
-
const declaredExtensions = declaredExtensionsFromInputs(inputs.
|
|
274
|
+
const declaredExtensions = declaredExtensionsFromInputs(inputs.extensions);
|
|
275
275
|
const loaded = await loadContractSpaceAggregateForCli(inputs);
|
|
276
276
|
if (!loaded.ok) {
|
|
277
277
|
return loaded;
|
|
@@ -375,7 +375,7 @@ export async function buildReadAggregate(
|
|
|
375
375
|
targetId: config.target.id,
|
|
376
376
|
migrationsDir: options.migrationsDir,
|
|
377
377
|
appContract: appContractForLoad,
|
|
378
|
-
|
|
378
|
+
extensions: config.extensions ?? [],
|
|
379
379
|
deserializeContract,
|
|
380
380
|
});
|
|
381
381
|
if (!loaded.ok) {
|