@prisma-next/core-control-plane 0.1.0-dev.29 → 0.1.0-dev.30

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.
@@ -119,6 +119,19 @@ function errorDriverRequired(options) {
119
119
  docsUrl: "https://prisma-next.dev/docs/cli/config"
120
120
  });
121
121
  }
122
+ function errorContractMissingExtensionPacks(options) {
123
+ const missing = [...options.missingExtensionPacks].sort();
124
+ return new CliStructuredError("4011", "Missing extension packs in config", {
125
+ domain: "CLI",
126
+ why: missing.length === 1 ? `Contract requires extension pack '${missing[0]}', but CLI config does not provide a matching descriptor.` : `Contract requires extension packs ${missing.map((p) => `'${p}'`).join(", ")}, but CLI config does not provide matching descriptors.`,
127
+ fix: "Add the missing extension descriptors to `extensions` in prisma-next.config.ts",
128
+ docsUrl: "https://prisma-next.dev/docs/cli/config",
129
+ meta: {
130
+ missingExtensionPacks: missing,
131
+ providedComponentIds: [...options.providedComponentIds].sort()
132
+ }
133
+ });
134
+ }
122
135
  function errorMigrationPlanningFailed(options) {
123
136
  const conflictSummaries = options.conflicts.map((c) => c.summary);
124
137
  const computedWhy = options.why ?? conflictSummaries.join("\n");
@@ -203,6 +216,7 @@ export {
203
216
  errorFamilyReadMarkerSqlRequired,
204
217
  errorJsonFormatNotSupported,
205
218
  errorDriverRequired,
219
+ errorContractMissingExtensionPacks,
206
220
  errorMigrationPlanningFailed,
207
221
  errorTargetMigrationNotSupported,
208
222
  errorConfigValidation,
@@ -212,4 +226,4 @@ export {
212
226
  errorRuntime,
213
227
  errorUnexpected
214
228
  };
215
- //# sourceMappingURL=chunk-FKWEUJ6X.js.map
229
+ //# sourceMappingURL=chunk-U5RYT6PT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/**\n * CLI error envelope for output formatting.\n * This is the serialized form of a CliStructuredError.\n */\nexport interface CliErrorEnvelope {\n readonly code: string;\n readonly domain: string;\n readonly severity: 'error' | 'warn' | 'info';\n readonly summary: string;\n readonly why: string | undefined;\n readonly fix: string | undefined;\n readonly where:\n | {\n readonly path: string | undefined;\n readonly line: number | undefined;\n }\n | undefined;\n readonly meta: Record<string, unknown> | undefined;\n readonly docsUrl: string | undefined;\n}\n\n/**\n * Minimal conflict data structure expected by CLI output.\n */\nexport interface CliErrorConflict {\n readonly kind: string;\n readonly summary: string;\n readonly why?: string;\n}\n\n/**\n * Structured CLI error that contains all information needed for error envelopes.\n * Call sites throw these errors with full context.\n */\nexport class CliStructuredError extends Error {\n readonly code: string;\n readonly domain: 'CLI' | 'RTM';\n readonly severity: 'error' | 'warn' | 'info';\n readonly why: string | undefined;\n readonly fix: string | undefined;\n readonly where:\n | {\n readonly path: string | undefined;\n readonly line: number | undefined;\n }\n | undefined;\n readonly meta: Record<string, unknown> | undefined;\n readonly docsUrl: string | undefined;\n\n constructor(\n code: string,\n summary: string,\n options?: {\n readonly domain?: 'CLI' | 'RTM';\n readonly severity?: 'error' | 'warn' | 'info';\n readonly why?: string;\n readonly fix?: string;\n readonly where?: { readonly path?: string; readonly line?: number };\n readonly meta?: Record<string, unknown>;\n readonly docsUrl?: string;\n },\n ) {\n super(summary);\n this.name = 'CliStructuredError';\n this.code = code;\n this.domain = options?.domain ?? 'CLI';\n this.severity = options?.severity ?? 'error';\n this.why = options?.why;\n this.fix = options?.fix;\n this.where = options?.where\n ? {\n path: options.where.path,\n line: options.where.line,\n }\n : undefined;\n this.meta = options?.meta;\n this.docsUrl = options?.docsUrl;\n }\n\n /**\n * Converts this error to a CLI error envelope for output formatting.\n */\n toEnvelope(): CliErrorEnvelope {\n const codePrefix = this.domain === 'CLI' ? 'PN-CLI-' : 'PN-RTM-';\n return {\n code: `${codePrefix}${this.code}`,\n domain: this.domain,\n severity: this.severity,\n summary: this.message,\n why: this.why,\n fix: this.fix,\n where: this.where,\n meta: this.meta,\n docsUrl: this.docsUrl,\n };\n }\n}\n\n// ============================================================================\n// Config Errors (PN-CLI-4001-4007)\n// ============================================================================\n\n/**\n * Config file not found or missing.\n */\nexport function errorConfigFileNotFound(\n configPath?: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4001', 'Config file not found', {\n domain: 'CLI',\n ...(options?.why ? { why: options.why } : { why: 'Config file not found' }),\n fix: \"Run 'prisma-next init' to create a config file\",\n docsUrl: 'https://prisma-next.dev/docs/cli/config',\n ...(configPath ? { where: { path: configPath } } : {}),\n });\n}\n\n/**\n * Contract configuration missing from config.\n */\nexport function errorContractConfigMissing(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4002', 'Contract configuration missing', {\n domain: 'CLI',\n why: options?.why ?? 'The contract configuration is required for emit',\n fix: 'Add contract configuration to your prisma-next.config.ts',\n docsUrl: 'https://prisma-next.dev/docs/cli/contract-emit',\n });\n}\n\n/**\n * Contract validation failed.\n */\nexport function errorContractValidationFailed(\n reason: string,\n options?: {\n readonly where?: { readonly path?: string; readonly line?: number };\n },\n): CliStructuredError {\n return new CliStructuredError('4003', 'Contract validation failed', {\n domain: 'CLI',\n why: reason,\n fix: 'Re-run `prisma-next contract emit`, or fix the contract file and try again',\n docsUrl: 'https://prisma-next.dev/docs/contracts',\n ...(options?.where ? { where: options.where } : {}),\n });\n}\n\n/**\n * File not found.\n */\nexport function errorFileNotFound(\n filePath: string,\n options?: {\n readonly why?: string;\n readonly fix?: string;\n readonly docsUrl?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4004', 'File not found', {\n domain: 'CLI',\n why: options?.why ?? `File not found: ${filePath}`,\n fix: options?.fix ?? 'Check that the file path is correct',\n where: { path: filePath },\n ...(options?.docsUrl ? { docsUrl: options.docsUrl } : {}),\n });\n}\n\n/**\n * Database URL is required but not provided.\n */\nexport function errorDatabaseUrlRequired(options?: { readonly why?: string }): CliStructuredError {\n return new CliStructuredError('4005', 'Database URL is required', {\n domain: 'CLI',\n why: options?.why ?? 'Database URL is required for this command',\n fix: 'Provide `--db <url>` or set `db: { url: \"postgres://…\" }` in prisma-next.config.ts',\n });\n}\n\n/**\n * Query runner factory is required but not provided in config.\n */\nexport function errorQueryRunnerFactoryRequired(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4006', 'Query runner factory is required', {\n domain: 'CLI',\n why: options?.why ?? 'Config.db.queryRunnerFactory is required for db verify',\n fix: 'Add db.queryRunnerFactory to prisma-next.config.ts',\n docsUrl: 'https://prisma-next.dev/docs/cli/db-verify',\n });\n}\n\n/**\n * Family verify.readMarker is required but not provided.\n */\nexport function errorFamilyReadMarkerSqlRequired(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4007', 'Family readMarker() is required', {\n domain: 'CLI',\n why: options?.why ?? 'Family verify.readMarker is required for db verify',\n fix: 'Ensure family.verify.readMarker() is exported by your family package',\n docsUrl: 'https://prisma-next.dev/docs/cli/db-verify',\n });\n}\n\n/**\n * JSON output format not supported.\n */\nexport function errorJsonFormatNotSupported(options: {\n readonly command: string;\n readonly format: string;\n readonly supportedFormats: readonly string[];\n}): CliStructuredError {\n return new CliStructuredError('4008', 'Unsupported JSON format', {\n domain: 'CLI',\n why: `The ${options.command} command does not support --json ${options.format}`,\n fix: `Use --json ${options.supportedFormats.join(' or ')}, or omit --json for human output`,\n meta: {\n command: options.command,\n format: options.format,\n supportedFormats: options.supportedFormats,\n },\n });\n}\n\n/**\n * Driver is required for DB-connected commands but not provided.\n */\nexport function errorDriverRequired(options?: { readonly why?: string }): CliStructuredError {\n return new CliStructuredError('4010', 'Driver is required for DB-connected commands', {\n domain: 'CLI',\n why: options?.why ?? 'Config.driver is required for DB-connected commands',\n fix: 'Add a control-plane driver to prisma-next.config.ts (e.g. import a driver descriptor and set `driver: postgresDriver`)',\n docsUrl: 'https://prisma-next.dev/docs/cli/config',\n });\n}\n\n/**\n * Contract requires extension packs that are not provided by config descriptors.\n */\nexport function errorContractMissingExtensionPacks(options: {\n readonly missingExtensionPacks: readonly string[];\n readonly providedComponentIds: readonly string[];\n}): CliStructuredError {\n const missing = [...options.missingExtensionPacks].sort();\n return new CliStructuredError('4011', 'Missing extension packs in config', {\n domain: 'CLI',\n why:\n missing.length === 1\n ? `Contract requires extension pack '${missing[0]}', but CLI config does not provide a matching descriptor.`\n : `Contract requires extension packs ${missing.map((p) => `'${p}'`).join(', ')}, but CLI config does not provide matching descriptors.`,\n fix: 'Add the missing extension descriptors to `extensions` in prisma-next.config.ts',\n docsUrl: 'https://prisma-next.dev/docs/cli/config',\n meta: {\n missingExtensionPacks: missing,\n providedComponentIds: [...options.providedComponentIds].sort(),\n },\n });\n}\n\n/**\n * Migration planning failed due to conflicts.\n */\nexport function errorMigrationPlanningFailed(options: {\n readonly conflicts: readonly CliErrorConflict[];\n readonly why?: string;\n}): CliStructuredError {\n // Build \"why\" from conflict summaries - these contain the actual problem description\n const conflictSummaries = options.conflicts.map((c) => c.summary);\n const computedWhy = options.why ?? conflictSummaries.join('\\n');\n\n // Build \"fix\" from conflict \"why\" fields - these contain actionable advice\n const conflictFixes = options.conflicts\n .map((c) => c.why)\n .filter((why): why is string => typeof why === 'string');\n const computedFix =\n conflictFixes.length > 0\n ? conflictFixes.join('\\n')\n : 'Use `db schema-verify` to inspect conflicts, or ensure the database is empty';\n\n return new CliStructuredError('4020', 'Migration planning failed', {\n domain: 'CLI',\n why: computedWhy,\n fix: computedFix,\n meta: { conflicts: options.conflicts },\n docsUrl: 'https://prisma-next.dev/docs/cli/db-init',\n });\n}\n\n/**\n * Target does not support migrations (missing createPlanner/createRunner).\n */\nexport function errorTargetMigrationNotSupported(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4021', 'Target does not support migrations', {\n domain: 'CLI',\n why: options?.why ?? 'The configured target does not provide migration planner/runner',\n fix: 'Select a target that provides migrations (it must export `target.migrations` for db init)',\n docsUrl: 'https://prisma-next.dev/docs/cli/db-init',\n });\n}\n\n/**\n * Config validation error (missing required fields).\n */\nexport function errorConfigValidation(\n field: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4001', 'Config file not found', {\n domain: 'CLI',\n why: options?.why ?? `Config must have a \"${field}\" field`,\n fix: \"Run 'prisma-next init' to create a config file\",\n docsUrl: 'https://prisma-next.dev/docs/cli/config',\n });\n}\n\n// ============================================================================\n// Runtime Errors (PN-RTM-3000-3003)\n// ============================================================================\n\n/**\n * Contract marker not found in database.\n */\nexport function errorMarkerMissing(options?: {\n readonly why?: string;\n readonly dbUrl?: string;\n}): CliStructuredError {\n return new CliStructuredError('3001', 'Marker missing', {\n domain: 'RTM',\n why: options?.why ?? 'Contract marker not found in database',\n fix: 'Run `prisma-next db sign --db <url>` to create marker',\n });\n}\n\n/**\n * Contract hash does not match database marker.\n */\nexport function errorHashMismatch(options?: {\n readonly why?: string;\n readonly expected?: string;\n readonly actual?: string;\n}): CliStructuredError {\n return new CliStructuredError('3002', 'Hash mismatch', {\n domain: 'RTM',\n why: options?.why ?? 'Contract hash does not match database marker',\n fix: 'Migrate database or re-sign if intentional',\n ...(options?.expected || options?.actual\n ? {\n meta: {\n ...(options.expected ? { expected: options.expected } : {}),\n ...(options.actual ? { actual: options.actual } : {}),\n },\n }\n : {}),\n });\n}\n\n/**\n * Contract target does not match config target.\n */\nexport function errorTargetMismatch(\n expected: string,\n actual: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('3003', 'Target mismatch', {\n domain: 'RTM',\n why:\n options?.why ??\n `Contract target does not match config target (expected: ${expected}, actual: ${actual})`,\n fix: 'Align contract target and config target',\n meta: { expected, actual },\n });\n}\n\n/**\n * Generic runtime error.\n */\nexport function errorRuntime(\n summary: string,\n options?: {\n readonly why?: string;\n readonly fix?: string;\n readonly meta?: Record<string, unknown>;\n },\n): CliStructuredError {\n return new CliStructuredError('3000', summary, {\n domain: 'RTM',\n ...(options?.why ? { why: options.why } : { why: 'Verification failed' }),\n ...(options?.fix ? { fix: options.fix } : { fix: 'Check contract and database state' }),\n ...(options?.meta ? { meta: options.meta } : {}),\n });\n}\n\n// ============================================================================\n// Generic Error\n// ============================================================================\n\n/**\n * Generic unexpected error.\n */\nexport function errorUnexpected(\n message: string,\n options?: {\n readonly why?: string;\n readonly fix?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4999', 'Unexpected error', {\n domain: 'CLI',\n why: options?.why ?? message,\n fix: options?.fix ?? 'Check the error message and try again',\n });\n}\n"],"mappings":"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","names":[]}
@@ -37,7 +37,7 @@ interface PrismaNextConfig<TFamilyId extends string = string, TTargetId extends
37
37
  readonly family: ControlFamilyDescriptor<TFamilyId>;
38
38
  readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
39
39
  readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
40
- readonly extensions?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
40
+ readonly extensionPacks?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
41
41
  /**
42
42
  * Driver descriptor for DB-connected CLI commands.
43
43
  * Required for DB-connected commands (e.g., db verify).
@@ -14,7 +14,7 @@ var PrismaNextConfigSchema = type({
14
14
  // ControlTargetDescriptor - validated separately
15
15
  adapter: "unknown",
16
16
  // ControlAdapterDescriptor - validated separately
17
- "extensions?": "unknown[]",
17
+ "extensionPacks?": "unknown[]",
18
18
  "driver?": "unknown",
19
19
  // ControlDriverDescriptor - validated separately (optional)
20
20
  "db?": "unknown",
@@ -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 * 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
+ {"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 extensionPacks?: 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 'extensionPacks?': '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,mBAAmB;AAAA,EACnB,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,6 +1,6 @@
1
1
  import {
2
2
  errorConfigValidation
3
- } from "../chunk-FKWEUJ6X.js";
3
+ } from "../chunk-U5RYT6PT.js";
4
4
 
5
5
  // src/config-validation.ts
6
6
  function validateConfig(config) {
@@ -30,9 +30,9 @@ function validateConfig(config) {
30
30
  why: "Config.family must have familyId: string"
31
31
  });
32
32
  }
33
- if (!family["manifest"] || typeof family["manifest"] !== "object") {
34
- throw errorConfigValidation("family.manifest", {
35
- why: "Config.family must have manifest: ExtensionPackManifest"
33
+ if (typeof family["version"] !== "string") {
34
+ throw errorConfigValidation("family.version", {
35
+ why: "Config.family must have version: string"
36
36
  });
37
37
  }
38
38
  if (!family["hook"] || typeof family["hook"] !== "object") {
@@ -62,9 +62,9 @@ function validateConfig(config) {
62
62
  why: "Config.target must have familyId: string"
63
63
  });
64
64
  }
65
- if (!target["manifest"] || typeof target["manifest"] !== "object") {
66
- throw errorConfigValidation("target.manifest", {
67
- why: "Config.target must have manifest: ExtensionPackManifest"
65
+ if (typeof target["version"] !== "string") {
66
+ throw errorConfigValidation("target.version", {
67
+ why: "Config.target must have version: string"
68
68
  });
69
69
  }
70
70
  if (target["familyId"] !== familyId) {
@@ -99,9 +99,9 @@ function validateConfig(config) {
99
99
  why: "Config.adapter must have familyId: string"
100
100
  });
101
101
  }
102
- if (!adapter["manifest"] || typeof adapter["manifest"] !== "object") {
103
- throw errorConfigValidation("adapter.manifest", {
104
- why: "Config.adapter must have manifest: ExtensionPackManifest"
102
+ if (typeof adapter["version"] !== "string") {
103
+ throw errorConfigValidation("adapter.version", {
104
+ why: "Config.adapter must have version: string"
105
105
  });
106
106
  }
107
107
  if (adapter["familyId"] !== familyId) {
@@ -152,9 +152,9 @@ function validateConfig(config) {
152
152
  why: "Config.extensions items must have familyId: string"
153
153
  });
154
154
  }
155
- if (!extObj["manifest"] || typeof extObj["manifest"] !== "object") {
156
- throw errorConfigValidation("extensions[].manifest", {
157
- why: "Config.extensions items must have manifest: ExtensionPackManifest"
155
+ if (typeof extObj["version"] !== "string") {
156
+ throw errorConfigValidation("extensions[].version", {
157
+ why: "Config.extensions items must have version: string"
158
158
  });
159
159
  }
160
160
  if (extObj["familyId"] !== familyId) {
@@ -191,9 +191,9 @@ function validateConfig(config) {
191
191
  why: "Config.driver must have id: string"
192
192
  });
193
193
  }
194
- if (!driver["manifest"] || typeof driver["manifest"] !== "object") {
195
- throw errorConfigValidation("driver.manifest", {
196
- why: "Config.driver must have manifest: ExtensionPackManifest"
194
+ if (typeof driver["version"] !== "string") {
195
+ throw errorConfigValidation("driver.version", {
196
+ why: "Config.driver must have version: string"
197
197
  });
198
198
  }
199
199
  if (typeof driver["familyId"] !== "string") {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config-validation.ts"],"sourcesContent":["import type { PrismaNextConfig } from './config-types';\nimport { errorConfigValidation } from './errors';\n\n/**\n * Validates that the config has the required structure.\n * This is pure validation logic with no file I/O or CLI awareness.\n *\n * @param config - Config object to validate\n * @throws CliStructuredError if config structure is invalid\n */\nexport function validateConfig(config: unknown): asserts config is PrismaNextConfig {\n if (!config || typeof config !== 'object') {\n throw errorConfigValidation('object', {\n why: 'Config must be an object',\n });\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!configObj['family']) {\n throw errorConfigValidation('family');\n }\n\n if (!configObj['target']) {\n throw errorConfigValidation('target');\n }\n\n if (!configObj['adapter']) {\n throw errorConfigValidation('adapter');\n }\n\n // Validate family descriptor\n const family = configObj['family'] as Record<string, unknown>;\n if (family['kind'] !== 'family') {\n throw errorConfigValidation('family.kind', {\n why: 'Config.family must have kind: \"family\"',\n });\n }\n if (typeof family['familyId'] !== 'string') {\n throw errorConfigValidation('family.familyId', {\n why: 'Config.family must have familyId: string',\n });\n }\n if (!family['manifest'] || typeof family['manifest'] !== 'object') {\n throw errorConfigValidation('family.manifest', {\n why: 'Config.family must have manifest: ExtensionPackManifest',\n });\n }\n if (!family['hook'] || typeof family['hook'] !== 'object') {\n throw errorConfigValidation('family.hook', {\n why: 'Config.family must have hook: TargetFamilyHook',\n });\n }\n if (typeof family['create'] !== 'function') {\n throw errorConfigValidation('family.create', {\n why: 'Config.family must have create: function',\n });\n }\n\n const familyId = family['familyId'] as string;\n\n // Validate target descriptor\n const target = configObj['target'] as Record<string, unknown>;\n if (target['kind'] !== 'target') {\n throw errorConfigValidation('target.kind', {\n why: 'Config.target must have kind: \"target\"',\n });\n }\n if (typeof target['id'] !== 'string') {\n throw errorConfigValidation('target.id', {\n why: 'Config.target must have id: string',\n });\n }\n if (typeof target['familyId'] !== 'string') {\n throw errorConfigValidation('target.familyId', {\n why: 'Config.target must have familyId: string',\n });\n }\n if (!target['manifest'] || typeof target['manifest'] !== 'object') {\n throw errorConfigValidation('target.manifest', {\n why: 'Config.target must have manifest: ExtensionPackManifest',\n });\n }\n if (target['familyId'] !== familyId) {\n throw errorConfigValidation('target.familyId', {\n why: `Config.target.familyId must match Config.family.familyId (expected: ${familyId}, got: ${target['familyId']})`,\n });\n }\n if (typeof target['targetId'] !== 'string') {\n throw errorConfigValidation('target.targetId', {\n why: 'Config.target must have targetId: string',\n });\n }\n if (typeof target['create'] !== 'function') {\n throw errorConfigValidation('target.create', {\n why: 'Config.target must have create: function',\n });\n }\n const expectedTargetId = target['targetId'] as string;\n\n // Validate adapter descriptor\n const adapter = configObj['adapter'] as Record<string, unknown>;\n if (adapter['kind'] !== 'adapter') {\n throw errorConfigValidation('adapter.kind', {\n why: 'Config.adapter must have kind: \"adapter\"',\n });\n }\n if (typeof adapter['id'] !== 'string') {\n throw errorConfigValidation('adapter.id', {\n why: 'Config.adapter must have id: string',\n });\n }\n if (typeof adapter['familyId'] !== 'string') {\n throw errorConfigValidation('adapter.familyId', {\n why: 'Config.adapter must have familyId: string',\n });\n }\n if (!adapter['manifest'] || typeof adapter['manifest'] !== 'object') {\n throw errorConfigValidation('adapter.manifest', {\n why: 'Config.adapter must have manifest: ExtensionPackManifest',\n });\n }\n if (adapter['familyId'] !== familyId) {\n throw errorConfigValidation('adapter.familyId', {\n why: `Config.adapter.familyId must match Config.family.familyId (expected: ${familyId}, got: ${adapter['familyId']})`,\n });\n }\n if (typeof adapter['targetId'] !== 'string') {\n throw errorConfigValidation('adapter.targetId', {\n why: 'Config.adapter must have targetId: string',\n });\n }\n if (adapter['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('adapter.targetId', {\n why: `Config.adapter.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${adapter['targetId']})`,\n });\n }\n if (typeof adapter['create'] !== 'function') {\n throw errorConfigValidation('adapter.create', {\n why: 'Config.adapter must have create: function',\n });\n }\n\n // Validate extensions array if present\n if (configObj['extensions'] !== undefined) {\n if (!Array.isArray(configObj['extensions'])) {\n throw errorConfigValidation('extensions', {\n why: 'Config.extensions must be an array',\n });\n }\n for (const ext of configObj['extensions']) {\n if (!ext || typeof ext !== 'object') {\n throw errorConfigValidation('extensions[]', {\n why: 'Config.extensions must contain ExtensionDescriptor objects',\n });\n }\n const extObj = ext as Record<string, unknown>;\n if (extObj['kind'] !== 'extension') {\n throw errorConfigValidation('extensions[].kind', {\n why: 'Config.extensions items must have kind: \"extension\"',\n });\n }\n if (typeof extObj['id'] !== 'string') {\n throw errorConfigValidation('extensions[].id', {\n why: 'Config.extensions items must have id: string',\n });\n }\n if (typeof extObj['familyId'] !== 'string') {\n throw errorConfigValidation('extensions[].familyId', {\n why: 'Config.extensions items must have familyId: string',\n });\n }\n if (!extObj['manifest'] || typeof extObj['manifest'] !== 'object') {\n throw errorConfigValidation('extensions[].manifest', {\n why: 'Config.extensions items must have manifest: ExtensionPackManifest',\n });\n }\n if (extObj['familyId'] !== familyId) {\n throw errorConfigValidation('extensions[].familyId', {\n why: `Config.extensions[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj['familyId']})`,\n });\n }\n if (typeof extObj['targetId'] !== 'string') {\n throw errorConfigValidation('extensions[].targetId', {\n why: 'Config.extensions items must have targetId: string',\n });\n }\n if (extObj['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('extensions[].targetId', {\n why: `Config.extensions[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj['targetId']})`,\n });\n }\n if (typeof extObj['create'] !== 'function') {\n throw errorConfigValidation('extensions[].create', {\n why: 'Config.extensions items must have create: function',\n });\n }\n }\n }\n\n // Validate driver descriptor if present\n if (configObj['driver'] !== undefined) {\n const driver = configObj['driver'] as Record<string, unknown>;\n if (driver['kind'] !== 'driver') {\n throw errorConfigValidation('driver.kind', {\n why: 'Config.driver must have kind: \"driver\"',\n });\n }\n if (typeof driver['id'] !== 'string') {\n throw errorConfigValidation('driver.id', {\n why: 'Config.driver must have id: string',\n });\n }\n if (!driver['manifest'] || typeof driver['manifest'] !== 'object') {\n throw errorConfigValidation('driver.manifest', {\n why: 'Config.driver must have manifest: ExtensionPackManifest',\n });\n }\n if (typeof driver['familyId'] !== 'string') {\n throw errorConfigValidation('driver.familyId', {\n why: 'Config.driver must have familyId: string',\n });\n }\n if (driver['familyId'] !== familyId) {\n throw errorConfigValidation('driver.familyId', {\n why: `Config.driver.familyId must match Config.family.familyId (expected: ${familyId}, got: ${driver['familyId']})`,\n });\n }\n if (typeof driver['targetId'] !== 'string') {\n throw errorConfigValidation('driver.targetId', {\n why: 'Config.driver must have targetId: string',\n });\n }\n if (driver['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('driver.targetId', {\n why: `Config.driver.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${driver['targetId']})`,\n });\n }\n if (typeof driver['create'] !== 'function') {\n throw errorConfigValidation('driver.create', {\n why: 'Config.driver must have create: function',\n });\n }\n }\n\n // Validate contract config if present (structure validation - defineConfig() handles normalization)\n if (configObj['contract'] !== undefined) {\n const contract = configObj['contract'] as Record<string, unknown>;\n if (!contract || typeof contract !== 'object') {\n throw errorConfigValidation('contract', {\n why: 'Config.contract must be an object',\n });\n }\n if (!('source' in contract)) {\n throw errorConfigValidation('contract.source', {\n why: 'Config.contract.source is required when contract is provided',\n });\n }\n if (contract['output'] !== undefined && typeof contract['output'] !== 'string') {\n throw errorConfigValidation('contract.output', {\n why: 'Config.contract.output must be a string when provided',\n });\n }\n if (contract['types'] !== undefined && typeof contract['types'] !== 'string') {\n throw errorConfigValidation('contract.types', {\n why: 'Config.contract.types must be a string when provided',\n });\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/config-validation.ts"],"sourcesContent":["import type { PrismaNextConfig } from './config-types';\nimport { errorConfigValidation } from './errors';\n\n/**\n * Validates that the config has the required structure.\n * This is pure validation logic with no file I/O or CLI awareness.\n *\n * @param config - Config object to validate\n * @throws CliStructuredError if config structure is invalid\n */\nexport function validateConfig(config: unknown): asserts config is PrismaNextConfig {\n if (!config || typeof config !== 'object') {\n throw errorConfigValidation('object', {\n why: 'Config must be an object',\n });\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!configObj['family']) {\n throw errorConfigValidation('family');\n }\n\n if (!configObj['target']) {\n throw errorConfigValidation('target');\n }\n\n if (!configObj['adapter']) {\n throw errorConfigValidation('adapter');\n }\n\n // Validate family descriptor\n const family = configObj['family'] as Record<string, unknown>;\n if (family['kind'] !== 'family') {\n throw errorConfigValidation('family.kind', {\n why: 'Config.family must have kind: \"family\"',\n });\n }\n if (typeof family['familyId'] !== 'string') {\n throw errorConfigValidation('family.familyId', {\n why: 'Config.family must have familyId: string',\n });\n }\n if (typeof family['version'] !== 'string') {\n throw errorConfigValidation('family.version', {\n why: 'Config.family must have version: string',\n });\n }\n if (!family['hook'] || typeof family['hook'] !== 'object') {\n throw errorConfigValidation('family.hook', {\n why: 'Config.family must have hook: TargetFamilyHook',\n });\n }\n if (typeof family['create'] !== 'function') {\n throw errorConfigValidation('family.create', {\n why: 'Config.family must have create: function',\n });\n }\n\n const familyId = family['familyId'] as string;\n\n // Validate target descriptor\n const target = configObj['target'] as Record<string, unknown>;\n if (target['kind'] !== 'target') {\n throw errorConfigValidation('target.kind', {\n why: 'Config.target must have kind: \"target\"',\n });\n }\n if (typeof target['id'] !== 'string') {\n throw errorConfigValidation('target.id', {\n why: 'Config.target must have id: string',\n });\n }\n if (typeof target['familyId'] !== 'string') {\n throw errorConfigValidation('target.familyId', {\n why: 'Config.target must have familyId: string',\n });\n }\n if (typeof target['version'] !== 'string') {\n throw errorConfigValidation('target.version', {\n why: 'Config.target must have version: string',\n });\n }\n if (target['familyId'] !== familyId) {\n throw errorConfigValidation('target.familyId', {\n why: `Config.target.familyId must match Config.family.familyId (expected: ${familyId}, got: ${target['familyId']})`,\n });\n }\n if (typeof target['targetId'] !== 'string') {\n throw errorConfigValidation('target.targetId', {\n why: 'Config.target must have targetId: string',\n });\n }\n if (typeof target['create'] !== 'function') {\n throw errorConfigValidation('target.create', {\n why: 'Config.target must have create: function',\n });\n }\n const expectedTargetId = target['targetId'] as string;\n\n // Validate adapter descriptor\n const adapter = configObj['adapter'] as Record<string, unknown>;\n if (adapter['kind'] !== 'adapter') {\n throw errorConfigValidation('adapter.kind', {\n why: 'Config.adapter must have kind: \"adapter\"',\n });\n }\n if (typeof adapter['id'] !== 'string') {\n throw errorConfigValidation('adapter.id', {\n why: 'Config.adapter must have id: string',\n });\n }\n if (typeof adapter['familyId'] !== 'string') {\n throw errorConfigValidation('adapter.familyId', {\n why: 'Config.adapter must have familyId: string',\n });\n }\n if (typeof adapter['version'] !== 'string') {\n throw errorConfigValidation('adapter.version', {\n why: 'Config.adapter must have version: string',\n });\n }\n if (adapter['familyId'] !== familyId) {\n throw errorConfigValidation('adapter.familyId', {\n why: `Config.adapter.familyId must match Config.family.familyId (expected: ${familyId}, got: ${adapter['familyId']})`,\n });\n }\n if (typeof adapter['targetId'] !== 'string') {\n throw errorConfigValidation('adapter.targetId', {\n why: 'Config.adapter must have targetId: string',\n });\n }\n if (adapter['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('adapter.targetId', {\n why: `Config.adapter.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${adapter['targetId']})`,\n });\n }\n if (typeof adapter['create'] !== 'function') {\n throw errorConfigValidation('adapter.create', {\n why: 'Config.adapter must have create: function',\n });\n }\n\n // Validate extensions array if present\n if (configObj['extensions'] !== undefined) {\n if (!Array.isArray(configObj['extensions'])) {\n throw errorConfigValidation('extensions', {\n why: 'Config.extensions must be an array',\n });\n }\n for (const ext of configObj['extensions']) {\n if (!ext || typeof ext !== 'object') {\n throw errorConfigValidation('extensions[]', {\n why: 'Config.extensions must contain ExtensionDescriptor objects',\n });\n }\n const extObj = ext as Record<string, unknown>;\n if (extObj['kind'] !== 'extension') {\n throw errorConfigValidation('extensions[].kind', {\n why: 'Config.extensions items must have kind: \"extension\"',\n });\n }\n if (typeof extObj['id'] !== 'string') {\n throw errorConfigValidation('extensions[].id', {\n why: 'Config.extensions items must have id: string',\n });\n }\n if (typeof extObj['familyId'] !== 'string') {\n throw errorConfigValidation('extensions[].familyId', {\n why: 'Config.extensions items must have familyId: string',\n });\n }\n if (typeof extObj['version'] !== 'string') {\n throw errorConfigValidation('extensions[].version', {\n why: 'Config.extensions items must have version: string',\n });\n }\n if (extObj['familyId'] !== familyId) {\n throw errorConfigValidation('extensions[].familyId', {\n why: `Config.extensions[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj['familyId']})`,\n });\n }\n if (typeof extObj['targetId'] !== 'string') {\n throw errorConfigValidation('extensions[].targetId', {\n why: 'Config.extensions items must have targetId: string',\n });\n }\n if (extObj['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('extensions[].targetId', {\n why: `Config.extensions[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj['targetId']})`,\n });\n }\n if (typeof extObj['create'] !== 'function') {\n throw errorConfigValidation('extensions[].create', {\n why: 'Config.extensions items must have create: function',\n });\n }\n }\n }\n\n // Validate driver descriptor if present\n if (configObj['driver'] !== undefined) {\n const driver = configObj['driver'] as Record<string, unknown>;\n if (driver['kind'] !== 'driver') {\n throw errorConfigValidation('driver.kind', {\n why: 'Config.driver must have kind: \"driver\"',\n });\n }\n if (typeof driver['id'] !== 'string') {\n throw errorConfigValidation('driver.id', {\n why: 'Config.driver must have id: string',\n });\n }\n if (typeof driver['version'] !== 'string') {\n throw errorConfigValidation('driver.version', {\n why: 'Config.driver must have version: string',\n });\n }\n if (typeof driver['familyId'] !== 'string') {\n throw errorConfigValidation('driver.familyId', {\n why: 'Config.driver must have familyId: string',\n });\n }\n if (driver['familyId'] !== familyId) {\n throw errorConfigValidation('driver.familyId', {\n why: `Config.driver.familyId must match Config.family.familyId (expected: ${familyId}, got: ${driver['familyId']})`,\n });\n }\n if (typeof driver['targetId'] !== 'string') {\n throw errorConfigValidation('driver.targetId', {\n why: 'Config.driver must have targetId: string',\n });\n }\n if (driver['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('driver.targetId', {\n why: `Config.driver.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${driver['targetId']})`,\n });\n }\n if (typeof driver['create'] !== 'function') {\n throw errorConfigValidation('driver.create', {\n why: 'Config.driver must have create: function',\n });\n }\n }\n\n // Validate contract config if present (structure validation - defineConfig() handles normalization)\n if (configObj['contract'] !== undefined) {\n const contract = configObj['contract'] as Record<string, unknown>;\n if (!contract || typeof contract !== 'object') {\n throw errorConfigValidation('contract', {\n why: 'Config.contract must be an object',\n });\n }\n if (!('source' in contract)) {\n throw errorConfigValidation('contract.source', {\n why: 'Config.contract.source is required when contract is provided',\n });\n }\n if (contract['output'] !== undefined && typeof contract['output'] !== 'string') {\n throw errorConfigValidation('contract.output', {\n why: 'Config.contract.output must be a string when provided',\n });\n }\n if (contract['types'] !== undefined && typeof contract['types'] !== 'string') {\n throw errorConfigValidation('contract.types', {\n why: 'Config.contract.types must be a string when provided',\n });\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -30,7 +30,7 @@ type ContractInput = {
30
30
  models: Record<string, unknown>;
31
31
  relations: Record<string, unknown>;
32
32
  storage: Record<string, unknown>;
33
- extensions: Record<string, unknown>;
33
+ extensionPacks: Record<string, unknown>;
34
34
  sources: Record<string, unknown>;
35
35
  capabilities: Record<string, Record<string, boolean>>;
36
36
  meta: Record<string, unknown>;
@@ -1,4 +1,5 @@
1
1
  // src/emission/canonicalization.ts
2
+ import { isArrayEqual } from "@prisma-next/utils/array-equal";
2
3
  var TOP_LEVEL_ORDER = [
3
4
  "schemaVersion",
4
5
  "canonicalVersion",
@@ -9,7 +10,7 @@ var TOP_LEVEL_ORDER = [
9
10
  "models",
10
11
  "storage",
11
12
  "capabilities",
12
- "extensions",
13
+ "extensionPacks",
13
14
  "meta",
14
15
  "sources"
15
16
  ];
@@ -43,19 +44,28 @@ function omitDefaults(obj, path) {
43
44
  continue;
44
45
  }
45
46
  if (isDefaultValue(value)) {
46
- const isRequiredModels = currentPath.length === 1 && currentPath[0] === "models";
47
- const isRequiredTables = currentPath.length === 2 && currentPath[0] === "storage" && currentPath[1] === "tables";
48
- const isRequiredRelations = currentPath.length === 1 && currentPath[0] === "relations";
49
- const isRequiredExtensions = currentPath.length === 1 && currentPath[0] === "extensions";
50
- const isRequiredCapabilities = currentPath.length === 1 && currentPath[0] === "capabilities";
51
- const isRequiredMeta = currentPath.length === 1 && currentPath[0] === "meta";
52
- const isRequiredSources = currentPath.length === 1 && currentPath[0] === "sources";
53
- const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === "extensions";
54
- const isModelRelations = currentPath.length === 3 && currentPath[0] === "models" && currentPath[2] === "relations";
55
- const isTableUniques = currentPath.length === 4 && currentPath[0] === "storage" && currentPath[1] === "tables" && currentPath[3] === "uniques";
56
- const isTableIndexes = currentPath.length === 4 && currentPath[0] === "storage" && currentPath[1] === "tables" && currentPath[3] === "indexes";
57
- const isTableForeignKeys = currentPath.length === 4 && currentPath[0] === "storage" && currentPath[1] === "tables" && currentPath[3] === "foreignKeys";
58
- if (!isRequiredModels && !isRequiredTables && !isRequiredRelations && !isRequiredExtensions && !isRequiredCapabilities && !isRequiredMeta && !isRequiredSources && !isExtensionNamespace && !isModelRelations && !isTableUniques && !isTableIndexes && !isTableForeignKeys) {
47
+ const isRequiredModels = isArrayEqual(currentPath, ["models"]);
48
+ const isRequiredTables = isArrayEqual(currentPath, ["storage", "tables"]);
49
+ const isRequiredRelations = isArrayEqual(currentPath, ["relations"]);
50
+ const isRequiredExtensionPacks = isArrayEqual(currentPath, ["extensionPacks"]);
51
+ const isRequiredCapabilities = isArrayEqual(currentPath, ["capabilities"]);
52
+ const isRequiredMeta = isArrayEqual(currentPath, ["meta"]);
53
+ const isRequiredSources = isArrayEqual(currentPath, ["sources"]);
54
+ const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === "extensionPacks";
55
+ const isModelRelations = currentPath.length === 3 && isArrayEqual([currentPath[0], currentPath[2]], ["models", "relations"]);
56
+ const isTableUniques = currentPath.length === 4 && isArrayEqual(
57
+ [currentPath[0], currentPath[1], currentPath[3]],
58
+ ["storage", "tables", "uniques"]
59
+ );
60
+ const isTableIndexes = currentPath.length === 4 && isArrayEqual(
61
+ [currentPath[0], currentPath[1], currentPath[3]],
62
+ ["storage", "tables", "indexes"]
63
+ );
64
+ const isTableForeignKeys = currentPath.length === 4 && isArrayEqual(
65
+ [currentPath[0], currentPath[1], currentPath[3]],
66
+ ["storage", "tables", "foreignKeys"]
67
+ );
68
+ if (!isRequiredModels && !isRequiredTables && !isRequiredRelations && !isRequiredExtensionPacks && !isRequiredCapabilities && !isRequiredMeta && !isRequiredSources && !isExtensionNamespace && !isModelRelations && !isTableUniques && !isTableIndexes && !isTableForeignKeys) {
59
69
  continue;
60
70
  }
61
71
  }
@@ -137,7 +147,7 @@ function canonicalizeContract(ir) {
137
147
  models: ir.models,
138
148
  relations: ir.relations,
139
149
  storage: ir.storage,
140
- extensions: ir.extensions,
150
+ extensionPacks: ir.extensionPacks,
141
151
  capabilities: ir.capabilities,
142
152
  meta: ir.meta,
143
153
  sources: ir.sources
@@ -174,7 +184,7 @@ function computeCoreHash(contract) {
174
184
  models: contract.models,
175
185
  relations: contract.relations,
176
186
  storage: contract.storage,
177
- extensions: contract.extensions,
187
+ extensionPacks: contract.extensionPacks,
178
188
  sources: contract.sources,
179
189
  capabilities: contract.capabilities,
180
190
  meta: contract.meta
@@ -190,7 +200,7 @@ function computeProfileHash(contract) {
190
200
  models: {},
191
201
  relations: {},
192
202
  storage: {},
193
- extensions: {},
203
+ extensionPacks: {},
194
204
  capabilities: contract.capabilities,
195
205
  meta: {},
196
206
  sources: {}
@@ -219,8 +229,8 @@ function validateCoreStructure(ir) {
219
229
  if (!ir.relations || typeof ir.relations !== "object") {
220
230
  throw new Error("ContractIR must have relations");
221
231
  }
222
- if (!ir.extensions || typeof ir.extensions !== "object") {
223
- throw new Error("ContractIR must have extensions");
232
+ if (!ir.extensionPacks || typeof ir.extensionPacks !== "object") {
233
+ throw new Error("ContractIR must have extensionPacks");
224
234
  }
225
235
  if (!ir.capabilities || typeof ir.capabilities !== "object") {
226
236
  throw new Error("ContractIR must have capabilities");
@@ -250,7 +260,7 @@ async function emit(ir, options, targetFamily) {
250
260
  models: ir.models,
251
261
  relations: ir.relations,
252
262
  storage: ir.storage,
253
- extensions: ir.extensions,
263
+ extensionPacks: ir.extensionPacks,
254
264
  capabilities: ir.capabilities,
255
265
  meta: ir.meta,
256
266
  sources: ir.sources
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/emission/canonicalization.ts","../../src/emission/emit.ts","../../src/emission/hashing.ts"],"sourcesContent":["import type { ContractIR } from '@prisma-next/contract/ir';\n\ntype NormalizedContract = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n coreHash?: string;\n profileHash?: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n extensions: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n sources: Record<string, unknown>;\n};\n\nconst TOP_LEVEL_ORDER = [\n 'schemaVersion',\n 'canonicalVersion',\n 'targetFamily',\n 'target',\n 'coreHash',\n 'profileHash',\n 'models',\n 'storage',\n 'capabilities',\n 'extensions',\n 'meta',\n 'sources',\n] as const;\n\nfunction isDefaultValue(value: unknown): boolean {\n if (value === false) return true;\n if (value === null) return false;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value);\n return keys.length === 0;\n }\n return false;\n}\n\nfunction omitDefaults(obj: unknown, path: readonly string[]): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => omitDefaults(item, path));\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n // Exclude metadata fields from canonicalization\n if (key === '_generated') {\n continue;\n }\n\n if (key === 'nullable' && value === false) {\n continue;\n }\n\n if (key === 'generated' && value === false) {\n continue;\n }\n\n if (isDefaultValue(value)) {\n const isRequiredModels = currentPath.length === 1 && currentPath[0] === 'models';\n const isRequiredTables =\n currentPath.length === 2 && currentPath[0] === 'storage' && currentPath[1] === 'tables';\n const isRequiredRelations = currentPath.length === 1 && currentPath[0] === 'relations';\n const isRequiredExtensions = currentPath.length === 1 && currentPath[0] === 'extensions';\n const isRequiredCapabilities = currentPath.length === 1 && currentPath[0] === 'capabilities';\n const isRequiredMeta = currentPath.length === 1 && currentPath[0] === 'meta';\n const isRequiredSources = currentPath.length === 1 && currentPath[0] === 'sources';\n const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensions';\n const isModelRelations =\n currentPath.length === 3 && currentPath[0] === 'models' && currentPath[2] === 'relations';\n const isTableUniques =\n currentPath.length === 4 &&\n currentPath[0] === 'storage' &&\n currentPath[1] === 'tables' &&\n currentPath[3] === 'uniques';\n const isTableIndexes =\n currentPath.length === 4 &&\n currentPath[0] === 'storage' &&\n currentPath[1] === 'tables' &&\n currentPath[3] === 'indexes';\n const isTableForeignKeys =\n currentPath.length === 4 &&\n currentPath[0] === 'storage' &&\n currentPath[1] === 'tables' &&\n currentPath[3] === 'foreignKeys';\n\n if (\n !isRequiredModels &&\n !isRequiredTables &&\n !isRequiredRelations &&\n !isRequiredExtensions &&\n !isRequiredCapabilities &&\n !isRequiredMeta &&\n !isRequiredSources &&\n !isExtensionNamespace &&\n !isModelRelations &&\n !isTableUniques &&\n !isTableIndexes &&\n !isTableForeignKeys\n ) {\n continue;\n }\n }\n\n result[key] = omitDefaults(value, currentPath);\n }\n\n return result;\n}\n\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj).sort();\n for (const key of keys) {\n sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n\n return sorted;\n}\n\ntype StorageObject = {\n tables?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\ntype TableObject = {\n indexes?: unknown[];\n uniques?: unknown[];\n [key: string]: unknown;\n};\n\nfunction sortIndexesAndUniques(storage: unknown): unknown {\n if (!storage || typeof storage !== 'object') {\n return storage;\n }\n\n const storageObj = storage as StorageObject;\n if (!storageObj.tables || typeof storageObj.tables !== 'object') {\n return storage;\n }\n\n const tables = storageObj.tables;\n const result: StorageObject = { ...storageObj };\n\n result.tables = {};\n // Sort table names to ensure deterministic ordering\n const sortedTableNames = Object.keys(tables).sort();\n for (const tableName of sortedTableNames) {\n const table = tables[tableName];\n if (!table || typeof table !== 'object') {\n result.tables[tableName] = table;\n continue;\n }\n\n const tableObj = table as TableObject;\n const sortedTable: TableObject = { ...tableObj };\n\n if (Array.isArray(tableObj.indexes)) {\n sortedTable.indexes = [...tableObj.indexes].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n if (Array.isArray(tableObj.uniques)) {\n sortedTable.uniques = [...tableObj.uniques].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n result.tables[tableName] = sortedTable;\n }\n\n return result;\n}\n\nfunction orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n const remaining = new Set(Object.keys(obj));\n\n for (const key of TOP_LEVEL_ORDER) {\n if (remaining.has(key)) {\n ordered[key] = obj[key];\n remaining.delete(key);\n }\n }\n\n for (const key of Array.from(remaining).sort()) {\n ordered[key] = obj[key];\n }\n\n return ordered;\n}\n\nexport function canonicalizeContract(\n ir: ContractIR & { coreHash?: string; profileHash?: string },\n): string {\n const normalized: NormalizedContract = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n extensions: ir.extensions,\n capabilities: ir.capabilities,\n meta: ir.meta,\n sources: ir.sources,\n };\n\n if (ir.coreHash !== undefined) {\n normalized.coreHash = ir.coreHash;\n }\n\n if (ir.profileHash !== undefined) {\n normalized.profileHash = ir.profileHash;\n }\n\n const withDefaultsOmitted = omitDefaults(normalized, []) as NormalizedContract;\n const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted.storage);\n const withSortedStorage = { ...withDefaultsOmitted, storage: withSortedIndexes };\n const withSortedKeys = sortObjectKeys(withSortedStorage) as Record<string, unknown>;\n const withOrderedTopLevel = orderTopLevel(withSortedKeys);\n\n return JSON.stringify(withOrderedTopLevel, null, 2);\n}\n","import type { ContractIR } from '@prisma-next/contract/ir';\nimport type { TargetFamilyHook, ValidationContext } from '@prisma-next/contract/types';\nimport { format } from 'prettier';\nimport { canonicalizeContract } from './canonicalization';\nimport { computeCoreHash, computeProfileHash } from './hashing';\nimport type { EmitOptions, EmitResult } from './types';\n\nfunction validateCoreStructure(ir: ContractIR): void {\n if (!ir.targetFamily) {\n throw new Error('ContractIR must have targetFamily');\n }\n if (!ir.target) {\n throw new Error('ContractIR must have target');\n }\n if (!ir.schemaVersion) {\n throw new Error('ContractIR must have schemaVersion');\n }\n if (!ir.models || typeof ir.models !== 'object') {\n throw new Error('ContractIR must have models');\n }\n if (!ir.storage || typeof ir.storage !== 'object') {\n throw new Error('ContractIR must have storage');\n }\n if (!ir.relations || typeof ir.relations !== 'object') {\n throw new Error('ContractIR must have relations');\n }\n if (!ir.extensions || typeof ir.extensions !== 'object') {\n throw new Error('ContractIR must have extensions');\n }\n if (!ir.capabilities || typeof ir.capabilities !== 'object') {\n throw new Error('ContractIR must have capabilities');\n }\n if (!ir.meta || typeof ir.meta !== 'object') {\n throw new Error('ContractIR must have meta');\n }\n if (!ir.sources || typeof ir.sources !== 'object') {\n throw new Error('ContractIR must have sources');\n }\n}\n\nexport async function emit(\n ir: ContractIR,\n options: EmitOptions,\n targetFamily: TargetFamilyHook,\n): Promise<EmitResult> {\n const { operationRegistry, codecTypeImports, operationTypeImports, extensionIds } = options;\n\n validateCoreStructure(ir);\n\n const ctx: ValidationContext = {\n ...(operationRegistry ? { operationRegistry } : {}),\n ...(codecTypeImports ? { codecTypeImports } : {}),\n ...(operationTypeImports ? { operationTypeImports } : {}),\n ...(extensionIds ? { extensionIds } : {}),\n };\n targetFamily.validateTypes(ir, ctx);\n\n targetFamily.validateStructure(ir);\n\n const contractJson = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n extensions: ir.extensions,\n capabilities: ir.capabilities,\n meta: ir.meta,\n sources: ir.sources,\n } as const;\n\n const coreHash = computeCoreHash(contractJson);\n const profileHash = computeProfileHash(contractJson);\n\n const contractWithHashes: ContractIR & { coreHash?: string; profileHash?: string } = {\n ...ir,\n schemaVersion: contractJson.schemaVersion,\n coreHash,\n profileHash,\n };\n\n // Add _generated metadata to indicate this is a generated artifact\n // This ensures consistency between CLI emit and programmatic emit\n // Always add/update _generated with standard content for consistency\n const contractJsonObj = JSON.parse(canonicalizeContract(contractWithHashes)) as Record<\n string,\n unknown\n >;\n const contractJsonWithMeta = {\n ...contractJsonObj,\n _generated: {\n warning: '⚠️ GENERATED FILE - DO NOT EDIT',\n message: 'This file is automatically generated by \"prisma-next emit\".',\n regenerate: 'To regenerate, run: prisma-next emit',\n },\n };\n const contractJsonString = JSON.stringify(contractJsonWithMeta, null, 2);\n\n const contractDtsRaw = targetFamily.generateContractTypes(\n ir,\n codecTypeImports ?? [],\n operationTypeImports ?? [],\n );\n const contractDts = await format(contractDtsRaw, {\n parser: 'typescript',\n singleQuote: true,\n semi: true,\n printWidth: 100,\n });\n\n return {\n contractJson: contractJsonString,\n contractDts,\n coreHash,\n profileHash,\n };\n}\n","import { createHash } from 'node:crypto';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport { canonicalizeContract } from './canonicalization';\n\ntype ContractInput = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n extensions: Record<string, unknown>;\n sources: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n [key: string]: unknown;\n};\n\nfunction computeHash(content: string): string {\n const hash = createHash('sha256');\n hash.update(content);\n return `sha256:${hash.digest('hex')}`;\n}\n\nexport function computeCoreHash(contract: ContractInput): string {\n const coreContract: ContractIR = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: contract.models,\n relations: contract.relations,\n storage: contract.storage,\n extensions: contract.extensions,\n sources: contract.sources,\n capabilities: contract.capabilities,\n meta: contract.meta,\n };\n const canonical = canonicalizeContract(coreContract);\n return computeHash(canonical);\n}\n\nexport function computeProfileHash(contract: ContractInput): string {\n const profileContract: ContractIR = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: {},\n relations: {},\n storage: {},\n extensions: {},\n capabilities: contract.capabilities,\n meta: {},\n sources: {},\n };\n const canonical = canonicalizeContract(profileContract);\n return computeHash(canonical);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/emission/canonicalization.ts","../../src/emission/emit.ts","../../src/emission/hashing.ts"],"sourcesContent":["import type { ContractIR } from '@prisma-next/contract/ir';\nimport { isArrayEqual } from '@prisma-next/utils/array-equal';\n\ntype NormalizedContract = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n coreHash?: string;\n profileHash?: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n extensionPacks: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n sources: Record<string, unknown>;\n};\n\nconst TOP_LEVEL_ORDER = [\n 'schemaVersion',\n 'canonicalVersion',\n 'targetFamily',\n 'target',\n 'coreHash',\n 'profileHash',\n 'models',\n 'storage',\n 'capabilities',\n 'extensionPacks',\n 'meta',\n 'sources',\n] as const;\n\nfunction isDefaultValue(value: unknown): boolean {\n if (value === false) return true;\n if (value === null) return false;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value);\n return keys.length === 0;\n }\n return false;\n}\n\nfunction omitDefaults(obj: unknown, path: readonly string[]): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => omitDefaults(item, path));\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n // Exclude metadata fields from canonicalization\n if (key === '_generated') {\n continue;\n }\n\n if (key === 'nullable' && value === false) {\n continue;\n }\n\n if (key === 'generated' && value === false) {\n continue;\n }\n\n if (isDefaultValue(value)) {\n const isRequiredModels = isArrayEqual(currentPath, ['models']);\n const isRequiredTables = isArrayEqual(currentPath, ['storage', 'tables']);\n const isRequiredRelations = isArrayEqual(currentPath, ['relations']);\n const isRequiredExtensionPacks = isArrayEqual(currentPath, ['extensionPacks']);\n const isRequiredCapabilities = isArrayEqual(currentPath, ['capabilities']);\n const isRequiredMeta = isArrayEqual(currentPath, ['meta']);\n const isRequiredSources = isArrayEqual(currentPath, ['sources']);\n const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensionPacks';\n const isModelRelations =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[2]], ['models', 'relations']);\n const isTableUniques =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'uniques'],\n );\n const isTableIndexes =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'indexes'],\n );\n const isTableForeignKeys =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'foreignKeys'],\n );\n\n if (\n !isRequiredModels &&\n !isRequiredTables &&\n !isRequiredRelations &&\n !isRequiredExtensionPacks &&\n !isRequiredCapabilities &&\n !isRequiredMeta &&\n !isRequiredSources &&\n !isExtensionNamespace &&\n !isModelRelations &&\n !isTableUniques &&\n !isTableIndexes &&\n !isTableForeignKeys\n ) {\n continue;\n }\n }\n\n result[key] = omitDefaults(value, currentPath);\n }\n\n return result;\n}\n\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj).sort();\n for (const key of keys) {\n sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n\n return sorted;\n}\n\ntype StorageObject = {\n tables?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\ntype TableObject = {\n indexes?: unknown[];\n uniques?: unknown[];\n [key: string]: unknown;\n};\n\nfunction sortIndexesAndUniques(storage: unknown): unknown {\n if (!storage || typeof storage !== 'object') {\n return storage;\n }\n\n const storageObj = storage as StorageObject;\n if (!storageObj.tables || typeof storageObj.tables !== 'object') {\n return storage;\n }\n\n const tables = storageObj.tables;\n const result: StorageObject = { ...storageObj };\n\n result.tables = {};\n // Sort table names to ensure deterministic ordering\n const sortedTableNames = Object.keys(tables).sort();\n for (const tableName of sortedTableNames) {\n const table = tables[tableName];\n if (!table || typeof table !== 'object') {\n result.tables[tableName] = table;\n continue;\n }\n\n const tableObj = table as TableObject;\n const sortedTable: TableObject = { ...tableObj };\n\n if (Array.isArray(tableObj.indexes)) {\n sortedTable.indexes = [...tableObj.indexes].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n if (Array.isArray(tableObj.uniques)) {\n sortedTable.uniques = [...tableObj.uniques].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n result.tables[tableName] = sortedTable;\n }\n\n return result;\n}\n\nfunction orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n const remaining = new Set(Object.keys(obj));\n\n for (const key of TOP_LEVEL_ORDER) {\n if (remaining.has(key)) {\n ordered[key] = obj[key];\n remaining.delete(key);\n }\n }\n\n for (const key of Array.from(remaining).sort()) {\n ordered[key] = obj[key];\n }\n\n return ordered;\n}\n\nexport function canonicalizeContract(\n ir: ContractIR & { coreHash?: string; profileHash?: string },\n): string {\n const normalized: NormalizedContract = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n extensionPacks: ir.extensionPacks,\n capabilities: ir.capabilities,\n meta: ir.meta,\n sources: ir.sources,\n };\n\n if (ir.coreHash !== undefined) {\n normalized.coreHash = ir.coreHash;\n }\n\n if (ir.profileHash !== undefined) {\n normalized.profileHash = ir.profileHash;\n }\n\n const withDefaultsOmitted = omitDefaults(normalized, []) as NormalizedContract;\n const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted.storage);\n const withSortedStorage = { ...withDefaultsOmitted, storage: withSortedIndexes };\n const withSortedKeys = sortObjectKeys(withSortedStorage) as Record<string, unknown>;\n const withOrderedTopLevel = orderTopLevel(withSortedKeys);\n\n return JSON.stringify(withOrderedTopLevel, null, 2);\n}\n","import type { ContractIR } from '@prisma-next/contract/ir';\nimport type { TargetFamilyHook, ValidationContext } from '@prisma-next/contract/types';\nimport { format } from 'prettier';\nimport { canonicalizeContract } from './canonicalization';\nimport { computeCoreHash, computeProfileHash } from './hashing';\nimport type { EmitOptions, EmitResult } from './types';\n\nfunction validateCoreStructure(ir: ContractIR): void {\n if (!ir.targetFamily) {\n throw new Error('ContractIR must have targetFamily');\n }\n if (!ir.target) {\n throw new Error('ContractIR must have target');\n }\n if (!ir.schemaVersion) {\n throw new Error('ContractIR must have schemaVersion');\n }\n if (!ir.models || typeof ir.models !== 'object') {\n throw new Error('ContractIR must have models');\n }\n if (!ir.storage || typeof ir.storage !== 'object') {\n throw new Error('ContractIR must have storage');\n }\n if (!ir.relations || typeof ir.relations !== 'object') {\n throw new Error('ContractIR must have relations');\n }\n if (!ir.extensionPacks || typeof ir.extensionPacks !== 'object') {\n throw new Error('ContractIR must have extensionPacks');\n }\n if (!ir.capabilities || typeof ir.capabilities !== 'object') {\n throw new Error('ContractIR must have capabilities');\n }\n if (!ir.meta || typeof ir.meta !== 'object') {\n throw new Error('ContractIR must have meta');\n }\n if (!ir.sources || typeof ir.sources !== 'object') {\n throw new Error('ContractIR must have sources');\n }\n}\n\nexport async function emit(\n ir: ContractIR,\n options: EmitOptions,\n targetFamily: TargetFamilyHook,\n): Promise<EmitResult> {\n const { operationRegistry, codecTypeImports, operationTypeImports, extensionIds } = options;\n\n validateCoreStructure(ir);\n\n const ctx: ValidationContext = {\n ...(operationRegistry ? { operationRegistry } : {}),\n ...(codecTypeImports ? { codecTypeImports } : {}),\n ...(operationTypeImports ? { operationTypeImports } : {}),\n ...(extensionIds ? { extensionIds } : {}),\n };\n targetFamily.validateTypes(ir, ctx);\n\n targetFamily.validateStructure(ir);\n\n const contractJson = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n extensionPacks: ir.extensionPacks,\n capabilities: ir.capabilities,\n meta: ir.meta,\n sources: ir.sources,\n } as const;\n\n const coreHash = computeCoreHash(contractJson);\n const profileHash = computeProfileHash(contractJson);\n\n const contractWithHashes: ContractIR & { coreHash?: string; profileHash?: string } = {\n ...ir,\n schemaVersion: contractJson.schemaVersion,\n coreHash,\n profileHash,\n };\n\n // Add _generated metadata to indicate this is a generated artifact\n // This ensures consistency between CLI emit and programmatic emit\n // Always add/update _generated with standard content for consistency\n const contractJsonObj = JSON.parse(canonicalizeContract(contractWithHashes)) as Record<\n string,\n unknown\n >;\n const contractJsonWithMeta = {\n ...contractJsonObj,\n _generated: {\n warning: '⚠️ GENERATED FILE - DO NOT EDIT',\n message: 'This file is automatically generated by \"prisma-next emit\".',\n regenerate: 'To regenerate, run: prisma-next emit',\n },\n };\n const contractJsonString = JSON.stringify(contractJsonWithMeta, null, 2);\n\n const contractDtsRaw = targetFamily.generateContractTypes(\n ir,\n codecTypeImports ?? [],\n operationTypeImports ?? [],\n );\n const contractDts = await format(contractDtsRaw, {\n parser: 'typescript',\n singleQuote: true,\n semi: true,\n printWidth: 100,\n });\n\n return {\n contractJson: contractJsonString,\n contractDts,\n coreHash,\n profileHash,\n };\n}\n","import { createHash } from 'node:crypto';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport { canonicalizeContract } from './canonicalization';\n\ntype ContractInput = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n extensionPacks: Record<string, unknown>;\n sources: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n [key: string]: unknown;\n};\n\nfunction computeHash(content: string): string {\n const hash = createHash('sha256');\n hash.update(content);\n return `sha256:${hash.digest('hex')}`;\n}\n\nexport function computeCoreHash(contract: ContractInput): string {\n const coreContract: ContractIR = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: contract.models,\n relations: contract.relations,\n storage: contract.storage,\n extensionPacks: contract.extensionPacks,\n sources: contract.sources,\n capabilities: contract.capabilities,\n meta: contract.meta,\n };\n const canonical = canonicalizeContract(coreContract);\n return computeHash(canonical);\n}\n\nexport function computeProfileHash(contract: ContractInput): string {\n const profileContract: ContractIR = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: {},\n relations: {},\n storage: {},\n extensionPacks: {},\n capabilities: contract.capabilities,\n meta: {},\n sources: {},\n };\n const canonical = canonicalizeContract(profileContract);\n return computeHash(canonical);\n}\n"],"mappings":"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","names":[]}
@@ -118,6 +118,13 @@ declare function errorJsonFormatNotSupported(options: {
118
118
  declare function errorDriverRequired(options?: {
119
119
  readonly why?: string;
120
120
  }): CliStructuredError;
121
+ /**
122
+ * Contract requires extension packs that are not provided by config descriptors.
123
+ */
124
+ declare function errorContractMissingExtensionPacks(options: {
125
+ readonly missingExtensionPacks: readonly string[];
126
+ readonly providedComponentIds: readonly string[];
127
+ }): CliStructuredError;
121
128
  /**
122
129
  * Migration planning failed due to conflicts.
123
130
  */
@@ -174,4 +181,4 @@ declare function errorUnexpected(message: string, options?: {
174
181
  readonly fix?: string;
175
182
  }): CliStructuredError;
176
183
 
177
- export { type CliErrorConflict, type CliErrorEnvelope, CliStructuredError, errorConfigFileNotFound, errorConfigValidation, errorContractConfigMissing, errorContractValidationFailed, errorDatabaseUrlRequired, errorDriverRequired, errorFamilyReadMarkerSqlRequired, errorFileNotFound, errorHashMismatch, errorJsonFormatNotSupported, errorMarkerMissing, errorMigrationPlanningFailed, errorQueryRunnerFactoryRequired, errorRuntime, errorTargetMigrationNotSupported, errorTargetMismatch, errorUnexpected };
184
+ export { type CliErrorConflict, type CliErrorEnvelope, CliStructuredError, errorConfigFileNotFound, errorConfigValidation, errorContractConfigMissing, errorContractMissingExtensionPacks, errorContractValidationFailed, errorDatabaseUrlRequired, errorDriverRequired, errorFamilyReadMarkerSqlRequired, errorFileNotFound, errorHashMismatch, errorJsonFormatNotSupported, errorMarkerMissing, errorMigrationPlanningFailed, errorQueryRunnerFactoryRequired, errorRuntime, errorTargetMigrationNotSupported, errorTargetMismatch, errorUnexpected };
@@ -3,6 +3,7 @@ import {
3
3
  errorConfigFileNotFound,
4
4
  errorConfigValidation,
5
5
  errorContractConfigMissing,
6
+ errorContractMissingExtensionPacks,
6
7
  errorContractValidationFailed,
7
8
  errorDatabaseUrlRequired,
8
9
  errorDriverRequired,
@@ -17,12 +18,13 @@ import {
17
18
  errorTargetMigrationNotSupported,
18
19
  errorTargetMismatch,
19
20
  errorUnexpected
20
- } from "../chunk-FKWEUJ6X.js";
21
+ } from "../chunk-U5RYT6PT.js";
21
22
  export {
22
23
  CliStructuredError,
23
24
  errorConfigFileNotFound,
24
25
  errorConfigValidation,
25
26
  errorContractConfigMissing,
27
+ errorContractMissingExtensionPacks,
26
28
  errorContractValidationFailed,
27
29
  errorDatabaseUrlRequired,
28
30
  errorDriverRequired,
@@ -382,7 +382,7 @@ interface ControlFamilyDescriptor<TFamilyId extends string, TFamilyInstance exte
382
382
  readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
383
383
  readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
384
384
  readonly driver: ControlDriverDescriptor<TFamilyId, TTargetId>;
385
- readonly extensions: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
385
+ readonly extensionPacks: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
386
386
  }): TFamilyInstance;
387
387
  }
388
388
  /**
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@prisma-next/core-control-plane",
3
- "version": "0.1.0-dev.29",
3
+ "version": "0.1.0-dev.30",
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-dev.29",
11
- "@prisma-next/operations": "0.1.0-dev.29",
12
- "@prisma-next/utils": "0.1.0-dev.29"
10
+ "@prisma-next/contract": "0.1.0-dev.30",
11
+ "@prisma-next/operations": "0.1.0-dev.30",
12
+ "@prisma-next/utils": "0.1.0-dev.30"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@vitest/coverage-v8": "^4.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/**\n * CLI error envelope for output formatting.\n * This is the serialized form of a CliStructuredError.\n */\nexport interface CliErrorEnvelope {\n readonly code: string;\n readonly domain: string;\n readonly severity: 'error' | 'warn' | 'info';\n readonly summary: string;\n readonly why: string | undefined;\n readonly fix: string | undefined;\n readonly where:\n | {\n readonly path: string | undefined;\n readonly line: number | undefined;\n }\n | undefined;\n readonly meta: Record<string, unknown> | undefined;\n readonly docsUrl: string | undefined;\n}\n\n/**\n * Minimal conflict data structure expected by CLI output.\n */\nexport interface CliErrorConflict {\n readonly kind: string;\n readonly summary: string;\n readonly why?: string;\n}\n\n/**\n * Structured CLI error that contains all information needed for error envelopes.\n * Call sites throw these errors with full context.\n */\nexport class CliStructuredError extends Error {\n readonly code: string;\n readonly domain: 'CLI' | 'RTM';\n readonly severity: 'error' | 'warn' | 'info';\n readonly why: string | undefined;\n readonly fix: string | undefined;\n readonly where:\n | {\n readonly path: string | undefined;\n readonly line: number | undefined;\n }\n | undefined;\n readonly meta: Record<string, unknown> | undefined;\n readonly docsUrl: string | undefined;\n\n constructor(\n code: string,\n summary: string,\n options?: {\n readonly domain?: 'CLI' | 'RTM';\n readonly severity?: 'error' | 'warn' | 'info';\n readonly why?: string;\n readonly fix?: string;\n readonly where?: { readonly path?: string; readonly line?: number };\n readonly meta?: Record<string, unknown>;\n readonly docsUrl?: string;\n },\n ) {\n super(summary);\n this.name = 'CliStructuredError';\n this.code = code;\n this.domain = options?.domain ?? 'CLI';\n this.severity = options?.severity ?? 'error';\n this.why = options?.why;\n this.fix = options?.fix;\n this.where = options?.where\n ? {\n path: options.where.path,\n line: options.where.line,\n }\n : undefined;\n this.meta = options?.meta;\n this.docsUrl = options?.docsUrl;\n }\n\n /**\n * Converts this error to a CLI error envelope for output formatting.\n */\n toEnvelope(): CliErrorEnvelope {\n const codePrefix = this.domain === 'CLI' ? 'PN-CLI-' : 'PN-RTM-';\n return {\n code: `${codePrefix}${this.code}`,\n domain: this.domain,\n severity: this.severity,\n summary: this.message,\n why: this.why,\n fix: this.fix,\n where: this.where,\n meta: this.meta,\n docsUrl: this.docsUrl,\n };\n }\n}\n\n// ============================================================================\n// Config Errors (PN-CLI-4001-4007)\n// ============================================================================\n\n/**\n * Config file not found or missing.\n */\nexport function errorConfigFileNotFound(\n configPath?: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4001', 'Config file not found', {\n domain: 'CLI',\n ...(options?.why ? { why: options.why } : { why: 'Config file not found' }),\n fix: \"Run 'prisma-next init' to create a config file\",\n docsUrl: 'https://prisma-next.dev/docs/cli/config',\n ...(configPath ? { where: { path: configPath } } : {}),\n });\n}\n\n/**\n * Contract configuration missing from config.\n */\nexport function errorContractConfigMissing(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4002', 'Contract configuration missing', {\n domain: 'CLI',\n why: options?.why ?? 'The contract configuration is required for emit',\n fix: 'Add contract configuration to your prisma-next.config.ts',\n docsUrl: 'https://prisma-next.dev/docs/cli/contract-emit',\n });\n}\n\n/**\n * Contract validation failed.\n */\nexport function errorContractValidationFailed(\n reason: string,\n options?: {\n readonly where?: { readonly path?: string; readonly line?: number };\n },\n): CliStructuredError {\n return new CliStructuredError('4003', 'Contract validation failed', {\n domain: 'CLI',\n why: reason,\n fix: 'Re-run `prisma-next contract emit`, or fix the contract file and try again',\n docsUrl: 'https://prisma-next.dev/docs/contracts',\n ...(options?.where ? { where: options.where } : {}),\n });\n}\n\n/**\n * File not found.\n */\nexport function errorFileNotFound(\n filePath: string,\n options?: {\n readonly why?: string;\n readonly fix?: string;\n readonly docsUrl?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4004', 'File not found', {\n domain: 'CLI',\n why: options?.why ?? `File not found: ${filePath}`,\n fix: options?.fix ?? 'Check that the file path is correct',\n where: { path: filePath },\n ...(options?.docsUrl ? { docsUrl: options.docsUrl } : {}),\n });\n}\n\n/**\n * Database URL is required but not provided.\n */\nexport function errorDatabaseUrlRequired(options?: { readonly why?: string }): CliStructuredError {\n return new CliStructuredError('4005', 'Database URL is required', {\n domain: 'CLI',\n why: options?.why ?? 'Database URL is required for this command',\n fix: 'Provide `--db <url>` or set `db: { url: \"postgres://…\" }` in prisma-next.config.ts',\n });\n}\n\n/**\n * Query runner factory is required but not provided in config.\n */\nexport function errorQueryRunnerFactoryRequired(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4006', 'Query runner factory is required', {\n domain: 'CLI',\n why: options?.why ?? 'Config.db.queryRunnerFactory is required for db verify',\n fix: 'Add db.queryRunnerFactory to prisma-next.config.ts',\n docsUrl: 'https://prisma-next.dev/docs/cli/db-verify',\n });\n}\n\n/**\n * Family verify.readMarker is required but not provided.\n */\nexport function errorFamilyReadMarkerSqlRequired(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4007', 'Family readMarker() is required', {\n domain: 'CLI',\n why: options?.why ?? 'Family verify.readMarker is required for db verify',\n fix: 'Ensure family.verify.readMarker() is exported by your family package',\n docsUrl: 'https://prisma-next.dev/docs/cli/db-verify',\n });\n}\n\n/**\n * JSON output format not supported.\n */\nexport function errorJsonFormatNotSupported(options: {\n readonly command: string;\n readonly format: string;\n readonly supportedFormats: readonly string[];\n}): CliStructuredError {\n return new CliStructuredError('4008', 'Unsupported JSON format', {\n domain: 'CLI',\n why: `The ${options.command} command does not support --json ${options.format}`,\n fix: `Use --json ${options.supportedFormats.join(' or ')}, or omit --json for human output`,\n meta: {\n command: options.command,\n format: options.format,\n supportedFormats: options.supportedFormats,\n },\n });\n}\n\n/**\n * Driver is required for DB-connected commands but not provided.\n */\nexport function errorDriverRequired(options?: { readonly why?: string }): CliStructuredError {\n return new CliStructuredError('4010', 'Driver is required for DB-connected commands', {\n domain: 'CLI',\n why: options?.why ?? 'Config.driver is required for DB-connected commands',\n fix: 'Add a control-plane driver to prisma-next.config.ts (e.g. import a driver descriptor and set `driver: postgresDriver`)',\n docsUrl: 'https://prisma-next.dev/docs/cli/config',\n });\n}\n\n/**\n * Migration planning failed due to conflicts.\n */\nexport function errorMigrationPlanningFailed(options: {\n readonly conflicts: readonly CliErrorConflict[];\n readonly why?: string;\n}): CliStructuredError {\n // Build \"why\" from conflict summaries - these contain the actual problem description\n const conflictSummaries = options.conflicts.map((c) => c.summary);\n const computedWhy = options.why ?? conflictSummaries.join('\\n');\n\n // Build \"fix\" from conflict \"why\" fields - these contain actionable advice\n const conflictFixes = options.conflicts\n .map((c) => c.why)\n .filter((why): why is string => typeof why === 'string');\n const computedFix =\n conflictFixes.length > 0\n ? conflictFixes.join('\\n')\n : 'Use `db schema-verify` to inspect conflicts, or ensure the database is empty';\n\n return new CliStructuredError('4020', 'Migration planning failed', {\n domain: 'CLI',\n why: computedWhy,\n fix: computedFix,\n meta: { conflicts: options.conflicts },\n docsUrl: 'https://prisma-next.dev/docs/cli/db-init',\n });\n}\n\n/**\n * Target does not support migrations (missing createPlanner/createRunner).\n */\nexport function errorTargetMigrationNotSupported(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4021', 'Target does not support migrations', {\n domain: 'CLI',\n why: options?.why ?? 'The configured target does not provide migration planner/runner',\n fix: 'Select a target that provides migrations (it must export `target.migrations` for db init)',\n docsUrl: 'https://prisma-next.dev/docs/cli/db-init',\n });\n}\n\n/**\n * Config validation error (missing required fields).\n */\nexport function errorConfigValidation(\n field: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4001', 'Config file not found', {\n domain: 'CLI',\n why: options?.why ?? `Config must have a \"${field}\" field`,\n fix: \"Run 'prisma-next init' to create a config file\",\n docsUrl: 'https://prisma-next.dev/docs/cli/config',\n });\n}\n\n// ============================================================================\n// Runtime Errors (PN-RTM-3000-3003)\n// ============================================================================\n\n/**\n * Contract marker not found in database.\n */\nexport function errorMarkerMissing(options?: {\n readonly why?: string;\n readonly dbUrl?: string;\n}): CliStructuredError {\n return new CliStructuredError('3001', 'Marker missing', {\n domain: 'RTM',\n why: options?.why ?? 'Contract marker not found in database',\n fix: 'Run `prisma-next db sign --db <url>` to create marker',\n });\n}\n\n/**\n * Contract hash does not match database marker.\n */\nexport function errorHashMismatch(options?: {\n readonly why?: string;\n readonly expected?: string;\n readonly actual?: string;\n}): CliStructuredError {\n return new CliStructuredError('3002', 'Hash mismatch', {\n domain: 'RTM',\n why: options?.why ?? 'Contract hash does not match database marker',\n fix: 'Migrate database or re-sign if intentional',\n ...(options?.expected || options?.actual\n ? {\n meta: {\n ...(options.expected ? { expected: options.expected } : {}),\n ...(options.actual ? { actual: options.actual } : {}),\n },\n }\n : {}),\n });\n}\n\n/**\n * Contract target does not match config target.\n */\nexport function errorTargetMismatch(\n expected: string,\n actual: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('3003', 'Target mismatch', {\n domain: 'RTM',\n why:\n options?.why ??\n `Contract target does not match config target (expected: ${expected}, actual: ${actual})`,\n fix: 'Align contract target and config target',\n meta: { expected, actual },\n });\n}\n\n/**\n * Generic runtime error.\n */\nexport function errorRuntime(\n summary: string,\n options?: {\n readonly why?: string;\n readonly fix?: string;\n readonly meta?: Record<string, unknown>;\n },\n): CliStructuredError {\n return new CliStructuredError('3000', summary, {\n domain: 'RTM',\n ...(options?.why ? { why: options.why } : { why: 'Verification failed' }),\n ...(options?.fix ? { fix: options.fix } : { fix: 'Check contract and database state' }),\n ...(options?.meta ? { meta: options.meta } : {}),\n });\n}\n\n// ============================================================================\n// Generic Error\n// ============================================================================\n\n/**\n * Generic unexpected error.\n */\nexport function errorUnexpected(\n message: string,\n options?: {\n readonly why?: string;\n readonly fix?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4999', 'Unexpected error', {\n domain: 'CLI',\n why: options?.why ?? message,\n fix: options?.fix ?? 'Check the error message and try again',\n });\n}\n"],"mappings":"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","names":[]}