@oclif/core 3.0.0-beta.17 → 3.0.0-beta.18

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 (54) hide show
  1. package/lib/cli-ux/action/base.js +7 -7
  2. package/lib/cli-ux/action/simple.js +1 -4
  3. package/lib/cli-ux/action/spinner.js +5 -2
  4. package/lib/cli-ux/config.js +4 -6
  5. package/lib/cli-ux/exit.js +3 -0
  6. package/lib/cli-ux/flush.js +5 -4
  7. package/lib/cli-ux/index.js +1 -1
  8. package/lib/cli-ux/stream.js +1 -0
  9. package/lib/cli-ux/styled/json.js +5 -3
  10. package/lib/cli-ux/styled/table.js +3 -0
  11. package/lib/cli-ux/styled/tree.js +1 -3
  12. package/lib/command.d.ts +6 -14
  13. package/lib/command.js +81 -68
  14. package/lib/config/config.d.ts +0 -1
  15. package/lib/config/config.js +43 -163
  16. package/lib/config/index.d.ts +0 -1
  17. package/lib/config/index.js +1 -3
  18. package/lib/config/plugin-loader.js +5 -4
  19. package/lib/config/plugin.d.ts +1 -0
  20. package/lib/config/plugin.js +31 -14
  21. package/lib/config/ts-node.js +9 -3
  22. package/lib/config/util.d.ts +0 -6
  23. package/lib/config/util.js +1 -13
  24. package/lib/errors/errors/cli.js +3 -1
  25. package/lib/errors/errors/exit.js +1 -1
  26. package/lib/errors/errors/module-load.js +1 -1
  27. package/lib/errors/handle.js +2 -2
  28. package/lib/errors/logger.js +3 -2
  29. package/lib/flags.d.ts +2 -2
  30. package/lib/help/command.js +3 -0
  31. package/lib/help/docopts.js +3 -0
  32. package/lib/help/formatter.js +12 -1
  33. package/lib/help/index.d.ts +5 -1
  34. package/lib/help/index.js +32 -8
  35. package/lib/help/root.js +5 -2
  36. package/lib/help/util.d.ts +1 -7
  37. package/lib/help/util.js +1 -21
  38. package/lib/index.d.ts +2 -2
  39. package/lib/index.js +2 -3
  40. package/lib/interfaces/parser.d.ts +8 -7
  41. package/lib/interfaces/plugin.d.ts +5 -0
  42. package/lib/module-loader.js +2 -2
  43. package/lib/parser/errors.js +6 -0
  44. package/lib/parser/parse.js +9 -2
  45. package/lib/performance.js +11 -3
  46. package/lib/util/aggregate-flags.d.ts +2 -0
  47. package/lib/util/aggregate-flags.js +15 -0
  48. package/lib/util/cache-command.d.ts +3 -0
  49. package/lib/util/cache-command.js +100 -0
  50. package/lib/util/cache-default-value.d.ts +2 -0
  51. package/lib/util/cache-default-value.js +28 -0
  52. package/lib/{util.d.ts → util/index.d.ts} +7 -2
  53. package/lib/{util.js → util/index.js} +13 -16
  54. package/package.json +9 -5
@@ -5,13 +5,13 @@ const stream_1 = require("../stream");
5
5
  const util_1 = require("../../util");
6
6
  const node_util_1 = require("node:util");
7
7
  class ActionBase {
8
- constructor() {
9
- this.std = 'stderr';
10
- this.stdmockOrigs = {
11
- stdout: stream_1.stdout.write,
12
- stderr: stream_1.stderr.write,
13
- };
14
- }
8
+ type;
9
+ std = 'stderr';
10
+ stdmocks;
11
+ stdmockOrigs = {
12
+ stdout: stream_1.stdout.write,
13
+ stderr: stream_1.stderr.write,
14
+ };
15
15
  start(action, status, opts = {}) {
16
16
  this.std = opts.stdout ? 'stdout' : 'stderr';
17
17
  const task = { action, status, active: Boolean(this.task && this.task.active) };
@@ -2,10 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const base_1 = require("./base");
4
4
  class SimpleAction extends base_1.ActionBase {
5
- constructor() {
6
- super(...arguments);
7
- this.type = 'simple';
8
- }
5
+ type = 'simple';
9
6
  _start() {
10
7
  if (!this.task)
11
8
  return;
@@ -15,9 +15,12 @@ function color(s) {
15
15
  return has256 ? `\u001B[38;5;104m${s}${ansi_styles_1.default.reset.open}` : chalk_1.default.magenta(s);
16
16
  }
17
17
  class SpinnerAction extends base_1.ActionBase {
18
+ type = 'spinner';
19
+ spinner;
20
+ frames;
21
+ frameIndex;
18
22
  constructor() {
19
23
  super();
20
- this.type = 'spinner';
21
24
  this.frames = this.getFrames();
22
25
  this.frameIndex = 0;
23
26
  }
@@ -55,7 +58,7 @@ class SpinnerAction extends base_1.ActionBase {
55
58
  }
56
59
  getFrames(opts) {
57
60
  if (opts?.style)
58
- return spinners_1.default[process.platform === 'win32' ? 'line' : opts.style].frames;
61
+ return spinners_1.default[opts.style].frames;
59
62
  return spinners_1.default[process.platform === 'win32' ? 'line' : 'dots2'].frames;
60
63
  }
61
64
  _render(icon) {
@@ -13,12 +13,10 @@ const actionType = (Boolean(process.stderr.isTTY)
13
13
  && 'spinner') || 'simple';
14
14
  const Action = actionType === 'spinner' ? spinner_1.default : simple_1.default;
15
15
  class Config {
16
- constructor() {
17
- this.outputLevel = 'info';
18
- this.action = new Action();
19
- this.errorsHandled = false;
20
- this.showStackTrace = true;
21
- }
16
+ outputLevel = 'info';
17
+ action = new Action();
18
+ errorsHandled = false;
19
+ showStackTrace = true;
22
20
  get debug() {
23
21
  return globals.debug || process.env.DEBUG === '*';
24
22
  }
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ExitError = void 0;
4
4
  class ExitError extends Error {
5
+ ux;
6
+ code;
7
+ error;
5
8
  constructor(status, error) {
6
9
  const code = 'EEXIT';
7
10
  super(error ? error.message : `${code}: ${status}`);
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.flush = void 0;
4
- const __1 = require("..");
4
+ const errors_1 = require("../errors");
5
+ const stream_1 = require("./stream");
5
6
  function timeout(p, ms) {
6
7
  function wait(ms, unref = false) {
7
8
  return new Promise(resolve => {
@@ -10,13 +11,13 @@ function timeout(p, ms) {
10
11
  t.unref();
11
12
  });
12
13
  }
13
- return Promise.race([p, wait(ms, true).then(() => __1.Errors.error('timed out'))]);
14
+ return Promise.race([p, wait(ms, true).then(() => (0, errors_1.error)('timed out'))]);
14
15
  }
15
16
  async function _flush() {
16
17
  const p = new Promise(resolve => {
17
- __1.stdout.once('drain', () => resolve(null));
18
+ stream_1.stdout.once('drain', () => resolve(null));
18
19
  });
19
- const flushed = __1.stdout.write('');
20
+ const flushed = stream_1.stdout.write('');
20
21
  if (flushed)
21
22
  return;
22
23
  return p;
@@ -13,6 +13,7 @@ const node_util_1 = require("node:util");
13
13
  const wait_1 = tslib_1.__importDefault(require("./wait"));
14
14
  const hyperlinker = require('hyperlinker');
15
15
  class ux {
16
+ static config = config_1.config;
16
17
  static get prompt() {
17
18
  return uxPrompt.prompt;
18
19
  }
@@ -92,7 +93,6 @@ class ux {
92
93
  }
93
94
  }
94
95
  exports.ux = ux;
95
- ux.config = config_1.config;
96
96
  const { action, annotation, anykey, confirm, debug, done, flush, info, log, progress, prompt, styledHeader, styledJSON, styledObject, table, trace, tree, url, wait, } = ux;
97
97
  exports.action = action;
98
98
  exports.annotation = annotation;
@@ -5,6 +5,7 @@ exports.stderr = exports.stdout = void 0;
5
5
  * A wrapper around process.stdout and process.stderr that allows us to mock out the streams for testing.
6
6
  */
7
7
  class Stream {
8
+ channel;
8
9
  constructor(channel) {
9
10
  this.channel = channel;
10
11
  }
@@ -2,15 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
5
- const index_1 = require("../../index");
5
+ const node_util_1 = require("node:util");
6
+ const stream_1 = require("../stream");
7
+ const info = (output) => stream_1.stdout.write((0, node_util_1.format)(output) + '\n');
6
8
  function styledJSON(obj) {
7
9
  const json = JSON.stringify(obj, null, 2);
8
10
  if (!chalk_1.default.level) {
9
- index_1.ux.info(json);
11
+ info(json);
10
12
  return;
11
13
  }
12
14
  const cardinal = require('cardinal');
13
15
  const theme = require('cardinal/themes/jq');
14
- index_1.ux.info(cardinal.highlight(json, { json: true, theme }));
16
+ info(cardinal.highlight(json, { json: true, theme }));
15
17
  }
16
18
  exports.default = styledJSON;
@@ -13,6 +13,9 @@ const stream_1 = require("../stream");
13
13
  const screen_1 = require("../../screen");
14
14
  const string_width_1 = tslib_1.__importDefault(require("string-width"));
15
15
  class Table {
16
+ data;
17
+ options;
18
+ columns;
16
19
  constructor(data, columns, options = {}) {
17
20
  this.data = data;
18
21
  // assign columns
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Tree = void 0;
4
4
  const treeify = require('object-treeify');
5
5
  class Tree {
6
- constructor() {
7
- this.nodes = {};
8
- }
6
+ nodes = {};
9
7
  insert(child, value = new Tree()) {
10
8
  this.nodes[child] = value;
11
9
  return this;
package/lib/command.d.ts CHANGED
@@ -65,13 +65,7 @@ export declare abstract class Command {
65
65
  */
66
66
  static examples: Command.Example[];
67
67
  static hasDynamicHelp: boolean;
68
- protected static '_--': boolean;
69
- protected static _enableJsonFlag: boolean;
70
- static get enableJsonFlag(): boolean;
71
- static set enableJsonFlag(value: boolean);
72
- static get '--'(): boolean;
73
- static set '--'(value: boolean);
74
- get passThroughEnabled(): boolean;
68
+ static enableJsonFlag: boolean;
75
69
  /**
76
70
  * instantiate and run the command
77
71
  *
@@ -81,13 +75,9 @@ export declare abstract class Command {
81
75
  * @returns {Promise<unknown>} result
82
76
  */
83
77
  static run<T extends Command>(this: new (argv: string[], config: Config) => T, argv?: string[], opts?: LoadOptions): Promise<ReturnType<T['run']>>;
84
- protected static _baseFlags: FlagInput;
85
- static get baseFlags(): FlagInput;
86
- static set baseFlags(flags: FlagInput);
78
+ static baseFlags: FlagInput;
87
79
  /** A hash of flags for the command */
88
- protected static _flags: FlagInput;
89
- static get flags(): FlagInput;
90
- static set flags(flags: FlagInput);
80
+ static flags: FlagInput;
91
81
  id: string | undefined;
92
82
  protected debug: (...args: any[]) => void;
93
83
  constructor(argv: string[], config: Config);
@@ -164,7 +154,9 @@ export declare namespace Command {
164
154
  };
165
155
  type Flag = IFlag<any>;
166
156
  namespace Flag {
167
- type Cached = Omit<Flag, 'parse' | 'input'> & (BooleanFlagProps | OptionFlagProps);
157
+ type Cached = Omit<Flag, 'parse' | 'input'> & (BooleanFlagProps | OptionFlagProps) & {
158
+ hasDynamicHelp?: boolean;
159
+ };
168
160
  type Any = Flag | Cached;
169
161
  }
170
162
  type Arg = IArg<any>;
package/lib/command.js CHANGED
@@ -9,7 +9,7 @@ const util_1 = require("./help/util");
9
9
  const util_2 = require("./util");
10
10
  const stream_1 = require("./cli-ux/stream");
11
11
  const config_1 = require("./config");
12
- const flags_1 = require("./flags");
12
+ const aggregate_flags_1 = require("./util/aggregate-flags");
13
13
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
14
14
  const node_url_1 = require("node:url");
15
15
  const cli_ux_1 = require("./cli-ux");
@@ -23,40 +23,68 @@ stream_1.stdout.on('error', (err) => {
23
23
  return;
24
24
  throw err;
25
25
  });
26
- const jsonFlag = {
27
- json: (0, flags_1.boolean)({
28
- description: 'Format output as json.',
29
- helpGroup: 'GLOBAL',
30
- }),
31
- };
32
26
  /**
33
27
  * An abstract class which acts as the base for each command
34
28
  * in your project.
35
29
  */
36
30
  class Command {
37
- static get enableJsonFlag() {
38
- return this._enableJsonFlag;
39
- }
40
- static set enableJsonFlag(value) {
41
- this._enableJsonFlag = value;
42
- if (value === true) {
43
- this.baseFlags = jsonFlag;
44
- }
45
- else {
46
- delete this.baseFlags?.json;
47
- this.flags = {}; // force the flags setter to run
48
- delete this.flags?.json;
49
- }
50
- }
51
- static get '--'() {
52
- return Command['_--'];
53
- }
54
- static set '--'(value) {
55
- Command['_--'] = value;
56
- }
57
- get passThroughEnabled() {
58
- return Command['_--'];
59
- }
31
+ argv;
32
+ config;
33
+ static _base = `${pjson.name}@${pjson.version}`;
34
+ /** A command ID, used mostly in error or verbose reporting. */
35
+ static id;
36
+ /**
37
+ * The tweet-sized description for your class, used in a parent-commands
38
+ * sub-command listing and as the header for the command help.
39
+ */
40
+ static summary;
41
+ /**
42
+ * A full description of how to use the command.
43
+ *
44
+ * If no summary, the first line of the description will be used as the summary.
45
+ */
46
+ static description;
47
+ /** Hide the command from help */
48
+ static hidden;
49
+ /** Mark the command as a given state (e.g. beta or deprecated) in help */
50
+ static state;
51
+ static deprecationOptions;
52
+ /**
53
+ * Emit deprecation warning when a command alias is used
54
+ */
55
+ static deprecateAliases;
56
+ /**
57
+ * An override string (or strings) for the default usage documentation.
58
+ */
59
+ static usage;
60
+ static help;
61
+ /** An array of aliases for this command. */
62
+ static aliases = [];
63
+ /** When set to false, allows a variable amount of arguments */
64
+ static strict = true;
65
+ /** An order-dependent object of arguments for the command */
66
+ static args = {};
67
+ static plugin;
68
+ static pluginName;
69
+ static pluginType;
70
+ static pluginAlias;
71
+ /**
72
+ * An array of examples to show at the end of the command's help.
73
+ *
74
+ * IF only a string is provided, it will try to look for a line that starts
75
+ * with the cmd.bin as the example command and the rest as the description.
76
+ * If found, the command will be formatted appropriately.
77
+ *
78
+ * ```
79
+ * EXAMPLES:
80
+ * A description of a particular use case.
81
+ *
82
+ * $ <%= config.bin => command flags
83
+ * ```
84
+ */
85
+ static examples;
86
+ static hasDynamicHelp = false;
87
+ static enableJsonFlag = false;
60
88
  /**
61
89
  * instantiate and run the command
62
90
  *
@@ -81,21 +109,11 @@ class Command {
81
109
  }
82
110
  return cmd._run();
83
111
  }
84
- static get baseFlags() {
85
- return this._baseFlags;
86
- }
87
- static set baseFlags(flags) {
88
- // eslint-disable-next-line prefer-object-spread
89
- this._baseFlags = Object.assign({}, this.baseFlags, flags);
90
- this.flags = {}; // force the flags setter to run
91
- }
92
- static get flags() {
93
- return this._flags;
94
- }
95
- static set flags(flags) {
96
- // eslint-disable-next-line prefer-object-spread
97
- this._flags = Object.assign({}, this._flags ?? {}, this.baseFlags, flags);
98
- }
112
+ static baseFlags;
113
+ /** A hash of flags for the command */
114
+ static flags;
115
+ id;
116
+ debug;
99
117
  constructor(argv, config) {
100
118
  this.argv = argv;
101
119
  this.config = config;
@@ -161,16 +179,19 @@ class Command {
161
179
  * @returns {boolean} true if the command supports json and the --json flag is present
162
180
  */
163
181
  jsonEnabled() {
164
- // if the command doesn't support json, return false
182
+ // If the command doesn't support json, return false
165
183
  if (!this.ctor.enableJsonFlag)
166
184
  return false;
167
- // if the command parameter pass through is enabled, return true if the --json flag is before the '--' separator
168
- if (this.passThroughEnabled) {
169
- const ptIndex = this.argv.indexOf('--');
170
- const jsonIndex = this.argv.indexOf('--json');
171
- return jsonIndex > -1 && (ptIndex === -1 || jsonIndex < ptIndex);
172
- }
173
- return this.argv.includes('--json') || this.config.scopedEnvVar?.('CONTENT_TYPE')?.toLowerCase() === 'json';
185
+ // If the CONTENT_TYPE env var is set to json, return true
186
+ if (this.config.scopedEnvVar?.('CONTENT_TYPE')?.toLowerCase() === 'json')
187
+ return true;
188
+ const passThroughIndex = this.argv.indexOf('--');
189
+ const jsonIndex = this.argv.indexOf('--json');
190
+ return passThroughIndex === -1
191
+ // If '--' is not present, then check for `--json` in this.argv
192
+ ? jsonIndex > -1
193
+ // If '--' is present, return true only the --json flag exists and is before the '--'
194
+ : jsonIndex > -1 && jsonIndex < passThroughIndex;
174
195
  }
175
196
  async init() {
176
197
  this.debug('init version: %s argv: %o', this.ctor._base, this.argv);
@@ -184,8 +205,9 @@ class Command {
184
205
  this.warnIfCommandDeprecated();
185
206
  }
186
207
  warnIfFlagDeprecated(flags) {
208
+ const allFlags = (0, aggregate_flags_1.aggregateFlags)(this.ctor.flags, this.ctor.baseFlags, this.ctor.enableJsonFlag);
187
209
  for (const flag of Object.keys(flags)) {
188
- const flagDef = this.ctor.flags[flag];
210
+ const flagDef = allFlags[flag];
189
211
  const deprecated = flagDef?.deprecated;
190
212
  if (deprecated) {
191
213
  this.warn((0, util_1.formatFlagDeprecationWarning)(flag, deprecated));
@@ -221,10 +243,11 @@ class Command {
221
243
  async parse(options, argv = this.argv) {
222
244
  if (!options)
223
245
  options = this.ctor;
224
- const opts = { context: this, ...options };
225
- // the spread operator doesn't work with getters so we have to manually add it here
226
- opts.flags = options?.flags;
227
- opts.args = options?.args;
246
+ const opts = {
247
+ context: this,
248
+ ...options,
249
+ flags: (0, aggregate_flags_1.aggregateFlags)(options.flags, options.baseFlags, options.enableJsonFlag),
250
+ };
228
251
  const results = await Parser.parse(argv, opts);
229
252
  this.warnIfFlagDeprecated(results.flags ?? {});
230
253
  return results;
@@ -275,13 +298,3 @@ class Command {
275
298
  }
276
299
  }
277
300
  exports.Command = Command;
278
- Command._base = `${pjson.name}@${pjson.version}`;
279
- /** An array of aliases for this command. */
280
- Command.aliases = [];
281
- /** When set to false, allows a variable amount of arguments */
282
- Command.strict = true;
283
- /** An order-dependent object of arguments for the command */
284
- Command.args = {};
285
- Command.hasDynamicHelp = false;
286
- Command['_--'] = false;
287
- Command._enableJsonFlag = false;
@@ -154,4 +154,3 @@ export declare class Config implements IConfig {
154
154
  */
155
155
  private insertLegacyPlugins;
156
156
  }
157
- export declare function toCached(c: Command.Class, plugin?: IPlugin, respectNoCacheDefault?: boolean): Promise<Command.Cached>;