@oclif/core 1.24.0 → 2.0.0-beta.4

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 (90) hide show
  1. package/README.md +5 -5
  2. package/lib/args.d.ts +39 -0
  3. package/lib/args.js +62 -0
  4. package/lib/cli-ux/action/base.d.ts +1 -1
  5. package/lib/cli-ux/action/pride-spinner.js +0 -1
  6. package/lib/cli-ux/action/spinner.js +10 -11
  7. package/lib/cli-ux/action/spinners.d.ts +251 -0
  8. package/lib/cli-ux/action/spinners.js +2 -1
  9. package/lib/cli-ux/config.d.ts +1 -1
  10. package/lib/cli-ux/config.js +7 -5
  11. package/lib/cli-ux/index.d.ts +27 -32
  12. package/lib/cli-ux/index.js +67 -24
  13. package/lib/cli-ux/list.js +3 -4
  14. package/lib/cli-ux/prompt.js +9 -8
  15. package/lib/cli-ux/styled/header.js +1 -1
  16. package/lib/cli-ux/styled/index.d.ts +7 -0
  17. package/lib/cli-ux/styled/index.js +15 -0
  18. package/lib/cli-ux/styled/json.d.ts +1 -1
  19. package/lib/cli-ux/styled/json.js +2 -3
  20. package/lib/cli-ux/styled/object.js +1 -1
  21. package/lib/cli-ux/styled/progress.d.ts +2 -1
  22. package/lib/cli-ux/styled/progress.js +1 -5
  23. package/lib/cli-ux/styled/table.js +1 -3
  24. package/lib/cli-ux/styled/tree.js +0 -1
  25. package/lib/cli-ux/wait.d.ts +1 -1
  26. package/lib/cli-ux/wait.js +0 -1
  27. package/lib/command.d.ts +77 -26
  28. package/lib/command.js +46 -43
  29. package/lib/config/config.d.ts +18 -17
  30. package/lib/config/config.js +46 -22
  31. package/lib/config/index.js +0 -5
  32. package/lib/config/plugin.d.ts +3 -2
  33. package/lib/config/plugin.js +4 -13
  34. package/lib/config/util.js +2 -2
  35. package/lib/errors/index.js +0 -1
  36. package/lib/errors/logger.js +2 -4
  37. package/lib/flags.d.ts +46 -18
  38. package/lib/flags.js +71 -29
  39. package/lib/help/command.d.ts +12 -12
  40. package/lib/help/command.js +6 -6
  41. package/lib/help/docopts.d.ts +3 -3
  42. package/lib/help/docopts.js +2 -3
  43. package/lib/help/formatter.d.ts +4 -3
  44. package/lib/help/index.d.ts +10 -14
  45. package/lib/help/index.js +0 -5
  46. package/lib/help/util.d.ts +3 -3
  47. package/lib/help/util.js +1 -1
  48. package/lib/index.d.ts +5 -4
  49. package/lib/index.js +10 -8
  50. package/lib/interfaces/args.d.ts +22 -0
  51. package/lib/interfaces/{command.js → args.js} +0 -0
  52. package/lib/interfaces/config.d.ts +1 -2
  53. package/lib/interfaces/flags.d.ts +2 -2
  54. package/lib/interfaces/hooks.d.ts +1 -1
  55. package/lib/interfaces/index.d.ts +2 -2
  56. package/lib/interfaces/manifest.d.ts +2 -2
  57. package/lib/interfaces/parser.d.ts +96 -81
  58. package/lib/interfaces/plugin.d.ts +1 -1
  59. package/lib/main.d.ts +54 -1
  60. package/lib/main.js +70 -6
  61. package/lib/parser/errors.d.ts +15 -8
  62. package/lib/parser/errors.js +17 -14
  63. package/lib/parser/help.d.ts +1 -1
  64. package/lib/parser/help.js +4 -9
  65. package/lib/parser/index.d.ts +2 -9
  66. package/lib/parser/index.js +5 -26
  67. package/lib/parser/parse.d.ts +4 -11
  68. package/lib/parser/parse.js +108 -72
  69. package/lib/parser/validate.d.ts +1 -1
  70. package/lib/parser/validate.js +6 -3
  71. package/lib/util.d.ts +8 -0
  72. package/lib/util.js +44 -1
  73. package/package.json +4 -4
  74. package/lib/cli-ux/deps.d.ts +0 -22
  75. package/lib/cli-ux/deps.js +0 -47
  76. package/lib/cli-ux/open.d.ts +0 -6
  77. package/lib/cli-ux/open.js +0 -69
  78. package/lib/help/_test-help-class.d.ts +0 -6
  79. package/lib/help/_test-help-class.js +0 -19
  80. package/lib/interfaces/command.d.ts +0 -110
  81. package/lib/parser/args.d.ts +0 -5
  82. package/lib/parser/args.js +0 -11
  83. package/lib/parser/deps.d.ts +0 -4
  84. package/lib/parser/deps.js +0 -17
  85. package/lib/parser/flags.d.ts +0 -60
  86. package/lib/parser/flags.js +0 -107
  87. package/lib/parser/list.d.ts +0 -2
  88. package/lib/parser/list.js +0 -29
  89. package/lib/parser/util.d.ts +0 -7
  90. package/lib/parser/util.js +0 -50
package/lib/command.js CHANGED
@@ -1,14 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Command = void 0;
3
4
  const url_1 = require("url");
5
+ const chalk = require("chalk");
4
6
  const util_1 = require("util");
5
- const index_1 = require("./index");
7
+ const ux = require("./cli-ux");
6
8
  const config_1 = require("./config");
7
9
  const Errors = require("./errors");
8
10
  const Parser = require("./parser");
9
- const Flags = require("./flags");
10
11
  const util_2 = require("./help/util");
11
- const pjson = require('../package.json');
12
+ const flags_1 = require("./flags");
13
+ const util_3 = require("./util");
14
+ const pjson = (0, util_3.requireJson)(__dirname, '..', 'package.json');
12
15
  /**
13
16
  * swallows stdout epipe errors
14
17
  * this occurs when stdout closes such as when piping to head
@@ -19,7 +22,7 @@ process.stdout.on('error', (err) => {
19
22
  throw err;
20
23
  });
21
24
  const jsonFlag = {
22
- json: Flags.boolean({
25
+ json: (0, flags_1.boolean)({
23
26
  description: 'Format output as json.',
24
27
  helpGroup: 'GLOBAL',
25
28
  }),
@@ -35,26 +38,45 @@ class Command {
35
38
  static set enableJsonFlag(value) {
36
39
  this._enableJsonFlag = value;
37
40
  if (value === true) {
38
- this.globalFlags = jsonFlag;
41
+ this.baseFlags = jsonFlag;
39
42
  }
40
43
  else {
41
- delete this.globalFlags?.json;
44
+ delete this.baseFlags?.json;
42
45
  this.flags = {}; // force the flags setter to run
43
46
  delete this.flags?.json;
44
47
  }
45
48
  }
46
- static get globalFlags() {
47
- return this._globalFlags;
48
- }
49
- static set globalFlags(flags) {
50
- this._globalFlags = Object.assign({}, this.globalFlags, flags);
49
+ /**
50
+ * instantiate and run the command
51
+ *
52
+ * @param {Command.Class} this - the command class
53
+ * @param {string[]} argv argv
54
+ * @param {LoadOptions} opts options
55
+ * @returns {Promise<unknown>} result
56
+ */
57
+ static async run(argv, opts) {
58
+ if (!argv)
59
+ argv = process.argv.slice(2);
60
+ // Handle the case when a file URL string is passed in such as 'import.meta.url'; covert to file path.
61
+ if (typeof opts === 'string' && opts.startsWith('file://')) {
62
+ opts = (0, url_1.fileURLToPath)(opts);
63
+ }
64
+ const config = await config_1.Config.load(opts || require.main?.filename || __dirname);
65
+ const cmd = new this(argv, config);
66
+ return cmd._run();
67
+ }
68
+ static get baseFlags() {
69
+ return this._baseFlags;
70
+ }
71
+ static set baseFlags(flags) {
72
+ this._baseFlags = Object.assign({}, this.baseFlags, flags);
51
73
  this.flags = {}; // force the flags setter to run
52
74
  }
53
75
  static get flags() {
54
76
  return this._flags;
55
77
  }
56
78
  static set flags(flags) {
57
- this._flags = Object.assign({}, this._flags ?? {}, this.globalFlags, flags);
79
+ this._flags = Object.assign({}, this._flags ?? {}, this.baseFlags, flags);
58
80
  }
59
81
  constructor(argv, config) {
60
82
  this.argv = argv;
@@ -87,7 +109,7 @@ class Command {
87
109
  await this.finally(err);
88
110
  }
89
111
  if (result && this.jsonEnabled()) {
90
- index_1.CliUx.ux.styledJSON(this.toSuccessJson(result));
112
+ ux.styledJSON(this.toSuccessJson(result));
91
113
  }
92
114
  return result;
93
115
  }
@@ -137,7 +159,7 @@ class Command {
137
159
  const deprecateAliases = this.ctor.flags[flag]?.deprecateAliases;
138
160
  const aliases = (this.ctor.flags[flag]?.aliases ?? []).map(a => a.length === 1 ? `-${a}` : `--${a}`);
139
161
  if (deprecateAliases && aliases.length > 0) {
140
- const foundAliases = this.argv.filter(a => aliases.includes(a));
162
+ const foundAliases = aliases.filter(alias => this.argv.some(a => a.startsWith(alias)));
141
163
  for (const alias of foundAliases) {
142
164
  this.warn((0, util_2.formatFlagDeprecationWarning)(alias, { to: this.ctor.flags[flag]?.name }));
143
165
  }
@@ -147,18 +169,18 @@ class Command {
147
169
  warnIfCommandDeprecated() {
148
170
  const [id] = (0, util_2.normalizeArgv)(this.config);
149
171
  if (this.ctor.deprecateAliases && this.ctor.aliases.includes(id)) {
150
- const cmdName = (0, index_1.toConfiguredId)(this.ctor.id, this.config);
151
- const aliasName = (0, index_1.toConfiguredId)(id, this.config);
172
+ const cmdName = (0, util_2.toConfiguredId)(this.ctor.id, this.config);
173
+ const aliasName = (0, util_2.toConfiguredId)(id, this.config);
152
174
  this.warn((0, util_2.formatCommandDeprecationWarning)(aliasName, { to: cmdName }));
153
175
  }
154
176
  if (this.ctor.state === 'deprecated') {
155
- const cmdName = (0, index_1.toConfiguredId)(this.ctor.id, this.config);
177
+ const cmdName = (0, util_2.toConfiguredId)(this.ctor.id, this.config);
156
178
  this.warn((0, util_2.formatCommandDeprecationWarning)(cmdName, this.ctor.deprecationOptions));
157
179
  }
158
180
  }
159
181
  async parse(options, argv = this.argv) {
160
182
  if (!options)
161
- options = this.constructor;
183
+ options = this.ctor;
162
184
  const opts = { context: this, ...options };
163
185
  // the spread operator doesn't work with getters so we have to manually add it here
164
186
  opts.flags = options?.flags;
@@ -170,14 +192,13 @@ class Command {
170
192
  async catch(err) {
171
193
  process.exitCode = process.exitCode ?? err.exitCode ?? 1;
172
194
  if (this.jsonEnabled()) {
173
- index_1.CliUx.ux.styledJSON(this.toErrorJson(err));
195
+ ux.styledJSON(this.toErrorJson(err));
174
196
  }
175
197
  else {
176
198
  if (!err.message)
177
199
  throw err;
178
200
  try {
179
- const chalk = require('chalk');
180
- index_1.CliUx.ux.action.stop(chalk.bold.red('!'));
201
+ ux.action.stop(chalk.bold.red('!'));
181
202
  }
182
203
  catch { }
183
204
  throw err;
@@ -200,31 +221,13 @@ class Command {
200
221
  return { error: err };
201
222
  }
202
223
  }
203
- exports.default = Command;
224
+ exports.Command = Command;
204
225
  Command._base = `${pjson.name}@${pjson.version}`;
205
226
  /** An array of aliases for this command. */
206
227
  Command.aliases = [];
207
228
  /** When set to false, allows a variable amount of arguments */
208
229
  Command.strict = true;
209
- Command.parse = true;
210
- Command.parserOptions = {};
230
+ /** An order-dependent object of arguments for the command */
231
+ Command.args = {};
232
+ Command.hasDynamicHelp = false;
211
233
  Command._enableJsonFlag = false;
212
- // eslint-disable-next-line valid-jsdoc
213
- /**
214
- * instantiate and run the command
215
- * @param {Interfaces.Command.Class} this Class
216
- * @param {string[]} argv argv
217
- * @param {Interfaces.LoadOptions} opts options
218
- */
219
- Command.run = async function (argv, opts) {
220
- if (!argv)
221
- argv = process.argv.slice(2);
222
- // Handle the case when a file URL string is passed in such as 'import.meta.url'; covert to file path.
223
- if (typeof opts === 'string' && opts.startsWith('file://')) {
224
- opts = (0, url_1.fileURLToPath)(opts);
225
- }
226
- // to-do: update in node-14 to module.main
227
- const config = await config_1.Config.load(opts || (module.parent && module.parent.parent && module.parent.parent.filename) || __dirname);
228
- const cmd = new this(argv, config);
229
- return cmd._run(argv);
230
- };
@@ -1,35 +1,36 @@
1
1
  import { Options, Plugin as IPlugin } from '../interfaces/plugin';
2
2
  import { Config as IConfig, ArchTypes, PlatformTypes, LoadOptions } from '../interfaces/config';
3
- import { Command, Hook, Hooks, PJSON, Topic } from '../interfaces';
3
+ import { Hook, Hooks, PJSON, Topic } from '../interfaces';
4
4
  import * as Plugin from './plugin';
5
+ import { Command } from '../command';
5
6
  export declare class Config implements IConfig {
6
7
  options: Options;
7
- _base: string;
8
- name: string;
9
- version: string;
10
- channel: string;
11
- root: string;
8
+ private _base;
12
9
  arch: ArchTypes;
13
10
  bin: string;
11
+ binPath?: string;
14
12
  cacheDir: string;
13
+ channel: string;
15
14
  configDir: string;
16
15
  dataDir: string;
16
+ debug: number;
17
17
  dirname: string;
18
18
  errlog: string;
19
+ flexibleTaxonomy: boolean;
19
20
  home: string;
21
+ name: string;
22
+ npmRegistry?: string;
23
+ pjson: PJSON.CLI;
20
24
  platform: PlatformTypes;
25
+ plugins: IPlugin[];
26
+ root: string;
21
27
  shell: string;
22
- windows: boolean;
28
+ topicSeparator: ':' | ' ';
23
29
  userAgent: string;
24
- debug: number;
25
- npmRegistry?: string;
26
- pjson: PJSON.CLI;
27
30
  userPJSON?: PJSON.User;
28
- plugins: IPlugin[];
29
- binPath?: string;
30
31
  valid: boolean;
31
- topicSeparator: ':' | ' ';
32
- flexibleTaxonomy: boolean;
32
+ version: string;
33
+ windows: boolean;
33
34
  protected warned: boolean;
34
35
  private commandPermutations;
35
36
  private topicPermutations;
@@ -37,13 +38,13 @@ export declare class Config implements IConfig {
37
38
  private _topics;
38
39
  private _commandIDs;
39
40
  constructor(options: Options);
40
- static load(opts?: LoadOptions): Promise<IConfig | Config>;
41
+ static load(opts?: LoadOptions): Promise<Config>;
41
42
  load(): Promise<void>;
42
43
  loadCorePlugins(): Promise<void>;
43
44
  loadDevPlugins(): Promise<void>;
44
45
  loadUserPlugins(): Promise<void>;
45
46
  runHook<T extends keyof Hooks>(event: T, opts: Hooks[T]['options'], timeout?: number): Promise<Hook.Result<Hooks[T]['return']>>;
46
- runCommand<T = unknown>(id: string, argv?: string[], cachedCommand?: Command.Loadable): Promise<T>;
47
+ runCommand<T = unknown>(id: string, argv?: string[], cachedCommand?: Command.Loadable | null): Promise<T>;
47
48
  scopedEnvVar(k: string): string | undefined;
48
49
  scopedEnvVarTrue(k: string): boolean;
49
50
  scopedEnvVarKey(k: string): string;
@@ -130,4 +131,4 @@ export declare class Config implements IConfig {
130
131
  */
131
132
  private determinePriority;
132
133
  }
133
- export declare function toCached(c: Command.Class, plugin?: IPlugin): Promise<Command>;
134
+ export declare function toCached(c: Command.Class, plugin?: IPlugin): Promise<Command.Cached>;
@@ -14,7 +14,7 @@ const module_loader_1 = require("../module-loader");
14
14
  const util_4 = require("../help/util");
15
15
  // eslint-disable-next-line new-cap
16
16
  const debug = (0, util_2.Debug)();
17
- const _pjson = require('../../package.json');
17
+ const _pjson = (0, util_3.requireJson)(__dirname, '..', '..', 'package.json');
18
18
  function channelFromVersion(version) {
19
19
  const m = version.match(/[^-]+(?:-([^.]+))?/);
20
20
  return (m && m[1]) || 'stable';
@@ -53,7 +53,6 @@ class Permutations extends Map {
53
53
  }
54
54
  }
55
55
  class Config {
56
- // eslint-disable-next-line no-useless-constructor
57
56
  constructor(options) {
58
57
  this.options = options;
59
58
  this._base = `${_pjson.name}@${_pjson.version}`;
@@ -66,7 +65,7 @@ class Config {
66
65
  this._commands = new Map();
67
66
  this._topics = new Map();
68
67
  }
69
- static async load(opts = (module.parent && module.parent.parent && module.parent.parent.filename) || __dirname) {
68
+ static async load(opts = module.filename || __dirname) {
70
69
  // Handle the case when a file URL string is passed in such as 'import.meta.url'; covert to file path.
71
70
  if (typeof opts === 'string' && opts.startsWith('file://')) {
72
71
  opts = (0, url_1.fileURLToPath)(opts);
@@ -249,10 +248,9 @@ class Config {
249
248
  debug('%s hook done', event);
250
249
  return final;
251
250
  }
252
- // eslint-disable-next-line default-param-last
253
- async runCommand(id, argv = [], cachedCommand) {
251
+ async runCommand(id, argv = [], cachedCommand = null) {
254
252
  debug('runCommand %s %o', id, argv);
255
- const c = cachedCommand || this.findCommand(id);
253
+ const c = cachedCommand ?? this.findCommand(id);
256
254
  if (!c) {
257
255
  const matches = this.flexibleTaxonomy ? this.findMatches(id, argv) : [];
258
256
  const hookResult = this.flexibleTaxonomy && matches.length > 0 ?
@@ -270,7 +268,7 @@ class Config {
270
268
  const command = await c.load();
271
269
  await this.runHook('prerun', { Command: command, argv });
272
270
  const result = (await command.run(argv, this));
273
- await this.runHook('postrun', { Command: command, result: result, argv });
271
+ await this.runHook('postrun', { Command: command, result, argv });
274
272
  return result;
275
273
  }
276
274
  scopedEnvVar(k) {
@@ -605,7 +603,7 @@ class Config {
605
603
  }
606
604
  exports.Config = Config;
607
605
  // when no manifest exists, the default is calculated. This may throw, so we need to catch it
608
- const defaultToCached = async (flag) => {
606
+ const defaultFlagToCached = async (flag) => {
609
607
  // Prefer the helpDefaultValue function (returns a friendly string for complex types)
610
608
  if (typeof flag.defaultHelp === 'function') {
611
609
  try {
@@ -626,6 +624,27 @@ const defaultToCached = async (flag) => {
626
624
  return flag.default;
627
625
  }
628
626
  };
627
+ const defaultArgToCached = async (arg) => {
628
+ // Prefer the helpDefaultValue function (returns a friendly string for complex types)
629
+ if (typeof arg.defaultHelp === 'function') {
630
+ try {
631
+ return await arg.defaultHelp();
632
+ }
633
+ catch {
634
+ return;
635
+ }
636
+ }
637
+ // if not specified, try the default function
638
+ if (typeof arg.default === 'function') {
639
+ try {
640
+ return await arg.default({ options: {}, flags: {} });
641
+ }
642
+ catch { }
643
+ }
644
+ else {
645
+ return arg.default;
646
+ }
647
+ };
629
648
  async function toCached(c, plugin) {
630
649
  const flags = {};
631
650
  for (const [name, flag] of Object.entries(c.flags || {})) {
@@ -647,6 +666,7 @@ async function toCached(c, plugin) {
647
666
  deprecated: flag.deprecated,
648
667
  deprecateAliases: c.deprecateAliases,
649
668
  aliases: flag.aliases,
669
+ delimiter: flag.delimiter,
650
670
  };
651
671
  }
652
672
  else {
@@ -666,10 +686,11 @@ async function toCached(c, plugin) {
666
686
  dependsOn: flag.dependsOn,
667
687
  relationships: flag.relationships,
668
688
  exclusive: flag.exclusive,
669
- default: await defaultToCached(flag),
689
+ default: await defaultFlagToCached(flag),
670
690
  deprecated: flag.deprecated,
671
691
  deprecateAliases: c.deprecateAliases,
672
692
  aliases: flag.aliases,
693
+ delimiter: flag.delimiter,
673
694
  };
674
695
  // a command-level placeholder in the manifest so that oclif knows it should regenerate the command during help-time
675
696
  if (typeof flag.defaultHelp === 'function') {
@@ -677,17 +698,21 @@ async function toCached(c, plugin) {
677
698
  }
678
699
  }
679
700
  }
680
- // v2 commands have args as an object, so we need to normalize it to an array for forwards compatibility
681
- const normalized = (Array.isArray(c.args) ? c.args ?? [] : Object.values(c.args ?? {}));
682
- const argsPromise = normalized.map(async (a) => ({
683
- name: a.name,
684
- description: a.description,
685
- required: a.required,
686
- options: a.options,
687
- default: typeof a.default === 'function' ? await a.default({}) : a.default,
688
- hidden: a.hidden,
689
- }));
690
- const args = await Promise.all(argsPromise);
701
+ // v1 commands have args as an array, so we need to normalize it to an object for backwards compatibility
702
+ const normalized = (Array.isArray(c.args) ? (c.args ?? []).reduce((x, y) => {
703
+ return { ...x, [y.name]: y };
704
+ }, {}) : c.args ?? {});
705
+ const args = {};
706
+ for (const [name, arg] of Object.entries(normalized)) {
707
+ args[name] = {
708
+ name,
709
+ description: arg.description,
710
+ required: arg.required,
711
+ options: arg.options,
712
+ default: await defaultArgToCached(arg),
713
+ hidden: arg.hidden,
714
+ };
715
+ }
691
716
  const stdProperties = {
692
717
  id: c.id,
693
718
  summary: c.summary,
@@ -706,8 +731,7 @@ async function toCached(c, plugin) {
706
731
  flags,
707
732
  args,
708
733
  };
709
- // do not include these properties in manifest
710
- const ignoreCommandProperties = ['plugin', '_flags', '_enableJsonFlag', '_globalFlags'];
734
+ const ignoreCommandProperties = ['plugin', '_flags', '_enableJsonFlag', '_baseFlags'];
711
735
  const stdKeys = Object.keys(stdProperties);
712
736
  const keysToAdd = Object.keys(c).filter(property => ![...stdKeys, ...ignoreCommandProperties].includes(property));
713
737
  const additionalProperties = {};
@@ -1,11 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.tsPath = exports.Plugin = exports.toCached = exports.Config = void 0;
4
- try {
5
- // eslint-disable-next-line node/no-missing-require
6
- require('fs-extra-debug');
7
- }
8
- catch { }
9
4
  var config_1 = require("./config");
10
5
  Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
11
6
  Object.defineProperty(exports, "toCached", { enumerable: true, get: function () { return config_1.toCached; } });
@@ -1,8 +1,9 @@
1
+ import { CLIError } from '../errors';
1
2
  import { Plugin as IPlugin, PluginOptions } from '../interfaces/plugin';
2
- import { Command } from '../interfaces/command';
3
3
  import { Manifest } from '../interfaces/manifest';
4
4
  import { PJSON } from '../interfaces/pjson';
5
5
  import { Topic } from '../interfaces/topic';
6
+ import { Command } from '../command';
6
7
  export declare class Plugin implements IPlugin {
7
8
  options: PluginOptions;
8
9
  _base: string;
@@ -36,6 +37,6 @@ export declare class Plugin implements IPlugin {
36
37
  must: boolean;
37
38
  }): Promise<Command.Class | undefined>;
38
39
  protected _manifest(ignoreManifest: boolean, errorOnManifestCreate?: boolean): Promise<Manifest>;
39
- protected warn(err: any, scope?: string): void;
40
+ protected warn(err: string | Error | CLIError, scope?: string): void;
40
41
  private addErrorScope;
41
42
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Plugin = void 0;
4
4
  const errors_1 = require("../errors");
5
+ const globby = require("globby");
5
6
  const path = require("path");
6
7
  const util_1 = require("util");
7
8
  const config_1 = require("./config");
@@ -10,17 +11,17 @@ const ts_node_1 = require("./ts-node");
10
11
  const util_3 = require("./util");
11
12
  const util_4 = require("../util");
12
13
  const module_loader_1 = require("../module-loader");
13
- const _pjson = require('../../package.json');
14
+ const _pjson = (0, util_4.requireJson)(__dirname, '..', '..', 'package.json');
14
15
  function topicsToArray(input, base) {
15
16
  if (!input)
16
17
  return [];
17
18
  base = base ? `${base}:` : '';
18
19
  if (Array.isArray(input)) {
19
- return input.concat((0, util_3.flatMap)(input, t => topicsToArray(t.subtopics, `${base}${t.name}`)));
20
+ return [...input, ...(0, util_3.flatMap)(input, t => topicsToArray(t.subtopics, `${base}${t.name}`))];
20
21
  }
21
22
  return (0, util_3.flatMap)(Object.keys(input), k => {
22
23
  input[k].name = k;
23
- return [{ ...input[k], name: `${base}${k}` }].concat(topicsToArray(input[k].subtopics, `${base}${input[k].name}`));
24
+ return [{ ...input[k], name: `${base}${k}` }, ...topicsToArray(input[k].subtopics, `${base}${input[k].name}`)];
24
25
  });
25
26
  }
26
27
  // essentially just "cd .."
@@ -86,7 +87,6 @@ async function findRoot(name, root) {
86
87
  return findSourcesRoot(root);
87
88
  }
88
89
  class Plugin {
89
- // eslint-disable-next-line no-useless-constructor
90
90
  constructor(options) {
91
91
  this.options = options;
92
92
  // static loadedPlugins: {[name: string]: Plugin} = {}
@@ -139,15 +139,6 @@ class Plugin {
139
139
  get commandIDs() {
140
140
  if (!this.commandsDir)
141
141
  return [];
142
- let globby;
143
- try {
144
- const globbyPath = require.resolve('globby', { paths: [this.root, __dirname] });
145
- globby = require(globbyPath);
146
- }
147
- catch (error) {
148
- this.warn(error, 'not loading commands, globby not found');
149
- return [];
150
- }
151
142
  this._debug(`loading IDs from ${this.commandsDir}`);
152
143
  const patterns = [
153
144
  '**/*.+(js|cjs|mjs|ts|tsx)',
@@ -4,7 +4,7 @@ exports.collectUsableIds = exports.getCommandIdPermutations = exports.getPermuta
4
4
  const fs = require("fs");
5
5
  const debug = require('debug');
6
6
  function flatMap(arr, fn) {
7
- return arr.reduce((arr, i) => arr.concat(fn(i)), []);
7
+ return arr.reduce((arr, i) => [...arr, ...fn(i)], []);
8
8
  }
9
9
  exports.flatMap = flatMap;
10
10
  function mapValues(obj, fn) {
@@ -81,7 +81,7 @@ function getPermutations(arr) {
81
81
  for (let j = 0, len2 = partial.length; j <= len2; j++) {
82
82
  const start = partial.slice(0, j);
83
83
  const end = partial.slice(j);
84
- const merged = start.concat(first, end);
84
+ const merged = [...start, first, ...end];
85
85
  output.push(merged);
86
86
  }
87
87
  }
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- // tslint:disable no-console
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.warn = exports.error = exports.exit = exports.config = exports.Logger = exports.CLIError = exports.ModuleLoadError = exports.ExitError = exports.handle = void 0;
5
4
  var handle_1 = require("./handle");
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Logger = void 0;
4
+ const fs = require("fs-extra");
4
5
  const path = require("path");
6
+ const stripAnsi = require("strip-ansi");
5
7
  const timestamp = () => new Date().toISOString();
6
8
  let timer;
7
9
  const wait = (ms) => new Promise(resolve => {
@@ -15,18 +17,15 @@ function chomp(s) {
15
17
  return s;
16
18
  }
17
19
  class Logger {
18
- // eslint-disable-next-line no-useless-constructor
19
20
  constructor(file) {
20
21
  this.file = file;
21
22
  this.flushing = Promise.resolve();
22
23
  this.buffer = [];
23
24
  }
24
25
  log(msg) {
25
- const stripAnsi = require('strip-ansi');
26
26
  msg = stripAnsi(chomp(msg));
27
27
  const lines = msg.split('\n').map(l => `${timestamp()} ${l}`.trimEnd());
28
28
  this.buffer.push(...lines);
29
- // tslint:disable-next-line no-console
30
29
  this.flush(50).catch(console.error);
31
30
  }
32
31
  async flush(waitForMs = 0) {
@@ -36,7 +35,6 @@ class Logger {
36
35
  return;
37
36
  const mylines = this.buffer;
38
37
  this.buffer = [];
39
- const fs = require('fs-extra');
40
38
  await fs.mkdirp(path.dirname(this.file));
41
39
  await fs.appendFile(this.file, mylines.join('\n') + '\n');
42
40
  });
package/lib/flags.d.ts CHANGED
@@ -1,21 +1,49 @@
1
- import { OptionFlag, BooleanFlag, EnumFlagOptions, Default } from './interfaces';
2
- export { boolean, integer, url, directory, file, string, build, option, custom } from './parser';
3
- export declare function _enum<T = string>(opts: EnumFlagOptions<T, true> & {
1
+ /// <reference types="node" />
2
+ import { URL } from 'url';
3
+ import { BooleanFlag } from './interfaces';
4
+ import { FlagDefinition, OptionFlagDefaults, FlagParser } from './interfaces/parser';
5
+ /**
6
+ * Create a custom flag.
7
+ *
8
+ * @example
9
+ * type Id = string
10
+ * type IdOpts = { startsWith: string; length: number };
11
+ *
12
+ * export const myFlag = custom<Id, IdOpts>({
13
+ * parse: async (input, opts) => {
14
+ * if (input.startsWith(opts.startsWith) && input.length === opts.length) {
15
+ * return input
16
+ * }
17
+ *
18
+ * throw new Error('Invalid id')
19
+ * },
20
+ * })
21
+ */
22
+ export declare function custom<T, P = Record<string, unknown>>(defaults: {
23
+ parse: FlagParser<T, string, P>;
4
24
  multiple: true;
5
- } & ({
6
- required: true;
7
- } | {
8
- default: Default<T[]>;
9
- })): OptionFlag<T[]>;
10
- export declare function _enum<T = string>(opts: EnumFlagOptions<T, true> & {
11
- multiple: true;
12
- }): OptionFlag<T[] | undefined>;
13
- export declare function _enum<T = string>(opts: EnumFlagOptions<T> & ({
14
- required: true;
15
- } | {
16
- default: Default<T>;
17
- })): OptionFlag<T>;
18
- export declare function _enum<T = string>(opts: EnumFlagOptions<T>): OptionFlag<T | undefined>;
19
- export { _enum as enum };
25
+ } & Partial<OptionFlagDefaults<T, P, true>>): FlagDefinition<T, P>;
26
+ export declare function custom<T, P = Record<string, unknown>>(defaults: {
27
+ parse: FlagParser<T, string, P>;
28
+ } & Partial<OptionFlagDefaults<T, P>>): FlagDefinition<T, P>;
29
+ export declare function custom<T = string, P = Record<string, unknown>>(defaults: Partial<OptionFlagDefaults<T, P>>): FlagDefinition<T, P>;
30
+ export declare function boolean<T = boolean>(options?: Partial<BooleanFlag<T>>): BooleanFlag<T>;
31
+ export declare const integer: FlagDefinition<number, {
32
+ min?: number | undefined;
33
+ max?: number | undefined;
34
+ }>;
35
+ export declare const directory: FlagDefinition<string, {
36
+ exists?: boolean | undefined;
37
+ }>;
38
+ export declare const file: FlagDefinition<string, {
39
+ exists?: boolean | undefined;
40
+ }>;
41
+ /**
42
+ * Initializes a string as a URL. Throws an error
43
+ * if the string is not a valid URL.
44
+ */
45
+ export declare const url: FlagDefinition<URL, Record<string, unknown>>;
46
+ declare const stringFlag: FlagDefinition<string, Record<string, unknown>>;
47
+ export { stringFlag as string };
20
48
  export declare const version: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;
21
49
  export declare const help: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;