argumental
Version:
Framework for building CLI apps with Node.js
296 lines • 27.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = void 0;
const chalk_1 = __importDefault(require("chalk"));
const lodash_1 = __importDefault(require("lodash"));
class Logger {
constructor() {
this.PADDING = 3;
/** Detected application name. */
this._appName = null;
/** Controls colored logging. */
this._colors = true;
/** Holds custom help renderer function. */
this._customHelp = null;
}
/**
* Returns the options signature of a command.
* @param command A command definition.
*/
_getOptionsSignature(command) {
for (const option of command.options) {
if (option.required)
return `<options>`;
}
return chalk_1.default.italic('[options]');
}
/**
* Returns a list of named argument signatures.
* @param command A command definition.
*/
_getArgumentsSignatureList(command) {
const list = [];
for (const argument of command.arguments) {
if (argument.required)
list.push(`<${argument.rest ? '...' : ''}${argument.name}>`);
else
list.push(chalk_1.default.italic(`[${argument.rest ? '...' : ''}${argument.name}]`));
}
return list;
}
/**
* Determines if any arguments are defined for any command.
* @param definitions List of command declarations.
*/
_doArgumentsExist(definitions) {
for (const commandName in definitions) {
if (definitions[commandName].arguments.length)
return true;
}
return false;
}
/**
* Returns the longest string length.
* @param strings Array of strings.
*/
_getLongest(strings) {
return Math.max(...strings.map(str => str.length));
}
/**
* Returns padding based on logger configuration and level.
* @param level The padding level.
*/
_pad(level = 1) {
return ' '.repeat(this.PADDING * level);
}
/**
* Returns option syntax from definition.
* @param option The option definition.
*/
_getOptionSyntax(option) {
const syntax = {};
const segments = [];
if (option.shortName) {
syntax.short = `-${option.shortName}`;
segments.push(syntax.short);
}
if (option.longName) {
syntax.long = `--${option.longName}`;
segments.push(syntax.long);
}
if (option.argument) {
syntax.arg = `${option.argument.required ? '<name>' : '[name]'}`.replace('name', option.argument.name);
segments.push(syntax.arg);
}
syntax.full = segments.join(' ');
return syntax;
}
/**
* Determines if command has any multi options.
* @param command The command definition.
*/
_hasMultiOption(command) {
for (const option of command.options) {
if (option.multi)
return true;
}
return false;
}
/**
* Determines whether requirements differ between components (option declarations, argument declarations, etc.).
* @param components An array of components.
*/
_doesRequirementsDiffer(components) {
let lastRequirement = undefined;
for (const component of components) {
if (lastRequirement === undefined) {
lastRequirement = component.required;
continue;
}
if (component.required !== lastRequirement)
return true;
}
return false;
}
/**
* Determines if there are any required declarations in a set of components (option declarations, argument declarations, etc.).
* @param components An array of components.
*/
_anyRequired(components) {
for (const component of components) {
if (component.required)
return true;
}
return false;
}
/** Application name setter. */
set appName(name) {
this._appName = name;
}
/** Log colors setter. */
set colors(value) {
this._colors = value;
}
/** Custom help renderer function setter. */
set customHelpRenderer(renderer) {
this._customHelp = renderer;
}
/**
* Logs an error.
* @param messages An array of string and/or error messages.
*/
error(...messages) {
// Set colors
let chalkOptions;
if (!this._colors)
chalkOptions = { level: 0 };
let color = new chalk_1.default.Instance(chalkOptions);
console.log('');
console.error(...messages
.map(message => color.redBright.bold(message instanceof Error ? this._pad() + message.message : this._pad() + message))
.concat(`\n${this._pad()}Run ${color.bold(`${this._appName + ' ' || ''}--help`)} to display usage info`));
console.log('');
}
/**
* Displays application help in the console.
* @param definitions Command definitions list.
* @param cmd The invoked command name.
*/
help(definitions, cmd) {
// If custom help renderer provided
if (this._customHelp)
return this._customHelp(lodash_1.default.cloneDeep(definitions), cmd);
// Set colors
let chalkOptions;
if (!this._colors)
chalkOptions = { level: 0 };
let color = new chalk_1.default.Instance(chalkOptions);
// Determine top-level usage signature
let topLevelOnly = lodash_1.default.keys(definitions).length === 1;
let usageSection, usageDescription, commandsSection, argumentsSection, optionsSection;
// Render usage section
usageSection = color.white.bold('USAGE: ');
// If top-level
if (cmd === '') {
let segments = [];
if (this._appName)
segments.push(this._appName);
// Generic signature
if (definitions[''].original) {
if (!topLevelOnly)
segments.push(color.blueBright('<command>'));
if (this._doArgumentsExist(definitions))
segments.push(color.magenta(`<arguments>`));
segments.push(color.yellow.italic('[options]'));
}
// Top-level specific signature
else {
segments = segments.concat(this._getArgumentsSignatureList(definitions['']).map(sig => color.magenta(sig)));
segments.push(color.yellow(this._getOptionsSignature(definitions[''])));
}
usageSection += segments.join(' ');
}
// Command level
else {
let segments = [];
if (this._appName)
segments.push(this._appName);
segments.push(color.blueBright(cmd));
segments = segments.concat(this._getArgumentsSignatureList(definitions[cmd]).map(sig => color.magenta(sig)));
segments.push(color.yellow(this._getOptionsSignature(definitions[cmd])));
usageSection += segments.join(' ');
}
// Render top-level description
if (cmd === '' && !definitions[''].original && definitions[''].description) {
usageDescription = definitions[''].description;
}
else if (cmd !== '' && definitions[cmd].description) {
usageDescription = definitions[cmd].description;
}
// Render commands section
if (cmd === '' && !topLevelOnly) {
commandsSection = color.white.bold('COMMANDS:\n\n');
// Display command-specific usage (if usage was not generic)
if (!definitions[''].original) {
const segments = [color.white.bold('USAGE:')];
if (this._appName)
segments.push(this._appName);
segments.push(color.blueBright('<command>'));
if (this._doArgumentsExist(definitions))
segments.push(color.magenta(`<arguments>`));
segments.push(color.yellow.italic('[options]'));
commandsSection += `${this._pad(2)}${segments.join(' ')}\n\n`;
}
const longest = this._getLongest(lodash_1.default.keys(definitions).map(name => [name, ...definitions[name].aliases].join('|')));
for (const command of lodash_1.default.values(definitions).sort((a, b) => a.order - b.order)) {
if (command.name === '')
continue;
const commandRightPad = ' '.repeat(longest - [command.name, ...command.aliases].join('|').length);
const coloredSyntax = [color.blueBright(command.name), ...command.aliases.map(alias => color.blueBright(alias))].join(color.dim('|'));
// Command name
commandsSection += `${this._pad(2)}${coloredSyntax}${commandRightPad}`;
// Command description
if (command.description)
commandsSection += `${this._pad()}${command.description}`;
commandsSection += '\n';
}
}
// Render arguments section
// If not generic top-level
if ((cmd !== '' || !definitions[''].original) && definitions[cmd].arguments.length) {
argumentsSection = color.white.bold('ARGUMENTS:\n\n');
const longest = this._getLongest(definitions[cmd].arguments.map(arg => arg.name));
const requirementsDiffer = this._doesRequirementsDiffer(definitions[cmd].arguments);
for (const argument of definitions[cmd].arguments) {
// Argument name
argumentsSection += `${this._pad(2)}${color.magenta((argument.rest ? '...' : '') + argument.name.padEnd(longest - (argument.rest ? 3 : 0)))}`;
// Argument requirement
if (requirementsDiffer)
argumentsSection += `${this._pad()}${argument.required ? color.bold('required') : color.italic.dim('optional')}`;
// Argument description
if (argument.description)
argumentsSection += `${this._pad()}${argument.description}`;
argumentsSection += '\n';
}
}
// Render options section
optionsSection = color.white.bold('OPTIONS:\n\n');
const longest = this._getLongest(definitions[cmd].options.map(opt => this._getOptionSyntax(opt).full));
const anyMulti = this._hasMultiOption(definitions[cmd]);
const anyRequired = this._anyRequired(definitions[cmd].options);
for (const option of definitions[cmd].options) {
// Option syntax
const syntax = this._getOptionSyntax(option);
const syntaxRightPad = ' '.repeat(longest - syntax.full.length);
optionsSection += `${this._pad(2)}${syntax.short ? color.yellow(syntax.short) + ' ' : ''}${syntax.long ? color.yellow(syntax.long) + ' ' : ''}${syntax.arg ? color.magenta(syntax.arg) + ' ' : ''}${syntaxRightPad}`;
optionsSection = optionsSection.substr(0, optionsSection.length - 1);
// Option requirement
if (anyRequired)
optionsSection += `${this._pad()}${option.required ? color.bold('required') : color.italic.dim('optional')}`;
// Option repeatable (multi)
if (anyMulti)
optionsSection += `${this._pad()}${option.multi ? color.greenBright('repeatable') : ' '}`;
// Option description
if (option.description)
optionsSection += `${this._pad()}${option.description}`;
optionsSection += '\n';
}
console.log('\n');
console.log(`${this._pad()}${usageSection}\n`);
if (usageDescription)
console.log(`${this._pad()}${usageDescription}\n`);
if (commandsSection)
console.log(`${this._pad()}${commandsSection}`);
if (argumentsSection)
console.log(`${this._pad()}${argumentsSection}`);
console.log(`${this._pad()}${optionsSection}`);
if (!topLevelOnly && cmd === '')
console.log(`${this._pad()}Run ${this._appName ? this._appName + ' ' : ''}${color.blueBright('<command>')} ${color.yellow('--help')} to view command-specific help.\n`);
console.log('');
}
}
exports.Logger = Logger;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6InNyYy8iLCJzb3VyY2VzIjpbImxpYi9sb2dnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsa0RBQTBCO0FBQzFCLG9EQUF1QjtBQUd2QixNQUFhLE1BQU07SUFBbkI7UUFFbUIsWUFBTyxHQUFXLENBQUMsQ0FBQztRQUNyQyxpQ0FBaUM7UUFDekIsYUFBUSxHQUFXLElBQUksQ0FBQztRQUNoQyxnQ0FBZ0M7UUFDeEIsWUFBTyxHQUFZLElBQUksQ0FBQztRQUNoQywyQ0FBMkM7UUFDbkMsZ0JBQVcsR0FBYSxJQUFJLENBQUM7SUF3WXZDLENBQUM7SUF0WUM7OztNQUdFO0lBQ00sb0JBQW9CLENBQUMsT0FBc0M7UUFFakUsS0FBTSxNQUFNLE1BQU0sSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFHO1lBRXRDLElBQUssTUFBTSxDQUFDLFFBQVE7Z0JBQUcsT0FBTyxXQUFXLENBQUM7U0FFM0M7UUFFRCxPQUFPLGVBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFbkMsQ0FBQztJQUVEOzs7TUFHRTtJQUNNLDBCQUEwQixDQUFDLE9BQXNDO1FBRXZFLE1BQU0sSUFBSSxHQUFhLEVBQUUsQ0FBQztRQUUxQixLQUFNLE1BQU0sUUFBUSxJQUFJLE9BQU8sQ0FBQyxTQUFTLEVBQUc7WUFFMUMsSUFBSyxRQUFRLENBQUMsUUFBUTtnQkFBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsUUFBUSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7O2dCQUNqRixJQUFJLENBQUMsSUFBSSxDQUFDLGVBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUMsSUFBSSxHQUFHLENBQUMs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