11import { randomBytes } from "node:crypto" ;
22
3+ import {
4+ type PrismaCliPackageCommandFormatter ,
5+ resolvePrismaCliPackageCommandFormatterSync ,
6+ } from "../lib/agent/cli-command" ;
37import { requireComputeAuth } from "../lib/auth/guard" ;
48import {
59 createManagementDatabaseProvider ,
@@ -363,15 +367,26 @@ export async function runDatabaseUsage(
363367 databaseRef : string ,
364368 flags : DatabaseUsageFlags ,
365369) : Promise < CommandSuccess < DatabaseUsageResult > > {
366- const from = parseUsageDate ( flags . from , "--from" ) ;
367- const to = parseUsageDate ( flags . to , "--to" ) ;
370+ const formatCommand = resolvePrismaCliPackageCommandFormatterSync (
371+ context . runtime . cwd ,
372+ ) ;
373+ const from = parseUsageDate ( flags . from , "--from" , formatCommand ) ;
374+ const to = parseUsageDate ( flags . to , "--to" , formatCommand ) ;
368375 if ( from && to && Date . parse ( from ) > Date . parse ( to ) ) {
369376 throw usageError (
370377 "Invalid usage period" ,
371378 "--from must not be later than --to." ,
372379 "Pass a --from date that is on or before the --to date." ,
373380 [
374- "prisma-cli database usage <database> --from 2026-06-01 --to 2026-06-30" ,
381+ formatCommand ( [
382+ "database" ,
383+ "usage" ,
384+ "<database>" ,
385+ "--from" ,
386+ "2026-06-01" ,
387+ "--to" ,
388+ "2026-06-30" ,
389+ ] ) ,
375390 ] ,
376391 "database" ,
377392 ) ;
@@ -416,7 +431,10 @@ export async function runDatabaseBackupList(
416431 databaseRef : string ,
417432 flags : DatabaseBackupListFlags ,
418433) : Promise < CommandSuccess < DatabaseBackupListResult > > {
419- const limit = parseBackupLimit ( flags . limit ) ;
434+ const limit = parseBackupLimit (
435+ flags . limit ,
436+ resolvePrismaCliPackageCommandFormatterSync ( context . runtime . cwd ) ,
437+ ) ;
420438
421439 const { provider, target } = await requireDatabaseContext (
422440 context ,
@@ -456,13 +474,16 @@ export async function runDatabaseRestore(
456474 databaseRef : string ,
457475 flags : DatabaseRestoreFlags ,
458476) : Promise < CommandSuccess < DatabaseRestoreResult > > {
477+ const formatCommand = resolvePrismaCliPackageCommandFormatterSync (
478+ context . runtime . cwd ,
479+ ) ;
459480 const backupId = flags . backupId ?. trim ( ) ;
460481 if ( ! backupId ) {
461482 throw usageError (
462483 "Backup id required" ,
463484 "Database restore needs the backup to restore from." ,
464- " Pass --backup <backup-id> from prisma-cli database backup list." ,
465- [ "prisma-cli database backup list <database>"] ,
485+ ` Pass --backup <backup-id> from ${ formatCommand ( [ " database" , " backup" , " list" , "<database>" ] ) } .` ,
486+ [ formatCommand ( [ " database" , " backup" , " list" , " <database>"] ) ] ,
466487 "database" ,
467488 ) ;
468489 }
@@ -500,7 +521,7 @@ export async function runDatabaseRestore(
500521 confirm : flags . confirm ,
501522 summary : "Confirm database restore" ,
502523 why : "Restoring immediately and irreversibly overwrites all data in the target database, so it requires the exact target database id." ,
503- nextStep : `prisma-cli database restore ${ database . id } --backup ${ backupId } ${ sourceDatabaseArg } --confirm ${ database . id } ` ,
524+ nextStep : `${ formatCommand ( [ " database" , " restore" , database . id , " --backup" , backupId ] ) } ${ sourceDatabaseArg } --confirm ${ database . id } ` ,
504525 } ) ;
505526
506527 const restored = await provider . restoreDatabase ( {
@@ -524,7 +545,7 @@ export async function runDatabaseRestore(
524545 } ,
525546 } ,
526547 warnings : [ ] ,
527- nextSteps : [ `prisma-cli database show ${ database . id } ` ] ,
548+ nextSteps : [ formatCommand ( [ " database" , " show" , database . id ] ) ] ,
528549 } ;
529550}
530551
@@ -533,14 +554,24 @@ export async function runDatabaseConnectionRotate(
533554 connectionRef : string ,
534555 flags : DatabaseConnectionRotateFlags ,
535556) : Promise < CommandSuccess < DatabaseConnectionRotateResult > > {
557+ const formatCommand = resolvePrismaCliPackageCommandFormatterSync (
558+ context . runtime . cwd ,
559+ ) ;
536560 const connectionId = connectionRef . trim ( ) ;
537561 if ( ! connectionId ) {
538562 throw usageError (
539563 "Connection id required" ,
540564 "Database connection rotation needs a connection id." ,
541565 "Pass the connection id to rotate." ,
542566 [
543- "prisma-cli database connection rotate <connection-id> --confirm <connection-id>" ,
567+ formatCommand ( [
568+ "database" ,
569+ "connection" ,
570+ "rotate" ,
571+ "<connection-id>" ,
572+ "--confirm" ,
573+ "<connection-id>" ,
574+ ] ) ,
544575 ] ,
545576 "database" ,
546577 ) ;
@@ -553,6 +584,14 @@ export async function runDatabaseConnectionRotate(
553584 confirm : flags . confirm ,
554585 summary : "Confirm database connection rotation" ,
555586 why : "Rotating revokes the previous credentials and breaks clients still using them, so it requires the exact connection id." ,
587+ nextStep : formatCommand ( [
588+ "database" ,
589+ "connection" ,
590+ "rotate" ,
591+ connectionId ,
592+ "--confirm" ,
593+ connectionId ,
594+ ] ) ,
556595 } ) ;
557596
558597 const provider = await requireDatabaseProviderOnly ( context ) ;
@@ -578,6 +617,7 @@ const USAGE_DATETIME_PATTERN = /^\d{4}-\d{2}-\d{2}T/;
578617function parseUsageDate (
579618 value : string | undefined ,
580619 flagName : string ,
620+ formatCommand : PrismaCliPackageCommandFormatter ,
581621) : string | undefined {
582622 if ( value === undefined ) {
583623 return undefined ;
@@ -603,7 +643,17 @@ function parseUsageDate(
603643 "Invalid usage period" ,
604644 `${ flagName } must be an ISO date such as 2026-06-01 or an ISO datetime such as 2026-06-01T12:00:00Z.` ,
605645 `Pass an ISO date or datetime to ${ flagName } .` ,
606- [ "prisma-cli database usage <database> --from 2026-06-01 --to 2026-06-30" ] ,
646+ [
647+ formatCommand ( [
648+ "database" ,
649+ "usage" ,
650+ "<database>" ,
651+ "--from" ,
652+ "2026-06-01" ,
653+ "--to" ,
654+ "2026-06-30" ,
655+ ] ) ,
656+ ] ,
607657 "database" ,
608658 ) ;
609659}
@@ -616,7 +666,10 @@ function isValidCalendarDate(datePart: string): boolean {
616666 ) ;
617667}
618668
619- function parseBackupLimit ( value : string | undefined ) : number | undefined {
669+ function parseBackupLimit (
670+ value : string | undefined ,
671+ formatCommand : PrismaCliPackageCommandFormatter ,
672+ ) : number | undefined {
620673 if ( value === undefined ) {
621674 return undefined ;
622675 }
@@ -627,7 +680,16 @@ function parseBackupLimit(value: string | undefined): number | undefined {
627680 "Invalid backup limit" ,
628681 "--limit must be an integer between 1 and 100." ,
629682 "Pass a --limit between 1 and 100." ,
630- [ "prisma-cli database backup list <database> --limit 50" ] ,
683+ [
684+ formatCommand ( [
685+ "database" ,
686+ "backup" ,
687+ "list" ,
688+ "<database>" ,
689+ "--limit" ,
690+ "50" ,
691+ ] ) ,
692+ ] ,
631693 "database" ,
632694 ) ;
633695 }
@@ -668,7 +730,11 @@ async function requireDatabaseContext(
668730 }
669731
670732 return {
671- provider : createManagementDatabaseProvider ( client ) ,
733+ provider : createManagementDatabaseProvider ( client , {
734+ formatCommand : resolvePrismaCliPackageCommandFormatterSync (
735+ context . runtime . cwd ,
736+ ) ,
737+ } ) ,
672738 target : targetResult . value ,
673739 } ;
674740 }
@@ -703,7 +769,11 @@ async function requireDatabaseProviderOnly(
703769 if ( ! client ) {
704770 throw authRequiredError ( ) ;
705771 }
706- return createManagementDatabaseProvider ( client ) ;
772+ return createManagementDatabaseProvider ( client , {
773+ formatCommand : resolvePrismaCliPackageCommandFormatterSync (
774+ context . runtime . cwd ,
775+ ) ,
776+ } ) ;
707777 }
708778
709779 return createFixtureDatabaseProvider ( context ) ;
@@ -805,7 +875,11 @@ function createFixtureDatabaseProvider(
805875 throw databaseNotFoundError ( options . targetDatabaseId ) ;
806876 }
807877 if ( restored . outcome === "backup-not-found" ) {
808- throw backupNotFoundError ( options . backupId , options . sourceDatabaseId ) ;
878+ throw backupNotFoundError (
879+ options . backupId ,
880+ options . sourceDatabaseId ,
881+ resolvePrismaCliPackageCommandFormatterSync ( context . runtime . cwd ) ,
882+ ) ;
809883 }
810884 return normalizeDatabase ( restored . database , options . projectId ) ;
811885 } ,
@@ -981,15 +1055,22 @@ function databaseAmbiguousError(
9811055function backupNotFoundError (
9821056 backupId : string ,
9831057 sourceDatabaseId : string ,
1058+ formatCommand : PrismaCliPackageCommandFormatter ,
9841059) : CliError {
1060+ const listCommand = formatCommand ( [
1061+ "database" ,
1062+ "backup" ,
1063+ "list" ,
1064+ sourceDatabaseId ,
1065+ ] ) ;
9851066 return new CliError ( {
9861067 code : "DATABASE_BACKUP_NOT_FOUND" ,
9871068 domain : "database" ,
9881069 summary : "Database backup not found" ,
9891070 why : `No backup matched "${ backupId } " for database "${ sourceDatabaseId } ".` ,
990- fix : " Pass a backup id from prisma-cli database backup list." ,
1071+ fix : ` Pass a backup id from ${ listCommand } .` ,
9911072 exitCode : 1 ,
992- nextSteps : [ `prisma-cli database backup list ${ sourceDatabaseId } ` ] ,
1073+ nextSteps : [ listCommand ] ,
9931074 } ) ;
9941075}
9951076
0 commit comments