@prisma-next/cli 0.3.0-dev.5 → 0.3.0-dev.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -74
- package/dist/cli.d.mts +1 -0
- package/dist/cli.js +1 -2376
- package/dist/cli.mjs +169 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client-BSZKpZTF.mjs +711 -0
- package/dist/client-BSZKpZTF.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 +147 -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 +179 -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 +120 -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 +116 -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 +138 -0
- package/dist/commands/db-sign.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 +129 -0
- package/dist/commands/db-verify.mjs.map +1 -0
- package/dist/config-loader-BJ8HsEdA.mjs +42 -0
- package/dist/config-loader-BJ8HsEdA.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 +433 -0
- package/dist/exports/control-api.d.mts.map +1 -0
- package/dist/exports/control-api.mjs +96 -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 +132 -0
- package/dist/exports/index.mjs.map +1 -0
- package/dist/result-handler-BZPY7HX4.mjs +1029 -0
- package/dist/result-handler-BZPY7HX4.mjs.map +1 -0
- package/package.json +48 -37
- package/src/commands/contract-emit.ts +205 -111
- package/src/commands/db-init.ts +258 -359
- package/src/commands/db-introspect.ts +151 -184
- package/src/commands/db-schema-verify.ts +151 -149
- package/src/commands/db-sign.ts +202 -200
- package/src/commands/db-verify.ts +181 -155
- package/src/control-api/client.ts +610 -0
- package/src/control-api/operations/contract-emit.ts +161 -0
- package/src/control-api/operations/db-init.ts +281 -0
- package/src/control-api/types.ts +475 -0
- package/src/exports/control-api.ts +48 -0
- package/src/load-ts-contract.ts +16 -11
- package/src/utils/cli-errors.ts +1 -1
- package/src/utils/framework-components.ts +11 -30
- package/src/utils/output.ts +16 -10
- 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
|
|
|
@@ -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
|
```
|
|
@@ -797,6 +790,7 @@ The CLI uses a config file to specify the target family, target, adapter, extens
|
|
|
797
790
|
|
|
798
791
|
```typescript
|
|
799
792
|
import { defineConfig } from '@prisma-next/cli/config-types';
|
|
793
|
+
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
|
|
800
794
|
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
801
795
|
import postgres from '@prisma-next/target-postgres/control';
|
|
802
796
|
import sql from '@prisma-next/family-sql/control';
|
|
@@ -807,22 +801,18 @@ export default defineConfig({
|
|
|
807
801
|
target: postgres,
|
|
808
802
|
adapter: postgresAdapter,
|
|
809
803
|
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
|
-
},
|
|
804
|
+
contract: typescriptContract(contract, 'src/prisma/contract.json'),
|
|
815
805
|
});
|
|
816
806
|
```
|
|
817
807
|
|
|
818
|
-
|
|
819
|
-
-
|
|
820
|
-
-
|
|
821
|
-
-
|
|
808
|
+
Prefer helper utilities for authoring mode selection:
|
|
809
|
+
- `typescriptContract(contractIR, outputPath?)` from `@prisma-next/sql-contract-ts/config-types` for TS-authored contracts
|
|
810
|
+
- `prismaContract(schemaPath, { output?, target? })` from `@prisma-next/sql-contract-psl/provider` for PSL-authored providers
|
|
811
|
+
- Provider failures are returned as structured diagnostics for CLI rendering
|
|
822
812
|
|
|
823
813
|
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
814
|
|
|
825
|
-
|
|
815
|
+
`contract.d.ts` is always colocated with `contract.json` and derived from `contract.output` (`contract.json` → `contract.d.ts`).
|
|
826
816
|
|
|
827
817
|
**Output:**
|
|
828
818
|
- `contract.json`: Includes `_generated` metadata field indicating it's a generated artifact (excluded from canonicalization/hashing)
|
|
@@ -865,18 +855,19 @@ See `.cursor/rules/config-validation-and-normalization.mdc` for detailed pattern
|
|
|
865
855
|
- **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
856
|
- **Command Taxonomy**: Groups commands by domain/plane (e.g., `contract emit`)
|
|
867
857
|
- **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**:
|
|
858
|
+
- **Command Descriptions**: See the “Command Descriptions” section above for `setCommandDescriptions()` usage.
|
|
869
859
|
|
|
870
860
|
### Contract Emit Command (`commands/contract-emit.ts`)
|
|
871
861
|
- Canonical command implementation using commander
|
|
872
862
|
- Supports global flags (JSON, verbosity, color, timestamps)
|
|
873
863
|
- **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
864
|
- Loads the user's config module (`prisma-next.config.ts`)
|
|
875
|
-
- Resolves contract from
|
|
876
|
-
-
|
|
877
|
-
-
|
|
865
|
+
- Resolves contract from provider:
|
|
866
|
+
- Calls `config.contract.source()` and expects `Result<ContractIR, Diagnostics>`
|
|
867
|
+
- Source-specific parsing/loading stays inside providers
|
|
868
|
+
- Provider diagnostics are surfaced as actionable CLI failures
|
|
878
869
|
- Throws error if `config.contract` is missing
|
|
879
|
-
- Uses artifact
|
|
870
|
+
- Uses artifact path from `config.contract.output` (already normalized by `defineConfig()` with defaults applied)
|
|
880
871
|
- Creates family instance via `config.family.create()` (assembles operation registry, type imports, extension IDs)
|
|
881
872
|
- Calls `familyInstance.emitContract()` with raw contract (instance handles stripping mappings and validation internally)
|
|
882
873
|
- Outputs human-readable or JSON format based on flags
|
|
@@ -1058,12 +1049,92 @@ pnpm test:integration # Run integration tests only
|
|
|
1058
1049
|
pnpm test:e2e # Run e2e tests only
|
|
1059
1050
|
```
|
|
1060
1051
|
|
|
1052
|
+
## Programmatic Control API
|
|
1053
|
+
|
|
1054
|
+
The CLI package provides a programmatic control client for running control-plane operations without using the command line. This is useful for:
|
|
1055
|
+
|
|
1056
|
+
- Integration with build tools and CI pipelines
|
|
1057
|
+
- Custom orchestration workflows
|
|
1058
|
+
- Test automation
|
|
1059
|
+
- Programmatic database management
|
|
1060
|
+
|
|
1061
|
+
### Basic Usage
|
|
1062
|
+
|
|
1063
|
+
```typescript
|
|
1064
|
+
import { createControlClient } from '@prisma-next/cli/control-api';
|
|
1065
|
+
import sql from '@prisma-next/family-sql/control';
|
|
1066
|
+
import postgres from '@prisma-next/target-postgres/control';
|
|
1067
|
+
import postgresAdapter from '@prisma-next/adapter-postgres/control';
|
|
1068
|
+
import postgresDriver from '@prisma-next/driver-postgres/control';
|
|
1069
|
+
|
|
1070
|
+
// Create a control client with framework component descriptors
|
|
1071
|
+
const client = createControlClient({
|
|
1072
|
+
family: sql,
|
|
1073
|
+
target: postgres,
|
|
1074
|
+
adapter: postgresAdapter,
|
|
1075
|
+
driver: postgresDriver,
|
|
1076
|
+
extensionPacks: [],
|
|
1077
|
+
});
|
|
1078
|
+
|
|
1079
|
+
try {
|
|
1080
|
+
// Connect to database
|
|
1081
|
+
await client.connect(databaseUrl);
|
|
1082
|
+
|
|
1083
|
+
// Run operations
|
|
1084
|
+
const verifyResult = await client.verify({ contractIR });
|
|
1085
|
+
const initResult = await client.dbInit({ contractIR, mode: 'apply' });
|
|
1086
|
+
const introspectResult = await client.introspect();
|
|
1087
|
+
} finally {
|
|
1088
|
+
// Clean up
|
|
1089
|
+
await client.close();
|
|
1090
|
+
}
|
|
1091
|
+
```
|
|
1092
|
+
|
|
1093
|
+
### Available Operations
|
|
1094
|
+
|
|
1095
|
+
| Method | Description |
|
|
1096
|
+
|--------|-------------|
|
|
1097
|
+
| `connect(url)` | Establishes database connection |
|
|
1098
|
+
| `close()` | Closes connection (idempotent) |
|
|
1099
|
+
| `verify(options)` | Verifies database marker matches contract |
|
|
1100
|
+
| `schemaVerify(options)` | Verifies database schema satisfies contract |
|
|
1101
|
+
| `sign(options)` | Writes contract marker to database |
|
|
1102
|
+
| `dbInit(options)` | Initializes database schema from contract |
|
|
1103
|
+
| `introspect(options)` | Introspects database schema |
|
|
1104
|
+
|
|
1105
|
+
### Result Types
|
|
1106
|
+
|
|
1107
|
+
Operations return structured result types:
|
|
1108
|
+
|
|
1109
|
+
- `verify()` → `VerifyDatabaseResult`
|
|
1110
|
+
- `schemaVerify()` → `VerifyDatabaseSchemaResult`
|
|
1111
|
+
- `sign()` → `SignDatabaseResult`
|
|
1112
|
+
- `dbInit()` → `Result<DbInitSuccess, DbInitFailure>` (uses Result pattern)
|
|
1113
|
+
- `introspect()` → Schema IR (family-specific)
|
|
1114
|
+
|
|
1115
|
+
### Error Handling
|
|
1116
|
+
|
|
1117
|
+
- **Connection errors**: Thrown as exceptions from `connect()`
|
|
1118
|
+
- **Not connected errors**: Thrown if operations called before `connect()`
|
|
1119
|
+
- **Driver not configured**: Thrown if driver is not provided in options
|
|
1120
|
+
- **Operation failures**: Returned as structured results (not thrown)
|
|
1121
|
+
|
|
1122
|
+
### Key Differences from CLI
|
|
1123
|
+
|
|
1124
|
+
| Aspect | CLI | Control API |
|
|
1125
|
+
|--------|-----|-------------|
|
|
1126
|
+
| Config | Reads `prisma-next.config.ts` | Accepts descriptors directly |
|
|
1127
|
+
| File I/O | Reads contract.json from disk | Accepts contract IR directly |
|
|
1128
|
+
| Output | Formats for console | Returns structured data |
|
|
1129
|
+
| Exit codes | Uses `process.exit()` | Returns results/throws |
|
|
1130
|
+
|
|
1061
1131
|
## Entrypoints
|
|
1062
1132
|
|
|
1063
1133
|
The CLI package exports several subpaths for different use cases:
|
|
1064
1134
|
|
|
1065
1135
|
- **`@prisma-next/cli`** (main export): Exports `loadContractFromTs` and `createContractEmitCommand`
|
|
1066
1136
|
- **`@prisma-next/cli/config-types`**: Exports `defineConfig` and config types
|
|
1137
|
+
- **`@prisma-next/cli/control-api`**: Exports `createControlClient` and control API types
|
|
1067
1138
|
- **`@prisma-next/cli/commands/db-init`**: Exports `createDbInitCommand`
|
|
1068
1139
|
- **`@prisma-next/cli/commands/db-introspect`**: Exports `createDbIntrospectCommand`
|
|
1069
1140
|
- **`@prisma-next/cli/commands/db-schema-verify`**: Exports `createDbSchemaVerifyCommand`
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|