import { join } from 'path' ; import { outputFileSync , existsSync , ensureDirSync } from 'fs-extra' ; import { prompt } from 'inquirer' ; import ora from 'ora' ; import untildify from 'untildify' ; import { ServerClient } from 'postmark' ; import { ProcessTemplatesOptions , Template , TemplateListOptions , TemplatePullArguments , MetaFile , } from '../../types' ; import { log , validateToken , pluralize } from '../../utils' ; export const command = 'pull <output directory> [options]' ; export const desc = 'Pull templates from a server to <output directory>' ; export const builder = { 'server-token' : { type : 'string' , hidden : true , } , 'request-host' : { type : 'string' , hidden : true , } , overwrite : { type : 'boolean' , alias : 'o' , default : false , describe : 'Overwrite templates if they already exist' , } , } ; export const handler = ( args ) => exec ( args ) ; /**
 * Execute the command
 */ const exec = ( args ) => { const { serverToken } = args ; return validateToken ( serverToken ) . then ( token => { pull ( token , args ) ; } ) ; } ; /**
 * Begin pulling the templates
 */ const pull = ( serverToken , args ) => { const { outputdirectory , overwrite , requestHost } = args ; if ( existsSync ( untildify ( outputdirectory ) ) && ! overwrite ) { return overwritePrompt ( serverToken , outputdirectory , requestHost ) ; } return fetchTemplateList ( { sourceServer : serverToken , outputDir : outputdirectory , requestHost : requestHost , } ) ; } ; /**
 * Ask user to confirm overwrite
 */ const overwritePrompt = ( serverToken , outputdirectory , requestHost ) => { return prompt ( [ { type : 'confirm' , name : 'overwrite' , default : false , message : `Overwrite the files in ${ outputdirectory }?` , } , ] ) . then ( ( answer ) => { if ( answer . overwrite ) { return fetchTemplateList ( { sourceServer : serverToken , outputDir : outputdirectory , requestHost : requestHost , } ) ; } } ) ; } ; /**
 * Fetch template list from PM
 */ const fetchTemplateList = ( options ) => { const { sourceServer , outputDir , requestHost } = options ; const spinner = ora ( 'Pulling templates from Postmark...' ) . start ( ) ; const client = new ServerClient ( sourceServer ) ; if ( requestHost !== undefined && requestHost !== '' ) { client . clientOptions . requestHost = requestHost ; } client . getTemplates ( { count : 300 } ) . then ( response => { if ( response . TotalCount === 0 ) { spinner . stop ( ) ; log ( 'There are no templates on this server.' , { error : true } ) ; process . exit ( 1 ) ; } else { processTemplates ( { spinner , client , outputDir : outputDir , totalCount : response . TotalCount , templates : response . Templates , } ) ; } } ) . catch ( ( error ) => { spinner . stop ( ) ; log ( error , { error : true } ) ; process . exit ( 1 ) ; } ) ; } ; /**
 * Fetch each template’s content from the server
 */ const processTemplates = ( options ) => { const { spinner , client , outputDir , totalCount , templates } = options ; let requestCount = 0 ; let totalDownloaded = 0 ; templates . forEach ( template => { if ( ! template . Alias ) { requestCount ++ ; log ( `Template named "${ template . Name }" will not be downloaded because it is missing an alias.` , { warn : true } ) ; if ( requestCount === totalCount ) spinner . stop ( ) ; return ; } client . getTemplate ( template . Alias ) . then ( ( response ) => { requestCount ++ ; saveTemplate ( outputDir , response , client ) ; totalDownloaded ++ ; if ( requestCount === totalCount ) { spinner . stop ( ) ; log ( `All finished! ${ totalDownloaded } ${ pluralize ( totalDownloaded , 'template has' , 'templates have' ) } been saved to ${ outputDir }.` , { color : 'green' } ) ; } } ) . catch ( ( error ) => { spinner . stop ( ) ; log ( error , { error : true } ) ; } ) ; } ) ; } ; return const saveTemplate = ( outputDir , template , client ) => { outputDir = template . TemplateType === 'Layout' ? join ( outputDir , '_layouts' ) : outputDir ; const path = untildify ( join ( outputDir , template . Alias ) ) ; ensureDirSync ( path ) ; if ( template . HtmlBody !== '' ) { outputFileSync ( join ( path , 'content.html' ) , template . HtmlBody ) ; } if ( template . TextBody !== '' ) { outputFileSync ( join ( path , 'content.txt' ) , template . TextBody ) ; } let meta = { Name : template . Name , Alias : template . Alias , ... ( template . Subject && { Subject : template . Subject } ) , TemplateType : template . TemplateType , ... ( template . TemplateType === 'Standard' && { LayoutTemplate : template . LayoutTemplate , } ) , } ; client . validateTemplate ( { ... ( template . HtmlBody && { HtmlBody : template . HtmlBody } ) , ... ( template . TextBody && { TextBody : template . TextBody } ) , ... meta , } ) . then ( ( result ) => { meta . TestRenderModel = result . SuggestedTemplateModel ; } ) . catch ( ( error ) => { log ( 'Error fetching suggested template model' , { error : true } ) ; log ( error , { error : true } ) ; } ) . then ( ( ) => { outputFileSync ( join ( path , 'meta.json' ) , JSON . stringify ( meta , null , 2 ) ) ; } ) ; } ;