prisma-next 0.11.0-dev.5 → 0.11.0-dev.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-errors-DFF1LlfU.mjs +215 -0
- package/dist/cli-errors-DFF1LlfU.mjs.map +1 -0
- package/dist/cli.mjs +9 -10
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-oXO2WCPD.mjs → client-5uvDppD8.mjs} +23 -21
- package/dist/client-5uvDppD8.mjs.map +1 -0
- package/dist/{command-helpers-DtavI0wJ.mjs → command-helpers-4UNsRRc4.mjs} +427 -9
- package/dist/command-helpers-4UNsRRc4.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts.map +1 -1
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.d.mts.map +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.d.mts.map +1 -1
- package/dist/commands/db-init.mjs +33 -7
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.d.mts.map +1 -1
- package/dist/commands/db-schema.mjs +3 -4
- package/dist/commands/db-schema.mjs.map +1 -1
- package/dist/commands/db-sign.d.mts.map +1 -1
- package/dist/commands/db-sign.mjs +6 -7
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +36 -8
- package/dist/commands/db-update.mjs.map +1 -1
- package/dist/commands/db-verify.d.mts.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +5 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +79 -39
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +4 -3
- package/dist/commands/migration-check.d.mts.map +1 -1
- package/dist/commands/migration-check.mjs +1 -280
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.d.mts.map +1 -1
- package/dist/commands/migration-graph.mjs +3 -4
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.d.mts +63 -12
- package/dist/commands/migration-list.d.mts.map +1 -1
- package/dist/commands/migration-list.mjs +2 -103
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +3 -4
- package/dist/commands/migration-log.mjs.map +1 -1
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +33 -38
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +2 -1
- package/dist/commands/migration-plan.d.mts.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +4 -55
- package/dist/commands/migration-show.d.mts.map +1 -1
- package/dist/commands/migration-show.mjs +62 -153
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +5 -40
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +93 -67
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.d.mts.map +1 -1
- package/dist/commands/ref.mjs +34 -9
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/config-loader-B6sJjXTv.mjs.map +1 -1
- package/dist/config-loader.d.mts.map +1 -1
- package/dist/{contract-emit-o-8VmdQX.mjs → contract-emit-C-CFGZsI.mjs} +9 -6
- package/dist/{contract-emit-o-8VmdQX.mjs.map → contract-emit-C-CFGZsI.mjs.map} +1 -1
- package/dist/{contract-emit-CmsklifJ.mjs → contract-emit-CuUzzM46.mjs} +5 -6
- package/dist/{contract-emit-CmsklifJ.mjs.map → contract-emit-CuUzzM46.mjs.map} +1 -1
- package/dist/{contract-enrichment-Dani0mMW.mjs → contract-enrichment-XmUPhmsS.mjs} +4 -25
- package/dist/contract-enrichment-XmUPhmsS.mjs.map +1 -0
- package/dist/{contract-infer-pKkiCt7C.mjs → contract-infer-C98ZaRhp.mjs} +3 -4
- package/dist/{contract-infer-pKkiCt7C.mjs.map → contract-infer-C98ZaRhp.mjs.map} +1 -1
- package/dist/contract-space-aggregate-loader-CVHGuA35.mjs +170 -0
- package/dist/contract-space-aggregate-loader-CVHGuA35.mjs.map +1 -0
- package/dist/{db-verify-AoIUriL4.mjs → db-verify-BWl1Yxi-.mjs} +6 -7
- package/dist/{db-verify-AoIUriL4.mjs.map → db-verify-BWl1Yxi-.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.d.mts.map +1 -1
- package/dist/exports/control-api.mjs +3 -3
- package/dist/exports/index.d.mts.map +1 -1
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/index.mjs.map +1 -1
- package/dist/exports/init-output.d.mts.map +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/extension-pack-inputs-BiY86HbQ.mjs +62 -0
- package/dist/extension-pack-inputs-BiY86HbQ.mjs.map +1 -0
- package/dist/{framework-components-65gOHkHB.mjs → framework-components-DTcjouhS.mjs} +2 -2
- package/dist/{framework-components-65gOHkHB.mjs.map → framework-components-DTcjouhS.mjs.map} +1 -1
- package/dist/{global-flags-CdE7M0d9.d.mts → global-flags-DWsQ6SSI.d.mts} +1 -1
- package/dist/global-flags-DWsQ6SSI.d.mts.map +1 -0
- package/dist/glyph-mode-CBB4emzO.d.mts +5 -0
- package/dist/glyph-mode-CBB4emzO.d.mts.map +1 -0
- package/dist/{graph-render-DJVv0_uf.mjs → graph-render-D2FnLpuK.mjs} +1 -1
- package/dist/{graph-render-DJVv0_uf.mjs.map → graph-render-D2FnLpuK.mjs.map} +1 -1
- package/dist/{init-Db5Itt5r.mjs → init-C7PvN163.mjs} +5 -5
- package/dist/{init-Db5Itt5r.mjs.map → init-C7PvN163.mjs.map} +1 -1
- package/dist/{inspect-live-schema-LeWvkZVz.mjs → inspect-live-schema-BRCWQ-Sr.mjs} +5 -5
- package/dist/{inspect-live-schema-LeWvkZVz.mjs.map → inspect-live-schema-BRCWQ-Sr.mjs.map} +1 -1
- package/dist/migration-check-DoskM1nB.mjs +341 -0
- package/dist/migration-check-DoskM1nB.mjs.map +1 -0
- package/dist/migration-cli.d.mts.map +1 -1
- package/dist/migration-cli.mjs +4 -4
- package/dist/migration-cli.mjs.map +1 -1
- package/dist/{migration-command-scaffold-BtkunvFQ.mjs → migration-command-scaffold-CXLkoIJx.mjs} +5 -5
- package/dist/{migration-command-scaffold-BtkunvFQ.mjs.map → migration-command-scaffold-CXLkoIJx.mjs.map} +1 -1
- package/dist/migration-list-B2-iQ5Jd.mjs +646 -0
- package/dist/migration-list-B2-iQ5Jd.mjs.map +1 -0
- package/dist/{migration-plan-C2jeH1J5.mjs → migration-plan-BqmIKQpZ.mjs} +341 -88
- package/dist/migration-plan-BqmIKQpZ.mjs.map +1 -0
- package/dist/{migration-types-BXWvz12q.d.mts → migration-types-q64xAI_J.d.mts} +1 -1
- package/dist/{migration-types-BXWvz12q.d.mts.map → migration-types-q64xAI_J.d.mts.map} +1 -1
- package/dist/{migrations-CwZMa1Ck.mjs → migrations-BcVTutso.mjs} +12 -13
- package/dist/migrations-BcVTutso.mjs.map +1 -0
- package/dist/{output-BlsrGMEF.mjs → output-B60Gw5fu.mjs} +1 -1
- package/dist/{output-BlsrGMEF.mjs.map → output-B60Gw5fu.mjs.map} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs → progress-adapter-xASh41wr.mjs} +1 -1
- package/dist/{progress-adapter-DFfvZcYL.mjs.map → progress-adapter-xASh41wr.mjs.map} +1 -1
- package/dist/ref-advancement-DRh5Nquq.mjs +50 -0
- package/dist/ref-advancement-DRh5Nquq.mjs.map +1 -0
- package/dist/{types-C9FfXb1l.d.mts → types-CEtm6v6a.d.mts} +5 -11
- package/dist/types-CEtm6v6a.d.mts.map +1 -0
- package/dist/{verify-Bom75OYI.mjs → verify-DOHbbrub.mjs} +2 -2
- package/dist/{verify-Bom75OYI.mjs.map → verify-DOHbbrub.mjs.map} +1 -1
- package/package.json +12 -12
- package/dist/cli-errors-Czmx92Zy.d.mts +0 -3
- package/dist/cli-errors-Djtz98Vm.mjs +0 -71
- package/dist/cli-errors-Djtz98Vm.mjs.map +0 -1
- package/dist/client-oXO2WCPD.mjs.map +0 -1
- package/dist/command-helpers-DtavI0wJ.mjs.map +0 -1
- package/dist/commands/migration-check.mjs.map +0 -1
- package/dist/commands/migration-list.mjs.map +0 -1
- package/dist/contract-enrichment-Dani0mMW.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs +0 -160
- package/dist/contract-space-aggregate-loader-BmNQwlws.mjs.map +0 -1
- package/dist/global-flags-CdE7M0d9.d.mts.map +0 -1
- package/dist/migration-plan-C2jeH1J5.mjs.map +0 -1
- package/dist/migrations-CwZMa1Ck.mjs.map +0 -1
- package/dist/terminal-ui-BiB_8KNo.mjs +0 -379
- package/dist/terminal-ui-BiB_8KNo.mjs.map +0 -1
- package/dist/types-C9FfXb1l.d.mts.map +0 -1
|
@@ -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, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type 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 = parseGlobalFlagsOrExit(options);\n\n const ui = createTerminalUI(flags);\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 { loadContractSpaceAggregate } from '@prisma-next/migration-tools/aggregate';\nimport type { OnDiskMigrationPackage } from '@prisma-next/migration-tools/package';\nimport { parseMigrationRef } from '@prisma-next/migration-tools/ref-resolution';\nimport { castAs } from '@prisma-next/utils/casts';\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 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 { formatMigrationShowOutput } from '../utils/formatters/migrations';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface MigrationShowOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nexport interface MigrationShowPresent {\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 readonly preview: OperationPreview;\n readonly summary: string;\n}\n\nexport interface MigrationShowResult {\n readonly ok: true;\n readonly migration: MigrationShowPresent;\n}\n\nfunction looksLikePath(target: string): boolean {\n return target.includes('/') || target.includes('\\\\');\n}\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\nfunction pkgToPresent(\n spaceId: string,\n pkg: OnDiskMigrationPackage,\n client: ReturnType<typeof createControlClient>,\n): MigrationShowPresent {\n const ops = castAs<readonly MigrationPlanOperation[]>(pkg.ops);\n const preview: OperationPreview = client.toOperationPreview(ops) ?? { statements: [] };\n return {\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\nfunction findPackageByDirPath(\n packages: readonly OnDiskMigrationPackage[],\n resolvedDirPath: string,\n): OnDiskMigrationPackage | undefined {\n const normalized = resolve(resolvedDirPath);\n return packages.find((p) => resolve(p.dirPath) === normalized);\n}\n\nasync function executeMigrationShowCommand(\n target: string,\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 } =\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 header = formatStyledHeader({\n command: 'migration show',\n description: 'Display migration package contents',\n details: [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'migrations', value: appMigrationsRelative },\n { label: 'target', value: target },\n ],\n flags,\n });\n ui.stderr(header);\n }\n\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 let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as NodeJS.ErrnoException).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 const stack = createControlStack(config);\n const familyInstance = config.family.create(stack);\n\n let appContract: Contract;\n try {\n appContract = familyInstance.deserializeContract(\n castAs<unknown>(JSON.parse(contractJsonContent)),\n );\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 aggregate = await loadContractSpaceAggregate({\n migrationsDir,\n appContract,\n deserializeContract: (json: unknown) => familyInstance.deserializeContract(json),\n });\n\n const packages = aggregate.app.packages;\n const graph = aggregate.app.graph();\n const refs = aggregate.app.refs;\n\n let appPkg: OnDiskMigrationPackage;\n if (looksLikePath(target)) {\n const resolved = resolveAppTargetPath(target, appMigrationsDir, appMigrationsRelative);\n if (!resolved.ok) return resolved;\n const matched = findPackageByDirPath(packages, resolved.value);\n if (!matched) {\n return notOk(\n errorRuntime('Migration package not found', {\n why: `No loaded migration package at ${relative(process.cwd(), resolved.value)}`,\n fix: 'Pass a directory name, hash prefix, or path to an on-disk app-space migration package.',\n }),\n );\n }\n appPkg = matched;\n } else {\n if (packages.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 migResult = parseMigrationRef(target, { graph, refs });\n if (!migResult.ok) {\n return notOk(mapRefResolutionError(migResult.failure));\n }\n const matchedPkg = packages.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\n return ok({\n ok: true,\n migration: pkgToPresent(APP_SPACE_ID, appPkg, client),\n });\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 one app-space migration.\\n' +\n 'Accepts a directory path, directory name, or hash prefix.',\n );\n setCommandExamples(command, [\n 'prisma-next migration show 20260101_100000_add_user',\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('<target>', 'Migration reference: directory name, hash/prefix, or path')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (target: string, options: MigrationShowOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n\n const ui = createTerminalUI(flags);\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,41 +1,9 @@
|
|
|
1
|
-
import { n as StatusRef, t as StatusDiagnostic } from "../migration-types-
|
|
1
|
+
import { n as StatusRef, t as StatusDiagnostic } from "../migration-types-q64xAI_J.mjs";
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
-
import {
|
|
4
|
-
import { ControlExtensionDescriptor } from "@prisma-next/framework-components/control";
|
|
5
|
-
import { ContractMarkerRecordLike } from "@prisma-next/migration-tools/aggregate";
|
|
6
|
-
import { Contract } from "@prisma-next/contract/types";
|
|
7
|
-
import { OnDiskMigrationPackage } from "@prisma-next/migration-tools/package";
|
|
3
|
+
import { ContractMarkerRecordLike, ContractSpaceAggregate } from "@prisma-next/migration-tools/aggregate";
|
|
8
4
|
import { MigrationGraph } from "@prisma-next/migration-tools/graph";
|
|
5
|
+
import { OnDiskMigrationPackage } from "@prisma-next/migration-tools/package";
|
|
9
6
|
|
|
10
|
-
//#region src/utils/contract-space-aggregate-loader.d.ts
|
|
11
|
-
/**
|
|
12
|
-
* Inputs needed to compose the aggregate loader at the CLI surface.
|
|
13
|
-
*
|
|
14
|
-
* Keeps the loader framework-neutral (no `Config` import) by accepting
|
|
15
|
-
* already-resolved structural inputs: validated app contract, target
|
|
16
|
-
* id, migrations root directory, and the set of extension descriptors.
|
|
17
|
-
*/
|
|
18
|
-
interface BuildAggregateInputs<TFamilyId extends string, TTargetId extends string> {
|
|
19
|
-
readonly targetId: TTargetId;
|
|
20
|
-
readonly migrationsDir: string;
|
|
21
|
-
readonly appContract: Contract;
|
|
22
|
-
readonly extensionPacks: ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>;
|
|
23
|
-
readonly deserializeContract: (contractJson: unknown) => Contract;
|
|
24
|
-
/**
|
|
25
|
-
* App-space migration packages to hydrate the app member's
|
|
26
|
-
* migration graph with. Defaults to `[]` (matches the `db init` /
|
|
27
|
-
* `db update` daily-driver behaviour, where the app's authored
|
|
28
|
-
* `migrations/` graph is not walked — the planner uses the synth
|
|
29
|
-
* strategy for the app member instead).
|
|
30
|
-
*
|
|
31
|
-
* `migrate` callers thread the user's authored app-space
|
|
32
|
-
* packages (loaded via `loadMigrationPackages(appMigrationsDir)`)
|
|
33
|
-
* through here so the graph-walk strategy can plot a path through
|
|
34
|
-
* them — the prod-time replay path explicitly forbids synth.
|
|
35
|
-
*/
|
|
36
|
-
readonly appMigrationPackages?: ReadonlyArray<OnDiskMigrationPackage>;
|
|
37
|
-
}
|
|
38
|
-
//#endregion
|
|
39
7
|
//#region src/utils/formatters/graph-migration-mapper.d.ts
|
|
40
8
|
type EdgeStatusKind = 'applied' | 'pending' | 'unreachable';
|
|
41
9
|
/** Minimal per-edge status from the CLI's status result. */
|
|
@@ -180,11 +148,8 @@ declare function deriveEdgeStatuses(graph: MigrationGraph, targetHash: string, c
|
|
|
180
148
|
* cross-space totals.
|
|
181
149
|
*/
|
|
182
150
|
declare function loadAggregateStatusSpaces(args: {
|
|
183
|
-
readonly
|
|
184
|
-
readonly
|
|
185
|
-
readonly appContractRaw: unknown;
|
|
186
|
-
readonly extensionPacks: BuildAggregateInputs<string, string>['extensionPacks'];
|
|
187
|
-
readonly deserializeContract: BuildAggregateInputs<string, string>['deserializeContract'];
|
|
151
|
+
readonly aggregate: ContractSpaceAggregate;
|
|
152
|
+
readonly extensionPacks: ReadonlyArray<unknown>;
|
|
188
153
|
readonly markersBySpace: ReadonlyMap<string, ContractMarkerRecordLike> | null;
|
|
189
154
|
}): Promise<readonly MigrationStatusSpaceEntry[]>;
|
|
190
155
|
declare function createMigrationStatusCommand(): Command;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/
|
|
1
|
+
{"version":3,"file":"migration-status.d.mts","names":[],"sources":["../../src/utils/formatters/graph-migration-mapper.ts","../../src/commands/migration-status.ts"],"mappings":";;;;;;;KAiBY,cAAA;;UAmBK,UAAA;EAAA,SACN,OAAA;EAAA,SACA,MAAA,EAAQ,cAAc;AAAA;;;UC8ChB,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,cAAc;AAAA;;;;;ADtDA;;;;AC8CjC;;;;;;;;;;;UA8BiB,yBAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;EAAA,SACA,YAAA;EAAA,SACA,MAAA;AAAA;;;;;;;;iBAUK,+BAAA,CACd,MAA4C,WAA3B,yBAAyB;AAAA,UAa3B,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;EAAA;EAAA,SAEhB,kBAAA;EA2CkB;;;;;;;;EAAA,SAlClB,iBAAA;EAfqB;EAAA,SAiBrB,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;EANlB;;;;;;;;;;;;;EAAA,SAoBJ,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;;;;;;;;;;AAqDE;AAsLb;;;;;iBA5LgB,kBAAA,CACd,KAAA,EAAO,cAAA,EACP,UAAA,UACA,YAAA,UACA,UAAA,sBACA,IAAA,yBACC,UAAU;;;;;;;;;;;;iBAsLS,yBAAA,CAA0B,IAAA;EAAA,SACrC,SAAA,EAAW,sBAAA;EAAA,SACX,cAAA,EAAgB,aAAA;EAAA,SAChB,cAAA,EAAgB,WAAA,SAAoB,wBAAA;AAAA,IAC3C,OAAA,UAAiB,yBAAA;AAAA,iBA2rBL,4BAAA,CAAA,GAAgC,OAAO;AAAA,iBAoGvC,mBAAA,CAAoB,MAAA,EAAQ,qBAAqB,EAAE,QAAA"}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as createTerminalUI } from "../
|
|
4
|
-
import {
|
|
5
|
-
import { t as
|
|
6
|
-
import {
|
|
7
|
-
import { i as migrationGraphToRenderInput, n as graphRenderer, r as isLinearGraph, t as extractRelevantSubgraph } from "../graph-render-
|
|
2
|
+
import { A as mapRefResolutionError, C as errorRuntime, O as errorUnexpected, k as mapMigrationToolsError, t as CliStructuredError } from "../cli-errors-DFF1LlfU.mjs";
|
|
3
|
+
import { D 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, v as parseGlobalFlagsOrExit, x as handleResult, y as createTerminalUI } from "../command-helpers-4UNsRRc4.mjs";
|
|
4
|
+
import { t as createControlClient } from "../client-5uvDppD8.mjs";
|
|
5
|
+
import { t as toDeclaredExtensionsFromRaw } from "../extension-pack-inputs-BiY86HbQ.mjs";
|
|
6
|
+
import { i as refusePackageCorruptionOnAggregate, r as refuseContractSpaceIntegrity } from "../contract-space-aggregate-loader-CVHGuA35.mjs";
|
|
7
|
+
import { i as migrationGraphToRenderInput, n as graphRenderer, r as isLinearGraph, t as extractRelevantSubgraph } from "../graph-render-D2FnLpuK.mjs";
|
|
8
8
|
import { Command } from "commander";
|
|
9
9
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
10
10
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
11
11
|
import { createControlStack } from "@prisma-next/framework-components/control";
|
|
12
12
|
import { findPath, findPathWithDecision, findReachableLeaves } from "@prisma-next/migration-tools/migration-graph";
|
|
13
13
|
import { cyan, dim, magenta, yellow } from "colorette";
|
|
14
|
-
import { graphWalkStrategy } from "@prisma-next/migration-tools/aggregate";
|
|
14
|
+
import { graphWalkStrategy, loadContractSpaceAggregate, requireHeadRef } from "@prisma-next/migration-tools/aggregate";
|
|
15
|
+
import { blindCast } from "@prisma-next/utils/casts";
|
|
15
16
|
import { EMPTY_CONTRACT_HASH } from "@prisma-next/migration-tools/constants";
|
|
16
17
|
import { MigrationToolsError, errorNoInvariantPath, errorUnknownInvariant } from "@prisma-next/migration-tools/errors";
|
|
17
|
-
import { parseContractRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
18
18
|
import { readRefs } from "@prisma-next/migration-tools/refs";
|
|
19
|
+
import { parseContractRef } from "@prisma-next/migration-tools/ref-resolution";
|
|
19
20
|
//#region src/commands/migration-status.ts
|
|
20
21
|
/**
|
|
21
22
|
* Sum per-space `pendingCount` into a cross-space total, but only when
|
|
@@ -187,28 +188,26 @@ function resolveDisplayChain(graph, targetHash, markerHash) {
|
|
|
187
188
|
* cross-space totals.
|
|
188
189
|
*/
|
|
189
190
|
async function loadAggregateStatusSpaces(args) {
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
});
|
|
197
|
-
if (!loaded.ok) return [];
|
|
198
|
-
const aggregate = loaded.value;
|
|
191
|
+
const declaredExtensions = toDeclaredExtensionsFromRaw(args.extensionPacks);
|
|
192
|
+
if (refuseContractSpaceIntegrity(args.aggregate, {
|
|
193
|
+
declaredExtensions,
|
|
194
|
+
checkContracts: true
|
|
195
|
+
})) return [];
|
|
196
|
+
const aggregate = args.aggregate;
|
|
199
197
|
const orderedMembers = [...aggregate.extensions, aggregate.app];
|
|
200
198
|
const rows = [];
|
|
201
199
|
for (const member of orderedMembers) {
|
|
202
200
|
const liveMarker = args.markersBySpace?.get(member.spaceId) ?? null;
|
|
203
201
|
const isApp = member.spaceId === aggregate.app.spaceId;
|
|
204
|
-
|
|
202
|
+
const headRef = requireHeadRef(member);
|
|
203
|
+
if (member.graph().nodes.size === 0) {
|
|
205
204
|
rows.push({
|
|
206
205
|
spaceId: member.spaceId,
|
|
207
206
|
kind: isApp ? "app" : "extension",
|
|
208
|
-
headHash:
|
|
207
|
+
headHash: headRef.hash,
|
|
209
208
|
...args.markersBySpace !== null ? {
|
|
210
209
|
markerHash: liveMarker?.storageHash ?? null,
|
|
211
|
-
status:
|
|
210
|
+
status: headRef.hash === EMPTY_CONTRACT_HASH ? "up-to-date" : "never-planned",
|
|
212
211
|
pendingCount: 0
|
|
213
212
|
} : {}
|
|
214
213
|
});
|
|
@@ -218,7 +217,7 @@ async function loadAggregateStatusSpaces(args) {
|
|
|
218
217
|
rows.push({
|
|
219
218
|
spaceId: member.spaceId,
|
|
220
219
|
kind: isApp ? "app" : "extension",
|
|
221
|
-
headHash:
|
|
220
|
+
headHash: headRef.hash
|
|
222
221
|
});
|
|
223
222
|
continue;
|
|
224
223
|
}
|
|
@@ -237,7 +236,7 @@ async function loadAggregateStatusSpaces(args) {
|
|
|
237
236
|
rows.push({
|
|
238
237
|
spaceId: member.spaceId,
|
|
239
238
|
kind: isApp ? "app" : "extension",
|
|
240
|
-
headHash:
|
|
239
|
+
headHash: headRef.hash,
|
|
241
240
|
markerHash: liveMarker?.storageHash ?? null,
|
|
242
241
|
pendingCount,
|
|
243
242
|
...status ? { status } : {}
|
|
@@ -251,9 +250,19 @@ async function loadAggregateStatusSpaces(args) {
|
|
|
251
250
|
* the existing `readContractEnvelope` path will report the same
|
|
252
251
|
* problem via a status diagnostic, no need to double-surface.
|
|
253
252
|
*/
|
|
253
|
+
function appContractShellForAggregateLoad(args) {
|
|
254
|
+
return blindCast({
|
|
255
|
+
storage: { storageHash: args.contractHash },
|
|
256
|
+
schemaVersion: "0.0.0",
|
|
257
|
+
target: args.targetId,
|
|
258
|
+
targetFamily: args.targetFamily,
|
|
259
|
+
models: {},
|
|
260
|
+
profileHash: EMPTY_CONTRACT_HASH
|
|
261
|
+
});
|
|
262
|
+
}
|
|
254
263
|
async function loadContractRawSafely(config) {
|
|
255
264
|
try {
|
|
256
|
-
const path = (await import("../command-helpers-
|
|
265
|
+
const path = (await import("../command-helpers-4UNsRRc4.mjs").then((n) => n.r)).resolveContractPath(config);
|
|
257
266
|
const raw = await (await import("node:fs/promises")).readFile(path, "utf-8");
|
|
258
267
|
return JSON.parse(raw);
|
|
259
268
|
} catch {
|
|
@@ -283,7 +292,7 @@ async function validateOnlineMarkerRead(config, dbConnection) {
|
|
|
283
292
|
}
|
|
284
293
|
async function executeMigrationStatusCommand(options, flags, ui) {
|
|
285
294
|
const config = await loadConfig(options.config);
|
|
286
|
-
const { configPath,
|
|
295
|
+
const { configPath, appMigrationsRelative, migrationsDir, refsDir } = resolveMigrationPaths(options.config, config);
|
|
287
296
|
const dbConnection = options.db ?? config.db?.connection;
|
|
288
297
|
const hasDriver = !!config.driver;
|
|
289
298
|
let activeRefName;
|
|
@@ -296,12 +305,58 @@ async function executeMigrationStatusCommand(options, flags, ui) {
|
|
|
296
305
|
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
297
306
|
throw error;
|
|
298
307
|
}
|
|
308
|
+
const diagnostics = [];
|
|
309
|
+
let contractHash = EMPTY_CONTRACT_HASH;
|
|
310
|
+
try {
|
|
311
|
+
contractHash = (await readContractEnvelope(config)).storageHash;
|
|
312
|
+
} catch (error) {
|
|
313
|
+
diagnostics.push({
|
|
314
|
+
code: "CONTRACT.UNREADABLE",
|
|
315
|
+
severity: "warn",
|
|
316
|
+
message: `Could not read contract: ${error instanceof Error ? error.message : "unknown error"}`,
|
|
317
|
+
hints: ["Run 'prisma-next contract emit' to generate a valid contract"]
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
const contractRawForAggregate = await loadContractRawSafely(config);
|
|
321
|
+
const stack = createControlStack(config);
|
|
322
|
+
const familyInstance = config.family.create(stack);
|
|
323
|
+
const deserializeContract = (json) => familyInstance.deserializeContract(json);
|
|
324
|
+
let appContractForLoad = appContractShellForAggregateLoad({
|
|
325
|
+
contractHash,
|
|
326
|
+
targetId: config.target.id,
|
|
327
|
+
targetFamily: config.target.familyId
|
|
328
|
+
});
|
|
329
|
+
if (contractRawForAggregate !== null) try {
|
|
330
|
+
appContractForLoad = deserializeContract(contractRawForAggregate);
|
|
331
|
+
} catch (error) {
|
|
332
|
+
diagnostics.push({
|
|
333
|
+
code: "CONTRACT.UNREADABLE",
|
|
334
|
+
severity: "warn",
|
|
335
|
+
message: `Could not deserialize contract: ${error instanceof Error ? error.message : "unknown error"}`,
|
|
336
|
+
hints: ["Run 'prisma-next contract emit' to generate a valid contract"]
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
let aggregate;
|
|
340
|
+
try {
|
|
341
|
+
aggregate = await loadContractSpaceAggregate({
|
|
342
|
+
migrationsDir,
|
|
343
|
+
deserializeContract,
|
|
344
|
+
appContract: appContractForLoad
|
|
345
|
+
});
|
|
346
|
+
} catch (error) {
|
|
347
|
+
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
348
|
+
return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read migrations directory: ${error instanceof Error ? error.message : String(error)}` }));
|
|
349
|
+
}
|
|
350
|
+
if (contractRawForAggregate !== null) {
|
|
351
|
+
const corruptionFailure = refusePackageCorruptionOnAggregate(aggregate);
|
|
352
|
+
if (corruptionFailure) return notOk(corruptionFailure);
|
|
353
|
+
}
|
|
354
|
+
const appGraph = aggregate.app.graph();
|
|
299
355
|
let fromOverrideHash;
|
|
300
|
-
if (options.to || options.from)
|
|
301
|
-
const { graph: earlyGraph } = await loadMigrationPackages(appMigrationsDir);
|
|
356
|
+
if (options.to || options.from) {
|
|
302
357
|
if (options.to) {
|
|
303
358
|
const refResult = parseContractRef(options.to, {
|
|
304
|
-
graph:
|
|
359
|
+
graph: appGraph,
|
|
305
360
|
refs: allRefs
|
|
306
361
|
});
|
|
307
362
|
if (!refResult.ok) return notOk(mapRefResolutionError(refResult.failure));
|
|
@@ -314,15 +369,12 @@ async function executeMigrationStatusCommand(options, flags, ui) {
|
|
|
314
369
|
}
|
|
315
370
|
if (options.from) {
|
|
316
371
|
const fromResult = parseContractRef(options.from, {
|
|
317
|
-
graph:
|
|
372
|
+
graph: appGraph,
|
|
318
373
|
refs: allRefs
|
|
319
374
|
});
|
|
320
375
|
if (!fromResult.ok) return notOk(mapRefResolutionError(fromResult.failure));
|
|
321
376
|
fromOverrideHash = fromResult.value.hash;
|
|
322
377
|
}
|
|
323
|
-
} catch (error) {
|
|
324
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
325
|
-
throw error;
|
|
326
378
|
}
|
|
327
379
|
const requiredInvariants = [...activeRefEntry?.invariants ?? []].sort();
|
|
328
380
|
const statusRefs = Object.entries(allRefs).map(([name, entry]) => ({
|
|
@@ -362,26 +414,8 @@ async function executeMigrationStatusCommand(options, flags, ui) {
|
|
|
362
414
|
});
|
|
363
415
|
ui.stderr(header);
|
|
364
416
|
}
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
try {
|
|
368
|
-
contractHash = (await readContractEnvelope(config)).storageHash;
|
|
369
|
-
} catch (error) {
|
|
370
|
-
diagnostics.push({
|
|
371
|
-
code: "CONTRACT.UNREADABLE",
|
|
372
|
-
severity: "warn",
|
|
373
|
-
message: `Could not read contract: ${error instanceof Error ? error.message : "unknown error"}`,
|
|
374
|
-
hints: ["Run 'prisma-next contract emit' to generate a valid contract"]
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
let bundles;
|
|
378
|
-
let graph;
|
|
379
|
-
try {
|
|
380
|
-
({bundles, graph} = await loadMigrationPackages(appMigrationsDir));
|
|
381
|
-
} catch (error) {
|
|
382
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
383
|
-
return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read migrations directory: ${error instanceof Error ? error.message : String(error)}` }));
|
|
384
|
-
}
|
|
417
|
+
const bundles = aggregate.app.packages;
|
|
418
|
+
const graph = appGraph;
|
|
385
419
|
if (bundles.length === 0) {
|
|
386
420
|
if (dbConnection && hasDriver) {
|
|
387
421
|
const markerProbe = await validateOnlineMarkerRead(config, dbConnection);
|
|
@@ -449,23 +483,15 @@ async function executeMigrationStatusCommand(options, flags, ui) {
|
|
|
449
483
|
mode = "offline";
|
|
450
484
|
allMarkers = null;
|
|
451
485
|
}
|
|
452
|
-
const contractRawForAggregate = await loadContractRawSafely(config);
|
|
453
486
|
let aggregateSpaces = [];
|
|
454
|
-
if (contractRawForAggregate !== null) {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
extensionPacks: config.extensionPacks ?? [],
|
|
463
|
-
deserializeContract: (json) => familyInstance.deserializeContract(json),
|
|
464
|
-
markersBySpace: allMarkers
|
|
465
|
-
});
|
|
466
|
-
} catch {
|
|
467
|
-
aggregateSpaces = [];
|
|
468
|
-
}
|
|
487
|
+
if (contractRawForAggregate !== null) try {
|
|
488
|
+
aggregateSpaces = await loadAggregateStatusSpaces({
|
|
489
|
+
aggregate,
|
|
490
|
+
extensionPacks: config.extensionPacks ?? [],
|
|
491
|
+
markersBySpace: allMarkers
|
|
492
|
+
});
|
|
493
|
+
} catch {
|
|
494
|
+
aggregateSpaces = [];
|
|
469
495
|
}
|
|
470
496
|
const totalPendingAcrossSpaces = computeTotalPendingAcrossSpaces(aggregateSpaces);
|
|
471
497
|
if (activeRefEntry && activeRefEntry.invariants.length > 0) {
|