From e623808231b3d88e3345b4c3cbb2c9309e2672e2 Mon Sep 17 00:00:00 2001 From: Ayo Date: Tue, 24 Oct 2023 19:56:59 +0200 Subject: [PATCH] refactor(create-mcfly): strictly type the script --- package-lock.json | 2 +- packages/create-mcfly/create.mjs | 144 +++++++++++++++++++++++++++++ packages/create-mcfly/index.js | 85 +---------------- packages/create-mcfly/package.json | 3 +- 4 files changed, 148 insertions(+), 86 deletions(-) create mode 100644 packages/create-mcfly/create.mjs diff --git a/package-lock.json b/package-lock.json index 43b2599..c9896cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3975,7 +3975,7 @@ } }, "packages/create-mcfly": { - "version": "0.2.9", + "version": "0.2.10", "license": "MIT", "dependencies": { "consola": "^3.2.3", diff --git a/packages/create-mcfly/create.mjs b/packages/create-mcfly/create.mjs new file mode 100644 index 0000000..d944c21 --- /dev/null +++ b/packages/create-mcfly/create.mjs @@ -0,0 +1,144 @@ +// @ts-check +import { consola } from "consola"; +import { colorize } from "consola/utils"; +import { downloadTemplate } from "giget"; +import { execSync as exec } from "node:child_process"; + +/** + * @typedef {{ + * prompt: string, + * info?: string, + * startMessage: string, + * command: string, + * }} PromptAction + **/ + +/** + * Create McFly App + */ +export async function create() { + console.clear(); + const defaultDirectory = "./mcfly-app"; + consola.box(`👋 Hello! Welcome to ${colorize("bold", "McFly")}!`); + const directory = + (await consola.prompt("Give your new project a name:", { + placeholder: defaultDirectory, + })) ?? defaultDirectory; + + const hasErrors = await downloadTemplateToDirectory(directory); + const safeDirectory = getSafeDirectory(directory); + + if (!hasErrors) { + /** + * @type Array + */ + const prompts = [ + { + prompt: "Would you like to install the dependencies?", + info: "This might take some time depending on your connectivity.", + startMessage: "Installing dependencies using npm...", + command: `npm --prefix ${safeDirectory} install`, + }, + { + prompt: "Would you like to initialize your git repository?", + startMessage: "Initializing git repository...", + command: `git -C ${safeDirectory} init`, + }, + ]; + + const intentions = await askPrompts(prompts); + showResults(safeDirectory, intentions[0]); + } +} + +/** + * Returns string that is safe for commands + * @param {string} directory + * @returns string + */ +function getSafeDirectory(directory) { + return /\s/.test(directory) ? `"${directory}"` : directory; +} + +/** + * Tries to download the template to the directory and returns a Promise whether the operation resulted to errors + * @param {string} directory + * @returns Promise hasErrors + */ +async function downloadTemplateToDirectory(directory) { + let hasErrors = false; + + try { + consola.start( + `Copying template to ${colorize("bold", getSafeDirectory(directory))}...` + ); + await downloadTemplate("github:ayoayco/mcfly/templates/basic", { + dir: directory, + }); + } catch (e) { + consola.error(e); + hasErrors = true; + } + + return hasErrors; +} + +/** + * + * @param {Array} prompts + * @returns Array + */ +async function askPrompts(prompts) { + const results = []; + + for (const p of prompts) { + const userIntends = await consola.prompt(p.prompt, { + type: "confirm", + }); + + if (userIntends) { + p.info && consola.info(p.info); + consola.start(p.startMessage); + try { + await exec(p.command); + consola.success("Done!"); + } catch (e) { + consola.error(e); + } + } + results.push(userIntends); + } + + return results; +} + +/** + * Displays the success result string based on directory and choices + * @param {string} directory + * @param {boolean} installDeps + */ +function showResults(directory, installDeps) { + let nextActions = [ + `Go to your project by running ${colorize("yellow", `cd ${directory}`)}`, + ]; + + if (!installDeps) { + nextActions.push( + `Install the dependencies with ${colorize("yellow", "npm install")}` + ); + } + + nextActions = nextActions.concat([ + `Start the dev server with ${colorize("yellow", "npm start")}`, + `Join us at ${colorize("blue", "https://ayco.io/gh/McFly")}`, + ]); + + const result = `🎉 Your new ${colorize( + "bold", + "McFly" + )} app is ready: ${directory}\n\nNext actions: ${nextActions + .map((action, index) => `\n${++index}. ${action}`) + .join("")}`; + + consola.box(result); +} diff --git a/packages/create-mcfly/index.js b/packages/create-mcfly/index.js index 73a9a85..d95cadb 100755 --- a/packages/create-mcfly/index.js +++ b/packages/create-mcfly/index.js @@ -1,86 +1,3 @@ #!/usr/bin/env node -const { downloadTemplate } = require("giget"); -const { consola } = require("consola"); -const { execSync: exec } = require("node:child_process"); -const { colorize } = require("consola/utils"); -create(); -async function create() { - console.clear(); - let hasErrors = false; - const defaultDirectory = "./mcfly-app"; - consola.box(`👋 Hello! Welcome to ${colorize("bold", "McFly")}!`); - const directory = - (await consola.prompt("Give your new project a name:", { - placeholder: defaultDirectory, - })) ?? defaultDirectory; - try { - consola.start(`Copying template to ${directory}...`); - await downloadTemplate("github:ayoayco/mcfly/templates/basic", { - dir: directory, - }); - } catch (e) { - consola.error(e); - hasErrors = true; - } - - if (!hasErrors) { - const installDeps = await consola.prompt( - "Would you like to install the dependencies?", - { - type: "confirm", - } - ); - if (installDeps) { - consola.info("This might take some time depending on your connectivity."); - consola.start("Installing dependencies using npm..."); - try { - await exec(`npm --prefix "${directory}" install`); - consola.success("Done!"); - } catch (e) { - consola.error(e); - } - } - - const initializeGit = await consola.prompt( - "Would you like to initialize your git repository?", - { - type: "confirm", - } - ); - if (initializeGit) { - consola.start("Initializing git repository..."); - try { - await exec(`git -C "${directory}" init`); - consola.success("Done!"); - } catch (e) { - consola.error(e); - } - } - - let nextActions = [ - `Go to your project by running ${colorize("yellow", `cd ${directory}`)}`, - ]; - - if (!installDeps) { - nextActions.push( - `Install the dependencies with ${colorize("yellow", "npm install")}` - ); - } - - nextActions = nextActions.concat([ - `Start the dev server with ${colorize("yellow", "npm start")}`, - `Join us at ${colorize("blue", "https://ayco.io/gh/McFly")}`, - ]); - - const result = `🎉 Your new ${colorize( - "bold", - "McFly" - )} app is ready: ${directory}\n\nNext actions: ${nextActions - .map((action, index) => `\n${++index}. ${action}`) - .join("")}`; - - consola.box(result); - } - return 1; -} +import("./create.mjs").then(({ create }) => create()); diff --git a/packages/create-mcfly/package.json b/packages/create-mcfly/package.json index bd97a46..8e763bc 100644 --- a/packages/create-mcfly/package.json +++ b/packages/create-mcfly/package.json @@ -1,6 +1,6 @@ { "name": "create-mcfly", - "version": "0.2.9", + "version": "0.2.10", "bin": { "create-mcfly": "./index.js" }, @@ -11,6 +11,7 @@ }, "files": [ "index.js", + "create.mjs", "LICENSE" ], "scripts": {