@prisma-next/cli 0.3.0-pr.99.6 → 0.3.0
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/LICENSE +201 -0
- package/README.md +381 -128
- package/dist/agent-skill-mongo.md +106 -0
- package/dist/agent-skill-postgres.md +106 -0
- package/dist/cli-errors-BDCYR5ap.mjs +4 -0
- package/dist/cli-errors-DStABy9d.d.mts +3 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.js +1 -2910
- package/dist/cli.mjs +261 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client-DiUkJAeN.mjs +987 -0
- package/dist/client-DiUkJAeN.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts +7 -0
- package/dist/commands/contract-emit.d.mts.map +1 -0
- package/dist/commands/contract-emit.mjs +9 -0
- package/dist/commands/contract-infer.d.mts +7 -0
- package/dist/commands/contract-infer.d.mts.map +1 -0
- package/dist/commands/contract-infer.mjs +10 -0
- package/dist/commands/db-init.d.mts +7 -0
- package/dist/commands/db-init.d.mts.map +1 -0
- package/dist/commands/db-init.mjs +126 -0
- package/dist/commands/db-init.mjs.map +1 -0
- package/dist/commands/db-schema.d.mts +7 -0
- package/dist/commands/db-schema.d.mts.map +1 -0
- package/dist/commands/db-schema.mjs +56 -0
- package/dist/commands/db-schema.mjs.map +1 -0
- package/dist/commands/db-sign.d.mts +7 -0
- package/dist/commands/db-sign.d.mts.map +1 -0
- package/dist/commands/db-sign.mjs +137 -0
- package/dist/commands/db-sign.mjs.map +1 -0
- package/dist/commands/db-update.d.mts +7 -0
- package/dist/commands/db-update.d.mts.map +1 -0
- package/dist/commands/db-update.mjs +123 -0
- package/dist/commands/db-update.mjs.map +1 -0
- package/dist/commands/db-verify.d.mts +7 -0
- package/dist/commands/db-verify.d.mts.map +1 -0
- package/dist/commands/db-verify.mjs +323 -0
- package/dist/commands/db-verify.mjs.map +1 -0
- package/dist/commands/migration-apply.d.mts +36 -0
- package/dist/commands/migration-apply.d.mts.map +1 -0
- package/dist/commands/migration-apply.mjs +245 -0
- package/dist/commands/migration-apply.mjs.map +1 -0
- package/dist/commands/migration-new.d.mts +8 -0
- package/dist/commands/migration-new.d.mts.map +1 -0
- package/dist/commands/migration-new.mjs +152 -0
- package/dist/commands/migration-new.mjs.map +1 -0
- package/dist/commands/migration-plan.d.mts +47 -0
- package/dist/commands/migration-plan.d.mts.map +1 -0
- package/dist/commands/migration-plan.mjs +313 -0
- package/dist/commands/migration-plan.mjs.map +1 -0
- package/dist/commands/migration-ref.d.mts +43 -0
- package/dist/commands/migration-ref.d.mts.map +1 -0
- package/dist/commands/migration-ref.mjs +195 -0
- package/dist/commands/migration-ref.mjs.map +1 -0
- package/dist/commands/migration-show.d.mts +28 -0
- package/dist/commands/migration-show.d.mts.map +1 -0
- package/dist/commands/migration-show.mjs +140 -0
- package/dist/commands/migration-show.mjs.map +1 -0
- package/dist/commands/migration-status.d.mts +86 -0
- package/dist/commands/migration-status.d.mts.map +1 -0
- package/dist/commands/migration-status.mjs +9 -0
- package/dist/commands/migration-verify.d.mts +16 -0
- package/dist/commands/migration-verify.d.mts.map +1 -0
- package/dist/commands/migration-verify.mjs +110 -0
- package/dist/commands/migration-verify.mjs.map +1 -0
- package/dist/config-loader-C4VXKl8f.mjs +43 -0
- package/dist/config-loader-C4VXKl8f.mjs.map +1 -0
- package/dist/{config-loader.d.ts → config-loader.d.mts} +8 -3
- package/dist/config-loader.d.mts.map +1 -0
- package/dist/config-loader.mjs +3 -0
- package/dist/contract-emit-D2wDXfyo.mjs +191 -0
- package/dist/contract-emit-D2wDXfyo.mjs.map +1 -0
- package/dist/contract-emit-Zm_sd1wQ.mjs +112 -0
- package/dist/contract-emit-Zm_sd1wQ.mjs.map +1 -0
- package/dist/contract-emit-kN-IkKTE.mjs +6 -0
- package/dist/contract-enrichment-CGW6mm-E.mjs +79 -0
- package/dist/contract-enrichment-CGW6mm-E.mjs.map +1 -0
- package/dist/contract-infer-DozZT511.mjs +90 -0
- package/dist/contract-infer-DozZT511.mjs.map +1 -0
- package/dist/exports/config-types.d.mts +2 -0
- package/dist/exports/config-types.mjs +3 -0
- package/dist/exports/control-api.d.mts +624 -0
- package/dist/exports/control-api.d.mts.map +1 -0
- package/dist/exports/control-api.mjs +8 -0
- package/dist/{load-ts-contract.d.ts → exports/index.d.mts} +12 -7
- package/dist/exports/index.d.mts.map +1 -0
- package/dist/exports/index.mjs +142 -0
- package/dist/exports/index.mjs.map +1 -0
- package/dist/extract-operation-statements-DZUJNmL3.mjs +13 -0
- package/dist/extract-operation-statements-DZUJNmL3.mjs.map +1 -0
- package/dist/extract-sql-ddl-DDMX-9mz.mjs +26 -0
- package/dist/extract-sql-ddl-DDMX-9mz.mjs.map +1 -0
- package/dist/framework-components-BAsliT4V.mjs +59 -0
- package/dist/framework-components-BAsliT4V.mjs.map +1 -0
- package/dist/init-6Pvm_esG.mjs +430 -0
- package/dist/init-6Pvm_esG.mjs.map +1 -0
- package/dist/inspect-live-schema-BYnhztxZ.mjs +91 -0
- package/dist/inspect-live-schema-BYnhztxZ.mjs.map +1 -0
- package/dist/migration-command-scaffold-CntCcntR.mjs +105 -0
- package/dist/migration-command-scaffold-CntCcntR.mjs.map +1 -0
- package/dist/migration-status-CJANY4yr.mjs +1583 -0
- package/dist/migration-status-CJANY4yr.mjs.map +1 -0
- package/dist/migrations-DTZBYXm1.mjs +173 -0
- package/dist/migrations-DTZBYXm1.mjs.map +1 -0
- package/dist/progress-adapter-B-YvmcDu.mjs +43 -0
- package/dist/progress-adapter-B-YvmcDu.mjs.map +1 -0
- package/dist/quick-reference-mongo.md +93 -0
- package/dist/quick-reference-postgres.md +91 -0
- package/dist/result-handler-oK_vA-Fn.mjs +697 -0
- package/dist/result-handler-oK_vA-Fn.mjs.map +1 -0
- package/dist/terminal-ui-C5k88MmW.mjs +274 -0
- package/dist/terminal-ui-C5k88MmW.mjs.map +1 -0
- package/dist/validate-contract-deps-esa-VQ0h.mjs +37 -0
- package/dist/validate-contract-deps-esa-VQ0h.mjs.map +1 -0
- package/dist/verify-DlFQ2FOw.mjs +385 -0
- package/dist/verify-DlFQ2FOw.mjs.map +1 -0
- package/package.json +87 -40
- package/src/cli.ts +118 -58
- package/src/commands/contract-emit.ts +101 -78
- package/src/commands/contract-infer-paths.ts +32 -0
- package/src/commands/contract-infer.ts +143 -0
- package/src/commands/db-init.ts +97 -219
- package/src/commands/db-schema.ts +77 -0
- package/src/commands/db-sign.ts +46 -73
- package/src/commands/db-update.ts +236 -0
- package/src/commands/db-verify.ts +409 -119
- package/src/commands/init/detect-package-manager.ts +47 -0
- package/src/commands/init/index.ts +21 -0
- package/src/commands/init/init.ts +203 -0
- package/src/commands/init/templates/agent-skill-mongo.md +106 -0
- package/src/commands/init/templates/agent-skill-postgres.md +106 -0
- package/src/commands/init/templates/agent-skill.ts +19 -0
- package/src/commands/init/templates/code-templates.ts +168 -0
- package/src/commands/init/templates/quick-reference-mongo.md +93 -0
- package/src/commands/init/templates/quick-reference-postgres.md +91 -0
- package/src/commands/init/templates/quick-reference.ts +19 -0
- package/src/commands/init/templates/render.ts +20 -0
- package/src/commands/init/templates/tsconfig.ts +35 -0
- package/src/commands/inspect-live-schema.ts +170 -0
- package/src/commands/migration-apply.ts +427 -0
- package/src/commands/migration-new.ts +260 -0
- package/src/commands/migration-plan.ts +519 -0
- package/src/commands/migration-ref.ts +305 -0
- package/src/commands/migration-show.ts +246 -0
- package/src/commands/migration-status.ts +864 -0
- package/src/commands/migration-verify.ts +180 -0
- package/src/config-loader.ts +13 -3
- package/src/control-api/client.ts +205 -183
- package/src/control-api/contract-enrichment.ts +119 -0
- package/src/control-api/errors.ts +9 -0
- package/src/control-api/operations/contract-emit.ts +181 -0
- package/src/control-api/operations/db-init.ts +53 -49
- package/src/control-api/operations/db-update.ts +220 -0
- package/src/control-api/operations/extract-operation-statements.ts +14 -0
- package/src/control-api/operations/extract-sql-ddl.ts +47 -0
- package/src/control-api/operations/migration-apply.ts +191 -0
- package/src/control-api/operations/migration-helpers.ts +49 -0
- package/src/control-api/types.ts +274 -52
- package/src/exports/config-types.ts +4 -3
- package/src/exports/control-api.ts +15 -5
- package/src/load-ts-contract.ts +30 -19
- package/src/utils/cli-errors.ts +14 -8
- package/src/utils/command-helpers.ts +302 -3
- package/src/utils/formatters/emit.ts +67 -0
- package/src/utils/formatters/errors.ts +82 -0
- package/src/utils/formatters/graph-migration-mapper.ts +240 -0
- package/src/utils/formatters/graph-render.ts +1323 -0
- package/src/utils/formatters/graph-types.ts +120 -0
- package/src/utils/formatters/help.ts +380 -0
- package/src/utils/formatters/helpers.ts +28 -0
- package/src/utils/formatters/migrations.ts +346 -0
- package/src/utils/formatters/styled.ts +212 -0
- package/src/utils/formatters/verify.ts +621 -0
- package/src/utils/framework-components.ts +13 -10
- package/src/utils/global-flags.ts +41 -23
- package/src/utils/migration-command-scaffold.ts +184 -0
- package/src/utils/migration-types.ts +12 -0
- package/src/utils/progress-adapter.ts +18 -29
- package/src/utils/result-handler.ts +12 -13
- package/src/utils/shutdown.ts +92 -0
- package/src/utils/suggest-command.ts +31 -0
- package/src/utils/terminal-ui.ts +276 -0
- package/src/utils/validate-contract-deps.ts +49 -0
- package/dist/chunk-AGOTG4L3.js +0 -965
- package/dist/chunk-AGOTG4L3.js.map +0 -1
- package/dist/chunk-HLLI4YL7.js +0 -180
- package/dist/chunk-HLLI4YL7.js.map +0 -1
- package/dist/chunk-HWYQOCAJ.js +0 -47
- package/dist/chunk-HWYQOCAJ.js.map +0 -1
- package/dist/chunk-VG2R7DGF.js +0 -735
- package/dist/chunk-VG2R7DGF.js.map +0 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/contract-emit.d.ts +0 -3
- package/dist/commands/contract-emit.d.ts.map +0 -1
- package/dist/commands/contract-emit.js +0 -10
- package/dist/commands/contract-emit.js.map +0 -1
- package/dist/commands/db-init.d.ts +0 -3
- package/dist/commands/db-init.d.ts.map +0 -1
- package/dist/commands/db-init.js +0 -257
- package/dist/commands/db-init.js.map +0 -1
- package/dist/commands/db-introspect.d.ts +0 -3
- package/dist/commands/db-introspect.d.ts.map +0 -1
- package/dist/commands/db-introspect.js +0 -155
- package/dist/commands/db-introspect.js.map +0 -1
- package/dist/commands/db-schema-verify.d.ts +0 -3
- package/dist/commands/db-schema-verify.d.ts.map +0 -1
- package/dist/commands/db-schema-verify.js +0 -171
- package/dist/commands/db-schema-verify.js.map +0 -1
- package/dist/commands/db-sign.d.ts +0 -3
- package/dist/commands/db-sign.d.ts.map +0 -1
- package/dist/commands/db-sign.js +0 -195
- package/dist/commands/db-sign.js.map +0 -1
- package/dist/commands/db-verify.d.ts +0 -3
- package/dist/commands/db-verify.d.ts.map +0 -1
- package/dist/commands/db-verify.js +0 -193
- package/dist/commands/db-verify.js.map +0 -1
- package/dist/config-loader.d.ts.map +0 -1
- package/dist/config-loader.js +0 -7
- package/dist/config-loader.js.map +0 -1
- package/dist/control-api/client.d.ts +0 -13
- package/dist/control-api/client.d.ts.map +0 -1
- package/dist/control-api/operations/db-init.d.ts +0 -29
- package/dist/control-api/operations/db-init.d.ts.map +0 -1
- package/dist/control-api/types.d.ts +0 -387
- package/dist/control-api/types.d.ts.map +0 -1
- package/dist/exports/config-types.d.ts +0 -3
- package/dist/exports/config-types.d.ts.map +0 -1
- package/dist/exports/config-types.js +0 -6
- package/dist/exports/config-types.js.map +0 -1
- package/dist/exports/control-api.d.ts +0 -13
- package/dist/exports/control-api.d.ts.map +0 -1
- package/dist/exports/control-api.js +0 -7
- package/dist/exports/control-api.js.map +0 -1
- package/dist/exports/index.d.ts +0 -4
- package/dist/exports/index.d.ts.map +0 -1
- package/dist/exports/index.js +0 -176
- package/dist/exports/index.js.map +0 -1
- package/dist/load-ts-contract.d.ts.map +0 -1
- package/dist/utils/cli-errors.d.ts +0 -7
- package/dist/utils/cli-errors.d.ts.map +0 -1
- package/dist/utils/command-helpers.d.ts +0 -12
- package/dist/utils/command-helpers.d.ts.map +0 -1
- package/dist/utils/framework-components.d.ts +0 -70
- package/dist/utils/framework-components.d.ts.map +0 -1
- package/dist/utils/global-flags.d.ts +0 -25
- package/dist/utils/global-flags.d.ts.map +0 -1
- package/dist/utils/output.d.ts +0 -142
- package/dist/utils/output.d.ts.map +0 -1
- package/dist/utils/progress-adapter.d.ts +0 -26
- package/dist/utils/progress-adapter.d.ts.map +0 -1
- package/dist/utils/result-handler.d.ts +0 -15
- package/dist/utils/result-handler.d.ts.map +0 -1
- package/src/commands/db-introspect.ts +0 -227
- package/src/commands/db-schema-verify.ts +0 -238
- package/src/utils/output.ts +0 -1471
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ Provide a command-line interface that:
|
|
|
22
22
|
- **Extension Pack Descriptor Assembly**: Collect adapter and extension descriptors for emission
|
|
23
23
|
- **Help Output Formatting**: Custom styled help output with command trees and formatted descriptions
|
|
24
24
|
- **Config Management**: Load and validate `prisma-next.config.ts` files using Arktype validation
|
|
25
|
+
- **CLI Binary Compatibility**: Build emits `dist/cli.mjs` and also writes a compatibility shim at `dist/cli.js`
|
|
25
26
|
|
|
26
27
|
### Wiring validation
|
|
27
28
|
|
|
@@ -31,13 +32,13 @@ This prevents runtime mismatches (for example: a contract that declares extensio
|
|
|
31
32
|
|
|
32
33
|
Commands that enforce wiring validation:
|
|
33
34
|
- **`db verify`**
|
|
34
|
-
- **`db introspect`** (when a contract is provided)
|
|
35
35
|
- **`db sign`**
|
|
36
36
|
- **`db init`**
|
|
37
|
+
- **`db update`**
|
|
37
38
|
|
|
38
39
|
If you hit a wiring validation error: add the required descriptors to `config.extensionPacks` (matched by descriptor `id`) and re-run the command.
|
|
39
40
|
|
|
40
|
-
**Note**: Control plane domain actions (database verification, contract emission) are implemented in `@prisma-next/
|
|
41
|
+
**Note**: Control plane domain actions (database verification, contract emission) are implemented in `@prisma-next/emitter` and `@prisma-next/framework-components/control`. The CLI uses the control plane domain actions programmatically but does not define control plane types itself.
|
|
41
42
|
|
|
42
43
|
## Command Descriptions
|
|
43
44
|
|
|
@@ -56,7 +57,7 @@ Emit `contract.json` and `contract.d.ts` from `config.contract`.
|
|
|
56
57
|
|
|
57
58
|
**Canonical command:**
|
|
58
59
|
```bash
|
|
59
|
-
prisma-next contract emit [--config <path>] [--json] [-v] [-q] [--
|
|
60
|
+
prisma-next contract emit [--config <path>] [--json] [-v] [-q] [--color/--no-color]
|
|
60
61
|
```
|
|
61
62
|
|
|
62
63
|
**Config File Requirements:**
|
|
@@ -65,6 +66,7 @@ The `contract emit` command does not require a `driver` in the config since it d
|
|
|
65
66
|
|
|
66
67
|
```typescript
|
|
67
68
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
69
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
68
70
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
69
71
|
import postgres from '@prisma-next/target-postgres/control';
|
|
70
72
|
import sql from '@prisma-next/family-sql/control';
|
|
@@ -75,11 +77,7 @@ export default defineConfig({
|
|
|
75
77
|
target: postgres,
|
|
76
78
|
adapter: postgresAdapter,
|
|
77
79
|
extensionPacks: [],
|
|
78
|
-
contract:
|
|
79
|
-
source: contract,
|
|
80
|
-
output: 'src/prisma/contract.json',
|
|
81
|
-
types: 'src/prisma/contract.d.ts',
|
|
82
|
-
},
|
|
80
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
83
81
|
});
|
|
84
82
|
```
|
|
85
83
|
|
|
@@ -89,7 +87,6 @@ Options:
|
|
|
89
87
|
- `-q, --quiet`: Quiet mode (errors only)
|
|
90
88
|
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
91
89
|
- `-vv, --trace`: Trace output (deep internals, stack traces)
|
|
92
|
-
- `--timestamps`: Add timestamps to output
|
|
93
90
|
- `--color/--no-color`: Force/disable color output
|
|
94
91
|
|
|
95
92
|
Examples:
|
|
@@ -100,27 +97,30 @@ prisma-next contract emit
|
|
|
100
97
|
# JSON output
|
|
101
98
|
prisma-next contract emit --json
|
|
102
99
|
|
|
103
|
-
# Verbose output
|
|
104
|
-
prisma-next contract emit -v
|
|
100
|
+
# Verbose output
|
|
101
|
+
prisma-next contract emit -v
|
|
105
102
|
```
|
|
106
103
|
|
|
107
104
|
### `prisma-next db verify`
|
|
108
105
|
|
|
109
|
-
Verify that a database instance matches the emitted contract by checking marker
|
|
106
|
+
Verify that a database instance matches the emitted contract by checking the marker first and, by default, the live schema second.
|
|
110
107
|
|
|
111
108
|
**Command:**
|
|
112
109
|
```bash
|
|
113
|
-
prisma-next db verify [--db <url>] [--config <path>] [--json] [-v] [-q] [--
|
|
110
|
+
prisma-next db verify [--db <url>] [--config <path>] [--marker-only | --schema-only] [--strict] [--json] [-v] [-q] [--color/--no-color]
|
|
114
111
|
```
|
|
115
112
|
|
|
116
113
|
Options:
|
|
117
114
|
- `--db <url>`: Database connection string (optional; defaults to `config.db.connection` if set)
|
|
118
115
|
- `--config <path>`: Optional. Path to `prisma-next.config.ts` (defaults to `./prisma-next.config.ts` if present)
|
|
116
|
+
- `--marker-only`: Skip schema verification and only check the database marker
|
|
117
|
+
- `--schema-only`: Skip marker verification and only check whether the live schema satisfies the contract
|
|
118
|
+
- `--strict`: When schema verification runs, schema elements not present in the contract are considered an error
|
|
119
|
+
- `--marker-only` cannot be combined with `--schema-only` or `--strict` (exit code 2, `PN-CLI-4012`). `--schema-only --strict` is valid.
|
|
119
120
|
- `--json`: Output as JSON object
|
|
120
121
|
- `-q, --quiet`: Quiet mode (errors only)
|
|
121
122
|
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
122
123
|
- `-vv, --trace`: Trace output (deep internals, stack traces)
|
|
123
|
-
- `--timestamps`: Add timestamps to output
|
|
124
124
|
- `--color/--no-color`: Force/disable color output
|
|
125
125
|
|
|
126
126
|
Examples:
|
|
@@ -131,11 +131,20 @@ prisma-next db verify
|
|
|
131
131
|
# Specify database URL
|
|
132
132
|
prisma-next db verify --db postgresql://user:pass@localhost/db
|
|
133
133
|
|
|
134
|
+
# Marker-only verification when callers accept the trade-off
|
|
135
|
+
prisma-next db verify --db postgresql://user:pass@localhost/db --marker-only
|
|
136
|
+
|
|
137
|
+
# Schema-only verification without relying on marker state
|
|
138
|
+
prisma-next db verify --db postgresql://user:pass@localhost/db --schema-only
|
|
139
|
+
|
|
140
|
+
# Strict schema verification (extras fail)
|
|
141
|
+
prisma-next db verify --db postgresql://user:pass@localhost/db --strict
|
|
142
|
+
|
|
134
143
|
# JSON output
|
|
135
144
|
prisma-next db verify --json
|
|
136
145
|
|
|
137
|
-
# Verbose output
|
|
138
|
-
prisma-next db verify -v
|
|
146
|
+
# Verbose output
|
|
147
|
+
prisma-next db verify -v
|
|
139
148
|
```
|
|
140
149
|
|
|
141
150
|
**Config File Requirements:**
|
|
@@ -144,6 +153,7 @@ The `db verify` command requires a `driver` in the config to connect to the data
|
|
|
144
153
|
|
|
145
154
|
```typescript
|
|
146
155
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
156
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
147
157
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
148
158
|
import postgresDriver from '@prisma-next/driver-postgres/control';
|
|
149
159
|
import postgres from '@prisma-next/target-postgres/control';
|
|
@@ -156,11 +166,7 @@ export default defineConfig({
|
|
|
156
166
|
adapter: postgresAdapter,
|
|
157
167
|
driver: postgresDriver,
|
|
158
168
|
extensionPacks: [],
|
|
159
|
-
contract:
|
|
160
|
-
source: contract,
|
|
161
|
-
output: 'src/prisma/contract.json',
|
|
162
|
-
types: 'src/prisma/contract.d.ts',
|
|
163
|
-
},
|
|
169
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
164
170
|
db: {
|
|
165
171
|
connection: process.env.DATABASE_URL, // Optional: can also use --db flag
|
|
166
172
|
},
|
|
@@ -171,52 +177,80 @@ export default defineConfig({
|
|
|
171
177
|
|
|
172
178
|
1. **Load Contract**: Reads the emitted `contract.json` from `config.contract.output`
|
|
173
179
|
2. **Connect to Database**: Uses `config.driver.create(url)` to create a driver
|
|
174
|
-
3. **Create Family Instance**: Creates a `
|
|
175
|
-
4. **Verify**: Calls `familyInstance.verify()` which:
|
|
180
|
+
3. **Create Family Instance**: Creates a `ControlStack` via `createControlStack()` and passes it to `config.family.create(stack)` to create a family instance
|
|
181
|
+
4. **Verify Marker**: Calls `familyInstance.verify()` which:
|
|
176
182
|
- Reads the contract marker from the database
|
|
177
|
-
- Compares marker presence: Returns `PN-
|
|
178
|
-
- Compares target compatibility: Returns `PN-
|
|
179
|
-
- Compares
|
|
180
|
-
- Compares profile hash: Returns `PN-
|
|
183
|
+
- Compares marker presence: Returns `PN-RUN-3001` if marker is missing
|
|
184
|
+
- Compares target compatibility: Returns `PN-RUN-3003` if contract target doesn't match config target
|
|
185
|
+
- Compares storage hash: Returns `PN-RUN-3002` if `storageHash` doesn't match
|
|
186
|
+
- Compares profile hash: Returns `PN-RUN-3002` if `profileHash` doesn't match (when present)
|
|
181
187
|
- Checks codec coverage (optional): Compares contract column types against supported codec types and reports missing codecs
|
|
188
|
+
5. **Verify Schema (default)**: Unless `--marker-only` is provided, calls `familyInstance.schemaVerify()` to catch schema mismatches such as missing tables or columns after manual DDL. By default this runs in tolerant mode; `--strict` treats schema elements not present in the contract as an error.
|
|
189
|
+
6. **Schema-only mode**: `--schema-only` skips marker verification entirely and runs only `schemaVerify()`. This is useful for brownfield adoption and corrupt-marker diagnosis.
|
|
182
190
|
|
|
183
191
|
**Output Format (TTY):**
|
|
184
192
|
|
|
185
193
|
Success:
|
|
186
|
-
```
|
|
187
|
-
✔ Database
|
|
188
|
-
|
|
194
|
+
```text
|
|
195
|
+
✔ Database marker and schema match contract
|
|
196
|
+
verification: marker + schema
|
|
197
|
+
storageHash: sha256:abc123...
|
|
189
198
|
profileHash: sha256:def456...
|
|
190
199
|
```
|
|
191
200
|
|
|
192
|
-
|
|
201
|
+
Marker-only success:
|
|
202
|
+
```text
|
|
203
|
+
✔ Database marker matches contract
|
|
204
|
+
verification: marker only (--marker-only)
|
|
205
|
+
storageHash: sha256:abc123...
|
|
206
|
+
profileHash: sha256:def456...
|
|
207
|
+
|
|
208
|
+
⚠ Schema verification skipped because --marker-only was provided
|
|
193
209
|
```
|
|
194
|
-
|
|
210
|
+
|
|
211
|
+
Marker failure:
|
|
212
|
+
```text
|
|
213
|
+
✖ Marker missing (PN-RUN-3001)
|
|
195
214
|
Why: Contract marker not found in database
|
|
196
215
|
Fix: Run `prisma-next db sign --db <url>` to create marker
|
|
197
216
|
```
|
|
198
217
|
|
|
218
|
+
Schema drift failure:
|
|
219
|
+
`db verify` prints the schema verification tree / JSON payload and exits with code 1.
|
|
220
|
+
|
|
199
221
|
**Output Format (JSON):**
|
|
200
222
|
|
|
201
223
|
```json
|
|
202
224
|
{
|
|
203
225
|
"ok": true,
|
|
204
|
-
"summary": "Database
|
|
226
|
+
"summary": "Database marker and schema match contract",
|
|
227
|
+
"mode": "full",
|
|
205
228
|
"contract": {
|
|
206
|
-
"
|
|
229
|
+
"storageHash": "sha256:abc123...",
|
|
207
230
|
"profileHash": "sha256:def456..."
|
|
208
231
|
},
|
|
209
232
|
"marker": {
|
|
210
|
-
"
|
|
233
|
+
"storageHash": "sha256:abc123...",
|
|
211
234
|
"profileHash": "sha256:def456..."
|
|
212
235
|
},
|
|
213
236
|
"target": {
|
|
214
237
|
"expected": "postgres"
|
|
215
238
|
},
|
|
216
239
|
"missingCodecs": [],
|
|
240
|
+
"schema": {
|
|
241
|
+
"summary": "Database schema satisfies contract",
|
|
242
|
+
"counts": {
|
|
243
|
+
"pass": 12,
|
|
244
|
+
"warn": 0,
|
|
245
|
+
"fail": 0,
|
|
246
|
+
"totalNodes": 12
|
|
247
|
+
},
|
|
248
|
+
"strict": false
|
|
249
|
+
},
|
|
217
250
|
"meta": {
|
|
218
251
|
"configPath": "/path/to/prisma-next.config.ts",
|
|
219
|
-
"contractPath": "/path/to/src/prisma/contract.json"
|
|
252
|
+
"contractPath": "/path/to/src/prisma/contract.json",
|
|
253
|
+
"schemaVerification": "performed"
|
|
220
254
|
},
|
|
221
255
|
"timings": {
|
|
222
256
|
"total": 42
|
|
@@ -227,22 +261,23 @@ Failure:
|
|
|
227
261
|
**Error Codes:**
|
|
228
262
|
|
|
229
263
|
- `PN-CLI-4010`: Missing driver in config — provide a driver descriptor
|
|
230
|
-
- `PN-
|
|
231
|
-
- `PN-
|
|
232
|
-
- `PN-
|
|
264
|
+
- `PN-RUN-3001`: Marker missing - Contract marker not found in database
|
|
265
|
+
- `PN-RUN-3002`: Hash mismatch - Contract hash does not match database marker
|
|
266
|
+
- `PN-RUN-3003`: Target mismatch - Contract target does not match config target
|
|
267
|
+
- Exit code 1 with schema verification payload: Schema does not match the contract (default mode or `--schema-only`)
|
|
233
268
|
|
|
234
269
|
**Family Requirements:**
|
|
235
270
|
|
|
236
|
-
The family must provide a `create()` method in the family descriptor that accepts a `
|
|
271
|
+
The family must provide a `create()` method in the family descriptor that accepts a `ControlStack` and returns a `ControlFamilyInstance` with a `verify()` method:
|
|
237
272
|
|
|
238
273
|
```typescript
|
|
239
274
|
interface ControlFamilyDescriptor<TFamilyId, TFamilyInstance> {
|
|
240
275
|
create<TTargetId extends string>(
|
|
241
|
-
stack:
|
|
276
|
+
stack: ControlStack<TFamilyId, TTargetId>,
|
|
242
277
|
): TFamilyInstance;
|
|
243
278
|
}
|
|
244
279
|
|
|
245
|
-
interface
|
|
280
|
+
interface ControlStack<TFamilyId, TTargetId> {
|
|
246
281
|
readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
|
|
247
282
|
readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
|
|
248
283
|
readonly driver: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;
|
|
@@ -252,7 +287,7 @@ interface ControlPlaneStack<TFamilyId, TTargetId> {
|
|
|
252
287
|
interface ControlFamilyInstance {
|
|
253
288
|
verify(options: {
|
|
254
289
|
driver: ControlDriverInstance;
|
|
255
|
-
|
|
290
|
+
contract: Contract;
|
|
256
291
|
expectedTargetId: string;
|
|
257
292
|
contractPath: string;
|
|
258
293
|
configPath?: string;
|
|
@@ -260,17 +295,17 @@ interface ControlFamilyInstance {
|
|
|
260
295
|
}
|
|
261
296
|
```
|
|
262
297
|
|
|
263
|
-
Use `
|
|
298
|
+
Use `createControlStack()` from `@prisma-next/framework-components/control` to create the stack with sensible defaults (`driver` defaults to `undefined`, `extensionPacks` defaults to `[]`).
|
|
264
299
|
|
|
265
|
-
The SQL family provides this via `@prisma-next/family-sql/control`. The `verify()` method handles
|
|
300
|
+
The SQL family provides this via `@prisma-next/family-sql/control`. The `verify()` method handles marker checks, full `db verify` follows it with `schemaVerify()`, `--marker-only` skips that schema step, and `--schema-only` runs `schemaVerify()` without marker checks.
|
|
266
301
|
|
|
267
|
-
### `prisma-next db
|
|
302
|
+
### `prisma-next db schema`
|
|
268
303
|
|
|
269
|
-
Inspect the live database schema and display it as a human-readable tree or machine-consumable JSON.
|
|
304
|
+
Inspect the live database schema and display it as a human-readable tree or machine-consumable JSON. This command is read-only and never writes files.
|
|
270
305
|
|
|
271
306
|
**Command:**
|
|
272
307
|
```bash
|
|
273
|
-
prisma-next db
|
|
308
|
+
prisma-next db schema [--db <url>] [--config <path>] [--json] [-v] [-q] [--color/--no-color]
|
|
274
309
|
```
|
|
275
310
|
|
|
276
311
|
Options:
|
|
@@ -280,30 +315,69 @@ Options:
|
|
|
280
315
|
- `-q, --quiet`: Quiet mode (errors only)
|
|
281
316
|
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
282
317
|
- `-vv, --trace`: Trace output (deep internals, stack traces)
|
|
283
|
-
- `--timestamps`: Add timestamps to output
|
|
284
318
|
- `--color/--no-color`: Force/disable color output
|
|
285
319
|
|
|
286
320
|
Examples:
|
|
287
321
|
```bash
|
|
288
322
|
# Use config defaults
|
|
289
|
-
prisma-next db
|
|
323
|
+
prisma-next db schema
|
|
290
324
|
|
|
291
325
|
# Specify database URL
|
|
292
|
-
prisma-next db
|
|
326
|
+
prisma-next db schema --db postgresql://user:pass@localhost/db
|
|
293
327
|
|
|
294
328
|
# JSON output
|
|
295
|
-
prisma-next db
|
|
329
|
+
prisma-next db schema --json
|
|
330
|
+
|
|
331
|
+
# Verbose output
|
|
332
|
+
prisma-next db schema -v
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### `prisma-next contract infer`
|
|
336
|
+
|
|
337
|
+
Inspect the live database schema and write an inferred PSL contract to disk. Use this for brownfield adoption when you want a starting `contract.prisma` before running `contract emit` and `db sign`.
|
|
338
|
+
|
|
339
|
+
**Command:**
|
|
340
|
+
```bash
|
|
341
|
+
prisma-next contract infer [--db <url>] [--config <path>] [--output <path>] [--json] [-v] [-q] [--color/--no-color]
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Options:
|
|
345
|
+
- `--db <url>`: Database connection string (optional; defaults to `config.db.connection` if set)
|
|
346
|
+
- `--config <path>`: Optional. Path to `prisma-next.config.ts` (defaults to `./prisma-next.config.ts` if present)
|
|
347
|
+
- `--output <path>`: Write the inferred PSL contract to the specified path
|
|
348
|
+
- `--json`: Output a JSON result envelope (includes `psl.path`)
|
|
349
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
350
|
+
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
351
|
+
- `-vv, --trace`: Trace output (deep internals, stack traces)
|
|
352
|
+
- `--color/--no-color`: Force/disable color output
|
|
353
|
+
|
|
354
|
+
Examples:
|
|
355
|
+
```bash
|
|
356
|
+
# Infer contract.prisma next to the configured contract.json output
|
|
357
|
+
prisma-next contract infer
|
|
358
|
+
|
|
359
|
+
# Specify database URL
|
|
360
|
+
prisma-next contract infer --db postgresql://user:pass@localhost/db
|
|
296
361
|
|
|
297
|
-
#
|
|
298
|
-
prisma-next
|
|
362
|
+
# Override the output path
|
|
363
|
+
prisma-next contract infer --output ./prisma/contract.prisma
|
|
364
|
+
|
|
365
|
+
# JSON output
|
|
366
|
+
prisma-next contract infer --json
|
|
299
367
|
```
|
|
300
368
|
|
|
369
|
+
By default, `contract infer` writes to:
|
|
370
|
+
1. `--output <path>`, if provided
|
|
371
|
+
2. `contract.prisma` next to `config.contract.output`
|
|
372
|
+
3. `contract.prisma` in the current working directory
|
|
373
|
+
|
|
301
374
|
**Config File Requirements:**
|
|
302
375
|
|
|
303
|
-
|
|
376
|
+
Both `db schema` and `contract infer` require a `driver` in the config to connect to the database:
|
|
304
377
|
|
|
305
378
|
```typescript
|
|
306
379
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
380
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
307
381
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
308
382
|
import postgresDriver from '@prisma-next/driver-postgres/control';
|
|
309
383
|
import postgres from '@prisma-next/target-postgres/control';
|
|
@@ -324,7 +398,7 @@ export default defineConfig({
|
|
|
324
398
|
**Introspection Process:**
|
|
325
399
|
|
|
326
400
|
1. **Connect to Database**: Uses `config.driver.create(url)` to create a driver
|
|
327
|
-
2. **Create Family Instance**: Creates a `
|
|
401
|
+
2. **Create Family Instance**: Creates a `ControlStack` via `createControlStack()` and passes it to `config.family.create(stack)` to create a family instance
|
|
328
402
|
3. **Introspect**: Calls `familyInstance.introspect()` which:
|
|
329
403
|
- Queries the database catalog to discover schema structure
|
|
330
404
|
- Returns a family-specific schema IR (e.g., `SqlSchemaIR` for SQL family)
|
|
@@ -403,7 +477,7 @@ The family must provide:
|
|
|
403
477
|
interface ControlFamilyInstance {
|
|
404
478
|
introspect(options: {
|
|
405
479
|
driver: ControlDriverInstance;
|
|
406
|
-
|
|
480
|
+
contract?: Contract;
|
|
407
481
|
schema?: string;
|
|
408
482
|
}): Promise<FamilySchemaIR>;
|
|
409
483
|
|
|
@@ -421,7 +495,7 @@ Mark the database as matching the emitted contract by writing or updating the co
|
|
|
421
495
|
|
|
422
496
|
**Command:**
|
|
423
497
|
```bash
|
|
424
|
-
prisma-next db sign [--db <url>] [--config <path>] [--json] [-v] [-q] [--
|
|
498
|
+
prisma-next db sign [--db <url>] [--config <path>] [--json] [-v] [-q] [--color/--no-color]
|
|
425
499
|
```
|
|
426
500
|
|
|
427
501
|
Options:
|
|
@@ -431,7 +505,6 @@ Options:
|
|
|
431
505
|
- `-q, --quiet`: Quiet mode (errors only)
|
|
432
506
|
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
433
507
|
- `-vv, --trace`: Trace output (deep internals, stack traces)
|
|
434
|
-
- `--timestamps`: Add timestamps to output
|
|
435
508
|
- `--color/--no-color`: Force/disable color output
|
|
436
509
|
|
|
437
510
|
Examples:
|
|
@@ -445,8 +518,8 @@ prisma-next db sign --db postgresql://user:pass@localhost/db
|
|
|
445
518
|
# JSON output
|
|
446
519
|
prisma-next db sign --json
|
|
447
520
|
|
|
448
|
-
# Verbose output
|
|
449
|
-
prisma-next db sign -v
|
|
521
|
+
# Verbose output
|
|
522
|
+
prisma-next db sign -v
|
|
450
523
|
```
|
|
451
524
|
|
|
452
525
|
**Config File Requirements:**
|
|
@@ -467,11 +540,7 @@ export default defineConfig({
|
|
|
467
540
|
adapter: postgresAdapter,
|
|
468
541
|
driver: postgresDriver,
|
|
469
542
|
extensionPacks: [],
|
|
470
|
-
contract:
|
|
471
|
-
source: contract,
|
|
472
|
-
output: 'src/prisma/contract.json',
|
|
473
|
-
types: 'src/prisma/contract.d.ts',
|
|
474
|
-
},
|
|
543
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
475
544
|
db: {
|
|
476
545
|
connection: process.env.DATABASE_URL, // Optional: can also use --db flag
|
|
477
546
|
},
|
|
@@ -482,7 +551,7 @@ export default defineConfig({
|
|
|
482
551
|
|
|
483
552
|
1. **Load Contract**: Reads the emitted `contract.json` from `config.contract.output`
|
|
484
553
|
2. **Connect to Database**: Uses `config.driver.create(url)` to create a driver
|
|
485
|
-
3. **Create Family Instance**: Creates a `
|
|
554
|
+
3. **Create Family Instance**: Creates a `ControlStack` via `createControlStack()` and passes it to `config.family.create(stack)` to create a family instance
|
|
486
555
|
4. **Schema Verification (Precondition)**: Calls `familyInstance.schemaVerify()` to verify the database schema matches the contract:
|
|
487
556
|
- If verification fails: Prints schema verification output and exits with code 1 (marker is not written)
|
|
488
557
|
- If verification passes: Proceeds to marker signing
|
|
@@ -499,7 +568,7 @@ export default defineConfig({
|
|
|
499
568
|
Success (new marker):
|
|
500
569
|
```
|
|
501
570
|
✔ Database signed (marker created)
|
|
502
|
-
|
|
571
|
+
storageHash: sha256:abc123...
|
|
503
572
|
profileHash: sha256:def456...
|
|
504
573
|
Total time: 42ms
|
|
505
574
|
```
|
|
@@ -507,16 +576,16 @@ Success (new marker):
|
|
|
507
576
|
Success (updated marker):
|
|
508
577
|
```
|
|
509
578
|
✔ Database signed (marker updated from sha256:old-hash)
|
|
510
|
-
|
|
579
|
+
storageHash: sha256:abc123...
|
|
511
580
|
profileHash: sha256:def456...
|
|
512
|
-
previous
|
|
581
|
+
previous storageHash: sha256:old-hash
|
|
513
582
|
Total time: 42ms
|
|
514
583
|
```
|
|
515
584
|
|
|
516
585
|
Success (already up-to-date):
|
|
517
586
|
```
|
|
518
587
|
✔ Database already signed with this contract
|
|
519
|
-
|
|
588
|
+
storageHash: sha256:abc123...
|
|
520
589
|
profileHash: sha256:def456...
|
|
521
590
|
Total time: 42ms
|
|
522
591
|
```
|
|
@@ -534,7 +603,7 @@ Failure (schema mismatch):
|
|
|
534
603
|
"ok": true,
|
|
535
604
|
"summary": "Database signed (marker created)",
|
|
536
605
|
"contract": {
|
|
537
|
-
"
|
|
606
|
+
"storageHash": "sha256:abc123...",
|
|
538
607
|
"profileHash": "sha256:def456..."
|
|
539
608
|
},
|
|
540
609
|
"target": {
|
|
@@ -561,7 +630,7 @@ For updated markers:
|
|
|
561
630
|
"ok": true,
|
|
562
631
|
"summary": "Database signed (marker updated from sha256:old-hash)",
|
|
563
632
|
"contract": {
|
|
564
|
-
"
|
|
633
|
+
"storageHash": "sha256:abc123...",
|
|
565
634
|
"profileHash": "sha256:def456..."
|
|
566
635
|
},
|
|
567
636
|
"target": {
|
|
@@ -572,7 +641,7 @@ For updated markers:
|
|
|
572
641
|
"created": false,
|
|
573
642
|
"updated": true,
|
|
574
643
|
"previous": {
|
|
575
|
-
"
|
|
644
|
+
"storageHash": "sha256:old-hash",
|
|
576
645
|
"profileHash": "sha256:old-profile-hash"
|
|
577
646
|
}
|
|
578
647
|
},
|
|
@@ -592,8 +661,7 @@ For updated markers:
|
|
|
592
661
|
- Exit code 1: Schema verification failed — database schema does not match contract (marker is not written)
|
|
593
662
|
|
|
594
663
|
**Relationship to Other Commands:**
|
|
595
|
-
- **`db
|
|
596
|
-
- **`db verify`**: `db verify` checks that the marker exists and matches the contract. `db sign` writes the marker that `db verify` checks.
|
|
664
|
+
- **`db verify`**: `db verify` checks that the marker exists and matches the contract, then runs schema verification by default. `db sign` writes the marker that `db verify` checks. Use `db verify --marker-only` for marker-only verification and `db verify --schema-only` to inspect only the live schema.
|
|
597
665
|
|
|
598
666
|
**Idempotency:**
|
|
599
667
|
The `db sign` command is idempotent and safe to run multiple times:
|
|
@@ -608,7 +676,7 @@ The family must provide a `create()` method in the family descriptor that return
|
|
|
608
676
|
interface ControlFamilyInstance {
|
|
609
677
|
schemaVerify(options: {
|
|
610
678
|
driver: ControlDriverInstance;
|
|
611
|
-
|
|
679
|
+
contract: Contract;
|
|
612
680
|
strict: boolean;
|
|
613
681
|
contractPath: string;
|
|
614
682
|
configPath?: string;
|
|
@@ -616,7 +684,7 @@ interface ControlFamilyInstance {
|
|
|
616
684
|
|
|
617
685
|
sign(options: {
|
|
618
686
|
driver: ControlDriverInstance;
|
|
619
|
-
|
|
687
|
+
contract: Contract;
|
|
620
688
|
contractPath: string;
|
|
621
689
|
configPath?: string;
|
|
622
690
|
}): Promise<SignDatabaseResult>;
|
|
@@ -631,18 +699,17 @@ Initialize a database schema from the contract. This command plans and applies *
|
|
|
631
699
|
|
|
632
700
|
**Command:**
|
|
633
701
|
```bash
|
|
634
|
-
prisma-next db init [--db <url>] [--config <path>] [--
|
|
702
|
+
prisma-next db init [--db <url>] [--config <path>] [--dry-run] [--json] [-v] [-q] [--color/--no-color]
|
|
635
703
|
```
|
|
636
704
|
|
|
637
705
|
Options:
|
|
638
706
|
- `--db <url>`: Database connection string (optional; defaults to `config.db.connection` if set)
|
|
639
707
|
- `--config <path>`: Optional. Path to `prisma-next.config.ts` (defaults to `./prisma-next.config.ts` if present)
|
|
640
|
-
- `--
|
|
708
|
+
- `--dry-run`: Only show the migration plan, do not apply it
|
|
641
709
|
- `--json [format]`: Output as JSON (`object` only; `ndjson` is not supported for this command)
|
|
642
710
|
- `-q, --quiet`: Quiet mode (errors only)
|
|
643
711
|
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
644
712
|
- `-vv, --trace`: Trace output (deep internals, stack traces)
|
|
645
|
-
- `--timestamps`: Add timestamps to output
|
|
646
713
|
- `--color/--no-color`: Force/disable color output
|
|
647
714
|
|
|
648
715
|
Examples:
|
|
@@ -651,7 +718,7 @@ Examples:
|
|
|
651
718
|
prisma-next db init
|
|
652
719
|
|
|
653
720
|
# Preview migration plan without applying
|
|
654
|
-
prisma-next db init --
|
|
721
|
+
prisma-next db init --dry-run
|
|
655
722
|
|
|
656
723
|
# Specify database URL
|
|
657
724
|
prisma-next db init --db postgresql://user:pass@localhost/db
|
|
@@ -666,6 +733,7 @@ The `db init` command requires a `driver` in the config to connect to the databa
|
|
|
666
733
|
|
|
667
734
|
```typescript
|
|
668
735
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
736
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
669
737
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
670
738
|
import postgresDriver from '@prisma-next/driver-postgres/control';
|
|
671
739
|
import postgres from '@prisma-next/target-postgres/control';
|
|
@@ -678,11 +746,7 @@ export default defineConfig({
|
|
|
678
746
|
adapter: postgresAdapter,
|
|
679
747
|
driver: postgresDriver,
|
|
680
748
|
extensionPacks: [],
|
|
681
|
-
contract:
|
|
682
|
-
source: contract,
|
|
683
|
-
output: 'src/prisma/contract.json',
|
|
684
|
-
types: 'src/prisma/contract.d.ts',
|
|
685
|
-
},
|
|
749
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
686
750
|
db: {
|
|
687
751
|
connection: process.env.DATABASE_URL, // Optional: can also use --db flag
|
|
688
752
|
},
|
|
@@ -693,17 +757,17 @@ export default defineConfig({
|
|
|
693
757
|
|
|
694
758
|
1. **Load Contract**: Reads the emitted `contract.json` from `config.contract.output`
|
|
695
759
|
2. **Connect to Database**: Uses `config.driver.create(url)` to create a driver
|
|
696
|
-
3. **Create Family Instance**: Creates a `
|
|
760
|
+
3. **Create Family Instance**: Creates a `ControlStack` via `createControlStack()` and passes it to `config.family.create(stack)` to create a family instance
|
|
697
761
|
4. **Introspect Schema**: Calls `familyInstance.introspect()` to get the current database schema IR
|
|
698
762
|
5. **Validate wiring**: Ensures the contract is compatible with the CLI config:
|
|
699
763
|
- `contract.targetFamily` matches `config.family.familyId`
|
|
700
764
|
- `contract.target` matches `config.target.targetId`
|
|
701
765
|
- `contract.extensionPacks` (if present) are provided by `config.extensionPacks` (matched by descriptor `id`)
|
|
702
766
|
6. **Create Planner/Runner**: Uses `config.target.migrations.createPlanner()` and `config.target.migrations.createRunner()`
|
|
703
|
-
7. **Plan Migration**: Calls `planner.plan()` with the contract
|
|
767
|
+
7. **Plan Migration**: Calls `planner.plan()` with the contract, schema IR, additive-only policy, and `frameworkComponents` (the active target/adapter/extension descriptors)
|
|
704
768
|
- On conflict: Returns a structured failure with conflict list
|
|
705
769
|
- On success: Returns a migration plan with operations
|
|
706
|
-
8. **Apply Migration** (if not `--
|
|
770
|
+
8. **Apply Migration** (if not `--dry-run`):
|
|
707
771
|
- Calls `runner.execute()` to apply the plan
|
|
708
772
|
- After execution, verifies schema matches contract
|
|
709
773
|
- Writes contract marker (and records a ledger entry via the target runner)
|
|
@@ -726,7 +790,7 @@ prisma-next db init ➜ Bootstrap a database to match the current contract
|
|
|
726
790
|
Destination hash: sha256:abc123...
|
|
727
791
|
|
|
728
792
|
This is a dry run. No changes were applied.
|
|
729
|
-
Run without --
|
|
793
|
+
Run without --dry-run to apply changes.
|
|
730
794
|
```
|
|
731
795
|
|
|
732
796
|
**Output Format (TTY - Apply Mode):**
|
|
@@ -754,7 +818,7 @@ Applying migration plan and verifying schema...
|
|
|
754
818
|
"plan": {
|
|
755
819
|
"targetId": "postgres",
|
|
756
820
|
"destination": {
|
|
757
|
-
"
|
|
821
|
+
"storageHash": "sha256:abc123..."
|
|
758
822
|
},
|
|
759
823
|
"operations": [
|
|
760
824
|
{
|
|
@@ -769,7 +833,7 @@ Applying migration plan and verifying schema...
|
|
|
769
833
|
"operationsExecuted": 4
|
|
770
834
|
},
|
|
771
835
|
"marker": {
|
|
772
|
-
"
|
|
836
|
+
"storageHash": "sha256:abc123..."
|
|
773
837
|
}
|
|
774
838
|
}
|
|
775
839
|
```
|
|
@@ -781,12 +845,33 @@ Applying migration plan and verifying schema...
|
|
|
781
845
|
- `PN-CLI-4010`: Missing driver in config
|
|
782
846
|
- `PN-CLI-4020`: Migration planning failed (conflicts)
|
|
783
847
|
- `PN-CLI-4021`: Target does not support migrations
|
|
784
|
-
- `PN-
|
|
848
|
+
- `PN-RUN-3000`: Runtime error (includes marker mismatch failures)
|
|
785
849
|
|
|
786
850
|
**Behavior Notes:**
|
|
787
851
|
|
|
788
852
|
- If the database already has a marker that matches the destination contract, `db init` succeeds as a noop (0 operations planned/executed).
|
|
789
|
-
- If the database has a marker that does **not** match the destination contract, `db init` fails (including in `--
|
|
853
|
+
- If the database has a marker that does **not** match the destination contract, `db init` fails (including in `--dry-run` mode). Use `db init` for bootstrapping; use your migration workflow to reconcile existing databases.
|
|
854
|
+
|
|
855
|
+
### `prisma-next db update`
|
|
856
|
+
|
|
857
|
+
Update your database schema to match the currently emitted contract.
|
|
858
|
+
|
|
859
|
+
`db update` differs from `db init`:
|
|
860
|
+
|
|
861
|
+
- Works on any database, whether or not it has been initialized with `db init` (creates the signature table if missing)
|
|
862
|
+
- Allows `additive`, `widening`, and `destructive` operation classes where supported by planner/runner
|
|
863
|
+
- Disables per-operation runner execution checks by default (precheck/postcheck/idempotency)
|
|
864
|
+
- In `--dry-run` mode for SQL targets, prints a DDL preview derived from planned operations
|
|
865
|
+
- In interactive mode, destructive plans require confirmation before apply
|
|
866
|
+
- In non-interactive mode, destructive plans fail unless `-y, --yes` is provided
|
|
867
|
+
|
|
868
|
+
**Command:**
|
|
869
|
+
```bash
|
|
870
|
+
prisma-next db update [--db <url>] [--config <path>] [--dry-run] [-y|--yes] [--interactive|--no-interactive] [--json] [-v] [-q] [--color/--no-color]
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
**Error codes (additional to shared CLI/runtime codes):**
|
|
874
|
+
- `RUNNER_FAILED`: runner rejected apply (origin mismatch, failed checks, policy failures, or execution errors)
|
|
790
875
|
|
|
791
876
|
**Config File (`prisma-next.config.ts`):**
|
|
792
877
|
|
|
@@ -801,6 +886,7 @@ The CLI uses a config file to specify the target family, target, adapter, extens
|
|
|
801
886
|
|
|
802
887
|
```typescript
|
|
803
888
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
889
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
804
890
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
805
891
|
import postgres from '@prisma-next/target-postgres/control';
|
|
806
892
|
import sql from '@prisma-next/family-sql/control';
|
|
@@ -811,42 +897,192 @@ export default defineConfig({
|
|
|
811
897
|
target: postgres,
|
|
812
898
|
adapter: postgresAdapter,
|
|
813
899
|
extensionPacks: [],
|
|
814
|
-
contract:
|
|
815
|
-
source: contract, // Can be a value or a function: () => import('./contract').then(m => m.contract)
|
|
816
|
-
output: 'src/prisma/contract.json', // Optional: defaults to 'src/prisma/contract.json'
|
|
817
|
-
types: 'src/prisma/contract.d.ts', // Optional: defaults to output with .d.ts extension
|
|
818
|
-
},
|
|
900
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
819
901
|
});
|
|
820
902
|
```
|
|
821
903
|
|
|
822
|
-
|
|
823
|
-
-
|
|
824
|
-
-
|
|
825
|
-
-
|
|
904
|
+
Prefer helper utilities for authoring mode selection:
|
|
905
|
+
- `typescriptContract(contract, outputPath?)` from `@prisma-next/sql-contract-ts/config-types` for TS-authored contracts
|
|
906
|
+
- `prismaContract(schemaPath, { output?, target? })` from `@prisma-next/sql-contract-psl/provider` for PSL-authored providers
|
|
907
|
+
- Provider failures are returned as structured diagnostics for CLI rendering
|
|
826
908
|
|
|
827
909
|
The `contract.output` field specifies the path to `contract.json`. This is the canonical location where other CLI commands can find the contract JSON artifact. Defaults to `'src/prisma/contract.json'` if not specified.
|
|
828
910
|
|
|
829
|
-
|
|
911
|
+
`contract.d.ts` is always colocated with `contract.json` and derived from `contract.output` (`contract.json` → `contract.d.ts`).
|
|
830
912
|
|
|
831
913
|
**Output:**
|
|
832
914
|
- `contract.json`: Includes `_generated` metadata field indicating it's a generated artifact (excluded from canonicalization/hashing)
|
|
833
915
|
- `contract.d.ts`: Includes warning header comments indicating it's a generated file
|
|
834
916
|
|
|
917
|
+
### `prisma-next migration plan`
|
|
918
|
+
|
|
919
|
+
Plan a migration from contract changes. Compares the emitted contract against the latest on-disk migration state and produces a new migration package with the required operations. No database connection is needed — fully offline.
|
|
920
|
+
|
|
921
|
+
```bash
|
|
922
|
+
prisma-next migration plan [--config <path>] [--name <slug>] [--from <hash>] [--json] [-v] [-q] [--color/--no-color]
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
**Options:**
|
|
926
|
+
- `--config <path>`: Path to `prisma-next.config.ts`
|
|
927
|
+
- `--name <slug>`: Name slug for the migration directory (default: `migration`)
|
|
928
|
+
- `--from <hash>`: Explicit starting contract hash (overrides latest migration target detection)
|
|
929
|
+
- `--json`: Output as JSON object
|
|
930
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
931
|
+
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
932
|
+
|
|
933
|
+
**What it does:**
|
|
934
|
+
1. Loads config and reads `contract.json` (the "to" contract)
|
|
935
|
+
2. Reads existing migrations from `config.migrations.dir` (default: `migrations/`)
|
|
936
|
+
3. Determines the starting point: `--from <hash>` if provided, otherwise the latest migration target
|
|
937
|
+
4. Diffs the starting contract against the new contract using the target's migration planner
|
|
938
|
+
5. Writes a new migration package (`migration.json` + `ops.json`) and attests the `migrationId`
|
|
939
|
+
|
|
940
|
+
**Branching with `--from`:** Use `--from` to create a migration edge from a specific contract hash instead of the latest migration target. This enables branched migration graphs where multiple environments diverge from a common ancestor.
|
|
941
|
+
|
|
942
|
+
### `prisma-next migration show`
|
|
943
|
+
|
|
944
|
+
Display a migration package's operations, DDL preview, and metadata. Accepts a directory path, a hash prefix (git-style matching against `migrationId`), or defaults to the latest migration.
|
|
945
|
+
|
|
946
|
+
```bash
|
|
947
|
+
prisma-next migration show [target] [--config <path>] [--json] [-v] [-q] [--color/--no-color]
|
|
948
|
+
```
|
|
949
|
+
|
|
950
|
+
**Options:**
|
|
951
|
+
- `[target]`: Migration directory path or migrationId hash prefix (defaults to latest)
|
|
952
|
+
- `--config <path>`: Path to `prisma-next.config.ts`
|
|
953
|
+
- `--json`: Output as JSON object
|
|
954
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
955
|
+
- `-v, --verbose`: Verbose output
|
|
956
|
+
|
|
957
|
+
**What it does:**
|
|
958
|
+
1. If `target` is a path (contains `/` or `\`), reads that directory directly
|
|
959
|
+
2. If `target` is a hash prefix, scans all attested migrations and matches against `migrationId`
|
|
960
|
+
3. If no target, defaults to the latest migration
|
|
961
|
+
4. Displays operations with operation class badges, destructive warnings, and DDL preview
|
|
962
|
+
|
|
963
|
+
**Destructive warnings:** When a migration contains destructive operations (e.g., `DROP TABLE`, `ALTER COLUMN TYPE`), the output includes a prominent `⚠` warning about potential data loss.
|
|
964
|
+
|
|
965
|
+
### `prisma-next migration status`
|
|
966
|
+
|
|
967
|
+
Show the migration graph and applied status. Adapts based on context:
|
|
968
|
+
|
|
969
|
+
- **With DB connection**: Shows applied/pending markers and "you are here" indicators
|
|
970
|
+
- **Without DB connection**: Shows the graph structure from disk only
|
|
971
|
+
- **With `--ref`**: Targets a specific ref instead of the contract hash; all refs from `refs.json` are rendered on the graph
|
|
972
|
+
|
|
973
|
+
```bash
|
|
974
|
+
prisma-next migration status [--db <url>] [--ref <name>] [--config <path>] [--json] [-v] [-q] [--color/--no-color]
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
**Options:**
|
|
978
|
+
- `--db <url>`: Database connection string (enables online mode)
|
|
979
|
+
- `--ref <name>`: Target a named ref from `migrations/refs.json` instead of the current contract hash
|
|
980
|
+
- `--config <path>`: Path to `prisma-next.config.ts`
|
|
981
|
+
- `--json`: Output as JSON object
|
|
982
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
983
|
+
- `-v, --verbose`: Verbose output
|
|
984
|
+
|
|
985
|
+
**What it does:**
|
|
986
|
+
1. Reads migration packages from disk and reconstructs the migration graph
|
|
987
|
+
2. Loads all refs from `migrations/refs.json` (if present) and renders them on the graph
|
|
988
|
+
3. If `--ref` is provided, uses the ref's hash as the target instead of the contract hash; the active ref is highlighted in bold, other refs are dimmed
|
|
989
|
+
4. If a DB connection is available, reads the marker to determine applied/pending status and shows distance from the ref target (e.g., "2 edge(s) behind ref")
|
|
990
|
+
5. Displays the graph with `◄ DB`, `◄ Contract`, and `◄ ref:<name>` markers
|
|
991
|
+
6. Shows operation summaries with destructive operation highlighting
|
|
992
|
+
7. In `--ref` mode, the `CONTRACT.AHEAD` warning is suppressed — contract being ahead of a ref target is expected in multi-environment workflows
|
|
993
|
+
|
|
994
|
+
**Branched graphs:** When the migration graph has multiple branches (divergence), status reports an `AMBIGUOUS_TARGET` error with the divergence point and branch details. Use `--ref` to target a specific branch.
|
|
995
|
+
|
|
996
|
+
### `prisma-next migration apply`
|
|
997
|
+
|
|
998
|
+
Apply planned migrations to the database. Executes previously planned migrations (created by `migration plan`). Compares the database marker against the migration graph to determine which migrations are pending, then executes them sequentially. Each migration runs in its own transaction. Does not plan new migrations — run `migration plan` first.
|
|
999
|
+
|
|
1000
|
+
```bash
|
|
1001
|
+
prisma-next migration apply [--db <url>] [--ref <name>] [--config <path>] [--json] [-v] [-q] [--color/--no-color]
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
**Options:**
|
|
1005
|
+
- `--db <url>`: Database connection string (optional; defaults to `config.db.connection`)
|
|
1006
|
+
- `--ref <name>`: Target a named ref from `migrations/refs.json` instead of the current contract hash
|
|
1007
|
+
- `--config <path>`: Path to `prisma-next.config.ts`
|
|
1008
|
+
- `--json`: Output as JSON object
|
|
1009
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
1010
|
+
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
1011
|
+
|
|
1012
|
+
**What it does:**
|
|
1013
|
+
1. Reads attested migration packages from `config.migrations.dir`
|
|
1014
|
+
2. Reconstructs the migration graph (skips drafts with `migrationId: null`)
|
|
1015
|
+
3. Determines the destination hash: from `--ref` (via `refs.json`) or from `contract.json`
|
|
1016
|
+
4. Connects to the database and reads the current marker hash
|
|
1017
|
+
5. Finds the shortest path from the marker hash to the destination using graph pathfinding
|
|
1018
|
+
6. Executes each pending migration in order using the target's `MigrationRunner`
|
|
1019
|
+
7. Each migration runs in its own transaction with prechecks, postchecks, and idempotency checks enabled
|
|
1020
|
+
8. After each migration, the runner verifies the schema and updates the marker/ledger
|
|
1021
|
+
|
|
1022
|
+
**Config requirements:** Requires `driver` and `db.connection` (or `--db`). `migrations.dir` is optional and defaults to `migrations/`.
|
|
1023
|
+
|
|
1024
|
+
**Resume semantics:** If a migration fails, previously applied migrations are preserved. Re-running `migration apply` resumes from the last successful migration.
|
|
1025
|
+
|
|
1026
|
+
**Ref-based routing:** With `--ref`, apply targets the ref's hash instead of the contract hash. This enables multi-environment workflows where staging and production track different points in the migration graph.
|
|
1027
|
+
|
|
1028
|
+
### `prisma-next migration verify`
|
|
1029
|
+
|
|
1030
|
+
Verify a migration package's integrity by recomputing the content-addressed `migrationId`.
|
|
1031
|
+
|
|
1032
|
+
```bash
|
|
1033
|
+
prisma-next migration verify --dir <path>
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
- **Verified**: stored `migrationId` matches recomputed value
|
|
1037
|
+
- **Draft**: `migrationId` is null — automatically attests the package
|
|
1038
|
+
- **Mismatch**: package has been modified since attestation (command exits non-zero)
|
|
1039
|
+
|
|
1040
|
+
### `prisma-next migration ref`
|
|
1041
|
+
|
|
1042
|
+
Manage named refs in `migrations/refs.json`. Refs map logical environment names (e.g., `staging`, `production`) to contract hashes, enabling multi-environment migration workflows where different environments track different points in the migration graph.
|
|
1043
|
+
|
|
1044
|
+
```bash
|
|
1045
|
+
prisma-next migration ref set <name> <hash> # Set a ref to a contract hash
|
|
1046
|
+
prisma-next migration ref get <name> # Get the hash for a ref
|
|
1047
|
+
prisma-next migration ref delete <name> # Delete a ref
|
|
1048
|
+
prisma-next migration ref list # List all refs
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
**Options (all subcommands):**
|
|
1052
|
+
- `--config <path>`: Path to `prisma-next.config.ts`
|
|
1053
|
+
- `--json`: Output as JSON object
|
|
1054
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
1055
|
+
|
|
1056
|
+
**Ref naming rules:** Lowercase alphanumeric with hyphens or forward slashes (e.g., `staging`, `prod/us-east`). No `.` or `..` segments.
|
|
1057
|
+
|
|
1058
|
+
**Ref values:** Must be valid contract hashes (`sha256:<64 hex chars>` or `sha256:empty`).
|
|
1059
|
+
|
|
1060
|
+
**Atomic writes:** `refs.json` is written atomically via temp file + rename to prevent corruption from concurrent writes.
|
|
1061
|
+
|
|
835
1062
|
## Architecture
|
|
836
1063
|
|
|
837
1064
|
```mermaid
|
|
838
1065
|
flowchart TD
|
|
839
1066
|
CLI[CLI Entry Point]
|
|
840
|
-
|
|
1067
|
+
CMD_EMIT[Emit Command]
|
|
1068
|
+
CMD_DB[DB Commands]
|
|
1069
|
+
CMD_MIG[Migration Commands]
|
|
841
1070
|
LOAD[TS Contract Loader]
|
|
842
1071
|
EMIT[Emitter]
|
|
1072
|
+
CTRL[Control Client]
|
|
1073
|
+
MIG_TOOLS["@prisma-next/migration-tools"]
|
|
843
1074
|
FS[File System]
|
|
844
1075
|
|
|
845
|
-
CLI -->
|
|
846
|
-
|
|
1076
|
+
CLI --> CMD_EMIT
|
|
1077
|
+
CLI --> CMD_DB
|
|
1078
|
+
CLI --> CMD_MIG
|
|
1079
|
+
CMD_EMIT --> LOAD
|
|
847
1080
|
LOAD --> EMIT
|
|
848
|
-
|
|
849
|
-
|
|
1081
|
+
CMD_DB --> CTRL
|
|
1082
|
+
CMD_MIG --> CTRL
|
|
1083
|
+
CMD_MIG --> MIG_TOOLS
|
|
1084
|
+
MIG_TOOLS --> FS
|
|
1085
|
+
CTRL --> FS
|
|
850
1086
|
```
|
|
851
1087
|
|
|
852
1088
|
## Config Validation and Normalization
|
|
@@ -868,38 +1104,39 @@ See `.cursor/rules/config-validation-and-normalization.mdc` for detailed pattern
|
|
|
868
1104
|
- Exit codes: 0 (success), 1 (runtime error), 2 (usage/config error)
|
|
869
1105
|
- **Error Handling**: Uses `exitOverride()` to catch unhandled errors (non-structured errors that fail fast) and print stack traces. Commands handle structured errors themselves via `process.exit()`.
|
|
870
1106
|
- **Command Taxonomy**: Groups commands by domain/plane (e.g., `contract emit`)
|
|
871
|
-
- **Help Formatting**: Uses `configureHelp()` to customize help output with styled format matching normal command output. Root help shows "prisma-next" title with command tree; command help shows "prisma-next <command> ➜ <description>" with options and docs URLs. See `utils/
|
|
1107
|
+
- **Help Formatting**: Uses `configureHelp()` to customize help output with styled format matching normal command output. Root help shows "prisma-next" title with command tree; command help shows "prisma-next <command> ➜ <description>" with options and docs URLs. See `utils/formatters/help.ts` for help formatters.
|
|
872
1108
|
- **Command Descriptions**: See the “Command Descriptions” section above for `setCommandDescriptions()` usage.
|
|
873
1109
|
|
|
874
1110
|
### Contract Emit Command (`commands/contract-emit.ts`)
|
|
875
1111
|
- Canonical command implementation using commander
|
|
876
|
-
- Supports global flags (JSON, verbosity, color,
|
|
877
|
-
- **Error Handling**: Uses structured errors (`CliStructuredError`), Result pattern
|
|
1112
|
+
- Supports global flags (JSON, verbosity, color, interactive, yes)
|
|
1113
|
+
- **Error Handling**: Uses structured errors (`CliStructuredError`), Result pattern, and `process.exit()`. Commands return `Result<T, CliStructuredError>`, process results with `handleResult()`, and call `process.exit(exitCode)` directly. See `.cursor/rules/cli-error-handling.mdc` for details.
|
|
878
1114
|
- Loads the user's config module (`prisma-next.config.ts`)
|
|
879
|
-
- Resolves contract from
|
|
880
|
-
-
|
|
881
|
-
-
|
|
1115
|
+
- Resolves contract from provider:
|
|
1116
|
+
- Calls `config.contract.source()` and expects `Result<Contract, ContractSourceDiagnostics>`
|
|
1117
|
+
- Source-specific parsing/loading stays inside providers
|
|
1118
|
+
- Provider diagnostics are surfaced as actionable CLI failures
|
|
882
1119
|
- Throws error if `config.contract` is missing
|
|
883
|
-
- Uses artifact
|
|
1120
|
+
- Uses artifact path from `config.contract.output` (already normalized by `defineConfig()` with defaults applied)
|
|
884
1121
|
- Creates family instance via `config.family.create()` (assembles operation registry, type imports, extension IDs)
|
|
885
1122
|
- Calls `familyInstance.emitContract()` with raw contract (instance handles stripping mappings and validation internally)
|
|
886
1123
|
- Outputs human-readable or JSON format based on flags
|
|
887
1124
|
|
|
888
1125
|
### Programmatic API (`api/emit-contract.ts`)
|
|
889
1126
|
- **`emitContract(options)`**: Programmatic API for emitting contracts
|
|
890
|
-
- Accepts resolved contract
|
|
1127
|
+
- Accepts resolved contract, output paths, and assembly data
|
|
891
1128
|
- Caller is responsible for loading the contract and resolving paths
|
|
892
1129
|
- Returns result with hashes, file paths, and timings
|
|
893
1130
|
- Used by CLI command internally
|
|
894
1131
|
|
|
895
1132
|
### Error Handling (`utils/errors.ts`, `utils/cli-errors.ts`, `utils/result.ts`, `utils/result-handler.ts`)
|
|
896
1133
|
- **Structured Errors**: Call sites throw `CliStructuredError` instances with full context (why, fix, docsUrl, etc.)
|
|
897
|
-
- **Result Pattern**: Commands
|
|
1134
|
+
- **Result Pattern**: Commands return `Result<T, CliStructuredError>` and use `handleResult()` for output and exit codes
|
|
898
1135
|
- **Error Conversion**: `CliStructuredError.toEnvelope()` converts errors to envelopes for output formatting
|
|
899
1136
|
- **Result Processing**: `handleResult()` processes Results, formats output, and returns exit codes
|
|
900
1137
|
- **Exit Codes**:
|
|
901
1138
|
- Usage/config errors (PN-CLI-4001-4007) → exit code 2
|
|
902
|
-
- Runtime errors (PN-
|
|
1139
|
+
- Runtime errors (PN-RUN-3xxx) → exit code 1
|
|
903
1140
|
- Success → exit code 0
|
|
904
1141
|
- **Fail Fast**: Non-structured errors propagate and are caught by Commander.js's `exitOverride()` with stack traces
|
|
905
1142
|
- See `.cursor/rules/cli-error-handling.mdc` for detailed patterns
|
|
@@ -909,7 +1146,7 @@ See `.cursor/rules/config-validation-and-normalization.mdc` for detailed pattern
|
|
|
909
1146
|
- **Removed**: `pack-assembly.ts` has been removed. Pack assembly is now handled by family instances. For SQL family, tests can import pack-based helpers directly from `packages/2-sql/3-tooling/family/src/core/assembly.ts` using relative paths.
|
|
910
1147
|
- Assembly logic is family-specific and owned by each family's instance implementation (e.g., `createSqlFamilyInstance` in `@prisma-next/family-sql`).
|
|
911
1148
|
|
|
912
|
-
### Output Formatting (`utils/
|
|
1149
|
+
### Output Formatting (`utils/formatters/`)
|
|
913
1150
|
- **Command Output Formatters**: Format human-readable output for commands (emit, verify, etc.)
|
|
914
1151
|
- Paths are shown as relative paths from current working directory (using `relative(process.cwd(), path)`)
|
|
915
1152
|
- Success indicators use consistent checkmark (✔) throughout
|
|
@@ -934,7 +1171,7 @@ See `.cursor/rules/config-validation-and-normalization.mdc` for detailed pattern
|
|
|
934
1171
|
- `create(options)` - Creates a family instance that implements domain actions
|
|
935
1172
|
- `hook` - Target family hook for contract emission
|
|
936
1173
|
- Family instances provide:
|
|
937
|
-
- `
|
|
1174
|
+
- `validateContract(contractJson)` - Validates and normalizes contract, returns `Contract` without mappings
|
|
938
1175
|
- `emitContract(options)` - Emits contract (handles stripping mappings and validation internally)
|
|
939
1176
|
- `verify(options)` - Verifies database marker against contract
|
|
940
1177
|
- `schemaVerify(options)` - Verifies database schema against contract
|
|
@@ -951,7 +1188,7 @@ See `.cursor/rules/config-validation-and-normalization.mdc` for detailed pattern
|
|
|
951
1188
|
- `types.storage`: Storage type bindings (`typeId`, `nativeType`, etc.) used in authoring/emission.
|
|
952
1189
|
- **`operations`**: Operation signatures the component contributes (extensions), used for type generation and (optionally) validation/lowering.
|
|
953
1190
|
- **Component-specific metadata**:
|
|
954
|
-
- Extensions may also include control-plane-only metadata like `databaseDependencies` (used by verify
|
|
1191
|
+
- Extensions may also include control-plane-only metadata like `databaseDependencies` (used by verify and schema verification flows and not required at runtime).
|
|
955
1192
|
|
|
956
1193
|
Unlike the older **manifest-based IR** approach (separate JSON manifests + a parsing/validation step to build an IR), descriptors are imported directly from packages (e.g., `@prisma-next/*/control`). This removes a file-format boundary and keeps the data and its types co-located.
|
|
957
1194
|
- Benefits: fewer moving parts (no JSON parsing), easier refactors (TypeScript catches drift), and clearer ownership (the package exports the canonical descriptor object).
|
|
@@ -1003,6 +1240,9 @@ export default defineConfig({
|
|
|
1003
1240
|
- **`commander`**: CLI argument parsing and command routing
|
|
1004
1241
|
- **`esbuild`**: Bundling TypeScript contract files with import allowlisting
|
|
1005
1242
|
- **`@prisma-next/emitter`**: Contract emission engine (returns strings)
|
|
1243
|
+
- **`@prisma-next/migration-tools`**: On-disk migration I/O, attestation, and history reconstruction
|
|
1244
|
+
- **`@prisma-next/framework-components`**: Control plane types, migration operation types, control stack (via `./control`)
|
|
1245
|
+
- **`@prisma-next/errors`**: Error types and factories (via `./control`)
|
|
1006
1246
|
|
|
1007
1247
|
## Design Decisions
|
|
1008
1248
|
|
|
@@ -1094,8 +1334,9 @@ try {
|
|
|
1094
1334
|
await client.connect(databaseUrl);
|
|
1095
1335
|
|
|
1096
1336
|
// Run operations
|
|
1097
|
-
const verifyResult = await client.verify({
|
|
1098
|
-
const initResult = await client.dbInit({
|
|
1337
|
+
const verifyResult = await client.verify({ contract });
|
|
1338
|
+
const initResult = await client.dbInit({ contract, mode: 'apply' });
|
|
1339
|
+
const updateResult = await client.dbUpdate({ contract, mode: 'apply' });
|
|
1099
1340
|
const introspectResult = await client.introspect();
|
|
1100
1341
|
} finally {
|
|
1101
1342
|
// Clean up
|
|
@@ -1109,20 +1350,26 @@ try {
|
|
|
1109
1350
|
|--------|-------------|
|
|
1110
1351
|
| `connect(url)` | Establishes database connection |
|
|
1111
1352
|
| `close()` | Closes connection (idempotent) |
|
|
1353
|
+
| `readMarker()` | Reads contract marker from database (null if none) |
|
|
1112
1354
|
| `verify(options)` | Verifies database marker matches contract |
|
|
1113
1355
|
| `schemaVerify(options)` | Verifies database schema satisfies contract |
|
|
1114
1356
|
| `sign(options)` | Writes contract marker to database |
|
|
1115
1357
|
| `dbInit(options)` | Initializes database schema from contract |
|
|
1358
|
+
| `dbUpdate(options)` | Updates database schema to match contract |
|
|
1359
|
+
| `migrationApply(options)` | Applies pre-planned migration edges to database |
|
|
1116
1360
|
| `introspect(options)` | Introspects database schema |
|
|
1117
1361
|
|
|
1118
1362
|
### Result Types
|
|
1119
1363
|
|
|
1120
1364
|
Operations return structured result types:
|
|
1121
1365
|
|
|
1366
|
+
- `readMarker()` → `ContractMarkerRecord | null`
|
|
1122
1367
|
- `verify()` → `VerifyDatabaseResult`
|
|
1123
1368
|
- `schemaVerify()` → `VerifyDatabaseSchemaResult`
|
|
1124
1369
|
- `sign()` → `SignDatabaseResult`
|
|
1125
1370
|
- `dbInit()` → `Result<DbInitSuccess, DbInitFailure>` (uses Result pattern)
|
|
1371
|
+
- `dbUpdate()` → `Result<DbUpdateSuccess, DbUpdateFailure>` (uses Result pattern)
|
|
1372
|
+
- `migrationApply()` → `Result<MigrationApplySuccess, MigrationApplyFailure>` (uses Result pattern)
|
|
1126
1373
|
- `introspect()` → Schema IR (family-specific)
|
|
1127
1374
|
|
|
1128
1375
|
### Error Handling
|
|
@@ -1137,7 +1384,7 @@ Operations return structured result types:
|
|
|
1137
1384
|
| Aspect | CLI | Control API |
|
|
1138
1385
|
|--------|-----|-------------|
|
|
1139
1386
|
| Config | Reads `prisma-next.config.ts` | Accepts descriptors directly |
|
|
1140
|
-
| File I/O | Reads contract.json from disk | Accepts contract
|
|
1387
|
+
| File I/O | Reads contract.json from disk | Accepts contract directly |
|
|
1141
1388
|
| Output | Formats for console | Returns structured data |
|
|
1142
1389
|
| Exit codes | Uses `process.exit()` | Returns results/throws |
|
|
1143
1390
|
|
|
@@ -1149,11 +1396,17 @@ The CLI package exports several subpaths for different use cases:
|
|
|
1149
1396
|
- **`@prisma-next/cli/config-types`**: Exports `defineConfig` and config types
|
|
1150
1397
|
- **`@prisma-next/cli/control-api`**: Exports `createControlClient` and control API types
|
|
1151
1398
|
- **`@prisma-next/cli/commands/db-init`**: Exports `createDbInitCommand`
|
|
1152
|
-
- **`@prisma-next/cli/commands/db-
|
|
1153
|
-
- **`@prisma-next/cli/commands/db-schema
|
|
1399
|
+
- **`@prisma-next/cli/commands/db-update`**: Exports `createDbUpdateCommand`
|
|
1400
|
+
- **`@prisma-next/cli/commands/db-schema`**: Exports `createDbSchemaCommand`
|
|
1154
1401
|
- **`@prisma-next/cli/commands/db-sign`**: Exports `createDbSignCommand`
|
|
1155
1402
|
- **`@prisma-next/cli/commands/db-verify`**: Exports `createDbVerifyCommand`
|
|
1156
1403
|
- **`@prisma-next/cli/commands/contract-emit`**: Exports `createContractEmitCommand`
|
|
1404
|
+
- **`@prisma-next/cli/commands/contract-infer`**: Exports `createContractInferCommand`
|
|
1405
|
+
- **`@prisma-next/cli/commands/migration-plan`**: Exports `createMigrationPlanCommand`
|
|
1406
|
+
- **`@prisma-next/cli/commands/migration-show`**: Exports `createMigrationShowCommand`
|
|
1407
|
+
- **`@prisma-next/cli/commands/migration-status`**: Exports `createMigrationStatusCommand`
|
|
1408
|
+
- **`@prisma-next/cli/commands/migration-apply`**: Exports `createMigrationApplyCommand`
|
|
1409
|
+
- **`@prisma-next/cli/commands/migration-verify`**: Exports `createMigrationVerifyCommand`
|
|
1157
1410
|
- **`@prisma-next/cli/config-loader`**: Exports `loadConfig` function
|
|
1158
1411
|
|
|
1159
1412
|
**Important**: `loadContractFromTs` is exported from the main package (`@prisma-next/cli`). See `.cursor/rules/cli-package-exports.mdc` for import patterns.
|