@prisma-next/core-control-plane 0.1.0-pr.56.2 → 0.1.0-pr.56.4

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 +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;\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;AAwErB,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
+ {"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":[]}
@@ -124,7 +124,7 @@ interface MigrationPlanner {
124
124
  interface MigrationRunner {
125
125
  execute(options: {
126
126
  readonly plan: MigrationPlan;
127
- readonly driver: ControlDriverInstance;
127
+ readonly driver: ControlDriverInstance<string, string>;
128
128
  readonly destinationContract: unknown;
129
129
  readonly policy: MigrationOperationPolicy;
130
130
  readonly callbacks?: {
@@ -149,12 +149,9 @@ interface TargetMigrationsCapability<TFamilyInstance extends ControlFamilyInstan
149
149
  * Extends the base FamilyInstance with control-plane domain actions.
150
150
  *
151
151
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
152
- * @template TSchemaIR - The schema IR type returned by introspect()
153
- * @template TVerifyResult - The result type for verify()
154
- * @template TSchemaVerifyResult - The result type for schemaVerify()
155
- * @template TSignResult - The result type for sign()
152
+ * @template TSchemaIR - The schema IR type returned by introspect() (family-specific)
156
153
  */
157
- interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = unknown, TVerifyResult = unknown, TSchemaVerifyResult = unknown, TSignResult = unknown> extends FamilyInstance<TFamilyId> {
154
+ interface ControlFamilyInstance<TFamilyId extends string, TSchemaIR = unknown> extends FamilyInstance<TFamilyId> {
158
155
  /**
159
156
  * Validates a contract JSON and returns a validated ContractIR (without mappings).
160
157
  * Mappings are runtime-only and should not be part of ContractIR.
@@ -165,34 +162,34 @@ interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = u
165
162
  * Compares target, coreHash, and profileHash.
166
163
  */
167
164
  verify(options: {
168
- readonly driver: ControlDriverInstance;
165
+ readonly driver: ControlDriverInstance<TFamilyId, string>;
169
166
  readonly contractIR: unknown;
170
167
  readonly expectedTargetId: string;
171
168
  readonly contractPath: string;
172
169
  readonly configPath?: string;
173
- }): Promise<TVerifyResult>;
170
+ }): Promise<VerifyDatabaseResult>;
174
171
  /**
175
172
  * Verifies the database schema against the contract.
176
173
  * Compares contract requirements against live database schema.
177
174
  */
178
175
  schemaVerify(options: {
179
- readonly driver: ControlDriverInstance;
176
+ readonly driver: ControlDriverInstance<TFamilyId, string>;
180
177
  readonly contractIR: unknown;
181
178
  readonly strict: boolean;
182
179
  readonly contractPath: string;
183
180
  readonly configPath?: string;
184
- }): Promise<TSchemaVerifyResult>;
181
+ }): Promise<VerifyDatabaseSchemaResult>;
185
182
  /**
186
183
  * Signs the database with the contract marker.
187
184
  * Writes or updates the contract marker if schema verification passes.
188
185
  * This operation is idempotent - if the marker already matches, no changes are made.
189
186
  */
190
187
  sign(options: {
191
- readonly driver: ControlDriverInstance;
188
+ readonly driver: ControlDriverInstance<TFamilyId, string>;
192
189
  readonly contractIR: unknown;
193
190
  readonly contractPath: string;
194
191
  readonly configPath?: string;
195
- }): Promise<TSignResult>;
192
+ }): Promise<SignDatabaseResult>;
196
193
  /**
197
194
  * Introspects the database schema and returns a family-specific schema IR.
198
195
  *
@@ -210,7 +207,7 @@ interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = u
210
207
  * The IR represents the complete schema snapshot at the time of introspection.
211
208
  */
212
209
  introspect(options: {
213
- readonly driver: ControlDriverInstance;
210
+ readonly driver: ControlDriverInstance<TFamilyId, string>;
214
211
  readonly contractIR?: unknown;
215
212
  }): Promise<TSchemaIR>;
216
213
  /**
@@ -235,7 +232,7 @@ interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = u
235
232
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
236
233
  * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
237
234
  */
238
- interface ControlTargetInstance<TFamilyId extends string = string, TTargetId extends string = string> extends TargetInstance<TFamilyId, TTargetId> {
235
+ interface ControlTargetInstance<TFamilyId extends string, TTargetId extends string> extends TargetInstance<TFamilyId, TTargetId> {
239
236
  }
240
237
  /**
241
238
  * Control-plane adapter instance interface.
@@ -245,7 +242,7 @@ interface ControlTargetInstance<TFamilyId extends string = string, TTargetId ext
245
242
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
246
243
  * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
247
244
  */
248
- interface ControlAdapterInstance<TFamilyId extends string = string, TTargetId extends string = string> extends AdapterInstance<TFamilyId, TTargetId> {
245
+ interface ControlAdapterInstance<TFamilyId extends string, TTargetId extends string> extends AdapterInstance<TFamilyId, TTargetId> {
249
246
  }
250
247
  /**
251
248
  * Control-plane driver instance interface.
@@ -254,7 +251,7 @@ interface ControlAdapterInstance<TFamilyId extends string = string, TTargetId ex
254
251
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
255
252
  * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
256
253
  */
257
- interface ControlDriverInstance<TFamilyId extends string = string, TTargetId extends string = string> extends DriverInstance<TFamilyId, TTargetId> {
254
+ interface ControlDriverInstance<TFamilyId extends string, TTargetId extends string> extends DriverInstance<TFamilyId, TTargetId> {
258
255
  query<Row = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<{
259
256
  readonly rows: Row[];
260
257
  }>;
@@ -267,7 +264,7 @@ interface ControlDriverInstance<TFamilyId extends string = string, TTargetId ext
267
264
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
268
265
  * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
269
266
  */
270
- interface ControlExtensionInstance<TFamilyId extends string = string, TTargetId extends string = string> extends ExtensionInstance<TFamilyId, TTargetId> {
267
+ interface ControlExtensionInstance<TFamilyId extends string, TTargetId extends string> extends ExtensionInstance<TFamilyId, TTargetId> {
271
268
  }
272
269
  /**
273
270
  * Operation context for propagating metadata through control-plane operation call chains.
@@ -471,7 +468,7 @@ interface EmitContractResult {
471
468
  *
472
469
  * @template TSchemaIR - The family-specific Schema IR type (e.g., `SqlSchemaIR` for SQL)
473
470
  */
474
- interface IntrospectSchemaResult<TSchemaIR = unknown> {
471
+ interface IntrospectSchemaResult<TSchemaIR> {
475
472
  readonly ok: true;
476
473
  readonly summary: string;
477
474
  readonly target: {
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@prisma-next/core-control-plane",
3
- "version": "0.1.0-pr.56.2",
3
+ "version": "0.1.0-pr.56.4",
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/contract": "0.1.0-pr.56.2",
11
- "@prisma-next/operations": "0.1.0-pr.56.2",
12
- "@prisma-next/utils": "0.1.0-pr.56.2"
10
+ "@prisma-next/contract": "0.1.0-pr.56.4",
11
+ "@prisma-next/operations": "0.1.0-pr.56.4",
12
+ "@prisma-next/utils": "0.1.0-pr.56.4"
13
13
  },
14
14
  "devDependencies": {
15
15
  "tsup": "^8.3.0",