UNPKG

zcatalyst-cli

Version:

Command Line Tool for CATALYST

298 lines (297 loc) 11.5 kB
"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;