prisma-next 0.8.0-dev.9 → 0.9.0-dev.1

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.
Files changed (56) hide show
  1. package/dist/cli.mjs +5 -5
  2. package/dist/{client-XkUw4xD0.mjs → client-Brv4qlfB.mjs} +13 -19
  3. package/dist/client-Brv4qlfB.mjs.map +1 -0
  4. package/dist/commands/contract-emit.mjs +1 -1
  5. package/dist/commands/contract-infer.mjs +1 -1
  6. package/dist/commands/db-init.mjs +2 -2
  7. package/dist/commands/db-schema.mjs +1 -1
  8. package/dist/commands/db-sign.mjs +1 -1
  9. package/dist/commands/db-update.mjs +2 -2
  10. package/dist/commands/db-verify.d.mts.map +1 -1
  11. package/dist/commands/db-verify.mjs +1 -1
  12. package/dist/commands/migrate.d.mts +1 -1
  13. package/dist/commands/migrate.d.mts.map +1 -1
  14. package/dist/commands/migrate.mjs +12 -4
  15. package/dist/commands/migrate.mjs.map +1 -1
  16. package/dist/commands/migration-log.mjs +1 -1
  17. package/dist/commands/migration-new.mjs +9 -9
  18. package/dist/commands/migration-new.mjs.map +1 -1
  19. package/dist/commands/migration-plan.d.mts.map +1 -1
  20. package/dist/commands/migration-plan.mjs +1 -1
  21. package/dist/commands/migration-show.d.mts.map +1 -1
  22. package/dist/commands/migration-show.mjs +7 -7
  23. package/dist/commands/migration-show.mjs.map +1 -1
  24. package/dist/commands/migration-status.d.mts +2 -2
  25. package/dist/commands/migration-status.d.mts.map +1 -1
  26. package/dist/commands/migration-status.mjs +5 -5
  27. package/dist/commands/migration-status.mjs.map +1 -1
  28. package/dist/{contract-emit-GpxW5RLe.mjs → contract-emit-C3STUIBg.mjs} +2 -2
  29. package/dist/{contract-emit-GpxW5RLe.mjs.map → contract-emit-C3STUIBg.mjs.map} +1 -1
  30. package/dist/{contract-emit-CgoFk9AU.mjs → contract-emit-iynA3BCA.mjs} +2 -2
  31. package/dist/{contract-emit-CgoFk9AU.mjs.map → contract-emit-iynA3BCA.mjs.map} +1 -1
  32. package/dist/{contract-infer-D8edZOCi.mjs → contract-infer-Cnj8G1E2.mjs} +2 -2
  33. package/dist/{contract-infer-D8edZOCi.mjs.map → contract-infer-Cnj8G1E2.mjs.map} +1 -1
  34. package/dist/{contract-space-aggregate-loader-D68YpuPR.mjs → contract-space-aggregate-loader-pAc8CDfY.mjs} +2 -2
  35. package/dist/{contract-space-aggregate-loader-D68YpuPR.mjs.map → contract-space-aggregate-loader-pAc8CDfY.mjs.map} +1 -1
  36. package/dist/{db-verify-DtRB9iHJ.mjs → db-verify-D7cyH_zz.mjs} +7 -4
  37. package/dist/db-verify-D7cyH_zz.mjs.map +1 -0
  38. package/dist/exports/control-api.d.mts +1 -1
  39. package/dist/exports/control-api.mjs +2 -2
  40. package/dist/exports/index.mjs +1 -1
  41. package/dist/exports/index.mjs.map +1 -1
  42. package/dist/{init-BU2G31T8.mjs → init-Bqg5JWg7.mjs} +3 -3
  43. package/dist/{init-BU2G31T8.mjs.map → init-Bqg5JWg7.mjs.map} +1 -1
  44. package/dist/{inspect-live-schema-CPPqCips.mjs → inspect-live-schema-CWLK_lgs.mjs} +2 -2
  45. package/dist/{inspect-live-schema-CPPqCips.mjs.map → inspect-live-schema-CWLK_lgs.mjs.map} +1 -1
  46. package/dist/{migration-command-scaffold-B_ezTTwX.mjs → migration-command-scaffold-CmXXC1UZ.mjs} +2 -2
  47. package/dist/{migration-command-scaffold-B_ezTTwX.mjs.map → migration-command-scaffold-CmXXC1UZ.mjs.map} +1 -1
  48. package/dist/{migration-plan-DWB-NTxH.mjs → migration-plan-CHyUlBV0.mjs} +34 -27
  49. package/dist/migration-plan-CHyUlBV0.mjs.map +1 -0
  50. package/dist/{types-BS_wpjAY.d.mts → types-0aS865QN.d.mts} +13 -7
  51. package/dist/types-0aS865QN.d.mts.map +1 -0
  52. package/package.json +10 -10
  53. package/dist/client-XkUw4xD0.mjs.map +0 -1
  54. package/dist/db-verify-DtRB9iHJ.mjs.map +0 -1
  55. package/dist/migration-plan-DWB-NTxH.mjs.map +0 -1
  56. package/dist/types-BS_wpjAY.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.mjs","names":[],"sources":["../../src/commands/migrate.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { errorUnknownInvariant, MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { RefEntry } from '@prisma-next/migration-tools/refs';\nimport { readRefs } from '@prisma-next/migration-tools/refs';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\n\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type {\n AggregatePerSpaceExecutionEntry,\n MigrationApplyFailure,\n MigrationApplyPathDecision,\n} from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n collectDeclaredInvariants,\n loadMigrationPackages,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { formatMigrationApplyCommandOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrateCommandOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly to?: string;\n}\n\nexport interface MigrateResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName: string;\n readonly migrationHash: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly perSpace: readonly AggregatePerSpaceExecutionEntry[];\n readonly pathDecision?: MigrationApplyPathDecision;\n readonly timings: {\n readonly total: number;\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 migrate --to <contract>` — previously applied migrations are preserved.',\n meta: failure.meta ?? {},\n });\n}\n\nasync function executeMigrateCommand(\n options: MigrateCommandOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrateResult, CliStructuredErrorType>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative, refsDir } =\n resolveMigrationPaths(options.config, config);\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for migrate (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'migrate',\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: 'Config.driver is required for migrate',\n }),\n );\n }\n\n if (!targetSupportsMigrations(config.target)) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n let refEntry: RefEntry | undefined;\n const toArg = options.to;\n\n if (toArg) {\n try {\n const refs = await readRefs(refsDir);\n const { graph } = await loadMigrationPackages(appMigrationsDir);\n const refResult = parseContractRef(toArg, { graph, refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n if (refResult.value.provenance.kind === 'ref') {\n const resolved = refs[refResult.value.provenance.refName];\n if (resolved) refEntry = resolved;\n } else {\n refEntry = { hash: refResult.value.hash, invariants: [] };\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n const contractPathAbsolute = resolveContractPath(config);\n let contractRaw: Contract;\n try {\n const contractContent = await readFile(contractPathAbsolute, 'utf-8');\n contractRaw = JSON.parse(contractContent) as Contract;\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 a valid contract.json, then retry.',\n }),\n );\n }\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 if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (typeof dbConnection === 'string') {\n details.push({\n label: 'database',\n value: maskConnectionUrl(dbConnection),\n });\n }\n if (toArg) {\n details.push({ label: 'to', value: toArg });\n }\n const header = formatStyledHeader({\n command: 'migrate',\n description: 'Apply planned migrations to advance the database',\n url: 'https://pris.ly/migrate',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let appPackages: Awaited<ReturnType<typeof loadMigrationPackages>>;\n try {\n appPackages = await loadMigrationPackages(appMigrationsDir);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\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 if (refEntry && refEntry.invariants.length > 0) {\n const allMarkers = await client.readAllMarkers();\n const appMarker = allMarkers.get('app') ?? null;\n const declared = collectDeclaredInvariants(appPackages.graph);\n const known = new Set<string>(declared);\n for (const id of appMarker?.invariants ?? []) known.add(id);\n const unknown = refEntry.invariants.filter((id) => !known.has(id));\n if (unknown.length > 0) {\n return notOk(\n mapMigrationToolsError(\n errorUnknownInvariant({\n ...ifDefined('refName', toArg),\n unknown,\n declared: [...declared].sort(),\n }),\n ),\n );\n }\n }\n\n if (!flags.quiet && !flags.json) {\n ui.step('Loading contract spaces…');\n }\n\n const applyResult = await client.migrationApply({\n contract: contractRaw,\n migrationsDir,\n appMigrationPackages: appPackages.bundles,\n ...ifDefined('refHash', refEntry?.hash),\n ...(refEntry?.invariants ? { refInvariants: refEntry.invariants } : {}),\n ...(refEntry !== undefined ? ifDefined('refName', toArg) : {}),\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: value.perSpace.length,\n markerHash: value.markerHash,\n applied: value.applied,\n summary: value.summary,\n perSpace: value.perSpace,\n ...ifDefined('pathDecision', value.pathDecision),\n timings: { total: Date.now() - startTime },\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migrate: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrateCommand(): Command {\n const command = new Command('migrate');\n setCommandDescriptions(\n command,\n 'Apply planned migrations to advance the database',\n 'Walks every contract space (app + extensions) and applies pending\\n' +\n 'on-disk migrations in canonical order (extensions alphabetically,\\n' +\n 'then app). Graph-walks the on-disk migration graph for every space.\\n' +\n 'Use --to to target a specific contract (hash, ref name, migration dir).',\n );\n setCommandExamples(command, [\n 'prisma-next migrate --db $DATABASE_URL',\n 'prisma-next migrate --to production --db $DATABASE_URL',\n 'prisma-next migrate --to sha256:abc123 --db $DATABASE_URL',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option(\n '--to <contract>',\n 'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .action(async (options: MigrateCommandOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n const ui = new TerminalUI({\n color: flags.color,\n interactive: flags.interactive,\n });\n\n const result = await executeMigrateCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (migrateResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(migrateResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationApplyCommandOutput(migrateResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":";;;;;;;;;;;;;;;AA2EA,SAAS,gBAAgB,SAAwD;CAC/E,OAAO,aAAa,QAAQ,SAAS;EACnC,KAAK,QAAQ,OAAO;EACpB,KAAK;EACL,MAAM,QAAQ,QAAQ,EAAE;EACzB,CAAC;;AAGJ,eAAe,sBACb,SACA,OACA,IACA,WACwD;CACxD,MAAM,SAAS,MAAM,WAAW,QAAQ,OAAO;CAC/C,MAAM,EAAE,YAAY,eAAe,kBAAkB,uBAAuB,YAC1E,sBAAsB,QAAQ,QAAQ,OAAO;CAE/C,MAAM,eAAe,QAAQ,MAAM,OAAO,IAAI;CAC9C,IAAI,CAAC,cACH,OAAO,MACL,gCAAgC;EAC9B,KAAK,qEAAqE,WAAW;EACrF,aAAa;EACd,CAAC,CACH;CAGH,IAAI,CAAC,OAAO,QACV,OAAO,MACL,oBAAoB,EAClB,KAAK,yCACN,CAAC,CACH;CAGH,IAAI,CAAC,yBAAyB,OAAO,OAAO,EAC1C,OAAO,MACL,iCAAiC,EAC/B,KAAK,WAAW,OAAO,OAAO,GAAG,gCAClC,CAAC,CACH;CAGH,IAAI;CACJ,MAAM,QAAQ,QAAQ;CAEtB,IAAI,OACF,IAAI;EACF,MAAM,OAAO,MAAM,SAAS,QAAQ;EACpC,MAAM,EAAE,UAAU,MAAM,sBAAsB,iBAAiB;EAC/D,MAAM,YAAY,iBAAiB,OAAO;GAAE;GAAO;GAAM,CAAC;EAC1D,IAAI,CAAC,UAAU,IACb,OAAO,MAAM,sBAAsB,UAAU,QAAQ,CAAC;EAExD,IAAI,UAAU,MAAM,WAAW,SAAS,OAAO;GAC7C,MAAM,WAAW,KAAK,UAAU,MAAM,WAAW;GACjD,IAAI,UAAU,WAAW;SAEzB,WAAW;GAAE,MAAM,UAAU,MAAM;GAAM,YAAY,EAAE;GAAE;UAEpD,OAAO;EACd,IAAI,oBAAoB,GAAG,MAAM,EAC/B,OAAO,MAAM,uBAAuB,MAAM,CAAC;EAE7C,MAAM;;CAIV,MAAM,uBAAuB,oBAAoB,OAAO;CACxD,IAAI;CACJ,IAAI;EACF,MAAM,kBAAkB,MAAM,SAAS,sBAAsB,QAAQ;EACrE,cAAc,KAAK,MAAM,gBAAgB;UAClC,OAAO;EACd,IAAI,iBAAiB,SAAU,MAA4B,SAAS,UAClE,OAAO,MACL,kBAAkB,sBAAsB;GACtC,KAAK,8BAA8B;GACnC,KAAK;GACN,CAAC,CACH;EAEH,OAAO,MACL,8BACE,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACnF,EAAE,OAAO,EAAE,MAAM,sBAAsB,EAAE,CAC1C,CACF;;CAGH,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OAAO;EAC/B,MAAM,UAAmD,CACvD;GAAE,OAAO;GAAU,OAAO;GAAY,EACtC;GAAE,OAAO;GAAc,OAAO;GAAuB,CACtD;EACD,IAAI,OAAO,iBAAiB,UAC1B,QAAQ,KAAK;GACX,OAAO;GACP,OAAO,kBAAkB,aAAa;GACvC,CAAC;EAEJ,IAAI,OACF,QAAQ,KAAK;GAAE,OAAO;GAAM,OAAO;GAAO,CAAC;EAE7C,MAAM,SAAS,mBAAmB;GAChC,SAAS;GACT,aAAa;GACb,KAAK;GACL;GACA;GACD,CAAC;EACF,GAAG,OAAO,OAAO;;CAGnB,IAAI;CACJ,IAAI;EACF,cAAc,MAAM,sBAAsB,iBAAiB;UACpD,OAAO;EACd,IAAI,oBAAoB,GAAG,MAAM,EAC/B,OAAO,MAAM,uBAAuB,MAAM,CAAC;EAE7C,MAAM;;CAGR,MAAM,SAAS,oBAAoB;EACjC,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf,gBAAgB,OAAO,kBAAkB,EAAE;EAC5C,CAAC;CAEF,IAAI;EACF,MAAM,OAAO,QAAQ,aAAa;EAElC,IAAI,YAAY,SAAS,WAAW,SAAS,GAAG;GAE9C,MAAM,aAAY,MADO,OAAO,gBAAgB,EACnB,IAAI,MAAM,IAAI;GAC3C,MAAM,WAAW,0BAA0B,YAAY,MAAM;GAC7D,MAAM,QAAQ,IAAI,IAAY,SAAS;GACvC,KAAK,MAAM,MAAM,WAAW,cAAc,EAAE,EAAE,MAAM,IAAI,GAAG;GAC3D,MAAM,UAAU,SAAS,WAAW,QAAQ,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;GAClE,IAAI,QAAQ,SAAS,GACnB,OAAO,MACL,uBACE,sBAAsB;IACpB,GAAG,UAAU,WAAW,MAAM;IAC9B;IACA,UAAU,CAAC,GAAG,SAAS,CAAC,MAAM;IAC/B,CAAC,CACH,CACF;;EAIL,IAAI,CAAC,MAAM,SAAS,CAAC,MAAM,MACzB,GAAG,KAAK,2BAA2B;EAGrC,MAAM,cAAc,MAAM,OAAO,eAAe;GAC9C,UAAU;GACV;GACA,sBAAsB,YAAY;GAClC,GAAG,UAAU,WAAW,UAAU,KAAK;GACvC,GAAI,UAAU,aAAa,EAAE,eAAe,SAAS,YAAY,GAAG,EAAE;GACtE,GAAI,aAAa,KAAA,IAAY,UAAU,WAAW,MAAM,GAAG,EAAE;GAC9D,CAAC;EAEF,IAAI,CAAC,YAAY,IACf,OAAO,MAAM,gBAAgB,YAAY,QAAQ,CAAC;EAGpD,MAAM,EAAE,UAAU;EAElB,OAAO,GAAG;GACR,IAAI;GACJ,mBAAmB,MAAM;GACzB,iBAAiB,MAAM,SAAS;GAChC,YAAY,MAAM;GAClB,SAAS,MAAM;GACf,SAAS,MAAM;GACf,UAAU,MAAM;GAChB,GAAG,UAAU,gBAAgB,MAAM,aAAa;GAChD,SAAS,EAAE,OAAO,KAAK,KAAK,GAAG,WAAW;GAC3C,CAAC;UACK,OAAO;EACd,IAAI,mBAAmB,GAAG,MAAM,EAC9B,OAAO,MAAM,MAAM;EAErB,IAAI,oBAAoB,GAAG,MAAM,EAC/B,OAAO,MAAM,uBAAuB,MAAM,CAAC;EAE7C,OAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IAChG,CAAC,CACH;WACO;EACR,MAAM,OAAO,OAAO;;;AAIxB,SAAgB,uBAAgC;CAC9C,MAAM,UAAU,IAAI,QAAQ,UAAU;CACtC,uBACE,SACA,oDACA,qRAID;CACD,mBAAmB,SAAS;EAC1B;EACA;EACA;EACD,CAAC;CACF,iBAAiB,QAAQ,CACtB,OAAO,cAAc,6BAA6B,CAClD,OAAO,mBAAmB,gCAAgC,CAC1D,OACC,mBACA,4FACD,CACA,OAAO,OAAO,YAAmC;EAChD,MAAM,QAAQ,iBAAiB,QAAQ;EACvC,MAAM,YAAY,KAAK,KAAK;EAE5B,MAAM,KAAK,IAAI,WAAW;GACxB,OAAO,MAAM;GACb,aAAa,MAAM;GACpB,CAAC;EAIF,MAAM,WAAW,aAAa,MAFT,sBAAsB,SAAS,OAAO,IAAI,UAAU,EAEnC,OAAO,KAAK,kBAAkB;GAClE,IAAI,MAAM,MACR,GAAG,OAAO,KAAK,UAAU,eAAe,MAAM,EAAE,CAAC;QAC5C,IAAI,CAAC,MAAM,OAChB,GAAG,IAAI,kCAAkC,eAAe,MAAM,CAAC;IAEjE;EAEF,QAAQ,KAAK,SAAS;GACtB;CAEJ,OAAO"}
1
+ {"version":3,"file":"migrate.mjs","names":[],"sources":["../../src/commands/migrate.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { errorUnknownInvariant, MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';\nimport type { RefEntry } from '@prisma-next/migration-tools/refs';\nimport { readRefs } from '@prisma-next/migration-tools/refs';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\n\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type {\n AggregatePerSpaceExecutionEntry,\n MigrationApplyFailure,\n MigrationApplyPathDecision,\n} from '../control-api/types';\nimport {\n CliStructuredError,\n type CliStructuredError as CliStructuredErrorType,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n collectDeclaredInvariants,\n loadMigrationPackages,\n maskConnectionUrl,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n targetSupportsMigrations,\n} from '../utils/command-helpers';\nimport { formatMigrationApplyCommandOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrateCommandOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly to?: string;\n}\n\nexport interface MigrateResult {\n readonly ok: boolean;\n readonly migrationsApplied: number;\n readonly migrationsTotal: number;\n readonly markerHash: string;\n readonly applied: readonly {\n readonly spaceId: string;\n readonly dirName: string;\n readonly migrationHash: string;\n readonly from: string;\n readonly to: string;\n readonly operationsExecuted: number;\n }[];\n readonly summary: string;\n readonly perSpace: readonly AggregatePerSpaceExecutionEntry[];\n readonly pathDecision?: MigrationApplyPathDecision;\n readonly timings: {\n readonly total: number;\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 migrate --to <contract>` — previously applied migrations are preserved.',\n meta: failure.meta ?? {},\n });\n}\n\nasync function executeMigrateCommand(\n options: MigrateCommandOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<MigrateResult, CliStructuredErrorType>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative, refsDir } =\n resolveMigrationPaths(options.config, config);\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for migrate (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: 'migrate',\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: 'Config.driver is required for migrate',\n }),\n );\n }\n\n if (!targetSupportsMigrations(config.target)) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n let refEntry: RefEntry | undefined;\n const toArg = options.to;\n\n if (toArg) {\n try {\n const refs = await readRefs(refsDir);\n const { graph } = await loadMigrationPackages(appMigrationsDir);\n const refResult = parseContractRef(toArg, { graph, refs });\n if (!refResult.ok) {\n return notOk(mapRefResolutionError(refResult.failure));\n }\n if (refResult.value.provenance.kind === 'ref') {\n const resolved = refs[refResult.value.provenance.refName];\n if (resolved) refEntry = resolved;\n } else {\n refEntry = { hash: refResult.value.hash, invariants: [] };\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n }\n\n // Construct the family instance up-front so the on-disk contract read\n // crosses the serializer seam (`familyInstance.deserializeContract`) at\n // the read site. The downstream `client.migrationApply({ contract })`\n // re-validates internally (no harm — validation is idempotent), but\n // closing the gap at the read site is what makes the cast-pattern\n // lint enforceable and matches the other CLI commands. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n const contractPathAbsolute = resolveContractPath(config);\n let contractRaw: Contract;\n let contractContent: string;\n try {\n contractContent = 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 a valid contract.json, then retry.',\n }),\n );\n }\n return notOk(\n errorContractValidationFailed(\n `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n try {\n contractRaw = familyInstance.deserializeContract(JSON.parse(contractContent) as unknown);\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (typeof dbConnection === 'string') {\n details.push({\n label: 'database',\n value: maskConnectionUrl(dbConnection),\n });\n }\n if (toArg) {\n details.push({ label: 'to', value: toArg });\n }\n const header = formatStyledHeader({\n command: 'migrate',\n description: 'Apply planned migrations to advance the database',\n url: 'https://pris.ly/migrate',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n let appPackages: Awaited<ReturnType<typeof loadMigrationPackages>>;\n try {\n appPackages = await loadMigrationPackages(appMigrationsDir);\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\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 if (refEntry && refEntry.invariants.length > 0) {\n const allMarkers = await client.readAllMarkers();\n const appMarker = allMarkers.get('app') ?? null;\n const declared = collectDeclaredInvariants(appPackages.graph);\n const known = new Set<string>(declared);\n for (const id of appMarker?.invariants ?? []) known.add(id);\n const unknown = refEntry.invariants.filter((id) => !known.has(id));\n if (unknown.length > 0) {\n return notOk(\n mapMigrationToolsError(\n errorUnknownInvariant({\n ...ifDefined('refName', toArg),\n unknown,\n declared: [...declared].sort(),\n }),\n ),\n );\n }\n }\n\n if (!flags.quiet && !flags.json) {\n ui.step('Loading contract spaces…');\n }\n\n const applyResult = await client.migrationApply({\n contract: contractRaw,\n migrationsDir,\n appMigrationPackages: appPackages.bundles,\n ...ifDefined('refHash', refEntry?.hash),\n ...(refEntry?.invariants ? { refInvariants: refEntry.invariants } : {}),\n ...(refEntry !== undefined ? ifDefined('refName', toArg) : {}),\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: value.perSpace.length,\n markerHash: value.markerHash,\n applied: value.applied,\n summary: value.summary,\n perSpace: value.perSpace,\n ...ifDefined('pathDecision', value.pathDecision),\n timings: { total: Date.now() - startTime },\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Unexpected error during migrate: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n\nexport function createMigrateCommand(): Command {\n const command = new Command('migrate');\n setCommandDescriptions(\n command,\n 'Apply planned migrations to advance the database',\n 'Walks every contract space (app + extensions) and applies pending\\n' +\n 'on-disk migrations in canonical order (extensions alphabetically,\\n' +\n 'then app). Graph-walks the on-disk migration graph for every space.\\n' +\n 'Use --to to target a specific contract (hash, ref name, migration dir).',\n );\n setCommandExamples(command, [\n 'prisma-next migrate --db $DATABASE_URL',\n 'prisma-next migrate --to production --db $DATABASE_URL',\n 'prisma-next migrate --to sha256:abc123 --db $DATABASE_URL',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option(\n '--to <contract>',\n 'Target contract reference (hash, prefix, ref name, migration dir name, <dir>^, or ./path)',\n )\n .action(async (options: MigrateCommandOptions) => {\n const flags = parseGlobalFlags(options);\n const startTime = Date.now();\n\n const ui = new TerminalUI({\n color: flags.color,\n interactive: flags.interactive,\n });\n\n const result = await executeMigrateCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (migrateResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(migrateResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationApplyCommandOutput(migrateResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { _ as errorUnexpected, c as errorDriverRequired, o as errorDatabaseConne
3
3
  import { _ as parseGlobalFlags, a as loadMigrationPackages, b as formatStyledHeader, d as setCommandDescriptions, f as setCommandExamples, l as resolveMigrationPaths, m as targetSupportsMigrations, o as maskConnectionUrl, p as setCommandSeeAlso, t as addGlobalOptions } from "../command-helpers-D3vL5yi8.mjs";
4
4
  import { t as handleResult } from "../result-handler-Bm_6dDYg.mjs";
5
5
  import { t as TerminalUI } from "../terminal-ui-XtOQsqe9.mjs";
6
- import { t as createControlClient } from "../client-XkUw4xD0.mjs";
6
+ import { t as createControlClient } from "../client-Brv4qlfB.mjs";
7
7
  import { Command } from "commander";
8
8
  import { notOk, ok } from "@prisma-next/utils/result";
9
9
  import { findPath } from "@prisma-next/migration-tools/migration-graph";
@@ -8,10 +8,10 @@ import { Command } from "commander";
8
8
  import { getEmittedArtifactPaths } from "@prisma-next/emitter";
9
9
  import { notOk, ok } from "@prisma-next/utils/result";
10
10
  import { join, relative } from "pathe";
11
+ import { readFile } from "node:fs/promises";
11
12
  import { APP_SPACE_ID, createControlStack } from "@prisma-next/framework-components/control";
12
13
  import { copyFilesWithRename, formatMigrationDirName, readMigrationsDir, writeMigrationPackage } from "@prisma-next/migration-tools/io";
13
14
  import { findLatestMigration, reconstructGraph } from "@prisma-next/migration-tools/migration-graph";
14
- import { readFileSync } from "node:fs";
15
15
  import { MigrationToolsError } from "@prisma-next/migration-tools/errors";
16
16
  import { computeMigrationHash } from "@prisma-next/migration-tools/hash";
17
17
  import { writeMigrationTs } from "@prisma-next/migration-tools/migration-ts";
@@ -28,10 +28,12 @@ import { writeMigrationTs } from "@prisma-next/migration-tools/migration-ts";
28
28
  async function executeMigrationNewCommand(options) {
29
29
  const config = await loadConfig(options.config);
30
30
  const { appMigrationsDir, appMigrationsRelative } = resolveMigrationPaths(options.config, config);
31
+ const stack = createControlStack(config);
32
+ const familyInstance = config.family.create(stack);
31
33
  const contractPathAbsolute = resolveContractPath(config);
32
34
  let contractJsonContent;
33
35
  try {
34
- contractJsonContent = readFileSync(contractPathAbsolute, "utf-8");
36
+ contractJsonContent = await readFile(contractPathAbsolute, "utf-8");
35
37
  } catch (error) {
36
38
  if (error instanceof Error && error.code === "ENOENT") return notOk(errorRuntime(`Contract file not found at ${contractPathAbsolute}`, {
37
39
  why: `Contract file not found at ${contractPathAbsolute}`,
@@ -39,17 +41,17 @@ async function executeMigrationNewCommand(options) {
39
41
  }));
40
42
  throw error;
41
43
  }
42
- let toContractJson;
44
+ let toContract;
43
45
  try {
44
- toContractJson = JSON.parse(contractJsonContent);
46
+ toContract = familyInstance.deserializeContract(JSON.parse(contractJsonContent));
45
47
  } catch (error) {
46
48
  return notOk(errorRuntime("Contract JSON is invalid", {
47
- why: `Failed to parse ${contractPathAbsolute}: ${error instanceof Error ? error.message : String(error)}`,
49
+ why: `Failed to deserialize ${contractPathAbsolute}: ${error instanceof Error ? error.message : String(error)}`,
48
50
  fix: "Run `prisma-next contract emit` to regenerate the contract"
49
51
  }));
50
52
  }
51
- const toStorageHash = toContractJson["storage"]?.["storageHash"];
52
- if (!toStorageHash) return notOk(errorRuntime("Contract is missing storageHash", {
53
+ const toStorageHash = toContract.storage?.storageHash;
54
+ if (typeof toStorageHash !== "string") return notOk(errorRuntime("Contract is missing storageHash", {
53
55
  why: `Contract at ${contractPathAbsolute} has no storageHash`,
54
56
  fix: "Run `prisma-next contract emit` to regenerate the contract"
55
57
  }));
@@ -137,8 +139,6 @@ async function executeMigrationNewCommand(options) {
137
139
  throw error;
138
140
  }
139
141
  }
140
- const stack = createControlStack(config);
141
- const familyInstance = config.family.create(stack);
142
142
  await writeMigrationTs(packageDir, migrations.createPlanner(familyInstance).emptyMigration({
143
143
  packageDir,
144
144
  contractJsonPath: join(packageDir, "end-contract.json"),
@@ -1 +1 @@
1
- {"version":3,"file":"migration-new.mjs","names":[],"sources":["../../src/commands/migration-new.ts"],"sourcesContent":["/**\n * `migration new` — scaffolds a migration package with a `migration.ts` file\n * for manual authoring.\n *\n * The planner's `emptyMigration(context)` returns a\n * `MigrationPlanWithAuthoringSurface`, whose `renderTypeScript()` produces\n * the target-appropriate empty stub. The CLI writes the returned source\n * verbatim.\n */\n\nimport { readFileSync } from 'node:fs';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { APP_SPACE_ID, createControlStack } from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { computeMigrationHash } from '@prisma-next/migration-tools/hash';\nimport {\n copyFilesWithRename,\n formatMigrationDirName,\n readMigrationsDir,\n writeMigrationPackage,\n} from '@prisma-next/migration-tools/io';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport {\n findLatestMigration,\n reconstructGraph,\n} from '@prisma-next/migration-tools/migration-graph';\nimport { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join, relative } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport {\n CliStructuredError,\n errorFileNotFound,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n getTargetMigrations,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationNewOptions extends CommonCommandOptions {\n readonly name?: string;\n readonly from?: string;\n readonly config?: string;\n}\n\ninterface MigrationNewResult {\n readonly ok: true;\n readonly dir: string;\n readonly from: string | null;\n readonly to: string;\n readonly summary: string;\n}\n\nasync function executeMigrationNewCommand(\n options: MigrationNewOptions,\n): Promise<Result<MigrationNewResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { appMigrationsDir, appMigrationsRelative } = resolveMigrationPaths(options.config, config);\n\n const contractPathAbsolute = resolveContractPath(config);\n\n let contractJsonContent: string;\n try {\n contractJsonContent = readFileSync(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorRuntime(`Contract file not found at ${contractPathAbsolute}`, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: 'Run `prisma-next contract emit` first to generate the contract',\n }),\n );\n }\n throw error;\n }\n\n let toContractJson: Contract;\n try {\n toContractJson = JSON.parse(contractJsonContent) as Contract;\n } catch (error) {\n return notOk(\n errorRuntime('Contract JSON is invalid', {\n why: `Failed to parse ${contractPathAbsolute}: ${error instanceof Error ? error.message : String(error)}`,\n fix: 'Run `prisma-next contract emit` to regenerate the contract',\n }),\n );\n }\n\n const toStorageHash = (\n (toContractJson as unknown as Record<string, unknown>)['storage'] as\n | Record<string, unknown>\n | undefined\n )?.['storageHash'] as string | undefined;\n if (!toStorageHash) {\n return notOk(\n errorRuntime('Contract is missing storageHash', {\n why: `Contract at ${contractPathAbsolute} has no storageHash`,\n fix: 'Run `prisma-next contract emit` to regenerate the contract',\n }),\n );\n }\n\n let fromHash: string | null = null;\n let fromContractSourceDir: string | null = null;\n\n try {\n const packages = await readMigrationsDir(appMigrationsDir);\n\n if (packages.length > 0) {\n const graph = reconstructGraph(packages);\n\n if (options.from) {\n const match = packages.find((p) => p.metadata.to.startsWith(options.from!));\n if (!match) {\n return notOk(\n errorRuntime('Starting contract not found', {\n why: `No migration with to hash matching \"${options.from}\" exists in ${appMigrationsRelative}`,\n fix: 'Check that the --from hash matches a known migration target hash.',\n }),\n );\n }\n fromHash = match.metadata.to;\n fromContractSourceDir = match.dirPath;\n } else {\n const latestMigration = findLatestMigration(graph);\n if (latestMigration) {\n fromHash = latestMigration.to;\n const leafPkg = packages.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n if (leafPkg) {\n fromContractSourceDir = leafPkg.dirPath;\n }\n }\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n if (fromHash === toStorageHash && !options.from) {\n return notOk(\n errorRuntime('No changes detected', {\n why: 'The from and to contract hashes are identical — there is nothing to migrate.',\n fix: 'Change the contract and run `prisma-next contract emit` before creating a new migration. To author a data-only migration on the current contract hash, pass `--from <hash>` explicitly.',\n }),\n );\n }\n\n const timestamp = new Date();\n const slug = options.name ?? 'migration';\n const dirName = formatMigrationDirName(timestamp, slug);\n const packageDir = join(appMigrationsDir, dirName);\n\n // `migration new` scaffolds an empty `migration.ts` for the user to\n // fill, so we attest over `ops: []`. Re-running self-emit after the\n // user adds operations will produce a different `migrationHash` (over\n // the real ops). This is intentional — there is no on-disk draft.\n const baseMetadata: Omit<MigrationMetadata, 'migrationHash'> = {\n from: fromHash,\n to: toStorageHash,\n hints: {\n used: [],\n applied: [],\n plannerVersion: '1.0.0',\n },\n labels: [],\n providedInvariants: [],\n createdAt: timestamp.toISOString(),\n };\n const metadata: MigrationMetadata = {\n ...baseMetadata,\n migrationHash: computeMigrationHash(baseMetadata, []),\n };\n\n const migrations = getTargetMigrations(config.target);\n if (!migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.targetId}\" does not support migrations`,\n }),\n );\n }\n\n try {\n assertFrameworkComponentsCompatible(config.family.familyId, config.target.targetId, [\n config.target,\n config.adapter,\n ...(config.extensionPacks ?? []),\n ]);\n\n await writeMigrationPackage(packageDir, metadata, []);\n const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);\n await copyFilesWithRename(packageDir, [\n { sourcePath: destinationArtifacts.jsonPath, destName: 'end-contract.json' },\n { sourcePath: destinationArtifacts.dtsPath, destName: 'end-contract.d.ts' },\n ]);\n if (fromContractSourceDir !== null) {\n const sourceArtifacts = getEmittedArtifactPaths(\n join(fromContractSourceDir, 'end-contract.json'),\n );\n try {\n await copyFilesWithRename(packageDir, [\n { sourcePath: sourceArtifacts.jsonPath, destName: 'start-contract.json' },\n { sourcePath: sourceArtifacts.dtsPath, destName: 'start-contract.d.ts' },\n ]);\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(sourceArtifacts.jsonPath, {\n why: `Predecessor migration is missing its destination contract snapshot at ${sourceArtifacts.jsonPath}`,\n fix: 'Re-emit the predecessor migration (`prisma-next migration plan` from its source) so its sibling `end-contract.json` is restored, then re-run this command.',\n }),\n );\n }\n throw error;\n }\n }\n\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n const planner = migrations.createPlanner(familyInstance);\n const emptyPlan = planner.emptyMigration(\n {\n packageDir,\n contractJsonPath: join(packageDir, 'end-contract.json'),\n fromHash,\n toHash: toStorageHash,\n },\n APP_SPACE_ID,\n );\n await writeMigrationTs(packageDir, emptyPlan.renderTypeScript());\n\n return ok({\n ok: true as const,\n dir: relative(process.cwd(), packageDir),\n from: fromHash,\n to: toStorageHash,\n summary: `Scaffolded migration at ${relative(process.cwd(), packageDir)}`,\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: `Failed to scaffold migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n}\n\nexport function createMigrationNewCommand(): Command {\n const command = new Command('new');\n setCommandDescriptions(\n command,\n 'Scaffold a new migration for manual authoring',\n 'Creates a migration package with a migration.ts file for manual authoring.\\n' +\n 'Write the migration body in migration.ts, then run the file with Node\\n' +\n '(`node migration.ts`) to self-emit ops.json and attest the package.',\n );\n setCommandExamples(command, [\n 'prisma-next migration new --name split-name',\n 'prisma-next migration new --name custom-fk --from sha256:abc...',\n ]);\n addGlobalOptions(command)\n .option('--name <slug>', 'Migration name (used in directory name)')\n .option('--from <hash>', 'Starting contract hash (default: latest migration target)')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (options: MigrationNewOptions) => {\n const flags = parseGlobalFlags(options);\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n if (!flags.json && !flags.quiet) {\n const header = formatStyledHeader({\n command: 'migration new',\n description: 'Scaffold a new migration',\n details: [],\n flags,\n });\n ui.stderr(header);\n }\n\n const result = await executeMigrationNewCommand(options);\n\n const exitCode = handleResult(result, flags, ui, (value) => {\n if (flags.json) {\n ui.output(JSON.stringify(value, null, 2));\n } else if (!flags.quiet) {\n ui.output(`\\nScaffolded migration at ${value.dir}`);\n ui.output(` from: ${value.from}`);\n ui.output(` to: ${value.to}`);\n ui.output(\n `\\nEdit migration.ts, then run it directly (\\`node \"${value.dir}/migration.ts\"\\`) to self-emit and attest.`,\n );\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"migration-new.mjs","names":[],"sources":["../../src/commands/migration-new.ts"],"sourcesContent":["/**\n * `migration new` — scaffolds a migration package with a `migration.ts` file\n * for manual authoring.\n *\n * The planner's `emptyMigration(context)` returns a\n * `MigrationPlanWithAuthoringSurface`, whose `renderTypeScript()` produces\n * the target-appropriate empty stub. The CLI writes the returned source\n * verbatim.\n */\n\nimport { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { APP_SPACE_ID, createControlStack } from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { computeMigrationHash } from '@prisma-next/migration-tools/hash';\nimport {\n copyFilesWithRename,\n formatMigrationDirName,\n readMigrationsDir,\n writeMigrationPackage,\n} from '@prisma-next/migration-tools/io';\nimport type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';\nimport {\n findLatestMigration,\n reconstructGraph,\n} from '@prisma-next/migration-tools/migration-graph';\nimport { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { join, relative } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport {\n CliStructuredError,\n errorFileNotFound,\n errorRuntime,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n mapMigrationToolsError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n getTargetMigrations,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport { assertFrameworkComponentsCompatible } from '../utils/framework-components';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationNewOptions extends CommonCommandOptions {\n readonly name?: string;\n readonly from?: string;\n readonly config?: string;\n}\n\ninterface MigrationNewResult {\n readonly ok: true;\n readonly dir: string;\n readonly from: string | null;\n readonly to: string;\n readonly summary: string;\n}\n\nasync function executeMigrationNewCommand(\n options: MigrationNewOptions,\n): Promise<Result<MigrationNewResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { appMigrationsDir, appMigrationsRelative } = resolveMigrationPaths(options.config, config);\n\n // Construct the family instance up-front so the on-disk contract read\n // below crosses the serializer seam (`familyInstance.deserializeContract`)\n // at the read site, not somewhere downstream. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n const contractPathAbsolute = resolveContractPath(config);\n\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 errorRuntime(`Contract file not found at ${contractPathAbsolute}`, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: 'Run `prisma-next contract emit` first to generate the contract',\n }),\n );\n }\n throw error;\n }\n\n let toContract: Contract;\n try {\n toContract = familyInstance.deserializeContract(JSON.parse(contractJsonContent) as unknown);\n } catch (error) {\n return notOk(\n errorRuntime('Contract JSON is invalid', {\n why: `Failed to deserialize ${contractPathAbsolute}: ${error instanceof Error ? error.message : String(error)}`,\n fix: 'Run `prisma-next contract emit` to regenerate the contract',\n }),\n );\n }\n\n const toStorageHash = toContract.storage?.storageHash;\n if (typeof toStorageHash !== 'string') {\n return notOk(\n errorRuntime('Contract is missing storageHash', {\n why: `Contract at ${contractPathAbsolute} has no storageHash`,\n fix: 'Run `prisma-next contract emit` to regenerate the contract',\n }),\n );\n }\n\n let fromHash: string | null = null;\n let fromContractSourceDir: string | null = null;\n\n try {\n const packages = await readMigrationsDir(appMigrationsDir);\n\n if (packages.length > 0) {\n const graph = reconstructGraph(packages);\n\n if (options.from) {\n const match = packages.find((p) => p.metadata.to.startsWith(options.from!));\n if (!match) {\n return notOk(\n errorRuntime('Starting contract not found', {\n why: `No migration with to hash matching \"${options.from}\" exists in ${appMigrationsRelative}`,\n fix: 'Check that the --from hash matches a known migration target hash.',\n }),\n );\n }\n fromHash = match.metadata.to;\n fromContractSourceDir = match.dirPath;\n } else {\n const latestMigration = findLatestMigration(graph);\n if (latestMigration) {\n fromHash = latestMigration.to;\n const leafPkg = packages.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n if (leafPkg) {\n fromContractSourceDir = leafPkg.dirPath;\n }\n }\n }\n }\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n throw error;\n }\n\n if (fromHash === toStorageHash && !options.from) {\n return notOk(\n errorRuntime('No changes detected', {\n why: 'The from and to contract hashes are identical — there is nothing to migrate.',\n fix: 'Change the contract and run `prisma-next contract emit` before creating a new migration. To author a data-only migration on the current contract hash, pass `--from <hash>` explicitly.',\n }),\n );\n }\n\n const timestamp = new Date();\n const slug = options.name ?? 'migration';\n const dirName = formatMigrationDirName(timestamp, slug);\n const packageDir = join(appMigrationsDir, dirName);\n\n // `migration new` scaffolds an empty `migration.ts` for the user to\n // fill, so we attest over `ops: []`. Re-running self-emit after the\n // user adds operations will produce a different `migrationHash` (over\n // the real ops). This is intentional — there is no on-disk draft.\n const baseMetadata: Omit<MigrationMetadata, 'migrationHash'> = {\n from: fromHash,\n to: toStorageHash,\n hints: {\n used: [],\n applied: [],\n plannerVersion: '1.0.0',\n },\n labels: [],\n providedInvariants: [],\n createdAt: timestamp.toISOString(),\n };\n const metadata: MigrationMetadata = {\n ...baseMetadata,\n migrationHash: computeMigrationHash(baseMetadata, []),\n };\n\n const migrations = getTargetMigrations(config.target);\n if (!migrations) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.targetId}\" does not support migrations`,\n }),\n );\n }\n\n try {\n assertFrameworkComponentsCompatible(config.family.familyId, config.target.targetId, [\n config.target,\n config.adapter,\n ...(config.extensionPacks ?? []),\n ]);\n\n await writeMigrationPackage(packageDir, metadata, []);\n const destinationArtifacts = getEmittedArtifactPaths(contractPathAbsolute);\n await copyFilesWithRename(packageDir, [\n { sourcePath: destinationArtifacts.jsonPath, destName: 'end-contract.json' },\n { sourcePath: destinationArtifacts.dtsPath, destName: 'end-contract.d.ts' },\n ]);\n if (fromContractSourceDir !== null) {\n const sourceArtifacts = getEmittedArtifactPaths(\n join(fromContractSourceDir, 'end-contract.json'),\n );\n try {\n await copyFilesWithRename(packageDir, [\n { sourcePath: sourceArtifacts.jsonPath, destName: 'start-contract.json' },\n { sourcePath: sourceArtifacts.dtsPath, destName: 'start-contract.d.ts' },\n ]);\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(sourceArtifacts.jsonPath, {\n why: `Predecessor migration is missing its destination contract snapshot at ${sourceArtifacts.jsonPath}`,\n fix: 'Re-emit the predecessor migration (`prisma-next migration plan` from its source) so its sibling `end-contract.json` is restored, then re-run this command.',\n }),\n );\n }\n throw error;\n }\n }\n\n const planner = migrations.createPlanner(familyInstance);\n const emptyPlan = planner.emptyMigration(\n {\n packageDir,\n contractJsonPath: join(packageDir, 'end-contract.json'),\n fromHash,\n toHash: toStorageHash,\n },\n APP_SPACE_ID,\n );\n await writeMigrationTs(packageDir, emptyPlan.renderTypeScript());\n\n return ok({\n ok: true as const,\n dir: relative(process.cwd(), packageDir),\n from: fromHash,\n to: toStorageHash,\n summary: `Scaffolded migration at ${relative(process.cwd(), packageDir)}`,\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: `Failed to scaffold migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n}\n\nexport function createMigrationNewCommand(): Command {\n const command = new Command('new');\n setCommandDescriptions(\n command,\n 'Scaffold a new migration for manual authoring',\n 'Creates a migration package with a migration.ts file for manual authoring.\\n' +\n 'Write the migration body in migration.ts, then run the file with Node\\n' +\n '(`node migration.ts`) to self-emit ops.json and attest the package.',\n );\n setCommandExamples(command, [\n 'prisma-next migration new --name split-name',\n 'prisma-next migration new --name custom-fk --from sha256:abc...',\n ]);\n addGlobalOptions(command)\n .option('--name <slug>', 'Migration name (used in directory name)')\n .option('--from <hash>', 'Starting contract hash (default: latest migration target)')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (options: MigrationNewOptions) => {\n const flags = parseGlobalFlags(options);\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n if (!flags.json && !flags.quiet) {\n const header = formatStyledHeader({\n command: 'migration new',\n description: 'Scaffold a new migration',\n details: [],\n flags,\n });\n ui.stderr(header);\n }\n\n const result = await executeMigrationNewCommand(options);\n\n const exitCode = handleResult(result, flags, ui, (value) => {\n if (flags.json) {\n ui.output(JSON.stringify(value, null, 2));\n } else if (!flags.quiet) {\n ui.output(`\\nScaffolded migration at ${value.dir}`);\n ui.output(` from: ${value.from}`);\n ui.output(` to: ${value.to}`);\n ui.output(\n `\\nEdit migration.ts, then run it directly (\\`node \"${value.dir}/migration.ts\"\\`) to self-emit and attest.`,\n );\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-plan.d.mts","names":[],"sources":["../../src/commands/migration-plan.ts"],"mappings":";;;;;;UA0FiB,mBAAA;EAAA,SACN,EAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,GAAA;EAJA;;;;;;;;;;;;EAAA,SAiBA,oBAAA;IAAA,SAA0C,OAAA;IAAA,SAA0B,OAAA;EAAA;EAAA,SACpE,UAAA;IAAA,SACE,EAAA;IAAA,SACA,KAAA;IAAA,SACA,cAAA;EAAA;EAiZ6B;;;;AA+D1C;EA/D0C,SA1Y/B,OAAA,GAAU,gBAAA;EAAA,SACV,OAAA;EAwc8E;;;;;EAAA,SAlc9E,mBAAA;EAAA,SACA,OAAA;IAAA,SACE,KAAA;EAAA;AAAA;AAAA,iBAiYG,0BAAA,CAAA,GAA8B,OAAA;AAAA,iBA+D9B,yBAAA,CAA0B,MAAA,EAAQ,mBAAA,EAAqB,KAAA,EAAO,WAAA;AAAA,KA2HlE,uBAAA;EACN,MAAA;EAAqB,KAAA;AAAA;EACrB,MAAA;AAAA;;;;;;;;;;;;;;iBAeU,qBAAA;EAAkC,QAAA;IAAY,EAAA;EAAA;AAAA,EAAA,CAC5D,OAAA,WAAkB,CAAA,IAClB,MAAA,WACC,MAAA,CAAO,CAAA,EAAG,uBAAA"}
1
+ {"version":3,"file":"migration-plan.d.mts","names":[],"sources":["../../src/commands/migration-plan.ts"],"mappings":";;;;;;UAgHiB,mBAAA;EAAA,SACN,EAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,GAAA;EAJA;;;;;;;;;;;;EAAA,SAiBA,oBAAA;IAAA,SAA0C,OAAA;IAAA,SAA0B,OAAA;EAAA;EAAA,SACpE,UAAA;IAAA,SACE,EAAA;IAAA,SACA,KAAA;IAAA,SACA,cAAA;EAAA;EA8Y6B;;;;AA+D1C;EA/D0C,SAvY/B,OAAA,GAAU,gBAAA;EAAA,SACV,OAAA;EAqc8E;;;;;EAAA,SA/b9E,mBAAA;EAAA,SACA,OAAA;IAAA,SACE,KAAA;EAAA;AAAA;AAAA,iBA8XG,0BAAA,CAAA,GAA8B,OAAA;AAAA,iBA+D9B,yBAAA,CAA0B,MAAA,EAAQ,mBAAA,EAAqB,KAAA,EAAO,WAAA;AAAA,KA2HlE,uBAAA;EACN,MAAA;EAAqB,KAAA;AAAA;EACrB,MAAA;AAAA;;;;;;;;;;;;;;iBAeU,qBAAA;EAAkC,QAAA;IAAY,EAAA;EAAA;AAAA,EAAA,CAC5D,OAAA,WAAkB,CAAA,IAClB,MAAA,WACC,MAAA,CAAO,CAAA,EAAG,uBAAA"}
@@ -1,2 +1,2 @@
1
- import { n as formatMigrationPlanOutput, r as resolveBundleByPrefix, t as createMigrationPlanCommand } from "../migration-plan-DWB-NTxH.mjs";
1
+ import { n as formatMigrationPlanOutput, r as resolveBundleByPrefix, t as createMigrationPlanCommand } from "../migration-plan-CHyUlBV0.mjs";
2
2
  export { createMigrationPlanCommand, formatMigrationPlanOutput, resolveBundleByPrefix };
@@ -1 +1 @@
1
- {"version":3,"file":"migration-show.d.mts","names":[],"sources":["../../src/commands/migration-show.ts"],"mappings":";;;;;;;;;AAwDA;UAAiB,yBAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA;EAAA,SACA,OAAA;EAAA,SACA,OAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,aAAA;EAAA,SACA,SAAA;EAAA,SACA,UAAA;IAAA,SACE,EAAA;IAAA,SACA,KAAA;IAAA,SACA,cAAA;EAAA;EAAA;;;;;EAAA,SAOF,OAAA,EAAS,gBAAA;EAAA,SACT,OAAA;AAAA;;;;;;;;UAUM,yBAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA;EAAA,SACA,OAAA;AAAA;AAAA,KAGC,wBAAA,GAA2B,yBAAA,GAA4B,yBAAA;AAAA,UAElD,mBAAA;EAAA,SACN,EAAA;EAKyC;;;;EAAA,SAAzC,MAAA,WAAiB,wBAAA;AAAA;AAoB5B;;;;;;;;;;;AAuBA;;AAvBA,iBAAgB,oBAAA,CACd,MAAA,UACA,gBAAA,UACA,qBAAA,WACC,MAAA,SAAe,kBAAA;AAAA,iBAmBF,mBAAA,CACd,QAAA,WAAmB,sBAAA,IACnB,MAAA,WACC,MAAA,CAAO,sBAAA,EAAwB,kBAAA;;;;;;;;;;iBAmCZ,oBAAA,CACpB,QAAA,WACC,OAAA,CAAQ,MAAA,CAAO,sBAAA,SAA+B,kBAAA;AAAA,iBA4RjC,0BAAA,CAAA,GAA8B,OAAA"}
1
+ {"version":3,"file":"migration-show.d.mts","names":[],"sources":["../../src/commands/migration-show.ts"],"mappings":";;;;;;;;;AAwDA;UAAiB,yBAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA;EAAA,SACA,OAAA;EAAA,SACA,OAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,aAAA;EAAA,SACA,SAAA;EAAA,SACA,UAAA;IAAA,SACE,EAAA;IAAA,SACA,KAAA;IAAA,SACA,cAAA;EAAA;EAAA;;;;;EAAA,SAOF,OAAA,EAAS,gBAAA;EAAA,SACT,OAAA;AAAA;;;;;;;;UAUM,yBAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA;EAAA,SACA,OAAA;AAAA;AAAA,KAGC,wBAAA,GAA2B,yBAAA,GAA4B,yBAAA;AAAA,UAElD,mBAAA;EAAA,SACN,EAAA;EAKyC;;;;EAAA,SAAzC,MAAA,WAAiB,wBAAA;AAAA;AAoB5B;;;;;;;;;;;AAuBA;;AAvBA,iBAAgB,oBAAA,CACd,MAAA,UACA,gBAAA,UACA,qBAAA,WACC,MAAA,SAAe,kBAAA;AAAA,iBAmBF,mBAAA,CACd,QAAA,WAAmB,sBAAA,IACnB,MAAA,WACC,MAAA,CAAO,sBAAA,EAAwB,kBAAA;;;;;;;;;;iBAmCZ,oBAAA,CACpB,QAAA,WACC,OAAA,CAAQ,MAAA,CAAO,sBAAA,SAA+B,kBAAA;AAAA,iBAgSjC,0BAAA,CAAA,GAA8B,OAAA"}
@@ -3,8 +3,8 @@ import { _ as errorUnexpected, a as errorContractValidationFailed, l as errorFil
3
3
  import { _ as parseGlobalFlags, b as formatStyledHeader, c as resolveContractPath, d as setCommandDescriptions, f as setCommandExamples, l as resolveMigrationPaths, p as setCommandSeeAlso, t as addGlobalOptions } from "../command-helpers-D3vL5yi8.mjs";
4
4
  import { t as handleResult } from "../result-handler-Bm_6dDYg.mjs";
5
5
  import { t as TerminalUI } from "../terminal-ui-XtOQsqe9.mjs";
6
- import { t as createControlClient } from "../client-XkUw4xD0.mjs";
7
- import { t as buildContractSpaceAggregate } from "../contract-space-aggregate-loader-D68YpuPR.mjs";
6
+ import { t as createControlClient } from "../client-Brv4qlfB.mjs";
7
+ import { t as buildContractSpaceAggregate } from "../contract-space-aggregate-loader-pAc8CDfY.mjs";
8
8
  import { a as formatMigrationShowOutput } from "../migrations-DyUf5lTt.mjs";
9
9
  import { Command } from "commander";
10
10
  import { ifDefined } from "@prisma-next/utils/defined";
@@ -183,20 +183,20 @@ async function executeMigrationShowCommand(target, options, flags, ui) {
183
183
  }));
184
184
  return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: "Failed to read contract file" }));
185
185
  }
186
+ const stack = createControlStack(config);
187
+ const familyInstance = config.family.create(stack);
186
188
  let appContract;
187
189
  try {
188
- appContract = JSON.parse(contractJsonContent);
190
+ appContract = familyInstance.deserializeContract(JSON.parse(contractJsonContent));
189
191
  } catch (error) {
190
- return notOk(errorContractValidationFailed(`Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`, { where: { path: contractPathAbsolute } }));
192
+ return notOk(errorContractValidationFailed(`Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`, { where: { path: contractPathAbsolute } }));
191
193
  }
192
- const stack = createControlStack(config);
193
- const familyInstance = config.family.create(stack);
194
194
  const aggregateResult = await buildContractSpaceAggregate({
195
195
  targetId: config.target.targetId,
196
196
  migrationsDir,
197
197
  appContract,
198
198
  extensionPacks: config.extensionPacks ?? [],
199
- validateContract: (json) => familyInstance.validateContract(json)
199
+ deserializeContract: (json) => familyInstance.deserializeContract(json)
200
200
  });
201
201
  if (!aggregateResult.ok) return notOk(aggregateResult.failure);
202
202
  const aggregate = aggregateResult.value;
@@ -1 +1 @@
1
- {"version":3,"file":"migration-show.mjs","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport {\n APP_SPACE_ID,\n createControlStack,\n type MigrationPlanOperation,\n type OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport {\n findLatestMigration,\n reconstructGraph,\n} from '@prisma-next/migration-tools/migration-graph';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { parseMigrationRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { readRefs } from '@prisma-next/migration-tools/refs';\nimport { spaceMigrationDirectory } from '@prisma-next/migration-tools/spaces';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { isAbsolute, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n type CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n} from '../utils/command-helpers';\nimport { buildContractSpaceAggregate } from '../utils/contract-space-aggregate-loader';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\n/**\n * Details of one space's latest (or targeted) migration package.\n */\nexport interface MigrationShowSpacePresent {\n readonly kind: 'present';\n readonly spaceId: string;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string | null;\n readonly to: string;\n readonly migrationHash: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n /**\n * Family-agnostic textual preview of the migration's operations. Always\n * defined; statements is empty for a no-op migration or a family that does\n * not implement the `OperationPreviewCapable` capability.\n */\n readonly preview: OperationPreview;\n readonly summary: string;\n}\n\n/**\n * Placeholder for a loaded contract space that has no on-disk migration\n * package — the extension descriptor declared the space but no migrations\n * directory has been materialised for it yet. Surfaces the space in the\n * response so JSON consumers see every loaded extension instead of having\n * silently-skipped entries.\n */\nexport interface MigrationShowSpaceMissing {\n readonly kind: 'missing';\n readonly spaceId: string;\n readonly summary: string;\n}\n\nexport type MigrationShowSpaceResult = MigrationShowSpacePresent | MigrationShowSpaceMissing;\n\nexport interface MigrationShowResult {\n readonly ok: true;\n /**\n * Per-space results, ordered: app first, then extensions alphabetically\n * (matching the aggregate's canonical ordering).\n */\n readonly spaces: readonly MigrationShowSpaceResult[];\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\n/**\n * Validate that a path-like `migration show` target resolves inside the app\n * migrations directory. The returned result is always emitted under\n * `aggregate.app.spaceId`, so accepting an extension-space (or otherwise\n * external) path here would silently mislabel the result. Returns the\n * resolved absolute path on success.\n *\n * `pathe.relative` can return an absolute path when the target cannot be\n * expressed relative to the base (e.g. on Windows when `target` is on a\n * different drive than `appMigrationsDir`). That case does not start with\n * `..`, so the absolute-check below is required to reject cross-drive\n * targets rather than mislabeling them as app-space.\n */\nexport function resolveAppTargetPath(\n target: string,\n appMigrationsDir: string,\n appMigrationsRelative: string,\n): Result<string, CliStructuredError> {\n const targetPath = resolve(target);\n const relativeToApp = relative(appMigrationsDir, targetPath);\n const isOutsideAppDir =\n relativeToApp === '' ||\n relativeToApp === '.' ||\n relativeToApp.startsWith('..') ||\n isAbsolute(relativeToApp);\n if (isOutsideAppDir) {\n return notOk(\n errorRuntime('Target must point to an app-space migration', {\n why: `Expected a path under ${appMigrationsRelative}, got ${target}`,\n fix: 'Pass an app-space migration directory or use a hash prefix.',\n }),\n );\n }\n return ok(targetPath);\n}\n\nexport function resolveByHashPrefix(\n packages: readonly OnDiskMigrationPackage[],\n prefix: string,\n): Result<OnDiskMigrationPackage, CliStructuredError> {\n const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;\n const matches = packages.filter((p) => p.metadata.migrationHash.startsWith(normalizedPrefix));\n\n if (matches.length === 1) {\n return ok(matches[0]!);\n }\n\n if (matches.length === 0) {\n return notOk(\n errorRuntime('No migration found matching prefix', {\n why: `No migration has a migrationHash starting with \"${normalizedPrefix}\"`,\n fix: 'Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages.',\n }),\n );\n }\n\n const candidates = matches.map((p) => ` ${p.dirName} ${p.metadata.migrationHash}`).join('\\n');\n return notOk(\n errorRuntime('Ambiguous hash prefix', {\n why: `Multiple migrations match prefix \"${normalizedPrefix}\":\\n${candidates}`,\n fix: 'Provide a longer prefix to uniquely identify the migration.',\n }),\n );\n}\n\n/**\n * Resolve the latest migration from a space directory.\n *\n * Returns `ok(null)` only when the directory is empty or absent (ENOENT is\n * absorbed by `readMigrationsDir`). If `readMigrationsDir` returned packages\n * but `findLatestMigration` cannot pick a leaf, the on-disk history is\n * corrupt — return a runtime error rather than collapsing it to a `missing`\n * placeholder, which would hide the corruption from the caller.\n */\nexport async function resolveLatestFromDir(\n spaceDir: string,\n): Promise<Result<OnDiskMigrationPackage | null, CliStructuredError>> {\n try {\n const allPackages = await readMigrationsDir(spaceDir);\n if (allPackages.length === 0) return ok(null);\n const graph = reconstructGraph(allPackages);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `No latest migration found in ${relative(process.cwd(), spaceDir)}`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = allPackages.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n return ok(leafPkg ?? null);\n } catch (error) {\n if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migrations: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n}\n\nfunction pkgToSpaceResult(\n spaceId: string,\n pkg: OnDiskMigrationPackage,\n client: ReturnType<typeof createControlClient>,\n): MigrationShowSpacePresent {\n const ops = pkg.ops as readonly MigrationPlanOperation[];\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n return {\n kind: 'present',\n spaceId,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.metadata.from,\n to: pkg.metadata.to,\n migrationHash: pkg.metadata.migrationHash,\n createdAt: pkg.metadata.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n preview,\n summary: `${ops.length} operation(s)`,\n };\n}\n\nasync function executeMigrationShowCommand(\n target: string | undefined,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative, refsDir } =\n resolveMigrationPaths(options.config, config);\n\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (target) {\n details.push({ label: 'target', value: target });\n }\n const header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n // `migration show` is an offline command; the control client is constructed\n // purely to dispatch the family-specific `toOperationPreview` capability and\n // is not connected to a database.\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...ifDefined('driver', config.driver),\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Explicit-target path. Read the app-space migrations directory directly\n // and resolve `target` against the app graph. We deliberately skip\n // `buildContractSpaceAggregate` here for two reasons:\n //\n // 1. Functional: the user asked about ONE specific migration. They don't\n // need extension-space enumeration; resolving + rendering the named\n // package is enough.\n // 2. UX: the aggregate's layout-integrity check (PN-MIG-5001) fires when\n // an extension is declared but its migrations directory hasn't been\n // materialised. Gating an offline read-only inspect command on that\n // check forces users to run `migrate` against a database before they\n // can see what a migration contains — which contradicts what an\n // offline read-only verb should require.\n //\n // Same pattern as `migration list`, `migration graph`, `migration check`:\n // those verbs read `appMigrationsDir` directly without ever consulting\n // the aggregate.\n if (target) {\n try {\n let appPkg: OnDiskMigrationPackage;\n if (looksLikePath(target)) {\n const resolved = resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative);\n if (!resolved.ok) return resolved;\n appPkg = await readMigrationPackage(resolved.value);\n } else {\n const allPackages = await readMigrationsDir(appMigrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${appMigrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n const graph = reconstructGraph(allPackages);\n const refs = await readRefs(refsDir);\n const migResult = parseMigrationRef(target, { graph, refs });\n if (!migResult.ok) {\n return notOk(mapRefResolutionError(migResult.failure));\n }\n const matchedPkg = allPackages.find(\n (p) => p.metadata.migrationHash === migResult.value.migrationHash,\n );\n if (!matchedPkg) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `Resolved migration \"${migResult.value.dirName}\" but the package was not loaded`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n appPkg = matchedPkg;\n }\n return ok({\n ok: true,\n spaces: [pkgToSpaceResult(APP_SPACE_ID, appPkg, client)],\n });\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read app-space migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n }\n\n // No-target path. Enumerate the latest migration per space (app +\n // extensions). The aggregate-loader is needed here because we need to\n // know which extension spaces are declared; its layout-integrity check\n // is appropriate at this entry point because the user is asking the\n // system to report on every loaded space.\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}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to read contract file',\n }),\n );\n }\n\n let appContract: Contract;\n try {\n appContract = JSON.parse(contractJsonContent) as Contract;\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 const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n const aggregateResult = await buildContractSpaceAggregate({\n targetId: config.target.targetId,\n migrationsDir,\n appContract,\n extensionPacks: config.extensionPacks ?? [],\n validateContract: (json: unknown) => familyInstance.validateContract(json),\n });\n if (!aggregateResult.ok) {\n return notOk(aggregateResult.failure);\n }\n const aggregate = aggregateResult.value;\n\n const spaces: MigrationShowSpaceResult[] = [];\n\n // App space: latest leaf.\n try {\n const allPackages = await readMigrationsDir(appMigrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${appMigrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n const graph = reconstructGraph(allPackages);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: 'No latest migration found in the migration history',\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = allPackages.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n if (!leafPkg) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `Latest migration ${latestMigration.dirName} does not match any package`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n spaces.push(pkgToSpaceResult(aggregate.app.spaceId, leafPkg, client));\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read app-space migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n // Extension spaces: always emit one entry per loaded extension so the\n // response enumerates every space the aggregate knows about. Spaces\n // with no on-disk migration package yet (e.g. an extension was declared\n // but never `migrate`d) become `kind: 'missing'` placeholders instead\n // of being silently skipped.\n for (const ext of aggregate.extensions) {\n const extSpaceDir = spaceMigrationDirectory(migrationsDir, ext.spaceId);\n const extPkgResult = await resolveLatestFromDir(extSpaceDir);\n if (!extPkgResult.ok) return extPkgResult;\n if (extPkgResult.value !== null) {\n spaces.push(pkgToSpaceResult(ext.spaceId, extPkgResult.value, client));\n } else {\n spaces.push({\n kind: 'missing',\n spaceId: ext.spaceId,\n summary: 'No on-disk migration package for this space',\n });\n }\n }\n\n return ok({ ok: true, spaces });\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, statement preview, and metadata for every loaded contract\\n' +\n 'space (app + extensions). Accepts a directory path or hash prefix to target a\\n' +\n 'specific app-space migration; defaults to the latest per space.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration log', oneLiner: 'Show executed migration history' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration graph', oneLiner: 'Show the migration graph topology' },\n ]);\n addGlobalOptions(command)\n .argument(\n '[target]',\n 'Migration reference: directory name, hash/prefix, or path (defaults to latest)',\n )\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlags(options);\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, 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-show.mjs","names":[],"sources":["../../src/commands/migration-show.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport {\n APP_SPACE_ID,\n createControlStack,\n type MigrationPlanOperation,\n type OperationPreview,\n} from '@prisma-next/framework-components/control';\nimport { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport { readMigrationPackage, readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport {\n findLatestMigration,\n reconstructGraph,\n} from '@prisma-next/migration-tools/migration-graph';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { parseMigrationRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { readRefs } from '@prisma-next/migration-tools/refs';\nimport { spaceMigrationDirectory } from '@prisma-next/migration-tools/spaces';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { isAbsolute, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n type CliStructuredError,\n errorContractValidationFailed,\n errorFileNotFound,\n errorRuntime,\n errorUnexpected,\n mapMigrationToolsError,\n mapRefResolutionError,\n} from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n resolveContractPath,\n resolveMigrationPaths,\n setCommandDescriptions,\n setCommandExamples,\n setCommandSeeAlso,\n} from '../utils/command-helpers';\nimport { buildContractSpaceAggregate } from '../utils/contract-space-aggregate-loader';\nimport { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\n/**\n * Details of one space's latest (or targeted) migration package.\n */\nexport interface MigrationShowSpacePresent {\n readonly kind: 'present';\n readonly spaceId: string;\n readonly dirName: string;\n readonly dirPath: string;\n readonly from: string | null;\n readonly to: string;\n readonly migrationHash: string;\n readonly createdAt: string;\n readonly operations: readonly {\n readonly id: string;\n readonly label: string;\n readonly operationClass: string;\n }[];\n /**\n * Family-agnostic textual preview of the migration's operations. Always\n * defined; statements is empty for a no-op migration or a family that does\n * not implement the `OperationPreviewCapable` capability.\n */\n readonly preview: OperationPreview;\n readonly summary: string;\n}\n\n/**\n * Placeholder for a loaded contract space that has no on-disk migration\n * package — the extension descriptor declared the space but no migrations\n * directory has been materialised for it yet. Surfaces the space in the\n * response so JSON consumers see every loaded extension instead of having\n * silently-skipped entries.\n */\nexport interface MigrationShowSpaceMissing {\n readonly kind: 'missing';\n readonly spaceId: string;\n readonly summary: string;\n}\n\nexport type MigrationShowSpaceResult = MigrationShowSpacePresent | MigrationShowSpaceMissing;\n\nexport interface MigrationShowResult {\n readonly ok: true;\n /**\n * Per-space results, ordered: app first, then extensions alphabetically\n * (matching the aggregate's canonical ordering).\n */\n readonly spaces: readonly MigrationShowSpaceResult[];\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\n\n/**\n * Validate that a path-like `migration show` target resolves inside the app\n * migrations directory. The returned result is always emitted under\n * `aggregate.app.spaceId`, so accepting an extension-space (or otherwise\n * external) path here would silently mislabel the result. Returns the\n * resolved absolute path on success.\n *\n * `pathe.relative` can return an absolute path when the target cannot be\n * expressed relative to the base (e.g. on Windows when `target` is on a\n * different drive than `appMigrationsDir`). That case does not start with\n * `..`, so the absolute-check below is required to reject cross-drive\n * targets rather than mislabeling them as app-space.\n */\nexport function resolveAppTargetPath(\n target: string,\n appMigrationsDir: string,\n appMigrationsRelative: string,\n): Result<string, CliStructuredError> {\n const targetPath = resolve(target);\n const relativeToApp = relative(appMigrationsDir, targetPath);\n const isOutsideAppDir =\n relativeToApp === '' ||\n relativeToApp === '.' ||\n relativeToApp.startsWith('..') ||\n isAbsolute(relativeToApp);\n if (isOutsideAppDir) {\n return notOk(\n errorRuntime('Target must point to an app-space migration', {\n why: `Expected a path under ${appMigrationsRelative}, got ${target}`,\n fix: 'Pass an app-space migration directory or use a hash prefix.',\n }),\n );\n }\n return ok(targetPath);\n}\n\nexport function resolveByHashPrefix(\n packages: readonly OnDiskMigrationPackage[],\n prefix: string,\n): Result<OnDiskMigrationPackage, CliStructuredError> {\n const normalizedPrefix = prefix.startsWith('sha256:') ? prefix : `sha256:${prefix}`;\n const matches = packages.filter((p) => p.metadata.migrationHash.startsWith(normalizedPrefix));\n\n if (matches.length === 1) {\n return ok(matches[0]!);\n }\n\n if (matches.length === 0) {\n return notOk(\n errorRuntime('No migration found matching prefix', {\n why: `No migration has a migrationHash starting with \"${normalizedPrefix}\"`,\n fix: 'Run `prisma-next migration show` (no argument) to see the latest migration, or check the migrations directory for available packages.',\n }),\n );\n }\n\n const candidates = matches.map((p) => ` ${p.dirName} ${p.metadata.migrationHash}`).join('\\n');\n return notOk(\n errorRuntime('Ambiguous hash prefix', {\n why: `Multiple migrations match prefix \"${normalizedPrefix}\":\\n${candidates}`,\n fix: 'Provide a longer prefix to uniquely identify the migration.',\n }),\n );\n}\n\n/**\n * Resolve the latest migration from a space directory.\n *\n * Returns `ok(null)` only when the directory is empty or absent (ENOENT is\n * absorbed by `readMigrationsDir`). If `readMigrationsDir` returned packages\n * but `findLatestMigration` cannot pick a leaf, the on-disk history is\n * corrupt — return a runtime error rather than collapsing it to a `missing`\n * placeholder, which would hide the corruption from the caller.\n */\nexport async function resolveLatestFromDir(\n spaceDir: string,\n): Promise<Result<OnDiskMigrationPackage | null, CliStructuredError>> {\n try {\n const allPackages = await readMigrationsDir(spaceDir);\n if (allPackages.length === 0) return ok(null);\n const graph = reconstructGraph(allPackages);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `No latest migration found in ${relative(process.cwd(), spaceDir)}`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = allPackages.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n return ok(leafPkg ?? null);\n } catch (error) {\n if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read migrations: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n}\n\nfunction pkgToSpaceResult(\n spaceId: string,\n pkg: OnDiskMigrationPackage,\n client: ReturnType<typeof createControlClient>,\n): MigrationShowSpacePresent {\n const ops = pkg.ops as readonly MigrationPlanOperation[];\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n return {\n kind: 'present',\n spaceId,\n dirName: pkg.dirName,\n dirPath: relative(process.cwd(), pkg.dirPath),\n from: pkg.metadata.from,\n to: pkg.metadata.to,\n migrationHash: pkg.metadata.migrationHash,\n createdAt: pkg.metadata.createdAt,\n operations: ops.map((op) => ({\n id: op.id,\n label: op.label,\n operationClass: op.operationClass,\n })),\n preview,\n summary: `${ops.length} operation(s)`,\n };\n}\n\nasync function executeMigrationShowCommand(\n target: string | undefined,\n options: MigrationShowOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n): Promise<Result<MigrationShowResult, CliStructuredError>> {\n const config = await loadConfig(options.config);\n const { configPath, migrationsDir, appMigrationsDir, appMigrationsRelative, refsDir } =\n resolveMigrationPaths(options.config, config);\n\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: appMigrationsRelative },\n ];\n if (target) {\n details.push({ label: 'target', value: target });\n }\n const header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n // `migration show` is an offline command; the control client is constructed\n // purely to dispatch the family-specific `toOperationPreview` capability and\n // is not connected to a database.\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n ...ifDefined('driver', config.driver),\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Explicit-target path. Read the app-space migrations directory directly\n // and resolve `target` against the app graph. We deliberately skip\n // `buildContractSpaceAggregate` here for two reasons:\n //\n // 1. Functional: the user asked about ONE specific migration. They don't\n // need extension-space enumeration; resolving + rendering the named\n // package is enough.\n // 2. UX: the aggregate's layout-integrity check (PN-MIG-5001) fires when\n // an extension is declared but its migrations directory hasn't been\n // materialised. Gating an offline read-only inspect command on that\n // check forces users to run `migrate` against a database before they\n // can see what a migration contains — which contradicts what an\n // offline read-only verb should require.\n //\n // Same pattern as `migration list`, `migration graph`, `migration check`:\n // those verbs read `appMigrationsDir` directly without ever consulting\n // the aggregate.\n if (target) {\n try {\n let appPkg: OnDiskMigrationPackage;\n if (looksLikePath(target)) {\n const resolved = resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative);\n if (!resolved.ok) return resolved;\n appPkg = await readMigrationPackage(resolved.value);\n } else {\n const allPackages = await readMigrationsDir(appMigrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${appMigrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n const graph = reconstructGraph(allPackages);\n const refs = await readRefs(refsDir);\n const migResult = parseMigrationRef(target, { graph, refs });\n if (!migResult.ok) {\n return notOk(mapRefResolutionError(migResult.failure));\n }\n const matchedPkg = allPackages.find(\n (p) => p.metadata.migrationHash === migResult.value.migrationHash,\n );\n if (!matchedPkg) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `Resolved migration \"${migResult.value.dirName}\" but the package was not loaded`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n appPkg = matchedPkg;\n }\n return ok({\n ok: true,\n spaces: [pkgToSpaceResult(APP_SPACE_ID, appPkg, client)],\n });\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read app-space migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n }\n\n // No-target path. Enumerate the latest migration per space (app +\n // extensions). The aggregate-loader is needed here because we need to\n // know which extension spaces are declared; its layout-integrity check\n // is appropriate at this entry point because the user is asking the\n // system to report on every loaded space.\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}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to read contract file',\n }),\n );\n }\n\n // Construct the family instance up-front so the on-disk app contract\n // read crosses the serializer seam (`familyInstance.deserializeContract`)\n // at the read site. See TML-2536.\n const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let appContract: Contract;\n try {\n appContract = familyInstance.deserializeContract(JSON.parse(contractJsonContent) as unknown);\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract at ${contractPathAbsolute} failed to deserialize: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n const aggregateResult = await buildContractSpaceAggregate({\n targetId: config.target.targetId,\n migrationsDir,\n appContract,\n extensionPacks: config.extensionPacks ?? [],\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n });\n if (!aggregateResult.ok) {\n return notOk(aggregateResult.failure);\n }\n const aggregate = aggregateResult.value;\n\n const spaces: MigrationShowSpaceResult[] = [];\n\n // App space: latest leaf.\n try {\n const allPackages = await readMigrationsDir(appMigrationsDir);\n if (allPackages.length === 0) {\n return notOk(\n errorRuntime('No migrations found', {\n why: `No migration packages found in ${appMigrationsRelative}`,\n fix: 'Run `prisma-next migration plan` to create a migration first.',\n }),\n );\n }\n const graph = reconstructGraph(allPackages);\n const latestMigration = findLatestMigration(graph);\n if (!latestMigration) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: 'No latest migration found in the migration history',\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n const leafPkg = allPackages.find(\n (p) => p.metadata.migrationHash === latestMigration.migrationHash,\n );\n if (!leafPkg) {\n return notOk(\n errorRuntime('Could not resolve latest migration', {\n why: `Latest migration ${latestMigration.dirName} does not match any package`,\n fix: 'The migrations directory may be corrupted. Inspect the migration.json files.',\n }),\n );\n }\n spaces.push(pkgToSpaceResult(aggregate.app.spaceId, leafPkg, client));\n } catch (error) {\n if (MigrationToolsError.is(error)) {\n return notOk(mapMigrationToolsError(error));\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read app-space migration: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n // Extension spaces: always emit one entry per loaded extension so the\n // response enumerates every space the aggregate knows about. Spaces\n // with no on-disk migration package yet (e.g. an extension was declared\n // but never `migrate`d) become `kind: 'missing'` placeholders instead\n // of being silently skipped.\n for (const ext of aggregate.extensions) {\n const extSpaceDir = spaceMigrationDirectory(migrationsDir, ext.spaceId);\n const extPkgResult = await resolveLatestFromDir(extSpaceDir);\n if (!extPkgResult.ok) return extPkgResult;\n if (extPkgResult.value !== null) {\n spaces.push(pkgToSpaceResult(ext.spaceId, extPkgResult.value, client));\n } else {\n spaces.push({\n kind: 'missing',\n spaceId: ext.spaceId,\n summary: 'No on-disk migration package for this space',\n });\n }\n }\n\n return ok({ ok: true, spaces });\n}\n\nexport function createMigrationShowCommand(): Command {\n const command = new Command('show');\n setCommandDescriptions(\n command,\n 'Display migration package contents',\n 'Shows the operations, statement preview, and metadata for every loaded contract\\n' +\n 'space (app + extensions). Accepts a directory path or hash prefix to target a\\n' +\n 'specific app-space migration; defaults to the latest per space.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show',\n 'prisma-next migration show sha256:a1b2c3',\n ]);\n setCommandSeeAlso(command, [\n { verb: 'migration status', oneLiner: 'Show migration path and pending status' },\n { verb: 'migration log', oneLiner: 'Show executed migration history' },\n { verb: 'migration list', oneLiner: 'List on-disk migrations' },\n { verb: 'migration graph', oneLiner: 'Show the migration graph topology' },\n ]);\n addGlobalOptions(command)\n .argument(\n '[target]',\n 'Migration reference: directory name, hash/prefix, or path (defaults to latest)',\n )\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string | undefined, options: MigrationShowOptions) => {\n const flags = parseGlobalFlags(options);\n\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n\n const result = await executeMigrationShowCommand(target, options, flags, ui);\n\n const exitCode = handleResult(result, flags, ui, (showResult) => {\n if (flags.json) {\n ui.output(JSON.stringify(showResult, null, 2));\n } else if (!flags.quiet) {\n ui.log(formatMigrationShowOutput(showResult, flags));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuGA,SAAS,cAAc,QAAyB;CAC9C,OAAO,OAAO,SAAS,IAAI,IAAI,OAAO,SAAS,KAAK;;;;;;;;;;;;;;;AAgBtD,SAAgB,qBACd,QACA,kBACA,uBACoC;CACpC,MAAM,aAAa,QAAQ,OAAO;CAClC,MAAM,gBAAgB,SAAS,kBAAkB,WAAW;CAM5D,IAJE,kBAAkB,MAClB,kBAAkB,OAClB,cAAc,WAAW,KAAK,IAC9B,WAAW,cAAc,EAEzB,OAAO,MACL,aAAa,+CAA+C;EAC1D,KAAK,yBAAyB,sBAAsB,QAAQ;EAC5D,KAAK;EACN,CAAC,CACH;CAEH,OAAO,GAAG,WAAW;;AAGvB,SAAgB,oBACd,UACA,QACoD;CACpD,MAAM,mBAAmB,OAAO,WAAW,UAAU,GAAG,SAAS,UAAU;CAC3E,MAAM,UAAU,SAAS,QAAQ,MAAM,EAAE,SAAS,cAAc,WAAW,iBAAiB,CAAC;CAE7F,IAAI,QAAQ,WAAW,GACrB,OAAO,GAAG,QAAQ,GAAI;CAGxB,IAAI,QAAQ,WAAW,GACrB,OAAO,MACL,aAAa,sCAAsC;EACjD,KAAK,mDAAmD,iBAAiB;EACzE,KAAK;EACN,CAAC,CACH;CAIH,OAAO,MACL,aAAa,yBAAyB;EACpC,KAAK,qCAAqC,iBAAiB,MAH5C,QAAQ,KAAK,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,SAAS,gBAAgB,CAAC,KAAK,KAGX;EAC3E,KAAK;EACN,CAAC,CACH;;;;;;;;;;;AAYH,eAAsB,qBACpB,UACoE;CACpE,IAAI;EACF,MAAM,cAAc,MAAM,kBAAkB,SAAS;EACrD,IAAI,YAAY,WAAW,GAAG,OAAO,GAAG,KAAK;EAE7C,MAAM,kBAAkB,oBADV,iBAAiB,YACkB,CAAC;EAClD,IAAI,CAAC,iBACH,OAAO,MACL,aAAa,sCAAsC;GACjD,KAAK,gCAAgC,SAAS,QAAQ,KAAK,EAAE,SAAS;GACtE,KAAK;GACN,CAAC,CACH;EAKH,OAAO,GAHS,YAAY,MACzB,MAAM,EAAE,SAAS,kBAAkB,gBAAgB,cAErC,IAAI,KAAK;UACnB,OAAO;EACd,IAAI,oBAAoB,GAAG,MAAM,EAAE,OAAO,MAAM,uBAAuB,MAAM,CAAC;EAC9E,OAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IAC1F,CAAC,CACH;;;AAIL,SAAS,iBACP,SACA,KACA,QAC2B;CAC3B,MAAM,MAAM,IAAI;CAChB,MAAM,UAA4B,OAAO,mBAAmB,IAAI,IAAI,EAAE,YAAY,EAAE,EAAE;CACtF,OAAO;EACL,MAAM;EACN;EACA,SAAS,IAAI;EACb,SAAS,SAAS,QAAQ,KAAK,EAAE,IAAI,QAAQ;EAC7C,MAAM,IAAI,SAAS;EACnB,IAAI,IAAI,SAAS;EACjB,eAAe,IAAI,SAAS;EAC5B,WAAW,IAAI,SAAS;EACxB,YAAY,IAAI,KAAK,QAAQ;GAC3B,IAAI,GAAG;GACP,OAAO,GAAG;GACV,gBAAgB,GAAG;GACpB,EAAE;EACH;EACA,SAAS,GAAG,IAAI,OAAO;EACxB;;AAGH,eAAe,4BACb,QACA,SACA,OACA,IAC0D;CAC1D,MAAM,SAAS,MAAM,WAAW,QAAQ,OAAO;CAC/C,MAAM,EAAE,YAAY,eAAe,kBAAkB,uBAAuB,YAC1E,sBAAsB,QAAQ,QAAQ,OAAO;CAE/C,MAAM,uBAAuB,oBAAoB,OAAO;CACxD,MAAM,eAAe,SAAS,QAAQ,KAAK,EAAE,qBAAqB;CAElE,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OAAO;EAC/B,MAAM,UAAmD;GACvD;IAAE,OAAO;IAAU,OAAO;IAAY;GACtC;IAAE,OAAO;IAAY,OAAO;IAAc;GAC1C;IAAE,OAAO;IAAc,OAAO;IAAuB;GACtD;EACD,IAAI,QACF,QAAQ,KAAK;GAAE,OAAO;GAAU,OAAO;GAAQ,CAAC;EAElD,MAAM,SAAS,mBAAmB;GAChC,SAAS;GACT,aAAa;GACb;GACA;GACD,CAAC;EACF,GAAG,OAAO,OAAO;;CAMnB,MAAM,SAAS,oBAAoB;EACjC,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,GAAG,UAAU,UAAU,OAAO,OAAO;EACrC,gBAAgB,OAAO,kBAAkB,EAAE;EAC5C,CAAC;CAmBF,IAAI,QACF,IAAI;EACF,IAAI;EACJ,IAAI,cAAc,OAAO,EAAE;GACzB,MAAM,WAAW,qBAAqB,QAAQ,kBAAkB,sBAAsB;GACtF,IAAI,CAAC,SAAS,IAAI,OAAO;GACzB,SAAS,MAAM,qBAAqB,SAAS,MAAM;SAC9C;GACL,MAAM,cAAc,MAAM,kBAAkB,iBAAiB;GAC7D,IAAI,YAAY,WAAW,GACzB,OAAO,MACL,aAAa,uBAAuB;IAClC,KAAK,kCAAkC;IACvC,KAAK;IACN,CAAC,CACH;GAIH,MAAM,YAAY,kBAAkB,QAAQ;IAAE,OAFhC,iBAAiB,YAEoB;IAAE,MAAA,MADlC,SAAS,QAAQ;IACuB,CAAC;GAC5D,IAAI,CAAC,UAAU,IACb,OAAO,MAAM,sBAAsB,UAAU,QAAQ,CAAC;GAExD,MAAM,aAAa,YAAY,MAC5B,MAAM,EAAE,SAAS,kBAAkB,UAAU,MAAM,cACrD;GACD,IAAI,CAAC,YACH,OAAO,MACL,aAAa,+BAA+B;IAC1C,KAAK,uBAAuB,UAAU,MAAM,QAAQ;IACpD,KAAK;IACN,CAAC,CACH;GAEH,SAAS;;EAEX,OAAO,GAAG;GACR,IAAI;GACJ,QAAQ,CAAC,iBAAiB,cAAc,QAAQ,OAAO,CAAC;GACzD,CAAC;UACK,OAAO;EACd,IAAI,oBAAoB,GAAG,MAAM,EAC/B,OAAO,MAAM,uBAAuB,MAAM,CAAC;EAE7C,OAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,uCAAuC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACnG,CAAC,CACH;;CASL,IAAI;CACJ,IAAI;EACF,sBAAsB,MAAM,SAAS,sBAAsB,QAAQ;UAC5D,OAAO;EACd,IAAI,iBAAiB,SAAU,MAA4B,SAAS,UAClE,OAAO,MACL,kBAAkB,sBAAsB;GACtC,KAAK,8BAA8B;GACnC,KAAK,iDAAiD;GACvD,CAAC,CACH;EAEH,OAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,gCACN,CAAC,CACH;;CAMH,MAAM,QAAQ,mBAAmB,OAAO;CACxC,MAAM,iBAAiB,OAAO,OAAO,OAAO,MAAM;CAElD,IAAI;CACJ,IAAI;EACF,cAAc,eAAe,oBAAoB,KAAK,MAAM,oBAAoB,CAAY;UACrF,OAAO;EACd,OAAO,MACL,8BACE,eAAe,qBAAqB,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACpH,EAAE,OAAO,EAAE,MAAM,sBAAsB,EAAE,CAC1C,CACF;;CAGH,MAAM,kBAAkB,MAAM,4BAA4B;EACxD,UAAU,OAAO,OAAO;EACxB;EACA;EACA,gBAAgB,OAAO,kBAAkB,EAAE;EAC3C,sBAAsB,SAAkB,eAAe,oBAAoB,KAAK;EACjF,CAAC;CACF,IAAI,CAAC,gBAAgB,IACnB,OAAO,MAAM,gBAAgB,QAAQ;CAEvC,MAAM,YAAY,gBAAgB;CAElC,MAAM,SAAqC,EAAE;CAG7C,IAAI;EACF,MAAM,cAAc,MAAM,kBAAkB,iBAAiB;EAC7D,IAAI,YAAY,WAAW,GACzB,OAAO,MACL,aAAa,uBAAuB;GAClC,KAAK,kCAAkC;GACvC,KAAK;GACN,CAAC,CACH;EAGH,MAAM,kBAAkB,oBADV,iBAAiB,YACkB,CAAC;EAClD,IAAI,CAAC,iBACH,OAAO,MACL,aAAa,sCAAsC;GACjD,KAAK;GACL,KAAK;GACN,CAAC,CACH;EAEH,MAAM,UAAU,YAAY,MACzB,MAAM,EAAE,SAAS,kBAAkB,gBAAgB,cACrD;EACD,IAAI,CAAC,SACH,OAAO,MACL,aAAa,sCAAsC;GACjD,KAAK,oBAAoB,gBAAgB,QAAQ;GACjD,KAAK;GACN,CAAC,CACH;EAEH,OAAO,KAAK,iBAAiB,UAAU,IAAI,SAAS,SAAS,OAAO,CAAC;UAC9D,OAAO;EACd,IAAI,oBAAoB,GAAG,MAAM,EAC/B,OAAO,MAAM,uBAAuB,MAAM,CAAC;EAE7C,OAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,uCAAuC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACnG,CAAC,CACH;;CAQH,KAAK,MAAM,OAAO,UAAU,YAAY;EAEtC,MAAM,eAAe,MAAM,qBADP,wBAAwB,eAAe,IAAI,QACJ,CAAC;EAC5D,IAAI,CAAC,aAAa,IAAI,OAAO;EAC7B,IAAI,aAAa,UAAU,MACzB,OAAO,KAAK,iBAAiB,IAAI,SAAS,aAAa,OAAO,OAAO,CAAC;OAEtE,OAAO,KAAK;GACV,MAAM;GACN,SAAS,IAAI;GACb,SAAS;GACV,CAAC;;CAIN,OAAO,GAAG;EAAE,IAAI;EAAM;EAAQ,CAAC;;AAGjC,SAAgB,6BAAsC;CACpD,MAAM,UAAU,IAAI,QAAQ,OAAO;CACnC,uBACE,SACA,sCACA,kOAGD;CACD,mBAAmB,SAAS,CAC1B,8BACA,2CACD,CAAC;CACF,kBAAkB,SAAS;EACzB;GAAE,MAAM;GAAoB,UAAU;GAA0C;EAChF;GAAE,MAAM;GAAiB,UAAU;GAAmC;EACtE;GAAE,MAAM;GAAkB,UAAU;GAA2B;EAC/D;GAAE,MAAM;GAAmB,UAAU;GAAqC;EAC3E,CAAC;CACF,iBAAiB,QAAQ,CACtB,SACC,YACA,iFACD,CACA,OAAO,mBAAmB,gCAAgC,CAC1D,OAAO,OAAO,QAA4B,YAAkC;EAC3E,MAAM,QAAQ,iBAAiB,QAAQ;EAEvC,MAAM,KAAK,IAAI,WAAW;GAAE,OAAO,MAAM;GAAO,aAAa,MAAM;GAAa,CAAC;EAIjF,MAAM,WAAW,aAAa,MAFT,4BAA4B,QAAQ,SAAS,OAAO,GAAG,EAEtC,OAAO,KAAK,eAAe;GAC/D,IAAI,MAAM,MACR,GAAG,OAAO,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,OAChB,GAAG,IAAI,0BAA0B,YAAY,MAAM,CAAC;IAEtD;EAEF,QAAQ,KAAK,SAAS;GACtB;CAEJ,OAAO"}
@@ -20,7 +20,7 @@ interface BuildAggregateInputs<TFamilyId extends string, TTargetId extends strin
20
20
  readonly migrationsDir: string;
21
21
  readonly appContract: Contract;
22
22
  readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
23
- readonly validateContract: (contractJson: unknown) => Contract;
23
+ readonly deserializeContract: (contractJson: unknown) => Contract;
24
24
  /**
25
25
  * App-space migration packages to hydrate the app member's
26
26
  * migration graph with. Defaults to `[]` (matches the `db init` /
@@ -184,7 +184,7 @@ declare function loadAggregateStatusSpaces(args: {
184
184
  readonly migrationsDir: string;
185
185
  readonly appContractRaw: unknown;
186
186
  readonly extensionPacks: BuildAggregateInputs<string, string>['extensionPacks'];
187
- readonly validateContract: BuildAggregateInputs<string, string>['validateContract'];
187
+ readonly deserializeContract: BuildAggregateInputs<string, string>['deserializeContract'];
188
188
  readonly markersBySpace: ReadonlyMap<string, ContractMarkerRecordLike> | null;
189
189
  }): Promise<readonly MigrationStatusSpaceEntry[]>;
190
190
  declare function createMigrationStatusCommand(): Command;
@@ -1 +1 @@
1
- {"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/contract-space-aggregate-loader.ts","../../src/utils/formatters/graph-migration-mapper.ts","../../src/commands/migration-status.ts"],"mappings":";;;;;;;;;;;;;;;;;UAqHiB,oBAAA;EAAA,SACN,QAAA,EAAU,SAAA;EAAA,SACV,aAAA;EAAA,SACA,WAAA,EAAa,QAAA;EAAA,SACb,cAAA,EAAgB,aAAA,CAAc,0BAAA,CAA2B,SAAA,EAAW,SAAA;EAAA,SACpE,gBAAA,GAAmB,YAAA,cAA0B,QAAA;EAJ7C;;;;;;;;;;;;EAAA,SAiBA,oBAAA,GAAuB,aAAA,CAAc,sBAAA;AAAA;;;KCtHpC,cAAA;;UAmBK,UAAA;EAAA,SACN,OAAA;EAAA,SACA,MAAA,EAAQ,cAAA;AAAA;;;UCyCF,oBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,aAAA;EAAA,SACA,cAAA;EAAA,SACA,gBAAA;EAAA,SACA,cAAA;EAAA,SACA,MAAA,EAAQ,cAAA;AAAA;;;;;;;;;;;;;;;;;;;;UAsBF,yBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;EAAA,SACA,YAAA;EAAA,SACA,MAAA;AAAA;;;;;ADlGX;;;iBC4GgB,+BAAA,CACd,MAAA,WAAiB,yBAAA;AAAA,UAaF,qBAAA;EAAA,SACN,EAAA;EAAA,SACA,IAAA;EAAA,SACA,UAAA,WAAqB,oBAAA;EAAA,SACrB,UAAA;EAAA,SACA,UAAA;EAAA,SACA,YAAA;EAAA,SACA,IAAA,YAAgB,SAAA;ED5GM;EAAA,SC8GtB,kBAAA;;;AArEX;;;;;;WA8EW,iBAAA;EA1EA;EAAA,SA4EA,iBAAA;EAAA,SACA,YAAA;IAAA,SACE,QAAA;IAAA,SACA,MAAA;IAAA,SACA,gBAAA;IAAA,SACA,eAAA;IAAA,SACA,OAAA;IAAA,SACA,kBAAA;IAAA,SACA,mBAAA;IAAA,SACA,YAAA;MAAA,SACE,OAAA;MAAA,SACA,aAAA;MAAA,SACA,IAAA;MAAA,SACA,EAAA;MAAA,SACA,UAAA;IAAA;EAAA;EAAA,SAGJ,OAAA;EAAA,SACA,WAAA,WAAsB,gBAAA;EApDjB;;;;;AAchB;;;;;;;;EAdgB,SAkEL,MAAA,YAAkB,yBAAA;EAKM;EAAA,SAHxB,wBAAA;EAAA,SACA,KAAA,GAAQ,cAAA;EAAA,SACR,OAAA,YAAmB,sBAAA;EAAA,SACnB,YAAA,YAAwB,UAAA;EAAA,SACxB,aAAA;EAAA,SACA,aAAA;EAAA,SACA,QAAA;AAAA;;;;;;;;;;;;;;;;iBA+CK,kBAAA,CACd,KAAA,EAAO,cAAA,EACP,UAAA,UACA,YAAA,UACA,UAAA,sBACA,IAAA,yBACC,UAAA;;;;;;;;;;;;iBAsLmB,yBAAA,CAA0B,IAAA;EAAA,SACrC,QAAA;EAAA,SACA,aAAA;EAAA,SACA,cAAA;EAAA,SACA,cAAA,EAAgB,oBAAA;EAAA,SAChB,gBAAA,EAAkB,oBAAA;EAAA,SAClB,cAAA,EAAgB,WAAA,SAAoB,wBAAA;AAAA,IAC3C,OAAA,UAAiB,yBAAA;AAAA,iBAknBL,4BAAA,CAAA,GAAgC,OAAA;AAAA,iBAoGhC,mBAAA,CAAoB,MAAA,EAAQ,qBAAA,EAAuB,QAAA"}
1
+ {"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/contract-space-aggregate-loader.ts","../../src/utils/formatters/graph-migration-mapper.ts","../../src/commands/migration-status.ts"],"mappings":";;;;;;;;;;;;;;;;;UAqHiB,oBAAA;EAAA,SACN,QAAA,EAAU,SAAA;EAAA,SACV,aAAA;EAAA,SACA,WAAA,EAAa,QAAA;EAAA,SACb,cAAA,EAAgB,aAAA,CAAc,0BAAA,CAA2B,SAAA,EAAW,SAAA;EAAA,SACpE,mBAAA,GAAsB,YAAA,cAA0B,QAAA;EAJhD;;;;;;;;;;;;EAAA,SAiBA,oBAAA,GAAuB,aAAA,CAAc,sBAAA;AAAA;;;KCtHpC,cAAA;;UAmBK,UAAA;EAAA,SACN,OAAA;EAAA,SACA,MAAA,EAAQ,cAAA;AAAA;;;UCyCF,oBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;EAAA,SACA,aAAA;EAAA,SACA,cAAA;EAAA,SACA,gBAAA;EAAA,SACA,cAAA;EAAA,SACA,MAAA,EAAQ,cAAA;AAAA;;;;;;;;;;;;;;;;;;;;UAsBF,yBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;EAAA,SACA,YAAA;EAAA,SACA,MAAA;AAAA;;;;;ADlGX;;;iBC4GgB,+BAAA,CACd,MAAA,WAAiB,yBAAA;AAAA,UAaF,qBAAA;EAAA,SACN,EAAA;EAAA,SACA,IAAA;EAAA,SACA,UAAA,WAAqB,oBAAA;EAAA,SACrB,UAAA;EAAA,SACA,UAAA;EAAA,SACA,YAAA;EAAA,SACA,IAAA,YAAgB,SAAA;ED5GM;EAAA,SC8GtB,kBAAA;;;AArEX;;;;;;WA8EW,iBAAA;EA1EA;EAAA,SA4EA,iBAAA;EAAA,SACA,YAAA;IAAA,SACE,QAAA;IAAA,SACA,MAAA;IAAA,SACA,gBAAA;IAAA,SACA,eAAA;IAAA,SACA,OAAA;IAAA,SACA,kBAAA;IAAA,SACA,mBAAA;IAAA,SACA,YAAA;MAAA,SACE,OAAA;MAAA,SACA,aAAA;MAAA,SACA,IAAA;MAAA,SACA,EAAA;MAAA,SACA,UAAA;IAAA;EAAA;EAAA,SAGJ,OAAA;EAAA,SACA,WAAA,WAAsB,gBAAA;EApDjB;;;;;AAchB;;;;;;;;EAdgB,SAkEL,MAAA,YAAkB,yBAAA;EAKM;EAAA,SAHxB,wBAAA;EAAA,SACA,KAAA,GAAQ,cAAA;EAAA,SACR,OAAA,YAAmB,sBAAA;EAAA,SACnB,YAAA,YAAwB,UAAA;EAAA,SACxB,aAAA;EAAA,SACA,aAAA;EAAA,SACA,QAAA;AAAA;;;;;;;;;;;;;;;;iBA+CK,kBAAA,CACd,KAAA,EAAO,cAAA,EACP,UAAA,UACA,YAAA,UACA,UAAA,sBACA,IAAA,yBACC,UAAA;;;;;;;;;;;;iBAsLmB,yBAAA,CAA0B,IAAA;EAAA,SACrC,QAAA;EAAA,SACA,aAAA;EAAA,SACA,cAAA;EAAA,SACA,cAAA,EAAgB,oBAAA;EAAA,SAChB,mBAAA,EAAqB,oBAAA;EAAA,SACrB,cAAA,EAAgB,WAAA,SAAoB,wBAAA;AAAA,IAC3C,OAAA,UAAiB,yBAAA;AAAA,iBAknBL,4BAAA,CAAA,GAAgC,OAAA;AAAA,iBAoGhC,mBAAA,CAAoB,MAAA,EAAQ,qBAAA,EAAuB,QAAA"}
@@ -3,8 +3,8 @@ import { _ as errorUnexpected, m as errorRuntime, v as mapMigrationToolsError, y
3
3
  import { _ as parseGlobalFlags, a as loadMigrationPackages, b as formatStyledHeader, d as setCommandDescriptions, f as setCommandExamples, g as toStructuralEdge, h as toPathDecisionResult, l as resolveMigrationPaths, n as collectDeclaredInvariants, o as maskConnectionUrl, p as setCommandSeeAlso, s as readContractEnvelope, t as addGlobalOptions } from "../command-helpers-D3vL5yi8.mjs";
4
4
  import { t as handleResult } from "../result-handler-Bm_6dDYg.mjs";
5
5
  import { t as TerminalUI } from "../terminal-ui-XtOQsqe9.mjs";
6
- import { t as createControlClient } from "../client-XkUw4xD0.mjs";
7
- import { t as buildContractSpaceAggregate } from "../contract-space-aggregate-loader-D68YpuPR.mjs";
6
+ import { t as createControlClient } from "../client-Brv4qlfB.mjs";
7
+ import { t as buildContractSpaceAggregate } from "../contract-space-aggregate-loader-pAc8CDfY.mjs";
8
8
  import { i as migrationGraphToRenderInput, n as graphRenderer, r as isLinearGraph, t as extractRelevantSubgraph } from "../graph-render-eJDcLWny.mjs";
9
9
  import { Command } from "commander";
10
10
  import { ifDefined } from "@prisma-next/utils/defined";
@@ -191,9 +191,9 @@ async function loadAggregateStatusSpaces(args) {
191
191
  const loaded = await buildContractSpaceAggregate({
192
192
  targetId: args.targetId,
193
193
  migrationsDir: args.migrationsDir,
194
- appContract: args.validateContract(args.appContractRaw),
194
+ appContract: args.deserializeContract(args.appContractRaw),
195
195
  extensionPacks: args.extensionPacks,
196
- validateContract: args.validateContract
196
+ deserializeContract: args.deserializeContract
197
197
  });
198
198
  if (!loaded.ok) return [];
199
199
  const aggregate = loaded.value;
@@ -435,7 +435,7 @@ async function executeMigrationStatusCommand(options, flags, ui) {
435
435
  migrationsDir,
436
436
  appContractRaw: contractRawForAggregate,
437
437
  extensionPacks: config.extensionPacks ?? [],
438
- validateContract: (json) => familyInstance.validateContract(json),
438
+ deserializeContract: (json) => familyInstance.deserializeContract(json),
439
439
  markersBySpace: allMarkers
440
440
  });
441
441
  } catch {