UNPKG

frontity

Version:

Frontity cli and entry point to other packages

134 lines (119 loc) 4.22 kB
import chalk from "chalk"; import { CreateCommandOptions } from "../steps/types"; import { EventPromised } from "../utils/eventPromised"; import { normalizeOptions, ensureProjectDir, createPackageJson, createReadme, createFrontitySettings, createTsConfig, cloneStarterTheme, installDependencies, downloadFavicon, initializeGit, revertProgress, createGitignore, } from "../steps"; import { hasGit, isInGitRepository } from "../utils"; const defaultOptions: CreateCommandOptions = { path: process.cwd(), typescript: false, noGit: false, packages: [], theme: "@frontity/mars-theme", }; /** * The types of events supported by the EventEmitter generated by `EventPromised`. */ type EventTypes = "error" | "message" | "subscribe"; /** * The create command, exported to be used programatically. * * @param options - The options of the create command. Defined by {@link * CreateCommandOptions}. * * @returns An instance of {@link EventPromised}, which is a promise that can * also send events using an EventEmitter. */ export default (options?: CreateCommandOptions) => // EventPromised is a combination of EventEmitter and Promise. new EventPromised<EventTypes>((resolve, reject, emit) => { // Run an async action to be able to use `await`. (async () => { let step: Promise<any>; let dirExisted: boolean; // Parses and validates options. const { name, theme, path, typescript, noGit }: CreateCommandOptions = normalizeOptions(defaultOptions, options); process.on("SIGINT", async () => { if (typeof dirExisted !== "undefined") await revertProgress(dirExisted, path); }); try { // Ensures that the project dir exists and is empty. step = ensureProjectDir(path); emit("message", `Ensuring ${chalk.yellow(path)} directory.`, step); dirExisted = await step; // Creates `README.md` step = createReadme(name, path); emit("message", `Creating ${chalk.yellow("README.md")}.`, step); await step; // Creates `package.json`. step = createPackageJson(name, theme, path, typescript); emit("message", `Creating ${chalk.yellow("package.json")}.`, step); await step; // Creates `frontity.settings`. const extension = typescript ? "ts" : "js"; step = createFrontitySettings(extension, name, path, theme); emit( "message", `Creating ${chalk.yellow(`frontity.settings.${extension}`)}.`, step ); await step; // Creates `tsconfig.json`. if (typescript) { step = createTsConfig(path); emit("message", `Creating ${chalk.yellow("tsconfig.json")}.`, step); await step; } // Clones the theme inside `packages`. step = cloneStarterTheme(theme, path); emit("message", `Cloning ${chalk.green(theme)}.`, step); await step; // Installs dependencies. step = installDependencies(path); emit("message", `Installing dependencies.`, step); await step; // Download favicon. step = downloadFavicon(path); emit("message", `Downloading ${chalk.yellow("favicon.ico")}.`, step); await step; // Run this step if `noGit` is false and if git is installed on user's machine if (!noGit && hasGit()) { const gitignoreCleanup = await createGitignore(path); if (isInGitRepository()) { emit( "message", "Already in a git repository. Skipping initialization of a new git repo.", step ); } else { step = initializeGit(path); emit("message", `Initializing git repo.`, step); try { await step; } catch (e) { await gitignoreCleanup(); emit("message", `Git initialization failed. Skipping...`, step); } } } } catch (error) { if (typeof dirExisted !== "undefined") await revertProgress(dirExisted, path); reject(error); } })().then(resolve); });