UNPKG

nativescript

Version:

Command-line interface for building NativeScript projects

177 lines (176 loc) • 5.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Prompter = void 0; const prompt = require("prompts"); const helpers = require("./helpers"); const readline = require("readline"); const yok_1 = require("./yok"); const MuteStream = require("mute-stream"); const _ = require("lodash"); class Prompter { constructor() { this.muteStreamInstance = null; } dispose() { if (this.ctrlcReader) { this.ctrlcReader.close(); } } async get(questions) { try { this.muteStdout(); if (!helpers.isInteractive()) { if (_.some(questions, (s) => !s.default)) { throw new Error("Console is not interactive and no default action specified."); } else { const result = {}; _.each(questions, (s) => { result[s.name] = s.default(); }); return result; } } else { const result = await prompt.prompt(questions); return result; } } finally { this.unmuteStdout(); } } async getPassword(message, options) { const schema = { message, type: "password", name: "password", validate: (value) => { const allowEmpty = options && options.allowEmpty; return !allowEmpty && !value ? "Password must be non-empty" : true; }, }; const result = await this.get([schema]); return result.password; } async getString(message, options) { const schema = { message, type: "text", name: "inputString", validate: (value) => { const doesNotAllowEmpty = options && _.has(options, "allowEmpty") && !options.allowEmpty; return doesNotAllowEmpty && !value ? `${message} must be non-empty` : true; }, default: options && options.defaultAction, }; const result = await this.get([schema]); return result.inputString; } async promptForChoice(promptMessage, choices, multiple = false, options = {}) { const schema = { message: promptMessage, type: multiple ? "multiselect" : "select", name: "userAnswer", choices, ...options, }; const result = await this.get([schema]); const extractValue = (choice) => { if (typeof choice === "object") { return choice.value || choice; } if (typeof choice === "string") { return choice; } if (typeof choice === "number") { return choices[choice]; } }; return multiple ? result.userAnswer.map(extractValue) : extractValue(result.userAnswer); } async promptForDetailedChoice(promptMessage, choices) { const inquirerChoices = choices.map((choice) => { return { title: choice.key, value: choice.key, description: choice.description, }; }); const schema = { message: promptMessage, type: "select", name: "userAnswer", choices: inquirerChoices, }; const result = await this.get([schema]); return result.userAnswer; } async confirm(message, defaultAction) { const schema = { type: "confirm", name: "prompt", default: defaultAction, message, }; const result = await this.get([schema]); return result.prompt; } muteStdout() { if (helpers.isInteractive()) { process.stdin.setRawMode(true); this.muteStreamInstance = new MuteStream(); this.muteStreamInstance.pipe(process.stdout); this.muteStreamInstance.mute(); this.ctrlcReader = readline.createInterface({ input: process.stdin, output: this.muteStreamInstance, }); this.ctrlcReader.on("SIGINT", () => { process.stdout.write("\x1B[?25h"); process.exit(); }); } } unmuteStdout() { if (helpers.isInteractive()) { process.stdin.setRawMode(false); if (this.muteStreamInstance) { this.cleanEventListeners(process.stdout); this.muteStreamInstance.unmute(); this.muteStreamInstance = null; this.dispose(); } } } cleanEventListeners(stream) { const memoryLeakEvents = [ { eventName: "close", listenerName: "cleanup", }, { eventName: "error", listenerName: "onerror", }, { eventName: "drain", listenerName: "ondrain", }, ]; _.each(memoryLeakEvents, (memoryleakEvent) => this.cleanListener(stream, memoryleakEvent.eventName, memoryleakEvent.listenerName)); } cleanListener(stream, eventName, listenerName) { const eventListeners = process.stdout.listeners(eventName); const listenerFunction = _.find(eventListeners, (func) => func.name === listenerName); if (listenerFunction) { stream.removeListener(eventName, listenerFunction); } } } exports.Prompter = Prompter; yok_1.injector.register("prompter", Prompter);