@prisma-next/cli 0.3.0-dev.6 → 0.3.0-dev.64
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 +314 -80
- package/dist/cli-errors-JlPTsazx.mjs +3 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.js +1 -2376
- package/dist/cli.mjs +203 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client-PimzSD1f.mjs +981 -0
- package/dist/client-PimzSD1f.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 +151 -0
- package/dist/commands/contract-emit.mjs.map +1 -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 +134 -0
- package/dist/commands/db-init.mjs.map +1 -0
- package/dist/commands/db-introspect.d.mts +7 -0
- package/dist/commands/db-introspect.d.mts.map +1 -0
- package/dist/commands/db-introspect.mjs +118 -0
- package/dist/commands/db-introspect.mjs.map +1 -0
- package/dist/commands/db-schema-verify.d.mts +7 -0
- package/dist/commands/db-schema-verify.d.mts.map +1 -0
- package/dist/commands/db-schema-verify.mjs +120 -0
- package/dist/commands/db-schema-verify.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 +142 -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 +133 -0
- package/dist/commands/db-verify.mjs.map +1 -0
- package/dist/commands/migration-apply.d.mts +23 -0
- package/dist/commands/migration-apply.d.mts.map +1 -0
- package/dist/commands/migration-apply.mjs +250 -0
- package/dist/commands/migration-apply.mjs.map +1 -0
- package/dist/commands/migration-plan.d.mts +25 -0
- package/dist/commands/migration-plan.d.mts.map +1 -0
- package/dist/commands/migration-plan.mjs +266 -0
- package/dist/commands/migration-plan.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 +138 -0
- package/dist/commands/migration-show.mjs.map +1 -0
- package/dist/commands/migration-status.d.mts +35 -0
- package/dist/commands/migration-status.d.mts.map +1 -0
- package/dist/commands/migration-status.mjs +260 -0
- package/dist/commands/migration-status.mjs.map +1 -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 +86 -0
- package/dist/commands/migration-verify.mjs.map +1 -0
- package/dist/config-loader-PPf4CtDj.mjs +43 -0
- package/dist/config-loader-PPf4CtDj.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/exports/config-types.d.mts +2 -0
- package/dist/exports/config-types.mjs +3 -0
- package/dist/exports/control-api.d.mts +621 -0
- package/dist/exports/control-api.d.mts.map +1 -0
- package/dist/exports/control-api.mjs +98 -0
- package/dist/exports/control-api.mjs.map +1 -0
- package/dist/{load-ts-contract.d.ts → exports/index.d.mts} +10 -5
- package/dist/exports/index.d.mts.map +1 -0
- package/dist/exports/index.mjs +135 -0
- package/dist/exports/index.mjs.map +1 -0
- package/dist/extract-sql-ddl-BmlKvk4o.mjs +26 -0
- package/dist/extract-sql-ddl-BmlKvk4o.mjs.map +1 -0
- package/dist/framework-components-CjV_jD8f.mjs +59 -0
- package/dist/framework-components-CjV_jD8f.mjs.map +1 -0
- package/dist/migration-command-scaffold-DfY_F3ev.mjs +97 -0
- package/dist/migration-command-scaffold-DfY_F3ev.mjs.map +1 -0
- package/dist/progress-adapter-DENrzF6I.mjs +49 -0
- package/dist/progress-adapter-DENrzF6I.mjs.map +1 -0
- package/dist/result-handler-iA9JtUC7.mjs +1186 -0
- package/dist/result-handler-iA9JtUC7.mjs.map +1 -0
- package/package.json +75 -38
- package/src/cli.ts +43 -0
- package/src/commands/contract-emit.ts +221 -111
- package/src/commands/db-init.ts +217 -426
- package/src/commands/db-introspect.ts +148 -185
- package/src/commands/db-schema-verify.ts +162 -149
- package/src/commands/db-sign.ts +215 -202
- package/src/commands/db-update.ts +220 -0
- package/src/commands/db-verify.ts +193 -156
- package/src/commands/migration-apply.ts +431 -0
- package/src/commands/migration-plan.ts +446 -0
- package/src/commands/migration-show.ts +255 -0
- package/src/commands/migration-status.ts +436 -0
- package/src/commands/migration-verify.ts +151 -0
- package/src/config-loader.ts +13 -3
- package/src/control-api/client.ts +605 -0
- package/src/control-api/errors.ts +9 -0
- package/src/control-api/operations/contract-emit.ts +161 -0
- package/src/control-api/operations/db-init.ts +286 -0
- package/src/control-api/operations/db-update.ts +221 -0
- package/src/control-api/operations/extract-sql-ddl.ts +47 -0
- package/src/control-api/operations/migration-apply.ts +195 -0
- package/src/control-api/operations/migration-helpers.ts +49 -0
- package/src/control-api/types.ts +687 -0
- package/src/exports/config-types.ts +3 -3
- package/src/exports/control-api.ts +53 -0
- package/src/load-ts-contract.ts +16 -11
- package/src/utils/cli-errors.ts +3 -1
- package/src/utils/command-helpers.ts +92 -3
- package/src/utils/framework-components.ts +11 -30
- package/src/utils/migration-command-scaffold.ts +190 -0
- package/src/utils/output.ts +363 -25
- package/src/utils/progress-adapter.ts +86 -0
- package/dist/chunk-464LNZCE.js +0 -134
- package/dist/chunk-464LNZCE.js.map +0 -1
- package/dist/chunk-BZMBKEEQ.js +0 -997
- package/dist/chunk-BZMBKEEQ.js.map +0 -1
- package/dist/chunk-HWYQOCAJ.js +0 -47
- package/dist/chunk-HWYQOCAJ.js.map +0 -1
- package/dist/chunk-ZKYEJROM.js +0 -94
- package/dist/chunk-ZKYEJROM.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 -9
- 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 -341
- 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 -190
- 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 -164
- 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 -199
- 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 -173
- 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/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/index.d.ts +0 -4
- package/dist/exports/index.d.ts.map +0 -1
- package/dist/exports/index.js +0 -175
- package/dist/exports/index.js.map +0 -1
- package/dist/load-ts-contract.d.ts.map +0 -1
- package/dist/utils/action.d.ts +0 -16
- package/dist/utils/action.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 -81
- 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/result-handler.d.ts +0 -15
- package/dist/utils/result-handler.d.ts.map +0 -1
- package/dist/utils/spinner.d.ts +0 -29
- package/dist/utils/spinner.d.ts.map +0 -1
- package/src/utils/action.ts +0 -43
- package/src/utils/spinner.ts +0 -67
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,9 +32,9 @@ 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
|
|
|
@@ -46,7 +47,7 @@ Commands use separate short and long descriptions via `setCommandDescriptions()`
|
|
|
46
47
|
- **Short description**: One-liner used in command trees and headers (e.g., "Emit signed contract artifacts")
|
|
47
48
|
- **Long description**: Multiline text shown at the bottom of help output with detailed context
|
|
48
49
|
|
|
49
|
-
See
|
|
50
|
+
See `src/utils/command-helpers.ts` for `setCommandDescriptions()` and `getLongDescription()`.
|
|
50
51
|
|
|
51
52
|
## Commands
|
|
52
53
|
|
|
@@ -61,12 +62,12 @@ prisma-next contract emit [--config <path>] [--json] [-v] [-q] [--timestamps] [-
|
|
|
61
62
|
|
|
62
63
|
**Config File Requirements:**
|
|
63
64
|
|
|
64
|
-
The `contract emit` command
|
|
65
|
+
The `contract emit` command does not require a `driver` in the config since it doesn't connect to a database:
|
|
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
|
-
import postgresDriver from '@prisma-next/driver-postgres/control';
|
|
70
71
|
import postgres from '@prisma-next/target-postgres/control';
|
|
71
72
|
import sql from '@prisma-next/family-sql/control';
|
|
72
73
|
import { contract } from './prisma/contract';
|
|
@@ -75,13 +76,8 @@ export default defineConfig({
|
|
|
75
76
|
family: sql,
|
|
76
77
|
target: postgres,
|
|
77
78
|
adapter: postgresAdapter,
|
|
78
|
-
driver: postgresDriver, // Required even though emit doesn't use it
|
|
79
79
|
extensionPacks: [],
|
|
80
|
-
contract:
|
|
81
|
-
source: contract,
|
|
82
|
-
output: 'src/prisma/contract.json',
|
|
83
|
-
types: 'src/prisma/contract.d.ts',
|
|
84
|
-
},
|
|
80
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
85
81
|
});
|
|
86
82
|
```
|
|
87
83
|
|
|
@@ -116,7 +112,7 @@ prisma-next db verify [--db <url>] [--config <path>] [--json] [-v] [-q] [--times
|
|
|
116
112
|
```
|
|
117
113
|
|
|
118
114
|
Options:
|
|
119
|
-
- `--db <url>`: Database connection string (optional; defaults to `config.db.
|
|
115
|
+
- `--db <url>`: Database connection string (optional; defaults to `config.db.connection` if set)
|
|
120
116
|
- `--config <path>`: Optional. Path to `prisma-next.config.ts` (defaults to `./prisma-next.config.ts` if present)
|
|
121
117
|
- `--json`: Output as JSON object
|
|
122
118
|
- `-q, --quiet`: Quiet mode (errors only)
|
|
@@ -146,6 +142,7 @@ The `db verify` command requires a `driver` in the config to connect to the data
|
|
|
146
142
|
|
|
147
143
|
```typescript
|
|
148
144
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
145
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
149
146
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
150
147
|
import postgresDriver from '@prisma-next/driver-postgres/control';
|
|
151
148
|
import postgres from '@prisma-next/target-postgres/control';
|
|
@@ -158,13 +155,9 @@ export default defineConfig({
|
|
|
158
155
|
adapter: postgresAdapter,
|
|
159
156
|
driver: postgresDriver,
|
|
160
157
|
extensionPacks: [],
|
|
161
|
-
contract:
|
|
162
|
-
source: contract,
|
|
163
|
-
output: 'src/prisma/contract.json',
|
|
164
|
-
types: 'src/prisma/contract.d.ts',
|
|
165
|
-
},
|
|
158
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
166
159
|
db: {
|
|
167
|
-
|
|
160
|
+
connection: process.env.DATABASE_URL, // Optional: can also use --db flag
|
|
168
161
|
},
|
|
169
162
|
});
|
|
170
163
|
```
|
|
@@ -173,12 +166,12 @@ export default defineConfig({
|
|
|
173
166
|
|
|
174
167
|
1. **Load Contract**: Reads the emitted `contract.json` from `config.contract.output`
|
|
175
168
|
2. **Connect to Database**: Uses `config.driver.create(url)` to create a driver
|
|
176
|
-
3. **Create Family Instance**:
|
|
169
|
+
3. **Create Family Instance**: Creates a `ControlPlaneStack` via `createControlPlaneStack()` and passes it to `config.family.create(stack)` to create a family instance
|
|
177
170
|
4. **Verify**: Calls `familyInstance.verify()` which:
|
|
178
171
|
- Reads the contract marker from the database
|
|
179
172
|
- Compares marker presence: Returns `PN-RTM-3001` if marker is missing
|
|
180
173
|
- Compares target compatibility: Returns `PN-RTM-3003` if contract target doesn't match config target
|
|
181
|
-
|
|
174
|
+
- Compares storage hash: Returns `PN-RTM-3002` if `storageHash` doesn't match
|
|
182
175
|
- Compares profile hash: Returns `PN-RTM-3002` if `profileHash` doesn't match (when present)
|
|
183
176
|
- Checks codec coverage (optional): Compares contract column types against supported codec types and reports missing codecs
|
|
184
177
|
|
|
@@ -187,7 +180,7 @@ export default defineConfig({
|
|
|
187
180
|
Success:
|
|
188
181
|
```
|
|
189
182
|
✔ Database matches contract
|
|
190
|
-
|
|
183
|
+
storageHash: sha256:abc123...
|
|
191
184
|
profileHash: sha256:def456...
|
|
192
185
|
```
|
|
193
186
|
|
|
@@ -205,11 +198,11 @@ Failure:
|
|
|
205
198
|
"ok": true,
|
|
206
199
|
"summary": "Database matches contract",
|
|
207
200
|
"contract": {
|
|
208
|
-
"
|
|
201
|
+
"storageHash": "sha256:abc123...",
|
|
209
202
|
"profileHash": "sha256:def456..."
|
|
210
203
|
},
|
|
211
204
|
"marker": {
|
|
212
|
-
"
|
|
205
|
+
"storageHash": "sha256:abc123...",
|
|
213
206
|
"profileHash": "sha256:def456..."
|
|
214
207
|
},
|
|
215
208
|
"target": {
|
|
@@ -235,16 +228,20 @@ Failure:
|
|
|
235
228
|
|
|
236
229
|
**Family Requirements:**
|
|
237
230
|
|
|
238
|
-
The family must provide a `create()` method in the family descriptor that returns a `ControlFamilyInstance` with a `verify()` method:
|
|
231
|
+
The family must provide a `create()` method in the family descriptor that accepts a `ControlPlaneStack` and returns a `ControlFamilyInstance` with a `verify()` method:
|
|
239
232
|
|
|
240
233
|
```typescript
|
|
241
|
-
interface ControlFamilyDescriptor {
|
|
242
|
-
create(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
234
|
+
interface ControlFamilyDescriptor<TFamilyId, TFamilyInstance> {
|
|
235
|
+
create<TTargetId extends string>(
|
|
236
|
+
stack: ControlPlaneStack<TFamilyId, TTargetId>,
|
|
237
|
+
): TFamilyInstance;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
interface ControlPlaneStack<TFamilyId, TTargetId> {
|
|
241
|
+
readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
|
|
242
|
+
readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
|
|
243
|
+
readonly driver: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;
|
|
244
|
+
readonly extensionPacks: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
|
|
248
245
|
}
|
|
249
246
|
|
|
250
247
|
interface ControlFamilyInstance {
|
|
@@ -258,6 +255,8 @@ interface ControlFamilyInstance {
|
|
|
258
255
|
}
|
|
259
256
|
```
|
|
260
257
|
|
|
258
|
+
Use `createControlPlaneStack()` from `@prisma-next/core-control-plane/stack` to create the stack with sensible defaults (`driver` defaults to `undefined`, `extensionPacks` defaults to `[]`).
|
|
259
|
+
|
|
261
260
|
The SQL family provides this via `@prisma-next/family-sql/control`. The `verify()` method handles reading the marker, comparing hashes, and checking codec coverage internally.
|
|
262
261
|
|
|
263
262
|
### `prisma-next db introspect`
|
|
@@ -270,7 +269,7 @@ prisma-next db introspect [--db <url>] [--config <path>] [--json] [-v] [-q] [--t
|
|
|
270
269
|
```
|
|
271
270
|
|
|
272
271
|
Options:
|
|
273
|
-
- `--db <url>`: Database connection string (optional; defaults to `config.db.
|
|
272
|
+
- `--db <url>`: Database connection string (optional; defaults to `config.db.connection` if set)
|
|
274
273
|
- `--config <path>`: Optional. Path to `prisma-next.config.ts` (defaults to `./prisma-next.config.ts` if present)
|
|
275
274
|
- `--json`: Output as JSON object
|
|
276
275
|
- `-q, --quiet`: Quiet mode (errors only)
|
|
@@ -300,6 +299,7 @@ The `db introspect` command requires a `driver` in the config to connect to the
|
|
|
300
299
|
|
|
301
300
|
```typescript
|
|
302
301
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
302
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
303
303
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
304
304
|
import postgresDriver from '@prisma-next/driver-postgres/control';
|
|
305
305
|
import postgres from '@prisma-next/target-postgres/control';
|
|
@@ -312,7 +312,7 @@ export default defineConfig({
|
|
|
312
312
|
driver: postgresDriver,
|
|
313
313
|
extensionPacks: [],
|
|
314
314
|
db: {
|
|
315
|
-
|
|
315
|
+
connection: process.env.DATABASE_URL, // Optional: can also use --db flag
|
|
316
316
|
},
|
|
317
317
|
});
|
|
318
318
|
```
|
|
@@ -320,7 +320,7 @@ export default defineConfig({
|
|
|
320
320
|
**Introspection Process:**
|
|
321
321
|
|
|
322
322
|
1. **Connect to Database**: Uses `config.driver.create(url)` to create a driver
|
|
323
|
-
2. **Create Family Instance**:
|
|
323
|
+
2. **Create Family Instance**: Creates a `ControlPlaneStack` via `createControlPlaneStack()` and passes it to `config.family.create(stack)` to create a family instance
|
|
324
324
|
3. **Introspect**: Calls `familyInstance.introspect()` which:
|
|
325
325
|
- Queries the database catalog to discover schema structure
|
|
326
326
|
- Returns a family-specific schema IR (e.g., `SqlSchemaIR` for SQL family)
|
|
@@ -387,7 +387,7 @@ sql schema (tables: 2)
|
|
|
387
387
|
|
|
388
388
|
**Error Codes:**
|
|
389
389
|
- `PN-CLI-4010`: Missing driver in config — provide a driver descriptor
|
|
390
|
-
- `PN-CLI-4005`: Missing database
|
|
390
|
+
- `PN-CLI-4005`: Missing database connection — provide `--db <url>` or set `db.connection` in config
|
|
391
391
|
|
|
392
392
|
**Family Requirements:**
|
|
393
393
|
|
|
@@ -421,7 +421,7 @@ prisma-next db sign [--db <url>] [--config <path>] [--json] [-v] [-q] [--timesta
|
|
|
421
421
|
```
|
|
422
422
|
|
|
423
423
|
Options:
|
|
424
|
-
- `--db <url>`: Database connection string (optional; defaults to `config.db.
|
|
424
|
+
- `--db <url>`: Database connection string (optional; defaults to `config.db.connection` if set)
|
|
425
425
|
- `--config <path>`: Optional. Path to `prisma-next.config.ts` (defaults to `./prisma-next.config.ts` if present)
|
|
426
426
|
- `--json`: Output as JSON object
|
|
427
427
|
- `-q, --quiet`: Quiet mode (errors only)
|
|
@@ -463,13 +463,9 @@ export default defineConfig({
|
|
|
463
463
|
adapter: postgresAdapter,
|
|
464
464
|
driver: postgresDriver,
|
|
465
465
|
extensionPacks: [],
|
|
466
|
-
contract:
|
|
467
|
-
source: contract,
|
|
468
|
-
output: 'src/prisma/contract.json',
|
|
469
|
-
types: 'src/prisma/contract.d.ts',
|
|
470
|
-
},
|
|
466
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
471
467
|
db: {
|
|
472
|
-
|
|
468
|
+
connection: process.env.DATABASE_URL, // Optional: can also use --db flag
|
|
473
469
|
},
|
|
474
470
|
});
|
|
475
471
|
```
|
|
@@ -478,7 +474,7 @@ export default defineConfig({
|
|
|
478
474
|
|
|
479
475
|
1. **Load Contract**: Reads the emitted `contract.json` from `config.contract.output`
|
|
480
476
|
2. **Connect to Database**: Uses `config.driver.create(url)` to create a driver
|
|
481
|
-
3. **Create Family Instance**:
|
|
477
|
+
3. **Create Family Instance**: Creates a `ControlPlaneStack` via `createControlPlaneStack()` and passes it to `config.family.create(stack)` to create a family instance
|
|
482
478
|
4. **Schema Verification (Precondition)**: Calls `familyInstance.schemaVerify()` to verify the database schema matches the contract:
|
|
483
479
|
- If verification fails: Prints schema verification output and exits with code 1 (marker is not written)
|
|
484
480
|
- If verification passes: Proceeds to marker signing
|
|
@@ -495,7 +491,7 @@ export default defineConfig({
|
|
|
495
491
|
Success (new marker):
|
|
496
492
|
```
|
|
497
493
|
✔ Database signed (marker created)
|
|
498
|
-
|
|
494
|
+
storageHash: sha256:abc123...
|
|
499
495
|
profileHash: sha256:def456...
|
|
500
496
|
Total time: 42ms
|
|
501
497
|
```
|
|
@@ -503,16 +499,16 @@ Success (new marker):
|
|
|
503
499
|
Success (updated marker):
|
|
504
500
|
```
|
|
505
501
|
✔ Database signed (marker updated from sha256:old-hash)
|
|
506
|
-
|
|
502
|
+
storageHash: sha256:abc123...
|
|
507
503
|
profileHash: sha256:def456...
|
|
508
|
-
previous
|
|
504
|
+
previous storageHash: sha256:old-hash
|
|
509
505
|
Total time: 42ms
|
|
510
506
|
```
|
|
511
507
|
|
|
512
508
|
Success (already up-to-date):
|
|
513
509
|
```
|
|
514
510
|
✔ Database already signed with this contract
|
|
515
|
-
|
|
511
|
+
storageHash: sha256:abc123...
|
|
516
512
|
profileHash: sha256:def456...
|
|
517
513
|
Total time: 42ms
|
|
518
514
|
```
|
|
@@ -530,7 +526,7 @@ Failure (schema mismatch):
|
|
|
530
526
|
"ok": true,
|
|
531
527
|
"summary": "Database signed (marker created)",
|
|
532
528
|
"contract": {
|
|
533
|
-
"
|
|
529
|
+
"storageHash": "sha256:abc123...",
|
|
534
530
|
"profileHash": "sha256:def456..."
|
|
535
531
|
},
|
|
536
532
|
"target": {
|
|
@@ -557,7 +553,7 @@ For updated markers:
|
|
|
557
553
|
"ok": true,
|
|
558
554
|
"summary": "Database signed (marker updated from sha256:old-hash)",
|
|
559
555
|
"contract": {
|
|
560
|
-
"
|
|
556
|
+
"storageHash": "sha256:abc123...",
|
|
561
557
|
"profileHash": "sha256:def456..."
|
|
562
558
|
},
|
|
563
559
|
"target": {
|
|
@@ -568,7 +564,7 @@ For updated markers:
|
|
|
568
564
|
"created": false,
|
|
569
565
|
"updated": true,
|
|
570
566
|
"previous": {
|
|
571
|
-
"
|
|
567
|
+
"storageHash": "sha256:old-hash",
|
|
572
568
|
"profileHash": "sha256:old-profile-hash"
|
|
573
569
|
}
|
|
574
570
|
},
|
|
@@ -584,7 +580,7 @@ For updated markers:
|
|
|
584
580
|
|
|
585
581
|
**Error Codes:**
|
|
586
582
|
- `PN-CLI-4010`: Missing driver in config — provide a driver descriptor
|
|
587
|
-
- `PN-CLI-4005`: Missing database
|
|
583
|
+
- `PN-CLI-4005`: Missing database connection — provide `--db <url>` or set `db.connection` in config
|
|
588
584
|
- Exit code 1: Schema verification failed — database schema does not match contract (marker is not written)
|
|
589
585
|
|
|
590
586
|
**Relationship to Other Commands:**
|
|
@@ -631,7 +627,7 @@ prisma-next db init [--db <url>] [--config <path>] [--plan] [--json] [-v] [-q] [
|
|
|
631
627
|
```
|
|
632
628
|
|
|
633
629
|
Options:
|
|
634
|
-
- `--db <url>`: Database connection string (optional; defaults to `config.db.
|
|
630
|
+
- `--db <url>`: Database connection string (optional; defaults to `config.db.connection` if set)
|
|
635
631
|
- `--config <path>`: Optional. Path to `prisma-next.config.ts` (defaults to `./prisma-next.config.ts` if present)
|
|
636
632
|
- `--plan`: Only show the migration plan, do not apply it
|
|
637
633
|
- `--json [format]`: Output as JSON (`object` only; `ndjson` is not supported for this command)
|
|
@@ -662,6 +658,7 @@ The `db init` command requires a `driver` in the config to connect to the databa
|
|
|
662
658
|
|
|
663
659
|
```typescript
|
|
664
660
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
661
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
665
662
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
666
663
|
import postgresDriver from '@prisma-next/driver-postgres/control';
|
|
667
664
|
import postgres from '@prisma-next/target-postgres/control';
|
|
@@ -674,13 +671,9 @@ export default defineConfig({
|
|
|
674
671
|
adapter: postgresAdapter,
|
|
675
672
|
driver: postgresDriver,
|
|
676
673
|
extensionPacks: [],
|
|
677
|
-
contract:
|
|
678
|
-
source: contract,
|
|
679
|
-
output: 'src/prisma/contract.json',
|
|
680
|
-
types: 'src/prisma/contract.d.ts',
|
|
681
|
-
},
|
|
674
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
682
675
|
db: {
|
|
683
|
-
|
|
676
|
+
connection: process.env.DATABASE_URL, // Optional: can also use --db flag
|
|
684
677
|
},
|
|
685
678
|
});
|
|
686
679
|
```
|
|
@@ -689,7 +682,7 @@ export default defineConfig({
|
|
|
689
682
|
|
|
690
683
|
1. **Load Contract**: Reads the emitted `contract.json` from `config.contract.output`
|
|
691
684
|
2. **Connect to Database**: Uses `config.driver.create(url)` to create a driver
|
|
692
|
-
3. **Create Family Instance**:
|
|
685
|
+
3. **Create Family Instance**: Creates a `ControlPlaneStack` via `createControlPlaneStack()` and passes it to `config.family.create(stack)` to create a family instance
|
|
693
686
|
4. **Introspect Schema**: Calls `familyInstance.introspect()` to get the current database schema IR
|
|
694
687
|
5. **Validate wiring**: Ensures the contract is compatible with the CLI config:
|
|
695
688
|
- `contract.targetFamily` matches `config.family.familyId`
|
|
@@ -750,7 +743,7 @@ Applying migration plan and verifying schema...
|
|
|
750
743
|
"plan": {
|
|
751
744
|
"targetId": "postgres",
|
|
752
745
|
"destination": {
|
|
753
|
-
"
|
|
746
|
+
"storageHash": "sha256:abc123..."
|
|
754
747
|
},
|
|
755
748
|
"operations": [
|
|
756
749
|
{
|
|
@@ -765,7 +758,7 @@ Applying migration plan and verifying schema...
|
|
|
765
758
|
"operationsExecuted": 4
|
|
766
759
|
},
|
|
767
760
|
"marker": {
|
|
768
|
-
"
|
|
761
|
+
"storageHash": "sha256:abc123..."
|
|
769
762
|
}
|
|
770
763
|
}
|
|
771
764
|
```
|
|
@@ -784,6 +777,25 @@ Applying migration plan and verifying schema...
|
|
|
784
777
|
- If the database already has a marker that matches the destination contract, `db init` succeeds as a noop (0 operations planned/executed).
|
|
785
778
|
- If the database has a marker that does **not** match the destination contract, `db init` fails (including in `--plan` mode). Use `db init` for bootstrapping; use your migration workflow to reconcile existing databases.
|
|
786
779
|
|
|
780
|
+
### `prisma-next db update`
|
|
781
|
+
|
|
782
|
+
Update your database schema to match the currently emitted contract.
|
|
783
|
+
|
|
784
|
+
`db update` differs from `db init`:
|
|
785
|
+
|
|
786
|
+
- Works on any database, whether or not it has been initialized with `db init` (creates the signature table if missing)
|
|
787
|
+
- Allows `additive`, `widening`, and `destructive` operation classes where supported by planner/runner
|
|
788
|
+
- Disables per-operation runner execution checks by default (precheck/postcheck/idempotency)
|
|
789
|
+
- In `--plan` mode for SQL targets, prints a DDL preview derived from planned operations
|
|
790
|
+
|
|
791
|
+
**Command:**
|
|
792
|
+
```bash
|
|
793
|
+
prisma-next db update [--db <url>] [--config <path>] [--plan] [--json] [-v] [-q] [--timestamps] [--color/--no-color]
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
**Error codes (additional to shared CLI/runtime codes):**
|
|
797
|
+
- `RUNNER_FAILED`: runner rejected apply (origin mismatch, failed checks, policy failures, or execution errors)
|
|
798
|
+
|
|
787
799
|
**Config File (`prisma-next.config.ts`):**
|
|
788
800
|
|
|
789
801
|
The CLI uses a config file to specify the target family, target, adapter, extensionPacks, and contract.
|
|
@@ -797,6 +809,7 @@ The CLI uses a config file to specify the target family, target, adapter, extens
|
|
|
797
809
|
|
|
798
810
|
```typescript
|
|
799
811
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
812
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
800
813
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
801
814
|
import postgres from '@prisma-next/target-postgres/control';
|
|
802
815
|
import sql from '@prisma-next/family-sql/control';
|
|
@@ -807,42 +820,167 @@ export default defineConfig({
|
|
|
807
820
|
target: postgres,
|
|
808
821
|
adapter: postgresAdapter,
|
|
809
822
|
extensionPacks: [],
|
|
810
|
-
contract:
|
|
811
|
-
source: contract, // Can be a value or a function: () => import('./contract').then(m => m.contract)
|
|
812
|
-
output: 'src/prisma/contract.json', // Optional: defaults to 'src/prisma/contract.json'
|
|
813
|
-
types: 'src/prisma/contract.d.ts', // Optional: defaults to output with .d.ts extension
|
|
814
|
-
},
|
|
823
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
815
824
|
});
|
|
816
825
|
```
|
|
817
826
|
|
|
818
|
-
|
|
819
|
-
-
|
|
820
|
-
-
|
|
821
|
-
-
|
|
827
|
+
Prefer helper utilities for authoring mode selection:
|
|
828
|
+
- `typescriptContract(contractIR, outputPath?)` from `@prisma-next/sql-contract-ts/config-types` for TS-authored contracts
|
|
829
|
+
- `prismaContract(schemaPath, { output?, target? })` from `@prisma-next/sql-contract-psl/provider` for PSL-authored providers
|
|
830
|
+
- Provider failures are returned as structured diagnostics for CLI rendering
|
|
822
831
|
|
|
823
832
|
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.
|
|
824
833
|
|
|
825
|
-
|
|
834
|
+
`contract.d.ts` is always colocated with `contract.json` and derived from `contract.output` (`contract.json` → `contract.d.ts`).
|
|
826
835
|
|
|
827
836
|
**Output:**
|
|
828
837
|
- `contract.json`: Includes `_generated` metadata field indicating it's a generated artifact (excluded from canonicalization/hashing)
|
|
829
838
|
- `contract.d.ts`: Includes warning header comments indicating it's a generated file
|
|
830
839
|
|
|
840
|
+
### `prisma-next migration plan`
|
|
841
|
+
|
|
842
|
+
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.
|
|
843
|
+
|
|
844
|
+
```bash
|
|
845
|
+
prisma-next migration plan [--config <path>] [--name <slug>] [--from <hash>] [--json] [-v] [-q] [--timestamps] [--color/--no-color]
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
**Options:**
|
|
849
|
+
- `--config <path>`: Path to `prisma-next.config.ts`
|
|
850
|
+
- `--name <slug>`: Name slug for the migration directory (default: `migration`)
|
|
851
|
+
- `--from <hash>`: Explicit starting contract hash (overrides latest chain leaf detection)
|
|
852
|
+
- `--json`: Output as JSON object
|
|
853
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
854
|
+
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
855
|
+
- `--timestamps`: Add timestamps to output
|
|
856
|
+
|
|
857
|
+
**What it does:**
|
|
858
|
+
1. Loads config and reads `contract.json` (the "to" contract)
|
|
859
|
+
2. Reads existing migrations from `config.migrations.dir` (default: `migrations/`)
|
|
860
|
+
3. Reconstructs the migration chain and finds the leaf (current state)
|
|
861
|
+
4. Diffs the leaf contract against the new contract using the target's migration planner (same planner as `db init`)
|
|
862
|
+
5. Writes a new migration package (`migration.json` + `ops.json`) and attests the `migrationId`
|
|
863
|
+
|
|
864
|
+
### `prisma-next migration show`
|
|
865
|
+
|
|
866
|
+
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.
|
|
867
|
+
|
|
868
|
+
```bash
|
|
869
|
+
prisma-next migration show [target] [--config <path>] [--json] [-v] [-q] [--timestamps] [--color/--no-color]
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
**Options:**
|
|
873
|
+
- `[target]`: Migration directory path or migrationId hash prefix (defaults to latest)
|
|
874
|
+
- `--config <path>`: Path to `prisma-next.config.ts`
|
|
875
|
+
- `--json`: Output as JSON object
|
|
876
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
877
|
+
- `-v, --verbose`: Verbose output
|
|
878
|
+
- `--timestamps`: Add timestamps to output
|
|
879
|
+
|
|
880
|
+
**What it does:**
|
|
881
|
+
1. If `target` is a path (contains `/` or `\`), reads that directory directly
|
|
882
|
+
2. If `target` is a hash prefix, scans all attested migrations and matches against `migrationId`
|
|
883
|
+
3. If no target, defaults to the latest migration (chain leaf)
|
|
884
|
+
4. Displays operations with operation class badges, destructive warnings, and DDL preview
|
|
885
|
+
|
|
886
|
+
**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.
|
|
887
|
+
|
|
888
|
+
### `prisma-next migration status`
|
|
889
|
+
|
|
890
|
+
Show the migration graph and applied status. Adapts based on context:
|
|
891
|
+
|
|
892
|
+
- **With DB connection**: Shows applied/pending markers and "you are here" indicators
|
|
893
|
+
- **Without DB connection**: Shows the graph structure from disk only
|
|
894
|
+
|
|
895
|
+
```bash
|
|
896
|
+
prisma-next migration status [--db <url>] [--config <path>] [--json] [-v] [-q] [--timestamps] [--color/--no-color]
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
**Options:**
|
|
900
|
+
- `--db <url>`: Database connection string (enables online mode)
|
|
901
|
+
- `--config <path>`: Path to `prisma-next.config.ts`
|
|
902
|
+
- `--json`: Output as JSON object
|
|
903
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
904
|
+
- `-v, --verbose`: Verbose output
|
|
905
|
+
- `--timestamps`: Add timestamps to output
|
|
906
|
+
|
|
907
|
+
**What it does:**
|
|
908
|
+
1. Reads migration packages from disk and reconstructs the chain
|
|
909
|
+
2. If a DB connection is available, reads the marker to determine applied/pending status
|
|
910
|
+
3. Displays the graph as a linear chain with `◄ DB` and `◄ Contract` markers
|
|
911
|
+
4. Shows operation summaries with destructive operation highlighting
|
|
912
|
+
5. Falls back to offline mode if DB connection fails
|
|
913
|
+
|
|
914
|
+
**Known limitation:** Branched migration graphs (multiple leaves) produce an error. Only linear chains are visualized.
|
|
915
|
+
|
|
916
|
+
### `prisma-next migration apply`
|
|
917
|
+
|
|
918
|
+
Apply planned migrations to the database. Executes previously planned migrations (created by `migration plan`). Compares the database marker against the migration chain 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.
|
|
919
|
+
|
|
920
|
+
```bash
|
|
921
|
+
prisma-next migration apply [--db <url>] [--config <path>] [--json] [-v] [-q] [--timestamps] [--color/--no-color]
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
**Options:**
|
|
925
|
+
- `--db <url>`: Database connection string (optional; defaults to `config.db.connection`)
|
|
926
|
+
- `--config <path>`: Path to `prisma-next.config.ts`
|
|
927
|
+
- `--json`: Output as JSON object
|
|
928
|
+
- `-q, --quiet`: Quiet mode (errors only)
|
|
929
|
+
- `-v, --verbose`: Verbose output (debug info, timings)
|
|
930
|
+
- `--timestamps`: Add timestamps to output
|
|
931
|
+
|
|
932
|
+
**What it does:**
|
|
933
|
+
1. Reads attested migration packages from `config.migrations.dir`
|
|
934
|
+
2. Reconstructs the migration chain (skips drafts with `migrationId: null`)
|
|
935
|
+
3. Reads the current contract hash from `contract.json`
|
|
936
|
+
4. Connects to the database and reads the current marker hash
|
|
937
|
+
5. Finds the path from the marker hash to the current contract hash
|
|
938
|
+
6. Executes each pending migration in order using the target's `MigrationRunner`
|
|
939
|
+
7. Each migration runs in its own transaction with prechecks, postchecks, and idempotency checks enabled
|
|
940
|
+
8. After each migration, the runner verifies the schema and updates the marker/ledger
|
|
941
|
+
|
|
942
|
+
**Config requirements:** Requires `driver` and `db.connection` (or `--db`). `migrations.dir` is optional and defaults to `migrations/`.
|
|
943
|
+
|
|
944
|
+
**Resume semantics:** If a migration fails, previously applied migrations are preserved. Re-running `migration apply` resumes from the last successful migration.
|
|
945
|
+
|
|
946
|
+
**Planning requirement:** `migration apply` now requires the current contract hash to exist in attested on-disk migrations. If the contract has changed and no migration was planned, apply exits with an error and asks you to run `migration plan`.
|
|
947
|
+
|
|
948
|
+
### `prisma-next migration verify`
|
|
949
|
+
|
|
950
|
+
Verify a migration package's integrity by recomputing the content-addressed `migrationId`.
|
|
951
|
+
|
|
952
|
+
```bash
|
|
953
|
+
prisma-next migration verify --dir <path>
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
- **Verified**: stored `migrationId` matches recomputed value
|
|
957
|
+
- **Draft**: `migrationId` is null — automatically attests the package
|
|
958
|
+
- **Mismatch**: package has been modified since attestation (command exits non-zero)
|
|
959
|
+
|
|
831
960
|
## Architecture
|
|
832
961
|
|
|
833
962
|
```mermaid
|
|
834
963
|
flowchart TD
|
|
835
964
|
CLI[CLI Entry Point]
|
|
836
|
-
|
|
965
|
+
CMD_EMIT[Emit Command]
|
|
966
|
+
CMD_DB[DB Commands]
|
|
967
|
+
CMD_MIG[Migration Commands]
|
|
837
968
|
LOAD[TS Contract Loader]
|
|
838
969
|
EMIT[Emitter]
|
|
970
|
+
CTRL[Control Client]
|
|
971
|
+
MIG_TOOLS["@prisma-next/migration-tools"]
|
|
839
972
|
FS[File System]
|
|
840
973
|
|
|
841
|
-
CLI -->
|
|
842
|
-
|
|
974
|
+
CLI --> CMD_EMIT
|
|
975
|
+
CLI --> CMD_DB
|
|
976
|
+
CLI --> CMD_MIG
|
|
977
|
+
CMD_EMIT --> LOAD
|
|
843
978
|
LOAD --> EMIT
|
|
844
|
-
|
|
845
|
-
|
|
979
|
+
CMD_DB --> CTRL
|
|
980
|
+
CMD_MIG --> CTRL
|
|
981
|
+
CMD_MIG --> MIG_TOOLS
|
|
982
|
+
MIG_TOOLS --> FS
|
|
983
|
+
CTRL --> FS
|
|
846
984
|
```
|
|
847
985
|
|
|
848
986
|
## Config Validation and Normalization
|
|
@@ -865,18 +1003,19 @@ See `.cursor/rules/config-validation-and-normalization.mdc` for detailed pattern
|
|
|
865
1003
|
- **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()`.
|
|
866
1004
|
- **Command Taxonomy**: Groups commands by domain/plane (e.g., `contract emit`)
|
|
867
1005
|
- **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/output.ts` for help formatters.
|
|
868
|
-
- **Command Descriptions**:
|
|
1006
|
+
- **Command Descriptions**: See the “Command Descriptions” section above for `setCommandDescriptions()` usage.
|
|
869
1007
|
|
|
870
1008
|
### Contract Emit Command (`commands/contract-emit.ts`)
|
|
871
1009
|
- Canonical command implementation using commander
|
|
872
1010
|
- Supports global flags (JSON, verbosity, color, timestamps)
|
|
873
1011
|
- **Error Handling**: Uses structured errors (`CliStructuredError`), Result pattern (`performAction`), and `process.exit()`. Commands wrap logic in `performAction()`, process results with `handleResult()`, and call `process.exit(exitCode)` directly. See `.cursor/rules/cli-error-handling.mdc` for details.
|
|
874
1012
|
- Loads the user's config module (`prisma-next.config.ts`)
|
|
875
|
-
- Resolves contract from
|
|
876
|
-
-
|
|
877
|
-
-
|
|
1013
|
+
- Resolves contract from provider:
|
|
1014
|
+
- Calls `config.contract.source()` and expects `Result<ContractIR, Diagnostics>`
|
|
1015
|
+
- Source-specific parsing/loading stays inside providers
|
|
1016
|
+
- Provider diagnostics are surfaced as actionable CLI failures
|
|
878
1017
|
- Throws error if `config.contract` is missing
|
|
879
|
-
- Uses artifact
|
|
1018
|
+
- Uses artifact path from `config.contract.output` (already normalized by `defineConfig()` with defaults applied)
|
|
880
1019
|
- Creates family instance via `config.family.create()` (assembles operation registry, type imports, extension IDs)
|
|
881
1020
|
- Calls `familyInstance.emitContract()` with raw contract (instance handles stripping mappings and validation internally)
|
|
882
1021
|
- Outputs human-readable or JSON format based on flags
|
|
@@ -999,6 +1138,8 @@ export default defineConfig({
|
|
|
999
1138
|
- **`commander`**: CLI argument parsing and command routing
|
|
1000
1139
|
- **`esbuild`**: Bundling TypeScript contract files with import allowlisting
|
|
1001
1140
|
- **`@prisma-next/emitter`**: Contract emission engine (returns strings)
|
|
1141
|
+
- **`@prisma-next/migration-tools`**: On-disk migration I/O, attestation, and chain reconstruction
|
|
1142
|
+
- **`@prisma-next/core-control-plane`**: Config types, migration operation types, error types, control plane stack
|
|
1002
1143
|
|
|
1003
1144
|
## Design Decisions
|
|
1004
1145
|
|
|
@@ -1058,18 +1199,111 @@ pnpm test:integration # Run integration tests only
|
|
|
1058
1199
|
pnpm test:e2e # Run e2e tests only
|
|
1059
1200
|
```
|
|
1060
1201
|
|
|
1202
|
+
## Programmatic Control API
|
|
1203
|
+
|
|
1204
|
+
The CLI package provides a programmatic control client for running control-plane operations without using the command line. This is useful for:
|
|
1205
|
+
|
|
1206
|
+
- Integration with build tools and CI pipelines
|
|
1207
|
+
- Custom orchestration workflows
|
|
1208
|
+
- Test automation
|
|
1209
|
+
- Programmatic database management
|
|
1210
|
+
|
|
1211
|
+
### Basic Usage
|
|
1212
|
+
|
|
1213
|
+
```typescript
|
|
1214
|
+
import { createControlClient } from '@prisma-next/cli/control-api';
|
|
1215
|
+
import sql from '@prisma-next/family-sql/control';
|
|
1216
|
+
import postgres from '@prisma-next/target-postgres/control';
|
|
1217
|
+
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
1218
|
+
import postgresDriver from '@prisma-next/driver-postgres/control';
|
|
1219
|
+
|
|
1220
|
+
// Create a control client with framework component descriptors
|
|
1221
|
+
const client = createControlClient({
|
|
1222
|
+
family: sql,
|
|
1223
|
+
target: postgres,
|
|
1224
|
+
adapter: postgresAdapter,
|
|
1225
|
+
driver: postgresDriver,
|
|
1226
|
+
extensionPacks: [],
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
try {
|
|
1230
|
+
// Connect to database
|
|
1231
|
+
await client.connect(databaseUrl);
|
|
1232
|
+
|
|
1233
|
+
// Run operations
|
|
1234
|
+
const verifyResult = await client.verify({ contractIR });
|
|
1235
|
+
const initResult = await client.dbInit({ contractIR, mode: 'apply' });
|
|
1236
|
+
const updateResult = await client.dbUpdate({ contractIR, mode: 'apply' });
|
|
1237
|
+
const introspectResult = await client.introspect();
|
|
1238
|
+
} finally {
|
|
1239
|
+
// Clean up
|
|
1240
|
+
await client.close();
|
|
1241
|
+
}
|
|
1242
|
+
```
|
|
1243
|
+
|
|
1244
|
+
### Available Operations
|
|
1245
|
+
|
|
1246
|
+
| Method | Description |
|
|
1247
|
+
|--------|-------------|
|
|
1248
|
+
| `connect(url)` | Establishes database connection |
|
|
1249
|
+
| `close()` | Closes connection (idempotent) |
|
|
1250
|
+
| `readMarker()` | Reads contract marker from database (null if none) |
|
|
1251
|
+
| `verify(options)` | Verifies database marker matches contract |
|
|
1252
|
+
| `schemaVerify(options)` | Verifies database schema satisfies contract |
|
|
1253
|
+
| `sign(options)` | Writes contract marker to database |
|
|
1254
|
+
| `dbInit(options)` | Initializes database schema from contract |
|
|
1255
|
+
| `dbUpdate(options)` | Updates database schema to match contract |
|
|
1256
|
+
| `migrationApply(options)` | Applies pre-planned migration edges to database |
|
|
1257
|
+
| `introspect(options)` | Introspects database schema |
|
|
1258
|
+
|
|
1259
|
+
### Result Types
|
|
1260
|
+
|
|
1261
|
+
Operations return structured result types:
|
|
1262
|
+
|
|
1263
|
+
- `readMarker()` → `ContractMarkerRecord | null`
|
|
1264
|
+
- `verify()` → `VerifyDatabaseResult`
|
|
1265
|
+
- `schemaVerify()` → `VerifyDatabaseSchemaResult`
|
|
1266
|
+
- `sign()` → `SignDatabaseResult`
|
|
1267
|
+
- `dbInit()` → `Result<DbInitSuccess, DbInitFailure>` (uses Result pattern)
|
|
1268
|
+
- `dbUpdate()` → `Result<DbUpdateSuccess, DbUpdateFailure>` (uses Result pattern)
|
|
1269
|
+
- `migrationApply()` → `Result<MigrationApplySuccess, MigrationApplyFailure>` (uses Result pattern)
|
|
1270
|
+
- `introspect()` → Schema IR (family-specific)
|
|
1271
|
+
|
|
1272
|
+
### Error Handling
|
|
1273
|
+
|
|
1274
|
+
- **Connection errors**: Thrown as exceptions from `connect()`
|
|
1275
|
+
- **Not connected errors**: Thrown if operations called before `connect()`
|
|
1276
|
+
- **Driver not configured**: Thrown if driver is not provided in options
|
|
1277
|
+
- **Operation failures**: Returned as structured results (not thrown)
|
|
1278
|
+
|
|
1279
|
+
### Key Differences from CLI
|
|
1280
|
+
|
|
1281
|
+
| Aspect | CLI | Control API |
|
|
1282
|
+
|--------|-----|-------------|
|
|
1283
|
+
| Config | Reads `prisma-next.config.ts` | Accepts descriptors directly |
|
|
1284
|
+
| File I/O | Reads contract.json from disk | Accepts contract IR directly |
|
|
1285
|
+
| Output | Formats for console | Returns structured data |
|
|
1286
|
+
| Exit codes | Uses `process.exit()` | Returns results/throws |
|
|
1287
|
+
|
|
1061
1288
|
## Entrypoints
|
|
1062
1289
|
|
|
1063
1290
|
The CLI package exports several subpaths for different use cases:
|
|
1064
1291
|
|
|
1065
1292
|
- **`@prisma-next/cli`** (main export): Exports `loadContractFromTs` and `createContractEmitCommand`
|
|
1066
1293
|
- **`@prisma-next/cli/config-types`**: Exports `defineConfig` and config types
|
|
1294
|
+
- **`@prisma-next/cli/control-api`**: Exports `createControlClient` and control API types
|
|
1067
1295
|
- **`@prisma-next/cli/commands/db-init`**: Exports `createDbInitCommand`
|
|
1296
|
+
- **`@prisma-next/cli/commands/db-update`**: Exports `createDbUpdateCommand`
|
|
1068
1297
|
- **`@prisma-next/cli/commands/db-introspect`**: Exports `createDbIntrospectCommand`
|
|
1069
1298
|
- **`@prisma-next/cli/commands/db-schema-verify`**: Exports `createDbSchemaVerifyCommand`
|
|
1070
1299
|
- **`@prisma-next/cli/commands/db-sign`**: Exports `createDbSignCommand`
|
|
1071
1300
|
- **`@prisma-next/cli/commands/db-verify`**: Exports `createDbVerifyCommand`
|
|
1072
1301
|
- **`@prisma-next/cli/commands/contract-emit`**: Exports `createContractEmitCommand`
|
|
1302
|
+
- **`@prisma-next/cli/commands/migration-plan`**: Exports `createMigrationPlanCommand`
|
|
1303
|
+
- **`@prisma-next/cli/commands/migration-show`**: Exports `createMigrationShowCommand`
|
|
1304
|
+
- **`@prisma-next/cli/commands/migration-status`**: Exports `createMigrationStatusCommand`
|
|
1305
|
+
- **`@prisma-next/cli/commands/migration-apply`**: Exports `createMigrationApplyCommand`
|
|
1306
|
+
- **`@prisma-next/cli/commands/migration-verify`**: Exports `createMigrationVerifyCommand`
|
|
1073
1307
|
- **`@prisma-next/cli/config-loader`**: Exports `loadConfig` function
|
|
1074
1308
|
|
|
1075
1309
|
**Important**: `loadContractFromTs` is exported from the main package (`@prisma-next/cli`). See `.cursor/rules/cli-package-exports.mdc` for import patterns.
|