@prisma-next/core-control-plane 0.0.1

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.
@@ -0,0 +1,371 @@
1
+ import { ContractIR } from '@prisma-next/contract/ir';
2
+ import { ExtensionPackManifest } from '@prisma-next/contract/pack-manifest-types';
3
+ import { TargetFamilyHook } from '@prisma-next/contract/types';
4
+ import { CoreSchemaView } from './schema-view.js';
5
+
6
+ /**
7
+ * Base interface for control-plane family instances.
8
+ * Families extend this with domain-specific methods.
9
+ *
10
+ * @template TFamilyId - The family ID (e.g., 'sql', 'document')
11
+ */
12
+ interface ControlFamilyInstance<TFamilyId extends string = string> {
13
+ readonly familyId: TFamilyId;
14
+ }
15
+ /**
16
+ * Base interface for control-plane target instances.
17
+ *
18
+ * @template TFamilyId - The family ID (e.g., 'sql', 'document')
19
+ * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
20
+ */
21
+ interface ControlTargetInstance<TFamilyId extends string = string, TTargetId extends string = string> {
22
+ readonly familyId: TFamilyId;
23
+ readonly targetId: TTargetId;
24
+ }
25
+ /**
26
+ * Base interface for control-plane adapter instances.
27
+ * Families extend this with family-specific adapter interfaces.
28
+ *
29
+ * @template TFamilyId - The family ID (e.g., 'sql', 'document')
30
+ * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
31
+ */
32
+ interface ControlAdapterInstance<TFamilyId extends string = string, TTargetId extends string = string> {
33
+ readonly familyId: TFamilyId;
34
+ readonly targetId: TTargetId;
35
+ }
36
+ /**
37
+ * Base interface for control-plane driver instances.
38
+ * Replaces ControlPlaneDriver with plane-first naming.
39
+ *
40
+ * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
41
+ */
42
+ interface ControlDriverInstance<TTargetId extends string = string> {
43
+ readonly targetId?: TTargetId;
44
+ query<Row = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<{
45
+ readonly rows: Row[];
46
+ }>;
47
+ close(): Promise<void>;
48
+ }
49
+ /**
50
+ * Base interface for control-plane extension instances.
51
+ *
52
+ * @template TFamilyId - The family ID (e.g., 'sql', 'document')
53
+ * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
54
+ */
55
+ interface ControlExtensionInstance<TFamilyId extends string = string, TTargetId extends string = string> {
56
+ readonly familyId: TFamilyId;
57
+ readonly targetId: TTargetId;
58
+ }
59
+ /**
60
+ * Descriptor for a control-plane family (e.g., SQL).
61
+ * Provides the family hook and factory method.
62
+ *
63
+ * @template TFamilyId - The family ID (e.g., 'sql', 'document')
64
+ * @template TFamilyInstance - The family instance type
65
+ */
66
+ interface ControlFamilyDescriptor<TFamilyId extends string, TFamilyInstance extends ControlFamilyInstance<TFamilyId> = ControlFamilyInstance<TFamilyId>> {
67
+ readonly kind: 'family';
68
+ readonly id: string;
69
+ readonly familyId: TFamilyId;
70
+ readonly manifest: ExtensionPackManifest;
71
+ readonly hook: TargetFamilyHook;
72
+ create<TTargetId extends string>(options: {
73
+ readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
74
+ readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
75
+ readonly driver: ControlDriverDescriptor<TFamilyId, TTargetId>;
76
+ readonly extensions: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
77
+ }): TFamilyInstance;
78
+ }
79
+ /**
80
+ * Descriptor for a control-plane target pack (e.g., Postgres target).
81
+ *
82
+ * @template TFamilyId - The family ID (e.g., 'sql', 'document')
83
+ * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
84
+ * @template TTargetInstance - The target instance type
85
+ */
86
+ interface ControlTargetDescriptor<TFamilyId extends string, TTargetId extends string, TTargetInstance extends ControlTargetInstance<TFamilyId, TTargetId> = ControlTargetInstance<TFamilyId, TTargetId>> {
87
+ readonly kind: 'target';
88
+ readonly id: string;
89
+ readonly familyId: TFamilyId;
90
+ readonly targetId: TTargetId;
91
+ readonly manifest: ExtensionPackManifest;
92
+ create(): TTargetInstance;
93
+ }
94
+ /**
95
+ * Descriptor for a control-plane adapter pack (e.g., Postgres adapter).
96
+ *
97
+ * @template TFamilyId - The family ID (e.g., 'sql', 'document')
98
+ * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
99
+ * @template TAdapterInstance - The adapter instance type
100
+ */
101
+ interface ControlAdapterDescriptor<TFamilyId extends string, TTargetId extends string, TAdapterInstance extends ControlAdapterInstance<TFamilyId, TTargetId> = ControlAdapterInstance<TFamilyId, TTargetId>> {
102
+ readonly kind: 'adapter';
103
+ readonly id: string;
104
+ readonly familyId: TFamilyId;
105
+ readonly targetId: TTargetId;
106
+ readonly manifest: ExtensionPackManifest;
107
+ create(): TAdapterInstance;
108
+ }
109
+ /**
110
+ * Descriptor for a control-plane driver pack (e.g., Postgres driver).
111
+ *
112
+ * @template TFamilyId - The family ID (e.g., 'sql', 'document')
113
+ * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
114
+ * @template TDriverInstance - The driver instance type
115
+ */
116
+ interface ControlDriverDescriptor<TFamilyId extends string, TTargetId extends string, TDriverInstance extends ControlDriverInstance<TTargetId> = ControlDriverInstance<TTargetId>> {
117
+ readonly kind: 'driver';
118
+ readonly id: string;
119
+ readonly familyId: TFamilyId;
120
+ readonly targetId: TTargetId;
121
+ readonly manifest: ExtensionPackManifest;
122
+ create(url: string): Promise<TDriverInstance>;
123
+ }
124
+ /**
125
+ * Descriptor for a control-plane extension pack (e.g., pgvector).
126
+ *
127
+ * @template TFamilyId - The family ID (e.g., 'sql', 'document')
128
+ * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
129
+ * @template TExtensionInstance - The extension instance type
130
+ */
131
+ interface ControlExtensionDescriptor<TFamilyId extends string, TTargetId extends string, TExtensionInstance extends ControlExtensionInstance<TFamilyId, TTargetId> = ControlExtensionInstance<TFamilyId, TTargetId>> {
132
+ readonly kind: 'extension';
133
+ readonly id: string;
134
+ readonly familyId: TFamilyId;
135
+ readonly targetId: TTargetId;
136
+ readonly manifest: ExtensionPackManifest;
137
+ create(): TExtensionInstance;
138
+ }
139
+ /**
140
+ * Family instance interface for control-plane domain actions.
141
+ * Each family implements this interface with family-specific types.
142
+ */
143
+ interface FamilyInstance<TFamilyId extends string, TSchemaIR = unknown, TVerifyResult = unknown, TSchemaVerifyResult = unknown, TSignResult = unknown> {
144
+ readonly familyId: TFamilyId;
145
+ /**
146
+ * Validates a contract JSON and returns a validated ContractIR (without mappings).
147
+ * Mappings are runtime-only and should not be part of ContractIR.
148
+ */
149
+ validateContractIR(contractJson: unknown): unknown;
150
+ /**
151
+ * Verifies the database marker against the contract.
152
+ * Compares target, coreHash, and profileHash.
153
+ */
154
+ verify(options: {
155
+ readonly driver: ControlDriverInstance;
156
+ readonly contractIR: unknown;
157
+ readonly expectedTargetId: string;
158
+ readonly contractPath: string;
159
+ readonly configPath?: string;
160
+ }): Promise<TVerifyResult>;
161
+ /**
162
+ * Verifies the database schema against the contract.
163
+ * Compares contract requirements against live database schema.
164
+ */
165
+ schemaVerify(options: {
166
+ readonly driver: ControlDriverInstance;
167
+ readonly contractIR: unknown;
168
+ readonly strict: boolean;
169
+ readonly contractPath: string;
170
+ readonly configPath?: string;
171
+ }): Promise<TSchemaVerifyResult>;
172
+ /**
173
+ * Signs the database with the contract marker.
174
+ * Writes or updates the contract marker if schema verification passes.
175
+ * This operation is idempotent - if the marker already matches, no changes are made.
176
+ */
177
+ sign(options: {
178
+ readonly driver: ControlDriverInstance;
179
+ readonly contractIR: unknown;
180
+ readonly contractPath: string;
181
+ readonly configPath?: string;
182
+ }): Promise<TSignResult>;
183
+ /**
184
+ * Introspects the database schema and returns a family-specific schema IR.
185
+ *
186
+ * This is a read-only operation that returns a snapshot of the live database schema.
187
+ * The method is family-owned and delegates to target/adapter-specific introspectors
188
+ * to perform the actual schema introspection.
189
+ *
190
+ * @param options - Introspection options
191
+ * @param options.driver - Control plane driver for database connection
192
+ * @param options.contractIR - Optional contract IR for contract-guided introspection.
193
+ * When provided, families may use it for filtering, optimization, or validation
194
+ * during introspection. The contract IR does not change the meaning of "what exists"
195
+ * in the database - it only guides how introspection is performed.
196
+ * @returns Promise resolving to the family-specific Schema IR (e.g., `SqlSchemaIR` for SQL).
197
+ * The IR represents the complete schema snapshot at the time of introspection.
198
+ */
199
+ introspect(options: {
200
+ readonly driver: ControlDriverInstance;
201
+ readonly contractIR?: unknown;
202
+ }): Promise<TSchemaIR>;
203
+ /**
204
+ * Optionally projects a family-specific Schema IR into a core schema view.
205
+ * Families that provide this method enable rich tree output for CLI visualization.
206
+ * Families that do not provide it still support introspection via raw Schema IR.
207
+ */
208
+ toSchemaView?(schema: TSchemaIR): CoreSchemaView;
209
+ /**
210
+ * Emits contract JSON and DTS as strings.
211
+ * Uses the instance's preassembled state (operation registry, type imports, extension IDs).
212
+ * Handles stripping mappings and validation internally.
213
+ */
214
+ emitContract(options: {
215
+ readonly contractIR: ContractIR | unknown;
216
+ }): Promise<EmitContractResult>;
217
+ }
218
+ /**
219
+ * Result type for database marker verification operations.
220
+ */
221
+ interface VerifyDatabaseResult {
222
+ readonly ok: boolean;
223
+ readonly code?: string;
224
+ readonly summary: string;
225
+ readonly contract: {
226
+ readonly coreHash: string;
227
+ readonly profileHash?: string;
228
+ };
229
+ readonly marker?: {
230
+ readonly coreHash?: string;
231
+ readonly profileHash?: string;
232
+ };
233
+ readonly target: {
234
+ readonly expected: string;
235
+ readonly actual?: string;
236
+ };
237
+ readonly missingCodecs?: readonly string[];
238
+ readonly codecCoverageSkipped?: boolean;
239
+ readonly meta?: {
240
+ readonly configPath?: string;
241
+ readonly contractPath: string;
242
+ };
243
+ readonly timings: {
244
+ readonly total: number;
245
+ };
246
+ }
247
+ /**
248
+ * Schema issue type for schema verification results.
249
+ */
250
+ interface SchemaIssue {
251
+ readonly kind: 'missing_table' | 'missing_column' | 'type_mismatch' | 'nullability_mismatch' | 'primary_key_mismatch' | 'foreign_key_mismatch' | 'unique_constraint_mismatch' | 'index_mismatch' | 'extension_missing';
252
+ readonly table: string;
253
+ readonly column?: string;
254
+ readonly indexOrConstraint?: string;
255
+ readonly expected?: string;
256
+ readonly actual?: string;
257
+ readonly message: string;
258
+ }
259
+ /**
260
+ * Contract-shaped verification tree node for schema verification results.
261
+ * Family-agnostic structure that follows the contract structure.
262
+ */
263
+ interface SchemaVerificationNode {
264
+ readonly status: 'pass' | 'warn' | 'fail';
265
+ readonly kind: string;
266
+ readonly name: string;
267
+ readonly contractPath: string;
268
+ readonly code: string;
269
+ readonly message: string;
270
+ readonly expected: unknown;
271
+ readonly actual: unknown;
272
+ readonly children: readonly SchemaVerificationNode[];
273
+ }
274
+ /**
275
+ * Result type for database schema verification operations.
276
+ */
277
+ interface VerifyDatabaseSchemaResult {
278
+ readonly ok: boolean;
279
+ readonly code?: string;
280
+ readonly summary: string;
281
+ readonly contract: {
282
+ readonly coreHash: string;
283
+ readonly profileHash?: string;
284
+ };
285
+ readonly target: {
286
+ readonly expected: string;
287
+ readonly actual?: string;
288
+ };
289
+ readonly schema: {
290
+ readonly issues: readonly SchemaIssue[];
291
+ readonly root: SchemaVerificationNode;
292
+ readonly counts: {
293
+ readonly pass: number;
294
+ readonly warn: number;
295
+ readonly fail: number;
296
+ readonly totalNodes: number;
297
+ };
298
+ };
299
+ readonly meta?: {
300
+ readonly configPath?: string;
301
+ readonly contractPath: string;
302
+ readonly strict: boolean;
303
+ };
304
+ readonly timings: {
305
+ readonly total: number;
306
+ };
307
+ }
308
+ /**
309
+ * Result type for contract emission operations.
310
+ */
311
+ interface EmitContractResult {
312
+ readonly contractJson: string;
313
+ readonly contractDts: string;
314
+ readonly coreHash: string;
315
+ readonly profileHash: string;
316
+ }
317
+ /**
318
+ * Result envelope for schema introspection operations.
319
+ * Used by CLI for JSON output when introspecting database schemas.
320
+ *
321
+ * @template TSchemaIR - The family-specific Schema IR type (e.g., `SqlSchemaIR` for SQL)
322
+ */
323
+ interface IntrospectSchemaResult<TSchemaIR = unknown> {
324
+ readonly ok: true;
325
+ readonly summary: string;
326
+ readonly target: {
327
+ readonly familyId: string;
328
+ readonly id: string;
329
+ };
330
+ readonly schema: TSchemaIR;
331
+ readonly meta?: {
332
+ readonly configPath?: string;
333
+ readonly dbUrl?: string;
334
+ };
335
+ readonly timings: {
336
+ readonly total: number;
337
+ };
338
+ }
339
+ /**
340
+ * Result type for database signing operations.
341
+ * Returned when writing or updating the contract marker in the database.
342
+ */
343
+ interface SignDatabaseResult {
344
+ readonly ok: boolean;
345
+ readonly summary: string;
346
+ readonly contract: {
347
+ readonly coreHash: string;
348
+ readonly profileHash?: string;
349
+ };
350
+ readonly target: {
351
+ readonly expected: string;
352
+ readonly actual?: string;
353
+ };
354
+ readonly marker: {
355
+ readonly created: boolean;
356
+ readonly updated: boolean;
357
+ readonly previous?: {
358
+ readonly coreHash?: string;
359
+ readonly profileHash?: string;
360
+ };
361
+ };
362
+ readonly meta?: {
363
+ readonly configPath?: string;
364
+ readonly contractPath: string;
365
+ };
366
+ readonly timings: {
367
+ readonly total: number;
368
+ };
369
+ }
370
+
371
+ export type { ControlAdapterDescriptor, ControlAdapterInstance, ControlDriverDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlExtensionInstance, ControlFamilyDescriptor, ControlFamilyInstance, ControlTargetDescriptor, ControlTargetInstance, EmitContractResult, FamilyInstance, IntrospectSchemaResult, SchemaIssue, SchemaVerificationNode, SignDatabaseResult, VerifyDatabaseResult, VerifyDatabaseSchemaResult };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@prisma-next/core-control-plane",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "sideEffects": false,
6
+ "description": "Control plane domain actions, config types, validation, and error factories for Prisma Next",
7
+ "dependencies": {
8
+ "arktype": "^2.1.26",
9
+ "prettier": "^3.3.3",
10
+ "@prisma-next/contract": "0.0.1",
11
+ "@prisma-next/operations": "0.0.1"
12
+ },
13
+ "devDependencies": {
14
+ "tsup": "^8.3.0",
15
+ "typescript": "^5.9.3",
16
+ "vitest": "^2.1.1",
17
+ "@prisma-next/test-utils": "0.0.1"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "exports": {
23
+ "./config-types": {
24
+ "types": "./dist/exports/config-types.d.ts",
25
+ "import": "./dist/exports/config-types.js"
26
+ },
27
+ "./config-validation": {
28
+ "types": "./dist/exports/config-validation.d.ts",
29
+ "import": "./dist/exports/config-validation.js"
30
+ },
31
+ "./errors": {
32
+ "types": "./dist/exports/errors.d.ts",
33
+ "import": "./dist/exports/errors.js"
34
+ },
35
+ "./types": {
36
+ "types": "./dist/exports/types.d.ts",
37
+ "import": "./dist/exports/types.js"
38
+ },
39
+ "./emission": {
40
+ "types": "./dist/exports/emission.d.ts",
41
+ "import": "./dist/exports/emission.js"
42
+ },
43
+ "./schema-view": {
44
+ "types": "./dist/exports/schema-view.d.ts",
45
+ "import": "./dist/exports/schema-view.js"
46
+ }
47
+ },
48
+ "scripts": {
49
+ "build": "tsup --config tsup.config.ts",
50
+ "test": "vitest run --passWithNoTests",
51
+ "test:coverage": "vitest run --coverage --passWithNoTests",
52
+ "typecheck": "tsc --project tsconfig.json --noEmit",
53
+ "lint": "biome check . --config-path ../../../biome.json --error-on-warnings",
54
+ "clean": "node ../../../scripts/clean.mjs"
55
+ }
56
+ }