@oclif/core 3.0.0-beta.17 → 3.0.0-beta.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/args.js +4 -4
- package/lib/cli-ux/action/base.js +8 -7
- package/lib/cli-ux/action/simple.js +1 -4
- package/lib/cli-ux/action/spinner.js +8 -7
- package/lib/cli-ux/action/spinners.js +1 -1
- package/lib/cli-ux/config.js +11 -12
- package/lib/cli-ux/exit.js +3 -0
- package/lib/cli-ux/flush.js +7 -6
- package/lib/cli-ux/index.js +2 -2
- package/lib/cli-ux/list.js +3 -3
- package/lib/cli-ux/prompt.js +8 -3
- package/lib/cli-ux/stream.js +1 -0
- package/lib/cli-ux/styled/json.js +5 -3
- package/lib/cli-ux/styled/object.js +2 -2
- package/lib/cli-ux/styled/table.js +26 -20
- package/lib/cli-ux/styled/tree.js +1 -3
- package/lib/cli-ux/wait.js +1 -1
- package/lib/command.d.ts +6 -14
- package/lib/command.js +86 -73
- package/lib/config/config.d.ts +8 -9
- package/lib/config/config.js +85 -199
- package/lib/config/index.d.ts +0 -1
- package/lib/config/index.js +1 -3
- package/lib/config/plugin-loader.js +12 -11
- package/lib/config/plugin.d.ts +1 -0
- package/lib/config/plugin.js +54 -34
- package/lib/config/ts-node.js +17 -13
- package/lib/config/util.d.ts +0 -6
- package/lib/config/util.js +3 -15
- package/lib/errors/errors/cli.js +4 -1
- package/lib/errors/errors/exit.js +1 -1
- package/lib/errors/errors/module-load.js +1 -1
- package/lib/errors/errors/pretty-print.js +2 -1
- package/lib/errors/handle.js +4 -3
- package/lib/errors/logger.js +5 -4
- package/lib/flags.d.ts +6 -6
- package/lib/flags.js +3 -3
- package/lib/help/command.js +46 -32
- package/lib/help/docopts.js +8 -5
- package/lib/help/formatter.js +19 -8
- package/lib/help/index.d.ts +5 -1
- package/lib/help/index.js +70 -49
- package/lib/help/root.js +7 -9
- package/lib/help/util.d.ts +1 -7
- package/lib/help/util.js +2 -22
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -3
- package/lib/interfaces/hooks.d.ts +3 -3
- package/lib/interfaces/index.d.ts +1 -1
- package/lib/interfaces/parser.d.ts +19 -18
- package/lib/interfaces/pjson.d.ts +1 -1
- package/lib/interfaces/plugin.d.ts +5 -0
- package/lib/module-loader.d.ts +8 -8
- package/lib/module-loader.js +13 -10
- package/lib/parser/errors.d.ts +1 -1
- package/lib/parser/errors.js +15 -9
- package/lib/parser/help.js +2 -3
- package/lib/parser/parse.js +72 -44
- package/lib/parser/validate.js +37 -21
- package/lib/performance.js +20 -9
- package/lib/util/aggregate-flags.d.ts +2 -0
- package/lib/util/aggregate-flags.js +13 -0
- package/lib/util/cache-command.d.ts +3 -0
- package/lib/util/cache-command.js +108 -0
- package/lib/util/cache-default-value.d.ts +2 -0
- package/lib/util/cache-default-value.js +28 -0
- package/lib/{util.d.ts → util/index.d.ts} +7 -2
- package/lib/{util.js → util/index.js} +15 -20
- package/package.json +19 -13
package/lib/help/command.js
CHANGED
|
@@ -11,12 +11,15 @@ const strip_ansi_1 = tslib_1.__importDefault(require("strip-ansi"));
|
|
|
11
11
|
// written on any platform, that may use \r\n or \n, will be
|
|
12
12
|
// split on any platform, not just the os specific EOL at runtime.
|
|
13
13
|
const POSSIBLE_LINE_FEED = /\r\n|\n/;
|
|
14
|
-
let { dim
|
|
14
|
+
let { dim } = chalk_1.default;
|
|
15
15
|
if (process.env.ConEmuANSI === 'ON') {
|
|
16
16
|
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
17
17
|
dim = chalk_1.default.gray;
|
|
18
18
|
}
|
|
19
19
|
class CommandHelp extends formatter_1.HelpFormatter {
|
|
20
|
+
command;
|
|
21
|
+
config;
|
|
22
|
+
opts;
|
|
20
23
|
constructor(command, config, opts) {
|
|
21
24
|
super(config, opts);
|
|
22
25
|
this.command = command;
|
|
@@ -30,13 +33,15 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
30
33
|
.map(([k, v]) => {
|
|
31
34
|
v.name = k;
|
|
32
35
|
return v;
|
|
33
|
-
}), f => [!f.char, f.char, f.name]);
|
|
34
|
-
const args = Object.values((0, util_1.ensureArgObject)(cmd.args)).filter(a => !a.hidden);
|
|
36
|
+
}), (f) => [!f.char, f.char, f.name]);
|
|
37
|
+
const args = Object.values((0, util_1.ensureArgObject)(cmd.args)).filter((a) => !a.hidden);
|
|
35
38
|
const output = (0, util_1.compact)(this.sections().map(({ header, generate }) => {
|
|
36
39
|
const body = generate({ cmd, flags, args }, header);
|
|
37
40
|
// Generate can return a list of sections
|
|
38
41
|
if (Array.isArray(body)) {
|
|
39
|
-
return body
|
|
42
|
+
return body
|
|
43
|
+
.map((helpSection) => helpSection && helpSection.body && this.section(helpSection.header, helpSection.body))
|
|
44
|
+
.join('\n\n');
|
|
40
45
|
}
|
|
41
46
|
return body && this.section(header, body);
|
|
42
47
|
})).join('\n\n');
|
|
@@ -108,13 +113,14 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
108
113
|
usage() {
|
|
109
114
|
const { usage } = this.command;
|
|
110
115
|
const body = (usage ? (0, util_1.castArray)(usage) : [this.defaultUsage()])
|
|
111
|
-
.map(u => {
|
|
116
|
+
.map((u) => {
|
|
112
117
|
const allowedSpacing = this.opts.maxWidth - this.indentSpacing;
|
|
113
118
|
const line = `$ ${this.config.bin} ${u}`.trim();
|
|
114
119
|
if (line.length > allowedSpacing) {
|
|
115
120
|
const splitIndex = line.slice(0, Math.max(0, allowedSpacing)).lastIndexOf(' ');
|
|
116
|
-
return line.slice(0, Math.max(0, splitIndex)) +
|
|
117
|
-
+
|
|
121
|
+
return (line.slice(0, Math.max(0, splitIndex)) +
|
|
122
|
+
'\n' +
|
|
123
|
+
this.indent(this.wrap(line.slice(Math.max(0, splitIndex)), this.indentSpacing * 2)));
|
|
118
124
|
}
|
|
119
125
|
return this.wrap(line);
|
|
120
126
|
})
|
|
@@ -128,7 +134,10 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
128
134
|
}
|
|
129
135
|
return (0, util_1.compact)([
|
|
130
136
|
this.command.id,
|
|
131
|
-
Object.values(this.command.args ?? {})
|
|
137
|
+
Object.values(this.command.args ?? {})
|
|
138
|
+
?.filter((a) => !a.hidden)
|
|
139
|
+
.map((a) => this.arg(a))
|
|
140
|
+
.join(' '),
|
|
132
141
|
]).join(' ');
|
|
133
142
|
}
|
|
134
143
|
description() {
|
|
@@ -139,10 +148,9 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
139
148
|
}
|
|
140
149
|
else if (cmd.description) {
|
|
141
150
|
const summary = cmd.summary ? `${cmd.summary}\n` : null;
|
|
142
|
-
description = summary
|
|
143
|
-
...summary.split(POSSIBLE_LINE_FEED),
|
|
144
|
-
|
|
145
|
-
] : (cmd.description || '').split(POSSIBLE_LINE_FEED);
|
|
151
|
+
description = summary
|
|
152
|
+
? [...summary.split(POSSIBLE_LINE_FEED), ...(cmd.description || '').split(POSSIBLE_LINE_FEED)]
|
|
153
|
+
: (cmd.description || '').split(POSSIBLE_LINE_FEED);
|
|
146
154
|
}
|
|
147
155
|
if (description) {
|
|
148
156
|
return this.wrap(description.join('\n'));
|
|
@@ -151,50 +159,51 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
151
159
|
aliases(aliases) {
|
|
152
160
|
if (!aliases || aliases.length === 0)
|
|
153
161
|
return;
|
|
154
|
-
const body = aliases.map(a => ['$', this.config.bin, a].join(' ')).join('\n');
|
|
162
|
+
const body = aliases.map((a) => ['$', this.config.bin, a].join(' ')).join('\n');
|
|
155
163
|
return body;
|
|
156
164
|
}
|
|
157
165
|
examples(examples) {
|
|
158
166
|
if (!examples || examples.length === 0)
|
|
159
167
|
return;
|
|
160
|
-
const body = (0, util_1.castArray)(examples)
|
|
168
|
+
const body = (0, util_1.castArray)(examples)
|
|
169
|
+
.map((a) => {
|
|
161
170
|
let description;
|
|
162
171
|
let commands;
|
|
163
172
|
if (typeof a === 'string') {
|
|
164
|
-
const lines = a
|
|
165
|
-
.split(POSSIBLE_LINE_FEED)
|
|
166
|
-
.filter(Boolean);
|
|
173
|
+
const lines = a.split(POSSIBLE_LINE_FEED).filter(Boolean);
|
|
167
174
|
// If the example is <description>\n<command> then format correctly
|
|
168
|
-
if (lines.length >= 2 && !this.isCommand(lines[0]) && lines.slice(1).every(i => this.isCommand(i))) {
|
|
175
|
+
if (lines.length >= 2 && !this.isCommand(lines[0]) && lines.slice(1).every((i) => this.isCommand(i))) {
|
|
169
176
|
description = lines[0];
|
|
170
177
|
commands = lines.slice(1);
|
|
171
178
|
}
|
|
172
179
|
else {
|
|
173
|
-
return lines.map(line => this.formatIfCommand(line)).join('\n');
|
|
180
|
+
return lines.map((line) => this.formatIfCommand(line)).join('\n');
|
|
174
181
|
}
|
|
175
182
|
}
|
|
176
183
|
else {
|
|
177
184
|
description = a.description;
|
|
178
185
|
commands = [a.command];
|
|
179
186
|
}
|
|
180
|
-
const multilineSeparator = this.config.platform === 'win32'
|
|
181
|
-
? (this.config.shell.includes('powershell') ? '`' : '^')
|
|
182
|
-
: '\\';
|
|
187
|
+
const multilineSeparator = this.config.platform === 'win32' ? (this.config.shell.includes('powershell') ? '`' : '^') : '\\';
|
|
183
188
|
// The command will be indented in the section, which is also indented
|
|
184
189
|
const finalIndentedSpacing = this.indentSpacing * 2;
|
|
185
|
-
const multilineCommands = commands
|
|
190
|
+
const multilineCommands = commands
|
|
191
|
+
.map((c) =>
|
|
186
192
|
// First indent keeping room for escaped newlines
|
|
187
193
|
this.indent(this.wrap(this.formatIfCommand(c), finalIndentedSpacing + 4))
|
|
188
194
|
// Then add the escaped newline
|
|
189
|
-
.split(POSSIBLE_LINE_FEED)
|
|
195
|
+
.split(POSSIBLE_LINE_FEED)
|
|
196
|
+
.join(` ${multilineSeparator}\n `))
|
|
197
|
+
.join('\n');
|
|
190
198
|
return `${this.wrap(description, finalIndentedSpacing)}\n\n${multilineCommands}`;
|
|
191
|
-
})
|
|
199
|
+
})
|
|
200
|
+
.join('\n\n');
|
|
192
201
|
return body;
|
|
193
202
|
}
|
|
194
203
|
args(args) {
|
|
195
|
-
if (args.filter(a => a.description).length === 0)
|
|
204
|
+
if (args.filter((a) => a.description).length === 0)
|
|
196
205
|
return;
|
|
197
|
-
return args.map(a => {
|
|
206
|
+
return args.map((a) => {
|
|
198
207
|
const name = a.name.toUpperCase();
|
|
199
208
|
let description = a.description || '';
|
|
200
209
|
if (a.default)
|
|
@@ -242,7 +251,7 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
242
251
|
flags(flags) {
|
|
243
252
|
if (flags.length === 0)
|
|
244
253
|
return;
|
|
245
|
-
return flags.map(flag => {
|
|
254
|
+
return flags.map((flag) => {
|
|
246
255
|
const left = this.flagHelpLabel(flag);
|
|
247
256
|
let right = flag.summary || flag.description || '';
|
|
248
257
|
if (flag.type === 'option' && flag.default) {
|
|
@@ -257,16 +266,21 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
257
266
|
});
|
|
258
267
|
}
|
|
259
268
|
flagsDescriptions(flags) {
|
|
260
|
-
const flagsWithExtendedDescriptions = flags.filter(flag => flag.summary && flag.description);
|
|
269
|
+
const flagsWithExtendedDescriptions = flags.filter((flag) => flag.summary && flag.description);
|
|
261
270
|
if (flagsWithExtendedDescriptions.length === 0)
|
|
262
271
|
return;
|
|
263
|
-
const body = flagsWithExtendedDescriptions
|
|
272
|
+
const body = flagsWithExtendedDescriptions
|
|
273
|
+
.map((flag) => {
|
|
264
274
|
// Guaranteed to be set because of the filter above, but make ts happy
|
|
265
275
|
const summary = flag.summary || '';
|
|
266
276
|
let flagHelp = this.flagHelpLabel(flag, true);
|
|
267
|
-
flagHelp +=
|
|
277
|
+
flagHelp +=
|
|
278
|
+
flagHelp.length + summary.length + 2 < this.opts.maxWidth
|
|
279
|
+
? ' ' + summary
|
|
280
|
+
: '\n\n' + this.indent(this.wrap(summary, this.indentSpacing * 2));
|
|
268
281
|
return `${flagHelp}\n\n${this.indent(this.wrap(flag.description || '', this.indentSpacing * 2))}`;
|
|
269
|
-
})
|
|
282
|
+
})
|
|
283
|
+
.join('\n\n');
|
|
270
284
|
return body;
|
|
271
285
|
}
|
|
272
286
|
formatIfCommand(example) {
|
package/lib/help/docopts.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DocOpts = void 0;
|
|
4
|
-
const
|
|
4
|
+
const index_1 = require("../util/index");
|
|
5
5
|
/**
|
|
6
6
|
* DocOpts - See http://docopt.org/.
|
|
7
7
|
*
|
|
@@ -59,6 +59,9 @@ const util_1 = require("../util");
|
|
|
59
59
|
*
|
|
60
60
|
*/
|
|
61
61
|
class DocOpts {
|
|
62
|
+
cmd;
|
|
63
|
+
flagMap;
|
|
64
|
+
flagList;
|
|
62
65
|
constructor(cmd) {
|
|
63
66
|
this.cmd = cmd;
|
|
64
67
|
// Create a new map with references to the flags that we can manipulate.
|
|
@@ -76,7 +79,7 @@ class DocOpts {
|
|
|
76
79
|
toString() {
|
|
77
80
|
const opts = this.cmd.id === '.' || this.cmd.id === '' ? [] : ['<%= command.id %>'];
|
|
78
81
|
if (this.cmd.args) {
|
|
79
|
-
const a = Object.values((0,
|
|
82
|
+
const a = Object.values((0, index_1.ensureArgObject)(this.cmd.args)).map((arg) => arg.required ? arg.name.toUpperCase() : `[${arg.name.toUpperCase()}]`) || [];
|
|
80
83
|
opts.push(...a);
|
|
81
84
|
}
|
|
82
85
|
try {
|
|
@@ -84,7 +87,7 @@ class DocOpts {
|
|
|
84
87
|
}
|
|
85
88
|
catch {
|
|
86
89
|
// If there is an error, just return no usage so we don't fail command help.
|
|
87
|
-
opts.push(...this.flagList.map(flag => {
|
|
90
|
+
opts.push(...this.flagList.map((flag) => {
|
|
88
91
|
const name = flag.char ? `-${flag.char}` : `--${flag.name}`;
|
|
89
92
|
if (flag.type === 'boolean')
|
|
90
93
|
return name;
|
|
@@ -97,9 +100,9 @@ class DocOpts {
|
|
|
97
100
|
const elementMap = {};
|
|
98
101
|
// Generate all doc opt elements for combining
|
|
99
102
|
// Show required flags first
|
|
100
|
-
this.generateElements(elementMap, this.flagList.filter(flag => flag.required));
|
|
103
|
+
this.generateElements(elementMap, this.flagList.filter((flag) => flag.required));
|
|
101
104
|
// Then show optional flags
|
|
102
|
-
this.generateElements(elementMap, this.flagList.filter(flag => !flag.required));
|
|
105
|
+
this.generateElements(elementMap, this.flagList.filter((flag) => !flag.required));
|
|
103
106
|
for (const flag of this.flagList) {
|
|
104
107
|
if (Array.isArray(flag.dependsOn)) {
|
|
105
108
|
this.combineElementsToFlag(elementMap, flag.name, flag.dependsOn, ' ');
|
package/lib/help/formatter.js
CHANGED
|
@@ -11,12 +11,23 @@ const widest_line_1 = tslib_1.__importDefault(require("widest-line"));
|
|
|
11
11
|
const string_width_1 = tslib_1.__importDefault(require("string-width"));
|
|
12
12
|
const wrap_ansi_1 = tslib_1.__importDefault(require("wrap-ansi"));
|
|
13
13
|
class HelpFormatter {
|
|
14
|
+
indentSpacing = 2;
|
|
15
|
+
/**
|
|
16
|
+
* Takes a string and replaces `<%= prop =>` with the value of prop, where prop is anything on
|
|
17
|
+
* `config=Interfaces.Config` or `opts=Interface.HelpOptions`.
|
|
18
|
+
*
|
|
19
|
+
* ```javascript
|
|
20
|
+
* `<%= config.bin =>` // will resolve to the bin defined in `pjson.oclif`.
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
render;
|
|
14
24
|
constructor(config, opts = {}) {
|
|
15
|
-
this.indentSpacing = 2;
|
|
16
25
|
this.config = config;
|
|
17
26
|
this.opts = { maxWidth: screen_1.stdtermwidth, ...opts };
|
|
18
27
|
this.render = (0, util_1.template)(this);
|
|
19
28
|
}
|
|
29
|
+
config;
|
|
30
|
+
opts;
|
|
20
31
|
/**
|
|
21
32
|
* Wrap text according to `opts.maxWidth` which is typically set to the terminal width. All text
|
|
22
33
|
* will be rendered before bring wrapped, otherwise it could mess up the lengths.
|
|
@@ -106,7 +117,7 @@ class HelpFormatter {
|
|
|
106
117
|
};
|
|
107
118
|
if (opts.multiline)
|
|
108
119
|
return renderMultiline();
|
|
109
|
-
const maxLength = (0, widest_line_1.default)(input.map(i => i[0]).join('\n'));
|
|
120
|
+
const maxLength = (0, widest_line_1.default)(input.map((i) => i[0]).join('\n'));
|
|
110
121
|
let output = '';
|
|
111
122
|
let spacer = opts.spacer || '\n';
|
|
112
123
|
let cur = '';
|
|
@@ -126,7 +137,7 @@ class HelpFormatter {
|
|
|
126
137
|
if (opts.stripAnsi)
|
|
127
138
|
right = (0, strip_ansi_1.default)(right);
|
|
128
139
|
right = this.wrap(right.trim(), opts.indentation + maxLength + 2);
|
|
129
|
-
const [first, ...lines] = right.split('\n').map(s => s.trim());
|
|
140
|
+
const [first, ...lines] = right.split('\n').map((s) => s.trim());
|
|
130
141
|
cur += ' '.repeat(maxLength - (0, string_width_1.default)(cur) + 2);
|
|
131
142
|
cur += first;
|
|
132
143
|
if (lines.length === 0) {
|
|
@@ -154,13 +165,13 @@ class HelpFormatter {
|
|
|
154
165
|
newBody = this.render(body);
|
|
155
166
|
}
|
|
156
167
|
else if (Array.isArray(body)) {
|
|
157
|
-
newBody = body.map(entry => {
|
|
168
|
+
newBody = body.map((entry) => {
|
|
158
169
|
if ('name' in entry) {
|
|
159
170
|
const tableEntry = entry;
|
|
160
|
-
return
|
|
171
|
+
return [this.render(tableEntry.name), this.render(tableEntry.description)];
|
|
161
172
|
}
|
|
162
173
|
const [left, right] = entry;
|
|
163
|
-
return
|
|
174
|
+
return [this.render(left), right && this.render(right)];
|
|
164
175
|
});
|
|
165
176
|
}
|
|
166
177
|
else if ('header' in body) {
|
|
@@ -168,8 +179,8 @@ class HelpFormatter {
|
|
|
168
179
|
}
|
|
169
180
|
else {
|
|
170
181
|
newBody = body
|
|
171
|
-
.map((entry) =>
|
|
172
|
-
.map(([left, right]) =>
|
|
182
|
+
.map((entry) => [entry.name, entry.description])
|
|
183
|
+
.map(([left, right]) => [this.render(left), right && this.render(right)]);
|
|
173
184
|
}
|
|
174
185
|
const output = [
|
|
175
186
|
chalk_1.default.bold(header),
|
package/lib/help/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Command } from '../command';
|
|
|
3
3
|
import { CommandHelp } from './command';
|
|
4
4
|
import { HelpFormatter } from './formatter';
|
|
5
5
|
export { CommandHelp } from './command';
|
|
6
|
-
export { standardizeIDFromArgv,
|
|
6
|
+
export { standardizeIDFromArgv, getHelpFlagAdditions, normalizeArgv } from './util';
|
|
7
7
|
export declare abstract class HelpBase extends HelpFormatter {
|
|
8
8
|
constructor(config: Interfaces.Config, opts?: Partial<Interfaces.HelpOptions>);
|
|
9
9
|
/**
|
|
@@ -39,3 +39,7 @@ export declare class Help extends HelpBase {
|
|
|
39
39
|
protected command(command: Command.Class): string;
|
|
40
40
|
protected log(...args: string[]): void;
|
|
41
41
|
}
|
|
42
|
+
interface HelpBaseDerived {
|
|
43
|
+
new (config: Interfaces.Config, opts?: Partial<Interfaces.HelpOptions>): HelpBase;
|
|
44
|
+
}
|
|
45
|
+
export declare function loadHelpClass(config: Interfaces.Config): Promise<HelpBaseDerived>;
|
package/lib/help/index.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.loadHelpClass = exports.Help = exports.HelpBase = exports.normalizeArgv = exports.getHelpFlagAdditions = exports.standardizeIDFromArgv = exports.CommandHelp = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const index_1 = require("../util/index");
|
|
6
|
+
const util_1 = require("./util");
|
|
7
7
|
const command_1 = require("./command");
|
|
8
8
|
const formatter_1 = require("./formatter");
|
|
9
9
|
const root_1 = tslib_1.__importDefault(require("./root"));
|
|
10
|
+
const cache_default_value_1 = require("../util/cache-default-value");
|
|
10
11
|
const errors_1 = require("../errors");
|
|
11
12
|
const node_util_1 = require("node:util");
|
|
13
|
+
const module_loader_1 = require("../module-loader");
|
|
12
14
|
const stream_1 = require("../cli-ux/stream");
|
|
13
|
-
const
|
|
14
|
-
const stripAnsi = require("strip-ansi");
|
|
15
|
+
const strip_ansi_1 = tslib_1.__importDefault(require("strip-ansi"));
|
|
15
16
|
var command_2 = require("./command");
|
|
16
17
|
Object.defineProperty(exports, "CommandHelp", { enumerable: true, get: function () { return command_2.CommandHelp; } });
|
|
17
|
-
var
|
|
18
|
-
Object.defineProperty(exports, "standardizeIDFromArgv", { enumerable: true, get: function () { return
|
|
19
|
-
Object.defineProperty(exports, "
|
|
20
|
-
Object.defineProperty(exports, "
|
|
21
|
-
Object.defineProperty(exports, "normalizeArgv", { enumerable: true, get: function () { return util_3.normalizeArgv; } });
|
|
18
|
+
var util_2 = require("./util");
|
|
19
|
+
Object.defineProperty(exports, "standardizeIDFromArgv", { enumerable: true, get: function () { return util_2.standardizeIDFromArgv; } });
|
|
20
|
+
Object.defineProperty(exports, "getHelpFlagAdditions", { enumerable: true, get: function () { return util_2.getHelpFlagAdditions; } });
|
|
21
|
+
Object.defineProperty(exports, "normalizeArgv", { enumerable: true, get: function () { return util_2.normalizeArgv; } });
|
|
22
22
|
function getHelpSubject(args, config) {
|
|
23
23
|
// for each help flag that starts with '--' create a new flag with same name sans '--'
|
|
24
|
-
const mergedHelpFlags = (0,
|
|
24
|
+
const mergedHelpFlags = (0, util_1.getHelpFlagAdditions)(config);
|
|
25
25
|
for (const arg of args) {
|
|
26
26
|
if (arg === '--')
|
|
27
27
|
return;
|
|
@@ -41,6 +41,7 @@ class HelpBase extends formatter_1.HelpFormatter {
|
|
|
41
41
|
}
|
|
42
42
|
exports.HelpBase = HelpBase;
|
|
43
43
|
class Help extends HelpBase {
|
|
44
|
+
CommandHelpClass = command_1.CommandHelp;
|
|
44
45
|
/*
|
|
45
46
|
* _topics is to work around Interfaces.topics mistakenly including commands that do
|
|
46
47
|
* not have children, as well as topics. A topic has children, either commands or other topics. When
|
|
@@ -50,33 +51,32 @@ class Help extends HelpBase {
|
|
|
50
51
|
get _topics() {
|
|
51
52
|
return this.config.topics.filter((topic) => {
|
|
52
53
|
// it is assumed a topic has a child if it has children
|
|
53
|
-
const hasChild = this.config.topics.some(subTopic => subTopic.name.includes(`${topic.name}:`));
|
|
54
|
+
const hasChild = this.config.topics.some((subTopic) => subTopic.name.includes(`${topic.name}:`));
|
|
54
55
|
return hasChild;
|
|
55
56
|
});
|
|
56
57
|
}
|
|
57
58
|
get sortedCommands() {
|
|
58
59
|
let { commands } = this.config;
|
|
59
|
-
commands = commands.filter(c => this.opts.all || !c.hidden);
|
|
60
|
-
commands = (0,
|
|
61
|
-
commands = (0,
|
|
60
|
+
commands = commands.filter((c) => this.opts.all || !c.hidden);
|
|
61
|
+
commands = (0, index_1.sortBy)(commands, (c) => c.id);
|
|
62
|
+
commands = (0, index_1.uniqBy)(commands, (c) => c.id);
|
|
62
63
|
return commands;
|
|
63
64
|
}
|
|
64
65
|
get sortedTopics() {
|
|
65
66
|
let topics = this._topics;
|
|
66
|
-
topics = topics.filter(t => this.opts.all || !t.hidden);
|
|
67
|
-
topics = (0,
|
|
68
|
-
topics = (0,
|
|
67
|
+
topics = topics.filter((t) => this.opts.all || !t.hidden);
|
|
68
|
+
topics = (0, index_1.sortBy)(topics, (t) => t.name);
|
|
69
|
+
topics = (0, index_1.uniqBy)(topics, (t) => t.name);
|
|
69
70
|
return topics;
|
|
70
71
|
}
|
|
71
72
|
constructor(config, opts = {}) {
|
|
72
73
|
super(config, opts);
|
|
73
|
-
this.CommandHelpClass = command_1.CommandHelp;
|
|
74
74
|
}
|
|
75
75
|
async showHelp(argv) {
|
|
76
76
|
const originalArgv = argv.slice(1);
|
|
77
|
-
argv = argv.filter(arg => !(0,
|
|
77
|
+
argv = argv.filter((arg) => !(0, util_1.getHelpFlagAdditions)(this.config).includes(arg));
|
|
78
78
|
if (this.config.topicSeparator !== ':')
|
|
79
|
-
argv = (0,
|
|
79
|
+
argv = (0, util_1.standardizeIDFromArgv)(argv, this.config);
|
|
80
80
|
const subject = getHelpSubject(argv, this.config);
|
|
81
81
|
if (!subject) {
|
|
82
82
|
if (this.config.pjson.oclif.default) {
|
|
@@ -92,8 +92,14 @@ class Help extends HelpBase {
|
|
|
92
92
|
const command = this.config.findCommand(subject);
|
|
93
93
|
if (command) {
|
|
94
94
|
if (command.hasDynamicHelp && command.pluginType !== 'jit') {
|
|
95
|
-
const
|
|
96
|
-
|
|
95
|
+
const loaded = await command.load();
|
|
96
|
+
for (const [name, flag] of Object.entries(loaded.flags)) {
|
|
97
|
+
if (flag.type === 'boolean' || !command.flags[name].hasDynamicHelp)
|
|
98
|
+
continue;
|
|
99
|
+
// eslint-disable-next-line no-await-in-loop
|
|
100
|
+
command.flags[name].default = await (0, cache_default_value_1.cacheDefaultValue)(flag, false);
|
|
101
|
+
}
|
|
102
|
+
await this.showCommandHelp(command);
|
|
97
103
|
}
|
|
98
104
|
else {
|
|
99
105
|
await this.showCommandHelp(command);
|
|
@@ -110,7 +116,7 @@ class Help extends HelpBase {
|
|
|
110
116
|
if (matches.length > 0) {
|
|
111
117
|
const result = await this.config.runHook('command_incomplete', {
|
|
112
118
|
id: subject,
|
|
113
|
-
argv: originalArgv.filter(o => !subject.split(':').includes(o)),
|
|
119
|
+
argv: originalArgv.filter((o) => !subject.split(':').includes(o)),
|
|
114
120
|
matches,
|
|
115
121
|
});
|
|
116
122
|
if (result.successes.length > 0)
|
|
@@ -122,15 +128,20 @@ class Help extends HelpBase {
|
|
|
122
128
|
async showCommandHelp(command) {
|
|
123
129
|
const name = command.id;
|
|
124
130
|
const depth = name.split(':').length;
|
|
125
|
-
const subTopics = this.sortedTopics.filter(t => t.name.startsWith(name + ':') && t.name.split(':').length === depth + 1);
|
|
126
|
-
const subCommands = this.sortedCommands.filter(c => c.id.startsWith(name + ':') && c.id.split(':').length === depth + 1);
|
|
131
|
+
const subTopics = this.sortedTopics.filter((t) => t.name.startsWith(name + ':') && t.name.split(':').length === depth + 1);
|
|
132
|
+
const subCommands = this.sortedCommands.filter((c) => c.id.startsWith(name + ':') && c.id.split(':').length === depth + 1);
|
|
127
133
|
const plugin = this.config.plugins.get(command.pluginName);
|
|
128
134
|
const state = this.config.pjson?.oclif?.state || plugin?.pjson?.oclif?.state || command.state;
|
|
129
135
|
if (state) {
|
|
130
136
|
this.log(state === 'deprecated'
|
|
131
|
-
? `${(0,
|
|
137
|
+
? `${(0, util_1.formatCommandDeprecationWarning)((0, util_1.toConfiguredId)(name, this.config), command.deprecationOptions)}\n`
|
|
132
138
|
: `This command is in ${state}.\n`);
|
|
133
139
|
}
|
|
140
|
+
if (command.deprecateAliases && command.aliases.includes(name)) {
|
|
141
|
+
const actualCmd = this.config.commands.find((c) => c.aliases.includes(name));
|
|
142
|
+
const opts = { ...command.deprecationOptions, ...(actualCmd ? { to: actualCmd.id } : {}) };
|
|
143
|
+
this.log(`${(0, util_1.formatCommandDeprecationWarning)((0, util_1.toConfiguredId)(name, this.config), opts)}\n`);
|
|
144
|
+
}
|
|
134
145
|
const summary = this.summary(command);
|
|
135
146
|
if (summary) {
|
|
136
147
|
this.log(summary + '\n');
|
|
@@ -143,7 +154,7 @@ class Help extends HelpBase {
|
|
|
143
154
|
}
|
|
144
155
|
if (subCommands.length > 0) {
|
|
145
156
|
const aliases = [];
|
|
146
|
-
const uniqueSubCommands = subCommands.filter(p => {
|
|
157
|
+
const uniqueSubCommands = subCommands.filter((p) => {
|
|
147
158
|
aliases.push(...p.aliases);
|
|
148
159
|
return !aliases.includes(p.id);
|
|
149
160
|
});
|
|
@@ -156,22 +167,20 @@ class Help extends HelpBase {
|
|
|
156
167
|
let rootCommands = this.sortedCommands;
|
|
157
168
|
const state = this.config.pjson?.oclif?.state;
|
|
158
169
|
if (state) {
|
|
159
|
-
this.log(state === 'deprecated'
|
|
160
|
-
? `${this.config.bin} is deprecated`
|
|
161
|
-
: `${this.config.bin} is in ${state}.\n`);
|
|
170
|
+
this.log(state === 'deprecated' ? `${this.config.bin} is deprecated` : `${this.config.bin} is in ${state}.\n`);
|
|
162
171
|
}
|
|
163
172
|
this.log(this.formatRoot());
|
|
164
173
|
this.log('');
|
|
165
174
|
if (!this.opts.all) {
|
|
166
|
-
rootTopics = rootTopics.filter(t => !t.name.includes(':'));
|
|
167
|
-
rootCommands = rootCommands.filter(c => !c.id.includes(':'));
|
|
175
|
+
rootTopics = rootTopics.filter((t) => !t.name.includes(':'));
|
|
176
|
+
rootCommands = rootCommands.filter((c) => !c.id.includes(':'));
|
|
168
177
|
}
|
|
169
178
|
if (rootTopics.length > 0) {
|
|
170
179
|
this.log(this.formatTopics(rootTopics));
|
|
171
180
|
this.log('');
|
|
172
181
|
}
|
|
173
182
|
if (rootCommands.length > 0) {
|
|
174
|
-
rootCommands = rootCommands.filter(c => c.id);
|
|
183
|
+
rootCommands = rootCommands.filter((c) => c.id);
|
|
175
184
|
this.log(this.formatCommands(rootCommands));
|
|
176
185
|
this.log('');
|
|
177
186
|
}
|
|
@@ -179,8 +188,8 @@ class Help extends HelpBase {
|
|
|
179
188
|
async showTopicHelp(topic) {
|
|
180
189
|
const { name } = topic;
|
|
181
190
|
const depth = name.split(':').length;
|
|
182
|
-
const subTopics = this.sortedTopics.filter(t => t.name.startsWith(name + ':') && t.name.split(':').length === depth + 1);
|
|
183
|
-
const commands = this.sortedCommands.filter(c => c.id.startsWith(name + ':') && c.id.split(':').length === depth + 1);
|
|
191
|
+
const subTopics = this.sortedTopics.filter((t) => t.name.startsWith(name + ':') && t.name.split(':').length === depth + 1);
|
|
192
|
+
const commands = this.sortedCommands.filter((c) => c.id.startsWith(name + ':') && c.id.split(':').length === depth + 1);
|
|
184
193
|
const state = this.config.pjson?.oclif?.state;
|
|
185
194
|
if (state)
|
|
186
195
|
this.log(`This topic is in ${state}.\n`);
|
|
@@ -201,7 +210,7 @@ class Help extends HelpBase {
|
|
|
201
210
|
formatCommand(command) {
|
|
202
211
|
if (this.config.topicSeparator !== ':') {
|
|
203
212
|
command.id = command.id.replaceAll(':', this.config.topicSeparator);
|
|
204
|
-
command.aliases = command.aliases && command.aliases.map(a => a.replaceAll(':', this.config.topicSeparator));
|
|
213
|
+
command.aliases = command.aliases && command.aliases.map((a) => a.replaceAll(':', this.config.topicSeparator));
|
|
205
214
|
}
|
|
206
215
|
const help = this.getCommandHelpClass(command);
|
|
207
216
|
return help.generate();
|
|
@@ -212,13 +221,10 @@ class Help extends HelpBase {
|
|
|
212
221
|
formatCommands(commands) {
|
|
213
222
|
if (commands.length === 0)
|
|
214
223
|
return '';
|
|
215
|
-
const body = this.renderList(commands.map(c => {
|
|
224
|
+
const body = this.renderList(commands.map((c) => {
|
|
216
225
|
if (this.config.topicSeparator !== ':')
|
|
217
226
|
c.id = c.id.replaceAll(':', this.config.topicSeparator);
|
|
218
|
-
return [
|
|
219
|
-
c.id,
|
|
220
|
-
this.summary(c),
|
|
221
|
-
];
|
|
227
|
+
return [c.id, this.summary(c)];
|
|
222
228
|
}), {
|
|
223
229
|
spacer: '\n',
|
|
224
230
|
stripAnsi: this.opts.stripAnsi,
|
|
@@ -245,25 +251,22 @@ class Help extends HelpBase {
|
|
|
245
251
|
let topicID = `${topic.name}:COMMAND`;
|
|
246
252
|
if (this.config.topicSeparator !== ':')
|
|
247
253
|
topicID = topicID.replaceAll(':', this.config.topicSeparator);
|
|
248
|
-
let output = (0,
|
|
254
|
+
let output = (0, index_1.compact)([
|
|
249
255
|
summary,
|
|
250
256
|
this.section(this.opts.usageHeader || 'USAGE', `$ ${this.config.bin} ${topicID}`),
|
|
251
257
|
description && this.section('DESCRIPTION', this.wrap(description)),
|
|
252
258
|
]).join('\n\n');
|
|
253
259
|
if (this.opts.stripAnsi)
|
|
254
|
-
output =
|
|
260
|
+
output = (0, strip_ansi_1.default)(output);
|
|
255
261
|
return output + '\n';
|
|
256
262
|
}
|
|
257
263
|
formatTopics(topics) {
|
|
258
264
|
if (topics.length === 0)
|
|
259
265
|
return '';
|
|
260
|
-
const body = this.renderList(topics.map(c => {
|
|
266
|
+
const body = this.renderList(topics.map((c) => {
|
|
261
267
|
if (this.config.topicSeparator !== ':')
|
|
262
268
|
c.name = c.name.replaceAll(':', this.config.topicSeparator);
|
|
263
|
-
return [
|
|
264
|
-
c.name,
|
|
265
|
-
c.description && this.render(c.description.split('\n')[0]),
|
|
266
|
-
];
|
|
269
|
+
return [c.name, c.description && this.render(c.description.split('\n')[0])];
|
|
267
270
|
}), {
|
|
268
271
|
spacer: '\n',
|
|
269
272
|
stripAnsi: this.opts.stripAnsi,
|
|
@@ -279,3 +282,21 @@ class Help extends HelpBase {
|
|
|
279
282
|
}
|
|
280
283
|
}
|
|
281
284
|
exports.Help = Help;
|
|
285
|
+
function extractClass(exported) {
|
|
286
|
+
return exported && exported.default ? exported.default : exported;
|
|
287
|
+
}
|
|
288
|
+
async function loadHelpClass(config) {
|
|
289
|
+
const { pjson } = config;
|
|
290
|
+
const configuredClass = pjson.oclif?.helpClass;
|
|
291
|
+
if (configuredClass) {
|
|
292
|
+
try {
|
|
293
|
+
const exported = (await (0, module_loader_1.load)(config, configuredClass));
|
|
294
|
+
return extractClass(exported);
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
throw new Error(`Unable to load configured help class "${configuredClass}", failed with message:\n${error.message}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return Help;
|
|
301
|
+
}
|
|
302
|
+
exports.loadHelpClass = loadHelpClass;
|
package/lib/help/root.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
3
4
|
const formatter_1 = require("./formatter");
|
|
4
|
-
const
|
|
5
|
-
const
|
|
5
|
+
const index_1 = require("../util/index");
|
|
6
|
+
const strip_ansi_1 = tslib_1.__importDefault(require("strip-ansi"));
|
|
6
7
|
class RootHelp extends formatter_1.HelpFormatter {
|
|
8
|
+
config;
|
|
9
|
+
opts;
|
|
7
10
|
constructor(config, opts) {
|
|
8
11
|
super(config, opts);
|
|
9
12
|
this.config = config;
|
|
@@ -13,14 +16,9 @@ class RootHelp extends formatter_1.HelpFormatter {
|
|
|
13
16
|
let description = this.config.pjson.oclif.description || this.config.pjson.description || '';
|
|
14
17
|
description = this.render(description);
|
|
15
18
|
description = description.split('\n')[0];
|
|
16
|
-
let output = (0,
|
|
17
|
-
description,
|
|
18
|
-
this.version(),
|
|
19
|
-
this.usage(),
|
|
20
|
-
this.description(),
|
|
21
|
-
]).join('\n\n');
|
|
19
|
+
let output = (0, index_1.compact)([description, this.version(), this.usage(), this.description()]).join('\n\n');
|
|
22
20
|
if (this.opts.stripAnsi)
|
|
23
|
-
output =
|
|
21
|
+
output = (0, strip_ansi_1.default)(output);
|
|
24
22
|
return output;
|
|
25
23
|
}
|
|
26
24
|
usage() {
|
package/lib/help/util.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import { Deprecation,
|
|
2
|
-
import { HelpBase } from '.';
|
|
3
|
-
interface HelpBaseDerived {
|
|
4
|
-
new (config: IConfig, opts?: Partial<HelpOptions>): HelpBase;
|
|
5
|
-
}
|
|
6
|
-
export declare function loadHelpClass(config: IConfig): Promise<HelpBaseDerived>;
|
|
1
|
+
import { Deprecation, Config as IConfig } from '../interfaces';
|
|
7
2
|
export declare function template(context: any): (t: string) => string;
|
|
8
3
|
export declare function toStandardizedId(commandID: string, config: IConfig): string;
|
|
9
4
|
export declare function toConfiguredId(commandID: string, config: IConfig): string;
|
|
@@ -12,4 +7,3 @@ export declare function getHelpFlagAdditions(config: IConfig): string[];
|
|
|
12
7
|
export declare function formatFlagDeprecationWarning(flag: string, opts: true | Deprecation): string;
|
|
13
8
|
export declare function formatCommandDeprecationWarning(command: string, opts?: Deprecation): string;
|
|
14
9
|
export declare function normalizeArgv(config: IConfig, argv?: string[]): string[];
|
|
15
|
-
export {};
|