UNPKG

zcatalyst-cli

Version:

Command Line Tool for CATALYST

282 lines (281 loc) 11 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const chalk_1 = __importDefault(require("chalk")); const cli_cursor_1 = __importDefault(require("cli-cursor")); const figures_1 = __importDefault(require("figures")); const choices_1 = __importDefault(require("inquirer/lib/objects/choices")); const base_1 = __importDefault(require("inquirer/lib/prompts/base")); const events_1 = __importDefault(require("inquirer/lib/utils/events")); const paginator_1 = __importDefault(require("inquirer/lib/utils/paginator")); const operators_1 = require("rxjs/operators"); class SearchBox extends base_1.default { constructor(questions, rl, answers) { super(questions, rl, answers); this.pointer = 0; if (this.opt.highlight == null) { this.opt.highlight = false; } if (typeof this.opt.searchable == null) { this.opt.searchable = false; } if (typeof this.opt.default == null) { this.opt.default = undefined; } if (this.opt.source == null) { this.throwParamError('source'); } if (this.opt.notFoundMsg === undefined) { this.opt.notFoundMsg = 'No results...'; } if (this.opt.searchMsg === undefined) { this.opt.searchMsg = 'Searching...'; } this.pointer = 0; this.firstSourceLoading = true; this.choices = new choices_1.default([], answers); this.checkedChoices = []; this.value = []; this.lastQuery = undefined; this.searching = false; this.lastSourcePromise = undefined; this.default = this.opt.default; this.opt.default = undefined; this.selection = []; this.done = undefined; this.paginator = new paginator_1.default(this.screen); } _run(callback) { this.done = callback; this.executeSource().then(() => { const events = (0, events_1.default)(this.rl); const validation = this.handleSubmitEvents(events.line.pipe((0, operators_1.map)(this.getCurrentValue.bind(this)))); validation.success.forEach(this.onEnd.bind(this)); validation.error.forEach(this.onError.bind(this)); events.normalizedUpKey .pipe((0, operators_1.takeUntil)(validation.success)) .forEach(this.onUpKey.bind(this)); events.normalizedDownKey .pipe((0, operators_1.takeUntil)(validation.success)) .forEach(this.onDownKey.bind(this)); events.spaceKey.pipe((0, operators_1.takeUntil)(validation.success)).forEach(this.onSpaceKey.bind(this)); if (this.opt.searchable === false) { events.numberKey .pipe((0, operators_1.takeUntil)(validation.success)) .forEach(this.onNumberKey.bind(this)); events.aKey.pipe((0, operators_1.takeUntil)(validation.success)).forEach(this.onAllKey.bind(this)); events.iKey .pipe((0, operators_1.takeUntil)(validation.success)) .forEach(this.onInverseKey.bind(this)); } else { events.keypress .pipe((0, operators_1.takeUntil)(validation.success)) .forEach(this.onKeypress.bind(this)); } if (this.rl.line) { this.onKeypress(); } cli_cursor_1.default.hide(); this.render(); }); return this; } getValue(choice) { if (choice.type === 'separator') { return undefined; } return choice.value; } executeSource() { let sourcePromise; this.rl.line = this.rl.line.trim(); if (this.rl.line === this.lastQuery) { return Promise.resolve(undefined); } if (this.opt.searchable) { sourcePromise = this.opt.source(this.answers, this.rl.line); } else { sourcePromise = this.opt.source(this.answers, undefined); } this.lastQuery = this.rl.line; this.lastSourcePromise = sourcePromise; this.searching = true; sourcePromise.then((choices) => { if (this.lastSourcePromise !== sourcePromise) { return; } this.searching = false; this.choices = new choices_1.default(choices, this.answers); this.choices.forEach((choice) => { var _a; if (this.value.some((eachValue) => this.getValue(choice) === eachValue)) { this.toggleChoice(choice, true); } else { this.toggleChoice(choice, false); } if (this.default !== null) { if ((_a = this.default) === null || _a === void 0 ? void 0 : _a.some((defaultValue) => this.getValue(choice) === defaultValue)) { this.toggleChoice(choice, true); } } }); this.pointer = 0; this.render(); this.default = undefined; this.firstSourceLoading = false; }); return sourcePromise; } render(error) { let message = this.getQuestion(); let bottomContent = ''; if (this.status === 'answered') { message += chalk_1.default.cyan(this.selection.join(', ')); return this.screen.render(message, bottomContent); } if (this.firstSourceLoading) { if (this.opt.searchable) { message += `(Press ${chalk_1.default.cyan.bold('<space>')} to select, or type anything to filter the list)`; } else { message += `(Press ${chalk_1.default.cyan.bold('<space>')} to select, ${chalk_1.default.cyan.bold('<a>')} to toggle all, ${chalk_1.default.cyan.bold('<i>')} to invert selection)`; } } if (this.opt.searchable) { message += this.rl.line; } if (this.searching) { message += `\n ${chalk_1.default.cyan(this.opt.searchMsg)}`; } else if (!this.choices.length) { message += `\n ${chalk_1.default.yellow(this.opt.notFoundMsg)}`; } else { const choicesStr = this.renderChoices(this.choices, this.pointer); const choice = this.choices.getChoice(this.pointer); const indexPosition = this.choices.indexOf(choice); message += `\n${this.paginator.paginate(choicesStr, indexPosition, this.opt.pageSize)}`; } if (error) { bottomContent = chalk_1.default.red('>> ') + error; } return this.screen.render(message, bottomContent); } onEnd(state) { var _a; this.status = 'answered'; this.render(); this.screen.done(); cli_cursor_1.default.show(); (_a = this.done) === null || _a === void 0 ? void 0 : _a.call(this, 'value' in state ? state.value : undefined); } onError(state) { if (state.isValid) { this.render(); } } getCurrentValue() { this.selection = this.checkedChoices.map((checkedChoice) => checkedChoice.short); const values = this.checkedChoices.map((checkedChoice) => checkedChoice.value); return values; } onUpKey() { const len = this.choices.realLength; this.pointer = this.pointer > 0 ? this.pointer - 1 : len - 1; this.render(); } onDownKey() { const len = this.choices.realLength; this.pointer = this.pointer < len - 1 ? this.pointer + 1 : 0; this.render(); } onNumberKey(input) { if (input <= this.choices.realLength) { this.pointer = input - 1; this.toggleChoice(this.choices.getChoice(this.pointer)); } this.render(); } onSpaceKey() { if (this.choices.getChoice(this.pointer) == null) { return; } this.toggleChoice(this.choices.getChoice(this.pointer)); this.render(); } onAllKey() { const shouldBeChecked = Boolean(this.choices.find((choice) => { return choice.type !== 'separator' && !choice.checked; })); this.choices.forEach((choice) => { if (choice.type !== 'separator') { choice.checked = shouldBeChecked; } return choice; }); this.render(); } onInverseKey() { this.choices.forEach((choice) => { if (choice.type !== 'separator') { choice.checked = !choice.checked; } }); this.render(); } onKeypress() { this.executeSource(); this.render(); } toggleChoice(choice, nextChecked) { var _a; if (choice.type === 'separator') { return; } const checked = nextChecked == null ? !((_a = choice.checked) !== null && _a !== void 0 ? _a : false) : nextChecked; this.value = this.value.filter((eachValue) => eachValue !== choice.value); this.checkedChoices = this.checkedChoices.filter((checkedChoice) => checkedChoice.value !== choice.value); choice.checked = false; if (checked === true) { this.value.push(choice.value); this.checkedChoices.push(choice); choice.checked = true; } } static getCheckboxFigure(checked = false) { return checked ? chalk_1.default.green(figures_1.default.radioOn) : figures_1.default.radioOff; } renderChoices(choices, pointer) { const output = []; let separatorOffset = 0; choices.forEach((choice, index) => { if (choice.type === 'separator') { separatorOffset += 1; output.push(` ${choice}\n`); return; } if (choice.disabled) { separatorOffset += 1; output.push(` - ${choice.name} (${typeof choice.disabled === 'string' ? choice.disabled : 'Disabled'})\n`); return; } if (index - separatorOffset === pointer) { output.push(chalk_1.default.cyan(figures_1.default.pointer)); output.push(SearchBox.getCheckboxFigure(choice.checked)); output.push(' '); output.push(this.opt.highlight ? chalk_1.default.gray(choice.name) : choice.name); } else { output.push(` ${SearchBox.getCheckboxFigure(choice.checked)} ${choice.name}`); } output.push('\n'); }); return output.join('').replace(/\n$/, ''); } } exports.default = SearchBox;