UNPKG

create-pro-ts-lib

Version:

A command-line-interface for building Typescript libraries

203 lines (172 loc) 3.98 kB
const _ = require('lodash'); const chalk = require('chalk'); const FilesManager = require('./FilesManager'); const ErrorWithCode = require('./ErrorWithCode'); const UNKNOWN_OPTION_NAME = 'UNKNOWN_OPTION_NAME'; const toYargsOptionsParam = options => options.reduce((acc, option) => { const name = option.name; const yargsSettings = option.yargsSettings; return Object.assign(acc, { [name]: yargsSettings }); }, {}); /* Handles collections for options */ class OptionsCollection { #options = []; get list() { return this.#options; } add(...options) { for (const option of options) { if (!option instanceof Option) { throw new Error('inserted Option that is not of type Option'); } if (!this.#options.find(option0 => option0.name === option.name)) { this.#options.push(option); } } return this; } addAll(options) { if (Array.isArray(options)) { this.add(...options); } return this; } remove(option) { const name = typeof option === 'string' ? option : option.name; _.remove(this.#options, option => option.name === name); return this; } #isOptionInList(option) { if (option instanceof Option) { return this.#options.includes(option); } else if (typeof option === 'string') { return !!this.#options.find( item => item.name === option || item.alias === option ); } throw new Error( `parameter "option" doesnt have a valid type: ${typeof option}` ); } includes(...options) { return options.reduce( (acc, curr) => acc && this.#isOptionInList(curr), true ); } findByName(name) { const result = this.#options.find(opt => opt.name === name); if (result === undefined) { throw new ErrorWithCode( `Could not find option name ${name}`, UNKNOWN_OPTION_NAME ); } return result; } } /** * Represents an option. */ class Option { static #initialOptions = { type: 'boolean', visible: true }; #yargsSettings = {}; #name; #initialSelected; #logic; #visible; #color; constructor(name, options = {}) { const { type, visible, color } = { ...Option.#initialOptions, ...options, }; this.#name = name; this.#yargsSettings.type = type; this.#visible = visible; this.#color = color; this.#initialSelected = false; } get yargsSettings() { return this.#yargsSettings; } get name() { return this.#name; } get logic() { if (!this.#logic) { throw new Error( `Logic not implemented in ${this.name}. Use option.setLogic(cb) to prevent this error.` ); } return this.#logic; } get initialSelected() { return this.#initialSelected; } get visible() { return this.#visible; } get color() { return this.#color; } /** * Sets an alias for option via command line * @param {string} alias */ setAlias(alias) { this.#yargsSettings.alias = alias; return this; } /** * Sets whether it is initially selected or not * @param {boolean} isSelected */ setInitialSelected(isSelected) { this.#initialSelected = isSelected; return this; } /** * Set a description for the option * @param {string} value brief description content * @returns */ setDescription(value) { this.#yargsSettings.describe = value; return this; } /** * Set a specific callback to run when the option is selected * @param {(manager: FilesManager, config: any, options:any) => void} logicFunc */ setLogic(logicFunc) { this.#logic = logicFunc; return this; } /** * Sets a color for this option * @param {string | import('chalk').Chalk} color * @returns */ setColor(color) { let colorValue = color; if (typeof color === 'string' && color.charAt(0) === '#') { colorValue = chalk.hex(color); } else if (typeof color !== 'function') { throw new Error('Color must be a chalk or kolorist color'); } this.#color = colorValue; return this; } toString() { return `Option{ ${this.name} }`; } } module.exports = { toYargsOptionsParam, Option, OptionsCollection, };