@prisma-next/cli 0.3.0-pr.94.3 → 0.3.0-pr.94.5

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.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["loadConfig","loadConfigC12","plannerResult: MigrationPlannerResult","migrationPlan: MigrationPlan","runnerResult: MigrationRunnerResult","contractRaw: unknown","flags: {\n json?: 'object' | 'ndjson';\n quiet?: boolean;\n verbose?: number;\n timestamps?: boolean;\n color?: boolean;\n }","lines: string[]","formattedLabel: string","prefix","statusColor: (text: string) => string","labelColor: (text: string) => string","parts: string[]","current: Command | undefined","program","exhaustive: never","config: Awaited<ReturnType<typeof loadConfig>>","loadConfig","errorUnexpected","source: EmitContractSource","mismatchParts: string[]","exhaustive: never","loadConfig","details: Array<{ label: string; value: string }>","contractJsonContent: string","errorUnexpected","contractJson: Record<string, unknown>","exitCode","loadConfig","details: Array<{ label: string; value: string }>","errorUnexpected","exitCode","loadConfig","details: Array<{ label: string; value: string }>","contractJsonContent: string","errorUnexpected","contractJson: Record<string, unknown>","exitCode","loadConfig","details: Array<{ label: string; value: string }>","contractJsonContent: string","errorUnexpected","contractJson: Record<string, unknown>","loadConfig","details: Array<{ label: string; value: string }>","contractJsonContent: string","errorUnexpected","contractJson: Record<string, unknown>","exitCode"],"sources":["../src/config-loader.ts","../src/utils/framework-components.ts","../src/control-api/operations/db-init.ts","../src/control-api/client.ts","../src/utils/command-helpers.ts","../src/utils/global-flags.ts","../src/utils/output.ts","../src/utils/progress-adapter.ts","../src/utils/result-handler.ts","../src/commands/contract-emit.ts","../src/commands/db-init.ts","../src/commands/db-introspect.ts","../src/commands/db-schema-verify.ts","../src/commands/db-sign.ts","../src/commands/db-verify.ts","../src/cli.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path';\nimport type { PrismaNextConfig } from '@prisma-next/core-control-plane/config-types';\nimport { validateConfig } from '@prisma-next/core-control-plane/config-validation';\nimport { errorConfigFileNotFound, errorUnexpected } from '@prisma-next/core-control-plane/errors';\nimport { loadConfig as loadConfigC12 } from 'c12';\n\n/**\n * Loads the Prisma Next config from a TypeScript file.\n * Supports both default export and named export.\n * Uses c12 to automatically handle TypeScript compilation and config file discovery.\n *\n * @param configPath - Optional path to config file. Defaults to `./prisma-next.config.ts` in current directory.\n * @returns The loaded config object.\n * @throws Error if config file doesn't exist or is invalid.\n */\nexport async function loadConfig(configPath?: string): Promise<PrismaNextConfig> {\n try {\n const cwd = process.cwd();\n // Resolve config path to absolute path and set cwd to config directory when path is provided\n const resolvedConfigPath = configPath ? resolve(cwd, configPath) : undefined;\n const configCwd = resolvedConfigPath ? dirname(resolvedConfigPath) : cwd;\n\n const result = await loadConfigC12<PrismaNextConfig>({\n name: 'prisma-next',\n ...(resolvedConfigPath ? { configFile: resolvedConfigPath } : {}),\n cwd: configCwd,\n });\n\n // When a specific config file was requested, verify it was actually loaded\n // (c12 falls back to searching by name if the specified file doesn't exist)\n if (resolvedConfigPath && result.configFile !== resolvedConfigPath) {\n throw errorConfigFileNotFound(resolvedConfigPath);\n }\n\n // Check if config is missing or empty (c12 may return empty object when file doesn't exist)\n if (!result.config || Object.keys(result.config).length === 0) {\n // Use c12's configFile if available, otherwise use explicit configPath, otherwise omit path\n const displayPath = result.configFile || resolvedConfigPath || configPath;\n throw errorConfigFileNotFound(displayPath);\n }\n\n // Validate config structure\n validateConfig(result.config);\n\n return result.config;\n } catch (error) {\n // Re-throw structured errors as-is\n if (\n error instanceof Error &&\n 'code' in error &&\n typeof (error as { code: string }).code === 'string'\n ) {\n throw error;\n }\n\n if (error instanceof Error) {\n // Check for file not found errors\n if (\n error.message.includes('not found') ||\n error.message.includes('Cannot find') ||\n error.message.includes('ENOENT')\n ) {\n // Use resolved path if available, otherwise use original configPath\n const displayPath = configPath ? resolve(process.cwd(), configPath) : undefined;\n throw errorConfigFileNotFound(displayPath, {\n why: error.message,\n });\n }\n // For other errors, wrap in unexpected error\n throw errorUnexpected(error.message, {\n why: `Failed to load config: ${error.message}`,\n });\n }\n throw errorUnexpected(String(error));\n }\n}\n","import {\n checkContractComponentRequirements,\n type TargetBoundComponentDescriptor,\n} from '@prisma-next/contract/framework-components';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport type { ControlPlaneStack } from '@prisma-next/core-control-plane/types';\nimport { errorConfigValidation, errorContractMissingExtensionPacks } from './cli-errors';\n\n/**\n * Asserts that all framework components are compatible with the expected family and target.\n *\n * This function validates that each component in the framework components array:\n * - Has kind 'target', 'adapter', 'extension', or 'driver'\n * - Has familyId matching expectedFamilyId\n * - Has targetId matching expectedTargetId\n *\n * This validation happens at the CLI composition boundary, before passing components\n * to typed planner/runner instances. It fills the gap between runtime validation\n * (via `validateConfig()`) and compile-time type enforcement.\n *\n * @param expectedFamilyId - The expected family ID (e.g., 'sql')\n * @param expectedTargetId - The expected target ID (e.g., 'postgres')\n * @param frameworkComponents - Array of framework components to validate\n * @returns The same array typed as TargetBoundComponentDescriptor\n * @throws CliStructuredError if any component is incompatible\n *\n * @example\n * ```ts\n * const config = await loadConfig();\n * const frameworkComponents = [config.target, config.adapter, ...(config.extensionPacks ?? [])];\n *\n * // Validate and type-narrow components before passing to planner\n * const typedComponents = assertFrameworkComponentsCompatible(\n * config.family.familyId,\n * config.target.targetId,\n * frameworkComponents\n * );\n *\n * const planner = target.migrations.createPlanner(familyInstance);\n * planner.plan({ contract, schema, policy, frameworkComponents: typedComponents });\n * ```\n */\nexport function assertFrameworkComponentsCompatible<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n expectedFamilyId: TFamilyId,\n expectedTargetId: TTargetId,\n frameworkComponents: ReadonlyArray<unknown>,\n): ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>> {\n for (let i = 0; i < frameworkComponents.length; i++) {\n const component = frameworkComponents[i];\n\n // Check that component is an object\n if (typeof component !== 'object' || component === null) {\n throw errorConfigValidation('frameworkComponents[]', {\n why: `Framework component at index ${i} must be an object`,\n });\n }\n\n const record = component as Record<string, unknown>;\n\n // Check kind\n if (!Object.hasOwn(record, 'kind')) {\n throw errorConfigValidation('frameworkComponents[].kind', {\n why: `Framework component at index ${i} must have 'kind' property`,\n });\n }\n\n const kind = record['kind'];\n if (kind !== 'target' && kind !== 'adapter' && kind !== 'extension' && kind !== 'driver') {\n throw errorConfigValidation('frameworkComponents[].kind', {\n why: `Framework component at index ${i} has invalid kind '${String(kind)}' (must be 'target', 'adapter', 'extension', or 'driver')`,\n });\n }\n\n // Check familyId\n if (!Object.hasOwn(record, 'familyId')) {\n throw errorConfigValidation('frameworkComponents[].familyId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'familyId' property`,\n });\n }\n\n const familyId = record['familyId'];\n if (familyId !== expectedFamilyId) {\n throw errorConfigValidation('frameworkComponents[].familyId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) has familyId '${String(familyId)}' but expected '${expectedFamilyId}'`,\n });\n }\n\n // Check targetId\n if (!Object.hasOwn(record, 'targetId')) {\n throw errorConfigValidation('frameworkComponents[].targetId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'targetId' property`,\n });\n }\n\n const targetId = record['targetId'];\n if (targetId !== expectedTargetId) {\n throw errorConfigValidation('frameworkComponents[].targetId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) has targetId '${String(targetId)}' but expected '${expectedTargetId}'`,\n });\n }\n }\n\n // Type assertion is safe because we've validated all components above\n return frameworkComponents as ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n}\n\n/**\n * Validates that a contract is compatible with the configured target, adapter,\n * and extension packs. Throws on family/target mismatches or missing extension packs.\n *\n * This check ensures the emitted contract matches the CLI config before running\n * commands that depend on the contract (e.g., db verify, db sign).\n *\n * @param contract - The contract IR to validate (must include targetFamily, target, extensionPacks).\n * @param stack - The control plane stack (target, adapter, driver, extensionPacks).\n *\n * @throws {CliStructuredError} errorConfigValidation when contract.targetFamily or contract.target\n * doesn't match the configured family/target.\n * @throws {CliStructuredError} errorContractMissingExtensionPacks when the contract requires\n * extension packs that are not provided in the config (includes all missing packs in error.meta).\n *\n * @example\n * ```ts\n * import { assertContractRequirementsSatisfied } from './framework-components';\n *\n * const config = await loadConfig();\n * const contractIR = await loadContractJson(config.contract.output);\n * const stack = createControlPlaneStack({ target: config.target, adapter: config.adapter, ... });\n *\n * // Throws if contract is incompatible with config\n * assertContractRequirementsSatisfied({ contract: contractIR, stack });\n * ```\n */\nexport function assertContractRequirementsSatisfied<\n TFamilyId extends string,\n TTargetId extends string,\n>({\n contract,\n stack,\n}: {\n readonly contract: Pick<ContractIR, 'targetFamily' | 'target' | 'extensionPacks'>;\n readonly stack: ControlPlaneStack<TFamilyId, TTargetId>;\n}): void {\n const providedComponentIds = new Set<string>([stack.target.id, stack.adapter.id]);\n for (const extension of stack.extensionPacks) {\n providedComponentIds.add(extension.id);\n }\n\n const result = checkContractComponentRequirements({\n contract,\n expectedTargetFamily: stack.target.familyId,\n expectedTargetId: stack.target.targetId,\n providedComponentIds,\n });\n\n if (result.familyMismatch) {\n throw errorConfigValidation('contract.targetFamily', {\n why: `Contract was emitted for family '${result.familyMismatch.actual}' but CLI config is wired to '${result.familyMismatch.expected}'.`,\n });\n }\n\n if (result.targetMismatch) {\n throw errorConfigValidation('contract.target', {\n why: `Contract target '${result.targetMismatch.actual}' does not match CLI target '${result.targetMismatch.expected}'.`,\n });\n }\n\n if (result.missingExtensionPackIds.length > 0) {\n throw errorContractMissingExtensionPacks({\n missingExtensionPacks: result.missingExtensionPackIds,\n providedComponentIds: [...providedComponentIds],\n });\n }\n}\n","import type { TargetBoundComponentDescriptor } from '@prisma-next/contract/framework-components';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport type {\n ControlDriverInstance,\n ControlFamilyInstance,\n MigrationPlan,\n MigrationPlannerResult,\n MigrationPlanOperation,\n MigrationRunnerResult,\n TargetMigrationsCapability,\n} from '@prisma-next/core-control-plane/types';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport type { DbInitResult, DbInitSuccess, OnControlProgress } from '../types';\n\n/**\n * Options for executing dbInit operation.\n */\nexport interface ExecuteDbInitOptions<TFamilyId extends string, TTargetId extends string> {\n readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;\n readonly familyInstance: ControlFamilyInstance<TFamilyId>;\n readonly contractIR: ContractIR;\n readonly mode: 'plan' | 'apply';\n readonly migrations: TargetMigrationsCapability<\n TFamilyId,\n TTargetId,\n ControlFamilyInstance<TFamilyId>\n >;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n /** Optional progress callback for observing operation progress */\n readonly onProgress?: OnControlProgress;\n}\n\n/**\n * Executes the dbInit operation.\n *\n * This is the core logic extracted from the CLI command, without any file I/O,\n * process.exit(), or console output. It uses the Result pattern to return\n * success or failure details.\n *\n * @param options - The options for executing dbInit\n * @returns Result with DbInitSuccess on success, DbInitFailure on failure\n */\nexport async function executeDbInit<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteDbInitOptions<TFamilyId, TTargetId>,\n): Promise<DbInitResult> {\n const { driver, familyInstance, contractIR, mode, migrations, frameworkComponents, onProgress } =\n options;\n\n // Create planner and runner from target migrations capability\n const planner = migrations.createPlanner(familyInstance);\n const runner = migrations.createRunner(familyInstance);\n\n // Introspect live schema\n const introspectSpanId = 'introspect';\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: introspectSpanId,\n label: 'Introspecting database schema',\n });\n const schemaIR = await familyInstance.introspect({ driver });\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: introspectSpanId,\n outcome: 'ok',\n });\n\n // Policy for init mode (additive only)\n const policy = { allowedOperationClasses: ['additive'] as const };\n\n // Plan migration\n const planSpanId = 'plan';\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: planSpanId,\n label: 'Planning migration',\n });\n const plannerResult: MigrationPlannerResult = await planner.plan({\n contract: contractIR,\n schema: schemaIR,\n policy,\n frameworkComponents,\n });\n\n if (plannerResult.kind === 'failure') {\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: planSpanId,\n outcome: 'error',\n });\n return notOk({\n code: 'PLANNING_FAILED' as const,\n summary: 'Migration planning failed due to conflicts',\n conflicts: plannerResult.conflicts,\n why: undefined,\n meta: undefined,\n });\n }\n\n const migrationPlan: MigrationPlan = plannerResult.plan;\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: planSpanId,\n outcome: 'ok',\n });\n\n // Check for existing marker - handle idempotency and mismatch errors\n const checkMarkerSpanId = 'checkMarker';\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: checkMarkerSpanId,\n label: 'Checking contract marker',\n });\n const existingMarker = await familyInstance.readMarker({ driver });\n if (existingMarker) {\n const markerMatchesDestination =\n existingMarker.coreHash === migrationPlan.destination.coreHash &&\n (!migrationPlan.destination.profileHash ||\n existingMarker.profileHash === migrationPlan.destination.profileHash);\n\n if (markerMatchesDestination) {\n // Already at destination - return success with no operations\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: checkMarkerSpanId,\n outcome: 'skipped',\n });\n const result: DbInitSuccess = {\n mode,\n plan: { operations: [] },\n ...(mode === 'apply'\n ? {\n execution: { operationsPlanned: 0, operationsExecuted: 0 },\n marker: {\n coreHash: existingMarker.coreHash,\n profileHash: existingMarker.profileHash,\n },\n }\n : {}),\n summary: 'Database already at target contract state',\n };\n return ok(result);\n }\n\n // Marker exists but doesn't match destination - fail\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: checkMarkerSpanId,\n outcome: 'error',\n });\n return notOk({\n code: 'MARKER_ORIGIN_MISMATCH' as const,\n summary: 'Existing contract marker does not match plan destination',\n marker: {\n coreHash: existingMarker.coreHash,\n profileHash: existingMarker.profileHash,\n },\n destination: {\n coreHash: migrationPlan.destination.coreHash,\n profileHash: migrationPlan.destination.profileHash,\n },\n why: undefined,\n conflicts: undefined,\n meta: undefined,\n });\n }\n\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: checkMarkerSpanId,\n outcome: 'ok',\n });\n\n // Plan mode - don't execute\n if (mode === 'plan') {\n const result: DbInitSuccess = {\n mode: 'plan',\n plan: { operations: migrationPlan.operations },\n summary: `Planned ${migrationPlan.operations.length} operation(s)`,\n };\n return ok(result);\n }\n\n // Apply mode - execute runner\n const applySpanId = 'apply';\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: applySpanId,\n label: 'Applying migration plan',\n });\n\n const callbacks = onProgress\n ? {\n onOperationStart: (op: MigrationPlanOperation) => {\n onProgress({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: `operation:${op.id}`,\n parentSpanId: applySpanId,\n label: op.label,\n });\n },\n onOperationComplete: (op: MigrationPlanOperation) => {\n onProgress({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: `operation:${op.id}`,\n outcome: 'ok',\n });\n },\n }\n : undefined;\n\n const runnerResult: MigrationRunnerResult = await runner.execute({\n plan: migrationPlan,\n driver,\n destinationContract: contractIR,\n policy,\n ...(callbacks ? { callbacks } : {}),\n // db init plans and applies back-to-back from a fresh introspection, so per-operation\n // pre/postchecks and the idempotency probe are usually redundant overhead. We still\n // enforce marker/origin compatibility and a full schema verification after apply.\n executionChecks: {\n prechecks: false,\n postchecks: false,\n idempotencyChecks: false,\n },\n frameworkComponents,\n });\n\n if (!runnerResult.ok) {\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: applySpanId,\n outcome: 'error',\n });\n return notOk({\n code: 'RUNNER_FAILED' as const,\n summary: runnerResult.failure.summary,\n why: runnerResult.failure.why,\n meta: runnerResult.failure.meta,\n conflicts: undefined,\n });\n }\n\n const execution = runnerResult.value;\n\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: applySpanId,\n outcome: 'ok',\n });\n\n const result: DbInitSuccess = {\n mode: 'apply',\n plan: { operations: migrationPlan.operations },\n execution: {\n operationsPlanned: execution.operationsPlanned,\n operationsExecuted: execution.operationsExecuted,\n },\n marker: migrationPlan.destination.profileHash\n ? {\n coreHash: migrationPlan.destination.coreHash,\n profileHash: migrationPlan.destination.profileHash,\n }\n : { coreHash: migrationPlan.destination.coreHash },\n summary: `Applied ${execution.operationsExecuted} operation(s), marker written`,\n };\n return ok(result);\n}\n","import type { TargetBoundComponentDescriptor } from '@prisma-next/contract/framework-components';\nimport type { CoreSchemaView } from '@prisma-next/core-control-plane/schema-view';\nimport { createControlPlaneStack } from '@prisma-next/core-control-plane/stack';\nimport type {\n ControlDriverInstance,\n ControlFamilyInstance,\n ControlPlaneStack,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/core-control-plane/types';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components';\nimport { executeDbInit } from './operations/db-init';\nimport type {\n ControlClient,\n ControlClientOptions,\n DbInitOptions,\n DbInitResult,\n EmitOptions,\n EmitResult,\n IntrospectOptions,\n SchemaVerifyOptions,\n SignOptions,\n VerifyOptions,\n} from './types';\n\n/**\n * Creates a programmatic control client for Prisma Next operations.\n *\n * The client accepts framework component descriptors at creation time,\n * manages driver lifecycle via connect()/close(), and exposes domain\n * operations that delegate to the existing family instance methods.\n *\n * @see {@link ControlClient} for the client interface\n * @see README.md \"Programmatic Control API\" section for usage examples\n */\nexport function createControlClient(options: ControlClientOptions): ControlClient {\n return new ControlClientImpl(options);\n}\n\n/**\n * Implementation of ControlClient.\n * Manages initialization and connection state, delegates operations to family instance.\n */\nclass ControlClientImpl implements ControlClient {\n private readonly options: ControlClientOptions;\n private stack: ControlPlaneStack<string, string> | null = null;\n private driver: ControlDriverInstance<string, string> | null = null;\n private familyInstance: ControlFamilyInstance<string> | null = null;\n private frameworkComponents: ReadonlyArray<\n TargetBoundComponentDescriptor<string, string>\n > | null = null;\n private initialized = false;\n private readonly defaultConnection: unknown;\n\n constructor(options: ControlClientOptions) {\n this.options = options;\n this.defaultConnection = options.connection;\n }\n\n init(): void {\n if (this.initialized) {\n return; // Idempotent\n }\n\n // Create the control plane stack\n this.stack = createControlPlaneStack({\n target: this.options.target,\n adapter: this.options.adapter,\n driver: this.options.driver,\n extensionPacks: this.options.extensionPacks,\n });\n\n // Create family instance using the stack\n this.familyInstance = this.options.family.create(this.stack);\n\n // Validate and type-narrow framework components\n const rawComponents = [\n this.options.target,\n this.options.adapter,\n ...(this.options.extensionPacks ?? []),\n ];\n this.frameworkComponents = assertFrameworkComponentsCompatible(\n this.options.family.familyId,\n this.options.target.targetId,\n rawComponents,\n );\n\n this.initialized = true;\n }\n\n async connect(connection?: unknown): Promise<void> {\n // Auto-init if needed\n this.init();\n\n if (this.driver) {\n throw new Error('Already connected. Call close() before reconnecting.');\n }\n\n // Resolve connection: argument > default from options\n const resolvedConnection = connection ?? this.defaultConnection;\n if (resolvedConnection === undefined) {\n throw new Error(\n 'No connection provided. Pass a connection to connect() or provide a default connection when creating the client.',\n );\n }\n\n // Check for driver descriptor\n if (!this.stack?.driver) {\n throw new Error(\n 'Driver is not configured. Pass a driver descriptor when creating the control client to enable database operations.',\n );\n }\n\n // Create driver instance\n // Cast through any since connection type is driver-specific at runtime.\n // The driver descriptor is typed with any for TConnection in ControlClientOptions,\n // but createControlPlaneStack defaults it to string. We bridge this at runtime.\n // biome-ignore lint/suspicious/noExplicitAny: required for runtime connection type flexibility\n this.driver = await this.stack?.driver.create(resolvedConnection as any);\n }\n\n async close(): Promise<void> {\n if (this.driver) {\n await this.driver.close();\n this.driver = null;\n }\n }\n\n private async ensureConnected(): Promise<{\n driver: ControlDriverInstance<string, string>;\n familyInstance: ControlFamilyInstance<string>;\n frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<string, string>>;\n }> {\n // Auto-init if needed\n this.init();\n\n // Auto-connect if not connected and default connection is available\n if (!this.driver && this.defaultConnection !== undefined) {\n await this.connect(this.defaultConnection);\n }\n\n if (!this.driver || !this.familyInstance || !this.frameworkComponents) {\n throw new Error('Not connected. Call connect(connection) first.');\n }\n return {\n driver: this.driver,\n familyInstance: this.familyInstance,\n frameworkComponents: this.frameworkComponents,\n };\n }\n\n async verify(options: VerifyOptions): Promise<VerifyDatabaseResult> {\n const { onProgress } = options;\n\n // Connect with progress span if connection provided\n if (options.connection !== undefined) {\n onProgress?.({\n action: 'verify',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance } = await this.ensureConnected();\n\n // Validate contract using family instance\n const contractIR = familyInstance.validateContractIR(options.contractIR);\n\n // Emit verify span\n onProgress?.({\n action: 'verify',\n kind: 'spanStart',\n spanId: 'verify',\n label: 'Verifying contract marker...',\n });\n\n try {\n // Delegate to family instance verify method\n // Note: We pass empty strings for contractPath/configPath since the programmatic\n // API doesn't deal with file paths. The family instance accepts these as optional\n // metadata for error reporting.\n const result = await familyInstance.verify({\n driver,\n contractIR,\n expectedTargetId: this.options.target.targetId,\n contractPath: '',\n });\n\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'verify',\n outcome: result.ok ? 'ok' : 'error',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'verify',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n async schemaVerify(options: SchemaVerifyOptions): Promise<VerifyDatabaseSchemaResult> {\n const { onProgress } = options;\n\n // Connect with progress span if connection provided\n if (options.connection !== undefined) {\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();\n\n // Validate contract using family instance\n const contractIR = familyInstance.validateContractIR(options.contractIR);\n\n // Emit schemaVerify span\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanStart',\n spanId: 'schemaVerify',\n label: 'Verifying database schema...',\n });\n\n try {\n // Delegate to family instance schemaVerify method\n const result = await familyInstance.schemaVerify({\n driver,\n contractIR,\n strict: options.strict ?? false,\n contractPath: '',\n frameworkComponents,\n });\n\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'schemaVerify',\n outcome: result.ok ? 'ok' : 'error',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'schemaVerify',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n async sign(options: SignOptions): Promise<SignDatabaseResult> {\n const { onProgress } = options;\n\n // Connect with progress span if connection provided\n if (options.connection !== undefined) {\n onProgress?.({\n action: 'sign',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance } = await this.ensureConnected();\n\n // Validate contract using family instance\n const contractIR = familyInstance.validateContractIR(options.contractIR);\n\n // Emit sign span\n onProgress?.({\n action: 'sign',\n kind: 'spanStart',\n spanId: 'sign',\n label: 'Signing database...',\n });\n\n try {\n // Delegate to family instance sign method\n const result = await familyInstance.sign({\n driver,\n contractIR,\n contractPath: options.contractPath ?? '',\n ...(options.configPath ? { configPath: options.configPath } : {}),\n });\n\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'sign',\n outcome: 'ok',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'sign',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n async dbInit(options: DbInitOptions): Promise<DbInitResult> {\n const { onProgress } = options;\n\n // Connect with progress span if connection provided\n if (options.connection !== undefined) {\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();\n\n // Check target supports migrations\n if (!this.options.target.migrations) {\n throw new Error(`Target \"${this.options.target.targetId}\" does not support migrations`);\n }\n\n // Validate contract using family instance\n const contractIR = familyInstance.validateContractIR(options.contractIR);\n\n // Delegate to extracted dbInit operation\n return executeDbInit({\n driver,\n familyInstance,\n contractIR,\n mode: options.mode,\n migrations: this.options.target.migrations,\n frameworkComponents,\n ...(onProgress ? { onProgress } : {}),\n });\n }\n\n async introspect(options?: IntrospectOptions): Promise<unknown> {\n const onProgress = options?.onProgress;\n\n // Connect with progress span if connection provided\n if (options?.connection !== undefined) {\n onProgress?.({\n action: 'introspect',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance } = await this.ensureConnected();\n\n // TODO: Pass schema option to familyInstance.introspect when schema filtering is implemented\n const _schema = options?.schema;\n void _schema;\n\n // Emit introspect span\n onProgress?.({\n action: 'introspect',\n kind: 'spanStart',\n spanId: 'introspect',\n label: 'Introspecting database schema...',\n });\n\n try {\n const result = await familyInstance.introspect({ driver });\n\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'introspect',\n outcome: 'ok',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'introspect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n toSchemaView(schemaIR: unknown): CoreSchemaView | undefined {\n this.init();\n if (this.familyInstance?.toSchemaView) {\n return this.familyInstance.toSchemaView(schemaIR);\n }\n return undefined;\n }\n\n async emit(options: EmitOptions): Promise<EmitResult> {\n const { onProgress, contractConfig } = options;\n\n // Ensure initialized (creates stack and family instance)\n // emit() does NOT require a database connection\n this.init();\n\n if (!this.familyInstance) {\n throw new Error('Family instance was not initialized. This is a bug.');\n }\n\n // Resolve contract source\n let contractRaw: unknown;\n onProgress?.({\n action: 'emit',\n kind: 'spanStart',\n spanId: 'resolveSource',\n label: 'Resolving contract source...',\n });\n\n try {\n switch (contractConfig.source.kind) {\n case 'loader':\n contractRaw = await contractConfig.source.load();\n break;\n case 'value':\n contractRaw = contractConfig.source.value;\n break;\n }\n\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'resolveSource',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'resolveSource',\n outcome: 'error',\n });\n\n return notOk({\n code: 'CONTRACT_SOURCE_INVALID',\n summary: 'Failed to resolve contract source',\n why: error instanceof Error ? error.message : String(error),\n meta: undefined,\n });\n }\n\n // Emit contract\n onProgress?.({\n action: 'emit',\n kind: 'spanStart',\n spanId: 'emit',\n label: 'Emitting contract...',\n });\n\n try {\n const emitResult = await this.familyInstance.emitContract({ contractIR: contractRaw });\n\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'emit',\n outcome: 'ok',\n });\n\n return ok({\n coreHash: emitResult.coreHash,\n profileHash: emitResult.profileHash,\n contractJson: emitResult.contractJson,\n contractDts: emitResult.contractDts,\n });\n } catch (error) {\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'emit',\n outcome: 'error',\n });\n\n return notOk({\n code: 'EMIT_FAILED',\n summary: 'Failed to emit contract',\n why: error instanceof Error ? error.message : String(error),\n meta: undefined,\n });\n }\n }\n}\n","import type { Command } from 'commander';\n\n/**\n * Sets both short and long descriptions for a command.\n * The short description is used in command trees and headers.\n * The long description is shown at the bottom of help output.\n */\nexport function setCommandDescriptions(\n command: Command,\n shortDescription: string,\n longDescription?: string,\n): Command {\n command.description(shortDescription);\n if (longDescription) {\n // Store long description in a custom property for our formatters to access\n (command as Command & { _longDescription?: string })._longDescription = longDescription;\n }\n return command;\n}\n\n/**\n * Gets the long description from a command if it was set via setCommandDescriptions.\n */\nexport function getLongDescription(command: Command): string | undefined {\n return (command as Command & { _longDescription?: string })._longDescription;\n}\n","export interface GlobalFlags {\n readonly json?: 'object' | 'ndjson';\n readonly quiet?: boolean;\n readonly verbose?: number; // 0, 1, or 2\n readonly timestamps?: boolean;\n readonly color?: boolean;\n}\n\nexport interface CliOptions {\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Parses global flags from CLI options.\n * Handles verbosity flags (-v, -vv, --trace), JSON output, quiet mode, timestamps, and color.\n */\nexport function parseGlobalFlags(options: CliOptions): GlobalFlags {\n const flags: {\n json?: 'object' | 'ndjson';\n quiet?: boolean;\n verbose?: number;\n timestamps?: boolean;\n color?: boolean;\n } = {};\n\n // JSON output\n if (options.json === true || options.json === 'object') {\n flags.json = 'object';\n } else if (options.json === 'ndjson') {\n flags.json = 'ndjson';\n }\n\n // Quiet mode\n if (options.quiet || options.q) {\n flags.quiet = true;\n }\n\n // Verbosity: -v = 1, -vv or --trace = 2\n if (options.vv || options.trace) {\n flags.verbose = 2;\n } else if (options.verbose || options.v) {\n flags.verbose = 1;\n } else {\n flags.verbose = 0;\n }\n\n // Timestamps\n if (options.timestamps) {\n flags.timestamps = true;\n }\n\n // Color: respect NO_COLOR env var, --color/--no-color flags\n // When JSON output is enabled (any format), disable color to ensure clean JSON output\n if (process.env['NO_COLOR'] || flags.json) {\n flags.color = false;\n } else if (options['no-color']) {\n flags.color = false;\n } else if (options.color !== undefined) {\n flags.color = options.color;\n } else {\n // Default: enable color if TTY\n flags.color = process.stdout.isTTY && !process.env['CI'];\n }\n\n return flags as GlobalFlags;\n}\n","import { relative } from 'node:path';\nimport { bgGreen, blue, bold, cyan, dim, green, magenta, red, yellow } from 'colorette';\nimport type { Command } from 'commander';\nimport stringWidth from 'string-width';\nimport stripAnsi from 'strip-ansi';\nimport wrapAnsi from 'wrap-ansi';\n// EmitContractResult type for CLI output formatting (includes file paths)\nexport interface EmitContractResult {\n readonly coreHash: string;\n readonly profileHash: string;\n readonly outDir: string;\n readonly files: {\n readonly json: string;\n readonly dts: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nimport type { CoreSchemaView, SchemaTreeNode } from '@prisma-next/core-control-plane/schema-view';\nimport type {\n IntrospectSchemaResult,\n SchemaVerificationNode,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/core-control-plane/types';\nimport type { CliErrorConflict, CliErrorEnvelope } from './cli-errors';\nimport { getLongDescription } from './command-helpers';\nimport type { GlobalFlags } from './global-flags';\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Formats a timestamp for output.\n */\nfunction formatTimestamp(): string {\n return new Date().toISOString();\n}\n\n/**\n * Creates a prefix string if timestamps are enabled.\n */\nfunction createPrefix(flags: GlobalFlags): string {\n return flags.timestamps ? `[${formatTimestamp()}] ` : '';\n}\n\n/**\n * Checks if verbose output is enabled at the specified level.\n */\nfunction isVerbose(flags: GlobalFlags, level: 1 | 2): boolean {\n return (flags.verbose ?? 0) >= level;\n}\n\n/**\n * Creates a color-aware formatter function.\n * Returns a function that applies the color only if colors are enabled.\n */\nfunction createColorFormatter<T extends (text: string) => string>(\n useColor: boolean,\n colorFn: T,\n): (text: string) => string {\n return useColor ? colorFn : (text: string) => text;\n}\n\n/**\n * Formats text with dim styling if colors are enabled.\n */\nfunction formatDim(useColor: boolean, text: string): string {\n return useColor ? dim(text) : text;\n}\n\n// ============================================================================\n// Emit Output Formatters\n// ============================================================================\n\n/**\n * Formats human-readable output for contract emit.\n */\nexport function formatEmitOutput(result: EmitContractResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n\n // Convert absolute paths to relative paths from cwd\n const jsonPath = relative(process.cwd(), result.files.json);\n const dtsPath = relative(process.cwd(), result.files.dts);\n\n lines.push(`${prefix}✔ Emitted contract.json → ${jsonPath}`);\n lines.push(`${prefix}✔ Emitted contract.d.ts → ${dtsPath}`);\n lines.push(`${prefix} coreHash: ${result.coreHash}`);\n if (result.profileHash) {\n lines.push(`${prefix} profileHash: ${result.profileHash}`);\n }\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix} Total time: ${result.timings.total}ms`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for contract emit.\n */\nexport function formatEmitJson(result: EmitContractResult): string {\n const output = {\n ok: true,\n coreHash: result.coreHash,\n ...(result.profileHash ? { profileHash: result.profileHash } : {}),\n outDir: result.outDir,\n files: result.files,\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n\n// ============================================================================\n// Error Output Formatters\n// ============================================================================\n\n/**\n * Formats error output for human-readable display.\n */\nexport function formatErrorOutput(error: CliErrorEnvelope, flags: GlobalFlags): string {\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatRed = createColorFormatter(useColor, red);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n lines.push(`${prefix}${formatRed('✖')} ${error.summary} (${error.code})`);\n\n if (error.why) {\n lines.push(`${prefix}${formatDimText(` Why: ${error.why}`)}`);\n }\n if (error.fix) {\n lines.push(`${prefix}${formatDimText(` Fix: ${error.fix}`)}`);\n }\n if (error.where?.path) {\n const whereLine = error.where.line\n ? `${error.where.path}:${error.where.line}`\n : error.where.path;\n lines.push(`${prefix}${formatDimText(` Where: ${whereLine}`)}`);\n }\n // Show conflicts list if present (always show a short list; show full list when verbose)\n if (error.meta?.['conflicts']) {\n const conflicts = error.meta['conflicts'] as readonly CliErrorConflict[];\n if (conflicts.length > 0) {\n const maxToShow = isVerbose(flags, 1) ? conflicts.length : Math.min(3, conflicts.length);\n const header = isVerbose(flags, 1)\n ? ' Conflicts:'\n : ` Conflicts (showing ${maxToShow} of ${conflicts.length}):`;\n lines.push(`${prefix}${formatDimText(header)}`);\n for (const conflict of conflicts.slice(0, maxToShow)) {\n lines.push(`${prefix}${formatDimText(` - [${conflict.kind}] ${conflict.summary}`)}`);\n }\n if (!isVerbose(flags, 1) && conflicts.length > maxToShow) {\n lines.push(`${prefix}${formatDimText(' Re-run with -v/--verbose to see all conflicts')}`);\n }\n }\n }\n // Show issues list if present (always show a short list; show full list when verbose)\n if (error.meta?.['issues']) {\n const issues = error.meta['issues'] as readonly { kind?: string; message?: string }[];\n if (issues.length > 0) {\n const maxToShow = isVerbose(flags, 1) ? issues.length : Math.min(3, issues.length);\n const header = isVerbose(flags, 1)\n ? ' Issues:'\n : ` Issues (showing ${maxToShow} of ${issues.length}):`;\n lines.push(`${prefix}${formatDimText(header)}`);\n for (const issue of issues.slice(0, maxToShow)) {\n const kind = issue.kind ?? 'issue';\n const message = issue.message ?? '';\n lines.push(`${prefix}${formatDimText(` - [${kind}] ${message}`)}`);\n }\n if (!isVerbose(flags, 1) && issues.length > maxToShow) {\n lines.push(`${prefix}${formatDimText(' Re-run with -v/--verbose to see all issues')}`);\n }\n }\n }\n if (error.docsUrl && isVerbose(flags, 1)) {\n lines.push(formatDimText(error.docsUrl));\n }\n if (isVerbose(flags, 2) && error.meta) {\n lines.push(`${prefix}${formatDimText(` Meta: ${JSON.stringify(error.meta, null, 2)}`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats error output as JSON.\n */\nexport function formatErrorJson(error: CliErrorEnvelope): string {\n return JSON.stringify(error, null, 2);\n}\n\n// ============================================================================\n// Verify Output Formatters\n// ============================================================================\n\n/**\n * Formats human-readable output for database verify.\n */\nexport function formatVerifyOutput(result: VerifyDatabaseResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatRed = createColorFormatter(useColor, red);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n lines.push(`${prefix}${formatGreen('✔')} ${result.summary}`);\n lines.push(`${prefix}${formatDimText(` coreHash: ${result.contract.coreHash}`)}`);\n if (result.contract.profileHash) {\n lines.push(`${prefix}${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n } else {\n lines.push(`${prefix}${formatRed('✖')} ${result.summary} (${result.code})`);\n }\n\n if (isVerbose(flags, 1)) {\n if (result.codecCoverageSkipped) {\n lines.push(\n `${prefix}${formatDimText(' Codec coverage check skipped (helper returned no supported types)')}`,\n );\n }\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database verify.\n */\nexport function formatVerifyJson(result: VerifyDatabaseResult): string {\n const output = {\n ok: result.ok,\n ...(result.code ? { code: result.code } : {}),\n summary: result.summary,\n contract: result.contract,\n ...(result.marker ? { marker: result.marker } : {}),\n target: result.target,\n ...(result.missingCodecs ? { missingCodecs: result.missingCodecs } : {}),\n ...(result.meta ? { meta: result.meta } : {}),\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Formats JSON output for database introspection.\n */\nexport function formatIntrospectJson(result: IntrospectSchemaResult<unknown>): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Renders a schema tree structure from CoreSchemaView.\n * Matches the style of renderSchemaVerificationTree for consistency.\n */\nfunction renderSchemaTree(\n node: SchemaTreeNode,\n flags: GlobalFlags,\n options: {\n readonly isLast: boolean;\n readonly prefix: string;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly isRoot?: boolean;\n },\n): string[] {\n const { isLast, prefix, useColor, formatDimText, isRoot = false } = options;\n const lines: string[] = [];\n\n // Format node label with color based on kind (matching schema-verify style)\n let formattedLabel: string = node.label;\n\n if (useColor) {\n switch (node.kind) {\n case 'root':\n formattedLabel = bold(node.label);\n break;\n case 'entity': {\n // Parse \"table tableName\" format - color \"table\" dim, tableName cyan\n const tableMatch = node.label.match(/^table\\s+(.+)$/);\n if (tableMatch?.[1]) {\n const tableName = tableMatch[1];\n formattedLabel = `${dim('table')} ${cyan(tableName)}`;\n } else {\n // Fallback: color entire label with cyan\n formattedLabel = cyan(node.label);\n }\n break;\n }\n case 'collection': {\n // \"columns\" grouping node - dim the label\n formattedLabel = dim(node.label);\n break;\n }\n case 'field': {\n // Parse column name format: \"columnName: typeDisplay (nullability)\"\n // Color code: column name (cyan), type (default), nullability (dim)\n const columnMatch = node.label.match(/^([^:]+):\\s*(.+)$/);\n if (columnMatch?.[1] && columnMatch[2]) {\n const columnName = columnMatch[1];\n const rest = columnMatch[2];\n // Parse rest: \"typeDisplay (nullability)\"\n const typeMatch = rest.match(/^([^\\s(]+)\\s*(\\([^)]+\\))$/);\n if (typeMatch?.[1] && typeMatch[2]) {\n const typeDisplay = typeMatch[1];\n const nullability = typeMatch[2];\n formattedLabel = `${cyan(columnName)}: ${typeDisplay} ${dim(nullability)}`;\n } else {\n // Fallback if format doesn't match\n formattedLabel = `${cyan(columnName)}: ${rest}`;\n }\n } else {\n formattedLabel = node.label;\n }\n break;\n }\n case 'index': {\n // Parse index/unique constraint/primary key formats\n // \"primary key: columnName\" -> dim \"primary key\", cyan columnName\n const pkMatch = node.label.match(/^primary key:\\s*(.+)$/);\n if (pkMatch?.[1]) {\n const columnNames = pkMatch[1];\n formattedLabel = `${dim('primary key')}: ${cyan(columnNames)}`;\n } else {\n // \"unique name\" -> dim \"unique\", cyan \"name\"\n const uniqueMatch = node.label.match(/^unique\\s+(.+)$/);\n if (uniqueMatch?.[1]) {\n const name = uniqueMatch[1];\n formattedLabel = `${dim('unique')} ${cyan(name)}`;\n } else {\n // \"index name\" or \"unique index name\" -> dim label prefix, cyan name\n const indexMatch = node.label.match(/^(unique\\s+)?index\\s+(.+)$/);\n if (indexMatch?.[2]) {\n const prefix = indexMatch[1] ? `${dim('unique')} ` : '';\n const name = indexMatch[2];\n formattedLabel = `${prefix}${dim('index')} ${cyan(name)}`;\n } else {\n formattedLabel = dim(node.label);\n }\n }\n }\n break;\n }\n case 'extension': {\n // Parse extension message formats similar to schema-verify\n // \"extensionName extension is enabled\" -> cyan extensionName, dim rest\n const extMatch = node.label.match(/^([^\\s]+)\\s+(extension is enabled)$/);\n if (extMatch?.[1] && extMatch[2]) {\n const extName = extMatch[1];\n const rest = extMatch[2];\n formattedLabel = `${cyan(extName)} ${dim(rest)}`;\n } else {\n // Fallback: color entire label with magenta\n formattedLabel = magenta(node.label);\n }\n break;\n }\n default:\n formattedLabel = node.label;\n break;\n }\n }\n\n // Root node renders without tree characters or │ prefix\n if (isRoot) {\n lines.push(formattedLabel);\n } else {\n // Determine tree character for this node\n const treeChar = isLast ? '└' : '├';\n const treePrefix = `${prefix}${formatDimText(treeChar)}─ `;\n // Root's direct children don't have │ prefix, other nodes do\n // But if prefix already contains │ (for nested children), don't add another\n const isRootChild = prefix === '';\n // Check if prefix already contains │ (strip ANSI codes for comparison)\n const prefixWithoutAnsi = stripAnsi(prefix);\n const prefixHasVerticalBar = prefixWithoutAnsi.includes('│');\n if (isRootChild) {\n lines.push(`${treePrefix}${formattedLabel}`);\n } else if (prefixHasVerticalBar) {\n // Prefix already has │, so just use treePrefix directly\n lines.push(`${treePrefix}${formattedLabel}`);\n } else {\n lines.push(`${formatDimText('│')} ${treePrefix}${formattedLabel}`);\n }\n }\n\n // Render children if present\n if (node.children && node.children.length > 0) {\n // For root node, children start with no prefix (they'll add their own tree characters)\n // For other nodes, calculate child prefix based on whether this is last\n const childPrefix = isRoot ? '' : isLast ? `${prefix} ` : `${prefix}${formatDimText('│')} `;\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n if (!child) continue;\n const isLastChild = i === node.children.length - 1;\n const childLines = renderSchemaTree(child, flags, {\n isLast: isLastChild,\n prefix: childPrefix,\n useColor,\n formatDimText,\n isRoot: false,\n });\n lines.push(...childLines);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats human-readable output for database introspection.\n */\nexport function formatIntrospectOutput(\n result: IntrospectSchemaResult<unknown>,\n schemaView: CoreSchemaView | undefined,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (schemaView) {\n // Render tree structure - root node is special (no tree characters)\n const treeLines = renderSchemaTree(schemaView.root, flags, {\n isLast: true,\n prefix: '',\n useColor,\n formatDimText,\n isRoot: true,\n });\n // Apply prefix (for timestamps) to each tree line\n const prefixedTreeLines = treeLines.map((line) => `${prefix}${line}`);\n lines.push(...prefixedTreeLines);\n } else {\n // Fallback: print summary when toSchemaView is not available\n lines.push(`${prefix}✔ ${result.summary}`);\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix} Target: ${result.target.familyId}/${result.target.id}`);\n if (result.meta?.dbUrl) {\n lines.push(`${prefix} Database: ${result.meta.dbUrl}`);\n }\n }\n }\n\n // Add timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Renders a schema verification tree structure from SchemaVerificationNode.\n * Similar to renderSchemaTree but for verification nodes with status-based colors and glyphs.\n */\nfunction renderSchemaVerificationTree(\n node: SchemaVerificationNode,\n flags: GlobalFlags,\n options: {\n readonly isLast: boolean;\n readonly prefix: string;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly isRoot?: boolean;\n },\n): string[] {\n const { isLast, prefix, useColor, formatDimText, isRoot = false } = options;\n const lines: string[] = [];\n\n // Format status glyph and color based on status\n let statusGlyph = '';\n let statusColor: (text: string) => string = (text) => text;\n if (useColor) {\n switch (node.status) {\n case 'pass':\n statusGlyph = '✔';\n statusColor = green;\n break;\n case 'warn':\n statusGlyph = '⚠';\n statusColor = (text) => (useColor ? yellow(text) : text);\n break;\n case 'fail':\n statusGlyph = '✖';\n statusColor = red;\n break;\n }\n } else {\n switch (node.status) {\n case 'pass':\n statusGlyph = '✔';\n break;\n case 'warn':\n statusGlyph = '⚠';\n break;\n case 'fail':\n statusGlyph = '✖';\n break;\n }\n }\n\n // Format node label with color based on kind\n // For column nodes, we need to parse the name to color code different parts\n let labelColor: (text: string) => string = (text) => text;\n let formattedLabel: string = node.name;\n\n if (useColor) {\n switch (node.kind) {\n case 'contract':\n case 'schema':\n labelColor = bold;\n formattedLabel = labelColor(node.name);\n break;\n case 'table': {\n // Parse \"table tableName\" format - color \"table\" dim, tableName cyan\n const tableMatch = node.name.match(/^table\\s+(.+)$/);\n if (tableMatch?.[1]) {\n const tableName = tableMatch[1];\n formattedLabel = `${dim('table')} ${cyan(tableName)}`;\n } else {\n formattedLabel = dim(node.name);\n }\n break;\n }\n case 'columns':\n labelColor = dim;\n formattedLabel = labelColor(node.name);\n break;\n case 'column': {\n // Parse column name format: \"columnName: contractType → nativeType (nullability)\"\n // Color code: column name (cyan), contract type (default), native type (dim), nullability (dim)\n const columnMatch = node.name.match(/^([^:]+):\\s*(.+)$/);\n if (columnMatch?.[1] && columnMatch[2]) {\n const columnName = columnMatch[1];\n const rest = columnMatch[2];\n // Parse rest: \"contractType → nativeType (nullability)\"\n // Match contract type (can contain /, @, etc.), arrow, native type, then nullability in parentheses\n const typeMatch = rest.match(/^([^\\s→]+)\\s*→\\s*([^\\s(]+)\\s*(\\([^)]+\\))$/);\n if (typeMatch?.[1] && typeMatch[2] && typeMatch[3]) {\n const contractType = typeMatch[1];\n const nativeType = typeMatch[2];\n const nullability = typeMatch[3];\n formattedLabel = `${cyan(columnName)}: ${contractType} → ${dim(nativeType)} ${dim(nullability)}`;\n } else {\n // Fallback if format doesn't match (e.g., no native type or no nullability)\n formattedLabel = `${cyan(columnName)}: ${rest}`;\n }\n } else {\n formattedLabel = node.name;\n }\n break;\n }\n case 'type':\n case 'nullability':\n labelColor = (text) => text; // Default color\n formattedLabel = labelColor(node.name);\n break;\n case 'primaryKey': {\n // Parse \"primary key: columnName\" format - color \"primary key\" dim, columnName cyan\n const pkMatch = node.name.match(/^primary key:\\s*(.+)$/);\n if (pkMatch?.[1]) {\n const columnNames = pkMatch[1];\n formattedLabel = `${dim('primary key')}: ${cyan(columnNames)}`;\n } else {\n formattedLabel = dim(node.name);\n }\n break;\n }\n case 'foreignKey':\n case 'unique':\n case 'index':\n labelColor = dim;\n formattedLabel = labelColor(node.name);\n break;\n case 'extension': {\n // Parse specific extension message formats\n // \"database is postgres\" -> dim \"database is\", cyan \"postgres\"\n const dbMatch = node.name.match(/^database is\\s+(.+)$/);\n if (dbMatch?.[1]) {\n const dbName = dbMatch[1];\n formattedLabel = `${dim('database is')} ${cyan(dbName)}`;\n } else {\n // \"vector extension is enabled\" -> dim everything except extension name\n // Match pattern: \"extensionName extension is enabled\"\n const extMatch = node.name.match(/^([^\\s]+)\\s+(extension is enabled)$/);\n if (extMatch?.[1] && extMatch[2]) {\n const extName = extMatch[1];\n const rest = extMatch[2];\n formattedLabel = `${cyan(extName)} ${dim(rest)}`;\n } else {\n // Fallback: color entire name with magenta\n labelColor = magenta;\n formattedLabel = labelColor(node.name);\n }\n }\n break;\n }\n default:\n formattedLabel = node.name;\n break;\n }\n } else {\n formattedLabel = node.name;\n }\n\n const statusGlyphColored = statusColor(statusGlyph);\n\n // Build the label with optional message for failure/warn nodes\n let nodeLabel = formattedLabel;\n if (\n (node.status === 'fail' || node.status === 'warn') &&\n node.message &&\n node.message.length > 0\n ) {\n // Always show message for failure/warn nodes - it provides crucial context\n // For parent nodes, the message summarizes child failures\n // For leaf nodes, the message explains the specific issue\n const messageText = formatDimText(`(${node.message})`);\n nodeLabel = `${formattedLabel} ${messageText}`;\n }\n\n // Root node renders without tree characters or │ prefix\n if (isRoot) {\n lines.push(`${statusGlyphColored} ${nodeLabel}`);\n } else {\n // Determine tree character for this node\n const treeChar = isLast ? '└' : '├';\n const treePrefix = `${prefix}${formatDimText(treeChar)}─ `;\n // Root's direct children don't have │ prefix, other nodes do\n const isRootChild = prefix === '';\n // Check if prefix already contains │ (strip ANSI codes for comparison)\n const prefixWithoutAnsi = stripAnsi(prefix);\n const prefixHasVerticalBar = prefixWithoutAnsi.includes('│');\n if (isRootChild) {\n lines.push(`${treePrefix}${statusGlyphColored} ${nodeLabel}`);\n } else if (prefixHasVerticalBar) {\n // Prefix already has │, so just use treePrefix directly\n lines.push(`${treePrefix}${statusGlyphColored} ${nodeLabel}`);\n } else {\n lines.push(`${formatDimText('│')} ${treePrefix}${statusGlyphColored} ${nodeLabel}`);\n }\n }\n\n // Render children if present\n if (node.children && node.children.length > 0) {\n // For root node, children start with no prefix (they'll add their own tree characters)\n // For other nodes, calculate child prefix based on whether this is last\n const childPrefix = isRoot ? '' : isLast ? `${prefix} ` : `${prefix}${formatDimText('│')} `;\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n if (!child) continue;\n const isLastChild = i === node.children.length - 1;\n const childLines = renderSchemaVerificationTree(child, flags, {\n isLast: isLastChild,\n prefix: childPrefix,\n useColor,\n formatDimText,\n isRoot: false,\n });\n lines.push(...childLines);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats human-readable output for database schema verification.\n */\nexport function formatSchemaVerifyOutput(\n result: VerifyDatabaseSchemaResult,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatRed = createColorFormatter(useColor, red);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Render verification tree first\n const treeLines = renderSchemaVerificationTree(result.schema.root, flags, {\n isLast: true,\n prefix: '',\n useColor,\n formatDimText,\n isRoot: true,\n });\n // Apply prefix (for timestamps) to each tree line\n const prefixedTreeLines = treeLines.map((line) => `${prefix}${line}`);\n lines.push(...prefixedTreeLines);\n\n // Add counts and timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n lines.push(\n `${prefix}${formatDimText(` pass=${result.schema.counts.pass} warn=${result.schema.counts.warn} fail=${result.schema.counts.fail}`)}`,\n );\n }\n\n // Blank line before summary\n lines.push('');\n\n // Summary line at the end: summary with status glyph\n if (result.ok) {\n lines.push(`${prefix}${formatGreen('✔')} ${result.summary}`);\n } else {\n const codeText = result.code ? ` (${result.code})` : '';\n lines.push(`${prefix}${formatRed('✖')} ${result.summary}${codeText}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database schema verification.\n */\nexport function formatSchemaVerifyJson(result: VerifyDatabaseSchemaResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n// ============================================================================\n// Sign Output Formatters\n// ============================================================================\n\n/**\n * Formats human-readable output for database sign.\n */\nexport function formatSignOutput(result: SignDatabaseResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n // Main success message in white (not dimmed)\n lines.push(`${prefix}${formatGreen('✔')} Database signed`);\n\n // Show from -> to hashes with clear labels\n const previousHash = result.marker.previous?.coreHash ?? 'none';\n const currentHash = result.contract.coreHash;\n\n lines.push(`${prefix}${formatDimText(` from: ${previousHash}`)}`);\n lines.push(`${prefix}${formatDimText(` to: ${currentHash}`)}`);\n\n if (isVerbose(flags, 1)) {\n if (result.contract.profileHash) {\n lines.push(`${prefix}${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n if (result.marker.previous?.profileHash) {\n lines.push(\n `${prefix}${formatDimText(` previous profileHash: ${result.marker.previous.profileHash}`)}`,\n );\n }\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database sign.\n */\nexport function formatSignJson(result: SignDatabaseResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n// ============================================================================\n// DB Init Output Formatters\n// ============================================================================\n\n/**\n * Result type for db init command.\n */\nexport interface DbInitResult {\n readonly ok: boolean;\n readonly mode: 'plan' | 'apply';\n readonly plan?: {\n readonly targetId: string;\n readonly destination: {\n readonly coreHash: string;\n readonly profileHash?: string;\n };\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n };\n readonly execution?: {\n readonly operationsPlanned: number;\n readonly operationsExecuted: number;\n };\n readonly marker?: {\n readonly coreHash: string;\n readonly profileHash?: string;\n };\n readonly summary: string;\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for db init plan mode.\n */\nexport function formatDbInitPlanOutput(result: DbInitResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Plan summary\n const operationCount = result.plan?.operations.length ?? 0;\n lines.push(`${prefix}${formatGreen('✔')} Planned ${operationCount} operation(s)`);\n\n // Show operations tree\n if (result.plan?.operations && result.plan.operations.length > 0) {\n lines.push(`${prefix}${formatDimText('│')}`);\n for (let i = 0; i < result.plan.operations.length; i++) {\n const op = result.plan.operations[i];\n if (!op) continue;\n const isLast = i === result.plan.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const opClass = formatDimText(`[${op.operationClass}]`);\n lines.push(`${prefix}${formatDimText(treeChar)}─ ${op.label} ${opClass}`);\n }\n }\n\n // Destination hash\n if (result.plan?.destination) {\n lines.push(`${prefix}`);\n lines.push(\n `${prefix}${formatDimText(`Destination hash: ${result.plan.destination.coreHash}`)}`,\n );\n }\n\n // Timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix}${formatDimText(`Total time: ${result.timings.total}ms`)}`);\n }\n\n // Note about dry run\n lines.push(`${prefix}`);\n lines.push(`${prefix}${formatDimText('This is a dry run. No changes were applied.')}`);\n lines.push(`${prefix}${formatDimText('Run without --plan to apply changes.')}`);\n\n return lines.join('\\n');\n}\n\n/**\n * Formats human-readable output for db init apply mode.\n */\nexport function formatDbInitApplyOutput(result: DbInitResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n // Success summary\n const executed = result.execution?.operationsExecuted ?? 0;\n lines.push(`${prefix}${formatGreen('✔')} Applied ${executed} operation(s)`);\n\n // Marker info\n if (result.marker) {\n lines.push(`${prefix}${formatDimText(` Marker written: ${result.marker.coreHash}`)}`);\n if (result.marker.profileHash) {\n lines.push(`${prefix}${formatDimText(` Profile hash: ${result.marker.profileHash}`)}`);\n }\n }\n\n // Timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for db init command.\n */\nexport function formatDbInitJson(result: DbInitResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n// ============================================================================\n// Styled Output Formatters\n// ============================================================================\n\n/**\n * Fixed width for left column in help output.\n */\nconst LEFT_COLUMN_WIDTH = 20;\n\n/**\n * Minimum width for right column wrapping in help output.\n */\nconst RIGHT_COLUMN_MIN_WIDTH = 40;\n\n/**\n * Maximum width for right column wrapping in help output (when terminal is wide enough).\n */\nconst RIGHT_COLUMN_MAX_WIDTH = 90;\n\n/**\n * Gets the terminal width, or returns a default if not available.\n */\nfunction getTerminalWidth(): number {\n // process.stdout.columns may be undefined in non-TTY environments\n const terminalWidth = process.stdout.columns;\n // Default to 80 if terminal width is not available, but allow override via env var\n const defaultWidth = Number.parseInt(process.env['CLI_WIDTH'] || '80', 10);\n return terminalWidth || defaultWidth;\n}\n\n/**\n * Calculates the available width for the right column based on terminal width.\n * Format: \"│ \" (2) + left column (20) + \" \" (2) + right column = total\n * So: right column = terminal width - 2 - 20 - 2 = terminal width - 24\n */\nfunction calculateRightColumnWidth(): number {\n const terminalWidth = getTerminalWidth();\n const availableWidth = terminalWidth - 2 - LEFT_COLUMN_WIDTH - 2; // Subtract separators and left column\n // Ensure minimum width, but don't exceed maximum\n return Math.max(RIGHT_COLUMN_MIN_WIDTH, Math.min(availableWidth, RIGHT_COLUMN_MAX_WIDTH));\n}\n\n/**\n * Creates an arrow segment badge with green background and white text.\n * Body: green background with white \"prisma-next\" text\n * Tip: dark grey arrow pointing right (Powerline separator)\n */\nfunction createPrismaNextBadge(useColor: boolean): string {\n if (!useColor) {\n return 'prisma-next';\n }\n // Body: green background with white text\n const text = ' prisma-next ';\n const body = bgGreen(bold(text));\n\n // Use Powerline separator (U+E0B0) which creates the arrow transition effect\n const separator = '\\u{E0B0}';\n const tip = green(separator); // Dark grey arrow tip\n\n return `${body}${tip}`;\n}\n\n/**\n * Creates a padding function.\n */\nfunction createPadFunction(): (s: string, w: number) => string {\n return (s: string, w: number) => s + ' '.repeat(Math.max(0, w - s.length));\n}\n\n/**\n * Formats a header line: brand + operation + intent\n */\nfunction formatHeaderLine(options: {\n readonly brand: string;\n readonly operation: string;\n readonly intent: string;\n}): string {\n if (options.operation) {\n return `${options.brand} ${options.operation} → ${options.intent}`;\n }\n return `${options.brand} ${options.intent}`;\n}\n\n/**\n * Formats a \"Read more\" URL line.\n * The \"Read more\" label is in default color (not cyan), and the URL is blue.\n */\nfunction formatReadMoreLine(options: {\n readonly url: string;\n readonly maxLabelWidth: number;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n}): string {\n const pad = createPadFunction();\n const labelPadded = pad('Read more', options.maxLabelWidth);\n // Label is default color (not cyan)\n const valueColored = options.useColor ? blue(options.url) : options.url;\n return `${options.formatDimText('│')} ${labelPadded} ${valueColored}`;\n}\n\n/**\n * Pads text to a fixed width, accounting for ANSI escape codes.\n * Uses string-width to measure the actual display width.\n */\nfunction padToFixedWidth(text: string, width: number): string {\n const actualWidth = stringWidth(text);\n const padding = Math.max(0, width - actualWidth);\n return text + ' '.repeat(padding);\n}\n\n/**\n * Wraps text to fit within a specified width using wrap-ansi.\n * Preserves ANSI escape codes and breaks at word boundaries.\n */\nfunction wrapTextAnsi(text: string, width: number): string[] {\n const wrapped = wrapAnsi(text, width, { hard: false, trim: true });\n return wrapped.split('\\n');\n}\n\n/**\n * Formats a default value as \"default: <value>\" with dimming.\n */\nfunction formatDefaultValue(value: unknown, useColor: boolean): string {\n const valueStr = String(value);\n const defaultText = `default: ${valueStr}`;\n return useColor ? dim(defaultText) : defaultText;\n}\n\n/**\n * Renders a command tree structure.\n * Handles both single-level (subcommands of a command) and multi-level (top-level commands with subcommands) trees.\n */\nfunction renderCommandTree(options: {\n readonly commands: readonly Command[];\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly hasItemsAfter: boolean;\n readonly continuationPrefix?: string;\n}): string[] {\n const { commands, useColor, formatDimText, hasItemsAfter, continuationPrefix } = options;\n const lines: string[] = [];\n\n if (commands.length === 0) {\n return lines;\n }\n\n // Format each command\n for (let i = 0; i < commands.length; i++) {\n const cmd = commands[i];\n if (!cmd) continue;\n\n const subcommands = cmd.commands.filter((subcmd) => !subcmd.name().startsWith('_'));\n const isLastCommand = i === commands.length - 1;\n\n if (subcommands.length > 0) {\n // Command with subcommands - show command name, then tree-structured subcommands\n const prefix = isLastCommand && !hasItemsAfter ? formatDimText('└') : formatDimText('├');\n // For top-level command, pad name to fixed width (accounting for \"│ ├─ \" = 5 chars)\n const treePrefix = `${prefix}─ `;\n const treePrefixWidth = stringWidth(stripAnsi(treePrefix));\n const remainingWidth = LEFT_COLUMN_WIDTH - treePrefixWidth;\n const commandNamePadded = padToFixedWidth(cmd.name(), remainingWidth);\n const commandNameColored = useColor ? cyan(commandNamePadded) : commandNamePadded;\n lines.push(`${formatDimText('│')} ${treePrefix}${commandNameColored}`);\n\n for (let j = 0; j < subcommands.length; j++) {\n const subcmd = subcommands[j];\n if (!subcmd) continue;\n\n const isLastSubcommand = j === subcommands.length - 1;\n const shortDescription = subcmd.description() || '';\n\n // Use tree characters: └─ for last subcommand, ├─ for others\n const treeChar = isLastSubcommand ? '└' : '├';\n const continuation =\n continuationPrefix ??\n (isLastCommand && isLastSubcommand && !hasItemsAfter ? ' ' : formatDimText('│'));\n // For subcommands, account for \"│ │ └─ \" = 7 chars (or \"│ └─ \" = 6 chars if continuation is space)\n const continuationStr = continuation === ' ' ? ' ' : continuation;\n const subTreePrefix = `${continuationStr} ${formatDimText(treeChar)}─ `;\n const subTreePrefixWidth = stringWidth(stripAnsi(subTreePrefix));\n const subRemainingWidth = LEFT_COLUMN_WIDTH - subTreePrefixWidth;\n const subcommandNamePadded = padToFixedWidth(subcmd.name(), subRemainingWidth);\n const subcommandNameColored = useColor ? cyan(subcommandNamePadded) : subcommandNamePadded;\n lines.push(\n `${formatDimText('│')} ${subTreePrefix}${subcommandNameColored} ${shortDescription}`,\n );\n }\n } else {\n // Standalone command - show command name and description on same line\n const prefix = isLastCommand && !hasItemsAfter ? formatDimText('└') : formatDimText('├');\n const treePrefix = `${prefix}─ `;\n const treePrefixWidth = stringWidth(stripAnsi(treePrefix));\n const remainingWidth = LEFT_COLUMN_WIDTH - treePrefixWidth;\n const commandNamePadded = padToFixedWidth(cmd.name(), remainingWidth);\n const commandNameColored = useColor ? cyan(commandNamePadded) : commandNamePadded;\n const shortDescription = cmd.description() || '';\n lines.push(`${formatDimText('│')} ${treePrefix}${commandNameColored} ${shortDescription}`);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats multiline description with \"Prisma Next\" in green.\n * Wraps at the same right-hand boundary as the right column.\n * The right edge is defined by: left column (20) + gap (2) + right column (90) = 112 characters total.\n * Since the description line starts with \"│ \" (2 chars), the text wraps at 112 - 2 = 110 characters.\n */\nfunction formatMultilineDescription(options: {\n readonly descriptionLines: readonly string[];\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n}): string[] {\n const lines: string[] = [];\n const formatGreen = (text: string) => (options.useColor ? green(text) : text);\n\n // Calculate wrap width to align with right edge of right column\n // Format: \"│ \" (2) + left column (20) + \" \" (2) + right column = total\n // Description line has \"│ \" prefix (2 chars), so text wraps at total - 2\n const rightColumnWidth = calculateRightColumnWidth();\n const totalWidth = 2 + LEFT_COLUMN_WIDTH + 2 + rightColumnWidth;\n const wrapWidth = totalWidth - 2; // Subtract \"│ \" prefix\n\n for (const descLine of options.descriptionLines) {\n // Replace \"Prisma Next\" with green version if present\n const formattedLine = descLine.replace(/Prisma Next/g, (match) => formatGreen(match));\n\n // Wrap the line at the same right edge as the right column\n const wrappedLines = wrapTextAnsi(formattedLine, wrapWidth);\n for (const wrappedLine of wrappedLines) {\n lines.push(`${options.formatDimText('│')} ${wrappedLine}`);\n }\n }\n return lines;\n}\n\n/**\n * Formats the header in the new experimental visual style.\n * This header appears at the start of command output, showing the operation,\n * intent, documentation link, and parameters.\n */\nexport function formatStyledHeader(options: {\n readonly command: string;\n readonly description: string;\n readonly url?: string;\n readonly details: ReadonlyArray<{ readonly label: string; readonly value: string }>;\n readonly flags: GlobalFlags;\n}): string {\n const lines: string[] = [];\n const useColor = options.flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Header: arrow + operation badge + intent\n const brand = createPrismaNextBadge(useColor);\n // Use full command path (e.g., \"contract emit\" not just \"emit\")\n const operation = useColor ? bold(options.command) : options.command;\n const intent = formatDimText(options.description);\n lines.push(formatHeaderLine({ brand, operation, intent }));\n lines.push(formatDimText('│')); // Vertical line separator between command and params\n\n // Format details using fixed left column width (same style as help text options)\n for (const detail of options.details) {\n // Add colon to label, then pad to fixed width using padToFixedWidth for ANSI-aware padding\n const labelWithColon = `${detail.label}:`;\n const labelPadded = padToFixedWidth(labelWithColon, LEFT_COLUMN_WIDTH);\n const labelColored = useColor ? cyan(labelPadded) : labelPadded;\n lines.push(`${formatDimText('│')} ${labelColored} ${detail.value}`);\n }\n\n // Add \"Read more\" URL if present (same style as help text)\n if (options.url) {\n lines.push(formatDimText('│')); // Separator line before \"Read more\"\n lines.push(\n formatReadMoreLine({\n url: options.url,\n maxLabelWidth: LEFT_COLUMN_WIDTH,\n useColor,\n formatDimText,\n }),\n );\n }\n\n lines.push(formatDimText('└'));\n\n return `${lines.join('\\n')}\\n`;\n}\n\n/**\n * Formats a success message in the styled output format.\n */\nexport function formatSuccessMessage(flags: GlobalFlags): string {\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n return `${formatGreen('✔')} Success`;\n}\n\n// ============================================================================\n// Help Output Formatters\n// ============================================================================\n\n/**\n * Maps command paths to their documentation URLs.\n */\nfunction getCommandDocsUrl(commandPath: string): string | undefined {\n const docsMap: Record<string, string> = {\n 'contract emit': 'https://pris.ly/contract-emit',\n 'db verify': 'https://pris.ly/db-verify',\n };\n return docsMap[commandPath];\n}\n\n/**\n * Builds the full command path from a command and its parents.\n */\nfunction buildCommandPath(command: Command): string {\n const parts: string[] = [];\n let current: Command | undefined = command;\n while (current && current.name() !== 'prisma-next') {\n parts.unshift(current.name());\n current = current.parent ?? undefined;\n }\n return parts.join(' ');\n}\n\n/**\n * Formats help output for a command using the styled format.\n */\nexport function formatCommandHelp(options: {\n readonly command: Command;\n readonly flags: GlobalFlags;\n}): string {\n const { command, flags } = options;\n const lines: string[] = [];\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Build full command path (e.g., \"db verify\")\n const commandPath = buildCommandPath(command);\n const shortDescription = command.description() || '';\n const longDescription = getLongDescription(command);\n\n // Header: \"prisma-next <full-command-path> <short-description>\"\n const brand = createPrismaNextBadge(useColor);\n const operation = useColor ? bold(commandPath) : commandPath;\n const intent = formatDimText(shortDescription);\n lines.push(formatHeaderLine({ brand, operation, intent }));\n lines.push(formatDimText('│')); // Vertical line separator between command and params\n\n // Extract options and format them\n const optionsList = command.options.map((opt) => {\n const flags = opt.flags;\n const description = opt.description || '';\n // Commander.js stores default value in defaultValue property\n const defaultValue = (opt as { defaultValue?: unknown }).defaultValue;\n return { flags, description, defaultValue };\n });\n\n // Extract subcommands if any\n const subcommands = command.commands.filter((cmd) => !cmd.name().startsWith('_'));\n\n // Format subcommands as a tree if present\n if (subcommands.length > 0) {\n const hasItemsAfter = optionsList.length > 0;\n const treeLines = renderCommandTree({\n commands: subcommands,\n useColor,\n formatDimText,\n hasItemsAfter,\n });\n lines.push(...treeLines);\n }\n\n // Add separator between subcommands and options if both exist\n if (subcommands.length > 0 && optionsList.length > 0) {\n lines.push(formatDimText('│'));\n }\n\n // Format options with fixed width, wrapping, and default values\n if (optionsList.length > 0) {\n for (const opt of optionsList) {\n // Format flag with fixed 30-char width\n const flagsPadded = padToFixedWidth(opt.flags, LEFT_COLUMN_WIDTH);\n let flagsColored = flagsPadded;\n if (useColor) {\n // Color placeholders in magenta, then wrap in cyan\n flagsColored = flagsPadded.replace(/(<[^>]+>)/g, (match: string) => magenta(match));\n flagsColored = cyan(flagsColored);\n }\n\n // Wrap description based on terminal width\n const rightColumnWidth = calculateRightColumnWidth();\n const wrappedDescription = wrapTextAnsi(opt.description, rightColumnWidth);\n\n // First line: flag + first line of description\n lines.push(`${formatDimText('│')} ${flagsColored} ${wrappedDescription[0] || ''}`);\n\n // Continuation lines: empty label (30 spaces) + wrapped lines\n for (let i = 1; i < wrappedDescription.length; i++) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${wrappedDescription[i] || ''}`);\n }\n\n // Default value line (if present)\n if (opt.defaultValue !== undefined) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n const defaultText = formatDefaultValue(opt.defaultValue, useColor);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${defaultText}`);\n }\n }\n }\n\n // Add docs URL if available (with separator line before it)\n const docsUrl = getCommandDocsUrl(commandPath);\n if (docsUrl) {\n lines.push(formatDimText('│')); // Separator line between params and docs\n lines.push(\n formatReadMoreLine({\n url: docsUrl,\n maxLabelWidth: LEFT_COLUMN_WIDTH,\n useColor,\n formatDimText,\n }),\n );\n }\n\n // Multi-line description (if present) - shown after all other content\n if (longDescription) {\n lines.push(formatDimText('│'));\n const descriptionLines = longDescription.split('\\n').filter((line) => line.trim().length > 0);\n lines.push(...formatMultilineDescription({ descriptionLines, useColor, formatDimText }));\n }\n\n lines.push(formatDimText('└'));\n\n return `${lines.join('\\n')}\\n`;\n}\n\n/**\n * Formats help output for the root program using the styled format.\n */\nexport function formatRootHelp(options: {\n readonly program: Command;\n readonly flags: GlobalFlags;\n}): string {\n const { program, flags } = options;\n const lines: string[] = [];\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Header: \"prisma-next → Manage your data layer\"\n const brand = createPrismaNextBadge(useColor);\n const shortDescription = 'Manage your data layer';\n const intent = formatDimText(shortDescription);\n lines.push(formatHeaderLine({ brand, operation: '', intent }));\n lines.push(formatDimText('│')); // Vertical line separator after header\n\n // Extract top-level commands (exclude hidden commands starting with '_' and the 'help' command)\n const topLevelCommands = program.commands.filter(\n (cmd) => !cmd.name().startsWith('_') && cmd.name() !== 'help',\n );\n\n // Extract global options (needed to determine if last command)\n const globalOptions = program.options.map((opt) => {\n const flags = opt.flags;\n const description = opt.description || '';\n // Commander.js stores default value in defaultValue property\n const defaultValue = (opt as { defaultValue?: unknown }).defaultValue;\n return { flags, description, defaultValue };\n });\n\n // Build command tree\n if (topLevelCommands.length > 0) {\n const hasItemsAfter = globalOptions.length > 0;\n const treeLines = renderCommandTree({\n commands: topLevelCommands,\n useColor,\n formatDimText,\n hasItemsAfter,\n });\n lines.push(...treeLines);\n }\n\n // Add separator between commands and options if both exist\n if (topLevelCommands.length > 0 && globalOptions.length > 0) {\n lines.push(formatDimText('│'));\n }\n\n // Format global options with fixed width, wrapping, and default values\n if (globalOptions.length > 0) {\n for (const opt of globalOptions) {\n // Format flag with fixed 30-char width\n const flagsPadded = padToFixedWidth(opt.flags, LEFT_COLUMN_WIDTH);\n let flagsColored = flagsPadded;\n if (useColor) {\n // Color placeholders in magenta, then wrap in cyan\n flagsColored = flagsPadded.replace(/(<[^>]+>)/g, (match: string) => magenta(match));\n flagsColored = cyan(flagsColored);\n }\n\n // Wrap description based on terminal width\n const rightColumnWidth = calculateRightColumnWidth();\n const wrappedDescription = wrapTextAnsi(opt.description, rightColumnWidth);\n\n // First line: flag + first line of description\n lines.push(`${formatDimText('│')} ${flagsColored} ${wrappedDescription[0] || ''}`);\n\n // Continuation lines: empty label (30 spaces) + wrapped lines\n for (let i = 1; i < wrappedDescription.length; i++) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${wrappedDescription[i] || ''}`);\n }\n\n // Default value line (if present)\n if (opt.defaultValue !== undefined) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n const defaultText = formatDefaultValue(opt.defaultValue, useColor);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${defaultText}`);\n }\n }\n }\n\n // Multi-line description (white, not dimmed, with \"Prisma Next\" in green) - shown at bottom\n const formatGreen = (text: string) => (useColor ? green(text) : text);\n const descriptionLines = [\n `Use ${formatGreen('Prisma Next')} to define your data layer as a contract. Sign your database and application with the same contract to guarantee compatibility. Plan and apply migrations to safely evolve your schema.`,\n ];\n if (descriptionLines.length > 0) {\n lines.push(formatDimText('│')); // Separator line before description\n lines.push(...formatMultilineDescription({ descriptionLines, useColor, formatDimText }));\n }\n\n lines.push(formatDimText('└'));\n\n return `${lines.join('\\n')}\\n`;\n}\n","import ora from 'ora';\nimport type { ControlProgressEvent, OnControlProgress } from '../control-api/types';\nimport type { GlobalFlags } from './global-flags';\n\n/**\n * Options for creating a progress adapter.\n */\ninterface ProgressAdapterOptions {\n /**\n * Global flags that control progress output behavior (quiet, json, color).\n */\n readonly flags: GlobalFlags;\n}\n\n/**\n * State for tracking active spans in the progress adapter.\n */\ninterface SpanState {\n readonly spinner: ReturnType<typeof ora>;\n readonly startTime: number;\n}\n\n/**\n * Creates a progress adapter that converts control-api progress events\n * into CLI spinner/progress output.\n *\n * The adapter:\n * - Starts/succeeds spinners for top-level span boundaries\n * - Prints per-operation lines for nested spans (e.g., migration operations under 'apply')\n * - Respects quiet/json/non-TTY flags (no-op in those cases)\n *\n * @param options - Progress adapter configuration\n * @returns An onProgress callback compatible with control-api operations\n */\nexport function createProgressAdapter(options: ProgressAdapterOptions): OnControlProgress {\n const { flags } = options;\n\n // Skip progress if quiet, JSON output, or non-TTY\n const shouldShowProgress = !flags.quiet && flags.json !== 'object' && process.stdout.isTTY;\n\n if (!shouldShowProgress) {\n // Return a no-op callback\n return () => {\n // No-op\n };\n }\n\n // Track active spans by spanId\n const activeSpans = new Map<string, SpanState>();\n\n return (event: ControlProgressEvent) => {\n if (event.kind === 'spanStart') {\n // Nested spans (with parentSpanId) are printed as lines, not spinners\n if (event.parentSpanId) {\n console.log(` → ${event.label}...`);\n return;\n }\n\n // Top-level spans get a spinner\n const spinner = ora({\n text: event.label,\n color: flags.color !== false ? 'cyan' : false,\n }).start();\n\n activeSpans.set(event.spanId, {\n spinner,\n startTime: Date.now(),\n });\n } else if (event.kind === 'spanEnd') {\n // Complete the spinner for this span (only top-level spans have spinners)\n const spanState = activeSpans.get(event.spanId);\n if (spanState) {\n const elapsed = Date.now() - spanState.startTime;\n if (event.outcome === 'error') {\n spanState.spinner.fail(`${spanState.spinner.text} (failed)`);\n } else if (event.outcome === 'skipped') {\n spanState.spinner.info(`${spanState.spinner.text} (skipped)`);\n } else {\n spanState.spinner.succeed(`${spanState.spinner.text} (${elapsed}ms)`);\n }\n activeSpans.delete(event.spanId);\n }\n // Nested span ends are no-ops (could log completion if needed)\n }\n };\n}\n","import type { Result } from '@prisma-next/utils/result';\nimport type { CliStructuredError } from './cli-errors';\nimport type { GlobalFlags } from './global-flags';\nimport { formatErrorJson, formatErrorOutput } from './output';\n\n/**\n * Processes a CLI command result, handling both success and error cases.\n * Formats output appropriately and returns the exit code.\n * Never throws - returns exit code for commands to use with process.exit().\n *\n * @param result - The result from a CLI command\n * @param flags - Global flags for output formatting\n * @param onSuccess - Optional callback for successful results (for custom success output)\n * @returns The exit code that should be used (0 for success, non-zero for errors)\n */\nexport function handleResult<T>(\n result: Result<T, CliStructuredError>,\n flags: GlobalFlags,\n onSuccess?: (value: T) => void,\n): number {\n if (result.ok) {\n // Success case\n if (onSuccess) {\n onSuccess(result.value);\n }\n return 0;\n }\n\n // Error case - convert to CLI envelope\n const envelope = result.failure.toEnvelope();\n\n // Output error based on flags\n if (flags.json) {\n // JSON error to stderr\n console.error(formatErrorJson(envelope));\n } else {\n // Human-readable error to stderr\n console.error(formatErrorOutput(envelope, flags));\n }\n\n // Infer exit code from error domain: CLI errors = 2, RTM errors = 1\n const exitCode = result.failure.domain === 'CLI' ? 2 : 1;\n return exitCode;\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, relative, resolve } from 'node:path';\nimport { errorContractConfigMissing } from '@prisma-next/core-control-plane/errors';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type { EmitContractSource, EmitFailure } from '../control-api/types';\nimport { CliStructuredError, errorRuntime, errorUnexpected } from '../utils/cli-errors';\nimport { setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n type EmitContractResult,\n formatCommandHelp,\n formatEmitJson,\n formatEmitOutput,\n formatStyledHeader,\n formatSuccessMessage,\n} from '../utils/output';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\n\ninterface ContractEmitOptions {\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Maps an EmitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapEmitFailure(failure: EmitFailure): CliStructuredError {\n if (failure.code === 'CONTRACT_SOURCE_INVALID') {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Contract source is invalid',\n fix: 'Check your contract source configuration in prisma-next.config.ts',\n });\n }\n\n if (failure.code === 'EMIT_FAILED') {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Failed to emit contract',\n fix: 'Check your contract configuration and ensure the source is valid',\n });\n }\n\n // Exhaustive check - TypeScript will error if a new code is added but not handled\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled EmitFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the contract emit command and returns a structured Result.\n */\nasync function executeContractEmitCommand(\n options: ContractEmitOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<EmitContractResult, CliStructuredError>> {\n // Load config\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(options.config);\n } catch (error) {\n // Convert thrown CliStructuredError to Result\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to load config',\n }),\n );\n }\n\n // Resolve contract from config\n if (!config.contract) {\n return notOk(\n errorContractConfigMissing({\n why: 'Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ..., types: ... }',\n }),\n );\n }\n\n // Contract config is already normalized by defineConfig() with defaults applied\n const contractConfig = config.contract;\n\n // Resolve artifact paths from config (already normalized by defineConfig() with defaults)\n if (!contractConfig.output || !contractConfig.types) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config must have output and types paths. This should not happen if defineConfig() was used.',\n }),\n );\n }\n const outputJsonPath = resolve(contractConfig.output);\n const outputDtsPath = resolve(contractConfig.types);\n\n // Output header (only for human-readable output)\n if (flags.json !== 'object' && !flags.quiet) {\n // Normalize config path for display (match contract path format - no ./ prefix)\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n // Convert absolute paths to relative paths for display\n const contractPath = relative(process.cwd(), outputJsonPath);\n const typesPath = relative(process.cwd(), outputDtsPath);\n const header = formatStyledHeader({\n command: 'contract emit',\n description: 'Write your contract to JSON and sign it',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'types', value: typesPath },\n ],\n flags,\n });\n console.log(header);\n }\n\n // Create control client (no driver needed for emit)\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n // Convert user config source to discriminated union\n // Type assertion is safe: we check typeof to determine if it's a function\n const source: EmitContractSource =\n typeof contractConfig.source === 'function'\n ? { kind: 'loader', load: contractConfig.source as () => unknown | Promise<unknown> }\n : { kind: 'value', value: contractConfig.source };\n\n // Call emit with progress callback\n const result = await client.emit({\n contractConfig: {\n source,\n output: outputJsonPath,\n types: outputDtsPath,\n },\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapEmitFailure(result.failure));\n }\n\n // Create directories if needed\n mkdirSync(dirname(outputJsonPath), { recursive: true });\n mkdirSync(dirname(outputDtsPath), { recursive: true });\n\n // Write the results to files\n writeFileSync(outputJsonPath, result.value.contractJson, 'utf-8');\n writeFileSync(outputDtsPath, result.value.contractDts, 'utf-8');\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n // Convert success result to CLI output format\n const emitResult: EmitContractResult = {\n coreHash: result.value.coreHash,\n profileHash: result.value.profileHash,\n outDir: dirname(outputJsonPath),\n files: {\n json: outputJsonPath,\n dts: outputDtsPath,\n },\n timings: { total: Date.now() - startTime },\n };\n\n return ok(emitResult);\n } catch (error) {\n // Use static type guard to work across module boundaries\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected('Unexpected error during contract emit', {\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createContractEmitCommand(): Command {\n const command = new Command('emit');\n setCommandDescriptions(\n command,\n 'Write your contract to JSON and sign it',\n 'Reads your contract source (TypeScript or Prisma schema) and emits contract.json and\\n' +\n 'contract.d.ts. The contract.json contains the canonical contract structure, and\\n' +\n 'contract.d.ts provides TypeScript types for type-safe query building.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object or ndjson)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n const result = await executeContractEmitCommand(options, flags, startTime);\n\n // Handle result - formats output and returns exit code\n const exitCode = handleResult(result, flags, (emitResult) => {\n // Output based on flags\n if (flags.json === 'object') {\n // JSON output to stdout\n console.log(formatEmitJson(emitResult));\n } else {\n // Human-readable output to stdout\n const output = formatEmitOutput(emitResult, flags);\n if (output) {\n console.log(output);\n }\n // Output success message\n if (!flags.quiet) {\n console.log(formatSuccessMessage(flags));\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type { DbInitFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorMigrationPlanningFailed,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n type DbInitResult,\n formatCommandHelp,\n formatDbInitApplyOutput,\n formatDbInitJson,\n formatDbInitPlanOutput,\n formatStyledHeader,\n} from '../utils/output';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\n\ninterface DbInitOptions {\n readonly db?: string;\n readonly config?: string;\n readonly plan?: boolean;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Maps a DbInitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapDbInitFailure(failure: DbInitFailure): CliStructuredError {\n if (failure.code === 'PLANNING_FAILED') {\n return errorMigrationPlanningFailed({ conflicts: failure.conflicts ?? [] });\n }\n\n if (failure.code === 'MARKER_ORIGIN_MISMATCH') {\n const mismatchParts: string[] = [];\n if (\n failure.marker?.coreHash !== failure.destination?.coreHash &&\n failure.marker?.coreHash &&\n failure.destination?.coreHash\n ) {\n mismatchParts.push(\n `coreHash (marker: ${failure.marker.coreHash}, destination: ${failure.destination.coreHash})`,\n );\n }\n if (\n failure.marker?.profileHash !== failure.destination?.profileHash &&\n failure.marker?.profileHash &&\n failure.destination?.profileHash\n ) {\n mismatchParts.push(\n `profileHash (marker: ${failure.marker.profileHash}, destination: ${failure.destination.profileHash})`,\n );\n }\n\n return errorRuntime(\n `Existing contract marker does not match plan destination.${mismatchParts.length > 0 ? ` Mismatch in ${mismatchParts.join(' and ')}.` : ''}`,\n {\n why: 'Database has an existing contract marker that does not match the target contract',\n fix: 'If bootstrapping, drop/reset the database then re-run `prisma-next db init`; otherwise reconcile schema/marker using your migration workflow',\n meta: {\n code: 'MARKER_ORIGIN_MISMATCH',\n ...(failure.marker?.coreHash ? { markerCoreHash: failure.marker.coreHash } : {}),\n ...(failure.destination?.coreHash\n ? { destinationCoreHash: failure.destination.coreHash }\n : {}),\n ...(failure.marker?.profileHash ? { markerProfileHash: failure.marker.profileHash } : {}),\n ...(failure.destination?.profileHash\n ? { destinationProfileHash: failure.destination.profileHash }\n : {}),\n },\n },\n );\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Fix the schema mismatch (db init is additive-only), or drop/reset the database and re-run `prisma-next db init`',\n meta: {\n code: 'RUNNER_FAILED',\n ...(failure.meta ?? {}),\n },\n });\n }\n\n // Exhaustive check - TypeScript will error if a new code is added but not handled\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled DbInitFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the db init command and returns a structured Result.\n */\nasync function executeDbInitCommand(\n options: DbInitOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<DbInitResult, CliStructuredError>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = config.contract?.output\n ? resolve(config.contract.output)\n : resolve('src/prisma/contract.json');\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: options.db });\n }\n if (options.plan) {\n details.push({ label: 'mode', value: 'plan (dry run)' });\n }\n const header = formatStyledHeader({\n command: 'db init',\n description: 'Bootstrap a database to match the current contract',\n url: 'https://pris.ly/db-init',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Load contract file\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db init (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db init' }));\n }\n\n // Check target supports migrations via the migrations capability\n if (!config.target.migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n // Call dbInit with connection and progress callback\n // Connection happens inside dbInit with a 'connect' progress span\n const result = await client.dbInit({\n contractIR: contractJson,\n mode: options.plan ? 'plan' : 'apply',\n connection: dbConnection,\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapDbInitFailure(result.failure));\n }\n\n // Convert success result to CLI output format\n const profileHash = result.value.marker?.profileHash;\n const dbInitResult: DbInitResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: config.target.targetId,\n destination: {\n coreHash: result.value.marker?.coreHash ?? '',\n ...(profileHash ? { profileHash } : {}),\n },\n operations: result.value.plan.operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n },\n ...(result.value.execution\n ? {\n execution: {\n operationsPlanned: result.value.execution.operationsPlanned,\n operationsExecuted: result.value.execution.operationsExecuted,\n },\n }\n : {}),\n ...(result.value.marker\n ? {\n marker: {\n coreHash: result.value.marker.coreHash,\n ...(result.value.marker.profileHash\n ? { profileHash: result.value.marker.profileHash }\n : {}),\n },\n }\n : {}),\n summary: result.value.summary,\n timings: { total: Date.now() - startTime },\n };\n\n return ok(dbInitResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n // Use static type guard to work across module boundaries\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db init: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbInitCommand(): Command {\n const command = new Command('init');\n setCommandDescriptions(\n command,\n 'Bootstrap a database to match the current contract and write the contract marker',\n 'Initializes a database to match your emitted contract using additive-only operations.\\n' +\n 'Creates any missing tables, columns, indexes, and constraints defined in your contract.\\n' +\n 'Leaves existing compatible structures in place, surfaces conflicts when destructive changes\\n' +\n 'would be required, and writes a contract marker to track the database state. Use --plan to\\n' +\n 'preview changes without applying.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--plan', 'Preview planned operations without applying', false)\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbInitOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db init',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbInitCommand(options, flags, startTime);\n\n const exitCode = handleResult(result, flags, (dbInitResult) => {\n if (flags.json === 'object') {\n console.log(formatDbInitJson(dbInitResult));\n } else {\n const output =\n dbInitResult.mode === 'plan'\n ? formatDbInitPlanOutput(dbInitResult, flags)\n : formatDbInitApplyOutput(dbInitResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n","import { relative, resolve } from 'node:path';\nimport type { CoreSchemaView } from '@prisma-next/core-control-plane/schema-view';\nimport type { IntrospectSchemaResult } from '@prisma-next/core-control-plane/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n CliStructuredError,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatIntrospectJson,\n formatIntrospectOutput,\n formatStyledHeader,\n} from '../utils/output';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\n\ninterface DbIntrospectOptions {\n readonly db?: string;\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\ninterface DbIntrospectCommandResult {\n readonly introspectResult: IntrospectSchemaResult<unknown>;\n readonly schemaView: CoreSchemaView | undefined;\n}\n\n/**\n * Executes the db introspect command and returns a structured Result.\n */\nasync function executeDbIntrospectCommand(\n options: DbIntrospectOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<DbIntrospectCommandResult, CliStructuredError>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n ];\n if (options.db) {\n // Mask password in URL for security\n const maskedUrl = options.db.replace(/:([^:@]+)@/, ':****@');\n details.push({ label: 'database', value: maskedUrl });\n } else if (config.db?.connection && typeof config.db.connection === 'string') {\n // Mask password in URL for security\n const maskedUrl = config.db.connection.replace(/:([^:@]+)@/, ':****@');\n details.push({ label: 'database', value: maskedUrl });\n }\n const header = formatStyledHeader({\n command: 'db introspect',\n description: 'Inspect the database schema',\n url: 'https://pris.ly/db-introspect',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db introspect (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db introspect' }));\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n // Introspect with connection and progress\n const schemaIR = await client.introspect({\n connection: dbConnection,\n onProgress,\n });\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n // Call toSchemaView to convert schema IR to CoreSchemaView for tree rendering\n const schemaView = client.toSchemaView(schemaIR);\n\n const totalTime = Date.now() - startTime;\n\n // Get masked connection URL for meta (only for string connections)\n const connectionForMeta =\n typeof dbConnection === 'string' ? dbConnection.replace(/:([^:@]+)@/, ':****@') : undefined;\n\n const introspectResult: IntrospectSchemaResult<unknown> = {\n ok: true,\n summary: 'Schema introspected successfully',\n target: {\n familyId: config.family.familyId,\n id: config.target.targetId,\n },\n schema: schemaIR,\n meta: {\n ...(configPath ? { configPath } : {}),\n ...(connectionForMeta ? { dbUrl: connectionForMeta } : {}),\n },\n timings: {\n total: totalTime,\n },\n };\n\n return ok({ introspectResult, schemaView });\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db introspect: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbIntrospectCommand(): Command {\n const command = new Command('introspect');\n setCommandDescriptions(\n command,\n 'Inspect the database schema',\n 'Reads the live database schema and displays it as a tree structure. This command\\n' +\n 'does not check the schema against your contract - it only shows what exists in\\n' +\n 'the database. Use `db verify` or `db schema-verify` to compare against your contract.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbIntrospectOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db introspect',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbIntrospectCommand(options, flags, startTime);\n\n // Handle result - formats output and returns exit code\n const exitCode = handleResult(result, flags, (value) => {\n const { introspectResult, schemaView } = value;\n if (flags.json === 'object') {\n console.log(formatIntrospectJson(introspectResult));\n } else {\n const output = formatIntrospectOutput(introspectResult, schemaView, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport type { VerifyDatabaseSchemaResult } from '@prisma-next/core-control-plane/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatStyledHeader,\n} from '../utils/output';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\n\ninterface DbSchemaVerifyOptions {\n readonly db?: string;\n readonly config?: string;\n readonly json?: string | boolean;\n readonly strict?: boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Executes the db schema-verify command and returns a structured Result.\n */\nasync function executeDbSchemaVerifyCommand(\n options: DbSchemaVerifyOptions,\n flags: GlobalFlags,\n): Promise<Result<VerifyDatabaseSchemaResult, CliStructuredError>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = config.contract?.output\n ? resolve(config.contract.output)\n : resolve('src/prisma/contract.json');\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: options.db });\n }\n const header = formatStyledHeader({\n command: 'db schema-verify',\n description: 'Check whether the database schema satisfies your contract',\n url: 'https://pris.ly/db-schema-verify',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Load contract file\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db schema-verify (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db schema-verify' }));\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n const schemaVerifyResult = await client.schemaVerify({\n contractIR: contractJson,\n strict: options.strict ?? false,\n connection: dbConnection,\n onProgress,\n });\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n return ok(schemaVerifyResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db schema-verify: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbSchemaVerifyCommand(): Command {\n const command = new Command('schema-verify');\n setCommandDescriptions(\n command,\n 'Check whether the database schema satisfies your contract',\n 'Verifies that your database schema satisfies the emitted contract. Compares table structures,\\n' +\n 'column types, constraints, and extensions. Reports any mismatches via a contract-shaped\\n' +\n 'verification tree. This is a read-only operation that does not modify the database.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('--strict', 'Strict mode: extra schema elements cause failures', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbSchemaVerifyOptions) => {\n const flags = parseGlobalFlags(options);\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db schema-verify',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbSchemaVerifyCommand(options, flags);\n\n // Handle result - formats output and returns exit code\n const exitCode = handleResult(result, flags, (schemaVerifyResult) => {\n if (flags.json === 'object') {\n console.log(formatSchemaVerifyJson(schemaVerifyResult));\n } else {\n const output = formatSchemaVerifyOutput(schemaVerifyResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n\n // For logical schema mismatches, check if verification passed\n // Infra errors already handled by handleResult (returns non-zero exit code)\n if (result.ok && !result.value.ok) {\n // Schema verification failed - exit with code 1\n process.exit(1);\n } else {\n // Success or infra error - use exit code from handleResult\n process.exit(exitCode);\n }\n });\n\n return command;\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport type {\n SignDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/core-control-plane/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatSignJson,\n formatSignOutput,\n formatStyledHeader,\n} from '../utils/output';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\n\ninterface DbSignOptions {\n readonly db?: string;\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Failure type for db sign command.\n * Either an infrastructure error (CliStructuredError) or a logical failure (schema verification failed).\n */\ntype DbSignFailure = CliStructuredError | VerifyDatabaseSchemaResult;\n\n/**\n * Executes the db sign command and returns a structured Result.\n * Success: SignDatabaseResult (sign happened)\n * Failure: CliStructuredError (infra error) or VerifyDatabaseSchemaResult (schema mismatch)\n */\nasync function executeDbSignCommand(\n options: DbSignOptions,\n flags: GlobalFlags,\n): Promise<Result<SignDatabaseResult, DbSignFailure>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = config.contract?.output\n ? resolve(config.contract.output)\n : resolve('src/prisma/contract.json');\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: options.db });\n }\n const header = formatStyledHeader({\n command: 'db sign',\n description: 'Sign the database with your contract so you can safely run queries',\n url: 'https://pris.ly/db-sign',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Load contract file\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db sign (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db sign' }));\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n // Step 1: Schema verification - connect here\n const schemaVerifyResult = await client.schemaVerify({\n contractIR: contractJson,\n strict: false,\n connection: dbConnection,\n onProgress,\n });\n\n // If schema verification failed, return as failure\n if (!schemaVerifyResult.ok) {\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n return notOk(schemaVerifyResult);\n }\n\n // Step 2: Sign (already connected from schemaVerify)\n const signResult = await client.sign({\n contractIR: contractJson,\n contractPath,\n configPath,\n onProgress,\n });\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n return ok(signResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db sign: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbSignCommand(): Command {\n const command = new Command('sign');\n setCommandDescriptions(\n command,\n 'Sign the database with your contract so you can safely run queries',\n 'Verifies that your database schema satisfies the emitted contract, and if so, writes or\\n' +\n 'updates the contract marker in the database. This command is idempotent and safe to run\\n' +\n 'in CI/deployment pipelines. The marker records that this database instance is aligned\\n' +\n 'with a specific contract version.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbSignOptions) => {\n const flags = parseGlobalFlags(options);\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db sign',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbSignCommand(options, flags);\n\n if (result.ok) {\n // Success - format sign output\n if (flags.json === 'object') {\n console.log(formatSignJson(result.value));\n } else {\n const output = formatSignOutput(result.value, flags);\n if (output) {\n console.log(output);\n }\n }\n process.exit(0);\n }\n\n // Failure - determine type and handle appropriately\n const failure = result.failure;\n\n if (failure instanceof CliStructuredError) {\n // Infrastructure error - use standard handler\n const exitCode = handleResult(result as Result<never, CliStructuredError>, flags);\n process.exit(exitCode);\n }\n\n // Schema verification failed - format and print schema verification output\n if (flags.json === 'object') {\n console.log(formatSchemaVerifyJson(failure));\n } else {\n const output = formatSchemaVerifyOutput(failure, flags);\n if (output) {\n console.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport type { VerifyDatabaseResult } from '@prisma-next/core-control-plane/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorHashMismatch,\n errorJsonFormatNotSupported,\n errorMarkerMissing,\n errorRuntime,\n errorTargetMismatch,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatStyledHeader,\n formatVerifyJson,\n formatVerifyOutput,\n} from '../utils/output';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\n\ninterface DbVerifyOptions {\n readonly db?: string;\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Maps a VerifyDatabaseResult failure to a CliStructuredError.\n */\nfunction mapVerifyFailure(verifyResult: VerifyDatabaseResult): CliStructuredError {\n if (!verifyResult.ok && verifyResult.code) {\n if (verifyResult.code === 'PN-RTM-3001') {\n return errorMarkerMissing();\n }\n if (verifyResult.code === 'PN-RTM-3002') {\n return errorHashMismatch({\n expected: verifyResult.contract.coreHash,\n ...(verifyResult.marker?.coreHash ? { actual: verifyResult.marker.coreHash } : {}),\n });\n }\n if (verifyResult.code === 'PN-RTM-3003') {\n return errorTargetMismatch(\n verifyResult.target.expected,\n verifyResult.target.actual ?? 'unknown',\n );\n }\n // Unknown code - fall through to runtime error\n }\n return errorRuntime(verifyResult.summary);\n}\n\n/**\n * Executes the db verify command and returns a structured Result.\n */\nasync function executeDbVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n): Promise<Result<VerifyDatabaseResult, CliStructuredError>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = config.contract?.output\n ? resolve(config.contract.output)\n : resolve('src/prisma/contract.json');\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: options.db });\n }\n const header = formatStyledHeader({\n command: 'db verify',\n description: 'Check whether the database has been signed with your contract',\n url: 'https://pris.ly/db-verify',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Load contract file\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db verify (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db verify' }));\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n const verifyResult = await client.verify({\n contractIR: contractJson,\n connection: dbConnection,\n onProgress,\n });\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n // If verification failed, map to CLI structured error\n if (!verifyResult.ok) {\n return notOk(mapVerifyFailure(verifyResult));\n }\n\n return ok(verifyResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db verify: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbVerifyCommand(): Command {\n const command = new Command('verify');\n setCommandDescriptions(\n command,\n 'Check whether the database has been signed with your contract',\n 'Verifies that your database schema matches the emitted contract. Checks table structures,\\n' +\n 'column types, constraints, and codec coverage. Reports any mismatches or missing codecs.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbVerifyOptions) => {\n const flags = parseGlobalFlags(options);\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db verify',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbVerifyCommand(options, flags);\n\n const exitCode = handleResult(result, flags, (verifyResult) => {\n if (flags.json === 'object') {\n console.log(formatVerifyJson(verifyResult));\n } else {\n const output = formatVerifyOutput(verifyResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n","import { Command } from 'commander';\nimport { createContractEmitCommand } from './commands/contract-emit';\nimport { createDbInitCommand } from './commands/db-init';\nimport { createDbIntrospectCommand } from './commands/db-introspect';\nimport { createDbSchemaVerifyCommand } from './commands/db-schema-verify';\nimport { createDbSignCommand } from './commands/db-sign';\nimport { createDbVerifyCommand } from './commands/db-verify';\nimport { setCommandDescriptions } from './utils/command-helpers';\nimport { parseGlobalFlags } from './utils/global-flags';\nimport { formatCommandHelp, formatRootHelp } from './utils/output';\n\nconst program = new Command();\n\nprogram.name('prisma-next').description('Prisma Next CLI').version('0.0.1');\n\n// Override version option description to match capitalization style\nconst versionOption = program.options.find((opt) => opt.flags.includes('--version'));\nif (versionOption) {\n versionOption.description = 'Output the version number';\n}\n\nprogram.configureOutput({\n writeErr: () => {\n // Suppress all default error output - we handle errors in exitOverride\n },\n writeOut: () => {\n // Suppress all default output - our custom formatters handle everything\n },\n});\n\n// Customize root help output to use our styled format\nconst rootHelpFormatter = (cmd: Command) => {\n const flags = parseGlobalFlags({});\n return formatRootHelp({ program: cmd, flags });\n};\n\nprogram.configureHelp({\n formatHelp: rootHelpFormatter,\n subcommandDescription: () => '',\n});\n\n// Override exit to handle unhandled errors (fail fast cases)\n// Commands handle structured errors themselves via process.exit()\nprogram.exitOverride((err) => {\n if (err) {\n // Help requests are not errors - allow Commander to output help and exit normally\n // Commander throws errors with codes like 'commander.help', 'commander.helpDisplayed', or 'outputHelp'\n const errorCode = (err as { code?: string }).code;\n const errorMessage = String(err.message ?? '');\n const errorName = err.name ?? '';\n\n // Check for unknown command errors first (before other checks)\n // Commander.js uses code 'commander.unknownCommand' or error message contains 'unknown command'\n const isUnknownCommandError =\n errorCode === 'commander.unknownCommand' ||\n errorCode === 'commander.unknownArgument' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('unknown command') || errorMessage.includes('unknown argument')));\n if (isUnknownCommandError) {\n const flags = parseGlobalFlags({});\n // Extract the command/subcommand name from the error message\n // Error message format: \"unknown command 'command-name'\"\n const match = errorMessage.match(/unknown command ['\"]([^'\"]+)['\"]/);\n const commandName = match ? match[1] : process.argv[3] || process.argv[2] || 'unknown';\n\n // Determine which command context we're in\n // Check if the first argument is a recognized parent command\n const firstArg = process.argv[2];\n const parentCommand = firstArg\n ? program.commands.find((cmd) => cmd.name() === firstArg)\n : undefined;\n\n if (parentCommand && commandName !== firstArg) {\n // Unrecognized subcommand - show parent command help\n // eslint-disable-next-line no-console\n console.error(`Unknown command: ${commandName}`);\n // eslint-disable-next-line no-console\n console.error('');\n const helpText = formatCommandHelp({ command: parentCommand, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n } else {\n // Unrecognized top-level command - show root help\n // eslint-disable-next-line no-console\n console.error(`Unknown command: ${commandName}`);\n // eslint-disable-next-line no-console\n console.error('');\n const helpText = formatRootHelp({ program, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n }\n process.exit(1);\n return;\n }\n const isHelpError =\n errorCode === 'commander.help' ||\n errorCode === 'commander.helpDisplayed' ||\n errorCode === 'outputHelp' ||\n errorMessage === '(outputHelp)' ||\n errorMessage.includes('outputHelp') ||\n (errorName === 'CommanderError' && errorMessage.includes('outputHelp'));\n if (isHelpError) {\n process.exit(0);\n return;\n }\n // Missing required arguments/subcommands - show help and exit with 0\n // Commander throws errors with code 'commander.missingArgument' or 'commander.missingMandatoryOptionValue'\n // or when a command with subcommands is called without a subcommand\n const isMissingArgumentError =\n errorCode === 'commander.missingArgument' ||\n errorCode === 'commander.missingMandatoryOptionValue' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('missing') || errorMessage.includes('required')));\n if (isMissingArgumentError) {\n // Help was already displayed by Commander.js, just exit with 0\n process.exit(0);\n return;\n }\n // Unhandled error - fail fast with exit code 1\n // eslint-disable-next-line no-console\n console.error(`Unhandled error: ${err.message}`);\n if (err.stack) {\n // eslint-disable-next-line no-console\n console.error(err.stack);\n }\n process.exit(1);\n }\n process.exit(0);\n});\n\n// Register contract subcommand\nconst contractCommand = new Command('contract');\nsetCommandDescriptions(\n contractCommand,\n 'Contract management commands',\n 'Define and emit your application data contract. The contract describes your schema as a\\n' +\n 'declarative data structure that can be signed and verified against your database.',\n);\ncontractCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add emit subcommand to contract\nconst contractEmitCommand = createContractEmitCommand();\ncontractCommand.addCommand(contractEmitCommand);\n\n// Register contract command\nprogram.addCommand(contractCommand);\n\n// Register db subcommand\nconst dbCommand = new Command('db');\nsetCommandDescriptions(\n dbCommand,\n 'Database management commands',\n 'Verify and sign your database with your contract. Ensure your database schema matches\\n' +\n 'your contract, and sign it to record the contract hash for future verification.',\n);\ndbCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add verify subcommand to db\nconst dbVerifyCommand = createDbVerifyCommand();\ndbCommand.addCommand(dbVerifyCommand);\n\n// Add init subcommand to db\nconst dbInitCommand = createDbInitCommand();\ndbCommand.addCommand(dbInitCommand);\n\n// Add introspect subcommand to db\nconst dbIntrospectCommand = createDbIntrospectCommand();\ndbCommand.addCommand(dbIntrospectCommand);\n\n// Add schema-verify subcommand to db\nconst dbSchemaVerifyCommand = createDbSchemaVerifyCommand();\ndbCommand.addCommand(dbSchemaVerifyCommand);\n\n// Add sign subcommand to db\nconst dbSignCommand = createDbSignCommand();\ndbCommand.addCommand(dbSignCommand);\n\n// Register db command\nprogram.addCommand(dbCommand);\n\n// Create help command\nconst helpCommand = new Command('help')\n .description('Show usage instructions')\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n process.exit(0);\n });\n\nprogram.addCommand(helpCommand);\n\n// Set help as the default action when no command is provided\nprogram.action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n process.exit(0);\n});\n\n// Check if a command was invoked with no arguments (just the command name)\n// or if an unrecognized command was provided\nconst args = process.argv.slice(2);\nif (args.length > 0) {\n const commandName = args[0];\n // Handle version option explicitly since we suppress default output\n if (commandName === '--version' || commandName === '-V') {\n // eslint-disable-next-line no-console\n console.log(program.version());\n process.exit(0);\n }\n // Skip command check for global options like --help, -h\n const isGlobalOption = commandName === '--help' || commandName === '-h';\n if (!isGlobalOption) {\n // Check if this is a recognized command\n const command = program.commands.find((cmd) => cmd.name() === commandName);\n\n if (!command) {\n // Unrecognized command - show error message and usage\n const flags = parseGlobalFlags({});\n // eslint-disable-next-line no-console\n console.error(`Unknown command: ${commandName}`);\n // eslint-disable-next-line no-console\n console.error('');\n const helpText = formatRootHelp({ program, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n process.exit(1);\n } else if (command.commands.length > 0 && args.length === 1) {\n // Parent command called with no subcommand - show help and exit with 0\n const flags = parseGlobalFlags({});\n const helpText = formatCommandHelp({ command, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n process.exit(0);\n }\n }\n}\n\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["loadConfig","loadConfigC12","plannerResult: MigrationPlannerResult","migrationPlan: MigrationPlan","runnerResult: MigrationRunnerResult","contractRaw: unknown","flags: {\n json?: 'object' | 'ndjson';\n quiet?: boolean;\n verbose?: number;\n timestamps?: boolean;\n color?: boolean;\n }","lines: string[]","formattedLabel: string","prefix","statusColor: (text: string) => string","labelColor: (text: string) => string","parts: string[]","current: Command | undefined","program","exhaustive: never","config: Awaited<ReturnType<typeof loadConfig>>","loadConfig","errorUnexpected","source: EmitContractSource","mismatchParts: string[]","exhaustive: never","loadConfig","details: Array<{ label: string; value: string }>","contractJsonContent: string","errorUnexpected","contractJson: Record<string, unknown>","exitCode","loadConfig","details: Array<{ label: string; value: string }>","errorUnexpected","exitCode","loadConfig","details: Array<{ label: string; value: string }>","contractJsonContent: string","errorUnexpected","contractJson: Record<string, unknown>","exitCode","loadConfig","details: Array<{ label: string; value: string }>","contractJsonContent: string","errorUnexpected","contractJson: Record<string, unknown>","loadConfig","details: Array<{ label: string; value: string }>","contractJsonContent: string","errorUnexpected","contractJson: Record<string, unknown>","exitCode"],"sources":["../src/config-loader.ts","../src/utils/framework-components.ts","../src/control-api/operations/db-init.ts","../src/control-api/client.ts","../src/utils/command-helpers.ts","../src/utils/global-flags.ts","../src/utils/output.ts","../src/utils/progress-adapter.ts","../src/utils/result-handler.ts","../src/commands/contract-emit.ts","../src/commands/db-init.ts","../src/commands/db-introspect.ts","../src/commands/db-schema-verify.ts","../src/commands/db-sign.ts","../src/commands/db-verify.ts","../src/cli.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path';\nimport type { PrismaNextConfig } from '@prisma-next/core-control-plane/config-types';\nimport { validateConfig } from '@prisma-next/core-control-plane/config-validation';\nimport { errorConfigFileNotFound, errorUnexpected } from '@prisma-next/core-control-plane/errors';\nimport { loadConfig as loadConfigC12 } from 'c12';\n\n/**\n * Loads the Prisma Next config from a TypeScript file.\n * Supports both default export and named export.\n * Uses c12 to automatically handle TypeScript compilation and config file discovery.\n *\n * @param configPath - Optional path to config file. Defaults to `./prisma-next.config.ts` in current directory.\n * @returns The loaded config object.\n * @throws Error if config file doesn't exist or is invalid.\n */\nexport async function loadConfig(configPath?: string): Promise<PrismaNextConfig> {\n try {\n const cwd = process.cwd();\n // Resolve config path to absolute path and set cwd to config directory when path is provided\n const resolvedConfigPath = configPath ? resolve(cwd, configPath) : undefined;\n const configCwd = resolvedConfigPath ? dirname(resolvedConfigPath) : cwd;\n\n const result = await loadConfigC12<PrismaNextConfig>({\n name: 'prisma-next',\n ...(resolvedConfigPath ? { configFile: resolvedConfigPath } : {}),\n cwd: configCwd,\n });\n\n // When a specific config file was requested, verify it was actually loaded\n // (c12 falls back to searching by name if the specified file doesn't exist)\n if (resolvedConfigPath && result.configFile !== resolvedConfigPath) {\n throw errorConfigFileNotFound(resolvedConfigPath);\n }\n\n // Check if config is missing or empty (c12 may return empty object when file doesn't exist)\n if (!result.config || Object.keys(result.config).length === 0) {\n // Use c12's configFile if available, otherwise use explicit configPath, otherwise omit path\n const displayPath = result.configFile || resolvedConfigPath || configPath;\n throw errorConfigFileNotFound(displayPath);\n }\n\n // Validate config structure\n validateConfig(result.config);\n\n return result.config;\n } catch (error) {\n // Re-throw structured errors as-is\n if (\n error instanceof Error &&\n 'code' in error &&\n typeof (error as { code: string }).code === 'string'\n ) {\n throw error;\n }\n\n if (error instanceof Error) {\n // Check for file not found errors\n if (\n error.message.includes('not found') ||\n error.message.includes('Cannot find') ||\n error.message.includes('ENOENT')\n ) {\n // Use resolved path if available, otherwise use original configPath\n const displayPath = configPath ? resolve(process.cwd(), configPath) : undefined;\n throw errorConfigFileNotFound(displayPath, {\n why: error.message,\n });\n }\n // For other errors, wrap in unexpected error\n throw errorUnexpected(error.message, {\n why: `Failed to load config: ${error.message}`,\n });\n }\n throw errorUnexpected(String(error));\n }\n}\n","import {\n checkContractComponentRequirements,\n type TargetBoundComponentDescriptor,\n} from '@prisma-next/contract/framework-components';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport type { ControlPlaneStack } from '@prisma-next/core-control-plane/types';\nimport { errorConfigValidation, errorContractMissingExtensionPacks } from './cli-errors.ts';\n\n/**\n * Asserts that all framework components are compatible with the expected family and target.\n *\n * This function validates that each component in the framework components array:\n * - Has kind 'target', 'adapter', 'extension', or 'driver'\n * - Has familyId matching expectedFamilyId\n * - Has targetId matching expectedTargetId\n *\n * This validation happens at the CLI composition boundary, before passing components\n * to typed planner/runner instances. It fills the gap between runtime validation\n * (via `validateConfig()`) and compile-time type enforcement.\n *\n * @param expectedFamilyId - The expected family ID (e.g., 'sql')\n * @param expectedTargetId - The expected target ID (e.g., 'postgres')\n * @param frameworkComponents - Array of framework components to validate\n * @returns The same array typed as TargetBoundComponentDescriptor\n * @throws CliStructuredError if any component is incompatible\n *\n * @example\n * ```ts\n * const config = await loadConfig();\n * const frameworkComponents = [config.target, config.adapter, ...(config.extensionPacks ?? [])];\n *\n * // Validate and type-narrow components before passing to planner\n * const typedComponents = assertFrameworkComponentsCompatible(\n * config.family.familyId,\n * config.target.targetId,\n * frameworkComponents\n * );\n *\n * const planner = target.migrations.createPlanner(familyInstance);\n * planner.plan({ contract, schema, policy, frameworkComponents: typedComponents });\n * ```\n */\nexport function assertFrameworkComponentsCompatible<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n expectedFamilyId: TFamilyId,\n expectedTargetId: TTargetId,\n frameworkComponents: ReadonlyArray<unknown>,\n): ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>> {\n for (let i = 0; i < frameworkComponents.length; i++) {\n const component = frameworkComponents[i];\n\n // Check that component is an object\n if (typeof component !== 'object' || component === null) {\n throw errorConfigValidation('frameworkComponents[]', {\n why: `Framework component at index ${i} must be an object`,\n });\n }\n\n const record = component as Record<string, unknown>;\n\n // Check kind\n if (!Object.hasOwn(record, 'kind')) {\n throw errorConfigValidation('frameworkComponents[].kind', {\n why: `Framework component at index ${i} must have 'kind' property`,\n });\n }\n\n const kind = record['kind'];\n if (kind !== 'target' && kind !== 'adapter' && kind !== 'extension' && kind !== 'driver') {\n throw errorConfigValidation('frameworkComponents[].kind', {\n why: `Framework component at index ${i} has invalid kind '${String(kind)}' (must be 'target', 'adapter', 'extension', or 'driver')`,\n });\n }\n\n // Check familyId\n if (!Object.hasOwn(record, 'familyId')) {\n throw errorConfigValidation('frameworkComponents[].familyId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'familyId' property`,\n });\n }\n\n const familyId = record['familyId'];\n if (familyId !== expectedFamilyId) {\n throw errorConfigValidation('frameworkComponents[].familyId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) has familyId '${String(familyId)}' but expected '${expectedFamilyId}'`,\n });\n }\n\n // Check targetId\n if (!Object.hasOwn(record, 'targetId')) {\n throw errorConfigValidation('frameworkComponents[].targetId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'targetId' property`,\n });\n }\n\n const targetId = record['targetId'];\n if (targetId !== expectedTargetId) {\n throw errorConfigValidation('frameworkComponents[].targetId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) has targetId '${String(targetId)}' but expected '${expectedTargetId}'`,\n });\n }\n }\n\n // Type assertion is safe because we've validated all components above\n return frameworkComponents as ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n}\n\n/**\n * Validates that a contract is compatible with the configured target, adapter,\n * and extension packs. Throws on family/target mismatches or missing extension packs.\n *\n * This check ensures the emitted contract matches the CLI config before running\n * commands that depend on the contract (e.g., db verify, db sign).\n *\n * @param contract - The contract IR to validate (must include targetFamily, target, extensionPacks).\n * @param stack - The control plane stack (target, adapter, driver, extensionPacks).\n *\n * @throws {CliStructuredError} errorConfigValidation when contract.targetFamily or contract.target\n * doesn't match the configured family/target.\n * @throws {CliStructuredError} errorContractMissingExtensionPacks when the contract requires\n * extension packs that are not provided in the config (includes all missing packs in error.meta).\n *\n * @example\n * ```ts\n * import { assertContractRequirementsSatisfied } from './framework-components';\n *\n * const config = await loadConfig();\n * const contractIR = await loadContractJson(config.contract.output);\n * const stack = createControlPlaneStack({ target: config.target, adapter: config.adapter, ... });\n *\n * // Throws if contract is incompatible with config\n * assertContractRequirementsSatisfied({ contract: contractIR, stack });\n * ```\n */\nexport function assertContractRequirementsSatisfied<\n TFamilyId extends string,\n TTargetId extends string,\n>({\n contract,\n stack,\n}: {\n readonly contract: Pick<ContractIR, 'targetFamily' | 'target' | 'extensionPacks'>;\n readonly stack: ControlPlaneStack<TFamilyId, TTargetId>;\n}): void {\n const providedComponentIds = new Set<string>([stack.target.id, stack.adapter.id]);\n for (const extension of stack.extensionPacks) {\n providedComponentIds.add(extension.id);\n }\n\n const result = checkContractComponentRequirements({\n contract,\n expectedTargetFamily: stack.target.familyId,\n expectedTargetId: stack.target.targetId,\n providedComponentIds,\n });\n\n if (result.familyMismatch) {\n throw errorConfigValidation('contract.targetFamily', {\n why: `Contract was emitted for family '${result.familyMismatch.actual}' but CLI config is wired to '${result.familyMismatch.expected}'.`,\n });\n }\n\n if (result.targetMismatch) {\n throw errorConfigValidation('contract.target', {\n why: `Contract target '${result.targetMismatch.actual}' does not match CLI target '${result.targetMismatch.expected}'.`,\n });\n }\n\n if (result.missingExtensionPackIds.length > 0) {\n throw errorContractMissingExtensionPacks({\n missingExtensionPacks: result.missingExtensionPackIds,\n providedComponentIds: [...providedComponentIds],\n });\n }\n}\n","import type { TargetBoundComponentDescriptor } from '@prisma-next/contract/framework-components';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport type {\n ControlDriverInstance,\n ControlFamilyInstance,\n MigrationPlan,\n MigrationPlannerResult,\n MigrationPlanOperation,\n MigrationRunnerResult,\n TargetMigrationsCapability,\n} from '@prisma-next/core-control-plane/types';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport type { DbInitResult, DbInitSuccess, OnControlProgress } from '../types.ts';\n\n/**\n * Options for executing dbInit operation.\n */\nexport interface ExecuteDbInitOptions<TFamilyId extends string, TTargetId extends string> {\n readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;\n readonly familyInstance: ControlFamilyInstance<TFamilyId>;\n readonly contractIR: ContractIR;\n readonly mode: 'plan' | 'apply';\n readonly migrations: TargetMigrationsCapability<\n TFamilyId,\n TTargetId,\n ControlFamilyInstance<TFamilyId>\n >;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n /** Optional progress callback for observing operation progress */\n readonly onProgress?: OnControlProgress;\n}\n\n/**\n * Executes the dbInit operation.\n *\n * This is the core logic extracted from the CLI command, without any file I/O,\n * process.exit(), or console output. It uses the Result pattern to return\n * success or failure details.\n *\n * @param options - The options for executing dbInit\n * @returns Result with DbInitSuccess on success, DbInitFailure on failure\n */\nexport async function executeDbInit<TFamilyId extends string, TTargetId extends string>(\n options: ExecuteDbInitOptions<TFamilyId, TTargetId>,\n): Promise<DbInitResult> {\n const { driver, familyInstance, contractIR, mode, migrations, frameworkComponents, onProgress } =\n options;\n\n // Create planner and runner from target migrations capability\n const planner = migrations.createPlanner(familyInstance);\n const runner = migrations.createRunner(familyInstance);\n\n // Introspect live schema\n const introspectSpanId = 'introspect';\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: introspectSpanId,\n label: 'Introspecting database schema',\n });\n const schemaIR = await familyInstance.introspect({ driver });\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: introspectSpanId,\n outcome: 'ok',\n });\n\n // Policy for init mode (additive only)\n const policy = { allowedOperationClasses: ['additive'] as const };\n\n // Plan migration\n const planSpanId = 'plan';\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: planSpanId,\n label: 'Planning migration',\n });\n const plannerResult: MigrationPlannerResult = await planner.plan({\n contract: contractIR,\n schema: schemaIR,\n policy,\n frameworkComponents,\n });\n\n if (plannerResult.kind === 'failure') {\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: planSpanId,\n outcome: 'error',\n });\n return notOk({\n code: 'PLANNING_FAILED' as const,\n summary: 'Migration planning failed due to conflicts',\n conflicts: plannerResult.conflicts,\n why: undefined,\n meta: undefined,\n });\n }\n\n const migrationPlan: MigrationPlan = plannerResult.plan;\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: planSpanId,\n outcome: 'ok',\n });\n\n // Check for existing marker - handle idempotency and mismatch errors\n const checkMarkerSpanId = 'checkMarker';\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: checkMarkerSpanId,\n label: 'Checking contract marker',\n });\n const existingMarker = await familyInstance.readMarker({ driver });\n if (existingMarker) {\n const markerMatchesDestination =\n existingMarker.coreHash === migrationPlan.destination.coreHash &&\n (!migrationPlan.destination.profileHash ||\n existingMarker.profileHash === migrationPlan.destination.profileHash);\n\n if (markerMatchesDestination) {\n // Already at destination - return success with no operations\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: checkMarkerSpanId,\n outcome: 'skipped',\n });\n const result: DbInitSuccess = {\n mode,\n plan: { operations: [] },\n ...(mode === 'apply'\n ? {\n execution: { operationsPlanned: 0, operationsExecuted: 0 },\n marker: {\n coreHash: existingMarker.coreHash,\n profileHash: existingMarker.profileHash,\n },\n }\n : {}),\n summary: 'Database already at target contract state',\n };\n return ok(result);\n }\n\n // Marker exists but doesn't match destination - fail\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: checkMarkerSpanId,\n outcome: 'error',\n });\n return notOk({\n code: 'MARKER_ORIGIN_MISMATCH' as const,\n summary: 'Existing contract marker does not match plan destination',\n marker: {\n coreHash: existingMarker.coreHash,\n profileHash: existingMarker.profileHash,\n },\n destination: {\n coreHash: migrationPlan.destination.coreHash,\n profileHash: migrationPlan.destination.profileHash,\n },\n why: undefined,\n conflicts: undefined,\n meta: undefined,\n });\n }\n\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: checkMarkerSpanId,\n outcome: 'ok',\n });\n\n // Plan mode - don't execute\n if (mode === 'plan') {\n const result: DbInitSuccess = {\n mode: 'plan',\n plan: { operations: migrationPlan.operations },\n summary: `Planned ${migrationPlan.operations.length} operation(s)`,\n };\n return ok(result);\n }\n\n // Apply mode - execute runner\n const applySpanId = 'apply';\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: applySpanId,\n label: 'Applying migration plan',\n });\n\n const callbacks = onProgress\n ? {\n onOperationStart: (op: MigrationPlanOperation) => {\n onProgress({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: `operation:${op.id}`,\n parentSpanId: applySpanId,\n label: op.label,\n });\n },\n onOperationComplete: (op: MigrationPlanOperation) => {\n onProgress({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: `operation:${op.id}`,\n outcome: 'ok',\n });\n },\n }\n : undefined;\n\n const runnerResult: MigrationRunnerResult = await runner.execute({\n plan: migrationPlan,\n driver,\n destinationContract: contractIR,\n policy,\n ...(callbacks ? { callbacks } : {}),\n // db init plans and applies back-to-back from a fresh introspection, so per-operation\n // pre/postchecks and the idempotency probe are usually redundant overhead. We still\n // enforce marker/origin compatibility and a full schema verification after apply.\n executionChecks: {\n prechecks: false,\n postchecks: false,\n idempotencyChecks: false,\n },\n frameworkComponents,\n });\n\n if (!runnerResult.ok) {\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: applySpanId,\n outcome: 'error',\n });\n return notOk({\n code: 'RUNNER_FAILED' as const,\n summary: runnerResult.failure.summary,\n why: runnerResult.failure.why,\n meta: runnerResult.failure.meta,\n conflicts: undefined,\n });\n }\n\n const execution = runnerResult.value;\n\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: applySpanId,\n outcome: 'ok',\n });\n\n const result: DbInitSuccess = {\n mode: 'apply',\n plan: { operations: migrationPlan.operations },\n execution: {\n operationsPlanned: execution.operationsPlanned,\n operationsExecuted: execution.operationsExecuted,\n },\n marker: migrationPlan.destination.profileHash\n ? {\n coreHash: migrationPlan.destination.coreHash,\n profileHash: migrationPlan.destination.profileHash,\n }\n : { coreHash: migrationPlan.destination.coreHash },\n summary: `Applied ${execution.operationsExecuted} operation(s), marker written`,\n };\n return ok(result);\n}\n","import type { TargetBoundComponentDescriptor } from '@prisma-next/contract/framework-components';\nimport type { CoreSchemaView } from '@prisma-next/core-control-plane/schema-view';\nimport { createControlPlaneStack } from '@prisma-next/core-control-plane/stack';\nimport type {\n ControlDriverInstance,\n ControlFamilyInstance,\n ControlPlaneStack,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/core-control-plane/types';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components.ts';\nimport { executeDbInit } from './operations/db-init.ts';\nimport type {\n ControlClient,\n ControlClientOptions,\n DbInitOptions,\n DbInitResult,\n EmitOptions,\n EmitResult,\n IntrospectOptions,\n SchemaVerifyOptions,\n SignOptions,\n VerifyOptions,\n} from './types.ts';\n\n/**\n * Creates a programmatic control client for Prisma Next operations.\n *\n * The client accepts framework component descriptors at creation time,\n * manages driver lifecycle via connect()/close(), and exposes domain\n * operations that delegate to the existing family instance methods.\n *\n * @see {@link ControlClient} for the client interface\n * @see README.md \"Programmatic Control API\" section for usage examples\n */\nexport function createControlClient(options: ControlClientOptions): ControlClient {\n return new ControlClientImpl(options);\n}\n\n/**\n * Implementation of ControlClient.\n * Manages initialization and connection state, delegates operations to family instance.\n */\nclass ControlClientImpl implements ControlClient {\n private readonly options: ControlClientOptions;\n private stack: ControlPlaneStack<string, string> | null = null;\n private driver: ControlDriverInstance<string, string> | null = null;\n private familyInstance: ControlFamilyInstance<string> | null = null;\n private frameworkComponents: ReadonlyArray<\n TargetBoundComponentDescriptor<string, string>\n > | null = null;\n private initialized = false;\n private readonly defaultConnection: unknown;\n\n constructor(options: ControlClientOptions) {\n this.options = options;\n this.defaultConnection = options.connection;\n }\n\n init(): void {\n if (this.initialized) {\n return; // Idempotent\n }\n\n // Create the control plane stack\n this.stack = createControlPlaneStack({\n target: this.options.target,\n adapter: this.options.adapter,\n driver: this.options.driver,\n extensionPacks: this.options.extensionPacks,\n });\n\n // Create family instance using the stack\n this.familyInstance = this.options.family.create(this.stack);\n\n // Validate and type-narrow framework components\n const rawComponents = [\n this.options.target,\n this.options.adapter,\n ...(this.options.extensionPacks ?? []),\n ];\n this.frameworkComponents = assertFrameworkComponentsCompatible(\n this.options.family.familyId,\n this.options.target.targetId,\n rawComponents,\n );\n\n this.initialized = true;\n }\n\n async connect(connection?: unknown): Promise<void> {\n // Auto-init if needed\n this.init();\n\n if (this.driver) {\n throw new Error('Already connected. Call close() before reconnecting.');\n }\n\n // Resolve connection: argument > default from options\n const resolvedConnection = connection ?? this.defaultConnection;\n if (resolvedConnection === undefined) {\n throw new Error(\n 'No connection provided. Pass a connection to connect() or provide a default connection when creating the client.',\n );\n }\n\n // Check for driver descriptor\n if (!this.stack?.driver) {\n throw new Error(\n 'Driver is not configured. Pass a driver descriptor when creating the control client to enable database operations.',\n );\n }\n\n // Create driver instance\n // Cast through any since connection type is driver-specific at runtime.\n // The driver descriptor is typed with any for TConnection in ControlClientOptions,\n // but createControlPlaneStack defaults it to string. We bridge this at runtime.\n // biome-ignore lint/suspicious/noExplicitAny: required for runtime connection type flexibility\n this.driver = await this.stack?.driver.create(resolvedConnection as any);\n }\n\n async close(): Promise<void> {\n if (this.driver) {\n await this.driver.close();\n this.driver = null;\n }\n }\n\n private async ensureConnected(): Promise<{\n driver: ControlDriverInstance<string, string>;\n familyInstance: ControlFamilyInstance<string>;\n frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<string, string>>;\n }> {\n // Auto-init if needed\n this.init();\n\n // Auto-connect if not connected and default connection is available\n if (!this.driver && this.defaultConnection !== undefined) {\n await this.connect(this.defaultConnection);\n }\n\n if (!this.driver || !this.familyInstance || !this.frameworkComponents) {\n throw new Error('Not connected. Call connect(connection) first.');\n }\n return {\n driver: this.driver,\n familyInstance: this.familyInstance,\n frameworkComponents: this.frameworkComponents,\n };\n }\n\n async verify(options: VerifyOptions): Promise<VerifyDatabaseResult> {\n const { onProgress } = options;\n\n // Connect with progress span if connection provided\n if (options.connection !== undefined) {\n onProgress?.({\n action: 'verify',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance } = await this.ensureConnected();\n\n // Validate contract using family instance\n const contractIR = familyInstance.validateContractIR(options.contractIR);\n\n // Emit verify span\n onProgress?.({\n action: 'verify',\n kind: 'spanStart',\n spanId: 'verify',\n label: 'Verifying contract marker...',\n });\n\n try {\n // Delegate to family instance verify method\n // Note: We pass empty strings for contractPath/configPath since the programmatic\n // API doesn't deal with file paths. The family instance accepts these as optional\n // metadata for error reporting.\n const result = await familyInstance.verify({\n driver,\n contractIR,\n expectedTargetId: this.options.target.targetId,\n contractPath: '',\n });\n\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'verify',\n outcome: result.ok ? 'ok' : 'error',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'verify',\n kind: 'spanEnd',\n spanId: 'verify',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n async schemaVerify(options: SchemaVerifyOptions): Promise<VerifyDatabaseSchemaResult> {\n const { onProgress } = options;\n\n // Connect with progress span if connection provided\n if (options.connection !== undefined) {\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();\n\n // Validate contract using family instance\n const contractIR = familyInstance.validateContractIR(options.contractIR);\n\n // Emit schemaVerify span\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanStart',\n spanId: 'schemaVerify',\n label: 'Verifying database schema...',\n });\n\n try {\n // Delegate to family instance schemaVerify method\n const result = await familyInstance.schemaVerify({\n driver,\n contractIR,\n strict: options.strict ?? false,\n contractPath: '',\n frameworkComponents,\n });\n\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'schemaVerify',\n outcome: result.ok ? 'ok' : 'error',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'schemaVerify',\n kind: 'spanEnd',\n spanId: 'schemaVerify',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n async sign(options: SignOptions): Promise<SignDatabaseResult> {\n const { onProgress } = options;\n\n // Connect with progress span if connection provided\n if (options.connection !== undefined) {\n onProgress?.({\n action: 'sign',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance } = await this.ensureConnected();\n\n // Validate contract using family instance\n const contractIR = familyInstance.validateContractIR(options.contractIR);\n\n // Emit sign span\n onProgress?.({\n action: 'sign',\n kind: 'spanStart',\n spanId: 'sign',\n label: 'Signing database...',\n });\n\n try {\n // Delegate to family instance sign method\n const result = await familyInstance.sign({\n driver,\n contractIR,\n contractPath: options.contractPath ?? '',\n ...(options.configPath ? { configPath: options.configPath } : {}),\n });\n\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'sign',\n outcome: 'ok',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'sign',\n kind: 'spanEnd',\n spanId: 'sign',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n async dbInit(options: DbInitOptions): Promise<DbInitResult> {\n const { onProgress } = options;\n\n // Connect with progress span if connection provided\n if (options.connection !== undefined) {\n onProgress?.({\n action: 'dbInit',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'dbInit',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance, frameworkComponents } = await this.ensureConnected();\n\n // Check target supports migrations\n if (!this.options.target.migrations) {\n throw new Error(`Target \"${this.options.target.targetId}\" does not support migrations`);\n }\n\n // Validate contract using family instance\n const contractIR = familyInstance.validateContractIR(options.contractIR);\n\n // Delegate to extracted dbInit operation\n return executeDbInit({\n driver,\n familyInstance,\n contractIR,\n mode: options.mode,\n migrations: this.options.target.migrations,\n frameworkComponents,\n ...(onProgress ? { onProgress } : {}),\n });\n }\n\n async introspect(options?: IntrospectOptions): Promise<unknown> {\n const onProgress = options?.onProgress;\n\n // Connect with progress span if connection provided\n if (options?.connection !== undefined) {\n onProgress?.({\n action: 'introspect',\n kind: 'spanStart',\n spanId: 'connect',\n label: 'Connecting to database...',\n });\n try {\n await this.connect(options.connection);\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'connect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n const { driver, familyInstance } = await this.ensureConnected();\n\n // TODO: Pass schema option to familyInstance.introspect when schema filtering is implemented\n const _schema = options?.schema;\n void _schema;\n\n // Emit introspect span\n onProgress?.({\n action: 'introspect',\n kind: 'spanStart',\n spanId: 'introspect',\n label: 'Introspecting database schema...',\n });\n\n try {\n const result = await familyInstance.introspect({ driver });\n\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'introspect',\n outcome: 'ok',\n });\n\n return result;\n } catch (error) {\n onProgress?.({\n action: 'introspect',\n kind: 'spanEnd',\n spanId: 'introspect',\n outcome: 'error',\n });\n throw error;\n }\n }\n\n toSchemaView(schemaIR: unknown): CoreSchemaView | undefined {\n this.init();\n if (this.familyInstance?.toSchemaView) {\n return this.familyInstance.toSchemaView(schemaIR);\n }\n return undefined;\n }\n\n async emit(options: EmitOptions): Promise<EmitResult> {\n const { onProgress, contractConfig } = options;\n\n // Ensure initialized (creates stack and family instance)\n // emit() does NOT require a database connection\n this.init();\n\n if (!this.familyInstance) {\n throw new Error('Family instance was not initialized. This is a bug.');\n }\n\n // Resolve contract source\n let contractRaw: unknown;\n onProgress?.({\n action: 'emit',\n kind: 'spanStart',\n spanId: 'resolveSource',\n label: 'Resolving contract source...',\n });\n\n try {\n switch (contractConfig.source.kind) {\n case 'loader':\n contractRaw = await contractConfig.source.load();\n break;\n case 'value':\n contractRaw = contractConfig.source.value;\n break;\n }\n\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'resolveSource',\n outcome: 'ok',\n });\n } catch (error) {\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'resolveSource',\n outcome: 'error',\n });\n\n return notOk({\n code: 'CONTRACT_SOURCE_INVALID',\n summary: 'Failed to resolve contract source',\n why: error instanceof Error ? error.message : String(error),\n meta: undefined,\n });\n }\n\n // Emit contract\n onProgress?.({\n action: 'emit',\n kind: 'spanStart',\n spanId: 'emit',\n label: 'Emitting contract...',\n });\n\n try {\n const emitResult = await this.familyInstance.emitContract({ contractIR: contractRaw });\n\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'emit',\n outcome: 'ok',\n });\n\n return ok({\n coreHash: emitResult.coreHash,\n profileHash: emitResult.profileHash,\n contractJson: emitResult.contractJson,\n contractDts: emitResult.contractDts,\n });\n } catch (error) {\n onProgress?.({\n action: 'emit',\n kind: 'spanEnd',\n spanId: 'emit',\n outcome: 'error',\n });\n\n return notOk({\n code: 'EMIT_FAILED',\n summary: 'Failed to emit contract',\n why: error instanceof Error ? error.message : String(error),\n meta: undefined,\n });\n }\n }\n}\n","import type { Command } from 'commander';\n\n/**\n * Sets both short and long descriptions for a command.\n * The short description is used in command trees and headers.\n * The long description is shown at the bottom of help output.\n */\nexport function setCommandDescriptions(\n command: Command,\n shortDescription: string,\n longDescription?: string,\n): Command {\n command.description(shortDescription);\n if (longDescription) {\n // Store long description in a custom property for our formatters to access\n (command as Command & { _longDescription?: string })._longDescription = longDescription;\n }\n return command;\n}\n\n/**\n * Gets the long description from a command if it was set via setCommandDescriptions.\n */\nexport function getLongDescription(command: Command): string | undefined {\n return (command as Command & { _longDescription?: string })._longDescription;\n}\n","export interface GlobalFlags {\n readonly json?: 'object' | 'ndjson';\n readonly quiet?: boolean;\n readonly verbose?: number; // 0, 1, or 2\n readonly timestamps?: boolean;\n readonly color?: boolean;\n}\n\nexport interface CliOptions {\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Parses global flags from CLI options.\n * Handles verbosity flags (-v, -vv, --trace), JSON output, quiet mode, timestamps, and color.\n */\nexport function parseGlobalFlags(options: CliOptions): GlobalFlags {\n const flags: {\n json?: 'object' | 'ndjson';\n quiet?: boolean;\n verbose?: number;\n timestamps?: boolean;\n color?: boolean;\n } = {};\n\n // JSON output\n if (options.json === true || options.json === 'object') {\n flags.json = 'object';\n } else if (options.json === 'ndjson') {\n flags.json = 'ndjson';\n }\n\n // Quiet mode\n if (options.quiet || options.q) {\n flags.quiet = true;\n }\n\n // Verbosity: -v = 1, -vv or --trace = 2\n if (options.vv || options.trace) {\n flags.verbose = 2;\n } else if (options.verbose || options.v) {\n flags.verbose = 1;\n } else {\n flags.verbose = 0;\n }\n\n // Timestamps\n if (options.timestamps) {\n flags.timestamps = true;\n }\n\n // Color: respect NO_COLOR env var, --color/--no-color flags\n // When JSON output is enabled (any format), disable color to ensure clean JSON output\n if (process.env['NO_COLOR'] || flags.json) {\n flags.color = false;\n } else if (options['no-color']) {\n flags.color = false;\n } else if (options.color !== undefined) {\n flags.color = options.color;\n } else {\n // Default: enable color if TTY\n flags.color = process.stdout.isTTY && !process.env['CI'];\n }\n\n return flags as GlobalFlags;\n}\n","import { relative } from 'node:path';\nimport { bgGreen, blue, bold, cyan, dim, green, magenta, red, yellow } from 'colorette';\nimport type { Command } from 'commander';\nimport stringWidth from 'string-width';\nimport stripAnsi from 'strip-ansi';\nimport wrapAnsi from 'wrap-ansi';\n// EmitContractResult type for CLI output formatting (includes file paths)\nexport interface EmitContractResult {\n readonly coreHash: string;\n readonly profileHash: string;\n readonly outDir: string;\n readonly files: {\n readonly json: string;\n readonly dts: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nimport type { CoreSchemaView, SchemaTreeNode } from '@prisma-next/core-control-plane/schema-view';\nimport type {\n IntrospectSchemaResult,\n SchemaVerificationNode,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/core-control-plane/types';\nimport type { CliErrorConflict, CliErrorEnvelope } from './cli-errors.ts';\nimport { getLongDescription } from './command-helpers.ts';\nimport type { GlobalFlags } from './global-flags.ts';\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Formats a timestamp for output.\n */\nfunction formatTimestamp(): string {\n return new Date().toISOString();\n}\n\n/**\n * Creates a prefix string if timestamps are enabled.\n */\nfunction createPrefix(flags: GlobalFlags): string {\n return flags.timestamps ? `[${formatTimestamp()}] ` : '';\n}\n\n/**\n * Checks if verbose output is enabled at the specified level.\n */\nfunction isVerbose(flags: GlobalFlags, level: 1 | 2): boolean {\n return (flags.verbose ?? 0) >= level;\n}\n\n/**\n * Creates a color-aware formatter function.\n * Returns a function that applies the color only if colors are enabled.\n */\nfunction createColorFormatter<T extends (text: string) => string>(\n useColor: boolean,\n colorFn: T,\n): (text: string) => string {\n return useColor ? colorFn : (text: string) => text;\n}\n\n/**\n * Formats text with dim styling if colors are enabled.\n */\nfunction formatDim(useColor: boolean, text: string): string {\n return useColor ? dim(text) : text;\n}\n\n// ============================================================================\n// Emit Output Formatters\n// ============================================================================\n\n/**\n * Formats human-readable output for contract emit.\n */\nexport function formatEmitOutput(result: EmitContractResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n\n // Convert absolute paths to relative paths from cwd\n const jsonPath = relative(process.cwd(), result.files.json);\n const dtsPath = relative(process.cwd(), result.files.dts);\n\n lines.push(`${prefix}✔ Emitted contract.json → ${jsonPath}`);\n lines.push(`${prefix}✔ Emitted contract.d.ts → ${dtsPath}`);\n lines.push(`${prefix} coreHash: ${result.coreHash}`);\n if (result.profileHash) {\n lines.push(`${prefix} profileHash: ${result.profileHash}`);\n }\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix} Total time: ${result.timings.total}ms`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for contract emit.\n */\nexport function formatEmitJson(result: EmitContractResult): string {\n const output = {\n ok: true,\n coreHash: result.coreHash,\n ...(result.profileHash ? { profileHash: result.profileHash } : {}),\n outDir: result.outDir,\n files: result.files,\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n\n// ============================================================================\n// Error Output Formatters\n// ============================================================================\n\n/**\n * Formats error output for human-readable display.\n */\nexport function formatErrorOutput(error: CliErrorEnvelope, flags: GlobalFlags): string {\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatRed = createColorFormatter(useColor, red);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n lines.push(`${prefix}${formatRed('✖')} ${error.summary} (${error.code})`);\n\n if (error.why) {\n lines.push(`${prefix}${formatDimText(` Why: ${error.why}`)}`);\n }\n if (error.fix) {\n lines.push(`${prefix}${formatDimText(` Fix: ${error.fix}`)}`);\n }\n if (error.where?.path) {\n const whereLine = error.where.line\n ? `${error.where.path}:${error.where.line}`\n : error.where.path;\n lines.push(`${prefix}${formatDimText(` Where: ${whereLine}`)}`);\n }\n // Show conflicts list if present (always show a short list; show full list when verbose)\n if (error.meta?.['conflicts']) {\n const conflicts = error.meta['conflicts'] as readonly CliErrorConflict[];\n if (conflicts.length > 0) {\n const maxToShow = isVerbose(flags, 1) ? conflicts.length : Math.min(3, conflicts.length);\n const header = isVerbose(flags, 1)\n ? ' Conflicts:'\n : ` Conflicts (showing ${maxToShow} of ${conflicts.length}):`;\n lines.push(`${prefix}${formatDimText(header)}`);\n for (const conflict of conflicts.slice(0, maxToShow)) {\n lines.push(`${prefix}${formatDimText(` - [${conflict.kind}] ${conflict.summary}`)}`);\n }\n if (!isVerbose(flags, 1) && conflicts.length > maxToShow) {\n lines.push(`${prefix}${formatDimText(' Re-run with -v/--verbose to see all conflicts')}`);\n }\n }\n }\n // Show issues list if present (always show a short list; show full list when verbose)\n if (error.meta?.['issues']) {\n const issues = error.meta['issues'] as readonly { kind?: string; message?: string }[];\n if (issues.length > 0) {\n const maxToShow = isVerbose(flags, 1) ? issues.length : Math.min(3, issues.length);\n const header = isVerbose(flags, 1)\n ? ' Issues:'\n : ` Issues (showing ${maxToShow} of ${issues.length}):`;\n lines.push(`${prefix}${formatDimText(header)}`);\n for (const issue of issues.slice(0, maxToShow)) {\n const kind = issue.kind ?? 'issue';\n const message = issue.message ?? '';\n lines.push(`${prefix}${formatDimText(` - [${kind}] ${message}`)}`);\n }\n if (!isVerbose(flags, 1) && issues.length > maxToShow) {\n lines.push(`${prefix}${formatDimText(' Re-run with -v/--verbose to see all issues')}`);\n }\n }\n }\n if (error.docsUrl && isVerbose(flags, 1)) {\n lines.push(formatDimText(error.docsUrl));\n }\n if (isVerbose(flags, 2) && error.meta) {\n lines.push(`${prefix}${formatDimText(` Meta: ${JSON.stringify(error.meta, null, 2)}`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats error output as JSON.\n */\nexport function formatErrorJson(error: CliErrorEnvelope): string {\n return JSON.stringify(error, null, 2);\n}\n\n// ============================================================================\n// Verify Output Formatters\n// ============================================================================\n\n/**\n * Formats human-readable output for database verify.\n */\nexport function formatVerifyOutput(result: VerifyDatabaseResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatRed = createColorFormatter(useColor, red);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n lines.push(`${prefix}${formatGreen('✔')} ${result.summary}`);\n lines.push(`${prefix}${formatDimText(` coreHash: ${result.contract.coreHash}`)}`);\n if (result.contract.profileHash) {\n lines.push(`${prefix}${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n } else {\n lines.push(`${prefix}${formatRed('✖')} ${result.summary} (${result.code})`);\n }\n\n if (isVerbose(flags, 1)) {\n if (result.codecCoverageSkipped) {\n lines.push(\n `${prefix}${formatDimText(' Codec coverage check skipped (helper returned no supported types)')}`,\n );\n }\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database verify.\n */\nexport function formatVerifyJson(result: VerifyDatabaseResult): string {\n const output = {\n ok: result.ok,\n ...(result.code ? { code: result.code } : {}),\n summary: result.summary,\n contract: result.contract,\n ...(result.marker ? { marker: result.marker } : {}),\n target: result.target,\n ...(result.missingCodecs ? { missingCodecs: result.missingCodecs } : {}),\n ...(result.meta ? { meta: result.meta } : {}),\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Formats JSON output for database introspection.\n */\nexport function formatIntrospectJson(result: IntrospectSchemaResult<unknown>): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Renders a schema tree structure from CoreSchemaView.\n * Matches the style of renderSchemaVerificationTree for consistency.\n */\nfunction renderSchemaTree(\n node: SchemaTreeNode,\n flags: GlobalFlags,\n options: {\n readonly isLast: boolean;\n readonly prefix: string;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly isRoot?: boolean;\n },\n): string[] {\n const { isLast, prefix, useColor, formatDimText, isRoot = false } = options;\n const lines: string[] = [];\n\n // Format node label with color based on kind (matching schema-verify style)\n let formattedLabel: string = node.label;\n\n if (useColor) {\n switch (node.kind) {\n case 'root':\n formattedLabel = bold(node.label);\n break;\n case 'entity': {\n // Parse \"table tableName\" format - color \"table\" dim, tableName cyan\n const tableMatch = node.label.match(/^table\\s+(.+)$/);\n if (tableMatch?.[1]) {\n const tableName = tableMatch[1];\n formattedLabel = `${dim('table')} ${cyan(tableName)}`;\n } else {\n // Fallback: color entire label with cyan\n formattedLabel = cyan(node.label);\n }\n break;\n }\n case 'collection': {\n // \"columns\" grouping node - dim the label\n formattedLabel = dim(node.label);\n break;\n }\n case 'field': {\n // Parse column name format: \"columnName: typeDisplay (nullability)\"\n // Color code: column name (cyan), type (default), nullability (dim)\n const columnMatch = node.label.match(/^([^:]+):\\s*(.+)$/);\n if (columnMatch?.[1] && columnMatch[2]) {\n const columnName = columnMatch[1];\n const rest = columnMatch[2];\n // Parse rest: \"typeDisplay (nullability)\"\n const typeMatch = rest.match(/^([^\\s(]+)\\s*(\\([^)]+\\))$/);\n if (typeMatch?.[1] && typeMatch[2]) {\n const typeDisplay = typeMatch[1];\n const nullability = typeMatch[2];\n formattedLabel = `${cyan(columnName)}: ${typeDisplay} ${dim(nullability)}`;\n } else {\n // Fallback if format doesn't match\n formattedLabel = `${cyan(columnName)}: ${rest}`;\n }\n } else {\n formattedLabel = node.label;\n }\n break;\n }\n case 'index': {\n // Parse index/unique constraint/primary key formats\n // \"primary key: columnName\" -> dim \"primary key\", cyan columnName\n const pkMatch = node.label.match(/^primary key:\\s*(.+)$/);\n if (pkMatch?.[1]) {\n const columnNames = pkMatch[1];\n formattedLabel = `${dim('primary key')}: ${cyan(columnNames)}`;\n } else {\n // \"unique name\" -> dim \"unique\", cyan \"name\"\n const uniqueMatch = node.label.match(/^unique\\s+(.+)$/);\n if (uniqueMatch?.[1]) {\n const name = uniqueMatch[1];\n formattedLabel = `${dim('unique')} ${cyan(name)}`;\n } else {\n // \"index name\" or \"unique index name\" -> dim label prefix, cyan name\n const indexMatch = node.label.match(/^(unique\\s+)?index\\s+(.+)$/);\n if (indexMatch?.[2]) {\n const prefix = indexMatch[1] ? `${dim('unique')} ` : '';\n const name = indexMatch[2];\n formattedLabel = `${prefix}${dim('index')} ${cyan(name)}`;\n } else {\n formattedLabel = dim(node.label);\n }\n }\n }\n break;\n }\n case 'extension': {\n // Parse extension message formats similar to schema-verify\n // \"extensionName extension is enabled\" -> cyan extensionName, dim rest\n const extMatch = node.label.match(/^([^\\s]+)\\s+(extension is enabled)$/);\n if (extMatch?.[1] && extMatch[2]) {\n const extName = extMatch[1];\n const rest = extMatch[2];\n formattedLabel = `${cyan(extName)} ${dim(rest)}`;\n } else {\n // Fallback: color entire label with magenta\n formattedLabel = magenta(node.label);\n }\n break;\n }\n default:\n formattedLabel = node.label;\n break;\n }\n }\n\n // Root node renders without tree characters or │ prefix\n if (isRoot) {\n lines.push(formattedLabel);\n } else {\n // Determine tree character for this node\n const treeChar = isLast ? '└' : '├';\n const treePrefix = `${prefix}${formatDimText(treeChar)}─ `;\n // Root's direct children don't have │ prefix, other nodes do\n // But if prefix already contains │ (for nested children), don't add another\n const isRootChild = prefix === '';\n // Check if prefix already contains │ (strip ANSI codes for comparison)\n const prefixWithoutAnsi = stripAnsi(prefix);\n const prefixHasVerticalBar = prefixWithoutAnsi.includes('│');\n if (isRootChild) {\n lines.push(`${treePrefix}${formattedLabel}`);\n } else if (prefixHasVerticalBar) {\n // Prefix already has │, so just use treePrefix directly\n lines.push(`${treePrefix}${formattedLabel}`);\n } else {\n lines.push(`${formatDimText('│')} ${treePrefix}${formattedLabel}`);\n }\n }\n\n // Render children if present\n if (node.children && node.children.length > 0) {\n // For root node, children start with no prefix (they'll add their own tree characters)\n // For other nodes, calculate child prefix based on whether this is last\n const childPrefix = isRoot ? '' : isLast ? `${prefix} ` : `${prefix}${formatDimText('│')} `;\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n if (!child) continue;\n const isLastChild = i === node.children.length - 1;\n const childLines = renderSchemaTree(child, flags, {\n isLast: isLastChild,\n prefix: childPrefix,\n useColor,\n formatDimText,\n isRoot: false,\n });\n lines.push(...childLines);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats human-readable output for database introspection.\n */\nexport function formatIntrospectOutput(\n result: IntrospectSchemaResult<unknown>,\n schemaView: CoreSchemaView | undefined,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (schemaView) {\n // Render tree structure - root node is special (no tree characters)\n const treeLines = renderSchemaTree(schemaView.root, flags, {\n isLast: true,\n prefix: '',\n useColor,\n formatDimText,\n isRoot: true,\n });\n // Apply prefix (for timestamps) to each tree line\n const prefixedTreeLines = treeLines.map((line) => `${prefix}${line}`);\n lines.push(...prefixedTreeLines);\n } else {\n // Fallback: print summary when toSchemaView is not available\n lines.push(`${prefix}✔ ${result.summary}`);\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix} Target: ${result.target.familyId}/${result.target.id}`);\n if (result.meta?.dbUrl) {\n lines.push(`${prefix} Database: ${result.meta.dbUrl}`);\n }\n }\n }\n\n // Add timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Renders a schema verification tree structure from SchemaVerificationNode.\n * Similar to renderSchemaTree but for verification nodes with status-based colors and glyphs.\n */\nfunction renderSchemaVerificationTree(\n node: SchemaVerificationNode,\n flags: GlobalFlags,\n options: {\n readonly isLast: boolean;\n readonly prefix: string;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly isRoot?: boolean;\n },\n): string[] {\n const { isLast, prefix, useColor, formatDimText, isRoot = false } = options;\n const lines: string[] = [];\n\n // Format status glyph and color based on status\n let statusGlyph = '';\n let statusColor: (text: string) => string = (text) => text;\n if (useColor) {\n switch (node.status) {\n case 'pass':\n statusGlyph = '✔';\n statusColor = green;\n break;\n case 'warn':\n statusGlyph = '⚠';\n statusColor = (text) => (useColor ? yellow(text) : text);\n break;\n case 'fail':\n statusGlyph = '✖';\n statusColor = red;\n break;\n }\n } else {\n switch (node.status) {\n case 'pass':\n statusGlyph = '✔';\n break;\n case 'warn':\n statusGlyph = '⚠';\n break;\n case 'fail':\n statusGlyph = '✖';\n break;\n }\n }\n\n // Format node label with color based on kind\n // For column nodes, we need to parse the name to color code different parts\n let labelColor: (text: string) => string = (text) => text;\n let formattedLabel: string = node.name;\n\n if (useColor) {\n switch (node.kind) {\n case 'contract':\n case 'schema':\n labelColor = bold;\n formattedLabel = labelColor(node.name);\n break;\n case 'table': {\n // Parse \"table tableName\" format - color \"table\" dim, tableName cyan\n const tableMatch = node.name.match(/^table\\s+(.+)$/);\n if (tableMatch?.[1]) {\n const tableName = tableMatch[1];\n formattedLabel = `${dim('table')} ${cyan(tableName)}`;\n } else {\n formattedLabel = dim(node.name);\n }\n break;\n }\n case 'columns':\n labelColor = dim;\n formattedLabel = labelColor(node.name);\n break;\n case 'column': {\n // Parse column name format: \"columnName: contractType → nativeType (nullability)\"\n // Color code: column name (cyan), contract type (default), native type (dim), nullability (dim)\n const columnMatch = node.name.match(/^([^:]+):\\s*(.+)$/);\n if (columnMatch?.[1] && columnMatch[2]) {\n const columnName = columnMatch[1];\n const rest = columnMatch[2];\n // Parse rest: \"contractType → nativeType (nullability)\"\n // Match contract type (can contain /, @, etc.), arrow, native type, then nullability in parentheses\n const typeMatch = rest.match(/^([^\\s→]+)\\s*→\\s*([^\\s(]+)\\s*(\\([^)]+\\))$/);\n if (typeMatch?.[1] && typeMatch[2] && typeMatch[3]) {\n const contractType = typeMatch[1];\n const nativeType = typeMatch[2];\n const nullability = typeMatch[3];\n formattedLabel = `${cyan(columnName)}: ${contractType} → ${dim(nativeType)} ${dim(nullability)}`;\n } else {\n // Fallback if format doesn't match (e.g., no native type or no nullability)\n formattedLabel = `${cyan(columnName)}: ${rest}`;\n }\n } else {\n formattedLabel = node.name;\n }\n break;\n }\n case 'type':\n case 'nullability':\n labelColor = (text) => text; // Default color\n formattedLabel = labelColor(node.name);\n break;\n case 'primaryKey': {\n // Parse \"primary key: columnName\" format - color \"primary key\" dim, columnName cyan\n const pkMatch = node.name.match(/^primary key:\\s*(.+)$/);\n if (pkMatch?.[1]) {\n const columnNames = pkMatch[1];\n formattedLabel = `${dim('primary key')}: ${cyan(columnNames)}`;\n } else {\n formattedLabel = dim(node.name);\n }\n break;\n }\n case 'foreignKey':\n case 'unique':\n case 'index':\n labelColor = dim;\n formattedLabel = labelColor(node.name);\n break;\n case 'extension': {\n // Parse specific extension message formats\n // \"database is postgres\" -> dim \"database is\", cyan \"postgres\"\n const dbMatch = node.name.match(/^database is\\s+(.+)$/);\n if (dbMatch?.[1]) {\n const dbName = dbMatch[1];\n formattedLabel = `${dim('database is')} ${cyan(dbName)}`;\n } else {\n // \"vector extension is enabled\" -> dim everything except extension name\n // Match pattern: \"extensionName extension is enabled\"\n const extMatch = node.name.match(/^([^\\s]+)\\s+(extension is enabled)$/);\n if (extMatch?.[1] && extMatch[2]) {\n const extName = extMatch[1];\n const rest = extMatch[2];\n formattedLabel = `${cyan(extName)} ${dim(rest)}`;\n } else {\n // Fallback: color entire name with magenta\n labelColor = magenta;\n formattedLabel = labelColor(node.name);\n }\n }\n break;\n }\n default:\n formattedLabel = node.name;\n break;\n }\n } else {\n formattedLabel = node.name;\n }\n\n const statusGlyphColored = statusColor(statusGlyph);\n\n // Build the label with optional message for failure/warn nodes\n let nodeLabel = formattedLabel;\n if (\n (node.status === 'fail' || node.status === 'warn') &&\n node.message &&\n node.message.length > 0\n ) {\n // Always show message for failure/warn nodes - it provides crucial context\n // For parent nodes, the message summarizes child failures\n // For leaf nodes, the message explains the specific issue\n const messageText = formatDimText(`(${node.message})`);\n nodeLabel = `${formattedLabel} ${messageText}`;\n }\n\n // Root node renders without tree characters or │ prefix\n if (isRoot) {\n lines.push(`${statusGlyphColored} ${nodeLabel}`);\n } else {\n // Determine tree character for this node\n const treeChar = isLast ? '└' : '├';\n const treePrefix = `${prefix}${formatDimText(treeChar)}─ `;\n // Root's direct children don't have │ prefix, other nodes do\n const isRootChild = prefix === '';\n // Check if prefix already contains │ (strip ANSI codes for comparison)\n const prefixWithoutAnsi = stripAnsi(prefix);\n const prefixHasVerticalBar = prefixWithoutAnsi.includes('│');\n if (isRootChild) {\n lines.push(`${treePrefix}${statusGlyphColored} ${nodeLabel}`);\n } else if (prefixHasVerticalBar) {\n // Prefix already has │, so just use treePrefix directly\n lines.push(`${treePrefix}${statusGlyphColored} ${nodeLabel}`);\n } else {\n lines.push(`${formatDimText('│')} ${treePrefix}${statusGlyphColored} ${nodeLabel}`);\n }\n }\n\n // Render children if present\n if (node.children && node.children.length > 0) {\n // For root node, children start with no prefix (they'll add their own tree characters)\n // For other nodes, calculate child prefix based on whether this is last\n const childPrefix = isRoot ? '' : isLast ? `${prefix} ` : `${prefix}${formatDimText('│')} `;\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n if (!child) continue;\n const isLastChild = i === node.children.length - 1;\n const childLines = renderSchemaVerificationTree(child, flags, {\n isLast: isLastChild,\n prefix: childPrefix,\n useColor,\n formatDimText,\n isRoot: false,\n });\n lines.push(...childLines);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats human-readable output for database schema verification.\n */\nexport function formatSchemaVerifyOutput(\n result: VerifyDatabaseSchemaResult,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatRed = createColorFormatter(useColor, red);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Render verification tree first\n const treeLines = renderSchemaVerificationTree(result.schema.root, flags, {\n isLast: true,\n prefix: '',\n useColor,\n formatDimText,\n isRoot: true,\n });\n // Apply prefix (for timestamps) to each tree line\n const prefixedTreeLines = treeLines.map((line) => `${prefix}${line}`);\n lines.push(...prefixedTreeLines);\n\n // Add counts and timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n lines.push(\n `${prefix}${formatDimText(` pass=${result.schema.counts.pass} warn=${result.schema.counts.warn} fail=${result.schema.counts.fail}`)}`,\n );\n }\n\n // Blank line before summary\n lines.push('');\n\n // Summary line at the end: summary with status glyph\n if (result.ok) {\n lines.push(`${prefix}${formatGreen('✔')} ${result.summary}`);\n } else {\n const codeText = result.code ? ` (${result.code})` : '';\n lines.push(`${prefix}${formatRed('✖')} ${result.summary}${codeText}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database schema verification.\n */\nexport function formatSchemaVerifyJson(result: VerifyDatabaseSchemaResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n// ============================================================================\n// Sign Output Formatters\n// ============================================================================\n\n/**\n * Formats human-readable output for database sign.\n */\nexport function formatSignOutput(result: SignDatabaseResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n // Main success message in white (not dimmed)\n lines.push(`${prefix}${formatGreen('✔')} Database signed`);\n\n // Show from -> to hashes with clear labels\n const previousHash = result.marker.previous?.coreHash ?? 'none';\n const currentHash = result.contract.coreHash;\n\n lines.push(`${prefix}${formatDimText(` from: ${previousHash}`)}`);\n lines.push(`${prefix}${formatDimText(` to: ${currentHash}`)}`);\n\n if (isVerbose(flags, 1)) {\n if (result.contract.profileHash) {\n lines.push(`${prefix}${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n if (result.marker.previous?.profileHash) {\n lines.push(\n `${prefix}${formatDimText(` previous profileHash: ${result.marker.previous.profileHash}`)}`,\n );\n }\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database sign.\n */\nexport function formatSignJson(result: SignDatabaseResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n// ============================================================================\n// DB Init Output Formatters\n// ============================================================================\n\n/**\n * Result type for db init command.\n */\nexport interface DbInitResult {\n readonly ok: boolean;\n readonly mode: 'plan' | 'apply';\n readonly plan?: {\n readonly targetId: string;\n readonly destination: {\n readonly coreHash: string;\n readonly profileHash?: string;\n };\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n };\n readonly execution?: {\n readonly operationsPlanned: number;\n readonly operationsExecuted: number;\n };\n readonly marker?: {\n readonly coreHash: string;\n readonly profileHash?: string;\n };\n readonly summary: string;\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for db init plan mode.\n */\nexport function formatDbInitPlanOutput(result: DbInitResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Plan summary\n const operationCount = result.plan?.operations.length ?? 0;\n lines.push(`${prefix}${formatGreen('✔')} Planned ${operationCount} operation(s)`);\n\n // Show operations tree\n if (result.plan?.operations && result.plan.operations.length > 0) {\n lines.push(`${prefix}${formatDimText('│')}`);\n for (let i = 0; i < result.plan.operations.length; i++) {\n const op = result.plan.operations[i];\n if (!op) continue;\n const isLast = i === result.plan.operations.length - 1;\n const treeChar = isLast ? '└' : '├';\n const opClass = formatDimText(`[${op.operationClass}]`);\n lines.push(`${prefix}${formatDimText(treeChar)}─ ${op.label} ${opClass}`);\n }\n }\n\n // Destination hash\n if (result.plan?.destination) {\n lines.push(`${prefix}`);\n lines.push(\n `${prefix}${formatDimText(`Destination hash: ${result.plan.destination.coreHash}`)}`,\n );\n }\n\n // Timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix}${formatDimText(`Total time: ${result.timings.total}ms`)}`);\n }\n\n // Note about dry run\n lines.push(`${prefix}`);\n lines.push(`${prefix}${formatDimText('This is a dry run. No changes were applied.')}`);\n lines.push(`${prefix}${formatDimText('Run without --plan to apply changes.')}`);\n\n return lines.join('\\n');\n}\n\n/**\n * Formats human-readable output for db init apply mode.\n */\nexport function formatDbInitApplyOutput(result: DbInitResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n const prefix = createPrefix(flags);\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n // Success summary\n const executed = result.execution?.operationsExecuted ?? 0;\n lines.push(`${prefix}${formatGreen('✔')} Applied ${executed} operation(s)`);\n\n // Marker info\n if (result.marker) {\n lines.push(`${prefix}${formatDimText(` Marker written: ${result.marker.coreHash}`)}`);\n if (result.marker.profileHash) {\n lines.push(`${prefix}${formatDimText(` Profile hash: ${result.marker.profileHash}`)}`);\n }\n }\n\n // Timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for db init command.\n */\nexport function formatDbInitJson(result: DbInitResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n// ============================================================================\n// Styled Output Formatters\n// ============================================================================\n\n/**\n * Fixed width for left column in help output.\n */\nconst LEFT_COLUMN_WIDTH = 20;\n\n/**\n * Minimum width for right column wrapping in help output.\n */\nconst RIGHT_COLUMN_MIN_WIDTH = 40;\n\n/**\n * Maximum width for right column wrapping in help output (when terminal is wide enough).\n */\nconst RIGHT_COLUMN_MAX_WIDTH = 90;\n\n/**\n * Gets the terminal width, or returns a default if not available.\n */\nfunction getTerminalWidth(): number {\n // process.stdout.columns may be undefined in non-TTY environments\n const terminalWidth = process.stdout.columns;\n // Default to 80 if terminal width is not available, but allow override via env var\n const defaultWidth = Number.parseInt(process.env['CLI_WIDTH'] || '80', 10);\n return terminalWidth || defaultWidth;\n}\n\n/**\n * Calculates the available width for the right column based on terminal width.\n * Format: \"│ \" (2) + left column (20) + \" \" (2) + right column = total\n * So: right column = terminal width - 2 - 20 - 2 = terminal width - 24\n */\nfunction calculateRightColumnWidth(): number {\n const terminalWidth = getTerminalWidth();\n const availableWidth = terminalWidth - 2 - LEFT_COLUMN_WIDTH - 2; // Subtract separators and left column\n // Ensure minimum width, but don't exceed maximum\n return Math.max(RIGHT_COLUMN_MIN_WIDTH, Math.min(availableWidth, RIGHT_COLUMN_MAX_WIDTH));\n}\n\n/**\n * Creates an arrow segment badge with green background and white text.\n * Body: green background with white \"prisma-next\" text\n * Tip: dark grey arrow pointing right (Powerline separator)\n */\nfunction createPrismaNextBadge(useColor: boolean): string {\n if (!useColor) {\n return 'prisma-next';\n }\n // Body: green background with white text\n const text = ' prisma-next ';\n const body = bgGreen(bold(text));\n\n // Use Powerline separator (U+E0B0) which creates the arrow transition effect\n const separator = '\\u{E0B0}';\n const tip = green(separator); // Dark grey arrow tip\n\n return `${body}${tip}`;\n}\n\n/**\n * Creates a padding function.\n */\nfunction createPadFunction(): (s: string, w: number) => string {\n return (s: string, w: number) => s + ' '.repeat(Math.max(0, w - s.length));\n}\n\n/**\n * Formats a header line: brand + operation + intent\n */\nfunction formatHeaderLine(options: {\n readonly brand: string;\n readonly operation: string;\n readonly intent: string;\n}): string {\n if (options.operation) {\n return `${options.brand} ${options.operation} → ${options.intent}`;\n }\n return `${options.brand} ${options.intent}`;\n}\n\n/**\n * Formats a \"Read more\" URL line.\n * The \"Read more\" label is in default color (not cyan), and the URL is blue.\n */\nfunction formatReadMoreLine(options: {\n readonly url: string;\n readonly maxLabelWidth: number;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n}): string {\n const pad = createPadFunction();\n const labelPadded = pad('Read more', options.maxLabelWidth);\n // Label is default color (not cyan)\n const valueColored = options.useColor ? blue(options.url) : options.url;\n return `${options.formatDimText('│')} ${labelPadded} ${valueColored}`;\n}\n\n/**\n * Pads text to a fixed width, accounting for ANSI escape codes.\n * Uses string-width to measure the actual display width.\n */\nfunction padToFixedWidth(text: string, width: number): string {\n const actualWidth = stringWidth(text);\n const padding = Math.max(0, width - actualWidth);\n return text + ' '.repeat(padding);\n}\n\n/**\n * Wraps text to fit within a specified width using wrap-ansi.\n * Preserves ANSI escape codes and breaks at word boundaries.\n */\nfunction wrapTextAnsi(text: string, width: number): string[] {\n const wrapped = wrapAnsi(text, width, { hard: false, trim: true });\n return wrapped.split('\\n');\n}\n\n/**\n * Formats a default value as \"default: <value>\" with dimming.\n */\nfunction formatDefaultValue(value: unknown, useColor: boolean): string {\n const valueStr = String(value);\n const defaultText = `default: ${valueStr}`;\n return useColor ? dim(defaultText) : defaultText;\n}\n\n/**\n * Renders a command tree structure.\n * Handles both single-level (subcommands of a command) and multi-level (top-level commands with subcommands) trees.\n */\nfunction renderCommandTree(options: {\n readonly commands: readonly Command[];\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly hasItemsAfter: boolean;\n readonly continuationPrefix?: string;\n}): string[] {\n const { commands, useColor, formatDimText, hasItemsAfter, continuationPrefix } = options;\n const lines: string[] = [];\n\n if (commands.length === 0) {\n return lines;\n }\n\n // Format each command\n for (let i = 0; i < commands.length; i++) {\n const cmd = commands[i];\n if (!cmd) continue;\n\n const subcommands = cmd.commands.filter((subcmd) => !subcmd.name().startsWith('_'));\n const isLastCommand = i === commands.length - 1;\n\n if (subcommands.length > 0) {\n // Command with subcommands - show command name, then tree-structured subcommands\n const prefix = isLastCommand && !hasItemsAfter ? formatDimText('└') : formatDimText('├');\n // For top-level command, pad name to fixed width (accounting for \"│ ├─ \" = 5 chars)\n const treePrefix = `${prefix}─ `;\n const treePrefixWidth = stringWidth(stripAnsi(treePrefix));\n const remainingWidth = LEFT_COLUMN_WIDTH - treePrefixWidth;\n const commandNamePadded = padToFixedWidth(cmd.name(), remainingWidth);\n const commandNameColored = useColor ? cyan(commandNamePadded) : commandNamePadded;\n lines.push(`${formatDimText('│')} ${treePrefix}${commandNameColored}`);\n\n for (let j = 0; j < subcommands.length; j++) {\n const subcmd = subcommands[j];\n if (!subcmd) continue;\n\n const isLastSubcommand = j === subcommands.length - 1;\n const shortDescription = subcmd.description() || '';\n\n // Use tree characters: └─ for last subcommand, ├─ for others\n const treeChar = isLastSubcommand ? '└' : '├';\n const continuation =\n continuationPrefix ??\n (isLastCommand && isLastSubcommand && !hasItemsAfter ? ' ' : formatDimText('│'));\n // For subcommands, account for \"│ │ └─ \" = 7 chars (or \"│ └─ \" = 6 chars if continuation is space)\n const continuationStr = continuation === ' ' ? ' ' : continuation;\n const subTreePrefix = `${continuationStr} ${formatDimText(treeChar)}─ `;\n const subTreePrefixWidth = stringWidth(stripAnsi(subTreePrefix));\n const subRemainingWidth = LEFT_COLUMN_WIDTH - subTreePrefixWidth;\n const subcommandNamePadded = padToFixedWidth(subcmd.name(), subRemainingWidth);\n const subcommandNameColored = useColor ? cyan(subcommandNamePadded) : subcommandNamePadded;\n lines.push(\n `${formatDimText('│')} ${subTreePrefix}${subcommandNameColored} ${shortDescription}`,\n );\n }\n } else {\n // Standalone command - show command name and description on same line\n const prefix = isLastCommand && !hasItemsAfter ? formatDimText('└') : formatDimText('├');\n const treePrefix = `${prefix}─ `;\n const treePrefixWidth = stringWidth(stripAnsi(treePrefix));\n const remainingWidth = LEFT_COLUMN_WIDTH - treePrefixWidth;\n const commandNamePadded = padToFixedWidth(cmd.name(), remainingWidth);\n const commandNameColored = useColor ? cyan(commandNamePadded) : commandNamePadded;\n const shortDescription = cmd.description() || '';\n lines.push(`${formatDimText('│')} ${treePrefix}${commandNameColored} ${shortDescription}`);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats multiline description with \"Prisma Next\" in green.\n * Wraps at the same right-hand boundary as the right column.\n * The right edge is defined by: left column (20) + gap (2) + right column (90) = 112 characters total.\n * Since the description line starts with \"│ \" (2 chars), the text wraps at 112 - 2 = 110 characters.\n */\nfunction formatMultilineDescription(options: {\n readonly descriptionLines: readonly string[];\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n}): string[] {\n const lines: string[] = [];\n const formatGreen = (text: string) => (options.useColor ? green(text) : text);\n\n // Calculate wrap width to align with right edge of right column\n // Format: \"│ \" (2) + left column (20) + \" \" (2) + right column = total\n // Description line has \"│ \" prefix (2 chars), so text wraps at total - 2\n const rightColumnWidth = calculateRightColumnWidth();\n const totalWidth = 2 + LEFT_COLUMN_WIDTH + 2 + rightColumnWidth;\n const wrapWidth = totalWidth - 2; // Subtract \"│ \" prefix\n\n for (const descLine of options.descriptionLines) {\n // Replace \"Prisma Next\" with green version if present\n const formattedLine = descLine.replace(/Prisma Next/g, (match) => formatGreen(match));\n\n // Wrap the line at the same right edge as the right column\n const wrappedLines = wrapTextAnsi(formattedLine, wrapWidth);\n for (const wrappedLine of wrappedLines) {\n lines.push(`${options.formatDimText('│')} ${wrappedLine}`);\n }\n }\n return lines;\n}\n\n/**\n * Formats the header in the new experimental visual style.\n * This header appears at the start of command output, showing the operation,\n * intent, documentation link, and parameters.\n */\nexport function formatStyledHeader(options: {\n readonly command: string;\n readonly description: string;\n readonly url?: string;\n readonly details: ReadonlyArray<{ readonly label: string; readonly value: string }>;\n readonly flags: GlobalFlags;\n}): string {\n const lines: string[] = [];\n const useColor = options.flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Header: arrow + operation badge + intent\n const brand = createPrismaNextBadge(useColor);\n // Use full command path (e.g., \"contract emit\" not just \"emit\")\n const operation = useColor ? bold(options.command) : options.command;\n const intent = formatDimText(options.description);\n lines.push(formatHeaderLine({ brand, operation, intent }));\n lines.push(formatDimText('│')); // Vertical line separator between command and params\n\n // Format details using fixed left column width (same style as help text options)\n for (const detail of options.details) {\n // Add colon to label, then pad to fixed width using padToFixedWidth for ANSI-aware padding\n const labelWithColon = `${detail.label}:`;\n const labelPadded = padToFixedWidth(labelWithColon, LEFT_COLUMN_WIDTH);\n const labelColored = useColor ? cyan(labelPadded) : labelPadded;\n lines.push(`${formatDimText('│')} ${labelColored} ${detail.value}`);\n }\n\n // Add \"Read more\" URL if present (same style as help text)\n if (options.url) {\n lines.push(formatDimText('│')); // Separator line before \"Read more\"\n lines.push(\n formatReadMoreLine({\n url: options.url,\n maxLabelWidth: LEFT_COLUMN_WIDTH,\n useColor,\n formatDimText,\n }),\n );\n }\n\n lines.push(formatDimText('└'));\n\n return `${lines.join('\\n')}\\n`;\n}\n\n/**\n * Formats a success message in the styled output format.\n */\nexport function formatSuccessMessage(flags: GlobalFlags): string {\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n return `${formatGreen('✔')} Success`;\n}\n\n// ============================================================================\n// Help Output Formatters\n// ============================================================================\n\n/**\n * Maps command paths to their documentation URLs.\n */\nfunction getCommandDocsUrl(commandPath: string): string | undefined {\n const docsMap: Record<string, string> = {\n 'contract emit': 'https://pris.ly/contract-emit',\n 'db verify': 'https://pris.ly/db-verify',\n };\n return docsMap[commandPath];\n}\n\n/**\n * Builds the full command path from a command and its parents.\n */\nfunction buildCommandPath(command: Command): string {\n const parts: string[] = [];\n let current: Command | undefined = command;\n while (current && current.name() !== 'prisma-next') {\n parts.unshift(current.name());\n current = current.parent ?? undefined;\n }\n return parts.join(' ');\n}\n\n/**\n * Formats help output for a command using the styled format.\n */\nexport function formatCommandHelp(options: {\n readonly command: Command;\n readonly flags: GlobalFlags;\n}): string {\n const { command, flags } = options;\n const lines: string[] = [];\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Build full command path (e.g., \"db verify\")\n const commandPath = buildCommandPath(command);\n const shortDescription = command.description() || '';\n const longDescription = getLongDescription(command);\n\n // Header: \"prisma-next <full-command-path> <short-description>\"\n const brand = createPrismaNextBadge(useColor);\n const operation = useColor ? bold(commandPath) : commandPath;\n const intent = formatDimText(shortDescription);\n lines.push(formatHeaderLine({ brand, operation, intent }));\n lines.push(formatDimText('│')); // Vertical line separator between command and params\n\n // Extract options and format them\n const optionsList = command.options.map((opt) => {\n const flags = opt.flags;\n const description = opt.description || '';\n // Commander.js stores default value in defaultValue property\n const defaultValue = (opt as { defaultValue?: unknown }).defaultValue;\n return { flags, description, defaultValue };\n });\n\n // Extract subcommands if any\n const subcommands = command.commands.filter((cmd) => !cmd.name().startsWith('_'));\n\n // Format subcommands as a tree if present\n if (subcommands.length > 0) {\n const hasItemsAfter = optionsList.length > 0;\n const treeLines = renderCommandTree({\n commands: subcommands,\n useColor,\n formatDimText,\n hasItemsAfter,\n });\n lines.push(...treeLines);\n }\n\n // Add separator between subcommands and options if both exist\n if (subcommands.length > 0 && optionsList.length > 0) {\n lines.push(formatDimText('│'));\n }\n\n // Format options with fixed width, wrapping, and default values\n if (optionsList.length > 0) {\n for (const opt of optionsList) {\n // Format flag with fixed 30-char width\n const flagsPadded = padToFixedWidth(opt.flags, LEFT_COLUMN_WIDTH);\n let flagsColored = flagsPadded;\n if (useColor) {\n // Color placeholders in magenta, then wrap in cyan\n flagsColored = flagsPadded.replace(/(<[^>]+>)/g, (match: string) => magenta(match));\n flagsColored = cyan(flagsColored);\n }\n\n // Wrap description based on terminal width\n const rightColumnWidth = calculateRightColumnWidth();\n const wrappedDescription = wrapTextAnsi(opt.description, rightColumnWidth);\n\n // First line: flag + first line of description\n lines.push(`${formatDimText('│')} ${flagsColored} ${wrappedDescription[0] || ''}`);\n\n // Continuation lines: empty label (30 spaces) + wrapped lines\n for (let i = 1; i < wrappedDescription.length; i++) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${wrappedDescription[i] || ''}`);\n }\n\n // Default value line (if present)\n if (opt.defaultValue !== undefined) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n const defaultText = formatDefaultValue(opt.defaultValue, useColor);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${defaultText}`);\n }\n }\n }\n\n // Add docs URL if available (with separator line before it)\n const docsUrl = getCommandDocsUrl(commandPath);\n if (docsUrl) {\n lines.push(formatDimText('│')); // Separator line between params and docs\n lines.push(\n formatReadMoreLine({\n url: docsUrl,\n maxLabelWidth: LEFT_COLUMN_WIDTH,\n useColor,\n formatDimText,\n }),\n );\n }\n\n // Multi-line description (if present) - shown after all other content\n if (longDescription) {\n lines.push(formatDimText('│'));\n const descriptionLines = longDescription.split('\\n').filter((line) => line.trim().length > 0);\n lines.push(...formatMultilineDescription({ descriptionLines, useColor, formatDimText }));\n }\n\n lines.push(formatDimText('└'));\n\n return `${lines.join('\\n')}\\n`;\n}\n\n/**\n * Formats help output for the root program using the styled format.\n */\nexport function formatRootHelp(options: {\n readonly program: Command;\n readonly flags: GlobalFlags;\n}): string {\n const { program, flags } = options;\n const lines: string[] = [];\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Header: \"prisma-next → Manage your data layer\"\n const brand = createPrismaNextBadge(useColor);\n const shortDescription = 'Manage your data layer';\n const intent = formatDimText(shortDescription);\n lines.push(formatHeaderLine({ brand, operation: '', intent }));\n lines.push(formatDimText('│')); // Vertical line separator after header\n\n // Extract top-level commands (exclude hidden commands starting with '_' and the 'help' command)\n const topLevelCommands = program.commands.filter(\n (cmd) => !cmd.name().startsWith('_') && cmd.name() !== 'help',\n );\n\n // Extract global options (needed to determine if last command)\n const globalOptions = program.options.map((opt) => {\n const flags = opt.flags;\n const description = opt.description || '';\n // Commander.js stores default value in defaultValue property\n const defaultValue = (opt as { defaultValue?: unknown }).defaultValue;\n return { flags, description, defaultValue };\n });\n\n // Build command tree\n if (topLevelCommands.length > 0) {\n const hasItemsAfter = globalOptions.length > 0;\n const treeLines = renderCommandTree({\n commands: topLevelCommands,\n useColor,\n formatDimText,\n hasItemsAfter,\n });\n lines.push(...treeLines);\n }\n\n // Add separator between commands and options if both exist\n if (topLevelCommands.length > 0 && globalOptions.length > 0) {\n lines.push(formatDimText('│'));\n }\n\n // Format global options with fixed width, wrapping, and default values\n if (globalOptions.length > 0) {\n for (const opt of globalOptions) {\n // Format flag with fixed 30-char width\n const flagsPadded = padToFixedWidth(opt.flags, LEFT_COLUMN_WIDTH);\n let flagsColored = flagsPadded;\n if (useColor) {\n // Color placeholders in magenta, then wrap in cyan\n flagsColored = flagsPadded.replace(/(<[^>]+>)/g, (match: string) => magenta(match));\n flagsColored = cyan(flagsColored);\n }\n\n // Wrap description based on terminal width\n const rightColumnWidth = calculateRightColumnWidth();\n const wrappedDescription = wrapTextAnsi(opt.description, rightColumnWidth);\n\n // First line: flag + first line of description\n lines.push(`${formatDimText('│')} ${flagsColored} ${wrappedDescription[0] || ''}`);\n\n // Continuation lines: empty label (30 spaces) + wrapped lines\n for (let i = 1; i < wrappedDescription.length; i++) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${wrappedDescription[i] || ''}`);\n }\n\n // Default value line (if present)\n if (opt.defaultValue !== undefined) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n const defaultText = formatDefaultValue(opt.defaultValue, useColor);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${defaultText}`);\n }\n }\n }\n\n // Multi-line description (white, not dimmed, with \"Prisma Next\" in green) - shown at bottom\n const formatGreen = (text: string) => (useColor ? green(text) : text);\n const descriptionLines = [\n `Use ${formatGreen('Prisma Next')} to define your data layer as a contract. Sign your database and application with the same contract to guarantee compatibility. Plan and apply migrations to safely evolve your schema.`,\n ];\n if (descriptionLines.length > 0) {\n lines.push(formatDimText('│')); // Separator line before description\n lines.push(...formatMultilineDescription({ descriptionLines, useColor, formatDimText }));\n }\n\n lines.push(formatDimText('└'));\n\n return `${lines.join('\\n')}\\n`;\n}\n","import ora from 'ora';\nimport type { ControlProgressEvent, OnControlProgress } from '../control-api/types.ts';\nimport type { GlobalFlags } from './global-flags.ts';\n\n/**\n * Options for creating a progress adapter.\n */\ninterface ProgressAdapterOptions {\n /**\n * Global flags that control progress output behavior (quiet, json, color).\n */\n readonly flags: GlobalFlags;\n}\n\n/**\n * State for tracking active spans in the progress adapter.\n */\ninterface SpanState {\n readonly spinner: ReturnType<typeof ora>;\n readonly startTime: number;\n}\n\n/**\n * Creates a progress adapter that converts control-api progress events\n * into CLI spinner/progress output.\n *\n * The adapter:\n * - Starts/succeeds spinners for top-level span boundaries\n * - Prints per-operation lines for nested spans (e.g., migration operations under 'apply')\n * - Respects quiet/json/non-TTY flags (no-op in those cases)\n *\n * @param options - Progress adapter configuration\n * @returns An onProgress callback compatible with control-api operations\n */\nexport function createProgressAdapter(options: ProgressAdapterOptions): OnControlProgress {\n const { flags } = options;\n\n // Skip progress if quiet, JSON output, or non-TTY\n const shouldShowProgress = !flags.quiet && flags.json !== 'object' && process.stdout.isTTY;\n\n if (!shouldShowProgress) {\n // Return a no-op callback\n return () => {\n // No-op\n };\n }\n\n // Track active spans by spanId\n const activeSpans = new Map<string, SpanState>();\n\n return (event: ControlProgressEvent) => {\n if (event.kind === 'spanStart') {\n // Nested spans (with parentSpanId) are printed as lines, not spinners\n if (event.parentSpanId) {\n console.log(` → ${event.label}...`);\n return;\n }\n\n // Top-level spans get a spinner\n const spinner = ora({\n text: event.label,\n color: flags.color !== false ? 'cyan' : false,\n }).start();\n\n activeSpans.set(event.spanId, {\n spinner,\n startTime: Date.now(),\n });\n } else if (event.kind === 'spanEnd') {\n // Complete the spinner for this span (only top-level spans have spinners)\n const spanState = activeSpans.get(event.spanId);\n if (spanState) {\n const elapsed = Date.now() - spanState.startTime;\n if (event.outcome === 'error') {\n spanState.spinner.fail(`${spanState.spinner.text} (failed)`);\n } else if (event.outcome === 'skipped') {\n spanState.spinner.info(`${spanState.spinner.text} (skipped)`);\n } else {\n spanState.spinner.succeed(`${spanState.spinner.text} (${elapsed}ms)`);\n }\n activeSpans.delete(event.spanId);\n }\n // Nested span ends are no-ops (could log completion if needed)\n }\n };\n}\n","import type { Result } from '@prisma-next/utils/result';\nimport type { CliStructuredError } from './cli-errors.ts';\nimport type { GlobalFlags } from './global-flags.ts';\nimport { formatErrorJson, formatErrorOutput } from './output.ts';\n\n/**\n * Processes a CLI command result, handling both success and error cases.\n * Formats output appropriately and returns the exit code.\n * Never throws - returns exit code for commands to use with process.exit().\n *\n * @param result - The result from a CLI command\n * @param flags - Global flags for output formatting\n * @param onSuccess - Optional callback for successful results (for custom success output)\n * @returns The exit code that should be used (0 for success, non-zero for errors)\n */\nexport function handleResult<T>(\n result: Result<T, CliStructuredError>,\n flags: GlobalFlags,\n onSuccess?: (value: T) => void,\n): number {\n if (result.ok) {\n // Success case\n if (onSuccess) {\n onSuccess(result.value);\n }\n return 0;\n }\n\n // Error case - convert to CLI envelope\n const envelope = result.failure.toEnvelope();\n\n // Output error based on flags\n if (flags.json) {\n // JSON error to stderr\n console.error(formatErrorJson(envelope));\n } else {\n // Human-readable error to stderr\n console.error(formatErrorOutput(envelope, flags));\n }\n\n // Infer exit code from error domain: CLI errors = 2, RTM errors = 1\n const exitCode = result.failure.domain === 'CLI' ? 2 : 1;\n return exitCode;\n}\n","import { mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, relative, resolve } from 'node:path';\nimport { errorContractConfigMissing } from '@prisma-next/core-control-plane/errors';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader.ts';\nimport { createControlClient } from '../control-api/client.ts';\nimport type { EmitContractSource, EmitFailure } from '../control-api/types.ts';\nimport { CliStructuredError, errorRuntime, errorUnexpected } from '../utils/cli-errors.ts';\nimport { setCommandDescriptions } from '../utils/command-helpers.ts';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags.ts';\nimport {\n type EmitContractResult,\n formatCommandHelp,\n formatEmitJson,\n formatEmitOutput,\n formatStyledHeader,\n formatSuccessMessage,\n} from '../utils/output.ts';\nimport { createProgressAdapter } from '../utils/progress-adapter.ts';\nimport { handleResult } from '../utils/result-handler.ts';\n\ninterface ContractEmitOptions {\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Maps an EmitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapEmitFailure(failure: EmitFailure): CliStructuredError {\n if (failure.code === 'CONTRACT_SOURCE_INVALID') {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Contract source is invalid',\n fix: 'Check your contract source configuration in prisma-next.config.ts',\n });\n }\n\n if (failure.code === 'EMIT_FAILED') {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Failed to emit contract',\n fix: 'Check your contract configuration and ensure the source is valid',\n });\n }\n\n // Exhaustive check - TypeScript will error if a new code is added but not handled\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled EmitFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the contract emit command and returns a structured Result.\n */\nasync function executeContractEmitCommand(\n options: ContractEmitOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<EmitContractResult, CliStructuredError>> {\n // Load config\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(options.config);\n } catch (error) {\n // Convert thrown CliStructuredError to Result\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to load config',\n }),\n );\n }\n\n // Resolve contract from config\n if (!config.contract) {\n return notOk(\n errorContractConfigMissing({\n why: 'Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ..., types: ... }',\n }),\n );\n }\n\n // Contract config is already normalized by defineConfig() with defaults applied\n const contractConfig = config.contract;\n\n // Resolve artifact paths from config (already normalized by defineConfig() with defaults)\n if (!contractConfig.output || !contractConfig.types) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config must have output and types paths. This should not happen if defineConfig() was used.',\n }),\n );\n }\n const outputJsonPath = resolve(contractConfig.output);\n const outputDtsPath = resolve(contractConfig.types);\n\n // Output header (only for human-readable output)\n if (flags.json !== 'object' && !flags.quiet) {\n // Normalize config path for display (match contract path format - no ./ prefix)\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n // Convert absolute paths to relative paths for display\n const contractPath = relative(process.cwd(), outputJsonPath);\n const typesPath = relative(process.cwd(), outputDtsPath);\n const header = formatStyledHeader({\n command: 'contract emit',\n description: 'Write your contract to JSON and sign it',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'types', value: typesPath },\n ],\n flags,\n });\n console.log(header);\n }\n\n // Create control client (no driver needed for emit)\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n // Convert user config source to discriminated union\n // Type assertion is safe: we check typeof to determine if it's a function\n const source: EmitContractSource =\n typeof contractConfig.source === 'function'\n ? { kind: 'loader', load: contractConfig.source as () => unknown | Promise<unknown> }\n : { kind: 'value', value: contractConfig.source };\n\n // Call emit with progress callback\n const result = await client.emit({\n contractConfig: {\n source,\n output: outputJsonPath,\n types: outputDtsPath,\n },\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapEmitFailure(result.failure));\n }\n\n // Create directories if needed\n mkdirSync(dirname(outputJsonPath), { recursive: true });\n mkdirSync(dirname(outputDtsPath), { recursive: true });\n\n // Write the results to files\n writeFileSync(outputJsonPath, result.value.contractJson, 'utf-8');\n writeFileSync(outputDtsPath, result.value.contractDts, 'utf-8');\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n // Convert success result to CLI output format\n const emitResult: EmitContractResult = {\n coreHash: result.value.coreHash,\n profileHash: result.value.profileHash,\n outDir: dirname(outputJsonPath),\n files: {\n json: outputJsonPath,\n dts: outputDtsPath,\n },\n timings: { total: Date.now() - startTime },\n };\n\n return ok(emitResult);\n } catch (error) {\n // Use static type guard to work across module boundaries\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected('Unexpected error during contract emit', {\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createContractEmitCommand(): Command {\n const command = new Command('emit');\n setCommandDescriptions(\n command,\n 'Write your contract to JSON and sign it',\n 'Reads your contract source (TypeScript or Prisma schema) and emits contract.json and\\n' +\n 'contract.d.ts. The contract.json contains the canonical contract structure, and\\n' +\n 'contract.d.ts provides TypeScript types for type-safe query building.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object or ndjson)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n const result = await executeContractEmitCommand(options, flags, startTime);\n\n // Handle result - formats output and returns exit code\n const exitCode = handleResult(result, flags, (emitResult) => {\n // Output based on flags\n if (flags.json === 'object') {\n // JSON output to stdout\n console.log(formatEmitJson(emitResult));\n } else {\n // Human-readable output to stdout\n const output = formatEmitOutput(emitResult, flags);\n if (output) {\n console.log(output);\n }\n // Output success message\n if (!flags.quiet) {\n console.log(formatSuccessMessage(flags));\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader.ts';\nimport { createControlClient } from '../control-api/client.ts';\nimport type { DbInitFailure } from '../control-api/types.ts';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorMigrationPlanningFailed,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors.ts';\nimport { setCommandDescriptions } from '../utils/command-helpers.ts';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags.ts';\nimport {\n type DbInitResult,\n formatCommandHelp,\n formatDbInitApplyOutput,\n formatDbInitJson,\n formatDbInitPlanOutput,\n formatStyledHeader,\n} from '../utils/output.ts';\nimport { createProgressAdapter } from '../utils/progress-adapter.ts';\nimport { handleResult } from '../utils/result-handler.ts';\n\ninterface DbInitOptions {\n readonly db?: string;\n readonly config?: string;\n readonly plan?: boolean;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Maps a DbInitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapDbInitFailure(failure: DbInitFailure): CliStructuredError {\n if (failure.code === 'PLANNING_FAILED') {\n return errorMigrationPlanningFailed({ conflicts: failure.conflicts ?? [] });\n }\n\n if (failure.code === 'MARKER_ORIGIN_MISMATCH') {\n const mismatchParts: string[] = [];\n if (\n failure.marker?.coreHash !== failure.destination?.coreHash &&\n failure.marker?.coreHash &&\n failure.destination?.coreHash\n ) {\n mismatchParts.push(\n `coreHash (marker: ${failure.marker.coreHash}, destination: ${failure.destination.coreHash})`,\n );\n }\n if (\n failure.marker?.profileHash !== failure.destination?.profileHash &&\n failure.marker?.profileHash &&\n failure.destination?.profileHash\n ) {\n mismatchParts.push(\n `profileHash (marker: ${failure.marker.profileHash}, destination: ${failure.destination.profileHash})`,\n );\n }\n\n return errorRuntime(\n `Existing contract marker does not match plan destination.${mismatchParts.length > 0 ? ` Mismatch in ${mismatchParts.join(' and ')}.` : ''}`,\n {\n why: 'Database has an existing contract marker that does not match the target contract',\n fix: 'If bootstrapping, drop/reset the database then re-run `prisma-next db init`; otherwise reconcile schema/marker using your migration workflow',\n meta: {\n code: 'MARKER_ORIGIN_MISMATCH',\n ...(failure.marker?.coreHash ? { markerCoreHash: failure.marker.coreHash } : {}),\n ...(failure.destination?.coreHash\n ? { destinationCoreHash: failure.destination.coreHash }\n : {}),\n ...(failure.marker?.profileHash ? { markerProfileHash: failure.marker.profileHash } : {}),\n ...(failure.destination?.profileHash\n ? { destinationProfileHash: failure.destination.profileHash }\n : {}),\n },\n },\n );\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Fix the schema mismatch (db init is additive-only), or drop/reset the database and re-run `prisma-next db init`',\n meta: {\n code: 'RUNNER_FAILED',\n ...(failure.meta ?? {}),\n },\n });\n }\n\n // Exhaustive check - TypeScript will error if a new code is added but not handled\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled DbInitFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the db init command and returns a structured Result.\n */\nasync function executeDbInitCommand(\n options: DbInitOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<DbInitResult, CliStructuredError>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = config.contract?.output\n ? resolve(config.contract.output)\n : resolve('src/prisma/contract.json');\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: options.db });\n }\n if (options.plan) {\n details.push({ label: 'mode', value: 'plan (dry run)' });\n }\n const header = formatStyledHeader({\n command: 'db init',\n description: 'Bootstrap a database to match the current contract',\n url: 'https://pris.ly/db-init',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Load contract file\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db init (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db init' }));\n }\n\n // Check target supports migrations via the migrations capability\n if (!config.target.migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n // Call dbInit with connection and progress callback\n // Connection happens inside dbInit with a 'connect' progress span\n const result = await client.dbInit({\n contractIR: contractJson,\n mode: options.plan ? 'plan' : 'apply',\n connection: dbConnection,\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapDbInitFailure(result.failure));\n }\n\n // Convert success result to CLI output format\n const profileHash = result.value.marker?.profileHash;\n const dbInitResult: DbInitResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: config.target.targetId,\n destination: {\n coreHash: result.value.marker?.coreHash ?? '',\n ...(profileHash ? { profileHash } : {}),\n },\n operations: result.value.plan.operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n },\n ...(result.value.execution\n ? {\n execution: {\n operationsPlanned: result.value.execution.operationsPlanned,\n operationsExecuted: result.value.execution.operationsExecuted,\n },\n }\n : {}),\n ...(result.value.marker\n ? {\n marker: {\n coreHash: result.value.marker.coreHash,\n ...(result.value.marker.profileHash\n ? { profileHash: result.value.marker.profileHash }\n : {}),\n },\n }\n : {}),\n summary: result.value.summary,\n timings: { total: Date.now() - startTime },\n };\n\n return ok(dbInitResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n // Use static type guard to work across module boundaries\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db init: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbInitCommand(): Command {\n const command = new Command('init');\n setCommandDescriptions(\n command,\n 'Bootstrap a database to match the current contract and write the contract marker',\n 'Initializes a database to match your emitted contract using additive-only operations.\\n' +\n 'Creates any missing tables, columns, indexes, and constraints defined in your contract.\\n' +\n 'Leaves existing compatible structures in place, surfaces conflicts when destructive changes\\n' +\n 'would be required, and writes a contract marker to track the database state. Use --plan to\\n' +\n 'preview changes without applying.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--plan', 'Preview planned operations without applying', false)\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbInitOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db init',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbInitCommand(options, flags, startTime);\n\n const exitCode = handleResult(result, flags, (dbInitResult) => {\n if (flags.json === 'object') {\n console.log(formatDbInitJson(dbInitResult));\n } else {\n const output =\n dbInitResult.mode === 'plan'\n ? formatDbInitPlanOutput(dbInitResult, flags)\n : formatDbInitApplyOutput(dbInitResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n","import { relative, resolve } from 'node:path';\nimport type { CoreSchemaView } from '@prisma-next/core-control-plane/schema-view';\nimport type { IntrospectSchemaResult } from '@prisma-next/core-control-plane/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader.ts';\nimport { createControlClient } from '../control-api/client.ts';\nimport {\n CliStructuredError,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors.ts';\nimport { setCommandDescriptions } from '../utils/command-helpers.ts';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags.ts';\nimport {\n formatCommandHelp,\n formatIntrospectJson,\n formatIntrospectOutput,\n formatStyledHeader,\n} from '../utils/output.ts';\nimport { createProgressAdapter } from '../utils/progress-adapter.ts';\nimport { handleResult } from '../utils/result-handler.ts';\n\ninterface DbIntrospectOptions {\n readonly db?: string;\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\ninterface DbIntrospectCommandResult {\n readonly introspectResult: IntrospectSchemaResult<unknown>;\n readonly schemaView: CoreSchemaView | undefined;\n}\n\n/**\n * Executes the db introspect command and returns a structured Result.\n */\nasync function executeDbIntrospectCommand(\n options: DbIntrospectOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<DbIntrospectCommandResult, CliStructuredError>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n ];\n if (options.db) {\n // Mask password in URL for security\n const maskedUrl = options.db.replace(/:([^:@]+)@/, ':****@');\n details.push({ label: 'database', value: maskedUrl });\n } else if (config.db?.connection && typeof config.db.connection === 'string') {\n // Mask password in URL for security\n const maskedUrl = config.db.connection.replace(/:([^:@]+)@/, ':****@');\n details.push({ label: 'database', value: maskedUrl });\n }\n const header = formatStyledHeader({\n command: 'db introspect',\n description: 'Inspect the database schema',\n url: 'https://pris.ly/db-introspect',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db introspect (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db introspect' }));\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n // Introspect with connection and progress\n const schemaIR = await client.introspect({\n connection: dbConnection,\n onProgress,\n });\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n // Call toSchemaView to convert schema IR to CoreSchemaView for tree rendering\n const schemaView = client.toSchemaView(schemaIR);\n\n const totalTime = Date.now() - startTime;\n\n // Get masked connection URL for meta (only for string connections)\n const connectionForMeta =\n typeof dbConnection === 'string' ? dbConnection.replace(/:([^:@]+)@/, ':****@') : undefined;\n\n const introspectResult: IntrospectSchemaResult<unknown> = {\n ok: true,\n summary: 'Schema introspected successfully',\n target: {\n familyId: config.family.familyId,\n id: config.target.targetId,\n },\n schema: schemaIR,\n meta: {\n ...(configPath ? { configPath } : {}),\n ...(connectionForMeta ? { dbUrl: connectionForMeta } : {}),\n },\n timings: {\n total: totalTime,\n },\n };\n\n return ok({ introspectResult, schemaView });\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db introspect: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbIntrospectCommand(): Command {\n const command = new Command('introspect');\n setCommandDescriptions(\n command,\n 'Inspect the database schema',\n 'Reads the live database schema and displays it as a tree structure. This command\\n' +\n 'does not check the schema against your contract - it only shows what exists in\\n' +\n 'the database. Use `db verify` or `db schema-verify` to compare against your contract.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbIntrospectOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db introspect',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbIntrospectCommand(options, flags, startTime);\n\n // Handle result - formats output and returns exit code\n const exitCode = handleResult(result, flags, (value) => {\n const { introspectResult, schemaView } = value;\n if (flags.json === 'object') {\n console.log(formatIntrospectJson(introspectResult));\n } else {\n const output = formatIntrospectOutput(introspectResult, schemaView, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport type { VerifyDatabaseSchemaResult } from '@prisma-next/core-control-plane/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader.ts';\nimport { createControlClient } from '../control-api/client.ts';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors.ts';\nimport { setCommandDescriptions } from '../utils/command-helpers.ts';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags.ts';\nimport {\n formatCommandHelp,\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatStyledHeader,\n} from '../utils/output.ts';\nimport { createProgressAdapter } from '../utils/progress-adapter.ts';\nimport { handleResult } from '../utils/result-handler.ts';\n\ninterface DbSchemaVerifyOptions {\n readonly db?: string;\n readonly config?: string;\n readonly json?: string | boolean;\n readonly strict?: boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Executes the db schema-verify command and returns a structured Result.\n */\nasync function executeDbSchemaVerifyCommand(\n options: DbSchemaVerifyOptions,\n flags: GlobalFlags,\n): Promise<Result<VerifyDatabaseSchemaResult, CliStructuredError>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = config.contract?.output\n ? resolve(config.contract.output)\n : resolve('src/prisma/contract.json');\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: options.db });\n }\n const header = formatStyledHeader({\n command: 'db schema-verify',\n description: 'Check whether the database schema satisfies your contract',\n url: 'https://pris.ly/db-schema-verify',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Load contract file\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db schema-verify (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db schema-verify' }));\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n const schemaVerifyResult = await client.schemaVerify({\n contractIR: contractJson,\n strict: options.strict ?? false,\n connection: dbConnection,\n onProgress,\n });\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n return ok(schemaVerifyResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db schema-verify: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbSchemaVerifyCommand(): Command {\n const command = new Command('schema-verify');\n setCommandDescriptions(\n command,\n 'Check whether the database schema satisfies your contract',\n 'Verifies that your database schema satisfies the emitted contract. Compares table structures,\\n' +\n 'column types, constraints, and extensions. Reports any mismatches via a contract-shaped\\n' +\n 'verification tree. This is a read-only operation that does not modify the database.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('--strict', 'Strict mode: extra schema elements cause failures', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbSchemaVerifyOptions) => {\n const flags = parseGlobalFlags(options);\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db schema-verify',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbSchemaVerifyCommand(options, flags);\n\n // Handle result - formats output and returns exit code\n const exitCode = handleResult(result, flags, (schemaVerifyResult) => {\n if (flags.json === 'object') {\n console.log(formatSchemaVerifyJson(schemaVerifyResult));\n } else {\n const output = formatSchemaVerifyOutput(schemaVerifyResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n\n // For logical schema mismatches, check if verification passed\n // Infra errors already handled by handleResult (returns non-zero exit code)\n if (result.ok && !result.value.ok) {\n // Schema verification failed - exit with code 1\n process.exit(1);\n } else {\n // Success or infra error - use exit code from handleResult\n process.exit(exitCode);\n }\n });\n\n return command;\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport type {\n SignDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/core-control-plane/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader.ts';\nimport { createControlClient } from '../control-api/client.ts';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors.ts';\nimport { setCommandDescriptions } from '../utils/command-helpers.ts';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags.ts';\nimport {\n formatCommandHelp,\n formatSchemaVerifyJson,\n formatSchemaVerifyOutput,\n formatSignJson,\n formatSignOutput,\n formatStyledHeader,\n} from '../utils/output.ts';\nimport { createProgressAdapter } from '../utils/progress-adapter.ts';\nimport { handleResult } from '../utils/result-handler.ts';\n\ninterface DbSignOptions {\n readonly db?: string;\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Failure type for db sign command.\n * Either an infrastructure error (CliStructuredError) or a logical failure (schema verification failed).\n */\ntype DbSignFailure = CliStructuredError | VerifyDatabaseSchemaResult;\n\n/**\n * Executes the db sign command and returns a structured Result.\n * Success: SignDatabaseResult (sign happened)\n * Failure: CliStructuredError (infra error) or VerifyDatabaseSchemaResult (schema mismatch)\n */\nasync function executeDbSignCommand(\n options: DbSignOptions,\n flags: GlobalFlags,\n): Promise<Result<SignDatabaseResult, DbSignFailure>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = config.contract?.output\n ? resolve(config.contract.output)\n : resolve('src/prisma/contract.json');\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: options.db });\n }\n const header = formatStyledHeader({\n command: 'db sign',\n description: 'Sign the database with your contract so you can safely run queries',\n url: 'https://pris.ly/db-sign',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Load contract file\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db sign (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db sign' }));\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n // Step 1: Schema verification - connect here\n const schemaVerifyResult = await client.schemaVerify({\n contractIR: contractJson,\n strict: false,\n connection: dbConnection,\n onProgress,\n });\n\n // If schema verification failed, return as failure\n if (!schemaVerifyResult.ok) {\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n return notOk(schemaVerifyResult);\n }\n\n // Step 2: Sign (already connected from schemaVerify)\n const signResult = await client.sign({\n contractIR: contractJson,\n contractPath,\n configPath,\n onProgress,\n });\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n return ok(signResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db sign: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbSignCommand(): Command {\n const command = new Command('sign');\n setCommandDescriptions(\n command,\n 'Sign the database with your contract so you can safely run queries',\n 'Verifies that your database schema satisfies the emitted contract, and if so, writes or\\n' +\n 'updates the contract marker in the database. This command is idempotent and safe to run\\n' +\n 'in CI/deployment pipelines. The marker records that this database instance is aligned\\n' +\n 'with a specific contract version.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbSignOptions) => {\n const flags = parseGlobalFlags(options);\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db sign',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbSignCommand(options, flags);\n\n if (result.ok) {\n // Success - format sign output\n if (flags.json === 'object') {\n console.log(formatSignJson(result.value));\n } else {\n const output = formatSignOutput(result.value, flags);\n if (output) {\n console.log(output);\n }\n }\n process.exit(0);\n }\n\n // Failure - determine type and handle appropriately\n const failure = result.failure;\n\n if (failure instanceof CliStructuredError) {\n // Infrastructure error - use standard handler\n const exitCode = handleResult(result as Result<never, CliStructuredError>, flags);\n process.exit(exitCode);\n }\n\n // Schema verification failed - format and print schema verification output\n if (flags.json === 'object') {\n console.log(formatSchemaVerifyJson(failure));\n } else {\n const output = formatSchemaVerifyOutput(failure, flags);\n if (output) {\n console.log(output);\n }\n }\n process.exit(1);\n });\n\n return command;\n}\n","import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport type { VerifyDatabaseResult } from '@prisma-next/core-control-plane/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader.ts';\nimport { createControlClient } from '../control-api/client.ts';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorHashMismatch,\n errorJsonFormatNotSupported,\n errorMarkerMissing,\n errorRuntime,\n errorTargetMismatch,\n errorUnexpected,\n} from '../utils/cli-errors.ts';\nimport { setCommandDescriptions } from '../utils/command-helpers.ts';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags.ts';\nimport {\n formatCommandHelp,\n formatStyledHeader,\n formatVerifyJson,\n formatVerifyOutput,\n} from '../utils/output.ts';\nimport { createProgressAdapter } from '../utils/progress-adapter.ts';\nimport { handleResult } from '../utils/result-handler.ts';\n\ninterface DbVerifyOptions {\n readonly db?: string;\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\n/**\n * Maps a VerifyDatabaseResult failure to a CliStructuredError.\n */\nfunction mapVerifyFailure(verifyResult: VerifyDatabaseResult): CliStructuredError {\n if (!verifyResult.ok && verifyResult.code) {\n if (verifyResult.code === 'PN-RTM-3001') {\n return errorMarkerMissing();\n }\n if (verifyResult.code === 'PN-RTM-3002') {\n return errorHashMismatch({\n expected: verifyResult.contract.coreHash,\n ...(verifyResult.marker?.coreHash ? { actual: verifyResult.marker.coreHash } : {}),\n });\n }\n if (verifyResult.code === 'PN-RTM-3003') {\n return errorTargetMismatch(\n verifyResult.target.expected,\n verifyResult.target.actual ?? 'unknown',\n );\n }\n // Unknown code - fall through to runtime error\n }\n return errorRuntime(verifyResult.summary);\n}\n\n/**\n * Executes the db verify command and returns a structured Result.\n */\nasync function executeDbVerifyCommand(\n options: DbVerifyOptions,\n flags: GlobalFlags,\n): Promise<Result<VerifyDatabaseResult, CliStructuredError>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = config.contract?.output\n ? resolve(config.contract.output)\n : resolve('src/prisma/contract.json');\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n // Output header\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: options.db });\n }\n const header = formatStyledHeader({\n command: 'db verify',\n description: 'Check whether the database has been signed with your contract',\n url: 'https://pris.ly/db-verify',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Load contract file\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for db verify (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for db verify' }));\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ flags });\n\n try {\n const verifyResult = await client.verify({\n contractIR: contractJson,\n connection: dbConnection,\n onProgress,\n });\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n // If verification failed, map to CLI structured error\n if (!verifyResult.ok) {\n return notOk(mapVerifyFailure(verifyResult));\n }\n\n return ok(verifyResult);\n } catch (error) {\n // Driver already throws CliStructuredError for connection failures\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during db verify: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbVerifyCommand(): Command {\n const command = new Command('verify');\n setCommandDescriptions(\n command,\n 'Check whether the database has been signed with your contract',\n 'Verifies that your database schema matches the emitted contract. Checks table structures,\\n' +\n 'column types, constraints, and codec coverage. Reports any mismatches or missing codecs.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: DbVerifyOptions) => {\n const flags = parseGlobalFlags(options);\n\n // Validate JSON format option\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db verify',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbVerifyCommand(options, flags);\n\n const exitCode = handleResult(result, flags, (verifyResult) => {\n if (flags.json === 'object') {\n console.log(formatVerifyJson(verifyResult));\n } else {\n const output = formatVerifyOutput(verifyResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n","import { Command } from 'commander';\nimport { createContractEmitCommand } from './commands/contract-emit.ts';\nimport { createDbInitCommand } from './commands/db-init.ts';\nimport { createDbIntrospectCommand } from './commands/db-introspect.ts';\nimport { createDbSchemaVerifyCommand } from './commands/db-schema-verify.ts';\nimport { createDbSignCommand } from './commands/db-sign.ts';\nimport { createDbVerifyCommand } from './commands/db-verify.ts';\nimport { setCommandDescriptions } from './utils/command-helpers.ts';\nimport { parseGlobalFlags } from './utils/global-flags.ts';\nimport { formatCommandHelp, formatRootHelp } from './utils/output.ts';\n\nconst program = new Command();\n\nprogram.name('prisma-next').description('Prisma Next CLI').version('0.0.1');\n\n// Override version option description to match capitalization style\nconst versionOption = program.options.find((opt) => opt.flags.includes('--version'));\nif (versionOption) {\n versionOption.description = 'Output the version number';\n}\n\nprogram.configureOutput({\n writeErr: () => {\n // Suppress all default error output - we handle errors in exitOverride\n },\n writeOut: () => {\n // Suppress all default output - our custom formatters handle everything\n },\n});\n\n// Customize root help output to use our styled format\nconst rootHelpFormatter = (cmd: Command) => {\n const flags = parseGlobalFlags({});\n return formatRootHelp({ program: cmd, flags });\n};\n\nprogram.configureHelp({\n formatHelp: rootHelpFormatter,\n subcommandDescription: () => '',\n});\n\n// Override exit to handle unhandled errors (fail fast cases)\n// Commands handle structured errors themselves via process.exit()\nprogram.exitOverride((err) => {\n if (err) {\n // Help requests are not errors - allow Commander to output help and exit normally\n // Commander throws errors with codes like 'commander.help', 'commander.helpDisplayed', or 'outputHelp'\n const errorCode = (err as { code?: string }).code;\n const errorMessage = String(err.message ?? '');\n const errorName = err.name ?? '';\n\n // Check for unknown command errors first (before other checks)\n // Commander.js uses code 'commander.unknownCommand' or error message contains 'unknown command'\n const isUnknownCommandError =\n errorCode === 'commander.unknownCommand' ||\n errorCode === 'commander.unknownArgument' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('unknown command') || errorMessage.includes('unknown argument')));\n if (isUnknownCommandError) {\n const flags = parseGlobalFlags({});\n // Extract the command/subcommand name from the error message\n // Error message format: \"unknown command 'command-name'\"\n const match = errorMessage.match(/unknown command ['\"]([^'\"]+)['\"]/);\n const commandName = match ? match[1] : process.argv[3] || process.argv[2] || 'unknown';\n\n // Determine which command context we're in\n // Check if the first argument is a recognized parent command\n const firstArg = process.argv[2];\n const parentCommand = firstArg\n ? program.commands.find((cmd) => cmd.name() === firstArg)\n : undefined;\n\n if (parentCommand && commandName !== firstArg) {\n // Unrecognized subcommand - show parent command help\n // eslint-disable-next-line no-console\n console.error(`Unknown command: ${commandName}`);\n // eslint-disable-next-line no-console\n console.error('');\n const helpText = formatCommandHelp({ command: parentCommand, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n } else {\n // Unrecognized top-level command - show root help\n // eslint-disable-next-line no-console\n console.error(`Unknown command: ${commandName}`);\n // eslint-disable-next-line no-console\n console.error('');\n const helpText = formatRootHelp({ program, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n }\n process.exit(1);\n return;\n }\n const isHelpError =\n errorCode === 'commander.help' ||\n errorCode === 'commander.helpDisplayed' ||\n errorCode === 'outputHelp' ||\n errorMessage === '(outputHelp)' ||\n errorMessage.includes('outputHelp') ||\n (errorName === 'CommanderError' && errorMessage.includes('outputHelp'));\n if (isHelpError) {\n process.exit(0);\n return;\n }\n // Missing required arguments/subcommands - show help and exit with 0\n // Commander throws errors with code 'commander.missingArgument' or 'commander.missingMandatoryOptionValue'\n // or when a command with subcommands is called without a subcommand\n const isMissingArgumentError =\n errorCode === 'commander.missingArgument' ||\n errorCode === 'commander.missingMandatoryOptionValue' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('missing') || errorMessage.includes('required')));\n if (isMissingArgumentError) {\n // Help was already displayed by Commander.js, just exit with 0\n process.exit(0);\n return;\n }\n // Unhandled error - fail fast with exit code 1\n // eslint-disable-next-line no-console\n console.error(`Unhandled error: ${err.message}`);\n if (err.stack) {\n // eslint-disable-next-line no-console\n console.error(err.stack);\n }\n process.exit(1);\n }\n process.exit(0);\n});\n\n// Register contract subcommand\nconst contractCommand = new Command('contract');\nsetCommandDescriptions(\n contractCommand,\n 'Contract management commands',\n 'Define and emit your application data contract. The contract describes your schema as a\\n' +\n 'declarative data structure that can be signed and verified against your database.',\n);\ncontractCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add emit subcommand to contract\nconst contractEmitCommand = createContractEmitCommand();\ncontractCommand.addCommand(contractEmitCommand);\n\n// Register contract command\nprogram.addCommand(contractCommand);\n\n// Register db subcommand\nconst dbCommand = new Command('db');\nsetCommandDescriptions(\n dbCommand,\n 'Database management commands',\n 'Verify and sign your database with your contract. Ensure your database schema matches\\n' +\n 'your contract, and sign it to record the contract hash for future verification.',\n);\ndbCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add verify subcommand to db\nconst dbVerifyCommand = createDbVerifyCommand();\ndbCommand.addCommand(dbVerifyCommand);\n\n// Add init subcommand to db\nconst dbInitCommand = createDbInitCommand();\ndbCommand.addCommand(dbInitCommand);\n\n// Add introspect subcommand to db\nconst dbIntrospectCommand = createDbIntrospectCommand();\ndbCommand.addCommand(dbIntrospectCommand);\n\n// Add schema-verify subcommand to db\nconst dbSchemaVerifyCommand = createDbSchemaVerifyCommand();\ndbCommand.addCommand(dbSchemaVerifyCommand);\n\n// Add sign subcommand to db\nconst dbSignCommand = createDbSignCommand();\ndbCommand.addCommand(dbSignCommand);\n\n// Register db command\nprogram.addCommand(dbCommand);\n\n// Create help command\nconst helpCommand = new Command('help')\n .description('Show usage instructions')\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n process.exit(0);\n });\n\nprogram.addCommand(helpCommand);\n\n// Set help as the default action when no command is provided\nprogram.action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n process.exit(0);\n});\n\n// Check if a command was invoked with no arguments (just the command name)\n// or if an unrecognized command was provided\nconst args = process.argv.slice(2);\nif (args.length > 0) {\n const commandName = args[0];\n // Handle version option explicitly since we suppress default output\n if (commandName === '--version' || commandName === '-V') {\n // eslint-disable-next-line no-console\n console.log(program.version());\n process.exit(0);\n }\n // Skip command check for global options like --help, -h\n const isGlobalOption = commandName === '--help' || commandName === '-h';\n if (!isGlobalOption) {\n // Check if this is a recognized command\n const command = program.commands.find((cmd) => cmd.name() === commandName);\n\n if (!command) {\n // Unrecognized command - show error message and usage\n const flags = parseGlobalFlags({});\n // eslint-disable-next-line no-console\n console.error(`Unknown command: ${commandName}`);\n // eslint-disable-next-line no-console\n console.error('');\n const helpText = formatRootHelp({ program, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n process.exit(1);\n } else if (command.commands.length > 0 && args.length === 1) {\n // Parent command called with no subcommand - show help and exit with 0\n const flags = parseGlobalFlags({});\n const helpText = formatCommandHelp({ command, flags });\n // eslint-disable-next-line no-console\n console.log(helpText);\n process.exit(0);\n }\n }\n}\n\nprogram.parse();\n"],"mappings":"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"}