@@ -6,12 +6,18 @@ import * as path from 'path'
66import * as fs from 'fs-extra'
77import { Seeder } from '../seed/Seeder'
88const debug = require ( 'debug' ) ( 'deploy' )
9- import { prettyTime , concatName , defaultDockerCompose } from '../../utils/util'
9+ import {
10+ prettyTime ,
11+ concatName ,
12+ defaultDockerCompose ,
13+ printAdminLink ,
14+ } from '../../utils/util'
1015import * as sillyname from 'sillyname'
1116import { EndpointDialog } from '../../utils/EndpointDialog'
1217import { spawnSync } from 'npm-run'
1318import { spawnSync as nativeSpawnSync } from 'child_process'
1419import * as figures from 'figures'
20+ import { satisfiesVersion } from '../../utils/satisfiesVersion'
1521
1622export default class Deploy extends Command {
1723 static topic = 'deploy'
@@ -58,10 +64,12 @@ ${chalk.gray(
5864 description : 'Path to .env file to inject env vars' ,
5965 char : 'e' ,
6066 } ) ,
67+ [ 'project' ] : flags . string ( {
68+ description : 'Path to Prisma definition file' ,
69+ char : 'p' ,
70+ } ) ,
6171 }
62- private deploying : boolean = false
6372 private showedHooks : boolean = false
64- private loggedIn : boolean = false
6573 async run ( ) {
6674 /**
6775 * Get Args
@@ -95,7 +103,6 @@ ${chalk.gray(
95103 */
96104 let workspace : string | undefined | null = this . definition . getWorkspace ( )
97105 let cluster
98- let dockerComposeYml = defaultDockerCompose
99106 if ( ! serviceName || ! stage || interactive ) {
100107 await this . env . fetchClusters ( )
101108 const endpointDialog = new EndpointDialog ( {
@@ -111,7 +118,6 @@ ${chalk.gray(
111118 workspace = results . workspace
112119 serviceName = results . service
113120 stage = results . stage
114- dockerComposeYml = results . dockerComposeYml
115121 this . definition . replaceEndpoint ( results . endpoint )
116122 // Reload definition because we are changing the yml file
117123 await this . definition . load ( this . flags , envFile )
@@ -182,12 +188,6 @@ ${chalk.gray(
182188 )
183189 }
184190
185- private getSillyName ( ) {
186- return `${ slugify ( sillyname ( ) ) . split ( '-' ) [ 0 ] } -${ Math . round (
187- Math . random ( ) * 1000 ,
188- ) } `
189- }
190-
191191 private async projectExists (
192192 cluster : Cluster ,
193193 name : string ,
@@ -232,7 +232,6 @@ ${chalk.gray(
232232 workspace : string | null ,
233233 noMigrate : boolean ,
234234 ) : Promise < void > {
235- this . deploying = true
236235 let before = Date . now ( )
237236
238237 const b = s => `\`${ chalk . bold ( s ) } \``
@@ -351,9 +350,8 @@ ${chalk.gray(
351350 }
352351
353352 // no action required
354- this . deploying = false
355353 if ( migrationResult . migration ) {
356- this . printEndpoints (
354+ await this . printEndpoints (
357355 cluster ,
358356 serviceName ,
359357 stageName ,
@@ -458,149 +456,32 @@ ${chalk.gray(
458456 }
459457 }
460458
461- private printEndpoints (
459+ private async printEndpoints (
462460 cluster : Cluster ,
463461 serviceName : string ,
464462 stageName : string ,
465463 workspace ?: string ,
466464 ) {
467- this . out . log ( `\n${ chalk . bold (
468- 'Your Prisma GraphQL database endpoint is live:' ,
469- ) }
465+ const version = await cluster . getVersion ( )
466+ const hasAdmin = satisfiesVersion ( version ! , '1.29.0' )
467+ const adminText = hasAdmin
468+ ? printAdminLink (
469+ cluster . getApiEndpoint ( serviceName , stageName , workspace ) ,
470+ )
471+ : ''
470472
471- ${ chalk . bold ( 'HTTP:' ) } ${ cluster . getApiEndpoint (
472- serviceName ,
473- stageName ,
474- workspace ,
475- ) }
476- ${ chalk . bold ( 'WS:' ) } ${ cluster . getWSEndpoint (
473+ this . out . log ( `\n${ 'Your Prisma GraphQL database endpoint is live:' }
474+
475+ ${ 'HTTP:' } ${ cluster . getApiEndpoint ( serviceName , stageName , workspace ) }
476+ ${ 'WS:' } ${ cluster . getWSEndpoint (
477477 serviceName ,
478478 stageName ,
479479 workspace ,
480- ) }
480+ ) } ${ adminText }
481481` )
482482 }
483-
484- private getCloudClusters ( ) : Cluster [ ] {
485- return this . env . clusters . filter ( c => c . shared || c . isPrivate )
486- }
487-
488- private async clusterSelection ( loggedIn : boolean ) : Promise < string > {
489- debug ( { loggedIn } )
490-
491- const choices = loggedIn
492- ? await this . getLoggedInChoices ( )
493- : this . getPublicChoices ( )
494-
495- const question = {
496- name : 'cluster' ,
497- type : 'list' ,
498- message : `Please choose the cluster you want to deploy to` ,
499- choices,
500- pageSize : 9 ,
501- }
502-
503- const { cluster } = await this . out . prompt ( question )
504-
505- if ( cluster === 'login' ) {
506- await this . client . login ( )
507- this . loggedIn = true
508- return this . clusterSelection ( true )
509- }
510-
511- return cluster
512- }
513-
514- private getLocalClusterChoices ( ) : string [ ] [ ] {
515- return [ [ 'local' , 'Local cluster (requires Docker)' ] ]
516- }
517-
518- private async getLoggedInChoices ( ) : Promise < any [ ] > {
519- await this . env . fetchClusters ( )
520- const localChoices = this . getLocalClusterChoices ( )
521- const combinations : string [ ] [ ] = [ ]
522- const remoteClusters = this . env . clusters . filter (
523- c => c . shared || c . isPrivate ,
524- )
525-
526- remoteClusters . forEach ( cluster => {
527- const label = this . env . sharedClusters . includes ( cluster . name )
528- ? 'Free development cluster (hosted on Prisma Cloud)'
529- : 'Private Prisma Cluster'
530- combinations . push ( [ `${ cluster . workspaceSlug } /${ cluster . name } ` , label ] )
531- } )
532-
533- const allCombinations = [ ...combinations , ...localChoices ]
534-
535- return [
536- new inquirer . Separator ( ' ' ) ,
537- ...this . convertChoices ( allCombinations ) ,
538- new inquirer . Separator ( ' ' ) ,
539- new inquirer . Separator (
540- chalk . dim (
541- `You can learn more about deployment in the docs: http://bit.ly/prisma-graphql-deployment` ,
542- ) ,
543- ) ,
544- ]
545- }
546-
547- private convertChoices (
548- choices : string [ ] [ ] ,
549- ) : Array < { value : string ; name : string } > {
550- const padded = this . out . printPadded ( choices , 0 , 6 ) . split ( '\n' )
551- return padded . map ( ( name , index ) => ( {
552- name,
553- value : choices [ index ] [ 0 ] ,
554- } ) )
555- }
556-
557- private getPublicChoices ( ) : any [ ] {
558- const publicChoices = [
559- [
560- 'prisma-eu1' ,
561- 'Public development cluster (hosted in EU on Prisma Cloud)' ,
562- ] ,
563- [
564- 'prisma-us1' ,
565- 'Public development cluster (hosted in US on Prisma Cloud)' ,
566- ] ,
567- ]
568- const allCombinations = [ ...publicChoices , ...this . getLocalClusterChoices ( ) ]
569-
570- return [
571- ...this . convertChoices ( allCombinations ) ,
572- new inquirer . Separator ( ' ' ) ,
573- {
574- value : 'login' ,
575- name : 'Log in or create new account on Prisma Cloud' ,
576- } ,
577- new inquirer . Separator ( ' ' ) ,
578- new inquirer . Separator (
579- chalk . dim (
580- `Note: When not logged in, service deployments to Prisma Cloud expire after 7 days.` ,
581- ) ,
582- ) ,
583- new inquirer . Separator (
584- chalk . dim (
585- `You can learn more about deployment in the docs: http://bit.ly/prisma-graphql-deployment` ,
586- ) ,
587- ) ,
588- new inquirer . Separator ( ' ' ) ,
589- ]
590- }
591483}
592484
593485export function isValidProjectName ( projectName : string ) : boolean {
594486 return / ^ [ A - Z ] ( .* ) / . test ( projectName )
595- }
596-
597- function slugify ( text ) {
598- return text
599- . toString ( )
600- . toLowerCase ( )
601- . replace ( / \s + / g, '-' ) // Replace spaces with -
602- . replace ( / [ ^ \w \- ] + / g, '' ) // Remove all non-word chars
603- . replace ( / \- \- + / g, '-' ) // Replace multiple - with single -
604- . replace ( / ^ - + / , '' ) // Trim - from start of text
605- . replace ( / - + $ / , '' ) // Trim - from end of text
606- }
487+ }
0 commit comments