@prisma-next/cli 0.3.0-dev.65 → 0.3.0-dev.67

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.mjs CHANGED
@@ -1,13 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import "./config-loader-PPf4CtDj.mjs";
4
- import "./cli-errors-JlPTsazx.mjs";
5
- import "./framework-components-CjV_jD8f.mjs";
6
- import "./client-PimzSD1f.mjs";
7
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, m as formatRootHelp, n as formatCommandHelp } from "./result-handler-iA9JtUC7.mjs";
8
- import "./progress-adapter-DENrzF6I.mjs";
9
5
  import { createContractEmitCommand } from "./commands/contract-emit.mjs";
10
- import "./migration-command-scaffold-DfY_F3ev.mjs";
11
6
  import { createDbInitCommand } from "./commands/db-init.mjs";
12
7
  import { createDbIntrospectCommand } from "./commands/db-introspect.mjs";
13
8
  import { createDbSchemaVerifyCommand } from "./commands/db-schema-verify.mjs";
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["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 { createDbUpdateCommand } from './commands/db-update';\nimport { createDbVerifyCommand } from './commands/db-verify';\nimport { createMigrationApplyCommand } from './commands/migration-apply';\nimport { createMigrationPlanCommand } from './commands/migration-plan';\nimport { createMigrationShowCommand } from './commands/migration-show';\nimport { createMigrationStatusCommand } from './commands/migration-status';\nimport { createMigrationVerifyCommand } from './commands/migration-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 update subcommand to db\nconst dbUpdateCommand = createDbUpdateCommand();\ndbCommand.addCommand(dbUpdateCommand);\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// Register migration subcommand\nconst migrationCommand = new Command('migration');\nsetCommandDescriptions(\n migrationCommand,\n 'On-disk migration management commands',\n 'Plan, apply, verify, and scaffold on-disk migration packages. Migrations are\\n' +\n 'contract-to-contract edges stored as versioned directories under migrations/.',\n);\nmigrationCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\nconst migrationPlanCommand = createMigrationPlanCommand();\nmigrationCommand.addCommand(migrationPlanCommand);\n\nconst migrationShowCommand = createMigrationShowCommand();\nmigrationCommand.addCommand(migrationShowCommand);\n\nconst migrationStatusCommand = createMigrationStatusCommand();\nmigrationCommand.addCommand(migrationStatusCommand);\n\nconst migrationVerifyCommand = createMigrationVerifyCommand();\nmigrationCommand.addCommand(migrationVerifyCommand);\n\nconst migrationApplyCommand = createMigrationApplyCommand();\nmigrationCommand.addCommand(migrationApplyCommand);\n\nprogram.addCommand(migrationCommand);\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.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["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 { createDbUpdateCommand } from './commands/db-update';\nimport { createDbVerifyCommand } from './commands/db-verify';\nimport { createMigrationApplyCommand } from './commands/migration-apply';\nimport { createMigrationPlanCommand } from './commands/migration-plan';\nimport { createMigrationShowCommand } from './commands/migration-show';\nimport { createMigrationStatusCommand } from './commands/migration-status';\nimport { createMigrationVerifyCommand } from './commands/migration-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 update subcommand to db\nconst dbUpdateCommand = createDbUpdateCommand();\ndbCommand.addCommand(dbUpdateCommand);\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// Register migration subcommand\nconst migrationCommand = new Command('migration');\nsetCommandDescriptions(\n migrationCommand,\n 'On-disk migration management commands',\n 'Plan, apply, verify, and scaffold on-disk migration packages. Migrations are\\n' +\n 'contract-to-contract edges stored as versioned directories under migrations/.',\n);\nmigrationCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\nconst migrationPlanCommand = createMigrationPlanCommand();\nmigrationCommand.addCommand(migrationPlanCommand);\n\nconst migrationShowCommand = createMigrationShowCommand();\nmigrationCommand.addCommand(migrationShowCommand);\n\nconst migrationStatusCommand = createMigrationStatusCommand();\nmigrationCommand.addCommand(migrationStatusCommand);\n\nconst migrationVerifyCommand = createMigrationVerifyCommand();\nmigrationCommand.addCommand(migrationVerifyCommand);\n\nconst migrationApplyCommand = createMigrationApplyCommand();\nmigrationCommand.addCommand(migrationApplyCommand);\n\nprogram.addCommand(migrationCommand);\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,6 +1,5 @@
1
1
  import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
2
  import { _ as errorUnexpected$1, i as errorContractValidationFailed, m as errorRuntime, t as CliStructuredError } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { t as createControlClient } from "../client-PimzSD1f.mjs";
5
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, b as formatSuccessMessage, i as formatEmitOutput, n as formatCommandHelp, r as formatEmitJson, t as handleResult, y as formatStyledHeader } from "../result-handler-iA9JtUC7.mjs";
6
5
  import { t as createProgressAdapter } from "../progress-adapter-DENrzF6I.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"contract-emit.mjs","names":["exhaustive: never","config: Awaited<ReturnType<typeof loadConfig>>","errorUnexpected"],"sources":["../../src/commands/contract-emit.ts"],"sourcesContent":["import { mkdirSync, writeFileSync } from 'node:fs';\nimport { errorContractConfigMissing } from '@prisma-next/core-control-plane/errors';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, isAbsolute, join, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type { EmitFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorRuntime,\n errorUnexpected,\n} 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\nfunction mapDiagnosticsToIssues(\n failure: EmitFailure,\n): ReadonlyArray<{ kind: string; message: string }> {\n const diagnostics = failure.diagnostics?.diagnostics ?? [];\n return diagnostics.map((diagnostic) => {\n const location =\n diagnostic.sourceId && diagnostic.span\n ? ` (${diagnostic.sourceId}:${diagnostic.span.start.line}:${diagnostic.span.start.column})`\n : diagnostic.sourceId\n ? ` (${diagnostic.sourceId})`\n : '';\n return {\n kind: diagnostic.code,\n message: `${diagnostic.message}${location}`,\n };\n });\n}\n\n/**\n * Maps an EmitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapEmitFailure(\n failure: EmitFailure,\n context?: { readonly configPath?: string },\n): CliStructuredError {\n if (failure.code === 'CONTRACT_SOURCE_INVALID') {\n const issues = mapDiagnosticsToIssues(failure);\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Contract source provider failed',\n fix: 'Check your contract source provider in prisma-next.config.ts and ensure it returns Result<ContractIR, Diagnostics>',\n ...(issues.length > 0 ? { meta: { issues } } : {}),\n });\n }\n\n if (failure.code === 'CONTRACT_VALIDATION_FAILED') {\n return errorContractValidationFailed(\n failure.why ?? 'Contract validation failed while emitting',\n context?.configPath ? { where: { path: context.configPath } } : undefined,\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 const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\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: ... }',\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) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config must have output path. This should not happen if defineConfig() was used.',\n }),\n );\n }\n if (!contractConfig.output.endsWith('.json')) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config output path must end with .json (e.g., \"src/prisma/contract.json\")',\n }),\n );\n }\n const configDir = options.config ? dirname(resolve(options.config)) : process.cwd();\n const outputJsonPath = isAbsolute(contractConfig.output)\n ? contractConfig.output\n : join(configDir, contractConfig.output);\n // Colocate .d.ts with .json (contract.json → contract.d.ts)\n const outputDtsPath = `${outputJsonPath.slice(0, -5)}.d.ts`;\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 // 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: 'Emit your contract artifacts',\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 // Call emit with progress callback\n const result = await client.emit({\n contractConfig: {\n sourceProvider: contractConfig.source,\n output: outputJsonPath,\n },\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapEmitFailure(result.failure, { configPath }));\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 storageHash: result.value.storageHash,\n ...(result.value.executionHash ? { executionHash: result.value.executionHash } : {}),\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 'Emit your contract artifacts',\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"],"mappings":";;;;;;;;;;;;;AAyCA,SAAS,uBACP,SACkD;AAElD,SADoB,QAAQ,aAAa,eAAe,EAAE,EACvC,KAAK,eAAe;EACrC,MAAM,WACJ,WAAW,YAAY,WAAW,OAC9B,KAAK,WAAW,SAAS,GAAG,WAAW,KAAK,MAAM,KAAK,GAAG,WAAW,KAAK,MAAM,OAAO,KACvF,WAAW,WACT,KAAK,WAAW,SAAS,KACzB;AACR,SAAO;GACL,MAAM,WAAW;GACjB,SAAS,GAAG,WAAW,UAAU;GAClC;GACD;;;;;AAMJ,SAAS,eACP,SACA,SACoB;AACpB,KAAI,QAAQ,SAAS,2BAA2B;EAC9C,MAAM,SAAS,uBAAuB,QAAQ;AAC9C,SAAO,aAAa,QAAQ,SAAS;GACnC,KAAK,QAAQ,OAAO;GACpB,KAAK;GACL,GAAI,OAAO,SAAS,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE;GAClD,CAAC;;AAGJ,KAAI,QAAQ,SAAS,6BACnB,QAAO,8BACL,QAAQ,OAAO,6CACf,SAAS,aAAa,EAAE,OAAO,EAAE,MAAM,QAAQ,YAAY,EAAE,GAAG,OACjE;AAGH,KAAI,QAAQ,SAAS,cACnB,QAAO,aAAa,QAAQ,SAAS;EACnC,KAAK,QAAQ,OAAO;EACpB,KAAK;EACN,CAAC;CAIJ,MAAMA,aAAoB,QAAQ;AAClC,OAAM,IAAI,MAAM,+BAA+B,aAAa;;;;;AAM9D,eAAe,2BACb,SACA,OACA,WACyD;CAEzD,IAAIC;AACJ,KAAI;AACF,WAAS,MAAM,WAAW,QAAQ,OAAO;UAClC,OAAO;AAEd,MAAI,iBAAiB,mBACnB,QAAO,MAAM,MAAM;AAErB,SAAO,MACLC,kBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,yBACN,CAAC,CACH;;CAGH,MAAM,aAAa,QAAQ,SACvB,SAAS,QAAQ,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC,GAChD;AAGJ,KAAI,CAAC,OAAO,SACV,QAAO,MACL,2BAA2B,EACzB,KAAK,0GACN,CAAC,CACH;CAIH,MAAM,iBAAiB,OAAO;AAG9B,KAAI,CAAC,eAAe,OAClB,QAAO,MACL,2BAA2B,EACzB,KAAK,6FACN,CAAC,CACH;AAEH,KAAI,CAAC,eAAe,OAAO,SAAS,QAAQ,CAC1C,QAAO,MACL,2BAA2B,EACzB,KAAK,wFACN,CAAC,CACH;CAEH,MAAM,YAAY,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,OAAO,CAAC,GAAG,QAAQ,KAAK;CACnF,MAAM,iBAAiB,WAAW,eAAe,OAAO,GACpD,eAAe,SACf,KAAK,WAAW,eAAe,OAAO;CAE1C,MAAM,gBAAgB,GAAG,eAAe,MAAM,GAAG,GAAG,CAAC;AAGrD,KAAI,MAAM,SAAS,YAAY,CAAC,MAAM,OAAO;EAG3C,MAAM,eAAe,SAAS,QAAQ,KAAK,EAAE,eAAe;EAC5D,MAAM,YAAY,SAAS,QAAQ,KAAK,EAAE,cAAc;EACxD,MAAM,SAAS,mBAAmB;GAChC,SAAS;GACT,aAAa;GACb,KAAK;GACL,SAAS;IACP;KAAE,OAAO;KAAU,OAAO;KAAY;IACtC;KAAE,OAAO;KAAY,OAAO;KAAc;IAC1C;KAAE,OAAO;KAAS,OAAO;KAAW;IACrC;GACD;GACD,CAAC;AACF,UAAQ,IAAI,OAAO;;CAIrB,MAAM,SAAS,oBAAoB;EACjC,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,gBAAgB,OAAO,kBAAkB,EAAE;EAC5C,CAAC;CAGF,MAAM,aAAa,sBAAsB,EAAE,OAAO,CAAC;AAEnD,KAAI;EAEF,MAAM,SAAS,MAAM,OAAO,KAAK;GAC/B,gBAAgB;IACd,gBAAgB,eAAe;IAC/B,QAAQ;IACT;GACD;GACD,CAAC;AAGF,MAAI,CAAC,OAAO,GACV,QAAO,MAAM,eAAe,OAAO,SAAS,EAAE,YAAY,CAAC,CAAC;AAI9D,YAAU,QAAQ,eAAe,EAAE,EAAE,WAAW,MAAM,CAAC;AACvD,YAAU,QAAQ,cAAc,EAAE,EAAE,WAAW,MAAM,CAAC;AAGtD,gBAAc,gBAAgB,OAAO,MAAM,cAAc,QAAQ;AACjE,gBAAc,eAAe,OAAO,MAAM,aAAa,QAAQ;AAG/D,MAAI,CAAC,MAAM,SAAS,MAAM,SAAS,YAAY,QAAQ,OAAO,MAC5D,SAAQ,IAAI,GAAG;AAgBjB,SAAO,GAZgC;GACrC,aAAa,OAAO,MAAM;GAC1B,GAAI,OAAO,MAAM,gBAAgB,EAAE,eAAe,OAAO,MAAM,eAAe,GAAG,EAAE;GACnF,aAAa,OAAO,MAAM;GAC1B,QAAQ,QAAQ,eAAe;GAC/B,OAAO;IACL,MAAM;IACN,KAAK;IACN;GACD,SAAS,EAAE,OAAO,KAAK,KAAK,GAAG,WAAW;GAC3C,CAEoB;UACd,OAAO;AAEd,MAAI,mBAAmB,GAAG,MAAM,CAC9B,QAAO,MAAM,MAAM;AAIrB,SAAO,MACLA,kBAAgB,yCAAyC,EACvD,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAC5D,CAAC,CACH;WACO;AACR,QAAM,OAAO,OAAO;;;AAIxB,SAAgB,4BAAqC;CACnD,MAAM,UAAU,IAAI,QAAQ,OAAO;AACnC,wBACE,SACA,gCACA,+OAGD;AACD,SACG,cAAc,EACb,aAAa,QAAQ;AAEnB,SAAO,kBAAkB;GAAE,SAAS;GAAK,OAD3B,iBAAiB,EAAE,CAAC;GACc,CAAC;IAEpD,CAAC,CACD,OAAO,mBAAmB,gCAAgC,CAC1D,OAAO,mBAAmB,qCAAqC,MAAM,CACrE,OAAO,eAAe,0BAA0B,CAChD,OAAO,iBAAiB,sCAAsC,CAC9D,OAAO,gBAAgB,6CAA6C,CACpE,OAAO,gBAAgB,2BAA2B,CAClD,OAAO,WAAW,qBAAqB,CACvC,OAAO,cAAc,uBAAuB,CAC5C,OAAO,OAAO,YAAiC;EAC9C,MAAM,QAAQ,iBAAiB,QAAQ;EAMvC,MAAM,WAAW,aAHF,MAAM,2BAA2B,SAAS,OAFvC,KAAK,KAAK,CAE8C,EAGpC,QAAQ,eAAe;AAE3D,OAAI,MAAM,SAAS,SAEjB,SAAQ,IAAI,eAAe,WAAW,CAAC;QAClC;IAEL,MAAM,SAAS,iBAAiB,YAAY,MAAM;AAClD,QAAI,OACF,SAAQ,IAAI,OAAO;AAGrB,QAAI,CAAC,MAAM,MACT,SAAQ,IAAI,qBAAqB,MAAM,CAAC;;IAG5C;AACF,UAAQ,KAAK,SAAS;GACtB;AAEJ,QAAO"}
1
+ {"version":3,"file":"contract-emit.mjs","names":["exhaustive: never","config: Awaited<ReturnType<typeof loadConfig>>","errorUnexpected"],"sources":["../../src/commands/contract-emit.ts"],"sourcesContent":["import { mkdirSync, writeFileSync } from 'node:fs';\nimport { errorContractConfigMissing } from '@prisma-next/core-control-plane/errors';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, isAbsolute, join, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type { EmitFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorRuntime,\n errorUnexpected,\n} 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\nfunction mapDiagnosticsToIssues(\n failure: EmitFailure,\n): ReadonlyArray<{ kind: string; message: string }> {\n const diagnostics = failure.diagnostics?.diagnostics ?? [];\n return diagnostics.map((diagnostic) => {\n const location =\n diagnostic.sourceId && diagnostic.span\n ? ` (${diagnostic.sourceId}:${diagnostic.span.start.line}:${diagnostic.span.start.column})`\n : diagnostic.sourceId\n ? ` (${diagnostic.sourceId})`\n : '';\n return {\n kind: diagnostic.code,\n message: `${diagnostic.message}${location}`,\n };\n });\n}\n\n/**\n * Maps an EmitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapEmitFailure(\n failure: EmitFailure,\n context?: { readonly configPath?: string },\n): CliStructuredError {\n if (failure.code === 'CONTRACT_SOURCE_INVALID') {\n const issues = mapDiagnosticsToIssues(failure);\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Contract source provider failed',\n fix: 'Check your contract source provider in prisma-next.config.ts and ensure it returns Result<ContractIR, Diagnostics>',\n ...(issues.length > 0 ? { meta: { issues } } : {}),\n });\n }\n\n if (failure.code === 'CONTRACT_VALIDATION_FAILED') {\n return errorContractValidationFailed(\n failure.why ?? 'Contract validation failed while emitting',\n context?.configPath ? { where: { path: context.configPath } } : undefined,\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 const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\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: ... }',\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) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config must have output path. This should not happen if defineConfig() was used.',\n }),\n );\n }\n if (!contractConfig.output.endsWith('.json')) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config output path must end with .json (e.g., \"src/prisma/contract.json\")',\n }),\n );\n }\n const configDir = options.config ? dirname(resolve(options.config)) : process.cwd();\n const outputJsonPath = isAbsolute(contractConfig.output)\n ? contractConfig.output\n : join(configDir, contractConfig.output);\n // Colocate .d.ts with .json (contract.json → contract.d.ts)\n const outputDtsPath = `${outputJsonPath.slice(0, -5)}.d.ts`;\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 // 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: 'Emit your contract artifacts',\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 // Call emit with progress callback\n const result = await client.emit({\n contractConfig: {\n sourceProvider: contractConfig.source,\n output: outputJsonPath,\n },\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapEmitFailure(result.failure, { configPath }));\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 storageHash: result.value.storageHash,\n ...(result.value.executionHash ? { executionHash: result.value.executionHash } : {}),\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 'Emit your contract artifacts',\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"],"mappings":"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"}
@@ -1,9 +1,7 @@
1
1
  import "../config-loader-PPf4CtDj.mjs";
2
2
  import { _ as errorUnexpected, f as errorMigrationPlanningFailed, i as errorContractValidationFailed, m as errorRuntime, p as errorRunnerFailed, t as CliStructuredError, u as errorJsonFormatNotSupported } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { n as ContractValidationError } from "../client-PimzSD1f.mjs";
5
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, E as sanitizeErrorMessage, c as formatMigrationApplyOutput, l as formatMigrationJson, n as formatCommandHelp, t as handleResult, u as formatMigrationPlanOutput } from "../result-handler-iA9JtUC7.mjs";
6
- import "../progress-adapter-DENrzF6I.mjs";
7
5
  import { n as prepareMigrationContext, t as addMigrationCommandOptions } from "../migration-command-scaffold-DfY_F3ev.mjs";
8
6
  import { Command } from "commander";
9
7
  import { notOk, ok } from "@prisma-next/utils/result";
@@ -1 +1 @@
1
- {"version":3,"file":"db-init.mjs","names":["mismatchParts: string[]","exhaustive: never","exitCode"],"sources":["../../src/commands/db-init.ts"],"sourcesContent":["import { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { ContractValidationError } from '../control-api/errors';\nimport type { DbInitFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorJsonFormatNotSupported,\n errorMigrationPlanningFailed,\n errorRunnerFailed,\n errorRuntime,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport type { MigrationCommandOptions } from '../utils/command-helpers';\nimport { sanitizeErrorMessage, setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n addMigrationCommandOptions,\n prepareMigrationContext,\n} from '../utils/migration-command-scaffold';\nimport {\n formatCommandHelp,\n formatMigrationApplyOutput,\n formatMigrationJson,\n formatMigrationPlanOutput,\n type MigrationCommandResult,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ntype DbInitOptions = MigrationCommandOptions;\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?.storageHash !== failure.destination?.storageHash &&\n failure.marker?.storageHash &&\n failure.destination?.storageHash\n ) {\n mismatchParts.push(\n `storageHash (marker: ${failure.marker.storageHash}, destination: ${failure.destination.storageHash})`,\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 database signature does not match plan destination.${mismatchParts.length > 0 ? ` Mismatch in ${mismatchParts.join(' and ')}.` : ''}`,\n {\n why: 'Database has an existing signature (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 ...ifDefined('markerStorageHash', failure.marker?.storageHash),\n ...ifDefined('destinationStorageHash', failure.destination?.storageHash),\n ...ifDefined('markerProfileHash', failure.marker?.profileHash),\n ...ifDefined('destinationProfileHash', failure.destination?.profileHash),\n },\n },\n );\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n return errorRunnerFailed(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 ...(failure.meta\n ? { meta: { code: 'RUNNER_FAILED', ...failure.meta } }\n : { meta: { code: 'RUNNER_FAILED' } }),\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<MigrationCommandResult, CliStructuredError>> {\n // Prepare shared migration context (config, contract, connection, client)\n const ctxResult = await prepareMigrationContext(options, flags, {\n commandName: 'db init',\n description: 'Bootstrap a database to match the current contract',\n url: 'https://pris.ly/db-init',\n });\n if (!ctxResult.ok) {\n return ctxResult;\n }\n const { client, contractJson, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;\n\n try {\n // Call dbInit with connection and progress callback\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 dbInitResult: MigrationCommandResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: ctxResult.value.config.target.targetId,\n destination: {\n storageHash: result.value.destination.storageHash,\n ...ifDefined('profileHash', result.value.destination.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 storageHash: result.value.marker.storageHash,\n ...ifDefined('profileHash', result.value.marker.profileHash),\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 if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n\n const rawMessage = error instanceof Error ? error.message : String(error);\n const safeMessage = sanitizeErrorMessage(\n rawMessage,\n typeof dbConnection === 'string' ? dbConnection : undefined,\n );\n return notOk(\n errorUnexpected(safeMessage, {\n why: `Unexpected error during db init: ${safeMessage}`,\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 sign it',\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 signs the database to track contract state. Use --plan to\\n' +\n 'preview changes without applying.',\n );\n addMigrationCommandOptions(command);\n command.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n });\n command.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(formatMigrationJson(dbInitResult));\n } else {\n const output =\n dbInitResult.mode === 'plan'\n ? formatMigrationPlanOutput(dbInitResult, flags)\n : formatMigrationApplyOutput(dbInitResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"db-init.mjs","names":["mismatchParts: string[]","exhaustive: never","exitCode"],"sources":["../../src/commands/db-init.ts"],"sourcesContent":["import { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { ContractValidationError } from '../control-api/errors';\nimport type { DbInitFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorJsonFormatNotSupported,\n errorMigrationPlanningFailed,\n errorRunnerFailed,\n errorRuntime,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport type { MigrationCommandOptions } from '../utils/command-helpers';\nimport { sanitizeErrorMessage, setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n addMigrationCommandOptions,\n prepareMigrationContext,\n} from '../utils/migration-command-scaffold';\nimport {\n formatCommandHelp,\n formatMigrationApplyOutput,\n formatMigrationJson,\n formatMigrationPlanOutput,\n type MigrationCommandResult,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ntype DbInitOptions = MigrationCommandOptions;\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?.storageHash !== failure.destination?.storageHash &&\n failure.marker?.storageHash &&\n failure.destination?.storageHash\n ) {\n mismatchParts.push(\n `storageHash (marker: ${failure.marker.storageHash}, destination: ${failure.destination.storageHash})`,\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 database signature does not match plan destination.${mismatchParts.length > 0 ? ` Mismatch in ${mismatchParts.join(' and ')}.` : ''}`,\n {\n why: 'Database has an existing signature (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 ...ifDefined('markerStorageHash', failure.marker?.storageHash),\n ...ifDefined('destinationStorageHash', failure.destination?.storageHash),\n ...ifDefined('markerProfileHash', failure.marker?.profileHash),\n ...ifDefined('destinationProfileHash', failure.destination?.profileHash),\n },\n },\n );\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n return errorRunnerFailed(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 ...(failure.meta\n ? { meta: { code: 'RUNNER_FAILED', ...failure.meta } }\n : { meta: { code: 'RUNNER_FAILED' } }),\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<MigrationCommandResult, CliStructuredError>> {\n // Prepare shared migration context (config, contract, connection, client)\n const ctxResult = await prepareMigrationContext(options, flags, {\n commandName: 'db init',\n description: 'Bootstrap a database to match the current contract',\n url: 'https://pris.ly/db-init',\n });\n if (!ctxResult.ok) {\n return ctxResult;\n }\n const { client, contractJson, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;\n\n try {\n // Call dbInit with connection and progress callback\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 dbInitResult: MigrationCommandResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: ctxResult.value.config.target.targetId,\n destination: {\n storageHash: result.value.destination.storageHash,\n ...ifDefined('profileHash', result.value.destination.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 storageHash: result.value.marker.storageHash,\n ...ifDefined('profileHash', result.value.marker.profileHash),\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 if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n\n const rawMessage = error instanceof Error ? error.message : String(error);\n const safeMessage = sanitizeErrorMessage(\n rawMessage,\n typeof dbConnection === 'string' ? dbConnection : undefined,\n );\n return notOk(\n errorUnexpected(safeMessage, {\n why: `Unexpected error during db init: ${safeMessage}`,\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 sign it',\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 signs the database to track contract state. Use --plan to\\n' +\n 'preview changes without applying.',\n );\n addMigrationCommandOptions(command);\n command.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n });\n command.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(formatMigrationJson(dbInitResult));\n } else {\n const output =\n dbInitResult.mode === 'plan'\n ? formatMigrationPlanOutput(dbInitResult, flags)\n : formatMigrationApplyOutput(dbInitResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
2
  import { _ as errorUnexpected, a as errorDatabaseConnectionRequired, s as errorDriverRequired, t as CliStructuredError, u as errorJsonFormatNotSupported } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { t as createControlClient } from "../client-PimzSD1f.mjs";
5
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, a as formatIntrospectJson, n as formatCommandHelp, o as formatIntrospectOutput, t as handleResult, w as maskConnectionUrl, y as formatStyledHeader } from "../result-handler-iA9JtUC7.mjs";
6
5
  import { t as createProgressAdapter } from "../progress-adapter-DENrzF6I.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"db-introspect.mjs","names":["details: Array<{ label: string; value: string }>","exitCode"],"sources":["../../src/commands/db-introspect.ts"],"sourcesContent":["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 { maskConnectionUrl, 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 details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n } else if (config.db?.connection && typeof config.db.connection === 'string') {\n details.push({ label: 'database', value: maskConnectionUrl(config.db.connection) });\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' ? maskConnectionUrl(dbConnection) : 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"],"mappings":"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"}
1
+ {"version":3,"file":"db-introspect.mjs","names":["details: Array<{ label: string; value: string }>","exitCode"],"sources":["../../src/commands/db-introspect.ts"],"sourcesContent":["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 { maskConnectionUrl, 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 details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n } else if (config.db?.connection && typeof config.db.connection === 'string') {\n details.push({ label: 'database', value: maskConnectionUrl(config.db.connection) });\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' ? maskConnectionUrl(dbConnection) : 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"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
2
  import { _ as errorUnexpected, a as errorDatabaseConnectionRequired, c as errorFileNotFound, i as errorContractValidationFailed, s as errorDriverRequired, t as CliStructuredError, u as errorJsonFormatNotSupported } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { n as ContractValidationError, t as createControlClient } from "../client-PimzSD1f.mjs";
5
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, T as resolveContractPath, g as formatSchemaVerifyOutput, h as formatSchemaVerifyJson, n as formatCommandHelp, t as handleResult, w as maskConnectionUrl, y as formatStyledHeader } from "../result-handler-iA9JtUC7.mjs";
6
5
  import { t as createProgressAdapter } from "../progress-adapter-DENrzF6I.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"db-schema-verify.mjs","names":["details: Array<{ label: string; value: string }>","contractJsonContent: string","contractJson: Record<string, unknown>","exitCode"],"sources":["../../src/commands/db-schema-verify.ts"],"sourcesContent":["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 { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} 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 = resolveContractPath(config);\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: maskConnectionUrl(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 if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\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"],"mappings":"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"}
1
+ {"version":3,"file":"db-schema-verify.mjs","names":["details: Array<{ label: string; value: string }>","contractJsonContent: string","contractJson: Record<string, unknown>","exitCode"],"sources":["../../src/commands/db-schema-verify.ts"],"sourcesContent":["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 { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} 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 = resolveContractPath(config);\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: maskConnectionUrl(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 if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\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"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
2
  import { _ as errorUnexpected, a as errorDatabaseConnectionRequired, c as errorFileNotFound, i as errorContractValidationFailed, s as errorDriverRequired, t as CliStructuredError, u as errorJsonFormatNotSupported } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { n as ContractValidationError, t as createControlClient } from "../client-PimzSD1f.mjs";
5
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, T as resolveContractPath, _ as formatSignJson, g as formatSchemaVerifyOutput, h as formatSchemaVerifyJson, n as formatCommandHelp, t as handleResult, v as formatSignOutput, w as maskConnectionUrl, y as formatStyledHeader } from "../result-handler-iA9JtUC7.mjs";
6
5
  import { t as createProgressAdapter } from "../progress-adapter-DENrzF6I.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"db-sign.mjs","names":["details: Array<{ label: string; value: string }>","contractJsonContent: string","contractJson: Record<string, unknown>"],"sources":["../../src/commands/db-sign.ts"],"sourcesContent":["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 { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} 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 = resolveContractPath(config);\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: maskConnectionUrl(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 if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\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 database signature. This command is idempotent and safe to run\\n' +\n 'in CI/deployment pipelines. The signature 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"],"mappings":"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"}
1
+ {"version":3,"file":"db-sign.mjs","names":["details: Array<{ label: string; value: string }>","contractJsonContent: string","contractJson: Record<string, unknown>"],"sources":["../../src/commands/db-sign.ts"],"sourcesContent":["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 { ContractValidationError } from '../control-api/errors';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorJsonFormatNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} 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 = resolveContractPath(config);\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: maskConnectionUrl(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 if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\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 database signature. This command is idempotent and safe to run\\n' +\n 'in CI/deployment pipelines. The signature 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"],"mappings":"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"}
@@ -1,9 +1,7 @@
1
1
  import "../config-loader-PPf4CtDj.mjs";
2
2
  import { _ as errorUnexpected, f as errorMigrationPlanningFailed, i as errorContractValidationFailed, o as errorDestructiveChanges, p as errorRunnerFailed, t as CliStructuredError, u as errorJsonFormatNotSupported } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { n as ContractValidationError } from "../client-PimzSD1f.mjs";
5
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, E as sanitizeErrorMessage, c as formatMigrationApplyOutput, l as formatMigrationJson, n as formatCommandHelp, t as handleResult, u as formatMigrationPlanOutput } from "../result-handler-iA9JtUC7.mjs";
6
- import "../progress-adapter-DENrzF6I.mjs";
7
5
  import { n as prepareMigrationContext, t as addMigrationCommandOptions } from "../migration-command-scaffold-DfY_F3ev.mjs";
8
6
  import { Command } from "commander";
9
7
  import { notOk, ok } from "@prisma-next/utils/result";
@@ -1 +1 @@
1
- {"version":3,"file":"db-update.mjs","names":["exhaustive: never","exitCode"],"sources":["../../src/commands/db-update.ts"],"sourcesContent":["import { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { ContractValidationError } from '../control-api/errors';\nimport type { DbUpdateFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDestructiveChanges,\n errorJsonFormatNotSupported,\n errorMigrationPlanningFailed,\n errorRunnerFailed,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport type { MigrationCommandOptions } from '../utils/command-helpers';\nimport { sanitizeErrorMessage, setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n addMigrationCommandOptions,\n prepareMigrationContext,\n} from '../utils/migration-command-scaffold';\nimport {\n formatCommandHelp,\n formatMigrationApplyOutput,\n formatMigrationJson,\n formatMigrationPlanOutput,\n type MigrationCommandResult,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ntype DbUpdateOptions = MigrationCommandOptions & {\n readonly acceptDataLoss?: boolean;\n};\n\n/**\n * Maps a DbUpdateFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapDbUpdateFailure(failure: DbUpdateFailure): CliStructuredError {\n if (failure.code === 'PLANNING_FAILED') {\n return errorMigrationPlanningFailed({ conflicts: failure.conflicts ?? [] });\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n return errorRunnerFailed(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Inspect the reported conflict, reconcile schema drift if needed, then re-run `prisma-next db update`',\n ...ifDefined('meta', failure.meta),\n });\n }\n\n if (failure.code === 'DESTRUCTIVE_CHANGES') {\n return errorDestructiveChanges(failure.summary, {\n ...ifDefined('why', failure.why),\n fix: 'Use `prisma-next db update --plan` to preview, then re-run with `--accept-data-loss` to apply destructive changes',\n ...ifDefined('meta', failure.meta),\n });\n }\n\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled DbUpdateFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the db update command and returns a structured Result.\n */\nasync function executeDbUpdateCommand(\n options: DbUpdateOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<MigrationCommandResult, CliStructuredError>> {\n // Prepare shared migration context (config, contract, connection, client)\n const ctxResult = await prepareMigrationContext(options, flags, {\n commandName: 'db update',\n description: 'Update your database schema to match your contract',\n url: 'https://pris.ly/db-update',\n });\n if (!ctxResult.ok) {\n return ctxResult;\n }\n const { client, contractJson, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;\n\n try {\n // Call dbUpdate with connection and progress callback\n const result = await client.dbUpdate({\n contractIR: contractJson,\n mode: options.plan ? 'plan' : 'apply',\n connection: dbConnection,\n ...(options.acceptDataLoss ? { acceptDataLoss: true } : {}),\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapDbUpdateFailure(result.failure));\n }\n\n // Convert success result to CLI output format\n const dbUpdateResult: MigrationCommandResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: ctxResult.value.config.target.targetId,\n destination: {\n storageHash: result.value.destination.storageHash,\n ...ifDefined('profileHash', result.value.destination.profileHash),\n },\n operations: result.value.plan.operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n ...ifDefined('sql', result.value.plan.sql),\n },\n ...ifDefined(\n 'execution',\n result.value.execution\n ? {\n operationsPlanned: result.value.execution.operationsPlanned,\n operationsExecuted: result.value.execution.operationsExecuted,\n }\n : undefined,\n ),\n ...ifDefined(\n 'marker',\n result.value.marker\n ? {\n storageHash: result.value.marker.storageHash,\n ...ifDefined('profileHash', result.value.marker.profileHash),\n }\n : undefined,\n ),\n summary: result.value.summary,\n timings: { total: Date.now() - startTime },\n };\n\n return ok(dbUpdateResult);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n\n const rawMessage = error instanceof Error ? error.message : String(error);\n const safeMessage = sanitizeErrorMessage(\n rawMessage,\n typeof dbConnection === 'string' ? dbConnection : undefined,\n );\n return notOk(\n errorUnexpected(safeMessage, {\n why: `Unexpected error during db update: ${safeMessage}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbUpdateCommand(): Command {\n const command = new Command('update');\n setCommandDescriptions(\n command,\n 'Update your database schema to match your contract',\n 'Compares your database schema to the emitted contract and applies the necessary\\n' +\n 'changes. Works on any database, whether or not it has been initialized with `db init`.\\n' +\n 'Use --plan to preview operations before applying.',\n );\n addMigrationCommandOptions(command);\n command.option(\n '--accept-data-loss',\n 'Confirm destructive operations (required when plan includes drops or type changes)',\n false,\n );\n command.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n });\n command.action(async (options: DbUpdateOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db update',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbUpdateCommand(options, flags, startTime);\n const exitCode = handleResult(result, flags, (dbUpdateResult) => {\n if (flags.json === 'object') {\n console.log(formatMigrationJson(dbUpdateResult));\n } else {\n const output =\n dbUpdateResult.mode === 'plan'\n ? formatMigrationPlanOutput(dbUpdateResult, flags)\n : formatMigrationApplyOutput(dbUpdateResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"db-update.mjs","names":["exhaustive: never","exitCode"],"sources":["../../src/commands/db-update.ts"],"sourcesContent":["import { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { ContractValidationError } from '../control-api/errors';\nimport type { DbUpdateFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorDestructiveChanges,\n errorJsonFormatNotSupported,\n errorMigrationPlanningFailed,\n errorRunnerFailed,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport type { MigrationCommandOptions } from '../utils/command-helpers';\nimport { sanitizeErrorMessage, setCommandDescriptions } from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n addMigrationCommandOptions,\n prepareMigrationContext,\n} from '../utils/migration-command-scaffold';\nimport {\n formatCommandHelp,\n formatMigrationApplyOutput,\n formatMigrationJson,\n formatMigrationPlanOutput,\n type MigrationCommandResult,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ntype DbUpdateOptions = MigrationCommandOptions & {\n readonly acceptDataLoss?: boolean;\n};\n\n/**\n * Maps a DbUpdateFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapDbUpdateFailure(failure: DbUpdateFailure): CliStructuredError {\n if (failure.code === 'PLANNING_FAILED') {\n return errorMigrationPlanningFailed({ conflicts: failure.conflicts ?? [] });\n }\n\n if (failure.code === 'RUNNER_FAILED') {\n return errorRunnerFailed(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Inspect the reported conflict, reconcile schema drift if needed, then re-run `prisma-next db update`',\n ...ifDefined('meta', failure.meta),\n });\n }\n\n if (failure.code === 'DESTRUCTIVE_CHANGES') {\n return errorDestructiveChanges(failure.summary, {\n ...ifDefined('why', failure.why),\n fix: 'Use `prisma-next db update --plan` to preview, then re-run with `--accept-data-loss` to apply destructive changes',\n ...ifDefined('meta', failure.meta),\n });\n }\n\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled DbUpdateFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the db update command and returns a structured Result.\n */\nasync function executeDbUpdateCommand(\n options: DbUpdateOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<MigrationCommandResult, CliStructuredError>> {\n // Prepare shared migration context (config, contract, connection, client)\n const ctxResult = await prepareMigrationContext(options, flags, {\n commandName: 'db update',\n description: 'Update your database schema to match your contract',\n url: 'https://pris.ly/db-update',\n });\n if (!ctxResult.ok) {\n return ctxResult;\n }\n const { client, contractJson, dbConnection, onProgress, contractPathAbsolute } = ctxResult.value;\n\n try {\n // Call dbUpdate with connection and progress callback\n const result = await client.dbUpdate({\n contractIR: contractJson,\n mode: options.plan ? 'plan' : 'apply',\n connection: dbConnection,\n ...(options.acceptDataLoss ? { acceptDataLoss: true } : {}),\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapDbUpdateFailure(result.failure));\n }\n\n // Convert success result to CLI output format\n const dbUpdateResult: MigrationCommandResult = {\n ok: true,\n mode: result.value.mode,\n plan: {\n targetId: ctxResult.value.config.target.targetId,\n destination: {\n storageHash: result.value.destination.storageHash,\n ...ifDefined('profileHash', result.value.destination.profileHash),\n },\n operations: result.value.plan.operations.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n ...ifDefined('sql', result.value.plan.sql),\n },\n ...ifDefined(\n 'execution',\n result.value.execution\n ? {\n operationsPlanned: result.value.execution.operationsPlanned,\n operationsExecuted: result.value.execution.operationsExecuted,\n }\n : undefined,\n ),\n ...ifDefined(\n 'marker',\n result.value.marker\n ? {\n storageHash: result.value.marker.storageHash,\n ...ifDefined('profileHash', result.value.marker.profileHash),\n }\n : undefined,\n ),\n summary: result.value.summary,\n timings: { total: Date.now() - startTime },\n };\n\n return ok(dbUpdateResult);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\n }\n\n const rawMessage = error instanceof Error ? error.message : String(error);\n const safeMessage = sanitizeErrorMessage(\n rawMessage,\n typeof dbConnection === 'string' ? dbConnection : undefined,\n );\n return notOk(\n errorUnexpected(safeMessage, {\n why: `Unexpected error during db update: ${safeMessage}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createDbUpdateCommand(): Command {\n const command = new Command('update');\n setCommandDescriptions(\n command,\n 'Update your database schema to match your contract',\n 'Compares your database schema to the emitted contract and applies the necessary\\n' +\n 'changes. Works on any database, whether or not it has been initialized with `db init`.\\n' +\n 'Use --plan to preview operations before applying.',\n );\n addMigrationCommandOptions(command);\n command.option(\n '--accept-data-loss',\n 'Confirm destructive operations (required when plan includes drops or type changes)',\n false,\n );\n command.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n });\n command.action(async (options: DbUpdateOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n if (flags.json === 'ndjson') {\n const result = notOk(\n errorJsonFormatNotSupported({\n command: 'db update',\n format: 'ndjson',\n supportedFormats: ['object'],\n }),\n );\n const exitCode = handleResult(result, flags);\n process.exit(exitCode);\n }\n\n const result = await executeDbUpdateCommand(options, flags, startTime);\n const exitCode = handleResult(result, flags, (dbUpdateResult) => {\n if (flags.json === 'object') {\n console.log(formatMigrationJson(dbUpdateResult));\n } else {\n const output =\n dbUpdateResult.mode === 'plan'\n ? formatMigrationPlanOutput(dbUpdateResult, flags)\n : formatMigrationApplyOutput(dbUpdateResult, flags);\n if (output) {\n console.log(output);\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":";;;;;;;;;;;;;AAqCA,SAAS,mBAAmB,SAA8C;AACxE,KAAI,QAAQ,SAAS,kBACnB,QAAO,6BAA6B,EAAE,WAAW,QAAQ,aAAa,EAAE,EAAE,CAAC;AAG7E,KAAI,QAAQ,SAAS,gBACnB,QAAO,kBAAkB,QAAQ,SAAS;EACxC,KAAK,QAAQ,OAAO;EACpB,KAAK;EACL,GAAG,UAAU,QAAQ,QAAQ,KAAK;EACnC,CAAC;AAGJ,KAAI,QAAQ,SAAS,sBACnB,QAAO,wBAAwB,QAAQ,SAAS;EAC9C,GAAG,UAAU,OAAO,QAAQ,IAAI;EAChC,KAAK;EACL,GAAG,UAAU,QAAQ,QAAQ,KAAK;EACnC,CAAC;CAGJ,MAAMA,aAAoB,QAAQ;AAClC,OAAM,IAAI,MAAM,mCAAmC,aAAa;;;;;AAMlE,eAAe,uBACb,SACA,OACA,WAC6D;CAE7D,MAAM,YAAY,MAAM,wBAAwB,SAAS,OAAO;EAC9D,aAAa;EACb,aAAa;EACb,KAAK;EACN,CAAC;AACF,KAAI,CAAC,UAAU,GACb,QAAO;CAET,MAAM,EAAE,QAAQ,cAAc,cAAc,YAAY,yBAAyB,UAAU;AAE3F,KAAI;EAEF,MAAM,SAAS,MAAM,OAAO,SAAS;GACnC,YAAY;GACZ,MAAM,QAAQ,OAAO,SAAS;GAC9B,YAAY;GACZ,GAAI,QAAQ,iBAAiB,EAAE,gBAAgB,MAAM,GAAG,EAAE;GAC1D;GACD,CAAC;AAGF,MAAI,CAAC,OAAO,GACV,QAAO,MAAM,mBAAmB,OAAO,QAAQ,CAAC;AA0ClD,SAAO,GAtCwC;GAC7C,IAAI;GACJ,MAAM,OAAO,MAAM;GACnB,MAAM;IACJ,UAAU,UAAU,MAAM,OAAO,OAAO;IACxC,aAAa;KACX,aAAa,OAAO,MAAM,YAAY;KACtC,GAAG,UAAU,eAAe,OAAO,MAAM,YAAY,YAAY;KAClE;IACD,YAAY,OAAO,MAAM,KAAK,WAAW,KAAK,QAAQ;KACpD,IAAI,GAAG;KACP,OAAO,GAAG;KACV,gBAAgB,GAAG;KACpB,EAAE;IACH,GAAG,UAAU,OAAO,OAAO,MAAM,KAAK,IAAI;IAC3C;GACD,GAAG,UACD,aACA,OAAO,MAAM,YACT;IACE,mBAAmB,OAAO,MAAM,UAAU;IAC1C,oBAAoB,OAAO,MAAM,UAAU;IAC5C,GACD,OACL;GACD,GAAG,UACD,UACA,OAAO,MAAM,SACT;IACE,aAAa,OAAO,MAAM,OAAO;IACjC,GAAG,UAAU,eAAe,OAAO,MAAM,OAAO,YAAY;IAC7D,GACD,OACL;GACD,SAAS,OAAO,MAAM;GACtB,SAAS,EAAE,OAAO,KAAK,KAAK,GAAG,WAAW;GAC3C,CAEwB;UAClB,OAAO;AACd,MAAI,mBAAmB,GAAG,MAAM,CAC9B,QAAO,MAAM,MAAM;AAGrB,MAAI,iBAAiB,wBACnB,QAAO,MACL,8BAA8B,+BAA+B,MAAM,WAAW,EAC5E,OAAO,EAAE,MAAM,sBAAsB,EACtC,CAAC,CACH;EAIH,MAAM,cAAc,qBADD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAGvE,OAAO,iBAAiB,WAAW,eAAe,OACnD;AACD,SAAO,MACL,gBAAgB,aAAa,EAC3B,KAAK,sCAAsC,eAC5C,CAAC,CACH;WACO;AACR,QAAM,OAAO,OAAO;;;AAIxB,SAAgB,wBAAiC;CAC/C,MAAM,UAAU,IAAI,QAAQ,SAAS;AACrC,wBACE,SACA,sDACA,6NAGD;AACD,4BAA2B,QAAQ;AACnC,SAAQ,OACN,sBACA,sFACA,MACD;AACD,SAAQ,cAAc,EACpB,aAAa,QAAQ;AAEnB,SAAO,kBAAkB;GAAE,SAAS;GAAK,OAD3B,iBAAiB,EAAE,CAAC;GACc,CAAC;IAEpD,CAAC;AACF,SAAQ,OAAO,OAAO,YAA6B;EACjD,MAAM,QAAQ,iBAAiB,QAAQ;EACvC,MAAM,YAAY,KAAK,KAAK;AAE5B,MAAI,MAAM,SAAS,UAAU;GAQ3B,MAAMC,aAAW,aAPF,MACb,4BAA4B;IAC1B,SAAS;IACT,QAAQ;IACR,kBAAkB,CAAC,SAAS;IAC7B,CAAC,CACH,EACqC,MAAM;AAC5C,WAAQ,KAAKA,WAAS;;EAIxB,MAAM,WAAW,aADF,MAAM,uBAAuB,SAAS,OAAO,UAAU,EAChC,QAAQ,mBAAmB;AAC/D,OAAI,MAAM,SAAS,SACjB,SAAQ,IAAI,oBAAoB,eAAe,CAAC;QAC3C;IACL,MAAM,SACJ,eAAe,SAAS,SACpB,0BAA0B,gBAAgB,MAAM,GAChD,2BAA2B,gBAAgB,MAAM;AACvD,QAAI,OACF,SAAQ,IAAI,OAAO;;IAGvB;AACF,UAAQ,KAAK,SAAS;GACtB;AAEF,QAAO"}
@@ -1,6 +1,5 @@
1
1
  import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
2
  import { _ as errorUnexpected, a as errorDatabaseConnectionRequired, c as errorFileNotFound, d as errorMarkerMissing, g as errorTargetMismatch, i as errorContractValidationFailed, l as errorHashMismatch, m as errorRuntime, s as errorDriverRequired, t as CliStructuredError, u as errorJsonFormatNotSupported } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { n as ContractValidationError, t as createControlClient } from "../client-PimzSD1f.mjs";
5
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, S as formatVerifyOutput, T as resolveContractPath, n as formatCommandHelp, t as handleResult, w as maskConnectionUrl, x as formatVerifyJson, y as formatStyledHeader } from "../result-handler-iA9JtUC7.mjs";
6
5
  import { t as createProgressAdapter } from "../progress-adapter-DENrzF6I.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"db-verify.mjs","names":["details: Array<{ label: string; value: string }>","contractJsonContent: string","contractJson: Record<string, unknown>","exitCode"],"sources":["../../src/commands/db-verify.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport type { VerifyDatabaseResult } from '@prisma-next/core-control-plane/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\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 { ContractValidationError } from '../control-api/errors';\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 {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} 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.storageHash,\n ...ifDefined('actual', verifyResult.marker?.storageHash),\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 = resolveContractPath(config);\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: maskConnectionUrl(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 if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\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"],"mappings":"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"}
1
+ {"version":3,"file":"db-verify.mjs","names":["details: Array<{ label: string; value: string }>","contractJsonContent: string","contractJson: Record<string, unknown>","exitCode"],"sources":["../../src/commands/db-verify.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport type { VerifyDatabaseResult } from '@prisma-next/core-control-plane/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\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 { ContractValidationError } from '../control-api/errors';\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 {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} 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.storageHash,\n ...ifDefined('actual', verifyResult.marker?.storageHash),\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 = resolveContractPath(config);\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: maskConnectionUrl(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 if (error instanceof ContractValidationError) {\n return notOk(\n errorContractValidationFailed(`Contract validation failed: ${error.message}`, {\n where: { path: contractPathAbsolute },\n }),\n );\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"],"mappings":";;;;;;;;;;;;;;;AAuDA,SAAS,iBAAiB,cAAwD;AAChF,KAAI,CAAC,aAAa,MAAM,aAAa,MAAM;AACzC,MAAI,aAAa,SAAS,cACxB,QAAO,oBAAoB;AAE7B,MAAI,aAAa,SAAS,cACxB,QAAO,kBAAkB;GACvB,UAAU,aAAa,SAAS;GAChC,GAAG,UAAU,UAAU,aAAa,QAAQ,YAAY;GACzD,CAAC;AAEJ,MAAI,aAAa,SAAS,cACxB,QAAO,oBACL,aAAa,OAAO,UACpB,aAAa,OAAO,UAAU,UAC/B;;AAIL,QAAO,aAAa,aAAa,QAAQ;;;;;AAM3C,eAAe,uBACb,SACA,OAC2D;CAE3D,MAAM,SAAS,MAAM,WAAW,QAAQ,OAAO;CAC/C,MAAM,aAAa,QAAQ,SACvB,SAAS,QAAQ,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC,GAChD;CACJ,MAAM,uBAAuB,oBAAoB,OAAO;CACxD,MAAM,eAAe,SAAS,QAAQ,KAAK,EAAE,qBAAqB;AAGlE,KAAI,MAAM,SAAS,YAAY,CAAC,MAAM,OAAO;EAC3C,MAAMA,UAAmD,CACvD;GAAE,OAAO;GAAU,OAAO;GAAY,EACtC;GAAE,OAAO;GAAY,OAAO;GAAc,CAC3C;AACD,MAAI,QAAQ,GACV,SAAQ,KAAK;GAAE,OAAO;GAAY,OAAO,kBAAkB,QAAQ,GAAG;GAAE,CAAC;EAE3E,MAAM,SAAS,mBAAmB;GAChC,SAAS;GACT,aAAa;GACb,KAAK;GACL;GACA;GACD,CAAC;AACF,UAAQ,IAAI,OAAO;;CAIrB,IAAIC;AACJ,KAAI;AACF,wBAAsB,MAAM,SAAS,sBAAsB,QAAQ;UAC5D,OAAO;AACd,MAAI,iBAAiB,SAAU,MAA4B,SAAS,SAClE,QAAO,MACL,kBAAkB,sBAAsB;GACtC,KAAK,8BAA8B;GACnC,KAAK,iDAAiD,aAAa,4CAA4C;GAChH,CAAC,CACH;AAEH,SAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,iCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IAC7F,CAAC,CACH;;CAGH,IAAIC;AACJ,KAAI;AACF,iBAAe,KAAK,MAAM,oBAAoB;UACvC,OAAO;AACd,SAAO,MACL,8BACE,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACnF,EAAE,OAAO,EAAE,MAAM,sBAAsB,EAAE,CAC1C,CACF;;CAIH,MAAM,eAAe,QAAQ,MAAM,OAAO,IAAI;AAC9C,KAAI,CAAC,aACH,QAAO,MACL,gCAAgC,EAC9B,KAAK,uEAAuE,WAAW,wBACxF,CAAC,CACH;AAIH,KAAI,CAAC,OAAO,OACV,QAAO,MAAM,oBAAoB,EAAE,KAAK,2CAA2C,CAAC,CAAC;CAIvF,MAAM,SAAS,oBAAoB;EACjC,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf,gBAAgB,OAAO,kBAAkB,EAAE;EAC5C,CAAC;CAGF,MAAM,aAAa,sBAAsB,EAAE,OAAO,CAAC;AAEnD,KAAI;EACF,MAAM,eAAe,MAAM,OAAO,OAAO;GACvC,YAAY;GACZ,YAAY;GACZ;GACD,CAAC;AAGF,MAAI,CAAC,MAAM,SAAS,MAAM,SAAS,YAAY,QAAQ,OAAO,MAC5D,SAAQ,IAAI,GAAG;AAIjB,MAAI,CAAC,aAAa,GAChB,QAAO,MAAM,iBAAiB,aAAa,CAAC;AAG9C,SAAO,GAAG,aAAa;UAChB,OAAO;AAEd,MAAI,iBAAiB,mBACnB,QAAO,MAAM,MAAM;AAGrB,MAAI,iBAAiB,wBACnB,QAAO,MACL,8BAA8B,+BAA+B,MAAM,WAAW,EAC5E,OAAO,EAAE,MAAM,sBAAsB,EACtC,CAAC,CACH;AAIH,SAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,sCAAsC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IAClG,CAAC,CACH;WACO;AACR,QAAM,OAAO,OAAO;;;AAIxB,SAAgB,wBAAiC;CAC/C,MAAM,UAAU,IAAI,QAAQ,SAAS;AACrC,wBACE,SACA,iEACA,sLAED;AACD,SACG,cAAc,EACb,aAAa,QAAQ;AAEnB,SAAO,kBAAkB;GAAE,SAAS;GAAK,OAD3B,iBAAiB,EAAE,CAAC;GACc,CAAC;IAEpD,CAAC,CACD,OAAO,cAAc,6BAA6B,CAClD,OAAO,mBAAmB,gCAAgC,CAC1D,OAAO,mBAAmB,2BAA2B,MAAM,CAC3D,OAAO,eAAe,0BAA0B,CAChD,OAAO,iBAAiB,sCAAsC,CAC9D,OAAO,gBAAgB,6CAA6C,CACpE,OAAO,gBAAgB,2BAA2B,CAClD,OAAO,WAAW,qBAAqB,CACvC,OAAO,cAAc,uBAAuB,CAC5C,OAAO,OAAO,YAA6B;EAC1C,MAAM,QAAQ,iBAAiB,QAAQ;AAGvC,MAAI,MAAM,SAAS,UAAU;GAQ3B,MAAMC,aAAW,aAPF,MACb,4BAA4B;IAC1B,SAAS;IACT,QAAQ;IACR,kBAAkB,CAAC,SAAS;IAC7B,CAAC,CACH,EACqC,MAAM;AAC5C,WAAQ,KAAKA,WAAS;;EAKxB,MAAM,WAAW,aAFF,MAAM,uBAAuB,SAAS,MAAM,EAErB,QAAQ,iBAAiB;AAC7D,OAAI,MAAM,SAAS,SACjB,SAAQ,IAAI,iBAAiB,aAAa,CAAC;QACtC;IACL,MAAM,SAAS,mBAAmB,cAAc,MAAM;AACtD,QAAI,OACF,SAAQ,IAAI,OAAO;;IAGvB;AACF,UAAQ,KAAK,SAAS;GACtB;AAEJ,QAAO"}
@@ -1,6 +1,5 @@
1
1
  import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
2
  import { _ as errorUnexpected, a as errorDatabaseConnectionRequired, h as errorTargetMigrationNotSupported, m as errorRuntime, s as errorDriverRequired, t as CliStructuredError } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { t as createControlClient } from "../client-PimzSD1f.mjs";
5
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, T as resolveContractPath, n as formatCommandHelp, s as formatMigrationApplyCommandOutput, t as handleResult, w as maskConnectionUrl, y as formatStyledHeader } from "../result-handler-iA9JtUC7.mjs";
6
5
  import { Command } from "commander";
@@ -1 +1 @@
1
- {"version":3,"file":"migration-apply.mjs","names":["destinationHash: string","details: Array<{ label: string; value: string }>","packages: readonly MigrationPackage[]","client","graph: MigrationGraph","pendingMigrations: MigrationApplyStep[]"],"sources":["../../src/commands/migration-apply.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { EMPTY_CONTRACT_HASH } from '@prisma-next/core-control-plane/constants';\nimport { findPath, reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type { MigrationGraph, MigrationPackage } from '@prisma-next/migration-tools/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type { MigrationApplyFailure, MigrationApplyStep } from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatMigrationApplyCommandOutput,\n formatStyledHeader,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ninterface MigrationApplyCommandOptions {\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\nexport interface MigrationApplyResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly dirName: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly timings: {\n readonly total: number;\n };\n}\n\nfunction mapMigrationToolsError(error: unknown): CliStructuredErrorType {\n if (MigrationToolsError.is(error)) {\n return errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n });\n }\n return errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migration apply: ${error instanceof Error ? error.message : String(error)}`,\n });\n}\n\nfunction mapApplyFailure(failure: MigrationApplyFailure): CliStructuredErrorType {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Fix the issue and re-run `prisma-next migration apply` — previously applied migrations are preserved.',\n meta: failure.meta ?? {},\n });\n}\n\nfunction packageToStep(pkg: MigrationPackage): MigrationApplyStep {\n return {\n dirName: pkg.dirName,\n from: pkg.manifest.from,\n to: pkg.manifest.to,\n toContract: pkg.manifest.toContract,\n operations: pkg.ops as MigrationApplyStep['operations'],\n };\n}\n\nasync function executeMigrationApplyCommand(\n options: MigrationApplyCommandOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<MigrationApplyResult, CliStructuredErrorType>> {\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 const migrationsDir = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for migration apply (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for migration apply' }));\n }\n\n const targetWithMigrations = config.target as typeof config.target & {\n readonly migrations?: unknown;\n };\n if (!targetWithMigrations.migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n let destinationHash: string;\n try {\n const contractPathAbsolute = resolveContractPath(config);\n const contractRaw = JSON.parse(await readFile(contractPathAbsolute, 'utf-8')) as Record<\n string,\n unknown\n >;\n const contractHash = contractRaw['storageHash'];\n if (typeof contractHash !== 'string') {\n return notOk(\n errorRuntime('Current contract is missing storage hash', {\n why: `The contract at ${relative(process.cwd(), contractPathAbsolute)} does not contain a valid storageHash`,\n fix: 'Run `prisma-next contract emit` and re-run `prisma-next migration apply`.',\n }),\n );\n }\n destinationHash = contractHash;\n } catch (error) {\n return notOk(\n errorRuntime('Current contract is unavailable', {\n why: `Failed to read contract hash before apply: ${error instanceof Error ? error.message : String(error)}`,\n fix: 'Run `prisma-next contract emit` to generate a valid contract.json, then retry apply.',\n }),\n );\n }\n\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (typeof dbConnection === 'string') {\n details.push({ label: 'database', value: maskConnectionUrl(dbConnection) });\n }\n const header = formatStyledHeader({\n command: 'migration apply',\n description: 'Apply planned migrations to the database',\n url: 'https://pris.ly/migration-apply',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Read migrations and build migration chain model (offline — no DB needed)\n let packages: readonly MigrationPackage[];\n try {\n const allPackages = await readMigrationsDir(migrationsDir);\n packages = allPackages.filter((p) => typeof p.manifest.migrationId === 'string');\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n if (packages.length === 0) {\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 try {\n await client.connect(dbConnection);\n const marker = await client.readMarker();\n const markerHash = marker?.storageHash ?? EMPTY_CONTRACT_HASH;\n if (markerHash !== EMPTY_CONTRACT_HASH) {\n return notOk(\n errorRuntime('Database has state but no migrations exist', {\n why: `The database marker hash \"${markerHash}\" exists but no attested migrations were found in ${migrationsRelative}`,\n fix: 'Ensure the migrations directory is correct, or reset the database with `prisma-next db init`.',\n meta: { markerHash, migrationsDir: migrationsRelative },\n }),\n );\n }\n if (destinationHash !== EMPTY_CONTRACT_HASH) {\n return notOk(\n errorRuntime('Current contract has no planned migrations', {\n why: `No attested migrations were found in ${migrationsRelative}, but current contract hash is \"${destinationHash}\"`,\n fix: 'Run `prisma-next migration plan` to create an attested migration for the current contract.',\n meta: { destinationHash, migrationsDir: migrationsRelative },\n }),\n );\n }\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migration apply: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n return ok({\n ok: true,\n migrationsApplied: 0,\n migrationsTotal: 0,\n markerHash: EMPTY_CONTRACT_HASH,\n applied: [],\n summary: 'No attested migrations found',\n timings: { total: Date.now() - startTime },\n });\n }\n\n let graph: MigrationGraph;\n try {\n graph = reconstructGraph(packages);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n // Create control client for all DB operations\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 try {\n await client.connect(dbConnection);\n\n const marker = await client.readMarker();\n\n // Distinguish \"no marker row\" (null) from \"marker row exists with the\n // empty sentinel\". The sentinel should never appear in a real marker row —\n // if it does, the marker was corrupted and replaying all migrations would\n // be dangerous (the DB likely already has tables).\n if (marker?.storageHash === EMPTY_CONTRACT_HASH) {\n return notOk(\n errorRuntime('Database marker contains the empty sentinel hash', {\n why: `The marker row exists but contains the empty sentinel value \"${EMPTY_CONTRACT_HASH}\". This should never happen — the marker should contain the hash of the last applied contract.`,\n fix: 'The marker is corrupted. Reset the database with `prisma-next db init`, or manually update the marker to the correct contract hash.',\n meta: { markerHash: EMPTY_CONTRACT_HASH },\n }),\n );\n }\n\n const markerHash = marker?.storageHash ?? EMPTY_CONTRACT_HASH;\n\n if (markerHash !== EMPTY_CONTRACT_HASH && !graph.nodes.has(markerHash)) {\n return notOk(\n errorRuntime('Database marker does not match any known migration', {\n why: `The database marker hash \"${markerHash}\" is not found in the migration history at ${migrationsRelative}`,\n fix: 'Ensure the migrations directory matches this database, or reset the database with `prisma-next db init`.',\n meta: { markerHash, knownNodes: [...graph.nodes] },\n }),\n );\n }\n\n if (!graph.nodes.has(destinationHash)) {\n return notOk(\n errorRuntime('Current contract has no planned migration path', {\n why: `Current contract hash \"${destinationHash}\" is not present in the migration history at ${migrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration for the current contract, then re-run apply.',\n meta: { destinationHash, knownNodes: [...graph.nodes] },\n }),\n );\n }\n\n const pendingPath = findPath(graph, markerHash, destinationHash);\n if (!pendingPath) {\n return notOk(\n errorRuntime('No migration path from current state to target', {\n why: `Cannot find a path from marker hash \"${markerHash}\" to target \"${destinationHash}\"`,\n fix: 'Check the migration history for gaps or inconsistencies.',\n meta: { markerHash, destinationHash },\n }),\n );\n }\n\n if (pendingPath.length === 0) {\n return ok({\n ok: true,\n migrationsApplied: 0,\n migrationsTotal: 0,\n markerHash,\n applied: [],\n summary: 'Already up to date',\n timings: { total: Date.now() - startTime },\n });\n }\n\n // Resolve graph edges to full apply-ready edges\n const packageByDir = new Map(packages.map((pkg) => [pkg.dirName, pkg]));\n const pendingMigrations: MigrationApplyStep[] = [];\n for (const migration of pendingPath) {\n const pkg = packageByDir.get(migration.dirName);\n if (!pkg) {\n return notOk(\n errorRuntime(`Migration package not found: ${migration.dirName}`, {\n why: `The migration directory for path segment ${migration.from} → ${migration.to} was not found`,\n fix: 'Ensure all migration directories are present and intact.',\n }),\n );\n }\n pendingMigrations.push(packageToStep(pkg));\n }\n\n if (!flags.quiet && flags.json !== 'object') {\n for (const migration of pendingMigrations) {\n console.log(` Applying ${migration.dirName}...`);\n }\n }\n\n const applyResult = await client.migrationApply({\n originHash: markerHash,\n destinationHash,\n pendingMigrations,\n });\n\n if (!applyResult.ok) {\n return notOk(mapApplyFailure(applyResult.failure));\n }\n\n const { value } = applyResult;\n\n return ok({\n ok: true,\n migrationsApplied: value.migrationsApplied,\n migrationsTotal: pendingPath.length,\n markerHash: value.markerHash,\n applied: value.applied,\n summary: value.summary,\n timings: { total: Date.now() - startTime },\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migration apply: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrationApplyCommand(): Command {\n const command = new Command('apply');\n setCommandDescriptions(\n command,\n 'Apply planned migrations to the database',\n 'Applies previously planned migrations (created by `migration plan`) to a live database.\\n' +\n 'Compares the database marker against the migration chain to determine which\\n' +\n 'migrations are pending, then executes them sequentially. Each migration runs\\n' +\n 'in its own transaction. Does not plan new migrations — run `migration plan` first.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const defaultFlags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags: defaultFlags });\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: MigrationApplyCommandOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n const result = await executeMigrationApplyCommand(options, flags, startTime);\n\n const exitCode = handleResult(result, flags, (applyResult) => {\n if (flags.json === 'object') {\n console.log(JSON.stringify(applyResult, null, 2));\n } else if (!flags.quiet) {\n console.log(formatMigrationApplyCommandOutput(applyResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"migration-apply.mjs","names":["destinationHash: string","details: Array<{ label: string; value: string }>","packages: readonly MigrationPackage[]","client","graph: MigrationGraph","pendingMigrations: MigrationApplyStep[]"],"sources":["../../src/commands/migration-apply.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { EMPTY_CONTRACT_HASH } from '@prisma-next/core-control-plane/constants';\nimport { findPath, reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type { MigrationGraph, MigrationPackage } from '@prisma-next/migration-tools/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type { MigrationApplyFailure, MigrationApplyStep } from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatMigrationApplyCommandOutput,\n formatStyledHeader,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ninterface MigrationApplyCommandOptions {\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\nexport interface MigrationApplyResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly dirName: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly timings: {\n readonly total: number;\n };\n}\n\nfunction mapMigrationToolsError(error: unknown): CliStructuredErrorType {\n if (MigrationToolsError.is(error)) {\n return errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n });\n }\n return errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migration apply: ${error instanceof Error ? error.message : String(error)}`,\n });\n}\n\nfunction mapApplyFailure(failure: MigrationApplyFailure): CliStructuredErrorType {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Migration runner failed',\n fix: 'Fix the issue and re-run `prisma-next migration apply` — previously applied migrations are preserved.',\n meta: failure.meta ?? {},\n });\n}\n\nfunction packageToStep(pkg: MigrationPackage): MigrationApplyStep {\n return {\n dirName: pkg.dirName,\n from: pkg.manifest.from,\n to: pkg.manifest.to,\n toContract: pkg.manifest.toContract,\n operations: pkg.ops as MigrationApplyStep['operations'],\n };\n}\n\nasync function executeMigrationApplyCommand(\n options: MigrationApplyCommandOptions,\n flags: GlobalFlags,\n startTime: number,\n): Promise<Result<MigrationApplyResult, CliStructuredErrorType>> {\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 const migrationsDir = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for migration apply (set db.connection in ${configPath}, or pass --db <url>)`,\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(errorDriverRequired({ why: 'Config.driver is required for migration apply' }));\n }\n\n const targetWithMigrations = config.target as typeof config.target & {\n readonly migrations?: unknown;\n };\n if (!targetWithMigrations.migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n let destinationHash: string;\n try {\n const contractPathAbsolute = resolveContractPath(config);\n const contractRaw = JSON.parse(await readFile(contractPathAbsolute, 'utf-8')) as Record<\n string,\n unknown\n >;\n const contractHash = contractRaw['storageHash'];\n if (typeof contractHash !== 'string') {\n return notOk(\n errorRuntime('Current contract is missing storage hash', {\n why: `The contract at ${relative(process.cwd(), contractPathAbsolute)} does not contain a valid storageHash`,\n fix: 'Run `prisma-next contract emit` and re-run `prisma-next migration apply`.',\n }),\n );\n }\n destinationHash = contractHash;\n } catch (error) {\n return notOk(\n errorRuntime('Current contract is unavailable', {\n why: `Failed to read contract hash before apply: ${error instanceof Error ? error.message : String(error)}`,\n fix: 'Run `prisma-next contract emit` to generate a valid contract.json, then retry apply.',\n }),\n );\n }\n\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (typeof dbConnection === 'string') {\n details.push({ label: 'database', value: maskConnectionUrl(dbConnection) });\n }\n const header = formatStyledHeader({\n command: 'migration apply',\n description: 'Apply planned migrations to the database',\n url: 'https://pris.ly/migration-apply',\n details,\n flags,\n });\n console.log(header);\n }\n\n // Read migrations and build migration chain model (offline — no DB needed)\n let packages: readonly MigrationPackage[];\n try {\n const allPackages = await readMigrationsDir(migrationsDir);\n packages = allPackages.filter((p) => typeof p.manifest.migrationId === 'string');\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n if (packages.length === 0) {\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 try {\n await client.connect(dbConnection);\n const marker = await client.readMarker();\n const markerHash = marker?.storageHash ?? EMPTY_CONTRACT_HASH;\n if (markerHash !== EMPTY_CONTRACT_HASH) {\n return notOk(\n errorRuntime('Database has state but no migrations exist', {\n why: `The database marker hash \"${markerHash}\" exists but no attested migrations were found in ${migrationsRelative}`,\n fix: 'Ensure the migrations directory is correct, or reset the database with `prisma-next db init`.',\n meta: { markerHash, migrationsDir: migrationsRelative },\n }),\n );\n }\n if (destinationHash !== EMPTY_CONTRACT_HASH) {\n return notOk(\n errorRuntime('Current contract has no planned migrations', {\n why: `No attested migrations were found in ${migrationsRelative}, but current contract hash is \"${destinationHash}\"`,\n fix: 'Run `prisma-next migration plan` to create an attested migration for the current contract.',\n meta: { destinationHash, migrationsDir: migrationsRelative },\n }),\n );\n }\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migration apply: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n return ok({\n ok: true,\n migrationsApplied: 0,\n migrationsTotal: 0,\n markerHash: EMPTY_CONTRACT_HASH,\n applied: [],\n summary: 'No attested migrations found',\n timings: { total: Date.now() - startTime },\n });\n }\n\n let graph: MigrationGraph;\n try {\n graph = reconstructGraph(packages);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n // Create control client for all DB operations\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 try {\n await client.connect(dbConnection);\n\n const marker = await client.readMarker();\n\n // Distinguish \"no marker row\" (null) from \"marker row exists with the\n // empty sentinel\". The sentinel should never appear in a real marker row —\n // if it does, the marker was corrupted and replaying all migrations would\n // be dangerous (the DB likely already has tables).\n if (marker?.storageHash === EMPTY_CONTRACT_HASH) {\n return notOk(\n errorRuntime('Database marker contains the empty sentinel hash', {\n why: `The marker row exists but contains the empty sentinel value \"${EMPTY_CONTRACT_HASH}\". This should never happen — the marker should contain the hash of the last applied contract.`,\n fix: 'The marker is corrupted. Reset the database with `prisma-next db init`, or manually update the marker to the correct contract hash.',\n meta: { markerHash: EMPTY_CONTRACT_HASH },\n }),\n );\n }\n\n const markerHash = marker?.storageHash ?? EMPTY_CONTRACT_HASH;\n\n if (markerHash !== EMPTY_CONTRACT_HASH && !graph.nodes.has(markerHash)) {\n return notOk(\n errorRuntime('Database marker does not match any known migration', {\n why: `The database marker hash \"${markerHash}\" is not found in the migration history at ${migrationsRelative}`,\n fix: 'Ensure the migrations directory matches this database, or reset the database with `prisma-next db init`.',\n meta: { markerHash, knownNodes: [...graph.nodes] },\n }),\n );\n }\n\n if (!graph.nodes.has(destinationHash)) {\n return notOk(\n errorRuntime('Current contract has no planned migration path', {\n why: `Current contract hash \"${destinationHash}\" is not present in the migration history at ${migrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration for the current contract, then re-run apply.',\n meta: { destinationHash, knownNodes: [...graph.nodes] },\n }),\n );\n }\n\n const pendingPath = findPath(graph, markerHash, destinationHash);\n if (!pendingPath) {\n return notOk(\n errorRuntime('No migration path from current state to target', {\n why: `Cannot find a path from marker hash \"${markerHash}\" to target \"${destinationHash}\"`,\n fix: 'Check the migration history for gaps or inconsistencies.',\n meta: { markerHash, destinationHash },\n }),\n );\n }\n\n if (pendingPath.length === 0) {\n return ok({\n ok: true,\n migrationsApplied: 0,\n migrationsTotal: 0,\n markerHash,\n applied: [],\n summary: 'Already up to date',\n timings: { total: Date.now() - startTime },\n });\n }\n\n // Resolve graph edges to full apply-ready edges\n const packageByDir = new Map(packages.map((pkg) => [pkg.dirName, pkg]));\n const pendingMigrations: MigrationApplyStep[] = [];\n for (const migration of pendingPath) {\n const pkg = packageByDir.get(migration.dirName);\n if (!pkg) {\n return notOk(\n errorRuntime(`Migration package not found: ${migration.dirName}`, {\n why: `The migration directory for path segment ${migration.from} → ${migration.to} was not found`,\n fix: 'Ensure all migration directories are present and intact.',\n }),\n );\n }\n pendingMigrations.push(packageToStep(pkg));\n }\n\n if (!flags.quiet && flags.json !== 'object') {\n for (const migration of pendingMigrations) {\n console.log(` Applying ${migration.dirName}...`);\n }\n }\n\n const applyResult = await client.migrationApply({\n originHash: markerHash,\n destinationHash,\n pendingMigrations,\n });\n\n if (!applyResult.ok) {\n return notOk(mapApplyFailure(applyResult.failure));\n }\n\n const { value } = applyResult;\n\n return ok({\n ok: true,\n migrationsApplied: value.migrationsApplied,\n migrationsTotal: pendingPath.length,\n markerHash: value.markerHash,\n applied: value.applied,\n summary: value.summary,\n timings: { total: Date.now() - startTime },\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migration apply: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrationApplyCommand(): Command {\n const command = new Command('apply');\n setCommandDescriptions(\n command,\n 'Apply planned migrations to the database',\n 'Applies previously planned migrations (created by `migration plan`) to a live database.\\n' +\n 'Compares the database marker against the migration chain to determine which\\n' +\n 'migrations are pending, then executes them sequentially. Each migration runs\\n' +\n 'in its own transaction. Does not plan new migrations — run `migration plan` first.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const defaultFlags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags: defaultFlags });\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: MigrationApplyCommandOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n const result = await executeMigrationApplyCommand(options, flags, startTime);\n\n const exitCode = handleResult(result, flags, (applyResult) => {\n if (flags.json === 'object') {\n console.log(JSON.stringify(applyResult, null, 2));\n } else if (!flags.quiet) {\n console.log(formatMigrationApplyCommandOutput(applyResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/commands/migration-status.ts"],"sourcesContent":[],"mappings":";;;;UA6CiB,oBAAA;;EAAA,SAAA,IAAA,EAAA,MAAA;EAWA,SAAA,EAAA,EAAA,MAAgB;EAOhB,SAAA,WAAA,EAAA,MAAqB,GAAA,IAAA;EAwCtB,SAAA,cAAA,EAAqB,MAAA;EACnB,SAAA,gBAAA,EAAA,MAAA;EACG,SAAA,cAAA,EAAA,OAAA;EAElB,SAAA,MAAA,EAAA,SAAA,GAAA,SAAA,GAAA,SAAA;;AA8Ra,UAjVC,gBAAA,CAiVD;;;;;;UA1UC,qBAAA;;;gCAGe;;;;;iCAKC;;iBAgCjB,qBAAA,iBACE,0CACG,qDAElB;iBA8Ra,4BAAA,CAAA,GAAgC"}
1
+ {"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/commands/migration-status.ts"],"sourcesContent":[],"mappings":";;;;UA6CiB,oBAAA;;EAAA,SAAA,IAAA,EAAA,MAAA;EAWA,SAAA,EAAA,EAAA,MAAgB;EAOhB,SAAA,WAAA,EAAA,MAAqB,GAAA,IAGN;EAqChB,SAAA,cAAA,EAAqB,MAAA;EACnB,SAAA,gBAAA,EAAA,MAAA;EACG,SAAA,cAAA,EAAA,OAAA;EAElB,SAAA,MAAA,EAAA,SAAA,GAAA,SAAA,GAAA,SAAA;;AA8Ra,UAjVC,gBAAA,CAiVD;;;;;;UA1UC,qBAAA;;;gCAGe;;;;;iCAKC;;iBAgCjB,qBAAA,iBACE,0CACG,qDAElB;iBA8Ra,4BAAA,CAAA,GAAgC"}
@@ -1,6 +1,5 @@
1
1
  import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
2
  import { _ as errorUnexpected, m as errorRuntime } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { t as createControlClient } from "../client-PimzSD1f.mjs";
5
4
  import { C as parseGlobalFlags, D as setCommandDescriptions, T as resolveContractPath, f as formatMigrationStatusOutput, n as formatCommandHelp, t as handleResult, w as maskConnectionUrl, y as formatStyledHeader } from "../result-handler-iA9JtUC7.mjs";
6
5
  import { Command } from "commander";
@@ -1 +1 @@
1
- {"version":3,"file":"migration-status.mjs","names":["entries: MigrationStatusEntry[]","status: 'applied' | 'pending' | 'unknown'","details: Array<{ label: string; value: string }>","diagnostics: StatusDiagnostic[]","contractHash: string","allPackages: readonly MigrationPackage[]","graph: MigrationGraph","leafHash: string","markerHash: string | undefined","mode: 'online' | 'offline'","summary: string"],"sources":["../../src/commands/migration-status.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { EMPTY_CONTRACT_HASH } from '@prisma-next/core-control-plane/constants';\nimport type { MigrationPlanOperation } from '@prisma-next/core-control-plane/types';\nimport { findLeaf, findPath, reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type {\n MigrationChainEntry,\n MigrationGraph,\n MigrationPackage,\n} from '@prisma-next/migration-tools/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport { type CliStructuredError, errorRuntime, errorUnexpected } from '../utils/cli-errors';\nimport {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatMigrationStatusOutput,\n formatStyledHeader,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ninterface MigrationStatusOptions {\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\nexport interface MigrationStatusEntry {\n readonly dirName: string;\n readonly from: string;\n readonly to: string;\n readonly migrationId: string | null;\n readonly operationCount: number;\n readonly operationSummary: string;\n readonly hasDestructive: boolean;\n readonly status: 'applied' | 'pending' | 'unknown';\n}\n\nexport interface StatusDiagnostic {\n readonly code: string;\n readonly severity: 'warn' | 'info';\n readonly message: string;\n readonly hints: readonly string[];\n}\n\nexport interface MigrationStatusResult {\n readonly ok: true;\n readonly mode: 'online' | 'offline';\n readonly migrations: readonly MigrationStatusEntry[];\n readonly markerHash?: string;\n readonly leafHash: string;\n readonly contractHash: string;\n readonly summary: string;\n readonly diagnostics: readonly StatusDiagnostic[];\n}\n\nfunction summarizeOps(ops: readonly MigrationPlanOperation[]): {\n summary: string;\n hasDestructive: boolean;\n} {\n if (ops.length === 0) return { summary: '0 ops', hasDestructive: false };\n\n const classes = new Map<string, number>();\n for (const op of ops) {\n classes.set(op.operationClass, (classes.get(op.operationClass) ?? 0) + 1);\n }\n\n const hasDestructive = classes.has('destructive');\n const count = ops.length;\n const noun = count === 1 ? 'op' : 'ops';\n\n if (classes.size === 1) {\n const cls = [...classes.keys()][0]!;\n return { summary: `${count} ${noun} (all ${cls})`, hasDestructive };\n }\n\n const destructiveCount = classes.get('destructive');\n if (destructiveCount) {\n return { summary: `${count} ${noun} (${destructiveCount} destructive)`, hasDestructive };\n }\n\n const parts = [...classes.entries()].map(([cls, n]) => `${n} ${cls}`);\n return { summary: `${count} ${noun} (${parts.join(', ')})`, hasDestructive };\n}\n\nexport function buildMigrationEntries(\n chain: readonly MigrationChainEntry[],\n packages: readonly MigrationPackage[],\n markerHash: string | undefined,\n): MigrationStatusEntry[] {\n const pkgByDirName = new Map(packages.map((p) => [p.dirName, p]));\n\n const markerInChain =\n markerHash === undefined ||\n markerHash === EMPTY_CONTRACT_HASH ||\n chain.some((e) => e.to === markerHash);\n\n const entries: MigrationStatusEntry[] = [];\n let reachedMarker = markerHash === undefined || markerHash === EMPTY_CONTRACT_HASH;\n\n for (const migration of chain) {\n const pkg = pkgByDirName.get(migration.dirName);\n const ops = (pkg?.ops ?? []) as readonly MigrationPlanOperation[];\n const { summary, hasDestructive } = summarizeOps(ops);\n\n let status: 'applied' | 'pending' | 'unknown';\n if (markerHash === undefined || !markerInChain) {\n status = 'unknown';\n } else if (reachedMarker) {\n status = 'pending';\n } else {\n status = 'applied';\n }\n\n entries.push({\n dirName: migration.dirName,\n from: migration.from,\n to: migration.to,\n migrationId: migration.migrationId,\n operationCount: ops.length,\n operationSummary: summary,\n hasDestructive,\n status,\n });\n\n if (!reachedMarker && migration.to === markerHash) {\n reachedMarker = true;\n }\n }\n\n return entries;\n}\n\nasync function executeMigrationStatusCommand(\n options: MigrationStatusOptions,\n flags: GlobalFlags,\n): Promise<Result<MigrationStatusResult, CliStructuredError>> {\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 const migrationsDir = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n\n const dbConnection = options.db ?? config.db?.connection;\n const hasDriver = !!config.driver;\n\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (dbConnection && hasDriver) {\n details.push({ label: 'database', value: maskConnectionUrl(String(dbConnection)) });\n }\n const header = formatStyledHeader({\n command: 'migration status',\n description: 'Show migration chain and applied status',\n details,\n flags,\n });\n console.log(header);\n }\n\n const diagnostics: StatusDiagnostic[] = [];\n let contractHash: string = EMPTY_CONTRACT_HASH;\n try {\n const contractPathAbsolute = resolveContractPath(config);\n const contractContent = await readFile(contractPathAbsolute, 'utf-8');\n try {\n const contractRaw = JSON.parse(contractContent) as Record<string, unknown>;\n const hash = contractRaw['storageHash'];\n if (typeof hash === 'string') {\n contractHash = hash;\n } else {\n diagnostics.push({\n code: 'CONTRACT.MISSING_HASH',\n severity: 'warn',\n message: 'Contract file exists but has no storageHash field',\n hints: [\"Run 'prisma-next contract emit' to regenerate the contract\"],\n });\n }\n } catch {\n diagnostics.push({\n code: 'CONTRACT.INVALID_JSON',\n severity: 'warn',\n message: 'Contract file contains invalid JSON',\n hints: [\"Run 'prisma-next contract emit' to regenerate the contract\"],\n });\n }\n } catch {\n diagnostics.push({\n code: 'CONTRACT.UNREADABLE',\n severity: 'warn',\n message: 'Could not read contract file — contract state unknown',\n hints: [\"Run 'prisma-next contract emit' to generate a contract\"],\n });\n }\n\n let allPackages: readonly MigrationPackage[];\n try {\n allPackages = await readMigrationsDir(migrationsDir);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(\n errorRuntime(error.message, { why: error.why, fix: error.fix, meta: { code: error.code } }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migrations directory: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n const attested = allPackages.filter((p) => typeof p.manifest.migrationId === 'string');\n\n if (attested.length === 0) {\n if (contractHash !== EMPTY_CONTRACT_HASH) {\n diagnostics.push({\n code: 'CONTRACT.AHEAD',\n severity: 'warn',\n message: 'Contract has changed since the last migration was planned',\n hints: [\n \"Run 'prisma-next migration plan' to generate a migration for the current contract\",\n ],\n });\n }\n return ok({\n ok: true,\n mode: dbConnection && hasDriver ? 'online' : 'offline',\n migrations: [],\n leafHash: EMPTY_CONTRACT_HASH,\n contractHash,\n summary: 'No migrations found',\n diagnostics,\n });\n }\n\n let graph: MigrationGraph;\n let leafHash: string;\n try {\n graph = reconstructGraph(attested);\n leafHash = findLeaf(graph);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(\n errorRuntime(error.message, { why: error.why, fix: error.fix, meta: { code: error.code } }),\n );\n }\n throw error;\n }\n\n const chain = findPath(graph, EMPTY_CONTRACT_HASH, leafHash);\n if (!chain) {\n return notOk(\n errorRuntime('Cannot reconstruct migration chain', {\n why: `No path from ${EMPTY_CONTRACT_HASH} to leaf ${leafHash}`,\n fix: 'The migration history may have gaps. Check the migrations directory for missing or corrupted packages.',\n }),\n );\n }\n\n let markerHash: string | undefined;\n let mode: 'online' | 'offline' = 'offline';\n\n if (dbConnection && hasDriver) {\n try {\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 try {\n await client.connect(dbConnection);\n const marker = await client.readMarker();\n markerHash = marker?.storageHash ?? EMPTY_CONTRACT_HASH;\n mode = 'online';\n } finally {\n await client.close();\n }\n } catch {\n if (flags.json !== 'object' && !flags.quiet) {\n console.log(' ⚠ Could not connect to database — showing offline status\\n');\n }\n }\n }\n\n const entries = buildMigrationEntries(\n chain,\n attested,\n mode === 'online' ? markerHash : undefined,\n );\n\n const markerInChain =\n markerHash === undefined ||\n markerHash === EMPTY_CONTRACT_HASH ||\n chain.some((e) => e.to === markerHash);\n\n let summary: string;\n if (mode === 'online') {\n if (!markerInChain) {\n summary = `Database marker does not match any migration — was the database managed with 'db update'?`;\n } else {\n const pendingCount = entries.filter((e) => e.status === 'pending').length;\n const appliedCount = entries.filter((e) => e.status === 'applied').length;\n if (pendingCount === 0) {\n summary = `Database is up to date (${appliedCount} migration${appliedCount !== 1 ? 's' : ''} applied)`;\n } else if (markerHash === EMPTY_CONTRACT_HASH) {\n summary = `${pendingCount} pending migration(s) — database has no marker`;\n } else {\n summary = `${pendingCount} pending migration(s) — run 'prisma-next migration apply' to apply`;\n }\n }\n } else {\n summary = `${entries.length} migration(s) on disk`;\n }\n\n if (contractHash !== EMPTY_CONTRACT_HASH && contractHash !== leafHash) {\n diagnostics.push({\n code: 'CONTRACT.AHEAD',\n severity: 'warn',\n message: 'Contract has changed since the last migration was planned',\n hints: [\"Run 'prisma-next migration plan' to generate a migration for the current contract\"],\n });\n }\n\n if (mode === 'online') {\n const pendingCount = entries.filter((e) => e.status === 'pending').length;\n if (!markerInChain) {\n diagnostics.push({\n code: 'MIGRATION.MARKER_DIVERGED',\n severity: 'warn',\n message: 'Database marker does not match any migration in the chain',\n hints: [\n \"The database may have been managed with 'db update' instead of migrations\",\n \"Run 'prisma-next db verify' to inspect the database state\",\n ],\n });\n } else if (pendingCount > 0) {\n diagnostics.push({\n code: 'MIGRATION.DATABASE_BEHIND',\n severity: 'info',\n message: `${pendingCount} migration(s) pending`,\n hints: [\"Run 'prisma-next migration apply' to apply pending migrations\"],\n });\n } else {\n diagnostics.push({\n code: 'MIGRATION.UP_TO_DATE',\n severity: 'info',\n message: 'Database is up to date',\n hints: [],\n });\n }\n }\n\n const result: MigrationStatusResult = {\n ok: true,\n mode,\n migrations: entries,\n leafHash,\n contractHash,\n summary,\n diagnostics,\n ...(markerHash !== undefined ? { markerHash } : {}),\n };\n return ok(result);\n}\n\nexport function createMigrationStatusCommand(): Command {\n const command = new Command('status');\n setCommandDescriptions(\n command,\n 'Show migration chain and applied status',\n 'Displays the migration chain in order. When a database connection\\n' +\n 'is available, shows which migrations are applied and which are pending.\\n' +\n 'Without a database connection, shows the chain from disk only.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const defaultFlags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags: defaultFlags });\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')\n .option('-vv, --trace', 'Trace output')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: MigrationStatusOptions) => {\n const flags = parseGlobalFlags(options);\n\n const result = await executeMigrationStatusCommand(options, flags);\n\n const exitCode = handleResult(result, flags, (statusResult) => {\n if (flags.json === 'object') {\n console.log(JSON.stringify(statusResult, null, 2));\n } else if (!flags.quiet) {\n console.log(formatMigrationStatusOutput(statusResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":";;;;;;;;;;;;;;;AA0EA,SAAS,aAAa,KAGpB;AACA,KAAI,IAAI,WAAW,EAAG,QAAO;EAAE,SAAS;EAAS,gBAAgB;EAAO;CAExE,MAAM,0BAAU,IAAI,KAAqB;AACzC,MAAK,MAAM,MAAM,IACf,SAAQ,IAAI,GAAG,iBAAiB,QAAQ,IAAI,GAAG,eAAe,IAAI,KAAK,EAAE;CAG3E,MAAM,iBAAiB,QAAQ,IAAI,cAAc;CACjD,MAAM,QAAQ,IAAI;CAClB,MAAM,OAAO,UAAU,IAAI,OAAO;AAElC,KAAI,QAAQ,SAAS,EAEnB,QAAO;EAAE,SAAS,GAAG,MAAM,GAAG,KAAK,QADvB,CAAC,GAAG,QAAQ,MAAM,CAAC,CAAC,GACe;EAAI;EAAgB;CAGrE,MAAM,mBAAmB,QAAQ,IAAI,cAAc;AACnD,KAAI,iBACF,QAAO;EAAE,SAAS,GAAG,MAAM,GAAG,KAAK,IAAI,iBAAiB;EAAgB;EAAgB;AAI1F,QAAO;EAAE,SAAS,GAAG,MAAM,GAAG,KAAK,IADrB,CAAC,GAAG,QAAQ,SAAS,CAAC,CAAC,KAAK,CAAC,KAAK,OAAO,GAAG,EAAE,GAAG,MAAM,CACxB,KAAK,KAAK,CAAC;EAAI;EAAgB;;AAG9E,SAAgB,sBACd,OACA,UACA,YACwB;CACxB,MAAM,eAAe,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;CAEjE,MAAM,gBACJ,eAAe,UACf,eAAe,uBACf,MAAM,MAAM,MAAM,EAAE,OAAO,WAAW;CAExC,MAAMA,UAAkC,EAAE;CAC1C,IAAI,gBAAgB,eAAe,UAAa,eAAe;AAE/D,MAAK,MAAM,aAAa,OAAO;EAE7B,MAAM,MADM,aAAa,IAAI,UAAU,QAAQ,EAC7B,OAAO,EAAE;EAC3B,MAAM,EAAE,SAAS,mBAAmB,aAAa,IAAI;EAErD,IAAIC;AACJ,MAAI,eAAe,UAAa,CAAC,cAC/B,UAAS;WACA,cACT,UAAS;MAET,UAAS;AAGX,UAAQ,KAAK;GACX,SAAS,UAAU;GACnB,MAAM,UAAU;GAChB,IAAI,UAAU;GACd,aAAa,UAAU;GACvB,gBAAgB,IAAI;GACpB,kBAAkB;GAClB;GACA;GACD,CAAC;AAEF,MAAI,CAAC,iBAAiB,UAAU,OAAO,WACrC,iBAAgB;;AAIpB,QAAO;;AAGT,eAAe,8BACb,SACA,OAC4D;CAC5D,MAAM,SAAS,MAAM,WAAW,QAAQ,OAAO;CAC/C,MAAM,aAAa,QAAQ,SACvB,SAAS,QAAQ,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC,GAChD;CAEJ,MAAM,gBAAgB,QACpB,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,KAAK,GAAG,QAAQ,KAAK,EAC9D,OAAO,YAAY,OAAO,aAC3B;CACD,MAAM,qBAAqB,SAAS,QAAQ,KAAK,EAAE,cAAc;CAEjE,MAAM,eAAe,QAAQ,MAAM,OAAO,IAAI;CAC9C,MAAM,YAAY,CAAC,CAAC,OAAO;AAE3B,KAAI,MAAM,SAAS,YAAY,CAAC,MAAM,OAAO;EAC3C,MAAMC,UAAmD,CACvD;GAAE,OAAO;GAAU,OAAO;GAAY,EACtC;GAAE,OAAO;GAAc,OAAO;GAAoB,CACnD;AACD,MAAI,gBAAgB,UAClB,SAAQ,KAAK;GAAE,OAAO;GAAY,OAAO,kBAAkB,OAAO,aAAa,CAAC;GAAE,CAAC;EAErF,MAAM,SAAS,mBAAmB;GAChC,SAAS;GACT,aAAa;GACb;GACA;GACD,CAAC;AACF,UAAQ,IAAI,OAAO;;CAGrB,MAAMC,cAAkC,EAAE;CAC1C,IAAIC,eAAuB;AAC3B,KAAI;EAEF,MAAM,kBAAkB,MAAM,SADD,oBAAoB,OAAO,EACK,QAAQ;AACrE,MAAI;GAEF,MAAM,OADc,KAAK,MAAM,gBAAgB,CACtB;AACzB,OAAI,OAAO,SAAS,SAClB,gBAAe;OAEf,aAAY,KAAK;IACf,MAAM;IACN,UAAU;IACV,SAAS;IACT,OAAO,CAAC,6DAA6D;IACtE,CAAC;UAEE;AACN,eAAY,KAAK;IACf,MAAM;IACN,UAAU;IACV,SAAS;IACT,OAAO,CAAC,6DAA6D;IACtE,CAAC;;SAEE;AACN,cAAY,KAAK;GACf,MAAM;GACN,UAAU;GACV,SAAS;GACT,OAAO,CAAC,yDAAyD;GAClE,CAAC;;CAGJ,IAAIC;AACJ,KAAI;AACF,gBAAc,MAAM,kBAAkB,cAAc;UAC7C,OAAO;AACd,MAAI,oBAAoB,GAAG,MAAM,CAC/B,QAAO,MACL,aAAa,MAAM,SAAS;GAAE,KAAK,MAAM;GAAK,KAAK,MAAM;GAAK,MAAM,EAAE,MAAM,MAAM,MAAM;GAAE,CAAC,CAC5F;AAEH,SAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,wCAAwC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACpG,CAAC,CACH;;CAGH,MAAM,WAAW,YAAY,QAAQ,MAAM,OAAO,EAAE,SAAS,gBAAgB,SAAS;AAEtF,KAAI,SAAS,WAAW,GAAG;AACzB,MAAI,iBAAiB,oBACnB,aAAY,KAAK;GACf,MAAM;GACN,UAAU;GACV,SAAS;GACT,OAAO,CACL,oFACD;GACF,CAAC;AAEJ,SAAO,GAAG;GACR,IAAI;GACJ,MAAM,gBAAgB,YAAY,WAAW;GAC7C,YAAY,EAAE;GACd,UAAU;GACV;GACA,SAAS;GACT;GACD,CAAC;;CAGJ,IAAIC;CACJ,IAAIC;AACJ,KAAI;AACF,UAAQ,iBAAiB,SAAS;AAClC,aAAW,SAAS,MAAM;UACnB,OAAO;AACd,MAAI,oBAAoB,GAAG,MAAM,CAC/B,QAAO,MACL,aAAa,MAAM,SAAS;GAAE,KAAK,MAAM;GAAK,KAAK,MAAM;GAAK,MAAM,EAAE,MAAM,MAAM,MAAM;GAAE,CAAC,CAC5F;AAEH,QAAM;;CAGR,MAAM,QAAQ,SAAS,OAAO,qBAAqB,SAAS;AAC5D,KAAI,CAAC,MACH,QAAO,MACL,aAAa,sCAAsC;EACjD,KAAK,gBAAgB,oBAAoB,WAAW;EACpD,KAAK;EACN,CAAC,CACH;CAGH,IAAIC;CACJ,IAAIC,OAA6B;AAEjC,KAAI,gBAAgB,UAClB,KAAI;EACF,MAAM,SAAS,oBAAoB;GACjC,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,QAAQ,OAAO;GACf,gBAAgB,OAAO,kBAAkB,EAAE;GAC5C,CAAC;AACF,MAAI;AACF,SAAM,OAAO,QAAQ,aAAa;AAElC,iBADe,MAAM,OAAO,YAAY,GACnB,eAAe;AACpC,UAAO;YACC;AACR,SAAM,OAAO,OAAO;;SAEhB;AACN,MAAI,MAAM,SAAS,YAAY,CAAC,MAAM,MACpC,SAAQ,IAAI,+DAA+D;;CAKjF,MAAM,UAAU,sBACd,OACA,UACA,SAAS,WAAW,aAAa,OAClC;CAED,MAAM,gBACJ,eAAe,UACf,eAAe,uBACf,MAAM,MAAM,MAAM,EAAE,OAAO,WAAW;CAExC,IAAIC;AACJ,KAAI,SAAS,SACX,KAAI,CAAC,cACH,WAAU;MACL;EACL,MAAM,eAAe,QAAQ,QAAQ,MAAM,EAAE,WAAW,UAAU,CAAC;EACnE,MAAM,eAAe,QAAQ,QAAQ,MAAM,EAAE,WAAW,UAAU,CAAC;AACnE,MAAI,iBAAiB,EACnB,WAAU,2BAA2B,aAAa,YAAY,iBAAiB,IAAI,MAAM,GAAG;WACnF,eAAe,oBACxB,WAAU,GAAG,aAAa;MAE1B,WAAU,GAAG,aAAa;;KAI9B,WAAU,GAAG,QAAQ,OAAO;AAG9B,KAAI,iBAAiB,uBAAuB,iBAAiB,SAC3D,aAAY,KAAK;EACf,MAAM;EACN,UAAU;EACV,SAAS;EACT,OAAO,CAAC,oFAAoF;EAC7F,CAAC;AAGJ,KAAI,SAAS,UAAU;EACrB,MAAM,eAAe,QAAQ,QAAQ,MAAM,EAAE,WAAW,UAAU,CAAC;AACnE,MAAI,CAAC,cACH,aAAY,KAAK;GACf,MAAM;GACN,UAAU;GACV,SAAS;GACT,OAAO,CACL,6EACA,4DACD;GACF,CAAC;WACO,eAAe,EACxB,aAAY,KAAK;GACf,MAAM;GACN,UAAU;GACV,SAAS,GAAG,aAAa;GACzB,OAAO,CAAC,gEAAgE;GACzE,CAAC;MAEF,aAAY,KAAK;GACf,MAAM;GACN,UAAU;GACV,SAAS;GACT,OAAO,EAAE;GACV,CAAC;;AAcN,QAAO,GAV+B;EACpC,IAAI;EACJ;EACA,YAAY;EACZ;EACA;EACA;EACA;EACA,GAAI,eAAe,SAAY,EAAE,YAAY,GAAG,EAAE;EACnD,CACgB;;AAGnB,SAAgB,+BAAwC;CACtD,MAAM,UAAU,IAAI,QAAQ,SAAS;AACrC,wBACE,SACA,2CACA,6MAGD;AACD,SACG,cAAc,EACb,aAAa,QAAQ;AAEnB,SAAO,kBAAkB;GAAE,SAAS;GAAK,OADpB,iBAAiB,EAAE,CAAC;GACqB,CAAC;IAElE,CAAC,CACD,OAAO,cAAc,6BAA6B,CAClD,OAAO,mBAAmB,gCAAgC,CAC1D,OAAO,mBAAmB,2BAA2B,MAAM,CAC3D,OAAO,eAAe,0BAA0B,CAChD,OAAO,iBAAiB,iBAAiB,CACzC,OAAO,gBAAgB,eAAe,CACtC,OAAO,gBAAgB,2BAA2B,CAClD,OAAO,WAAW,qBAAqB,CACvC,OAAO,cAAc,uBAAuB,CAC5C,OAAO,OAAO,YAAoC;EACjD,MAAM,QAAQ,iBAAiB,QAAQ;EAIvC,MAAM,WAAW,aAFF,MAAM,8BAA8B,SAAS,MAAM,EAE5B,QAAQ,iBAAiB;AAC7D,OAAI,MAAM,SAAS,SACjB,SAAQ,IAAI,KAAK,UAAU,cAAc,MAAM,EAAE,CAAC;YACzC,CAAC,MAAM,MAChB,SAAQ,IAAI,4BAA4B,cAAc,MAAM,CAAC;IAE/D;AAEF,UAAQ,KAAK,SAAS;GACtB;AAEJ,QAAO"}
1
+ {"version":3,"file":"migration-status.mjs","names":["entries: MigrationStatusEntry[]","status: 'applied' | 'pending' | 'unknown'","details: Array<{ label: string; value: string }>","diagnostics: StatusDiagnostic[]","contractHash: string","allPackages: readonly MigrationPackage[]","graph: MigrationGraph","leafHash: string","markerHash: string | undefined","mode: 'online' | 'offline'","summary: string"],"sources":["../../src/commands/migration-status.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { EMPTY_CONTRACT_HASH } from '@prisma-next/core-control-plane/constants';\nimport type { MigrationPlanOperation } from '@prisma-next/core-control-plane/types';\nimport { findLeaf, findPath, reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type {\n MigrationChainEntry,\n MigrationGraph,\n MigrationPackage,\n} from '@prisma-next/migration-tools/types';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/types';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport { type CliStructuredError, errorRuntime, errorUnexpected } from '../utils/cli-errors';\nimport {\n maskConnectionUrl,\n resolveContractPath,\n setCommandDescriptions,\n} from '../utils/command-helpers';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatMigrationStatusOutput,\n formatStyledHeader,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\n\ninterface MigrationStatusOptions {\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\nexport interface MigrationStatusEntry {\n readonly dirName: string;\n readonly from: string;\n readonly to: string;\n readonly migrationId: string | null;\n readonly operationCount: number;\n readonly operationSummary: string;\n readonly hasDestructive: boolean;\n readonly status: 'applied' | 'pending' | 'unknown';\n}\n\nexport interface StatusDiagnostic {\n readonly code: string;\n readonly severity: 'warn' | 'info';\n readonly message: string;\n readonly hints: readonly string[];\n}\n\nexport interface MigrationStatusResult {\n readonly ok: true;\n readonly mode: 'online' | 'offline';\n readonly migrations: readonly MigrationStatusEntry[];\n readonly markerHash?: string;\n readonly leafHash: string;\n readonly contractHash: string;\n readonly summary: string;\n readonly diagnostics: readonly StatusDiagnostic[];\n}\n\nfunction summarizeOps(ops: readonly MigrationPlanOperation[]): {\n summary: string;\n hasDestructive: boolean;\n} {\n if (ops.length === 0) return { summary: '0 ops', hasDestructive: false };\n\n const classes = new Map<string, number>();\n for (const op of ops) {\n classes.set(op.operationClass, (classes.get(op.operationClass) ?? 0) + 1);\n }\n\n const hasDestructive = classes.has('destructive');\n const count = ops.length;\n const noun = count === 1 ? 'op' : 'ops';\n\n if (classes.size === 1) {\n const cls = [...classes.keys()][0]!;\n return { summary: `${count} ${noun} (all ${cls})`, hasDestructive };\n }\n\n const destructiveCount = classes.get('destructive');\n if (destructiveCount) {\n return { summary: `${count} ${noun} (${destructiveCount} destructive)`, hasDestructive };\n }\n\n const parts = [...classes.entries()].map(([cls, n]) => `${n} ${cls}`);\n return { summary: `${count} ${noun} (${parts.join(', ')})`, hasDestructive };\n}\n\nexport function buildMigrationEntries(\n chain: readonly MigrationChainEntry[],\n packages: readonly MigrationPackage[],\n markerHash: string | undefined,\n): MigrationStatusEntry[] {\n const pkgByDirName = new Map(packages.map((p) => [p.dirName, p]));\n\n const markerInChain =\n markerHash === undefined ||\n markerHash === EMPTY_CONTRACT_HASH ||\n chain.some((e) => e.to === markerHash);\n\n const entries: MigrationStatusEntry[] = [];\n let reachedMarker = markerHash === undefined || markerHash === EMPTY_CONTRACT_HASH;\n\n for (const migration of chain) {\n const pkg = pkgByDirName.get(migration.dirName);\n const ops = (pkg?.ops ?? []) as readonly MigrationPlanOperation[];\n const { summary, hasDestructive } = summarizeOps(ops);\n\n let status: 'applied' | 'pending' | 'unknown';\n if (markerHash === undefined || !markerInChain) {\n status = 'unknown';\n } else if (reachedMarker) {\n status = 'pending';\n } else {\n status = 'applied';\n }\n\n entries.push({\n dirName: migration.dirName,\n from: migration.from,\n to: migration.to,\n migrationId: migration.migrationId,\n operationCount: ops.length,\n operationSummary: summary,\n hasDestructive,\n status,\n });\n\n if (!reachedMarker && migration.to === markerHash) {\n reachedMarker = true;\n }\n }\n\n return entries;\n}\n\nasync function executeMigrationStatusCommand(\n options: MigrationStatusOptions,\n flags: GlobalFlags,\n): Promise<Result<MigrationStatusResult, CliStructuredError>> {\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 const migrationsDir = resolve(\n options.config ? resolve(options.config, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n\n const dbConnection = options.db ?? config.db?.connection;\n const hasDriver = !!config.driver;\n\n if (flags.json !== 'object' && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: migrationsRelative },\n ];\n if (dbConnection && hasDriver) {\n details.push({ label: 'database', value: maskConnectionUrl(String(dbConnection)) });\n }\n const header = formatStyledHeader({\n command: 'migration status',\n description: 'Show migration chain and applied status',\n details,\n flags,\n });\n console.log(header);\n }\n\n const diagnostics: StatusDiagnostic[] = [];\n let contractHash: string = EMPTY_CONTRACT_HASH;\n try {\n const contractPathAbsolute = resolveContractPath(config);\n const contractContent = await readFile(contractPathAbsolute, 'utf-8');\n try {\n const contractRaw = JSON.parse(contractContent) as Record<string, unknown>;\n const hash = contractRaw['storageHash'];\n if (typeof hash === 'string') {\n contractHash = hash;\n } else {\n diagnostics.push({\n code: 'CONTRACT.MISSING_HASH',\n severity: 'warn',\n message: 'Contract file exists but has no storageHash field',\n hints: [\"Run 'prisma-next contract emit' to regenerate the contract\"],\n });\n }\n } catch {\n diagnostics.push({\n code: 'CONTRACT.INVALID_JSON',\n severity: 'warn',\n message: 'Contract file contains invalid JSON',\n hints: [\"Run 'prisma-next contract emit' to regenerate the contract\"],\n });\n }\n } catch {\n diagnostics.push({\n code: 'CONTRACT.UNREADABLE',\n severity: 'warn',\n message: 'Could not read contract file — contract state unknown',\n hints: [\"Run 'prisma-next contract emit' to generate a contract\"],\n });\n }\n\n let allPackages: readonly MigrationPackage[];\n try {\n allPackages = await readMigrationsDir(migrationsDir);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(\n errorRuntime(error.message, { why: error.why, fix: error.fix, meta: { code: error.code } }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migrations directory: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n const attested = allPackages.filter((p) => typeof p.manifest.migrationId === 'string');\n\n if (attested.length === 0) {\n if (contractHash !== EMPTY_CONTRACT_HASH) {\n diagnostics.push({\n code: 'CONTRACT.AHEAD',\n severity: 'warn',\n message: 'Contract has changed since the last migration was planned',\n hints: [\n \"Run 'prisma-next migration plan' to generate a migration for the current contract\",\n ],\n });\n }\n return ok({\n ok: true,\n mode: dbConnection && hasDriver ? 'online' : 'offline',\n migrations: [],\n leafHash: EMPTY_CONTRACT_HASH,\n contractHash,\n summary: 'No migrations found',\n diagnostics,\n });\n }\n\n let graph: MigrationGraph;\n let leafHash: string;\n try {\n graph = reconstructGraph(attested);\n leafHash = findLeaf(graph);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(\n errorRuntime(error.message, { why: error.why, fix: error.fix, meta: { code: error.code } }),\n );\n }\n throw error;\n }\n\n const chain = findPath(graph, EMPTY_CONTRACT_HASH, leafHash);\n if (!chain) {\n return notOk(\n errorRuntime('Cannot reconstruct migration chain', {\n why: `No path from ${EMPTY_CONTRACT_HASH} to leaf ${leafHash}`,\n fix: 'The migration history may have gaps. Check the migrations directory for missing or corrupted packages.',\n }),\n );\n }\n\n let markerHash: string | undefined;\n let mode: 'online' | 'offline' = 'offline';\n\n if (dbConnection && hasDriver) {\n try {\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 try {\n await client.connect(dbConnection);\n const marker = await client.readMarker();\n markerHash = marker?.storageHash ?? EMPTY_CONTRACT_HASH;\n mode = 'online';\n } finally {\n await client.close();\n }\n } catch {\n if (flags.json !== 'object' && !flags.quiet) {\n console.log(' ⚠ Could not connect to database — showing offline status\\n');\n }\n }\n }\n\n const entries = buildMigrationEntries(\n chain,\n attested,\n mode === 'online' ? markerHash : undefined,\n );\n\n const markerInChain =\n markerHash === undefined ||\n markerHash === EMPTY_CONTRACT_HASH ||\n chain.some((e) => e.to === markerHash);\n\n let summary: string;\n if (mode === 'online') {\n if (!markerInChain) {\n summary = `Database marker does not match any migration — was the database managed with 'db update'?`;\n } else {\n const pendingCount = entries.filter((e) => e.status === 'pending').length;\n const appliedCount = entries.filter((e) => e.status === 'applied').length;\n if (pendingCount === 0) {\n summary = `Database is up to date (${appliedCount} migration${appliedCount !== 1 ? 's' : ''} applied)`;\n } else if (markerHash === EMPTY_CONTRACT_HASH) {\n summary = `${pendingCount} pending migration(s) — database has no marker`;\n } else {\n summary = `${pendingCount} pending migration(s) — run 'prisma-next migration apply' to apply`;\n }\n }\n } else {\n summary = `${entries.length} migration(s) on disk`;\n }\n\n if (contractHash !== EMPTY_CONTRACT_HASH && contractHash !== leafHash) {\n diagnostics.push({\n code: 'CONTRACT.AHEAD',\n severity: 'warn',\n message: 'Contract has changed since the last migration was planned',\n hints: [\"Run 'prisma-next migration plan' to generate a migration for the current contract\"],\n });\n }\n\n if (mode === 'online') {\n const pendingCount = entries.filter((e) => e.status === 'pending').length;\n if (!markerInChain) {\n diagnostics.push({\n code: 'MIGRATION.MARKER_DIVERGED',\n severity: 'warn',\n message: 'Database marker does not match any migration in the chain',\n hints: [\n \"The database may have been managed with 'db update' instead of migrations\",\n \"Run 'prisma-next db verify' to inspect the database state\",\n ],\n });\n } else if (pendingCount > 0) {\n diagnostics.push({\n code: 'MIGRATION.DATABASE_BEHIND',\n severity: 'info',\n message: `${pendingCount} migration(s) pending`,\n hints: [\"Run 'prisma-next migration apply' to apply pending migrations\"],\n });\n } else {\n diagnostics.push({\n code: 'MIGRATION.UP_TO_DATE',\n severity: 'info',\n message: 'Database is up to date',\n hints: [],\n });\n }\n }\n\n const result: MigrationStatusResult = {\n ok: true,\n mode,\n migrations: entries,\n leafHash,\n contractHash,\n summary,\n diagnostics,\n ...(markerHash !== undefined ? { markerHash } : {}),\n };\n return ok(result);\n}\n\nexport function createMigrationStatusCommand(): Command {\n const command = new Command('status');\n setCommandDescriptions(\n command,\n 'Show migration chain and applied status',\n 'Displays the migration chain in order. When a database connection\\n' +\n 'is available, shows which migrations are applied and which are pending.\\n' +\n 'Without a database connection, shows the chain from disk only.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const defaultFlags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags: defaultFlags });\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')\n .option('-vv, --trace', 'Trace output')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: MigrationStatusOptions) => {\n const flags = parseGlobalFlags(options);\n\n const result = await executeMigrationStatusCommand(options, flags);\n\n const exitCode = handleResult(result, flags, (statusResult) => {\n if (flags.json === 'object') {\n console.log(JSON.stringify(statusResult, null, 2));\n } else if (!flags.quiet) {\n console.log(formatMigrationStatusOutput(statusResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { t as loadConfig } from "../config-loader-PPf4CtDj.mjs";
2
2
  import { m as errorRuntime, r as errorContractConfigMissing } from "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
3
  import { t as createControlClient } from "../client-PimzSD1f.mjs";
5
4
  import { dirname, isAbsolute, join, resolve } from "pathe";
6
5
  import { createControlPlaneStack } from "@prisma-next/core-control-plane/stack";
@@ -1 +1 @@
1
- {"version":3,"file":"control-api.mjs","names":["providerResult: Awaited<ReturnType<typeof contractConfig.source>>"],"sources":["../../src/control-api/operations/contract-emit.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { createControlPlaneStack } from '@prisma-next/core-control-plane/stack';\nimport { abortable } from '@prisma-next/utils/abortable';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { dirname, isAbsolute, join, resolve } from 'pathe';\nimport { loadConfig } from '../../config-loader';\nimport { errorContractConfigMissing, errorRuntime } from '../../utils/cli-errors';\nimport type { ContractEmitOptions, ContractEmitResult } from '../types';\n\ninterface ProviderFailureLike {\n readonly summary: string;\n readonly diagnostics: readonly unknown[];\n readonly meta?: unknown;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isAbortError(error: unknown): boolean {\n return isRecord(error) && typeof error['name'] === 'string' && error['name'] === 'AbortError';\n}\n\nfunction isProviderFailureLike(value: unknown): value is ProviderFailureLike {\n return (\n isRecord(value) && typeof value['summary'] === 'string' && Array.isArray(value['diagnostics'])\n );\n}\n\n/**\n * Executes the contract emit operation.\n *\n * This is an offline operation that:\n * 1. Loads the Prisma Next config from the specified path\n * 2. Resolves the contract source from config\n * 3. Creates a control plane stack and family instance\n * 4. Emits contract artifacts (JSON and DTS)\n * 5. Writes files to the paths specified in config\n *\n * Supports AbortSignal for cancellation, enabling \"last change wins\" behavior.\n *\n * @param options - Options including configPath and optional signal\n * @returns File paths and hashes of emitted artifacts\n * @throws If config loading fails, contract is invalid, or file I/O fails\n * @throws signal.reason if cancelled via AbortSignal (typically DOMException with name 'AbortError')\n */\nexport async function executeContractEmit(\n options: ContractEmitOptions,\n): Promise<ContractEmitResult> {\n const { configPath, signal = new AbortController().signal } = options;\n const unlessAborted = abortable(signal);\n\n // Load config using the existing config loader\n const config = await unlessAborted(loadConfig(configPath));\n\n // Validate contract config is present\n if (!config.contract) {\n throw errorContractConfigMissing({\n why: 'Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n });\n }\n\n const contractConfig = config.contract;\n\n // Validate output path is present and ends with .json\n if (!contractConfig.output) {\n throw errorContractConfigMissing({\n why: 'Contract config must have output path. This should not happen if defineConfig() was used.',\n });\n }\n if (!contractConfig.output.endsWith('.json')) {\n throw errorContractConfigMissing({\n why: 'Contract config output path must end with .json (e.g., \"src/prisma/contract.json\")',\n });\n }\n\n // Validate source exists and is callable\n if (typeof contractConfig.source !== 'function') {\n throw errorContractConfigMissing({\n why: 'Contract config must include a valid source provider function',\n });\n }\n\n // Normalize configPath and resolve artifact paths relative to config file directory\n const normalizedConfigPath = resolve(configPath);\n const configDir = dirname(normalizedConfigPath);\n const outputJsonPath = isAbsolute(contractConfig.output)\n ? contractConfig.output\n : join(configDir, contractConfig.output);\n // Colocate .d.ts with .json (contract.json → contract.d.ts)\n const outputDtsPath = `${outputJsonPath.slice(0, -5)}.d.ts`;\n\n let providerResult: Awaited<ReturnType<typeof contractConfig.source>>;\n try {\n providerResult = await unlessAborted(contractConfig.source());\n } catch (error) {\n if (signal.aborted || isAbortError(error)) {\n throw error;\n }\n throw errorRuntime('Failed to resolve contract source', {\n why: error instanceof Error ? error.message : String(error),\n fix: 'Ensure contract.source resolves to ok(contractIR) or returns structured diagnostics.',\n });\n }\n\n if (!isRecord(providerResult) || typeof providerResult.ok !== 'boolean') {\n throw errorRuntime('Failed to resolve contract source', {\n why: 'Contract source provider returned malformed result shape.',\n fix: 'Ensure contract.source resolves to ok(contractIR) or notOk({ summary, diagnostics }).',\n });\n }\n\n if (providerResult.ok && !('value' in providerResult)) {\n throw errorRuntime('Failed to resolve contract source', {\n why: 'Contract source provider returned malformed success result: missing value.',\n fix: 'Ensure contract.source success payload is ok(contractIR).',\n });\n }\n\n if (!providerResult.ok && !isProviderFailureLike(providerResult.failure)) {\n throw errorRuntime('Failed to resolve contract source', {\n why: 'Contract source provider returned malformed failure result: expected summary and diagnostics.',\n fix: 'Ensure contract.source failure payload is notOk({ summary, diagnostics, meta? }).',\n });\n }\n\n if (!providerResult.ok) {\n throw errorRuntime('Failed to resolve contract source', {\n why: providerResult.failure.summary,\n fix: 'Fix contract source diagnostics and return ok(contractIR).',\n meta: {\n diagnostics: providerResult.failure.diagnostics,\n ...ifDefined('providerMeta', providerResult.failure.meta),\n },\n });\n }\n\n // Create control plane stack from config\n const stack = createControlPlaneStack(config);\n const familyInstance = config.family.create(stack);\n\n // Emit contract via family instance\n const emitResult = await unlessAborted(\n familyInstance.emitContract({ contractIR: providerResult.value }),\n );\n\n // Create directory if needed and write files (both colocated)\n await unlessAborted(mkdir(dirname(outputJsonPath), { recursive: true }));\n await unlessAborted(writeFile(outputJsonPath, emitResult.contractJson, 'utf-8'));\n await unlessAborted(writeFile(outputDtsPath, emitResult.contractDts, 'utf-8'));\n\n return {\n storageHash: emitResult.storageHash,\n ...ifDefined('executionHash', emitResult.executionHash),\n profileHash: emitResult.profileHash,\n files: {\n json: outputJsonPath,\n dts: outputDtsPath,\n },\n };\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU;;AAGhD,SAAS,aAAa,OAAyB;AAC7C,QAAO,SAAS,MAAM,IAAI,OAAO,MAAM,YAAY,YAAY,MAAM,YAAY;;AAGnF,SAAS,sBAAsB,OAA8C;AAC3E,QACE,SAAS,MAAM,IAAI,OAAO,MAAM,eAAe,YAAY,MAAM,QAAQ,MAAM,eAAe;;;;;;;;;;;;;;;;;;;AAqBlG,eAAsB,oBACpB,SAC6B;CAC7B,MAAM,EAAE,YAAY,SAAS,IAAI,iBAAiB,CAAC,WAAW;CAC9D,MAAM,gBAAgB,UAAU,OAAO;CAGvC,MAAM,SAAS,MAAM,cAAc,WAAW,WAAW,CAAC;AAG1D,KAAI,CAAC,OAAO,SACV,OAAM,2BAA2B,EAC/B,KAAK,0GACN,CAAC;CAGJ,MAAM,iBAAiB,OAAO;AAG9B,KAAI,CAAC,eAAe,OAClB,OAAM,2BAA2B,EAC/B,KAAK,6FACN,CAAC;AAEJ,KAAI,CAAC,eAAe,OAAO,SAAS,QAAQ,CAC1C,OAAM,2BAA2B,EAC/B,KAAK,wFACN,CAAC;AAIJ,KAAI,OAAO,eAAe,WAAW,WACnC,OAAM,2BAA2B,EAC/B,KAAK,iEACN,CAAC;CAKJ,MAAM,YAAY,QADW,QAAQ,WAAW,CACD;CAC/C,MAAM,iBAAiB,WAAW,eAAe,OAAO,GACpD,eAAe,SACf,KAAK,WAAW,eAAe,OAAO;CAE1C,MAAM,gBAAgB,GAAG,eAAe,MAAM,GAAG,GAAG,CAAC;CAErD,IAAIA;AACJ,KAAI;AACF,mBAAiB,MAAM,cAAc,eAAe,QAAQ,CAAC;UACtD,OAAO;AACd,MAAI,OAAO,WAAW,aAAa,MAAM,CACvC,OAAM;AAER,QAAM,aAAa,qCAAqC;GACtD,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAC3D,KAAK;GACN,CAAC;;AAGJ,KAAI,CAAC,SAAS,eAAe,IAAI,OAAO,eAAe,OAAO,UAC5D,OAAM,aAAa,qCAAqC;EACtD,KAAK;EACL,KAAK;EACN,CAAC;AAGJ,KAAI,eAAe,MAAM,EAAE,WAAW,gBACpC,OAAM,aAAa,qCAAqC;EACtD,KAAK;EACL,KAAK;EACN,CAAC;AAGJ,KAAI,CAAC,eAAe,MAAM,CAAC,sBAAsB,eAAe,QAAQ,CACtE,OAAM,aAAa,qCAAqC;EACtD,KAAK;EACL,KAAK;EACN,CAAC;AAGJ,KAAI,CAAC,eAAe,GAClB,OAAM,aAAa,qCAAqC;EACtD,KAAK,eAAe,QAAQ;EAC5B,KAAK;EACL,MAAM;GACJ,aAAa,eAAe,QAAQ;GACpC,GAAG,UAAU,gBAAgB,eAAe,QAAQ,KAAK;GAC1D;EACF,CAAC;CAIJ,MAAM,QAAQ,wBAAwB,OAAO;CAI7C,MAAM,aAAa,MAAM,cAHF,OAAO,OAAO,OAAO,MAAM,CAIjC,aAAa,EAAE,YAAY,eAAe,OAAO,CAAC,CAClE;AAGD,OAAM,cAAc,MAAM,QAAQ,eAAe,EAAE,EAAE,WAAW,MAAM,CAAC,CAAC;AACxE,OAAM,cAAc,UAAU,gBAAgB,WAAW,cAAc,QAAQ,CAAC;AAChF,OAAM,cAAc,UAAU,eAAe,WAAW,aAAa,QAAQ,CAAC;AAE9E,QAAO;EACL,aAAa,WAAW;EACxB,GAAG,UAAU,iBAAiB,WAAW,cAAc;EACvD,aAAa,WAAW;EACxB,OAAO;GACL,MAAM;GACN,KAAK;GACN;EACF"}
1
+ {"version":3,"file":"control-api.mjs","names":["providerResult: Awaited<ReturnType<typeof contractConfig.source>>"],"sources":["../../src/control-api/operations/contract-emit.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { createControlPlaneStack } from '@prisma-next/core-control-plane/stack';\nimport { abortable } from '@prisma-next/utils/abortable';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { dirname, isAbsolute, join, resolve } from 'pathe';\nimport { loadConfig } from '../../config-loader';\nimport { errorContractConfigMissing, errorRuntime } from '../../utils/cli-errors';\nimport type { ContractEmitOptions, ContractEmitResult } from '../types';\n\ninterface ProviderFailureLike {\n readonly summary: string;\n readonly diagnostics: readonly unknown[];\n readonly meta?: unknown;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isAbortError(error: unknown): boolean {\n return isRecord(error) && typeof error['name'] === 'string' && error['name'] === 'AbortError';\n}\n\nfunction isProviderFailureLike(value: unknown): value is ProviderFailureLike {\n return (\n isRecord(value) && typeof value['summary'] === 'string' && Array.isArray(value['diagnostics'])\n );\n}\n\n/**\n * Executes the contract emit operation.\n *\n * This is an offline operation that:\n * 1. Loads the Prisma Next config from the specified path\n * 2. Resolves the contract source from config\n * 3. Creates a control plane stack and family instance\n * 4. Emits contract artifacts (JSON and DTS)\n * 5. Writes files to the paths specified in config\n *\n * Supports AbortSignal for cancellation, enabling \"last change wins\" behavior.\n *\n * @param options - Options including configPath and optional signal\n * @returns File paths and hashes of emitted artifacts\n * @throws If config loading fails, contract is invalid, or file I/O fails\n * @throws signal.reason if cancelled via AbortSignal (typically DOMException with name 'AbortError')\n */\nexport async function executeContractEmit(\n options: ContractEmitOptions,\n): Promise<ContractEmitResult> {\n const { configPath, signal = new AbortController().signal } = options;\n const unlessAborted = abortable(signal);\n\n // Load config using the existing config loader\n const config = await unlessAborted(loadConfig(configPath));\n\n // Validate contract config is present\n if (!config.contract) {\n throw errorContractConfigMissing({\n why: 'Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n });\n }\n\n const contractConfig = config.contract;\n\n // Validate output path is present and ends with .json\n if (!contractConfig.output) {\n throw errorContractConfigMissing({\n why: 'Contract config must have output path. This should not happen if defineConfig() was used.',\n });\n }\n if (!contractConfig.output.endsWith('.json')) {\n throw errorContractConfigMissing({\n why: 'Contract config output path must end with .json (e.g., \"src/prisma/contract.json\")',\n });\n }\n\n // Validate source exists and is callable\n if (typeof contractConfig.source !== 'function') {\n throw errorContractConfigMissing({\n why: 'Contract config must include a valid source provider function',\n });\n }\n\n // Normalize configPath and resolve artifact paths relative to config file directory\n const normalizedConfigPath = resolve(configPath);\n const configDir = dirname(normalizedConfigPath);\n const outputJsonPath = isAbsolute(contractConfig.output)\n ? contractConfig.output\n : join(configDir, contractConfig.output);\n // Colocate .d.ts with .json (contract.json → contract.d.ts)\n const outputDtsPath = `${outputJsonPath.slice(0, -5)}.d.ts`;\n\n let providerResult: Awaited<ReturnType<typeof contractConfig.source>>;\n try {\n providerResult = await unlessAborted(contractConfig.source());\n } catch (error) {\n if (signal.aborted || isAbortError(error)) {\n throw error;\n }\n throw errorRuntime('Failed to resolve contract source', {\n why: error instanceof Error ? error.message : String(error),\n fix: 'Ensure contract.source resolves to ok(contractIR) or returns structured diagnostics.',\n });\n }\n\n if (!isRecord(providerResult) || typeof providerResult.ok !== 'boolean') {\n throw errorRuntime('Failed to resolve contract source', {\n why: 'Contract source provider returned malformed result shape.',\n fix: 'Ensure contract.source resolves to ok(contractIR) or notOk({ summary, diagnostics }).',\n });\n }\n\n if (providerResult.ok && !('value' in providerResult)) {\n throw errorRuntime('Failed to resolve contract source', {\n why: 'Contract source provider returned malformed success result: missing value.',\n fix: 'Ensure contract.source success payload is ok(contractIR).',\n });\n }\n\n if (!providerResult.ok && !isProviderFailureLike(providerResult.failure)) {\n throw errorRuntime('Failed to resolve contract source', {\n why: 'Contract source provider returned malformed failure result: expected summary and diagnostics.',\n fix: 'Ensure contract.source failure payload is notOk({ summary, diagnostics, meta? }).',\n });\n }\n\n if (!providerResult.ok) {\n throw errorRuntime('Failed to resolve contract source', {\n why: providerResult.failure.summary,\n fix: 'Fix contract source diagnostics and return ok(contractIR).',\n meta: {\n diagnostics: providerResult.failure.diagnostics,\n ...ifDefined('providerMeta', providerResult.failure.meta),\n },\n });\n }\n\n // Create control plane stack from config\n const stack = createControlPlaneStack(config);\n const familyInstance = config.family.create(stack);\n\n // Emit contract via family instance\n const emitResult = await unlessAborted(\n familyInstance.emitContract({ contractIR: providerResult.value }),\n );\n\n // Create directory if needed and write files (both colocated)\n await unlessAborted(mkdir(dirname(outputJsonPath), { recursive: true }));\n await unlessAborted(writeFile(outputJsonPath, emitResult.contractJson, 'utf-8'));\n await unlessAborted(writeFile(outputDtsPath, emitResult.contractDts, 'utf-8'));\n\n return {\n storageHash: emitResult.storageHash,\n ...ifDefined('executionHash', emitResult.executionHash),\n profileHash: emitResult.profileHash,\n files: {\n json: outputJsonPath,\n dts: outputDtsPath,\n },\n };\n}\n"],"mappings":";;;;;;;;;;AAeA,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU;;AAGhD,SAAS,aAAa,OAAyB;AAC7C,QAAO,SAAS,MAAM,IAAI,OAAO,MAAM,YAAY,YAAY,MAAM,YAAY;;AAGnF,SAAS,sBAAsB,OAA8C;AAC3E,QACE,SAAS,MAAM,IAAI,OAAO,MAAM,eAAe,YAAY,MAAM,QAAQ,MAAM,eAAe;;;;;;;;;;;;;;;;;;;AAqBlG,eAAsB,oBACpB,SAC6B;CAC7B,MAAM,EAAE,YAAY,SAAS,IAAI,iBAAiB,CAAC,WAAW;CAC9D,MAAM,gBAAgB,UAAU,OAAO;CAGvC,MAAM,SAAS,MAAM,cAAc,WAAW,WAAW,CAAC;AAG1D,KAAI,CAAC,OAAO,SACV,OAAM,2BAA2B,EAC/B,KAAK,0GACN,CAAC;CAGJ,MAAM,iBAAiB,OAAO;AAG9B,KAAI,CAAC,eAAe,OAClB,OAAM,2BAA2B,EAC/B,KAAK,6FACN,CAAC;AAEJ,KAAI,CAAC,eAAe,OAAO,SAAS,QAAQ,CAC1C,OAAM,2BAA2B,EAC/B,KAAK,wFACN,CAAC;AAIJ,KAAI,OAAO,eAAe,WAAW,WACnC,OAAM,2BAA2B,EAC/B,KAAK,iEACN,CAAC;CAKJ,MAAM,YAAY,QADW,QAAQ,WAAW,CACD;CAC/C,MAAM,iBAAiB,WAAW,eAAe,OAAO,GACpD,eAAe,SACf,KAAK,WAAW,eAAe,OAAO;CAE1C,MAAM,gBAAgB,GAAG,eAAe,MAAM,GAAG,GAAG,CAAC;CAErD,IAAIA;AACJ,KAAI;AACF,mBAAiB,MAAM,cAAc,eAAe,QAAQ,CAAC;UACtD,OAAO;AACd,MAAI,OAAO,WAAW,aAAa,MAAM,CACvC,OAAM;AAER,QAAM,aAAa,qCAAqC;GACtD,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAC3D,KAAK;GACN,CAAC;;AAGJ,KAAI,CAAC,SAAS,eAAe,IAAI,OAAO,eAAe,OAAO,UAC5D,OAAM,aAAa,qCAAqC;EACtD,KAAK;EACL,KAAK;EACN,CAAC;AAGJ,KAAI,eAAe,MAAM,EAAE,WAAW,gBACpC,OAAM,aAAa,qCAAqC;EACtD,KAAK;EACL,KAAK;EACN,CAAC;AAGJ,KAAI,CAAC,eAAe,MAAM,CAAC,sBAAsB,eAAe,QAAQ,CACtE,OAAM,aAAa,qCAAqC;EACtD,KAAK;EACL,KAAK;EACN,CAAC;AAGJ,KAAI,CAAC,eAAe,GAClB,OAAM,aAAa,qCAAqC;EACtD,KAAK,eAAe,QAAQ;EAC5B,KAAK;EACL,MAAM;GACJ,aAAa,eAAe,QAAQ;GACpC,GAAG,UAAU,gBAAgB,eAAe,QAAQ,KAAK;GAC1D;EACF,CAAC;CAIJ,MAAM,QAAQ,wBAAwB,OAAO;CAI7C,MAAM,aAAa,MAAM,cAHF,OAAO,OAAO,OAAO,MAAM,CAIjC,aAAa,EAAE,YAAY,eAAe,OAAO,CAAC,CAClE;AAGD,OAAM,cAAc,MAAM,QAAQ,eAAe,EAAE,EAAE,WAAW,MAAM,CAAC,CAAC;AACxE,OAAM,cAAc,UAAU,gBAAgB,WAAW,cAAc,QAAQ,CAAC;AAChF,OAAM,cAAc,UAAU,eAAe,WAAW,aAAa,QAAQ,CAAC;AAE9E,QAAO;EACL,aAAa,WAAW;EACxB,GAAG,UAAU,iBAAiB,WAAW,cAAc;EACvD,aAAa,WAAW;EACxB,OAAO;GACL,MAAM;GACN,KAAK;GACN;EACF"}
@@ -1,9 +1,4 @@
1
1
  import "../config-loader-PPf4CtDj.mjs";
2
- import "../cli-errors-JlPTsazx.mjs";
3
- import "../framework-components-CjV_jD8f.mjs";
4
- import "../client-PimzSD1f.mjs";
5
- import "../result-handler-iA9JtUC7.mjs";
6
- import "../progress-adapter-DENrzF6I.mjs";
7
2
  import { createContractEmitCommand } from "../commands/contract-emit.mjs";
8
3
  import { existsSync, unlinkSync, writeFileSync } from "node:fs";
9
4
  import { join } from "node:path";
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["value","disallowedImports: string[]","contract: unknown"],"sources":["../../src/load-ts-contract.ts"],"sourcesContent":["import { existsSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport type { Plugin } from 'esbuild';\nimport { build } from 'esbuild';\n\nexport interface LoadTsContractOptions {\n readonly allowlist?: ReadonlyArray<string>;\n}\n\nconst DEFAULT_ALLOWLIST = ['@prisma-next/*'];\n\nfunction isAllowedImport(importPath: string, allowlist: ReadonlyArray<string>): boolean {\n for (const pattern of allowlist) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n if (importPath === prefix || importPath.startsWith(`${prefix}/`)) {\n return true;\n }\n } else if (importPath === pattern) {\n return true;\n }\n }\n return false;\n}\n\nfunction validatePurity(value: unknown): void {\n if (typeof value !== 'object' || value === null) {\n return;\n }\n\n const path = new WeakSet();\n\n function check(value: unknown): void {\n if (value === null || typeof value !== 'object') {\n return;\n }\n\n if (path.has(value)) {\n throw new Error('Contract export contains circular references');\n }\n path.add(value);\n\n try {\n for (const key in value) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (descriptor && (descriptor.get || descriptor.set)) {\n throw new Error(`Contract export contains getter/setter at key \"${key}\"`);\n }\n if (descriptor && typeof descriptor.value === 'function') {\n throw new Error(`Contract export contains function at key \"${key}\"`);\n }\n check((value as Record<string, unknown>)[key]);\n }\n } finally {\n path.delete(value);\n }\n }\n\n try {\n check(value);\n JSON.stringify(value);\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('getter') || error.message.includes('circular')) {\n throw error;\n }\n throw new Error(`Contract export is not JSON-serializable: ${error.message}`);\n }\n throw new Error('Contract export is not JSON-serializable');\n }\n}\n\nfunction createImportAllowlistPlugin(allowlist: ReadonlyArray<string>, entryPath: string): Plugin {\n return {\n name: 'import-allowlist',\n setup(build) {\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind === 'entry-point') {\n return undefined;\n }\n if (args.path.startsWith('.') || args.path.startsWith('/')) {\n return undefined;\n }\n const isFromEntryPoint = args.importer === entryPath || args.importer === '<stdin>';\n if (isFromEntryPoint && !isAllowedImport(args.path, allowlist)) {\n return {\n path: args.path,\n external: true,\n };\n }\n return undefined;\n });\n },\n };\n}\n\n/**\n * Loads a contract from a TypeScript file and returns it as ContractIR.\n *\n * **Responsibility: Parsing Only**\n * This function loads and parses a TypeScript contract file. It does NOT normalize the contract.\n * The contract should already be normalized if it was built using the contract builder.\n *\n * Normalization must happen in the contract builder when the contract is created.\n * This function only validates that the contract is JSON-serializable and returns it as-is.\n *\n * @param entryPath - Path to the TypeScript contract file\n * @param options - Optional configuration (import allowlist)\n * @returns The contract as ContractIR (should already be normalized)\n * @throws Error if the contract cannot be loaded or is not JSON-serializable\n */\nexport async function loadContractFromTs(\n entryPath: string,\n options?: LoadTsContractOptions,\n): Promise<ContractIR> {\n const allowlist = options?.allowlist ?? DEFAULT_ALLOWLIST;\n\n if (!existsSync(entryPath)) {\n throw new Error(`Contract file not found: ${entryPath}`);\n }\n\n const tempFile = join(\n tmpdir(),\n `prisma-next-contract-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`,\n );\n\n try {\n const result = await build({\n entryPoints: [entryPath],\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'es2022',\n outfile: tempFile,\n write: false,\n metafile: true,\n plugins: [createImportAllowlistPlugin(allowlist, entryPath)],\n logLevel: 'error',\n });\n\n if (result.errors.length > 0) {\n const errorMessages = result.errors.map((e: { text: string }) => e.text).join('\\n');\n throw new Error(`Failed to bundle contract file: ${errorMessages}`);\n }\n\n if (!result.outputFiles || result.outputFiles.length === 0) {\n throw new Error('No output files generated from bundling');\n }\n\n const disallowedImports: string[] = [];\n if (result.metafile) {\n const inputs = result.metafile.inputs;\n for (const [, inputData] of Object.entries(inputs)) {\n const imports =\n (inputData as { imports?: Array<{ path: string; external?: boolean }> }).imports || [];\n for (const imp of imports) {\n if (\n imp.external &&\n !imp.path.startsWith('.') &&\n !imp.path.startsWith('/') &&\n !isAllowedImport(imp.path, allowlist)\n ) {\n disallowedImports.push(imp.path);\n }\n }\n }\n }\n\n if (disallowedImports.length > 0) {\n throw new Error(\n `Disallowed imports detected. Only imports matching the allowlist are permitted:\\n Allowlist: ${allowlist.join(', ')}\\n Disallowed imports: ${disallowedImports.join(', ')}\\n\\nOnly @prisma-next/* packages are allowed in contract files.`,\n );\n }\n\n const bundleContent = result.outputFiles[0]?.text;\n if (bundleContent === undefined) {\n throw new Error('Bundle content is undefined');\n }\n writeFileSync(tempFile, bundleContent, 'utf-8');\n\n const module = (await import(`file://${tempFile}`)) as {\n default?: unknown;\n contract?: unknown;\n };\n unlinkSync(tempFile);\n\n let contract: unknown;\n\n if (module.default !== undefined) {\n contract = module.default;\n } else if (module.contract !== undefined) {\n contract = module.contract;\n } else {\n throw new Error(\n `Contract file must export a contract as default export or named export 'contract'. Found exports: ${Object.keys(module as Record<string, unknown>).join(', ') || 'none'}`,\n );\n }\n\n if (typeof contract !== 'object' || contract === null) {\n throw new Error(`Contract export must be an object, got ${typeof contract}`);\n }\n\n validatePurity(contract);\n\n return contract as ContractIR;\n } catch (error) {\n try {\n if (tempFile) {\n unlinkSync(tempFile);\n }\n } catch {\n // Ignore cleanup errors\n }\n\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`Failed to load contract from ${entryPath}: ${String(error)}`);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["value","disallowedImports: string[]","contract: unknown"],"sources":["../../src/load-ts-contract.ts"],"sourcesContent":["import { existsSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport type { Plugin } from 'esbuild';\nimport { build } from 'esbuild';\n\nexport interface LoadTsContractOptions {\n readonly allowlist?: ReadonlyArray<string>;\n}\n\nconst DEFAULT_ALLOWLIST = ['@prisma-next/*'];\n\nfunction isAllowedImport(importPath: string, allowlist: ReadonlyArray<string>): boolean {\n for (const pattern of allowlist) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n if (importPath === prefix || importPath.startsWith(`${prefix}/`)) {\n return true;\n }\n } else if (importPath === pattern) {\n return true;\n }\n }\n return false;\n}\n\nfunction validatePurity(value: unknown): void {\n if (typeof value !== 'object' || value === null) {\n return;\n }\n\n const path = new WeakSet();\n\n function check(value: unknown): void {\n if (value === null || typeof value !== 'object') {\n return;\n }\n\n if (path.has(value)) {\n throw new Error('Contract export contains circular references');\n }\n path.add(value);\n\n try {\n for (const key in value) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (descriptor && (descriptor.get || descriptor.set)) {\n throw new Error(`Contract export contains getter/setter at key \"${key}\"`);\n }\n if (descriptor && typeof descriptor.value === 'function') {\n throw new Error(`Contract export contains function at key \"${key}\"`);\n }\n check((value as Record<string, unknown>)[key]);\n }\n } finally {\n path.delete(value);\n }\n }\n\n try {\n check(value);\n JSON.stringify(value);\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('getter') || error.message.includes('circular')) {\n throw error;\n }\n throw new Error(`Contract export is not JSON-serializable: ${error.message}`);\n }\n throw new Error('Contract export is not JSON-serializable');\n }\n}\n\nfunction createImportAllowlistPlugin(allowlist: ReadonlyArray<string>, entryPath: string): Plugin {\n return {\n name: 'import-allowlist',\n setup(build) {\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind === 'entry-point') {\n return undefined;\n }\n if (args.path.startsWith('.') || args.path.startsWith('/')) {\n return undefined;\n }\n const isFromEntryPoint = args.importer === entryPath || args.importer === '<stdin>';\n if (isFromEntryPoint && !isAllowedImport(args.path, allowlist)) {\n return {\n path: args.path,\n external: true,\n };\n }\n return undefined;\n });\n },\n };\n}\n\n/**\n * Loads a contract from a TypeScript file and returns it as ContractIR.\n *\n * **Responsibility: Parsing Only**\n * This function loads and parses a TypeScript contract file. It does NOT normalize the contract.\n * The contract should already be normalized if it was built using the contract builder.\n *\n * Normalization must happen in the contract builder when the contract is created.\n * This function only validates that the contract is JSON-serializable and returns it as-is.\n *\n * @param entryPath - Path to the TypeScript contract file\n * @param options - Optional configuration (import allowlist)\n * @returns The contract as ContractIR (should already be normalized)\n * @throws Error if the contract cannot be loaded or is not JSON-serializable\n */\nexport async function loadContractFromTs(\n entryPath: string,\n options?: LoadTsContractOptions,\n): Promise<ContractIR> {\n const allowlist = options?.allowlist ?? DEFAULT_ALLOWLIST;\n\n if (!existsSync(entryPath)) {\n throw new Error(`Contract file not found: ${entryPath}`);\n }\n\n const tempFile = join(\n tmpdir(),\n `prisma-next-contract-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`,\n );\n\n try {\n const result = await build({\n entryPoints: [entryPath],\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'es2022',\n outfile: tempFile,\n write: false,\n metafile: true,\n plugins: [createImportAllowlistPlugin(allowlist, entryPath)],\n logLevel: 'error',\n });\n\n if (result.errors.length > 0) {\n const errorMessages = result.errors.map((e: { text: string }) => e.text).join('\\n');\n throw new Error(`Failed to bundle contract file: ${errorMessages}`);\n }\n\n if (!result.outputFiles || result.outputFiles.length === 0) {\n throw new Error('No output files generated from bundling');\n }\n\n const disallowedImports: string[] = [];\n if (result.metafile) {\n const inputs = result.metafile.inputs;\n for (const [, inputData] of Object.entries(inputs)) {\n const imports =\n (inputData as { imports?: Array<{ path: string; external?: boolean }> }).imports || [];\n for (const imp of imports) {\n if (\n imp.external &&\n !imp.path.startsWith('.') &&\n !imp.path.startsWith('/') &&\n !isAllowedImport(imp.path, allowlist)\n ) {\n disallowedImports.push(imp.path);\n }\n }\n }\n }\n\n if (disallowedImports.length > 0) {\n throw new Error(\n `Disallowed imports detected. Only imports matching the allowlist are permitted:\\n Allowlist: ${allowlist.join(', ')}\\n Disallowed imports: ${disallowedImports.join(', ')}\\n\\nOnly @prisma-next/* packages are allowed in contract files.`,\n );\n }\n\n const bundleContent = result.outputFiles[0]?.text;\n if (bundleContent === undefined) {\n throw new Error('Bundle content is undefined');\n }\n writeFileSync(tempFile, bundleContent, 'utf-8');\n\n const module = (await import(`file://${tempFile}`)) as {\n default?: unknown;\n contract?: unknown;\n };\n unlinkSync(tempFile);\n\n let contract: unknown;\n\n if (module.default !== undefined) {\n contract = module.default;\n } else if (module.contract !== undefined) {\n contract = module.contract;\n } else {\n throw new Error(\n `Contract file must export a contract as default export or named export 'contract'. Found exports: ${Object.keys(module as Record<string, unknown>).join(', ') || 'none'}`,\n );\n }\n\n if (typeof contract !== 'object' || contract === null) {\n throw new Error(`Contract export must be an object, got ${typeof contract}`);\n }\n\n validatePurity(contract);\n\n return contract as ContractIR;\n } catch (error) {\n try {\n if (tempFile) {\n unlinkSync(tempFile);\n }\n } catch {\n // Ignore cleanup errors\n }\n\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`Failed to load contract from ${entryPath}: ${String(error)}`);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma-next/cli",
3
- "version": "0.3.0-dev.65",
3
+ "version": "0.3.0-dev.67",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "files": [
@@ -21,26 +21,26 @@
21
21
  "string-width": "^7.2.0",
22
22
  "strip-ansi": "^7.1.2",
23
23
  "wrap-ansi": "^9.0.2",
24
- "@prisma-next/contract": "0.3.0-dev.65",
25
- "@prisma-next/emitter": "0.3.0-dev.65",
26
- "@prisma-next/core-control-plane": "0.3.0-dev.65",
27
- "@prisma-next/config": "0.3.0-dev.65",
28
- "@prisma-next/migration-tools": "0.3.0-dev.65",
29
- "@prisma-next/utils": "0.3.0-dev.65"
24
+ "@prisma-next/config": "0.3.0-dev.67",
25
+ "@prisma-next/core-control-plane": "0.3.0-dev.67",
26
+ "@prisma-next/contract": "0.3.0-dev.67",
27
+ "@prisma-next/emitter": "0.3.0-dev.67",
28
+ "@prisma-next/utils": "0.3.0-dev.67",
29
+ "@prisma-next/migration-tools": "0.3.0-dev.67"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "24.10.4",
33
33
  "tsdown": "0.18.4",
34
34
  "typescript": "5.9.3",
35
35
  "vitest": "4.0.17",
36
- "@prisma-next/sql-contract": "0.3.0-dev.65",
37
- "@prisma-next/sql-contract-ts": "0.3.0-dev.65",
38
- "@prisma-next/sql-operations": "0.3.0-dev.65",
39
- "@prisma-next/sql-runtime": "0.3.0-dev.65",
40
- "@prisma-next/sql-contract-emitter": "0.3.0-dev.65",
41
- "@prisma-next/test-utils": "0.0.1",
36
+ "@prisma-next/sql-contract": "0.3.0-dev.67",
37
+ "@prisma-next/sql-contract-emitter": "0.3.0-dev.67",
38
+ "@prisma-next/sql-contract-ts": "0.3.0-dev.67",
39
+ "@prisma-next/sql-operations": "0.3.0-dev.67",
40
+ "@prisma-next/sql-runtime": "0.3.0-dev.67",
42
41
  "@prisma-next/tsconfig": "0.0.0",
43
- "@prisma-next/tsdown": "0.0.0"
42
+ "@prisma-next/tsdown": "0.0.0",
43
+ "@prisma-next/test-utils": "0.0.1"
44
44
  },
45
45
  "exports": {
46
46
  ".": {