@prisma-next/cli 0.10.0 → 0.11.0-dev.10
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 +1 -1
- package/dist/cli-errors-Bw2GlweY.mjs +175 -0
- package/dist/cli-errors-Bw2GlweY.mjs.map +1 -0
- package/dist/cli.mjs +400 -13
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-Brv4qlfB.mjs → client-UnIveZxZ.mjs} +6 -5
- package/dist/client-UnIveZxZ.mjs.map +1 -0
- package/dist/{command-helpers-D3vL5yi8.mjs → command-helpers-CRfjbZRz.mjs} +109 -12
- package/dist/command-helpers-CRfjbZRz.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts.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 +47 -21
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +6 -10
- package/dist/commands/db-schema.mjs.map +1 -1
- package/dist/commands/db-sign.mjs +8 -12
- 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 +47 -19
- 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 +47 -15
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.mjs +5 -8
- package/dist/commands/migration-check.mjs.map +1 -1
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.mjs +6 -10
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.mjs +5 -9
- package/dist/commands/migration-list.mjs.map +1 -1
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +7 -10
- package/dist/commands/migration-log.mjs.map +1 -1
- package/dist/commands/migration-new.mjs +6 -10
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +2 -1
- 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 +9 -13
- 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 +37 -15
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +41 -25
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/{contract-emit-iynA3BCA.mjs → contract-emit-C6rlsljO.mjs} +7 -6
- package/dist/contract-emit-C6rlsljO.mjs.map +1 -0
- package/dist/{contract-emit-C3STUIBg.mjs → contract-emit-mqXmapxB.mjs} +22 -20
- package/dist/contract-emit-mqXmapxB.mjs.map +1 -0
- package/dist/{contract-infer-Cnj8G1E2.mjs → contract-infer-C4jxc1aZ.mjs} +9 -14
- package/dist/contract-infer-C4jxc1aZ.mjs.map +1 -0
- package/dist/{contract-space-aggregate-loader-pAc8CDfY.mjs → contract-space-aggregate-loader-CGakRlKM.mjs} +2 -2
- package/dist/{contract-space-aggregate-loader-pAc8CDfY.mjs.map → contract-space-aggregate-loader-CGakRlKM.mjs.map} +1 -1
- package/dist/{db-verify-D7cyH_zz.mjs → db-verify-1d8tDoFN.mjs} +9 -13
- package/dist/db-verify-1d8tDoFN.mjs.map +1 -0
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.mjs +2 -2
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{framework-components-xFLFpZUO.mjs → framework-components-Bexd0f4E.mjs} +2 -2
- package/dist/{framework-components-xFLFpZUO.mjs.map → framework-components-Bexd0f4E.mjs.map} +1 -1
- package/dist/{global-flags-DGmw6Kqg.d.mts → global-flags-CdE7M0d9.d.mts} +4 -1
- package/dist/global-flags-CdE7M0d9.d.mts.map +1 -0
- package/dist/{graph-render-eJDcLWny.mjs → graph-render-BE8vmJ_7.mjs} +1 -1
- package/dist/{graph-render-eJDcLWny.mjs.map → graph-render-BE8vmJ_7.mjs.map} +1 -1
- package/dist/{init-eh2z5Tl6.mjs → init-ByoeQphC.mjs} +528 -627
- package/dist/init-ByoeQphC.mjs.map +1 -0
- package/dist/{inspect-live-schema-CWLK_lgs.mjs → inspect-live-schema-B1Q49RF0.mjs} +4 -4
- package/dist/{inspect-live-schema-CWLK_lgs.mjs.map → inspect-live-schema-B1Q49RF0.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-CmXXC1UZ.mjs → migration-command-scaffold-oY4P1Qto.mjs} +4 -4
- package/dist/{migration-command-scaffold-CmXXC1UZ.mjs.map → migration-command-scaffold-oY4P1Qto.mjs.map} +1 -1
- package/dist/{migration-plan-CHyUlBV0.mjs → migration-plan-jdAHg_gK.mjs} +349 -94
- package/dist/migration-plan-jdAHg_gK.mjs.map +1 -0
- package/dist/{migration-types-D2FW63pr.d.mts → migration-types-BXWvz12q.d.mts} +1 -1
- package/dist/{migration-types-D2FW63pr.d.mts.map → migration-types-BXWvz12q.d.mts.map} +1 -1
- package/dist/{migrations-DyUf5lTt.mjs → migrations-B7n518mT.mjs} +11 -2
- package/dist/migrations-B7n518mT.mjs.map +1 -0
- package/dist/{output-B60Gw5fu.mjs → output-CUIdfYo5.mjs} +1 -1
- package/dist/{output-B60Gw5fu.mjs.map → output-CUIdfYo5.mjs.map} +1 -1
- package/dist/quick-reference-mongo.md +1 -1
- package/dist/quick-reference-postgres.md +1 -1
- package/dist/readme-mongo.md +35 -0
- package/dist/readme-postgres.md +34 -0
- package/dist/ref-advancement-DRh5Nquq.mjs +50 -0
- package/dist/ref-advancement-DRh5Nquq.mjs.map +1 -0
- package/dist/{terminal-ui-XtOQsqe9.mjs → terminal-ui-BiB_8KNo.mjs} +131 -24
- package/dist/terminal-ui-BiB_8KNo.mjs.map +1 -0
- package/dist/{types-0aS865QN.d.mts → types-UWB2-rrw.d.mts} +12 -4
- package/dist/types-UWB2-rrw.d.mts.map +1 -0
- package/dist/{verify-D7ypCCe6.mjs → verify-C5UvbrF1.mjs} +2 -2
- package/dist/{verify-D7ypCCe6.mjs.map → verify-C5UvbrF1.mjs.map} +1 -1
- package/package.json +20 -18
- package/src/cli.ts +42 -0
- package/src/commands/contract-emit.ts +23 -11
- package/src/commands/contract-infer.ts +7 -7
- package/src/commands/db-init.ts +61 -7
- package/src/commands/db-schema.ts +4 -4
- package/src/commands/db-sign.ts +4 -4
- package/src/commands/db-update.ts +58 -5
- package/src/commands/db-verify.ts +5 -5
- package/src/commands/init/detect-package-manager.ts +15 -0
- package/src/commands/init/errors.ts +33 -2
- package/src/commands/init/hygiene-gitattributes.ts +2 -2
- package/src/commands/init/index.ts +15 -6
- package/src/commands/init/init.ts +61 -32
- package/src/commands/init/inputs.ts +82 -5
- package/src/commands/init/output.ts +1 -1
- package/src/commands/init/{agent-skill-install.ts → skill-install.ts} +42 -31
- package/src/commands/init/templates/code-templates.ts +26 -24
- package/src/commands/init/templates/env.ts +8 -1
- package/src/commands/init/templates/quick-reference-mongo.md +1 -1
- package/src/commands/init/templates/quick-reference-postgres.md +1 -1
- package/src/commands/init/templates/readme-mongo.md +35 -0
- package/src/commands/init/templates/readme-postgres.md +34 -0
- package/src/commands/init/templates/readme.ts +62 -0
- package/src/commands/migrate.ts +77 -10
- package/src/commands/migration-check.ts +4 -4
- package/src/commands/migration-graph.ts +4 -4
- package/src/commands/migration-list.ts +4 -4
- package/src/commands/migration-log.ts +6 -5
- package/src/commands/migration-new.ts +4 -4
- package/src/commands/migration-plan.ts +369 -132
- package/src/commands/migration-show.ts +4 -4
- package/src/commands/migration-status.ts +49 -6
- package/src/commands/ref.ts +54 -14
- package/src/control-api/operations/apply-aggregate.ts +1 -0
- package/src/control-api/operations/contract-emit.ts +7 -4
- package/src/control-api/types.ts +7 -0
- package/src/utils/cli-errors.ts +177 -0
- package/src/utils/command-helpers.ts +14 -6
- package/src/utils/formatters/migrations.ts +25 -0
- package/src/utils/global-flags.ts +105 -16
- package/src/utils/is-ci.ts +18 -0
- package/src/utils/plan-resolution.ts +257 -0
- package/src/utils/ref-advancement.ts +68 -0
- package/src/utils/telemetry.ts +141 -0
- package/src/utils/terminal-ui.ts +44 -23
- package/dist/cli-errors-CF60g2cG.mjs +0 -71
- package/dist/cli-errors-CF60g2cG.mjs.map +0 -1
- package/dist/cli-errors-DdcjVLJV.d.mts +0 -3
- package/dist/client-Brv4qlfB.mjs.map +0 -1
- package/dist/command-helpers-D3vL5yi8.mjs.map +0 -1
- package/dist/contract-emit-C3STUIBg.mjs.map +0 -1
- package/dist/contract-emit-iynA3BCA.mjs.map +0 -1
- package/dist/contract-infer-Cnj8G1E2.mjs.map +0 -1
- package/dist/db-verify-D7cyH_zz.mjs.map +0 -1
- package/dist/errors-Cw6kyTyV.mjs +0 -56
- package/dist/errors-Cw6kyTyV.mjs.map +0 -1
- package/dist/global-flags-DGmw6Kqg.d.mts.map +0 -1
- package/dist/helpers-eqdN8tH6.mjs +0 -25
- package/dist/helpers-eqdN8tH6.mjs.map +0 -1
- package/dist/init-eh2z5Tl6.mjs.map +0 -1
- package/dist/migration-plan-CHyUlBV0.mjs.map +0 -1
- package/dist/migrations-DyUf5lTt.mjs.map +0 -1
- package/dist/result-handler-Bm_6dDYg.mjs +0 -25
- package/dist/result-handler-Bm_6dDYg.mjs.map +0 -1
- package/dist/terminal-ui-XtOQsqe9.mjs.map +0 -1
- package/dist/types-0aS865QN.d.mts.map +0 -1
|
@@ -40,7 +40,14 @@ function envPlaceholderBody(target: TargetId): string {
|
|
|
40
40
|
if (target === 'postgres') {
|
|
41
41
|
lines.push('DATABASE_URL="postgresql://user:password@localhost:5432/mydb"');
|
|
42
42
|
} else {
|
|
43
|
-
lines.push(
|
|
43
|
+
lines.push(
|
|
44
|
+
'# Standalone local mongod / `docker run mongo:7` — no replica set required for first-run queries.',
|
|
45
|
+
);
|
|
46
|
+
lines.push(
|
|
47
|
+
'# Transactions and change streams need a replica set; add ?replicaSet=... only after initiating one.',
|
|
48
|
+
);
|
|
49
|
+
lines.push('');
|
|
50
|
+
lines.push('DATABASE_URL="mongodb://user:password@localhost:27017/mydb"');
|
|
44
51
|
}
|
|
45
52
|
lines.push('');
|
|
46
53
|
return lines.join('\n');
|
|
@@ -22,7 +22,7 @@ const user = await db.orm.users
|
|
|
22
22
|
.first();
|
|
23
23
|
|
|
24
24
|
// Your editor will show the type of user as
|
|
25
|
-
// { _id: ObjectId; email: string; name: string | null; posts: Post[] } | null
|
|
25
|
+
// { _id: ObjectId; email: string; username: string | null; name: string | null; posts: Post[] } | null
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
`db` connects to MongoDB lazily on the first query, so there is no manual `connect(...)` step in your application code. Call `await db.close()` if you need to release the underlying connection (typically only in tests or short-lived scripts). After `close()` the client is single-shot — any further query, `connect()`, or `runtime()` call rejects with `"Mongo client is closed"`. Construct a new `mongo({...})` if you need to use it again.
|
|
@@ -22,7 +22,7 @@ const user = await db.orm.User
|
|
|
22
22
|
.first();
|
|
23
23
|
|
|
24
24
|
// Your editor will show the type of user as
|
|
25
|
-
// { id: number; email: string;
|
|
25
|
+
// { id: number; email: string; username: string | null; name: string | null; createdAt: Date; posts: Post[] } | null
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Your contract has two companion files in the same directory:
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
Generated by `prisma-next init` with the Minimal template.
|
|
4
|
+
|
|
5
|
+
## First run
|
|
6
|
+
|
|
7
|
+
1. `{{runDbUp}}` — start the local MongoDB replica set with `mongodb-memory-server`. Data persists in `.mongo-data/` across restarts.
|
|
8
|
+
2. `{{runDev}}` — runs `src/index.ts`, which writes one row and reads it back.
|
|
9
|
+
|
|
10
|
+
## Available scripts
|
|
11
|
+
|
|
12
|
+
- `{{runDev}}` — run the Prisma Next sample script
|
|
13
|
+
|
|
14
|
+
### Database and migrations
|
|
15
|
+
|
|
16
|
+
- `{{runContractEmit}}` — emit contract artifacts after contract changes
|
|
17
|
+
- `{{runDbUp}}` — start the local MongoDB replica set with `mongodb-memory-server`. Data persists in `.mongo-data/` across restarts.
|
|
18
|
+
- `{{runDbDown}}` — stop the local MongoDB process (data preserved)
|
|
19
|
+
- `{{runDbReset}}` — stop and wipe `.mongo-data/` for a clean slate
|
|
20
|
+
- `{{runMigrationPlan}}` — create a MongoDB migration plan
|
|
21
|
+
- `{{runMigrate}}` — apply the planned MongoDB migration
|
|
22
|
+
- `{{runDbSeed}}` — insert sample users manually
|
|
23
|
+
|
|
24
|
+
## Prisma Next
|
|
25
|
+
|
|
26
|
+
Prisma Next setup is scaffolded in:
|
|
27
|
+
|
|
28
|
+
- `{{contractPath}}`
|
|
29
|
+
- `prisma-next.config.ts`
|
|
30
|
+
- `prisma/db.ts`
|
|
31
|
+
- `src/lib/prisma.ts`
|
|
32
|
+
|
|
33
|
+
For provider-specific Prisma Next reference docs, see `prisma-next.md`. Prisma Next skills live in the upstream `skills/` directory: https://github.com/prisma/prisma-next/tree/main/skills.
|
|
34
|
+
|
|
35
|
+
Node-based Prisma Next projects expect Node.js 24 LTS or newer.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
Generated by `prisma-next init` with the Minimal template.
|
|
4
|
+
|
|
5
|
+
## First run
|
|
6
|
+
|
|
7
|
+
1. `{{runDbInit}}` — applies your contract to the database (creates tables, signs the marker).
|
|
8
|
+
2. `{{runDev}}` — runs `src/index.ts`, which writes one row and reads it back.
|
|
9
|
+
|
|
10
|
+
## Available scripts
|
|
11
|
+
|
|
12
|
+
- `{{runDev}}` — run the Prisma Next sample script
|
|
13
|
+
|
|
14
|
+
### Database and migrations
|
|
15
|
+
|
|
16
|
+
- `{{runContractEmit}}` — emit contract artifacts after contract changes
|
|
17
|
+
- `{{runDbInit}}` — initialize database state manually
|
|
18
|
+
- `{{runDbUpdate}}` — update database state manually
|
|
19
|
+
- `{{runMigrationPlan}}` — create a migration plan
|
|
20
|
+
- `{{runMigrate}}` — apply a planned migration
|
|
21
|
+
- `{{runDbSeed}}` — insert sample users manually (run after `db:init`)
|
|
22
|
+
|
|
23
|
+
## Prisma Next
|
|
24
|
+
|
|
25
|
+
Prisma Next setup is scaffolded in:
|
|
26
|
+
|
|
27
|
+
- `{{contractPath}}`
|
|
28
|
+
- `prisma-next.config.ts`
|
|
29
|
+
- `prisma/db.ts`
|
|
30
|
+
- `src/lib/prisma.ts`
|
|
31
|
+
|
|
32
|
+
For provider-specific Prisma Next reference docs, see `prisma-next.md`. Prisma Next skills live in the upstream `skills/` directory: https://github.com/prisma/prisma-next/tree/main/skills.
|
|
33
|
+
|
|
34
|
+
Node-based Prisma Next projects expect Node.js 24 LTS or newer.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { formatRunScriptCommand, type PackageManager } from '../detect-package-manager';
|
|
2
|
+
import type { TargetId } from './code-templates';
|
|
3
|
+
import { renderTemplate } from './render';
|
|
4
|
+
|
|
5
|
+
const sharedVariables = ['projectName', 'contractPath', 'runDev', 'runContractEmit'] as const;
|
|
6
|
+
|
|
7
|
+
export const postgresVariables = [
|
|
8
|
+
...sharedVariables,
|
|
9
|
+
'runDbInit',
|
|
10
|
+
'runDbUpdate',
|
|
11
|
+
'runMigrationPlan',
|
|
12
|
+
'runMigrate',
|
|
13
|
+
'runDbSeed',
|
|
14
|
+
] as const;
|
|
15
|
+
|
|
16
|
+
export const mongoVariables = [
|
|
17
|
+
...sharedVariables,
|
|
18
|
+
'runDbUp',
|
|
19
|
+
'runDbDown',
|
|
20
|
+
'runDbReset',
|
|
21
|
+
'runMigrationPlan',
|
|
22
|
+
'runMigrate',
|
|
23
|
+
'runDbSeed',
|
|
24
|
+
] as const;
|
|
25
|
+
|
|
26
|
+
type PostgresVars = Record<(typeof postgresVariables)[number], string>;
|
|
27
|
+
type MongoVars = Record<(typeof mongoVariables)[number], string>;
|
|
28
|
+
|
|
29
|
+
export function minimalProjectReadmeMd(
|
|
30
|
+
target: TargetId,
|
|
31
|
+
schemaPath: string,
|
|
32
|
+
projectName: string,
|
|
33
|
+
pm: PackageManager,
|
|
34
|
+
): string {
|
|
35
|
+
const run = (script: string): string => formatRunScriptCommand(pm, script);
|
|
36
|
+
const shared = {
|
|
37
|
+
projectName,
|
|
38
|
+
contractPath: schemaPath,
|
|
39
|
+
runDev: run('dev'),
|
|
40
|
+
runContractEmit: run('contract:emit'),
|
|
41
|
+
runMigrationPlan: run('migration:plan'),
|
|
42
|
+
runMigrate: run('migrate'),
|
|
43
|
+
runDbSeed: run('db:seed'),
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
if (target === 'mongo') {
|
|
47
|
+
const vars: MongoVars = {
|
|
48
|
+
...shared,
|
|
49
|
+
runDbUp: run('db:up'),
|
|
50
|
+
runDbDown: run('db:down'),
|
|
51
|
+
runDbReset: run('db:reset'),
|
|
52
|
+
};
|
|
53
|
+
return renderTemplate('readme-mongo.md', mongoVariables, vars);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const vars: PostgresVars = {
|
|
57
|
+
...shared,
|
|
58
|
+
runDbInit: run('db:init'),
|
|
59
|
+
runDbUpdate: run('db:update'),
|
|
60
|
+
};
|
|
61
|
+
return renderTemplate('readme-postgres.md', postgresVariables, vars);
|
|
62
|
+
}
|
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,
|
|
@@ -43,14 +46,16 @@ import {
|
|
|
43
46
|
import { formatMigrationApplyCommandOutput } from '../utils/formatters/migrations';
|
|
44
47
|
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
45
48
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
46
|
-
import { type GlobalFlags,
|
|
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
|
-
import { TerminalUI } from '../utils/terminal-ui';
|
|
52
|
+
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
49
53
|
|
|
50
54
|
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,14 +387,12 @@ 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
|
-
const flags =
|
|
392
|
+
const flags = parseGlobalFlagsOrExit(options);
|
|
323
393
|
const startTime = Date.now();
|
|
324
394
|
|
|
325
|
-
const ui =
|
|
326
|
-
color: flags.color,
|
|
327
|
-
interactive: flags.interactive,
|
|
328
|
-
});
|
|
395
|
+
const ui = createTerminalUI(flags);
|
|
329
396
|
|
|
330
397
|
const result = await executeMigrateCommand(options, flags, ui, startTime);
|
|
331
398
|
|
|
@@ -17,8 +17,8 @@ import {
|
|
|
17
17
|
} from '../utils/command-helpers';
|
|
18
18
|
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
19
19
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
20
|
-
import { type GlobalFlags,
|
|
21
|
-
import { TerminalUI } from '../utils/terminal-ui';
|
|
20
|
+
import { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
21
|
+
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
22
22
|
import { INTEGRITY_FAILED, OK, PRECONDITION } from './migration-check/exit-codes';
|
|
23
23
|
|
|
24
24
|
interface MigrationCheckOptions extends CommonCommandOptions {
|
|
@@ -335,8 +335,8 @@ export function createMigrationCheckCommand(): Command {
|
|
|
335
335
|
.argument('[migration]', 'Migration reference (directory name or hash) to check')
|
|
336
336
|
.option('--config <path>', 'Path to prisma-next.config.ts')
|
|
337
337
|
.action(async (target: string | undefined, options: MigrationCheckOptions) => {
|
|
338
|
-
const flags =
|
|
339
|
-
const ui =
|
|
338
|
+
const flags = parseGlobalFlagsOrExit(options);
|
|
339
|
+
const ui = createTerminalUI(flags);
|
|
340
340
|
|
|
341
341
|
let result: MigrationCheckResult;
|
|
342
342
|
let exitCode: number;
|
|
@@ -23,10 +23,10 @@ import { migrationGraphToRenderInput } from '../utils/formatters/graph-migration
|
|
|
23
23
|
import { graphRenderer } from '../utils/formatters/graph-render';
|
|
24
24
|
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
25
25
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
26
|
-
import { type GlobalFlags,
|
|
26
|
+
import { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
27
27
|
import type { StatusRef } from '../utils/migration-types';
|
|
28
28
|
import { handleResult } from '../utils/result-handler';
|
|
29
|
-
import { TerminalUI } from '../utils/terminal-ui';
|
|
29
|
+
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
30
30
|
|
|
31
31
|
interface MigrationGraphOptions extends CommonCommandOptions {
|
|
32
32
|
readonly config?: string;
|
|
@@ -130,8 +130,8 @@ export function createMigrationGraphCommand(): Command {
|
|
|
130
130
|
.option('--config <path>', 'Path to prisma-next.config.ts')
|
|
131
131
|
.option('--dot', 'Output in Graphviz DOT format')
|
|
132
132
|
.action(async (options: MigrationGraphOptions) => {
|
|
133
|
-
const flags =
|
|
134
|
-
const ui =
|
|
133
|
+
const flags = parseGlobalFlagsOrExit(options);
|
|
134
|
+
const ui = createTerminalUI(flags);
|
|
135
135
|
const result = await executeMigrationGraphCommand(options, flags, ui);
|
|
136
136
|
const exitCode = handleResult(result, flags, ui, (graphResult) => {
|
|
137
137
|
// Explicit format flags win over the auto-JSON default. `flags.json`
|
|
@@ -20,9 +20,9 @@ import {
|
|
|
20
20
|
} from '../utils/command-helpers';
|
|
21
21
|
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
22
22
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
23
|
-
import { type GlobalFlags,
|
|
23
|
+
import { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
24
24
|
import { handleResult } from '../utils/result-handler';
|
|
25
|
-
import { TerminalUI } from '../utils/terminal-ui';
|
|
25
|
+
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
26
26
|
|
|
27
27
|
interface MigrationListOptions extends CommonCommandOptions {
|
|
28
28
|
readonly config?: string;
|
|
@@ -130,8 +130,8 @@ export function createMigrationListCommand(): Command {
|
|
|
130
130
|
addGlobalOptions(command)
|
|
131
131
|
.option('--config <path>', 'Path to prisma-next.config.ts')
|
|
132
132
|
.action(async (options: MigrationListOptions) => {
|
|
133
|
-
const flags =
|
|
134
|
-
const ui =
|
|
133
|
+
const flags = parseGlobalFlagsOrExit(options);
|
|
134
|
+
const ui = createTerminalUI(flags);
|
|
135
135
|
const result = await executeMigrationListCommand(options, flags, ui);
|
|
136
136
|
const exitCode = handleResult(result, flags, ui, (listResult) => {
|
|
137
137
|
if (flags.json) {
|
|
@@ -8,7 +8,7 @@ import { Command } from 'commander';
|
|
|
8
8
|
import { loadConfig } from '../config-loader';
|
|
9
9
|
import { createControlClient } from '../control-api/client';
|
|
10
10
|
import {
|
|
11
|
-
|
|
11
|
+
CliStructuredError,
|
|
12
12
|
errorDatabaseConnectionRequired,
|
|
13
13
|
errorDriverRequired,
|
|
14
14
|
errorUnexpected,
|
|
@@ -26,9 +26,9 @@ import {
|
|
|
26
26
|
} from '../utils/command-helpers';
|
|
27
27
|
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
28
28
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
29
|
-
import { type GlobalFlags,
|
|
29
|
+
import { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
30
30
|
import { handleResult } from '../utils/result-handler';
|
|
31
|
-
import { TerminalUI } from '../utils/terminal-ui';
|
|
31
|
+
import { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';
|
|
32
32
|
|
|
33
33
|
interface MigrationLogOptions extends CommonCommandOptions {
|
|
34
34
|
readonly db?: string;
|
|
@@ -159,6 +159,7 @@ async function executeMigrationLogCommand(
|
|
|
159
159
|
summary: `${entries.length} migration(s) applied`,
|
|
160
160
|
});
|
|
161
161
|
} catch (error) {
|
|
162
|
+
if (CliStructuredError.is(error)) return notOk(error);
|
|
162
163
|
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
163
164
|
return notOk(
|
|
164
165
|
errorUnexpected(error instanceof Error ? error.message : String(error), {
|
|
@@ -192,8 +193,8 @@ export function createMigrationLogCommand(): Command {
|
|
|
192
193
|
.option('--db <url>', 'Database connection string')
|
|
193
194
|
.option('--config <path>', 'Path to prisma-next.config.ts')
|
|
194
195
|
.action(async (options: MigrationLogOptions) => {
|
|
195
|
-
const flags =
|
|
196
|
-
const ui =
|
|
196
|
+
const flags = parseGlobalFlagsOrExit(options);
|
|
197
|
+
const ui = createTerminalUI(flags);
|
|
197
198
|
const result = await executeMigrationLogCommand(options, flags, ui);
|
|
198
199
|
const exitCode = handleResult(result, flags, ui, (logResult) => {
|
|
199
200
|
if (flags.json) {
|
|
@@ -49,9 +49,9 @@ import {
|
|
|
49
49
|
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
50
50
|
import { assertFrameworkComponentsCompatible } from '../utils/framework-components';
|
|
51
51
|
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
52
|
-
import {
|
|
52
|
+
import { parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
53
53
|
import { handleResult } from '../utils/result-handler';
|
|
54
|
-
import {
|
|
54
|
+
import { createTerminalUI } from '../utils/terminal-ui';
|
|
55
55
|
|
|
56
56
|
interface MigrationNewOptions extends CommonCommandOptions {
|
|
57
57
|
readonly name?: string;
|
|
@@ -287,8 +287,8 @@ export function createMigrationNewCommand(): Command {
|
|
|
287
287
|
.option('--from <hash>', 'Starting contract hash (default: latest migration target)')
|
|
288
288
|
.option('--config <path>', 'Path to prisma-next.config.ts')
|
|
289
289
|
.action(async (options: MigrationNewOptions) => {
|
|
290
|
-
const flags =
|
|
291
|
-
const ui =
|
|
290
|
+
const flags = parseGlobalFlagsOrExit(options);
|
|
291
|
+
const ui = createTerminalUI(flags);
|
|
292
292
|
|
|
293
293
|
if (!flags.json && !flags.quiet) {
|
|
294
294
|
const header = formatStyledHeader({
|