prisma-next 0.11.0-dev.45 → 0.11.0-dev.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +9 -9
- package/dist/{client-a5NJce0-.mjs → client-5uvDppD8.mjs} +20 -18
- package/dist/client-5uvDppD8.mjs.map +1 -0
- package/dist/{command-helpers-yLuA78TP.mjs → command-helpers-CI8P5Xyd.mjs} +4 -4
- package/dist/{command-helpers-yLuA78TP.mjs.map → command-helpers-CI8P5Xyd.mjs.map} +1 -1
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.mjs +5 -5
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +3 -3
- package/dist/commands/db-update.mjs +5 -5
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +42 -37
- 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 -279
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.mjs +2 -2
- package/dist/commands/migration-list.d.mts +2 -2
- package/dist/commands/migration-list.mjs +1 -1
- package/dist/commands/migration-log.mjs +2 -2
- package/dist/commands/migration-new.d.mts.map +1 -1
- package/dist/commands/migration-new.mjs +32 -30
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +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 -152
- 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 +91 -64
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +2 -2
- package/dist/{contract-emit-FtDVFs2Q.mjs → contract-emit-DmBG2Nnc.mjs} +2 -2
- package/dist/{contract-emit-FtDVFs2Q.mjs.map → contract-emit-DmBG2Nnc.mjs.map} +1 -1
- package/dist/{contract-infer-CVMuoJKk.mjs → contract-infer-BSWFKgI1.mjs} +3 -3
- package/dist/{contract-infer-CVMuoJKk.mjs.map → contract-infer-BSWFKgI1.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-B00o3LuC.mjs → db-verify-BzpwFyLg.mjs} +4 -4
- package/dist/{db-verify-B00o3LuC.mjs.map → db-verify-BzpwFyLg.mjs.map} +1 -1
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +1 -1
- package/dist/exports/index.mjs +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/{global-flags-Dvibm2yu.d.mts → global-flags-DWsQ6SSI.d.mts} +1 -1
- package/dist/{global-flags-Dvibm2yu.d.mts.map → global-flags-DWsQ6SSI.d.mts.map} +1 -1
- 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-BKgB6EKw.mjs → init-DEssiJ8j.mjs} +3 -3
- package/dist/{init-BKgB6EKw.mjs.map → init-DEssiJ8j.mjs.map} +1 -1
- package/dist/{inspect-live-schema-BXUd6RfS.mjs → inspect-live-schema-DlBM84nh.mjs} +3 -3
- package/dist/{inspect-live-schema-BXUd6RfS.mjs.map → inspect-live-schema-DlBM84nh.mjs.map} +1 -1
- package/dist/migration-check-CzLbAqIQ.mjs +341 -0
- package/dist/migration-check-CzLbAqIQ.mjs.map +1 -0
- package/dist/{migration-command-scaffold-3l3EdmSD.mjs → migration-command-scaffold-Bp8UHnvJ.mjs} +3 -3
- package/dist/{migration-command-scaffold-3l3EdmSD.mjs.map → migration-command-scaffold-Bp8UHnvJ.mjs.map} +1 -1
- package/dist/{migration-list-DopkAG7L.mjs → migration-list-C2xnaYsT.mjs} +2 -2
- package/dist/{migration-list-DopkAG7L.mjs.map → migration-list-C2xnaYsT.mjs.map} +1 -1
- package/dist/{migration-list-graph-render-C-daUZLU.d.mts → migration-list-graph-render-DKw1AT-e.d.mts} +1 -1
- package/dist/migration-list-graph-render-DKw1AT-e.d.mts.map +1 -0
- package/dist/{migration-plan-BHoeET4O.mjs → migration-plan-BLvOmNCu.mjs} +6 -5
- package/dist/{migration-plan-BHoeET4O.mjs.map → migration-plan-BLvOmNCu.mjs.map} +1 -1
- 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-D-UCOGtk.mjs → migrations-vzQt9LI2.mjs} +3 -13
- package/dist/migrations-vzQt9LI2.mjs.map +1 -0
- package/dist/{output-CUIdfYo5.mjs → output-B60Gw5fu.mjs} +1 -1
- package/dist/{output-CUIdfYo5.mjs.map → output-B60Gw5fu.mjs.map} +1 -1
- package/dist/{ref-advancement-CHJ_8HxQ.mjs → ref-advancement-DRh5Nquq.mjs} +1 -1
- package/dist/{ref-advancement-CHJ_8HxQ.mjs.map → ref-advancement-DRh5Nquq.mjs.map} +1 -1
- package/dist/{types-UWB2-rrw.d.mts → types-CEtm6v6a.d.mts} +1 -8
- package/dist/types-CEtm6v6a.d.mts.map +1 -0
- package/dist/{verify-9gDJz6cm.mjs → verify-ktSRQvIS.mjs} +2 -2
- package/dist/{verify-9gDJz6cm.mjs.map → verify-ktSRQvIS.mjs.map} +1 -1
- package/package.json +11 -11
- package/dist/client-a5NJce0-.mjs.map +0 -1
- package/dist/commands/migration-check.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-EVU3n9YE.mjs +0 -160
- package/dist/contract-space-aggregate-loader-EVU3n9YE.mjs.map +0 -1
- package/dist/migration-list-graph-render-C-daUZLU.d.mts.map +0 -1
- package/dist/migrations-D-UCOGtk.mjs.map +0 -1
- package/dist/types-UWB2-rrw.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,16 +1,18 @@
|
|
|
1
1
|
import { t as loadConfig } from "../config-loader-B6sJjXTv.mjs";
|
|
2
2
|
import { A as mapRefResolutionError, C as errorRuntime, O as errorUnexpected, k as mapMigrationToolsError, t as CliStructuredError } from "../cli-errors-DFF1LlfU.mjs";
|
|
3
|
-
import { A as formatStyledHeader,
|
|
4
|
-
import { t as createControlClient } from "../client-
|
|
5
|
-
import { t as
|
|
6
|
-
import { i as
|
|
3
|
+
import { A 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, w as handleResult, y as createTerminalUI } from "../command-helpers-CI8P5Xyd.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";
|
|
7
8
|
import { Command } from "commander";
|
|
8
9
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
9
10
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
10
11
|
import { createControlStack } from "@prisma-next/framework-components/control";
|
|
11
12
|
import { findPath, findPathWithDecision, findReachableLeaves } from "@prisma-next/migration-tools/migration-graph";
|
|
12
13
|
import { cyan, dim, magenta, yellow } from "colorette";
|
|
13
|
-
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";
|
|
14
16
|
import { EMPTY_CONTRACT_HASH } from "@prisma-next/migration-tools/constants";
|
|
15
17
|
import { MigrationToolsError, errorNoInvariantPath, errorUnknownInvariant } from "@prisma-next/migration-tools/errors";
|
|
16
18
|
import { readRefs } from "@prisma-next/migration-tools/refs";
|
|
@@ -186,28 +188,26 @@ function resolveDisplayChain(graph, targetHash, markerHash) {
|
|
|
186
188
|
* cross-space totals.
|
|
187
189
|
*/
|
|
188
190
|
async function loadAggregateStatusSpaces(args) {
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
});
|
|
196
|
-
if (!loaded.ok) return [];
|
|
197
|
-
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;
|
|
198
197
|
const orderedMembers = [...aggregate.extensions, aggregate.app];
|
|
199
198
|
const rows = [];
|
|
200
199
|
for (const member of orderedMembers) {
|
|
201
200
|
const liveMarker = args.markersBySpace?.get(member.spaceId) ?? null;
|
|
202
201
|
const isApp = member.spaceId === aggregate.app.spaceId;
|
|
203
|
-
|
|
202
|
+
const headRef = requireHeadRef(member);
|
|
203
|
+
if (member.graph().nodes.size === 0) {
|
|
204
204
|
rows.push({
|
|
205
205
|
spaceId: member.spaceId,
|
|
206
206
|
kind: isApp ? "app" : "extension",
|
|
207
|
-
headHash:
|
|
207
|
+
headHash: headRef.hash,
|
|
208
208
|
...args.markersBySpace !== null ? {
|
|
209
209
|
markerHash: liveMarker?.storageHash ?? null,
|
|
210
|
-
status:
|
|
210
|
+
status: headRef.hash === EMPTY_CONTRACT_HASH ? "up-to-date" : "never-planned",
|
|
211
211
|
pendingCount: 0
|
|
212
212
|
} : {}
|
|
213
213
|
});
|
|
@@ -217,7 +217,7 @@ async function loadAggregateStatusSpaces(args) {
|
|
|
217
217
|
rows.push({
|
|
218
218
|
spaceId: member.spaceId,
|
|
219
219
|
kind: isApp ? "app" : "extension",
|
|
220
|
-
headHash:
|
|
220
|
+
headHash: headRef.hash
|
|
221
221
|
});
|
|
222
222
|
continue;
|
|
223
223
|
}
|
|
@@ -236,7 +236,7 @@ async function loadAggregateStatusSpaces(args) {
|
|
|
236
236
|
rows.push({
|
|
237
237
|
spaceId: member.spaceId,
|
|
238
238
|
kind: isApp ? "app" : "extension",
|
|
239
|
-
headHash:
|
|
239
|
+
headHash: headRef.hash,
|
|
240
240
|
markerHash: liveMarker?.storageHash ?? null,
|
|
241
241
|
pendingCount,
|
|
242
242
|
...status ? { status } : {}
|
|
@@ -250,9 +250,19 @@ async function loadAggregateStatusSpaces(args) {
|
|
|
250
250
|
* the existing `readContractEnvelope` path will report the same
|
|
251
251
|
* problem via a status diagnostic, no need to double-surface.
|
|
252
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
|
+
}
|
|
253
263
|
async function loadContractRawSafely(config) {
|
|
254
264
|
try {
|
|
255
|
-
const path = (await import("../command-helpers-
|
|
265
|
+
const path = (await import("../command-helpers-CI8P5Xyd.mjs").then((n) => n.r)).resolveContractPath(config);
|
|
256
266
|
const raw = await (await import("node:fs/promises")).readFile(path, "utf-8");
|
|
257
267
|
return JSON.parse(raw);
|
|
258
268
|
} catch {
|
|
@@ -282,7 +292,7 @@ async function validateOnlineMarkerRead(config, dbConnection) {
|
|
|
282
292
|
}
|
|
283
293
|
async function executeMigrationStatusCommand(options, flags, ui) {
|
|
284
294
|
const config = await loadConfig(options.config);
|
|
285
|
-
const { configPath,
|
|
295
|
+
const { configPath, appMigrationsRelative, migrationsDir, refsDir } = resolveMigrationPaths(options.config, config);
|
|
286
296
|
const dbConnection = options.db ?? config.db?.connection;
|
|
287
297
|
const hasDriver = !!config.driver;
|
|
288
298
|
let activeRefName;
|
|
@@ -295,12 +305,58 @@ async function executeMigrationStatusCommand(options, flags, ui) {
|
|
|
295
305
|
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
296
306
|
throw error;
|
|
297
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();
|
|
298
355
|
let fromOverrideHash;
|
|
299
|
-
if (options.to || options.from)
|
|
300
|
-
const { graph: earlyGraph } = await loadMigrationPackages(appMigrationsDir);
|
|
356
|
+
if (options.to || options.from) {
|
|
301
357
|
if (options.to) {
|
|
302
358
|
const refResult = parseContractRef(options.to, {
|
|
303
|
-
graph:
|
|
359
|
+
graph: appGraph,
|
|
304
360
|
refs: allRefs
|
|
305
361
|
});
|
|
306
362
|
if (!refResult.ok) return notOk(mapRefResolutionError(refResult.failure));
|
|
@@ -313,15 +369,12 @@ async function executeMigrationStatusCommand(options, flags, ui) {
|
|
|
313
369
|
}
|
|
314
370
|
if (options.from) {
|
|
315
371
|
const fromResult = parseContractRef(options.from, {
|
|
316
|
-
graph:
|
|
372
|
+
graph: appGraph,
|
|
317
373
|
refs: allRefs
|
|
318
374
|
});
|
|
319
375
|
if (!fromResult.ok) return notOk(mapRefResolutionError(fromResult.failure));
|
|
320
376
|
fromOverrideHash = fromResult.value.hash;
|
|
321
377
|
}
|
|
322
|
-
} catch (error) {
|
|
323
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
324
|
-
throw error;
|
|
325
378
|
}
|
|
326
379
|
const requiredInvariants = [...activeRefEntry?.invariants ?? []].sort();
|
|
327
380
|
const statusRefs = Object.entries(allRefs).map(([name, entry]) => ({
|
|
@@ -361,26 +414,8 @@ async function executeMigrationStatusCommand(options, flags, ui) {
|
|
|
361
414
|
});
|
|
362
415
|
ui.stderr(header);
|
|
363
416
|
}
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
try {
|
|
367
|
-
contractHash = (await readContractEnvelope(config)).storageHash;
|
|
368
|
-
} catch (error) {
|
|
369
|
-
diagnostics.push({
|
|
370
|
-
code: "CONTRACT.UNREADABLE",
|
|
371
|
-
severity: "warn",
|
|
372
|
-
message: `Could not read contract: ${error instanceof Error ? error.message : "unknown error"}`,
|
|
373
|
-
hints: ["Run 'prisma-next contract emit' to generate a valid contract"]
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
let bundles;
|
|
377
|
-
let graph;
|
|
378
|
-
try {
|
|
379
|
-
({bundles, graph} = await loadMigrationPackages(appMigrationsDir));
|
|
380
|
-
} catch (error) {
|
|
381
|
-
if (MigrationToolsError.is(error)) return notOk(mapMigrationToolsError(error));
|
|
382
|
-
return notOk(errorUnexpected(error instanceof Error ? error.message : String(error), { why: `Failed to read migrations directory: ${error instanceof Error ? error.message : String(error)}` }));
|
|
383
|
-
}
|
|
417
|
+
const bundles = aggregate.app.packages;
|
|
418
|
+
const graph = appGraph;
|
|
384
419
|
if (bundles.length === 0) {
|
|
385
420
|
if (dbConnection && hasDriver) {
|
|
386
421
|
const markerProbe = await validateOnlineMarkerRead(config, dbConnection);
|
|
@@ -448,23 +483,15 @@ async function executeMigrationStatusCommand(options, flags, ui) {
|
|
|
448
483
|
mode = "offline";
|
|
449
484
|
allMarkers = null;
|
|
450
485
|
}
|
|
451
|
-
const contractRawForAggregate = await loadContractRawSafely(config);
|
|
452
486
|
let aggregateSpaces = [];
|
|
453
|
-
if (contractRawForAggregate !== null) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
extensionPacks: config.extensionPacks ?? [],
|
|
462
|
-
deserializeContract: (json) => familyInstance.deserializeContract(json),
|
|
463
|
-
markersBySpace: allMarkers
|
|
464
|
-
});
|
|
465
|
-
} catch {
|
|
466
|
-
aggregateSpaces = [];
|
|
467
|
-
}
|
|
487
|
+
if (contractRawForAggregate !== null) try {
|
|
488
|
+
aggregateSpaces = await loadAggregateStatusSpaces({
|
|
489
|
+
aggregate,
|
|
490
|
+
extensionPacks: config.extensionPacks ?? [],
|
|
491
|
+
markersBySpace: allMarkers
|
|
492
|
+
});
|
|
493
|
+
} catch {
|
|
494
|
+
aggregateSpaces = [];
|
|
468
495
|
}
|
|
469
496
|
const totalPendingAcrossSpaces = computeTotalPendingAcrossSpaces(aggregateSpaces);
|
|
470
497
|
if (activeRefEntry && activeRefEntry.invariants.length > 0) {
|