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

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?: {
@@ -154,7 +154,7 @@ interface TargetMigrationsCapability<TFamilyInstance extends ControlFamilyInstan
154
154
  * @template TSchemaVerifyResult - The result type for schemaVerify()
155
155
  * @template TSignResult - The result type for sign()
156
156
  */
157
- interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = unknown, TVerifyResult = unknown, TSchemaVerifyResult = unknown, TSignResult = unknown> extends FamilyInstance<TFamilyId> {
157
+ interface ControlFamilyInstance<TFamilyId extends string, TSchemaIR = unknown, TVerifyResult = unknown, TSchemaVerifyResult = unknown, TSignResult = unknown> extends FamilyInstance<TFamilyId> {
158
158
  /**
159
159
  * Validates a contract JSON and returns a validated ContractIR (without mappings).
160
160
  * Mappings are runtime-only and should not be part of ContractIR.
@@ -165,7 +165,7 @@ interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = u
165
165
  * Compares target, coreHash, and profileHash.
166
166
  */
167
167
  verify(options: {
168
- readonly driver: ControlDriverInstance;
168
+ readonly driver: ControlDriverInstance<TFamilyId, string>;
169
169
  readonly contractIR: unknown;
170
170
  readonly expectedTargetId: string;
171
171
  readonly contractPath: string;
@@ -176,7 +176,7 @@ interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = u
176
176
  * Compares contract requirements against live database schema.
177
177
  */
178
178
  schemaVerify(options: {
179
- readonly driver: ControlDriverInstance;
179
+ readonly driver: ControlDriverInstance<TFamilyId, string>;
180
180
  readonly contractIR: unknown;
181
181
  readonly strict: boolean;
182
182
  readonly contractPath: string;
@@ -188,7 +188,7 @@ interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = u
188
188
  * This operation is idempotent - if the marker already matches, no changes are made.
189
189
  */
190
190
  sign(options: {
191
- readonly driver: ControlDriverInstance;
191
+ readonly driver: ControlDriverInstance<TFamilyId, string>;
192
192
  readonly contractIR: unknown;
193
193
  readonly contractPath: string;
194
194
  readonly configPath?: string;
@@ -210,7 +210,7 @@ interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = u
210
210
  * The IR represents the complete schema snapshot at the time of introspection.
211
211
  */
212
212
  introspect(options: {
213
- readonly driver: ControlDriverInstance;
213
+ readonly driver: ControlDriverInstance<TFamilyId, string>;
214
214
  readonly contractIR?: unknown;
215
215
  }): Promise<TSchemaIR>;
216
216
  /**
@@ -235,7 +235,7 @@ interface ControlFamilyInstance<TFamilyId extends string = string, TSchemaIR = u
235
235
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
236
236
  * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
237
237
  */
238
- interface ControlTargetInstance<TFamilyId extends string = string, TTargetId extends string = string> extends TargetInstance<TFamilyId, TTargetId> {
238
+ interface ControlTargetInstance<TFamilyId extends string, TTargetId extends string> extends TargetInstance<TFamilyId, TTargetId> {
239
239
  }
240
240
  /**
241
241
  * Control-plane adapter instance interface.
@@ -245,7 +245,7 @@ interface ControlTargetInstance<TFamilyId extends string = string, TTargetId ext
245
245
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
246
246
  * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
247
247
  */
248
- interface ControlAdapterInstance<TFamilyId extends string = string, TTargetId extends string = string> extends AdapterInstance<TFamilyId, TTargetId> {
248
+ interface ControlAdapterInstance<TFamilyId extends string, TTargetId extends string> extends AdapterInstance<TFamilyId, TTargetId> {
249
249
  }
250
250
  /**
251
251
  * Control-plane driver instance interface.
@@ -254,7 +254,7 @@ interface ControlAdapterInstance<TFamilyId extends string = string, TTargetId ex
254
254
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
255
255
  * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
256
256
  */
257
- interface ControlDriverInstance<TFamilyId extends string = string, TTargetId extends string = string> extends DriverInstance<TFamilyId, TTargetId> {
257
+ interface ControlDriverInstance<TFamilyId extends string, TTargetId extends string> extends DriverInstance<TFamilyId, TTargetId> {
258
258
  query<Row = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<{
259
259
  readonly rows: Row[];
260
260
  }>;
@@ -267,7 +267,7 @@ interface ControlDriverInstance<TFamilyId extends string = string, TTargetId ext
267
267
  * @template TFamilyId - The family ID (e.g., 'sql', 'document')
268
268
  * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
269
269
  */
270
- interface ControlExtensionInstance<TFamilyId extends string = string, TTargetId extends string = string> extends ExtensionInstance<TFamilyId, TTargetId> {
270
+ interface ControlExtensionInstance<TFamilyId extends string, TTargetId extends string> extends ExtensionInstance<TFamilyId, TTargetId> {
271
271
  }
272
272
  /**
273
273
  * Operation context for propagating metadata through control-plane operation call chains.
@@ -471,7 +471,7 @@ interface EmitContractResult {
471
471
  *
472
472
  * @template TSchemaIR - The family-specific Schema IR type (e.g., `SqlSchemaIR` for SQL)
473
473
  */
474
- interface IntrospectSchemaResult<TSchemaIR = unknown> {
474
+ interface IntrospectSchemaResult<TSchemaIR> {
475
475
  readonly ok: true;
476
476
  readonly summary: string;
477
477
  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.3",
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.3",
11
+ "@prisma-next/operations": "0.1.0-pr.56.3",
12
+ "@prisma-next/utils": "0.1.0-pr.56.3"
13
13
  },
14
14
  "devDependencies": {
15
15
  "tsup": "^8.3.0",