nativescript
Version:
Command-line interface for building NativeScript projects
177 lines (176 loc) • 5.83 kB
JavaScript
;
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);