From 0c0a63858c73aeab5d92b340d5d1ca171dc68320 Mon Sep 17 00:00:00 2001 From: alexguo8 <37782734+alexguo8@users.noreply.github.com> Date: Thu, 22 Apr 2021 20:57:29 -0400 Subject: [PATCH] Prevent graphql and python combination (#10) --- cli/index.ts | 63 +++++++++++++++++++++++++++++++++++++++++++--------- index.ts | 7 ++++-- package.json | 4 ++-- 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/cli/index.ts b/cli/index.ts index 991f2a6..bba46c0 100644 --- a/cli/index.ts +++ b/cli/index.ts @@ -79,6 +79,33 @@ const OPTIONS: OptionConfigs = { }, }; +const OPTION_COMBINATION_DENY_LIST = [ + [ + { optionType: "backend", value: "python" }, + { optionType: "api", value: "graphql" }, + ], +]; + +const validateCommandLineOptions = ( + commandLineOptions: CommandLineOptions, +): void => { + OPTION_COMBINATION_DENY_LIST.forEach((combination) => { + if ( + combination.every( + (option) => + commandLineOptions[option.optionType as keyof CommandLineOptions] === + option.value, + ) + ) { + const formattedCombination = combination.map((c) => c.value).join(", "); + // TODO: custom error type would be a nice-to-have + throw new Error( + `Sorry, we currently do not support the following combination: ${formattedCombination}`, + ); + } + }); +}; + const parseArguments = (args: CommandLineArgs): CommandLineOptions => { const { argv } = yargs(args.slice(2)).options({ backend: { @@ -122,22 +149,34 @@ const parseArguments = (args: CommandLineArgs): CommandLineOptions => { const promptOptions = async ( options: CommandLineOptions, ): Promise => { - const prompts = []; + let prompts = []; + const tsChoice = OPTIONS.backend.choices.find( + (choice) => choice.value === "typescript", + ); + if (!options.backend) { prompts.push({ type: "list", name: "backend", message: OPTIONS.backend.message, - choices: OPTIONS.backend.choices, + choices: options.api === "graphql" ? [tsChoice] : OPTIONS.backend.choices, }); } + let answers = await inquirer.prompt(prompts); + prompts = []; + + const backend = options.backend || answers.backend; + const restChoice = OPTIONS.api.choices.find( + (choice) => choice.value === "rest", + ); + if (!options.api) { prompts.push({ type: "list", name: "api", message: OPTIONS.api.message, - choices: OPTIONS.api.choices, + choices: backend === "python" ? [restChoice] : OPTIONS.api.choices, }); } @@ -168,11 +207,11 @@ const promptOptions = async ( }); } - const answers = await inquirer.prompt(prompts); + answers = await inquirer.prompt(prompts); return { appOptions: { - backend: options.backend || answers.backend, + backend, api: options.api || answers.api, database: options.database || answers.database, auth: (options.auth || answers.auth ? "auth" : null) as AuthType, @@ -210,7 +249,7 @@ const confirmPrompt = async (options: Options) => { return confirm; }; -async function cli(args: CommandLineArgs): Promise { +async function cli(args: CommandLineArgs): Promise { console.log( boxen( chalk.bold( @@ -227,13 +266,16 @@ async function cli(args: CommandLineArgs): Promise { const commandLineOptions: CommandLineOptions = parseArguments(args); + validateCommandLineOptions(commandLineOptions); + const { appOptions, outputDir } = await promptOptions(commandLineOptions); const confirm = await confirmPrompt(appOptions); if (!confirm) { - console.log(chalk.red.bold("Blueprint app creation has been cancelled.")); - return null; + return Promise.reject( + new Error("Blueprint app creation has been cancelled."), + ); } console.log(chalk.green.bold("Confirmed. Creating blueprint app...")); @@ -242,8 +284,7 @@ async function cli(args: CommandLineArgs): Promise { const changeDirectory = shell.cd(path); if (changeDirectory.code !== 0) { - console.log("No directory exists. Exiting..."); - return null; + return Promise.reject(new Error("No directory exists. Exiting...")); } const clone = shell.exec( @@ -251,7 +292,7 @@ async function cli(args: CommandLineArgs): Promise { ); if (clone.code !== 0) { - console.log("Git clone failed. Exiting..."); + return Promise.reject(new Error("Git clone failed. Exiting...")); } return appOptions; diff --git a/index.ts b/index.ts index bbc9f78..2730653 100755 --- a/index.ts +++ b/index.ts @@ -1,4 +1,5 @@ #!/usr/bin/env node +import chalk from "chalk"; import cli from "./cli"; import { Options } from "./cli/optionTypes"; @@ -17,9 +18,11 @@ async function scrub(rootDir: string, options: Options) { async function run() { const rootDir = __dirname; - const options = await cli(process.argv); - if (options) { + try { + const options = await cli(process.argv); await scrub(rootDir, options); + } catch (err) { + console.log(chalk.red.bold(err.message)); } } diff --git a/package.json b/package.json index 7a2f294..e4375fa 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "license": "MIT", "scripts": { "dev": "ts-node index.ts", - "lint": "eslint . --ext .ts,.js", - "lint-fix": "eslint . --ext .ts,.js --fix", + "lint": "eslint . --ext .ts", + "lint-fix": "eslint . --ext .ts --fix", "prod": "tsc -p . && node bin/index.js" }, "devDependencies": {