UNPKG

3.12 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _screen = require('./screen');
8
9var _color = require('./color');
10
11function linewrap(length, s) {
12 const linewrap = require('@heroku/linewrap');
13 return linewrap(length, _screen.stdtermwidth, {
14 skipScheme: 'ansi-color'
15 })(s).trim();
16}
17
18function renderList(items) {
19 const S = require('string');
20 const max = require('lodash.maxby');
21
22 let maxLength = max(items, '[0].length')[0].length;
23 let lines = items.map(i => {
24 let left = i[0];
25 let right = i[1];
26 if (!right) return left;
27 left = `${S(left).padRight(maxLength)}`;
28 right = linewrap(maxLength + 2, right);
29 return `${left} ${right}`;
30 });
31 return lines.join('\n');
32}
33
34function buildUsage(command) {
35 if (command.usage) return command.usage.trim();
36 let cmd = command.id;
37 if (!command.args) return cmd.trim();
38 let args = command.args.map(renderArg);
39 return `${cmd} ${args.join(' ')}`.trim();
40}
41
42function renderArg(arg) {
43 let name = arg.name.toUpperCase();
44 if (arg.required !== false && arg.optional !== true) return `${name}`;else return `[${name}]`;
45}
46
47class Help {
48
49 constructor(config) {
50 this.config = config;
51 }
52
53 command(cmd) {
54 let flags = Object.entries(cmd.flags || {}).filter(([name, flag]) => !flag.hidden);
55 let args = (cmd.args || []).filter(a => !a.hidden);
56 let hasFlags = flags.length ? ` ${_color.color.blue('[flags]')}` : '';
57 let usage = `${_color.color.bold('Usage:')} ${this.config.bin} ${buildUsage(cmd)}${hasFlags}\n`;
58 return [usage, cmd.description ? `\n${_color.color.bold(cmd.description.trim())}\n` : '', this.renderAliases(cmd.aliases), this.renderArgs(args), this.renderFlags(flags), cmd.help ? `\n${cmd.help.trim()}\n` : ''].join('');
59 }
60
61 commandLine(cmd) {
62 return [buildUsage(cmd), cmd.description ? _color.color.dim(cmd.description) : null];
63 }
64
65 renderAliases(aliases) {
66 if (!aliases || !aliases.length) return '';
67 let a = aliases.map(a => ` $ ${this.config.bin} ${a}`).join('\n');
68 return `\n${_color.color.blue('Aliases:')}\n${a}\n`;
69 }
70
71 renderArgs(args) {
72 if (!args.find(f => f.description)) return '';
73 return '\n' + renderList(args.map(a => {
74 return [a.name.toUpperCase(), a.description ? _color.color.dim(a.description) : null];
75 })) + '\n';
76 }
77
78 renderFlags(flags) {
79 if (!flags.length) return '';
80 flags.sort((a, b) => {
81 if (a[1].char && !b[1].char) return -1;
82 if (b[1].char && !a[1].char) return 1;
83 if (a[0] < b[0]) return -1;
84 return b[0] < a[0] ? 1 : 0;
85 });
86 return `\n${_color.color.blue('Flags:')}\n` + renderList(flags.map(([name, f]) => {
87 let label = [];
88 if (f.char) label.push(`-${f.char}`);
89 if (name) label.push(` --${name}`);
90 let usage = f.parse ? ` ${name.toUpperCase()}` : '';
91 let description = f.description || '';
92 if (f.required || f.optional === false) description = `(required) ${description}`;
93 return [` ${label.join(',').trim()}` + usage, description ? _color.color.dim(description) : null];
94 })) + '\n';
95 }
96}
97exports.default = Help;
\No newline at end of file