@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.
Files changed (69) hide show
  1. package/lib/args.js +4 -4
  2. package/lib/cli-ux/action/base.js +8 -7
  3. package/lib/cli-ux/action/simple.js +1 -4
  4. package/lib/cli-ux/action/spinner.js +8 -7
  5. package/lib/cli-ux/action/spinners.js +1 -1
  6. package/lib/cli-ux/config.js +11 -12
  7. package/lib/cli-ux/exit.js +3 -0
  8. package/lib/cli-ux/flush.js +7 -6
  9. package/lib/cli-ux/index.js +2 -2
  10. package/lib/cli-ux/list.js +3 -3
  11. package/lib/cli-ux/prompt.js +8 -3
  12. package/lib/cli-ux/stream.js +1 -0
  13. package/lib/cli-ux/styled/json.js +5 -3
  14. package/lib/cli-ux/styled/object.js +2 -2
  15. package/lib/cli-ux/styled/table.js +26 -20
  16. package/lib/cli-ux/styled/tree.js +1 -3
  17. package/lib/cli-ux/wait.js +1 -1
  18. package/lib/command.d.ts +6 -14
  19. package/lib/command.js +86 -73
  20. package/lib/config/config.d.ts +8 -9
  21. package/lib/config/config.js +85 -199
  22. package/lib/config/index.d.ts +0 -1
  23. package/lib/config/index.js +1 -3
  24. package/lib/config/plugin-loader.js +12 -11
  25. package/lib/config/plugin.d.ts +1 -0
  26. package/lib/config/plugin.js +54 -34
  27. package/lib/config/ts-node.js +17 -13
  28. package/lib/config/util.d.ts +0 -6
  29. package/lib/config/util.js +3 -15
  30. package/lib/errors/errors/cli.js +4 -1
  31. package/lib/errors/errors/exit.js +1 -1
  32. package/lib/errors/errors/module-load.js +1 -1
  33. package/lib/errors/errors/pretty-print.js +2 -1
  34. package/lib/errors/handle.js +4 -3
  35. package/lib/errors/logger.js +5 -4
  36. package/lib/flags.d.ts +6 -6
  37. package/lib/flags.js +3 -3
  38. package/lib/help/command.js +46 -32
  39. package/lib/help/docopts.js +8 -5
  40. package/lib/help/formatter.js +19 -8
  41. package/lib/help/index.d.ts +5 -1
  42. package/lib/help/index.js +70 -49
  43. package/lib/help/root.js +7 -9
  44. package/lib/help/util.d.ts +1 -7
  45. package/lib/help/util.js +2 -22
  46. package/lib/index.d.ts +2 -2
  47. package/lib/index.js +2 -3
  48. package/lib/interfaces/hooks.d.ts +3 -3
  49. package/lib/interfaces/index.d.ts +1 -1
  50. package/lib/interfaces/parser.d.ts +19 -18
  51. package/lib/interfaces/pjson.d.ts +1 -1
  52. package/lib/interfaces/plugin.d.ts +5 -0
  53. package/lib/module-loader.d.ts +8 -8
  54. package/lib/module-loader.js +13 -10
  55. package/lib/parser/errors.d.ts +1 -1
  56. package/lib/parser/errors.js +15 -9
  57. package/lib/parser/help.js +2 -3
  58. package/lib/parser/parse.js +72 -44
  59. package/lib/parser/validate.js +37 -21
  60. package/lib/performance.js +20 -9
  61. package/lib/util/aggregate-flags.d.ts +2 -0
  62. package/lib/util/aggregate-flags.js +13 -0
  63. package/lib/util/cache-command.d.ts +3 -0
  64. package/lib/util/cache-command.js +108 -0
  65. package/lib/util/cache-default-value.d.ts +2 -0
  66. package/lib/util/cache-default-value.js +28 -0
  67. package/lib/{util.d.ts → util/index.d.ts} +7 -2
  68. package/lib/{util.js → util/index.js} +15 -20
  69. package/package.json +19 -13
@@ -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, } = chalk_1.default;
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.map(helpSection => helpSection && helpSection.body && this.section(helpSection.header, helpSection.body)).join('\n\n');
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)) + '\n'
117
- + this.indent(this.wrap(line.slice(Math.max(0, splitIndex)), this.indentSpacing * 2));
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 ?? {})?.filter(a => !a.hidden).map(a => this.arg(a)).join(' '),
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
- ...(cmd.description || '').split(POSSIBLE_LINE_FEED),
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).map(a => {
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.map(c =>
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).join(` ${multilineSeparator}\n `)).join('\n');
195
+ .split(POSSIBLE_LINE_FEED)
196
+ .join(` ${multilineSeparator}\n `))
197
+ .join('\n');
190
198
  return `${this.wrap(description, finalIndentedSpacing)}\n\n${multilineCommands}`;
191
- }).join('\n\n');
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.map(flag => {
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 += flagHelp.length + summary.length + 2 < this.opts.maxWidth ? ' ' + summary : '\n\n' + this.indent(this.wrap(summary, this.indentSpacing * 2));
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
- }).join('\n\n');
282
+ })
283
+ .join('\n\n');
270
284
  return body;
271
285
  }
272
286
  formatIfCommand(example) {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DocOpts = void 0;
4
- const util_1 = require("../util");
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, util_1.ensureArgObject)(this.cmd.args)).map(arg => arg.required ? arg.name.toUpperCase() : `[${arg.name.toUpperCase()}]`) || [];
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, ' ');
@@ -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 ([this.render(tableEntry.name), this.render(tableEntry.description)]);
171
+ return [this.render(tableEntry.name), this.render(tableEntry.description)];
161
172
  }
162
173
  const [left, right] = entry;
163
- return ([this.render(left), right && this.render(right)]);
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) => ([entry.name, entry.description]))
172
- .map(([left, right]) => ([this.render(left), right && this.render(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),
@@ -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, loadHelpClass, getHelpFlagAdditions, normalizeArgv } from './util';
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.Help = exports.HelpBase = exports.normalizeArgv = exports.getHelpFlagAdditions = exports.loadHelpClass = exports.standardizeIDFromArgv = exports.CommandHelp = void 0;
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 util_1 = require("../util");
6
- const util_2 = require("./util");
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 config_1 = require("../config/config");
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 util_3 = require("./util");
18
- Object.defineProperty(exports, "standardizeIDFromArgv", { enumerable: true, get: function () { return util_3.standardizeIDFromArgv; } });
19
- Object.defineProperty(exports, "loadHelpClass", { enumerable: true, get: function () { return util_3.loadHelpClass; } });
20
- Object.defineProperty(exports, "getHelpFlagAdditions", { enumerable: true, get: function () { return util_3.getHelpFlagAdditions; } });
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, util_2.getHelpFlagAdditions)(config);
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, util_1.sortBy)(commands, c => c.id);
61
- commands = (0, util_1.uniqBy)(commands, c => c.id);
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, util_1.sortBy)(topics, t => t.name);
68
- topics = (0, util_1.uniqBy)(topics, t => t.name);
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, util_2.getHelpFlagAdditions)(this.config).includes(arg));
77
+ argv = argv.filter((arg) => !(0, util_1.getHelpFlagAdditions)(this.config).includes(arg));
78
78
  if (this.config.topicSeparator !== ':')
79
- argv = (0, util_2.standardizeIDFromArgv)(argv, this.config);
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 dynamicCommand = await (0, config_1.toCached)(await command.load());
96
- await this.showCommandHelp(dynamicCommand);
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, util_2.formatCommandDeprecationWarning)((0, util_2.toConfiguredId)(name, this.config), command.deprecationOptions)}`
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, util_1.compact)([
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 = stripAnsi(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 util_1 = require("../util");
5
- const stripAnsi = require("strip-ansi");
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, util_1.compact)([
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 = stripAnsi(output);
21
+ output = (0, strip_ansi_1.default)(output);
24
22
  return output;
25
23
  }
26
24
  usage() {
@@ -1,9 +1,4 @@
1
- import { Deprecation, HelpOptions, Config as IConfig } from '../interfaces';
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 {};