UNPKG

5.5 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const chalk_1 = require("chalk");
4const indent = require("indent-string");
5const stripAnsi = require("strip-ansi");
6const list_1 = require("./list");
7const util_1 = require("./util");
8const { underline, bold, } = chalk_1.default;
9let { dim, } = chalk_1.default;
10if (process.env.ConEmuANSI === 'ON') {
11 dim = chalk_1.default.gray;
12}
13const wrap = require('wrap-ansi');
14class CommandHelp {
15 constructor(command, config, opts) {
16 this.command = command;
17 this.config = config;
18 this.opts = opts;
19 this.render = util_1.template(this);
20 }
21 generate() {
22 const cmd = this.command;
23 const flags = util_1.sortBy(Object.entries(cmd.flags || {})
24 .filter(([, v]) => !v.hidden)
25 .map(([k, v]) => {
26 v.name = k;
27 return v;
28 }), f => [!f.char, f.char, f.name]);
29 const args = (cmd.args || []).filter(a => !a.hidden);
30 let output = util_1.compact([
31 this.usage(flags),
32 this.args(args),
33 this.flags(flags),
34 this.description(),
35 this.aliases(cmd.aliases),
36 this.examples(cmd.examples || cmd.example),
37 ]).join('\n\n');
38 if (this.opts.stripAnsi)
39 output = stripAnsi(output);
40 return output;
41 }
42 usage(flags) {
43 const usage = this.command.usage;
44 const body = (usage ? util_1.castArray(usage) : [this.defaultUsage(flags)])
45 .map(u => `$ ${this.config.bin} ${u}`.trim())
46 .join('\n');
47 return [
48 bold('USAGE'),
49 indent(wrap(this.render(body), this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
50 ].join('\n');
51 }
52 defaultUsage(_) {
53 return util_1.compact([
54 this.command.id,
55 this.command.args.filter(a => !a.hidden).map(a => this.arg(a)).join(' '),
56 ]).join(' ');
57 }
58 description() {
59 const cmd = this.command;
60 const description = cmd.description && this.render(cmd.description).split('\n').slice(1).join('\n');
61 if (!description)
62 return;
63 return [
64 bold('DESCRIPTION'),
65 indent(wrap(description.trim(), this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
66 ].join('\n');
67 }
68 aliases(aliases) {
69 if (!aliases || aliases.length === 0)
70 return;
71 const body = aliases.map(a => ['$', this.config.bin, a].join(' ')).join('\n');
72 return [
73 bold('ALIASES'),
74 indent(wrap(body, this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
75 ].join('\n');
76 }
77 examples(examples) {
78 if (!examples || examples.length === 0)
79 return;
80 const body = util_1.castArray(examples).map(a => this.render(a)).join('\n');
81 return [
82 bold('EXAMPLE' + (examples.length > 1 ? 'S' : '')),
83 indent(wrap(body, this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
84 ].join('\n');
85 }
86 args(args) {
87 if (args.filter(a => a.description).length === 0)
88 return;
89 const body = list_1.renderList(args.map(a => {
90 const name = a.name.toUpperCase();
91 let description = a.description || '';
92 if (a.default)
93 description = `[default: ${a.default}] ${description}`;
94 if (a.options)
95 description = `(${a.options.join('|')}) ${description}`;
96 return [name, description ? dim(description) : undefined];
97 }), { stripAnsi: this.opts.stripAnsi, maxWidth: this.opts.maxWidth - 2 });
98 return [
99 bold('ARGUMENTS'),
100 indent(body, 2),
101 ].join('\n');
102 }
103 arg(arg) {
104 const name = arg.name.toUpperCase();
105 if (arg.required)
106 return `${name}`;
107 return `[${name}]`;
108 }
109 flags(flags) {
110 if (flags.length === 0)
111 return;
112 const body = list_1.renderList(flags.map(flag => {
113 let left = flag.helpLabel;
114 if (!left) {
115 const label = [];
116 if (flag.char)
117 label.push(`-${flag.char[0]}`);
118 if (flag.name) {
119 if (flag.type === 'boolean' && flag.allowNo) {
120 label.push(`--[no-]${flag.name.trim()}`);
121 }
122 else {
123 label.push(`--${flag.name.trim()}`);
124 }
125 }
126 left = label.join(', ');
127 }
128 if (flag.type === 'option') {
129 let value = flag.helpValue || flag.name;
130 if (!flag.helpValue && flag.options) {
131 value = flag.options.join('|');
132 }
133 if (!value.includes('|'))
134 value = underline(value);
135 left += `=${value}`;
136 }
137 let right = flag.description || '';
138 if (flag.type === 'option' && flag.default) {
139 right = `[default: ${flag.default}] ${right}`;
140 }
141 if (flag.required)
142 right = `(required) ${right}`;
143 return [left, dim(right.trim())];
144 }), { stripAnsi: this.opts.stripAnsi, maxWidth: this.opts.maxWidth - 2 });
145 return [
146 bold('OPTIONS'),
147 indent(body, 2),
148 ].join('\n');
149 }
150}
151exports.default = CommandHelp;