UNPKG

@log4brains/cli-common

Version:

Log4brains architecture knowledge base common CLI features

295 lines (236 loc) 7.45 kB
import chalk from 'chalk'; import inquirer from 'inquirer'; import ora from 'ora'; import CliTable3 from 'cli-table3'; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable no-console */ /** * Captures console.log(), console.error() and console.warn() * Source: https://github.com/vercel/next.js/blob/canary/packages/next/build/spinner.ts Thanks! */ class ConsoleCapturer { start() { this.origConsoleLog = console.log; this.origConsoleWarn = console.warn; this.origConsoleError = console.error; const logHandle = (method, args) => { if (this.onLog) { this.onLog(method, args, method === this.origConsoleLog ? "stdout" : "stderr"); } }; console.log = (...args) => logHandle(this.origConsoleLog, args); console.warn = (...args) => logHandle(this.origConsoleWarn, args); console.error = (...args) => logHandle(this.origConsoleError, args); } doPrintln(message, ...optionalParams) { if (!this.origConsoleLog) { throw new Error("ConsoleCapturer is not started"); } this.origConsoleLog(message != null ? message : "", ...optionalParams); } doPrintlnErr(message, ...optionalParams) { if (!this.origConsoleError) { throw new Error("ConsoleCapturer is not started"); } this.origConsoleError(message != null ? message : "", ...optionalParams); } stop() { if (!this.origConsoleLog || !this.origConsoleWarn || !this.origConsoleError) { throw new Error("ConsoleCapturer is not started"); } console.log = this.origConsoleLog; console.warn = this.origConsoleWarn; console.error = this.origConsoleError; this.origConsoleLog = undefined; this.origConsoleWarn = undefined; this.origConsoleError = undefined; } } class AppConsole { constructor(opts = {}) { this.spinnerConsoleCapturer = new ConsoleCapturer(); this.opts = _extends({ debug: false, traces: false }, opts); } isSpinning() { return !!this.spinner; } startSpinner(message) { if (this.spinner) { throw new Error("Spinner already started"); } this.spinner = ora({ text: message, spinner: "bouncingBar", stream: process.stdout }).start(); // Add capturing of console.log/warn/error to allow pausing // the spinner before logging and then restarting spinner after this.spinnerConsoleCapturer.onLog = (method, args) => { var _this$spinner, _this$spinner2; (_this$spinner = this.spinner) == null ? void 0 : _this$spinner.stop(); method(...args); (_this$spinner2 = this.spinner) == null ? void 0 : _this$spinner2.start(); }; this.spinnerConsoleCapturer.start(); } updateSpinner(message) { if (!this.spinner) { throw new Error("Spinner is not started"); } this.spinner.text = message; } stopSpinner(withError = false) { if (!this.spinner) { throw new Error("Spinner is not started"); } this.spinnerConsoleCapturer.stop(); this.spinner.stopAndPersist({ symbol: chalk.dim(withError ? "[== ]" : "[====]"), text: `${this.spinner.text} ${withError ? chalk.red("Error") : "Done"}` }); this.println(); this.spinner = undefined; } println(message, ...optionalParams) { console.log(message != null ? message : "", ...optionalParams); } printlnErr(message, ...optionalParams) { console.error(message != null ? message : "", ...optionalParams); } debug(message, ...optionalParams) { if (this.opts.debug) { this.println(chalk.dim(message), ...optionalParams.map(p => chalk.dim(p))); } } warn(messageOrErr) { if (messageOrErr instanceof Error) { this.printlnErr(chalk.yellowBright(` ⚠ ${messageOrErr.message}`)); if (this.opts.traces && messageOrErr.stack) { this.printlnErr(chalk.yellow(messageOrErr.stack)); this.printlnErr(); } } else { this.printlnErr(chalk.yellowBright(` ⚠ ${messageOrErr}`)); } } error(messageOrErr) { if (messageOrErr instanceof Error) { this.printlnErr(chalk.redBright(` ✖ ${messageOrErr.message}`)); if (this.opts.traces && messageOrErr.stack) { this.printlnErr(chalk.red(messageOrErr.stack)); this.printlnErr(); } } else { this.printlnErr(chalk.redBright(` ✖ ${messageOrErr}`)); } } fatal(messageOrErr) { this.printlnErr(); if (messageOrErr instanceof Error) { this.printlnErr(`${chalk.bgRed.bold(" FATAL ")} ${chalk.redBright(messageOrErr.message)}`); if (this.opts.traces && messageOrErr.stack) { this.printlnErr(); this.printlnErr(chalk.red(messageOrErr.stack)); } } else { this.printlnErr(`${chalk.bgRed.bold(" FATAL ")} ${chalk.redBright(messageOrErr)}`); } this.printlnErr(); } success(message) { this.println(chalk.greenBright(` ✔ ${message}`)); } createTable(options) { return new CliTable3(_extends({ style: { head: ["blue"] } }, options)); } printTable(table, raw = false) { if (raw) { table.forEach(value => { if (typeof value === "object" && value instanceof Array) { console.log(value.join(",")); } else { console.log(value); } }); } else { console.log(table.toString()); } } async askYesNoQuestion(question, defaultValue) { console.log(""); const answer = await inquirer.prompt([{ type: "confirm", name: "q", message: question, default: defaultValue }]); return answer.q; } async askInputQuestion(question, defaultValue) { console.log(""); const answer = await inquirer.prompt([{ type: "input", name: "q", message: question, default: defaultValue }]); return answer.q; } async askInputQuestionAndValidate(question, validationCb, defaultValue) { let answer; let valid = true; let i = 0; do { if (valid !== true) { console.log(chalk.red(`✗ Please enter a correct value${valid === false ? "" : `: ${valid}`}`)); } if (i >= 10) { throw new Error("Reached maximum number of retries (10)"); } // eslint-disable-next-line no-await-in-loop answer = await this.askInputQuestion(question, defaultValue); valid = validationCb(answer); i += 1; } while (valid !== true); return answer; } async askListQuestion(question, choices, defaultValue) { console.log(""); const answer = await inquirer.prompt([{ type: "list", name: "q", message: question, default: defaultValue, choices }]); return answer.q; } } class FailureExit extends Error { constructor() { super("The CLI exited with an error"); } } export { AppConsole, ConsoleCapturer, FailureExit }; //# sourceMappingURL=index.module.js.map