UNPKG

nav-new-publication-cli

Version:

Add new publication to the navigator web project

250 lines (215 loc) 6.57 kB
#!/usr/bin/env node import { Command } from 'commander'; import prompts from 'prompts'; import { cyan, green, red } from 'picocolors'; import { readJson, writeJson, existsSync } from 'fs-extra'; import { resolve } from 'path'; import { logError, logWarn, logSuccess } from './utils'; import { loadJson, writePublicationJson, PublicationData } from './readWritePublications'; import { PromptConfig, createPrompts } from './prompts'; import { updateFiles } from './fileUpdates'; import { checkArn, checkNotEmpty, stripSpace, checkName, checkDomain } from './checkers'; const program = new Command(); const handleSigTerm = () => process.exit(0) process.on('SIGINT', handleSigTerm); process.on('SIGTERM', handleSigTerm); (async ()=> { const packageObj = await loadJson(resolve('./package.json'), { error: 'Error loading package.json', success: null }); program .version( packageObj.version, '-v, --version', 'Output the current version of create new publication.' ) .helpOption('-h, --help', 'Display this help message.') .option('--db, --debug', 'output extra debugging') .option('-p, --platform <type>', 'platform') .option('-t, --title <type>', 'publication title') .option('-c, --cue-name <type>', 'name in cue') .option('--vr', '--vr-steps <type>', 'number of vr steps') .option('-f, --func-steps <type>', 'number of functional steps') .option('-d, --domain <type>', 'domain of site') .allowUnknownOption(); program.parse(process.argv); })(); const opts = program.opts() const platforms: prompts.Choice[] = [ { title: 'nationals', value: 'nationals' }, { title: 'ronionals', value: 'ronionals', }, { title: 'regionals', value: 'regionals', }, { title: "visionals", value: "visionals", } ]; async function run () { const currentDir = process.cwd(); const webRepoPath = currentDir.includes('web') ? currentDir : null; if (!webRepoPath) { throw new Error('This script must be run inside the web repository.'); } const publicationJson = resolve(webRepoPath, 'drone', 'publication.json'); if (!existsSync(publicationJson)) { throw new Error(`Required file not found: ${publicationJson}`); } const publicationList = await loadJson(publicationJson, { error: 'Error loading publication list', success: 'Publication list loaded successfully' }); const platformObj = platforms.find(({title})=> title === opts.platform); let config: PublicationData = { domain: opts.domain, platform: (platformObj) ? platformObj.value : null, title: opts.title, stackAlias: opts.cueName, vr: opts.vrSteps, func: opts.funcSteps, arn: { dev: '', qa: '', preprod: '', prod: '', }, autoScaling: { min: 5, max: 20, } }; config = await createPrompts(config, 'platform', { type: 'select', name: 'platform', message: 'What Platform is it on?', choices: platforms, errorMsg: 'Platform is required' }); console.log(config, publicationList, publicationList[config.platform]) config = await createPrompts(config, 'title', { type: 'text', name: 'title', errorMsg: 'Publication Name is required', message: 'What is the Name of the publication?', validate: checkName(publicationList[config.platform]) as PromptConfig['validate'] }); config = await createPrompts(config, 'cueName', [ { type: 'confirm', name: 'hasCue', message: 'Is the publication name different in cue?', initial: false }, { type: prev => prev ? 'text' : null, name: 'stackAlias', message: 'What is the publication\'s name in cue?', validate: checkNotEmpty as PromptConfig['validate'] } ]); if(!config.domain) { const { domain } = await prompts({ type: 'text', name: 'domain', message: 'What is the publication\'s domain?', validate: checkDomain }); config.domain = domain; } if(!config.vr) { const { vr } = await prompts({ type: 'number', name: 'vr', message: 'How many vr steps for this publication?', initial: 5 }); config.vr = vr; } if(!config.func) { const { func } = await prompts({ type: 'number', name: 'func', message: 'How many Functional steps for this publication?', initial: 14 },); config.func = func; } const awsResponses = await prompts([ { type: 'confirm', name: 'arnTrue', message: 'Do you know the certificateArn for each environment?', initial: true }, { type: (prev: any, values: {arnTrue: boolean}) => values.arnTrue ? 'text' : null, name: 'devCertificateArn', message: 'What is certificateArn for dev environment?', validate: checkArn }, { type: (prev: any, values: {arnTrue: boolean}) => values.arnTrue ? 'text' : null, name: 'qaCertificateArn', message: 'What is certificateArn for QA environment?', validate: checkArn }, { type: (prev: any, values: {arnTrue: boolean}) => values.arnTrue ? 'text' : null, name: 'preprodCertificateArn', message: 'What is certificateArn for PreProd environment?', validate: checkArn }, { type: (prev: any, values: {arnTrue: boolean}) => values.arnTrue ? 'text' : null, name: 'prodCertificateArn', message: 'What is certificateArn for Prod environment?', validate: checkArn }, { type: 'number', name: 'autoScalingMin', message: 'AWS autoscaling, what is the minimum capacity?', initial: 5, }, { type: 'number', name: 'autoScalingMax', message: 'AWS autoscaling, what is the maximum capacity?', initial: 20, }, ]); config.arn = { dev: awsResponses.devCertificateArn, qa: awsResponses.qaCertificateArn, preprod: awsResponses.preprodCertificateArn, prod: awsResponses.prodCertificateArn, }; config.autoScaling = { min: awsResponses.autoScalingMin, max: awsResponses.autoScalingMax, }; await updateFiles(config); }; async function exit(reason: any) { console.log() console.log('Aborting installation.') if (reason.command) { console.log(` ${cyan(reason.command)} has failed.`) } else { console.log( red('Unexpected error. Please report it as a bug:') + '\n', reason ) } process.exit(1) } run().catch(exit);