zcatalyst-cli
Version:
Command Line Tool for CATALYST
298 lines (297 loc) • 11.5 kB
JavaScript
"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _TreeNode_instances, _TreeNode_constructNodes;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TreeNode = void 0;
const ansi_colors_1 = require("ansi-colors");
const cli_cursor_1 = __importDefault(require("cli-cursor"));
const base_js_1 = __importDefault(require("inquirer/lib/prompts/base.js"));
const events_js_1 = __importDefault(require("inquirer/lib/utils/events.js"));
const paginator_js_1 = __importDefault(require("inquirer/lib/utils/paginator.js"));
const figures = {
arrowRight: '→',
arrowDown: '↓'
};
var ETreeState;
(function (ETreeState) {
ETreeState[ETreeState["OPEN"] = 1] = "OPEN";
ETreeState[ETreeState["CLOSED"] = 2] = "CLOSED";
ETreeState[ETreeState["EXPANDED"] = 3] = "EXPANDED";
})(ETreeState || (ETreeState = {}));
class TreeNode {
get indent() {
return this.level * 2;
}
constructor(root) {
_TreeNode_instances.add(this);
this.open = false;
this.leaves = [];
this.activeIdx = 0;
this.prevActiveIdx = -1;
this.nodes = [];
this.level = 1;
this.root = root;
}
addNode(node) {
if (node instanceof TreeNode) {
this.leaves.push(node);
}
else {
this.leaves.push(Object.assign({ isExpanded: false }, node));
}
return this;
}
buildTree({ paginator, force = false } = {}) {
if (this.nodes.length === 0 || force) {
__classPrivateFieldGet(this, _TreeNode_instances, "m", _TreeNode_constructNodes).call(this);
}
if (this.prevActiveIdx >= 0) {
this.nodes[this.prevActiveIdx] = (0, ansi_colors_1.stripColor)(this.nodes[this.prevActiveIdx]);
}
const activeNodeArr = this.nodes[this.activeIdx].split('\n');
this.nodes[this.activeIdx] =
(0, ansi_colors_1.cyan)((0, ansi_colors_1.stripColor)(activeNodeArr.shift() || '')) +
(activeNodeArr.length > 0 ? '\n' + activeNodeArr.join('\n') : '');
return paginator
? paginator.paginate(this.nodes.join('\n'), this.activeIdx, 3)
: this.nodes.join('\n');
}
expandNode(display, expand) {
const lineLength = process.stdout.columns -
(display.length % (process.stdout.columns - this.indent)) -
this.indent;
return (this.wrapLine('- ' + display, this.indent - 2) +
' '.repeat(lineLength) +
this.wrapLine(expand, this.indent + 2));
}
openTree(strict = false) {
const activeLeaf = this.leaves[this.activeIdx];
if (!(activeLeaf instanceof TreeNode)) {
if (!activeLeaf.expand || strict) {
return ETreeState.CLOSED;
}
this.nodes[this.activeIdx] = this.expandNode(activeLeaf.display, activeLeaf.expand);
activeLeaf.isExpanded = true;
return ETreeState.EXPANDED;
}
if (activeLeaf.leaves.length === 0) {
throw new Error('No leaves');
}
if (activeLeaf.open) {
const state = activeLeaf.openTree();
if (state === ETreeState.EXPANDED) {
const activeNode = this.nodes[this.activeIdx].split('\n')[0];
const subTree = activeLeaf.buildTree();
this.nodes[this.activeIdx] = activeNode + '\n' + subTree;
return state;
}
else if (state === ETreeState.CLOSED) {
return state;
}
}
const activeNode = this.nodes[this.activeIdx]
.split('\n')[0]
.replace(figures.arrowRight, figures.arrowDown);
activeLeaf.level = this.level + 1;
const subTree = activeLeaf.buildTree();
this.nodes[this.activeIdx] = activeNode + '\n' + subTree;
activeLeaf.open = true;
return ETreeState.OPEN;
}
closeTree() {
const activeLeaf = this.leaves[this.activeIdx];
if (!(activeLeaf instanceof TreeNode) || !activeLeaf.open) {
return;
}
const subActive = activeLeaf.leaves[activeLeaf.activeIdx];
if (subActive instanceof TreeNode && subActive.open) {
activeLeaf.closeTree();
this.nodes[this.activeIdx] = this.nodes[this.activeIdx].replace(/\n{1}[\s\S]*/m, '\n' + activeLeaf.buildTree({ force: true }));
return;
}
else if (!(subActive instanceof TreeNode) && subActive.expand && subActive.isExpanded) {
activeLeaf.nodes[activeLeaf.activeIdx] = this.wrapLine('+ ' + subActive.display, activeLeaf.indent - 2);
this.nodes[this.activeIdx] =
this.nodes[this.activeIdx].split('\n')[0] + '\n' + activeLeaf.buildTree();
subActive.isExpanded = false;
return;
}
this.nodes[this.activeIdx] = this.nodes[this.activeIdx]
.replace(figures.arrowDown, figures.arrowRight)
.replace(/\n{1}[\s\S]*/m, '');
activeLeaf.open = false;
}
moveActive(distance = 0) {
const activeLeaf = this.leaves[this.activeIdx];
if (activeLeaf instanceof TreeNode && activeLeaf.open) {
activeLeaf.moveActive(distance);
const subTree = activeLeaf.buildTree();
this.nodes[this.activeIdx] =
this.wrapLine(figures.arrowDown + ' ' + activeLeaf.root, this.indent - 2) +
'\n' +
subTree;
return;
}
const effectiveIndex = this.activeIdx + distance;
if (effectiveIndex === -1 && this.leaves.length > 1) {
this.prevActiveIdx = 0;
this.activeIdx = this.leaves.length - 1;
return;
}
else if (effectiveIndex === this.leaves.length && this.leaves.length > 1) {
this.prevActiveIdx = this.leaves.length - 1;
this.activeIdx = 0;
return;
}
else if (effectiveIndex <= -1 || effectiveIndex >= this.leaves.length) {
return;
}
this.prevActiveIdx = this.activeIdx;
this.activeIdx = effectiveIndex;
}
getValue() {
const activeLeaf = this.leaves[this.activeIdx];
if (activeLeaf instanceof TreeNode) {
return activeLeaf.getValue();
}
return activeLeaf;
}
wrapLine(line, indent) {
if (line.length <= process.stdout.columns - indent) {
return ' '.repeat(indent) + line;
}
const splitLine = line.slice(0, process.stdout.columns - indent);
return (' '.repeat(indent) +
splitLine +
this.wrapLine(line.slice(process.stdout.columns - (indent + 1)).trimStart(), indent));
}
}
exports.TreeNode = TreeNode;
_TreeNode_instances = new WeakSet(), _TreeNode_constructNodes = function _TreeNode_constructNodes() {
const nodes = this.leaves.map((leaf) => {
if (leaf instanceof TreeNode) {
const rootNode = this.wrapLine((leaf.open ? figures.arrowDown : figures.arrowRight) + ' ' + leaf.root, this.indent - 2);
const subNodes = leaf.open ? '\n' + leaf.nodes.join('\n') : '';
return rootNode + subNodes;
}
if (leaf.expand) {
return this.wrapLine('+ ' + leaf.display, this.indent - 2);
}
return this.wrapLine(leaf.display, this.indent);
});
this.nodes = nodes;
};
class InquirerTree extends base_js_1.default {
constructor(question, rl, answers) {
const questionBase = {
name: question.name,
message: question.message
};
super(questionBase, rl, answers);
this.treeOpts = {
pageSize: 10,
multiple: false,
loop: true
};
this.message = question.message;
this.choices = new TreeNode();
question.treeChoices.forEach((choice) => this.choices.addNode(choice));
this.done = () => undefined;
this.opt.default = null;
this.paginator = new paginator_js_1.default(this.screen, { isInfinite: this.treeOpts.loop !== false });
}
_run(callback) {
this.done = callback;
cli_cursor_1.default.hide();
this.bindKeyEvents();
this.render();
return this;
}
bindKeyEvents() {
const events = (0, events_js_1.default)(this.rl);
events.normalizedDownKey.subscribe(() => {
try {
this.choices.moveActive(1);
this.render();
}
catch (er) {
this.render({ error: er });
}
});
events.normalizedUpKey.subscribe(() => {
try {
this.choices.moveActive(-1);
this.render();
}
catch (er) {
this.render({ error: er });
}
});
events.line.subscribe(() => {
try {
const treeState = this.choices.openTree(true);
if (treeState === ETreeState.OPEN) {
this.render();
return;
}
const answer = this.choices.getValue();
this.render({ answer });
this.screen.done();
cli_cursor_1.default.show();
if (this.done) {
this.done(answer.value);
}
}
catch (er) {
this.render({ error: er });
}
});
events.keypress.subscribe((event) => {
try {
switch (event.key.name) {
case 'right': {
this.choices.openTree();
break;
}
case 'left': {
this.choices.closeTree();
break;
}
default: {
return;
}
}
return this.render();
}
catch (er) {
this.render({ error: er });
}
});
}
constructTree() {
this.choices.buildTree();
}
render({ answer, error } = {}) {
let message = (0, ansi_colors_1.bold)(this.message);
if (answer) {
message += ` ${(0, ansi_colors_1.cyan)(answer.short)}`;
}
else {
message += (0, ansi_colors_1.dim)(` (Use arrow keys to navigate and enter to select)`);
message += '\n' + this.choices.buildTree();
}
let bottomContent = '';
if (error) {
bottomContent = '\n' + (0, ansi_colors_1.red)('>> ') + (error instanceof Error ? error.message : error);
}
this.screen.render(message, bottomContent);
}
}
exports.default = InquirerTree;