@prisma-next/core-control-plane 0.1.0-dev.16 → 0.1.0-dev.18
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.
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ControlFamilyDescriptor, ControlTargetDescriptor, ControlAdapterDescriptor, ControlExtensionDescriptor, ControlDriverDescriptor } from './types.js';
|
|
2
|
+
import '@prisma-next/contract/framework-components';
|
|
2
3
|
import '@prisma-next/contract/ir';
|
|
3
|
-
import '@prisma-next/contract/pack-manifest-types';
|
|
4
4
|
import '@prisma-next/contract/types';
|
|
5
|
+
import '@prisma-next/utils/result';
|
|
5
6
|
import './schema-view.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config-types.ts"],"sourcesContent":["import { dirname, join } from 'node:path';\nimport { type } from 'arktype';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyDescriptor,\n ControlTargetDescriptor,\n} from './types';\n\n/**\n * Type alias for CLI driver instances.\n */\nexport type CliDriver = ControlDriverInstance
|
|
1
|
+
{"version":3,"sources":["../../src/config-types.ts"],"sourcesContent":["import { dirname, join } from 'node:path';\nimport { type } from 'arktype';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyDescriptor,\n ControlTargetDescriptor,\n} from './types';\n\n/**\n * Type alias for CLI driver instances.\n * Uses string for both family and target IDs for maximum flexibility.\n */\nexport type CliDriver = ControlDriverInstance<string, string>;\n\n/**\n * Contract configuration specifying source and artifact locations.\n */\nexport interface ContractConfig {\n /**\n * Contract source. Can be a value or a function that returns a value (sync or async).\n * If a function, it will be called to resolve the contract.\n */\n readonly source: unknown | (() => unknown | Promise<unknown>);\n /**\n * Path to contract.json artifact. Defaults to 'src/prisma/contract.json'.\n * This is the canonical location where other CLI commands can find the contract JSON.\n */\n readonly output?: string;\n /**\n * Path to contract.d.ts artifact. Defaults to output with .d.ts extension.\n * If output ends with .json, replaces .json with .d.ts.\n * Otherwise, appends .d.ts to the directory containing output.\n */\n readonly types?: string;\n}\n\n/**\n * Configuration for Prisma Next CLI.\n * Uses Control*Descriptor types for type-safe wiring with compile-time compatibility checks.\n *\n * @template TFamilyId - The family ID (e.g., 'sql', 'document')\n * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')\n */\nexport interface PrismaNextConfig<\n TFamilyId extends string = string,\n TTargetId extends string = string,\n> {\n readonly family: ControlFamilyDescriptor<TFamilyId>;\n readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;\n readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;\n readonly extensions?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];\n /**\n * Driver descriptor for DB-connected CLI commands.\n * Required for DB-connected commands (e.g., db verify).\n * Optional for commands that don't need database access (e.g., emit).\n */\n readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId>;\n readonly db?: {\n readonly url?: string;\n };\n /**\n * Contract configuration. Specifies source and artifact locations.\n * Required for emit command; optional for other commands that only read artifacts.\n */\n readonly contract?: ContractConfig;\n}\n\n/**\n * Arktype schema for ContractConfig validation.\n * Validates that source is present and output/types are strings when provided.\n */\nconst ContractConfigSchema = type({\n source: 'unknown', // Can be value or function - runtime check needed\n 'output?': 'string',\n 'types?': 'string',\n});\n\n/**\n * Arktype schema for PrismaNextConfig validation.\n * Note: This validates structure only. Descriptor objects (family, target, adapter) are validated separately.\n */\nconst PrismaNextConfigSchema = type({\n family: 'unknown', // ControlFamilyDescriptor - validated separately\n target: 'unknown', // ControlTargetDescriptor - validated separately\n adapter: 'unknown', // ControlAdapterDescriptor - validated separately\n 'extensions?': 'unknown[]',\n 'driver?': 'unknown', // ControlDriverDescriptor - validated separately (optional)\n 'db?': 'unknown',\n 'contract?': ContractConfigSchema,\n});\n\n/**\n * Helper function to define a Prisma Next config.\n * Validates and normalizes the config using Arktype, then returns the normalized IR.\n *\n * Normalization:\n * - contract.output defaults to 'src/prisma/contract.json' if missing\n * - contract.types defaults to output with .d.ts extension if missing\n *\n * @param config - Raw config input from user\n * @returns Normalized config IR with defaults applied\n * @throws Error if config structure is invalid\n */\nexport function defineConfig<TFamilyId extends string = string, TTargetId extends string = string>(\n config: PrismaNextConfig<TFamilyId, TTargetId>,\n): PrismaNextConfig<TFamilyId, TTargetId> {\n // Validate structure using Arktype\n const validated = PrismaNextConfigSchema(config);\n if (validated instanceof type.errors) {\n const messages = validated.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Config validation failed: ${messages}`);\n }\n\n // Normalize contract config if present\n if (config.contract) {\n // Validate contract.source is a value or function (runtime check)\n const source = config.contract.source;\n if (\n source !== null &&\n typeof source !== 'object' &&\n typeof source !== 'function' &&\n typeof source !== 'string' &&\n typeof source !== 'number' &&\n typeof source !== 'boolean'\n ) {\n throw new Error(\n 'Config.contract.source must be a value (object, string, number, boolean, null) or a function',\n );\n }\n\n // Apply defaults\n const output = config.contract.output ?? 'src/prisma/contract.json';\n const types =\n config.contract.types ??\n (output.endsWith('.json')\n ? `${output.slice(0, -5)}.d.ts`\n : join(dirname(output), 'contract.d.ts'));\n\n const normalizedContract: ContractConfig = {\n source: config.contract.source,\n output,\n types,\n };\n\n // Return normalized config\n return {\n ...config,\n contract: normalizedContract,\n };\n }\n\n // Return config as-is if no contract (preserve literal types)\n return config;\n}\n"],"mappings":";AAAA,SAAS,SAAS,YAAY;AAC9B,SAAS,YAAY;AAyErB,IAAM,uBAAuB,KAAK;AAAA,EAChC,QAAQ;AAAA;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AACZ,CAAC;AAMD,IAAM,yBAAyB,KAAK;AAAA,EAClC,QAAQ;AAAA;AAAA,EACR,QAAQ;AAAA;AAAA,EACR,SAAS;AAAA;AAAA,EACT,eAAe;AAAA,EACf,WAAW;AAAA;AAAA,EACX,OAAO;AAAA,EACP,aAAa;AACf,CAAC;AAcM,SAAS,aACd,QACwC;AAExC,QAAM,YAAY,uBAAuB,MAAM;AAC/C,MAAI,qBAAqB,KAAK,QAAQ;AACpC,UAAM,WAAW,UAAU,IAAI,CAAC,MAA2B,EAAE,OAAO,EAAE,KAAK,IAAI;AAC/E,UAAM,IAAI,MAAM,6BAA6B,QAAQ,EAAE;AAAA,EACzD;AAGA,MAAI,OAAO,UAAU;AAEnB,UAAM,SAAS,OAAO,SAAS;AAC/B,QACE,WAAW,QACX,OAAO,WAAW,YAClB,OAAO,WAAW,cAClB,OAAO,WAAW,YAClB,OAAO,WAAW,YAClB,OAAO,WAAW,WAClB;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAGA,UAAM,SAAS,OAAO,SAAS,UAAU;AACzC,UAAM,QACJ,OAAO,SAAS,UACf,OAAO,SAAS,OAAO,IACpB,GAAG,OAAO,MAAM,GAAG,EAAE,CAAC,UACtB,KAAK,QAAQ,MAAM,GAAG,eAAe;AAE3C,UAAM,qBAAqC;AAAA,MACzC,QAAQ,OAAO,SAAS;AAAA,MACxB;AAAA,MACA;AAAA,IACF;AAGA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU;AAAA,IACZ;AAAA,EACF;AAGA,SAAO;AACT;","names":[]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { PrismaNextConfig } from './config-types.js';
|
|
2
2
|
import './types.js';
|
|
3
|
+
import '@prisma-next/contract/framework-components';
|
|
3
4
|
import '@prisma-next/contract/ir';
|
|
4
|
-
import '@prisma-next/contract/pack-manifest-types';
|
|
5
5
|
import '@prisma-next/contract/types';
|
|
6
|
+
import '@prisma-next/utils/result';
|
|
6
7
|
import './schema-view.js';
|
|
7
8
|
|
|
8
9
|
/**
|
package/dist/exports/types.d.ts
CHANGED
|
@@ -1,60 +1,278 @@
|
|
|
1
|
+
import { FamilyInstance, DriverInstance, FamilyDescriptor, TargetInstance, TargetDescriptor, AdapterInstance, AdapterDescriptor, DriverDescriptor, ExtensionInstance, ExtensionDescriptor } from '@prisma-next/contract/framework-components';
|
|
1
2
|
import { ContractIR } from '@prisma-next/contract/ir';
|
|
2
|
-
import { ExtensionPackManifest } from '@prisma-next/contract/pack-manifest-types';
|
|
3
3
|
import { TargetFamilyHook } from '@prisma-next/contract/types';
|
|
4
|
+
import { Result } from '@prisma-next/utils/result';
|
|
4
5
|
import { CoreSchemaView } from './schema-view.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
8
|
+
* Core migration types for the framework control plane.
|
|
9
|
+
*
|
|
10
|
+
* These are family-agnostic, display-oriented types that provide a stable
|
|
11
|
+
* vocabulary for CLI commands to work with migration planners and runners
|
|
12
|
+
* without importing family-specific types.
|
|
13
|
+
*
|
|
14
|
+
* Family-specific types (e.g., SqlMigrationPlan) extend these base types
|
|
15
|
+
* with additional fields for execution (precheck SQL, execute SQL, etc.).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Migration operation classes define the safety level of an operation.
|
|
20
|
+
* - 'additive': Adds new structures without modifying existing ones (safe)
|
|
21
|
+
* - 'widening': Relaxes constraints or expands types (generally safe)
|
|
22
|
+
* - 'destructive': Removes or alters existing structures (potentially unsafe)
|
|
23
|
+
*/
|
|
24
|
+
type MigrationOperationClass = 'additive' | 'widening' | 'destructive';
|
|
25
|
+
/**
|
|
26
|
+
* Policy defining which operation classes are allowed during a migration.
|
|
27
|
+
*/
|
|
28
|
+
interface MigrationOperationPolicy {
|
|
29
|
+
readonly allowedOperationClasses: readonly MigrationOperationClass[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A single migration operation for display purposes.
|
|
33
|
+
* Contains only the fields needed for CLI output (tree view, JSON envelope).
|
|
34
|
+
*/
|
|
35
|
+
interface MigrationPlanOperation {
|
|
36
|
+
/** Unique identifier for this operation (e.g., "table.users.create"). */
|
|
37
|
+
readonly id: string;
|
|
38
|
+
/** Human-readable label for display in UI/CLI (e.g., "Create table users"). */
|
|
39
|
+
readonly label: string;
|
|
40
|
+
/** The class of operation (additive, widening, destructive). */
|
|
41
|
+
readonly operationClass: MigrationOperationClass;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A migration plan for display purposes.
|
|
45
|
+
* Contains only the fields needed for CLI output (summary, JSON envelope).
|
|
46
|
+
*/
|
|
47
|
+
interface MigrationPlan {
|
|
48
|
+
/** The target ID this plan is for (e.g., 'postgres'). */
|
|
49
|
+
readonly targetId: string;
|
|
50
|
+
/** Destination contract identity that the plan intends to reach. */
|
|
51
|
+
readonly destination: {
|
|
52
|
+
readonly coreHash: string;
|
|
53
|
+
readonly profileHash?: string;
|
|
54
|
+
};
|
|
55
|
+
/** Ordered list of operations to execute. */
|
|
56
|
+
readonly operations: readonly MigrationPlanOperation[];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A conflict detected during migration planning.
|
|
60
|
+
*/
|
|
61
|
+
interface MigrationPlannerConflict {
|
|
62
|
+
/** Kind of conflict (e.g., 'typeMismatch', 'nullabilityConflict'). */
|
|
63
|
+
readonly kind: string;
|
|
64
|
+
/** Human-readable summary of the conflict. */
|
|
65
|
+
readonly summary: string;
|
|
66
|
+
/** Optional explanation of why this conflict occurred. */
|
|
67
|
+
readonly why?: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Successful planner result with the migration plan.
|
|
71
|
+
*/
|
|
72
|
+
interface MigrationPlannerSuccessResult {
|
|
73
|
+
readonly kind: 'success';
|
|
74
|
+
readonly plan: MigrationPlan;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Failed planner result with the list of conflicts.
|
|
78
|
+
*/
|
|
79
|
+
interface MigrationPlannerFailureResult {
|
|
80
|
+
readonly kind: 'failure';
|
|
81
|
+
readonly conflicts: readonly MigrationPlannerConflict[];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Union type for planner results.
|
|
85
|
+
*/
|
|
86
|
+
type MigrationPlannerResult = MigrationPlannerSuccessResult | MigrationPlannerFailureResult;
|
|
87
|
+
/**
|
|
88
|
+
* Success value for migration runner execution.
|
|
89
|
+
*/
|
|
90
|
+
interface MigrationRunnerSuccessValue {
|
|
91
|
+
readonly operationsPlanned: number;
|
|
92
|
+
readonly operationsExecuted: number;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Failure details for migration runner execution.
|
|
96
|
+
*/
|
|
97
|
+
interface MigrationRunnerFailure {
|
|
98
|
+
/** Error code for the failure. */
|
|
99
|
+
readonly code: string;
|
|
100
|
+
/** Human-readable summary of the failure. */
|
|
101
|
+
readonly summary: string;
|
|
102
|
+
/** Optional explanation of why the failure occurred. */
|
|
103
|
+
readonly why?: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Result type for migration runner execution.
|
|
107
|
+
*/
|
|
108
|
+
type MigrationRunnerResult = Result<MigrationRunnerSuccessValue, MigrationRunnerFailure>;
|
|
109
|
+
/**
|
|
110
|
+
* Migration planner interface for planning schema changes.
|
|
111
|
+
* This is the minimal interface that CLI commands use.
|
|
112
|
+
*/
|
|
113
|
+
interface MigrationPlanner {
|
|
114
|
+
plan(options: {
|
|
115
|
+
readonly contract: unknown;
|
|
116
|
+
readonly schema: unknown;
|
|
117
|
+
readonly policy: MigrationOperationPolicy;
|
|
118
|
+
}): MigrationPlannerResult;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Migration runner interface for executing migration plans.
|
|
122
|
+
* This is the minimal interface that CLI commands use.
|
|
123
|
+
*/
|
|
124
|
+
interface MigrationRunner {
|
|
125
|
+
execute(options: {
|
|
126
|
+
readonly plan: MigrationPlan;
|
|
127
|
+
readonly driver: ControlDriverInstance<string, string>;
|
|
128
|
+
readonly destinationContract: unknown;
|
|
129
|
+
readonly policy: MigrationOperationPolicy;
|
|
130
|
+
readonly callbacks?: {
|
|
131
|
+
onOperationStart?(op: MigrationPlanOperation): void;
|
|
132
|
+
onOperationComplete?(op: MigrationPlanOperation): void;
|
|
133
|
+
};
|
|
134
|
+
}): Promise<MigrationRunnerResult>;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Optional capability interface for targets that support migrations.
|
|
138
|
+
* Targets that implement migrations expose this via their descriptor.
|
|
139
|
+
*
|
|
140
|
+
* @template TFamilyInstance - The family instance type (e.g., SqlControlFamilyInstance)
|
|
141
|
+
*/
|
|
142
|
+
interface TargetMigrationsCapability<TFamilyInstance extends ControlFamilyInstance<string> = ControlFamilyInstance<string>> {
|
|
143
|
+
createPlanner(family: TFamilyInstance): MigrationPlanner;
|
|
144
|
+
createRunner(family: TFamilyInstance): MigrationRunner;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Control-plane family instance interface.
|
|
149
|
+
* Extends the base FamilyInstance with control-plane domain actions.
|
|
9
150
|
*
|
|
10
151
|
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
152
|
+
* @template TSchemaIR - The schema IR type returned by introspect() (family-specific)
|
|
11
153
|
*/
|
|
12
|
-
interface ControlFamilyInstance<TFamilyId extends string =
|
|
13
|
-
|
|
154
|
+
interface ControlFamilyInstance<TFamilyId extends string, TSchemaIR = unknown> extends FamilyInstance<TFamilyId> {
|
|
155
|
+
/**
|
|
156
|
+
* Validates a contract JSON and returns a validated ContractIR (without mappings).
|
|
157
|
+
* Mappings are runtime-only and should not be part of ContractIR.
|
|
158
|
+
*
|
|
159
|
+
* Note: The returned ContractIR may include additional fields from the emitted contract
|
|
160
|
+
* (like coreHash, profileHash) that are not part of the ContractIR type but are preserved
|
|
161
|
+
* for use by verify/sign operations.
|
|
162
|
+
*/
|
|
163
|
+
validateContractIR(contractJson: unknown): ContractIR;
|
|
164
|
+
/**
|
|
165
|
+
* Verifies the database marker against the contract.
|
|
166
|
+
* Compares target, coreHash, and profileHash.
|
|
167
|
+
*
|
|
168
|
+
* @param options.contractIR - The validated contract (from validateContractIR). Must have
|
|
169
|
+
* coreHash and target fields for verification. These fields are present in emitted
|
|
170
|
+
* contracts but not in the ContractIR type definition.
|
|
171
|
+
*/
|
|
172
|
+
verify(options: {
|
|
173
|
+
readonly driver: ControlDriverInstance<TFamilyId, string>;
|
|
174
|
+
readonly contractIR: unknown;
|
|
175
|
+
readonly expectedTargetId: string;
|
|
176
|
+
readonly contractPath: string;
|
|
177
|
+
readonly configPath?: string;
|
|
178
|
+
}): Promise<VerifyDatabaseResult>;
|
|
179
|
+
/**
|
|
180
|
+
* Verifies the database schema against the contract.
|
|
181
|
+
* Compares contract requirements against live database schema.
|
|
182
|
+
*/
|
|
183
|
+
schemaVerify(options: {
|
|
184
|
+
readonly driver: ControlDriverInstance<TFamilyId, string>;
|
|
185
|
+
readonly contractIR: unknown;
|
|
186
|
+
readonly strict: boolean;
|
|
187
|
+
readonly contractPath: string;
|
|
188
|
+
readonly configPath?: string;
|
|
189
|
+
}): Promise<VerifyDatabaseSchemaResult>;
|
|
190
|
+
/**
|
|
191
|
+
* Signs the database with the contract marker.
|
|
192
|
+
* Writes or updates the contract marker if schema verification passes.
|
|
193
|
+
* This operation is idempotent - if the marker already matches, no changes are made.
|
|
194
|
+
*/
|
|
195
|
+
sign(options: {
|
|
196
|
+
readonly driver: ControlDriverInstance<TFamilyId, string>;
|
|
197
|
+
readonly contractIR: unknown;
|
|
198
|
+
readonly contractPath: string;
|
|
199
|
+
readonly configPath?: string;
|
|
200
|
+
}): Promise<SignDatabaseResult>;
|
|
201
|
+
/**
|
|
202
|
+
* Introspects the database schema and returns a family-specific schema IR.
|
|
203
|
+
*
|
|
204
|
+
* This is a read-only operation that returns a snapshot of the live database schema.
|
|
205
|
+
* The method is family-owned and delegates to target/adapter-specific introspectors
|
|
206
|
+
* to perform the actual schema introspection.
|
|
207
|
+
*
|
|
208
|
+
* @param options - Introspection options
|
|
209
|
+
* @param options.driver - Control plane driver for database connection
|
|
210
|
+
* @param options.contractIR - Optional contract for contract-guided introspection.
|
|
211
|
+
* When provided, families may use it for filtering, optimization, or validation
|
|
212
|
+
* during introspection. The contract does not change the meaning of "what exists"
|
|
213
|
+
* in the database - it only guides how introspection is performed.
|
|
214
|
+
* @returns Promise resolving to the family-specific Schema IR (e.g., `SqlSchemaIR` for SQL).
|
|
215
|
+
* The IR represents the complete schema snapshot at the time of introspection.
|
|
216
|
+
*/
|
|
217
|
+
introspect(options: {
|
|
218
|
+
readonly driver: ControlDriverInstance<TFamilyId, string>;
|
|
219
|
+
readonly contractIR?: unknown;
|
|
220
|
+
}): Promise<TSchemaIR>;
|
|
221
|
+
/**
|
|
222
|
+
* Optionally projects a family-specific Schema IR into a core schema view.
|
|
223
|
+
* Families that provide this method enable rich tree output for CLI visualization.
|
|
224
|
+
* Families that do not provide it still support introspection via raw Schema IR.
|
|
225
|
+
*/
|
|
226
|
+
toSchemaView?(schema: TSchemaIR): CoreSchemaView;
|
|
227
|
+
/**
|
|
228
|
+
* Emits contract JSON and DTS as strings.
|
|
229
|
+
* Uses the instance's preassembled state (operation registry, type imports, extension IDs).
|
|
230
|
+
* Handles stripping mappings and validation internally.
|
|
231
|
+
*/
|
|
232
|
+
emitContract(options: {
|
|
233
|
+
readonly contractIR: ContractIR | unknown;
|
|
234
|
+
}): Promise<EmitContractResult>;
|
|
14
235
|
}
|
|
15
236
|
/**
|
|
16
|
-
*
|
|
237
|
+
* Control-plane target instance interface.
|
|
238
|
+
* Extends the base TargetInstance with control-plane specific behavior.
|
|
17
239
|
*
|
|
18
240
|
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
19
241
|
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
|
|
20
242
|
*/
|
|
21
|
-
interface ControlTargetInstance<TFamilyId extends string
|
|
22
|
-
readonly familyId: TFamilyId;
|
|
23
|
-
readonly targetId: TTargetId;
|
|
243
|
+
interface ControlTargetInstance<TFamilyId extends string, TTargetId extends string> extends TargetInstance<TFamilyId, TTargetId> {
|
|
24
244
|
}
|
|
25
245
|
/**
|
|
26
|
-
*
|
|
246
|
+
* Control-plane adapter instance interface.
|
|
247
|
+
* Extends the base AdapterInstance with control-plane specific behavior.
|
|
27
248
|
* Families extend this with family-specific adapter interfaces.
|
|
28
249
|
*
|
|
29
250
|
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
30
251
|
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
|
|
31
252
|
*/
|
|
32
|
-
interface ControlAdapterInstance<TFamilyId extends string
|
|
33
|
-
readonly familyId: TFamilyId;
|
|
34
|
-
readonly targetId: TTargetId;
|
|
253
|
+
interface ControlAdapterInstance<TFamilyId extends string, TTargetId extends string> extends AdapterInstance<TFamilyId, TTargetId> {
|
|
35
254
|
}
|
|
36
255
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
256
|
+
* Control-plane driver instance interface.
|
|
257
|
+
* Extends the base DriverInstance with control-plane specific behavior.
|
|
39
258
|
*
|
|
259
|
+
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
40
260
|
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
|
|
41
261
|
*/
|
|
42
|
-
interface ControlDriverInstance<
|
|
43
|
-
readonly targetId?: TTargetId;
|
|
262
|
+
interface ControlDriverInstance<TFamilyId extends string, TTargetId extends string> extends DriverInstance<TFamilyId, TTargetId> {
|
|
44
263
|
query<Row = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<{
|
|
45
264
|
readonly rows: Row[];
|
|
46
265
|
}>;
|
|
47
266
|
close(): Promise<void>;
|
|
48
267
|
}
|
|
49
268
|
/**
|
|
50
|
-
*
|
|
269
|
+
* Control-plane extension instance interface.
|
|
270
|
+
* Extends the base ExtensionInstance with control-plane specific behavior.
|
|
51
271
|
*
|
|
52
272
|
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
53
273
|
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
|
|
54
274
|
*/
|
|
55
|
-
interface ControlExtensionInstance<TFamilyId extends string
|
|
56
|
-
readonly familyId: TFamilyId;
|
|
57
|
-
readonly targetId: TTargetId;
|
|
275
|
+
interface ControlExtensionInstance<TFamilyId extends string, TTargetId extends string> extends ExtensionInstance<TFamilyId, TTargetId> {
|
|
58
276
|
}
|
|
59
277
|
/**
|
|
60
278
|
* Operation context for propagating metadata through control-plane operation call chains.
|
|
@@ -98,11 +316,7 @@ interface OperationContext {
|
|
|
98
316
|
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
99
317
|
* @template TFamilyInstance - The family instance type
|
|
100
318
|
*/
|
|
101
|
-
interface ControlFamilyDescriptor<TFamilyId extends string, TFamilyInstance extends ControlFamilyInstance<TFamilyId> = ControlFamilyInstance<TFamilyId>> {
|
|
102
|
-
readonly kind: 'family';
|
|
103
|
-
readonly id: string;
|
|
104
|
-
readonly familyId: TFamilyId;
|
|
105
|
-
readonly manifest: ExtensionPackManifest;
|
|
319
|
+
interface ControlFamilyDescriptor<TFamilyId extends string, TFamilyInstance extends ControlFamilyInstance<TFamilyId> = ControlFamilyInstance<TFamilyId>> extends FamilyDescriptor<TFamilyId> {
|
|
106
320
|
readonly hook: TargetFamilyHook;
|
|
107
321
|
create<TTargetId extends string>(options: {
|
|
108
322
|
readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
|
|
@@ -112,144 +326,51 @@ interface ControlFamilyDescriptor<TFamilyId extends string, TFamilyInstance exte
|
|
|
112
326
|
}): TFamilyInstance;
|
|
113
327
|
}
|
|
114
328
|
/**
|
|
115
|
-
* Descriptor for a control-plane target
|
|
329
|
+
* Descriptor for a control-plane target component (e.g., Postgres target).
|
|
116
330
|
*
|
|
117
331
|
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
118
332
|
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
|
|
119
333
|
* @template TTargetInstance - The target instance type
|
|
334
|
+
* @template TFamilyInstance - The family instance type for migrations (optional)
|
|
120
335
|
*/
|
|
121
|
-
interface ControlTargetDescriptor<TFamilyId extends string, TTargetId extends string, TTargetInstance extends ControlTargetInstance<TFamilyId, TTargetId> = ControlTargetInstance<TFamilyId, TTargetId>> {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
readonly
|
|
336
|
+
interface ControlTargetDescriptor<TFamilyId extends string, TTargetId extends string, TTargetInstance extends ControlTargetInstance<TFamilyId, TTargetId> = ControlTargetInstance<TFamilyId, TTargetId>, TFamilyInstance extends ControlFamilyInstance<TFamilyId> = ControlFamilyInstance<TFamilyId>> extends TargetDescriptor<TFamilyId, TTargetId> {
|
|
337
|
+
/**
|
|
338
|
+
* Optional migrations capability.
|
|
339
|
+
* Targets that support migrations expose this property.
|
|
340
|
+
*/
|
|
341
|
+
readonly migrations?: TargetMigrationsCapability<TFamilyInstance>;
|
|
127
342
|
create(): TTargetInstance;
|
|
128
343
|
}
|
|
129
344
|
/**
|
|
130
|
-
* Descriptor for a control-plane adapter
|
|
345
|
+
* Descriptor for a control-plane adapter component (e.g., Postgres adapter).
|
|
131
346
|
*
|
|
132
347
|
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
133
348
|
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
|
|
134
349
|
* @template TAdapterInstance - The adapter instance type
|
|
135
350
|
*/
|
|
136
|
-
interface ControlAdapterDescriptor<TFamilyId extends string, TTargetId extends string, TAdapterInstance extends ControlAdapterInstance<TFamilyId, TTargetId> = ControlAdapterInstance<TFamilyId, TTargetId>> {
|
|
137
|
-
readonly kind: 'adapter';
|
|
138
|
-
readonly id: string;
|
|
139
|
-
readonly familyId: TFamilyId;
|
|
140
|
-
readonly targetId: TTargetId;
|
|
141
|
-
readonly manifest: ExtensionPackManifest;
|
|
351
|
+
interface ControlAdapterDescriptor<TFamilyId extends string, TTargetId extends string, TAdapterInstance extends ControlAdapterInstance<TFamilyId, TTargetId> = ControlAdapterInstance<TFamilyId, TTargetId>> extends AdapterDescriptor<TFamilyId, TTargetId> {
|
|
142
352
|
create(): TAdapterInstance;
|
|
143
353
|
}
|
|
144
354
|
/**
|
|
145
|
-
* Descriptor for a control-plane driver
|
|
355
|
+
* Descriptor for a control-plane driver component (e.g., Postgres driver).
|
|
146
356
|
*
|
|
147
357
|
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
148
358
|
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
|
|
149
359
|
* @template TDriverInstance - The driver instance type
|
|
150
360
|
*/
|
|
151
|
-
interface ControlDriverDescriptor<TFamilyId extends string, TTargetId extends string, TDriverInstance extends ControlDriverInstance<TTargetId> = ControlDriverInstance<TTargetId>> {
|
|
152
|
-
readonly kind: 'driver';
|
|
153
|
-
readonly id: string;
|
|
154
|
-
readonly familyId: TFamilyId;
|
|
155
|
-
readonly targetId: TTargetId;
|
|
156
|
-
readonly manifest: ExtensionPackManifest;
|
|
361
|
+
interface ControlDriverDescriptor<TFamilyId extends string, TTargetId extends string, TDriverInstance extends ControlDriverInstance<TFamilyId, TTargetId> = ControlDriverInstance<TFamilyId, TTargetId>> extends DriverDescriptor<TFamilyId, TTargetId> {
|
|
157
362
|
create(url: string): Promise<TDriverInstance>;
|
|
158
363
|
}
|
|
159
364
|
/**
|
|
160
|
-
* Descriptor for a control-plane extension
|
|
365
|
+
* Descriptor for a control-plane extension component (e.g., pgvector).
|
|
161
366
|
*
|
|
162
367
|
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
163
368
|
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
|
|
164
369
|
* @template TExtensionInstance - The extension instance type
|
|
165
370
|
*/
|
|
166
|
-
interface ControlExtensionDescriptor<TFamilyId extends string, TTargetId extends string, TExtensionInstance extends ControlExtensionInstance<TFamilyId, TTargetId> = ControlExtensionInstance<TFamilyId, TTargetId>> {
|
|
167
|
-
readonly kind: 'extension';
|
|
168
|
-
readonly id: string;
|
|
169
|
-
readonly familyId: TFamilyId;
|
|
170
|
-
readonly targetId: TTargetId;
|
|
171
|
-
readonly manifest: ExtensionPackManifest;
|
|
371
|
+
interface ControlExtensionDescriptor<TFamilyId extends string, TTargetId extends string, TExtensionInstance extends ControlExtensionInstance<TFamilyId, TTargetId> = ControlExtensionInstance<TFamilyId, TTargetId>> extends ExtensionDescriptor<TFamilyId, TTargetId> {
|
|
172
372
|
create(): TExtensionInstance;
|
|
173
373
|
}
|
|
174
|
-
/**
|
|
175
|
-
* Family instance interface for control-plane domain actions.
|
|
176
|
-
* Each family implements this interface with family-specific types.
|
|
177
|
-
*/
|
|
178
|
-
interface FamilyInstance<TFamilyId extends string, TSchemaIR = unknown, TVerifyResult = unknown, TSchemaVerifyResult = unknown, TSignResult = unknown> {
|
|
179
|
-
readonly familyId: TFamilyId;
|
|
180
|
-
/**
|
|
181
|
-
* Validates a contract JSON and returns a validated ContractIR (without mappings).
|
|
182
|
-
* Mappings are runtime-only and should not be part of ContractIR.
|
|
183
|
-
*/
|
|
184
|
-
validateContractIR(contractJson: unknown): unknown;
|
|
185
|
-
/**
|
|
186
|
-
* Verifies the database marker against the contract.
|
|
187
|
-
* Compares target, coreHash, and profileHash.
|
|
188
|
-
*/
|
|
189
|
-
verify(options: {
|
|
190
|
-
readonly driver: ControlDriverInstance;
|
|
191
|
-
readonly contractIR: unknown;
|
|
192
|
-
readonly expectedTargetId: string;
|
|
193
|
-
readonly contractPath: string;
|
|
194
|
-
readonly configPath?: string;
|
|
195
|
-
}): Promise<TVerifyResult>;
|
|
196
|
-
/**
|
|
197
|
-
* Verifies the database schema against the contract.
|
|
198
|
-
* Compares contract requirements against live database schema.
|
|
199
|
-
*/
|
|
200
|
-
schemaVerify(options: {
|
|
201
|
-
readonly driver: ControlDriverInstance;
|
|
202
|
-
readonly contractIR: unknown;
|
|
203
|
-
readonly strict: boolean;
|
|
204
|
-
readonly contractPath: string;
|
|
205
|
-
readonly configPath?: string;
|
|
206
|
-
}): Promise<TSchemaVerifyResult>;
|
|
207
|
-
/**
|
|
208
|
-
* Signs the database with the contract marker.
|
|
209
|
-
* Writes or updates the contract marker if schema verification passes.
|
|
210
|
-
* This operation is idempotent - if the marker already matches, no changes are made.
|
|
211
|
-
*/
|
|
212
|
-
sign(options: {
|
|
213
|
-
readonly driver: ControlDriverInstance;
|
|
214
|
-
readonly contractIR: unknown;
|
|
215
|
-
readonly contractPath: string;
|
|
216
|
-
readonly configPath?: string;
|
|
217
|
-
}): Promise<TSignResult>;
|
|
218
|
-
/**
|
|
219
|
-
* Introspects the database schema and returns a family-specific schema IR.
|
|
220
|
-
*
|
|
221
|
-
* This is a read-only operation that returns a snapshot of the live database schema.
|
|
222
|
-
* The method is family-owned and delegates to target/adapter-specific introspectors
|
|
223
|
-
* to perform the actual schema introspection.
|
|
224
|
-
*
|
|
225
|
-
* @param options - Introspection options
|
|
226
|
-
* @param options.driver - Control plane driver for database connection
|
|
227
|
-
* @param options.contractIR - Optional contract IR for contract-guided introspection.
|
|
228
|
-
* When provided, families may use it for filtering, optimization, or validation
|
|
229
|
-
* during introspection. The contract IR does not change the meaning of "what exists"
|
|
230
|
-
* in the database - it only guides how introspection is performed.
|
|
231
|
-
* @returns Promise resolving to the family-specific Schema IR (e.g., `SqlSchemaIR` for SQL).
|
|
232
|
-
* The IR represents the complete schema snapshot at the time of introspection.
|
|
233
|
-
*/
|
|
234
|
-
introspect(options: {
|
|
235
|
-
readonly driver: ControlDriverInstance;
|
|
236
|
-
readonly contractIR?: unknown;
|
|
237
|
-
}): Promise<TSchemaIR>;
|
|
238
|
-
/**
|
|
239
|
-
* Optionally projects a family-specific Schema IR into a core schema view.
|
|
240
|
-
* Families that provide this method enable rich tree output for CLI visualization.
|
|
241
|
-
* Families that do not provide it still support introspection via raw Schema IR.
|
|
242
|
-
*/
|
|
243
|
-
toSchemaView?(schema: TSchemaIR): CoreSchemaView;
|
|
244
|
-
/**
|
|
245
|
-
* Emits contract JSON and DTS as strings.
|
|
246
|
-
* Uses the instance's preassembled state (operation registry, type imports, extension IDs).
|
|
247
|
-
* Handles stripping mappings and validation internally.
|
|
248
|
-
*/
|
|
249
|
-
emitContract(options: {
|
|
250
|
-
readonly contractIR: ContractIR | unknown;
|
|
251
|
-
}): Promise<EmitContractResult>;
|
|
252
|
-
}
|
|
253
374
|
/**
|
|
254
375
|
* Result type for database marker verification operations.
|
|
255
376
|
*/
|
|
@@ -355,7 +476,7 @@ interface EmitContractResult {
|
|
|
355
476
|
*
|
|
356
477
|
* @template TSchemaIR - The family-specific Schema IR type (e.g., `SqlSchemaIR` for SQL)
|
|
357
478
|
*/
|
|
358
|
-
interface IntrospectSchemaResult<TSchemaIR
|
|
479
|
+
interface IntrospectSchemaResult<TSchemaIR> {
|
|
359
480
|
readonly ok: true;
|
|
360
481
|
readonly summary: string;
|
|
361
482
|
readonly target: {
|
|
@@ -403,4 +524,4 @@ interface SignDatabaseResult {
|
|
|
403
524
|
};
|
|
404
525
|
}
|
|
405
526
|
|
|
406
|
-
export type { ControlAdapterDescriptor, ControlAdapterInstance, ControlDriverDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlExtensionInstance, ControlFamilyDescriptor, ControlFamilyInstance, ControlTargetDescriptor, ControlTargetInstance, EmitContractResult,
|
|
527
|
+
export type { ControlAdapterDescriptor, ControlAdapterInstance, ControlDriverDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlExtensionInstance, ControlFamilyDescriptor, ControlFamilyInstance, ControlTargetDescriptor, ControlTargetInstance, EmitContractResult, IntrospectSchemaResult, MigrationOperationClass, MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlanner, MigrationPlannerConflict, MigrationPlannerFailureResult, MigrationPlannerResult, MigrationPlannerSuccessResult, MigrationRunner, MigrationRunnerFailure, MigrationRunnerResult, MigrationRunnerSuccessValue, OperationContext, SchemaIssue, SchemaVerificationNode, SignDatabaseResult, TargetMigrationsCapability, VerifyDatabaseResult, VerifyDatabaseSchemaResult };
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/core-control-plane",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.18",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "Control plane domain actions, config types, validation, and error factories for Prisma Next",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"arktype": "^2.1.26",
|
|
9
9
|
"prettier": "^3.3.3",
|
|
10
|
-
"@prisma-next/
|
|
11
|
-
"@prisma-next/
|
|
12
|
-
"@prisma-next/
|
|
10
|
+
"@prisma-next/operations": "0.1.0-dev.18",
|
|
11
|
+
"@prisma-next/utils": "0.1.0-dev.18",
|
|
12
|
+
"@prisma-next/contract": "0.1.0-dev.18"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"tsup": "^8.3.0",
|