@oclif/core 3.0.0-beta.9 → 3.0.0

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 (142) hide show
  1. package/README.md +4 -2
  2. package/flush.d.ts +3 -0
  3. package/flush.js +1 -0
  4. package/handle.js +1 -0
  5. package/lib/args.d.ts +2 -2
  6. package/lib/args.js +17 -18
  7. package/lib/{ux → cli-ux}/action/base.d.ts +19 -21
  8. package/lib/{ux → cli-ux}/action/base.js +126 -120
  9. package/lib/{ux → cli-ux}/action/simple.js +25 -30
  10. package/lib/{ux → cli-ux}/action/spinner.d.ts +9 -7
  11. package/lib/{ux → cli-ux}/action/spinner.js +45 -37
  12. package/lib/{ux → cli-ux}/action/spinners.js +187 -187
  13. package/lib/cli-ux/action/types.d.ts +5 -0
  14. package/lib/cli-ux/action/types.js +2 -0
  15. package/lib/{ux → cli-ux}/config.d.ts +5 -5
  16. package/lib/{ux → cli-ux}/config.js +17 -17
  17. package/lib/{ux → cli-ux}/exit.js +3 -0
  18. package/lib/cli-ux/flush.d.ts +1 -0
  19. package/lib/cli-ux/flush.js +28 -0
  20. package/lib/cli-ux/index.d.ts +39 -0
  21. package/lib/{ux → cli-ux}/index.js +74 -88
  22. package/lib/{ux → cli-ux}/list.js +3 -3
  23. package/lib/{ux → cli-ux}/prompt.d.ts +3 -3
  24. package/lib/{ux → cli-ux}/prompt.js +35 -25
  25. package/lib/{ux → cli-ux}/stream.d.ts +6 -6
  26. package/lib/{ux → cli-ux}/stream.js +11 -10
  27. package/lib/cli-ux/styled/index.d.ts +4 -0
  28. package/lib/cli-ux/styled/index.js +11 -0
  29. package/lib/{ux → cli-ux}/styled/object.js +7 -9
  30. package/lib/{ux → cli-ux}/styled/table.d.ts +10 -10
  31. package/lib/{ux → cli-ux}/styled/table.js +130 -133
  32. package/lib/{ux → cli-ux}/styled/tree.js +11 -13
  33. package/lib/cli-ux/wait.js +5 -0
  34. package/lib/command.d.ts +82 -88
  35. package/lib/command.js +196 -175
  36. package/lib/config/config.d.ts +89 -90
  37. package/lib/config/config.js +466 -566
  38. package/lib/config/index.d.ts +0 -1
  39. package/lib/config/index.js +1 -3
  40. package/lib/config/plugin-loader.d.ts +12 -12
  41. package/lib/config/plugin-loader.js +72 -56
  42. package/lib/config/plugin.d.ts +25 -24
  43. package/lib/config/plugin.js +188 -154
  44. package/lib/config/ts-node.d.ts +2 -1
  45. package/lib/config/ts-node.js +71 -58
  46. package/lib/config/util.d.ts +1 -11
  47. package/lib/config/util.js +6 -59
  48. package/lib/errors/config.d.ts +1 -1
  49. package/lib/errors/config.js +6 -6
  50. package/lib/errors/errors/cli.d.ts +7 -7
  51. package/lib/errors/errors/cli.js +20 -16
  52. package/lib/errors/errors/exit.d.ts +1 -4
  53. package/lib/errors/errors/exit.js +1 -1
  54. package/lib/errors/errors/module-load.d.ts +1 -4
  55. package/lib/errors/errors/module-load.js +1 -1
  56. package/lib/errors/errors/pretty-print.d.ts +1 -1
  57. package/lib/errors/errors/pretty-print.js +12 -10
  58. package/lib/errors/handle.d.ts +12 -2
  59. package/lib/errors/handle.js +26 -14
  60. package/lib/errors/index.d.ts +10 -10
  61. package/lib/errors/index.js +25 -24
  62. package/lib/errors/logger.d.ts +2 -2
  63. package/lib/errors/logger.js +14 -13
  64. package/lib/execute.d.ts +6 -6
  65. package/lib/execute.js +10 -9
  66. package/lib/flags.d.ts +103 -32
  67. package/lib/flags.js +79 -45
  68. package/lib/help/command.d.ts +16 -14
  69. package/lib/help/command.js +178 -163
  70. package/lib/help/docopts.d.ts +5 -5
  71. package/lib/help/docopts.js +50 -54
  72. package/lib/help/formatter.d.ts +37 -37
  73. package/lib/help/formatter.js +66 -55
  74. package/lib/help/index.d.ts +25 -21
  75. package/lib/help/index.js +169 -147
  76. package/lib/help/root.d.ts +1 -1
  77. package/lib/help/root.js +15 -17
  78. package/lib/help/util.d.ts +2 -8
  79. package/lib/help/util.js +8 -28
  80. package/lib/index.d.ts +19 -20
  81. package/lib/index.js +37 -43
  82. package/lib/interfaces/config.d.ts +67 -66
  83. package/lib/interfaces/errors.d.ts +5 -5
  84. package/lib/interfaces/help.d.ts +17 -17
  85. package/lib/interfaces/hooks.d.ts +49 -49
  86. package/lib/interfaces/index.d.ts +7 -7
  87. package/lib/interfaces/manifest.d.ts +1 -1
  88. package/lib/interfaces/parser.d.ts +175 -51
  89. package/lib/interfaces/pjson.d.ts +41 -41
  90. package/lib/interfaces/plugin.d.ts +47 -41
  91. package/lib/interfaces/s3-manifest.d.ts +7 -7
  92. package/lib/interfaces/topic.d.ts +1 -1
  93. package/lib/interfaces/ts-config.d.ts +7 -7
  94. package/lib/main.d.ts +2 -2
  95. package/lib/main.js +16 -16
  96. package/lib/module-loader.d.ts +67 -77
  97. package/lib/module-loader.js +183 -150
  98. package/lib/parser/errors.d.ts +7 -7
  99. package/lib/parser/errors.js +29 -22
  100. package/lib/parser/help.js +5 -5
  101. package/lib/parser/index.js +2 -2
  102. package/lib/parser/parse.d.ts +9 -6
  103. package/lib/parser/parse.js +253 -221
  104. package/lib/parser/validate.js +53 -33
  105. package/lib/performance.d.ts +43 -32
  106. package/lib/performance.js +133 -91
  107. package/lib/screen.js +2 -2
  108. package/lib/settings.d.ts +11 -12
  109. package/lib/settings.js +2 -2
  110. package/lib/util/aggregate-flags.d.ts +2 -0
  111. package/lib/util/aggregate-flags.js +13 -0
  112. package/lib/util/cache-command.d.ts +3 -0
  113. package/lib/util/cache-command.js +109 -0
  114. package/lib/util/cache-default-value.d.ts +2 -0
  115. package/lib/util/cache-default-value.js +28 -0
  116. package/lib/util/ensure-arg-object.d.ts +12 -0
  117. package/lib/util/ensure-arg-object.js +14 -0
  118. package/lib/util/fs.d.ts +7 -0
  119. package/lib/util/fs.js +54 -0
  120. package/lib/util/os.d.ts +19 -0
  121. package/lib/util/os.js +28 -0
  122. package/lib/{util.d.ts → util/util.d.ts} +7 -16
  123. package/lib/util/util.js +98 -0
  124. package/package.json +35 -37
  125. package/lib/util.js +0 -126
  126. package/lib/ux/flush.d.ts +0 -1
  127. package/lib/ux/flush.js +0 -27
  128. package/lib/ux/index.d.ts +0 -58
  129. package/lib/ux/styled/index.d.ts +0 -6
  130. package/lib/ux/styled/index.js +0 -13
  131. package/lib/ux/styled/json.d.ts +0 -1
  132. package/lib/ux/styled/json.js +0 -15
  133. package/lib/ux/wait.js +0 -7
  134. package/lib/{ux → cli-ux}/action/simple.d.ts +4 -4
  135. package/lib/{ux → cli-ux}/action/spinners.d.ts +117 -117
  136. package/lib/{ux → cli-ux}/exit.d.ts +2 -2
  137. package/lib/{ux → cli-ux}/list.d.ts +0 -0
  138. package/lib/{ux → cli-ux}/styled/object.d.ts +0 -0
  139. package/lib/{ux → cli-ux}/styled/progress.d.ts +0 -0
  140. package/lib/{ux → cli-ux}/styled/progress.js +0 -0
  141. package/lib/{ux → cli-ux}/styled/tree.d.ts +1 -1
  142. /package/lib/{ux → cli-ux}/wait.d.ts +0 -0
@@ -1,40 +1,52 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handle = exports.Exit = void 0;
4
+ const tslib_1 = require("tslib");
3
5
  /* eslint-disable no-process-exit */
4
- /* eslint-disable unicorn/no-process-exit */
6
+ const clean_stack_1 = tslib_1.__importDefault(require("clean-stack"));
5
7
  const config_1 = require("./config");
6
- const pretty_print_1 = require("./errors/pretty-print");
7
- const _1 = require(".");
8
- const clean = require("clean-stack");
9
8
  const cli_1 = require("./errors/cli");
9
+ const exit_1 = require("./errors/exit");
10
+ const pretty_print_1 = tslib_1.__importDefault(require("./errors/pretty-print"));
11
+ /**
12
+ * This is an odd abstraction for process.exit, but it allows us to stub it in tests.
13
+ *
14
+ * https://github.com/sinonjs/sinon/issues/562
15
+ */
16
+ exports.Exit = {
17
+ exit(code = 0) {
18
+ process.exit(code);
19
+ },
20
+ };
10
21
  async function handle(err) {
11
22
  try {
12
23
  if (!err)
13
24
  err = new cli_1.CLIError('no error?');
14
25
  if (err.message === 'SIGINT')
15
- process.exit(1);
16
- const shouldPrint = !(err instanceof _1.ExitError) && !err.skipOclifErrorHandling;
26
+ exports.Exit.exit(1);
27
+ const shouldPrint = !(err instanceof exit_1.ExitError) && !err.skipOclifErrorHandling;
17
28
  const pretty = (0, pretty_print_1.default)(err);
18
- const stack = clean(err.stack || '', { pretty: true });
29
+ const stack = (0, clean_stack_1.default)(err.stack || '', { pretty: true });
19
30
  if (shouldPrint) {
20
- console.error(pretty ? pretty : stack);
31
+ console.error(pretty ?? stack);
21
32
  }
22
- const exitCode = err.oclif?.exit !== undefined && err.oclif?.exit !== false ? err.oclif?.exit : 1;
33
+ const exitCode = err.oclif?.exit ?? 1;
23
34
  if (config_1.config.errorLogger && err.code !== 'EEXIT') {
24
35
  if (stack) {
25
36
  config_1.config.errorLogger.log(stack);
26
37
  }
27
- await config_1.config.errorLogger.flush()
28
- .then(() => process.exit(exitCode))
38
+ await config_1.config.errorLogger
39
+ .flush()
40
+ .then(() => exports.Exit.exit(exitCode))
29
41
  .catch(console.error);
30
42
  }
31
43
  else
32
- process.exit(exitCode);
44
+ exports.Exit.exit(exitCode);
33
45
  }
34
46
  catch (error) {
35
47
  console.error(err.stack);
36
48
  console.error(error.stack);
37
- process.exit(1);
49
+ exports.Exit.exit(1);
38
50
  }
39
51
  }
40
- exports.default = handle;
52
+ exports.handle = handle;
@@ -1,17 +1,17 @@
1
- export { default as handle } from './handle';
1
+ import { PrettyPrintableError } from '../interfaces';
2
+ export { PrettyPrintableError } from '../interfaces';
3
+ export { config } from './config';
4
+ export { CLIError } from './errors/cli';
2
5
  export { ExitError } from './errors/exit';
3
6
  export { ModuleLoadError } from './errors/module-load';
4
- export { CLIError } from './errors/cli';
5
- export { Logger } from './logger';
6
- export { config } from './config';
7
- import { PrettyPrintableError } from '../interfaces';
8
- export { PrettyPrintableError };
7
+ export { handle } from './handle';
9
8
  export declare function exit(code?: number): never;
10
- export declare function error(input: string | Error, options: {
9
+ export declare function error(input: Error | string, options: {
11
10
  exit: false;
12
11
  } & PrettyPrintableError): void;
13
- export declare function error(input: string | Error, options?: {
12
+ export declare function error(input: Error | string, options?: {
14
13
  exit?: number;
15
14
  } & PrettyPrintableError): never;
16
- export declare function warn(input: string | Error): void;
17
- export declare function memoizedWarn(input: string | Error): void;
15
+ export declare function warn(input: Error | string): void;
16
+ export declare function memoizedWarn(input: Error | string): void;
17
+ export { Logger } from './logger';
@@ -1,33 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.memoizedWarn = exports.warn = exports.error = exports.exit = exports.config = exports.Logger = exports.CLIError = exports.ModuleLoadError = exports.ExitError = exports.handle = void 0;
4
- var handle_1 = require("./handle");
5
- Object.defineProperty(exports, "handle", { enumerable: true, get: function () { return handle_1.default; } });
6
- var exit_1 = require("./errors/exit");
7
- Object.defineProperty(exports, "ExitError", { enumerable: true, get: function () { return exit_1.ExitError; } });
3
+ exports.Logger = exports.memoizedWarn = exports.warn = exports.error = exports.exit = exports.handle = exports.ModuleLoadError = exports.ExitError = exports.CLIError = exports.config = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const config_1 = require("./config");
6
+ const cli_1 = require("./errors/cli");
7
+ const exit_1 = require("./errors/exit");
8
+ const pretty_print_1 = tslib_1.__importStar(require("./errors/pretty-print"));
9
+ var config_2 = require("./config");
10
+ Object.defineProperty(exports, "config", { enumerable: true, get: function () { return config_2.config; } });
11
+ var cli_2 = require("./errors/cli");
12
+ Object.defineProperty(exports, "CLIError", { enumerable: true, get: function () { return cli_2.CLIError; } });
13
+ var exit_2 = require("./errors/exit");
14
+ Object.defineProperty(exports, "ExitError", { enumerable: true, get: function () { return exit_2.ExitError; } });
8
15
  var module_load_1 = require("./errors/module-load");
9
16
  Object.defineProperty(exports, "ModuleLoadError", { enumerable: true, get: function () { return module_load_1.ModuleLoadError; } });
10
- var cli_1 = require("./errors/cli");
11
- Object.defineProperty(exports, "CLIError", { enumerable: true, get: function () { return cli_1.CLIError; } });
12
- var logger_1 = require("./logger");
13
- Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
14
- var config_1 = require("./config");
15
- Object.defineProperty(exports, "config", { enumerable: true, get: function () { return config_1.config; } });
16
- const config_2 = require("./config");
17
- const cli_2 = require("./errors/cli");
18
- const exit_2 = require("./errors/exit");
19
- const pretty_print_1 = require("./errors/pretty-print");
17
+ var handle_1 = require("./handle");
18
+ Object.defineProperty(exports, "handle", { enumerable: true, get: function () { return handle_1.handle; } });
20
19
  function exit(code = 0) {
21
- throw new exit_2.ExitError(code);
20
+ throw new exit_1.ExitError(code);
22
21
  }
23
22
  exports.exit = exit;
24
23
  function error(input, options = {}) {
25
24
  let err;
26
25
  if (typeof input === 'string') {
27
- err = new cli_2.CLIError(input, options);
26
+ err = new cli_1.CLIError(input, options);
28
27
  }
29
28
  else if (input instanceof Error) {
30
- err = (0, cli_2.addOclifExitCode)(input, options);
29
+ err = (0, cli_1.addOclifExitCode)(input, options);
31
30
  }
32
31
  else {
33
32
  throw new TypeError('first argument must be a string or instance of Error');
@@ -36,8 +35,8 @@ function error(input, options = {}) {
36
35
  if (options.exit === false) {
37
36
  const message = (0, pretty_print_1.default)(err);
38
37
  console.error(message);
39
- if (config_2.config.errorLogger)
40
- config_2.config.errorLogger.log(err?.stack ?? '');
38
+ if (config_1.config.errorLogger)
39
+ config_1.config.errorLogger.log(err?.stack ?? '');
41
40
  }
42
41
  else
43
42
  throw err;
@@ -46,18 +45,18 @@ exports.error = error;
46
45
  function warn(input) {
47
46
  let err;
48
47
  if (typeof input === 'string') {
49
- err = new cli_2.CLIError.Warn(input);
48
+ err = new cli_1.CLIError.Warn(input);
50
49
  }
51
50
  else if (input instanceof Error) {
52
- err = (0, cli_2.addOclifExitCode)(input);
51
+ err = (0, cli_1.addOclifExitCode)(input);
53
52
  }
54
53
  else {
55
54
  throw new TypeError('first argument must be a string or instance of Error');
56
55
  }
57
56
  const message = (0, pretty_print_1.default)(err);
58
57
  console.error(message);
59
- if (config_2.config.errorLogger)
60
- config_2.config.errorLogger.log(err?.stack ?? '');
58
+ if (config_1.config.errorLogger)
59
+ config_1.config.errorLogger.log(err?.stack ?? '');
61
60
  }
62
61
  exports.warn = warn;
63
62
  const WARNINGS = new Set();
@@ -67,3 +66,5 @@ function memoizedWarn(input) {
67
66
  WARNINGS.add(input);
68
67
  }
69
68
  exports.memoizedWarn = memoizedWarn;
69
+ var logger_1 = require("./logger");
70
+ Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
@@ -1,8 +1,8 @@
1
1
  export declare class Logger {
2
2
  file: string;
3
- protected flushing: Promise<void>;
4
3
  protected buffer: string[];
4
+ protected flushing: Promise<void>;
5
5
  constructor(file: string);
6
- log(msg: string): void;
7
6
  flush(waitForMs?: number): Promise<void>;
7
+ log(msg: string): void;
8
8
  }
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Logger = void 0;
4
- const fs = require("fs/promises");
5
- const path_1 = require("path");
4
+ const promises_1 = require("node:fs/promises");
5
+ const node_path_1 = require("node:path");
6
6
  const stripAnsi = require("strip-ansi");
7
7
  const timestamp = () => new Date().toISOString();
8
8
  let timer;
9
- const wait = (ms) => new Promise(resolve => {
9
+ const wait = (ms) => new Promise((resolve) => {
10
10
  if (timer)
11
11
  timer.unref();
12
12
  timer = setTimeout(() => resolve(null), ms);
@@ -17,16 +17,11 @@ function chomp(s) {
17
17
  return s;
18
18
  }
19
19
  class Logger {
20
+ file;
21
+ buffer = [];
22
+ flushing = Promise.resolve();
20
23
  constructor(file) {
21
24
  this.file = file;
22
- this.flushing = Promise.resolve();
23
- this.buffer = [];
24
- }
25
- log(msg) {
26
- msg = stripAnsi(chomp(msg));
27
- const lines = msg.split('\n').map(l => `${timestamp()} ${l}`.trimEnd());
28
- this.buffer.push(...lines);
29
- this.flush(50).catch(console.error);
30
25
  }
31
26
  async flush(waitForMs = 0) {
32
27
  await wait(waitForMs);
@@ -35,10 +30,16 @@ class Logger {
35
30
  return;
36
31
  const mylines = this.buffer;
37
32
  this.buffer = [];
38
- await fs.mkdir((0, path_1.dirname)(this.file), { recursive: true });
39
- await fs.appendFile(this.file, mylines.join('\n') + '\n');
33
+ await (0, promises_1.mkdir)((0, node_path_1.dirname)(this.file), { recursive: true });
34
+ await (0, promises_1.appendFile)(this.file, mylines.join('\n') + '\n');
40
35
  });
41
36
  await this.flushing;
42
37
  }
38
+ log(msg) {
39
+ msg = stripAnsi(chomp(msg));
40
+ const lines = msg.split('\n').map((l) => `${timestamp()} ${l}`.trimEnd());
41
+ this.buffer.push(...lines);
42
+ this.flush(50).catch(console.error);
43
+ }
43
44
  }
44
45
  exports.Logger = Logger;
package/lib/execute.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as Interfaces from './interfaces';
1
+ import { LoadOptions } from './interfaces';
2
2
  /**
3
3
  * Load and run oclif CLI
4
4
  *
@@ -7,7 +7,7 @@ import * as Interfaces from './interfaces';
7
7
  *
8
8
  * @example For ESM dev.js
9
9
  * ```
10
- * #!/usr/bin/env node
10
+ * #!/usr/bin/env ts-node
11
11
  * void (async () => {
12
12
  * const oclif = await import('@oclif/core')
13
13
  * await oclif.execute({development: true, dir: import.meta.url})
@@ -25,7 +25,7 @@ import * as Interfaces from './interfaces';
25
25
  *
26
26
  * @example For CJS dev.js
27
27
  * ```
28
- * #!/usr/bin/env node
28
+ * #!/usr/bin/env ts-node
29
29
  * void (async () => {
30
30
  * const oclif = await import('@oclif/core')
31
31
  * await oclif.execute({development: true, dir: __dirname})
@@ -41,9 +41,9 @@ import * as Interfaces from './interfaces';
41
41
  * })()
42
42
  * ```
43
43
  */
44
- export default function execute(options: {
45
- dir: string;
44
+ export declare function execute(options: {
46
45
  args?: string[];
47
- loadOptions?: Interfaces.LoadOptions;
48
46
  development?: boolean;
47
+ dir: string;
48
+ loadOptions?: LoadOptions;
49
49
  }): Promise<unknown>;
package/lib/execute.js CHANGED
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const settings_1 = require("./settings");
4
- const flush_1 = require("./ux/flush");
3
+ exports.execute = void 0;
4
+ const flush_1 = require("./cli-ux/flush");
5
5
  const handle_1 = require("./errors/handle");
6
6
  const main_1 = require("./main");
7
+ const settings_1 = require("./settings");
7
8
  /**
8
9
  * Load and run oclif CLI
9
10
  *
@@ -12,7 +13,7 @@ const main_1 = require("./main");
12
13
  *
13
14
  * @example For ESM dev.js
14
15
  * ```
15
- * #!/usr/bin/env node
16
+ * #!/usr/bin/env ts-node
16
17
  * void (async () => {
17
18
  * const oclif = await import('@oclif/core')
18
19
  * await oclif.execute({development: true, dir: import.meta.url})
@@ -30,7 +31,7 @@ const main_1 = require("./main");
30
31
  *
31
32
  * @example For CJS dev.js
32
33
  * ```
33
- * #!/usr/bin/env node
34
+ * #!/usr/bin/env ts-node
34
35
  * void (async () => {
35
36
  * const oclif = await import('@oclif/core')
36
37
  * await oclif.execute({development: true, dir: __dirname})
@@ -50,13 +51,13 @@ async function execute(options) {
50
51
  if (options.development) {
51
52
  // In dev mode -> use ts-node and dev plugins
52
53
  process.env.NODE_ENV = 'development';
53
- settings_1.default.debug = true;
54
+ settings_1.settings.debug = true;
54
55
  }
55
- return (0, main_1.default)(options.args ?? process.argv.slice(2), options.loadOptions ?? options.dir)
56
+ return (0, main_1.run)(options.args ?? process.argv.slice(2), options.loadOptions ?? options.dir)
56
57
  .then(async (result) => {
57
- (0, flush_1.default)();
58
+ (0, flush_1.flush)();
58
59
  return result;
59
60
  })
60
- .catch(async (error) => (0, handle_1.default)(error));
61
+ .catch(async (error) => (0, handle_1.handle)(error));
61
62
  }
62
- exports.default = execute;
63
+ exports.execute = execute;
package/lib/flags.d.ts CHANGED
@@ -1,49 +1,120 @@
1
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>;
24
- multiple: true;
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>;
2
+ import { URL } from 'node:url';
3
+ import { BooleanFlag, CustomOptions, FlagDefinition, OptionFlag } from './interfaces';
4
+ type NotArray<T> = T extends Array<any> ? never : T;
5
+ export declare function custom<T = string, P extends CustomOptions = CustomOptions>(defaults: Partial<OptionFlag<T[], P>> & {
6
+ multiple: true;
7
+ } & ({
8
+ default: OptionFlag<T[], P>['default'];
9
+ } | {
10
+ required: true;
11
+ })): FlagDefinition<T, P, {
12
+ multiple: true;
13
+ requiredOrDefaulted: true;
14
+ }>;
15
+ export declare function custom<T = string, P extends CustomOptions = CustomOptions>(defaults: Partial<OptionFlag<NotArray<T>, P>> & {
16
+ multiple?: false | undefined;
17
+ } & ({
18
+ default: OptionFlag<NotArray<T>, P>['default'];
19
+ } | {
20
+ required: true;
21
+ })): FlagDefinition<T, P, {
22
+ multiple: false;
23
+ requiredOrDefaulted: true;
24
+ }>;
25
+ export declare function custom<T = string, P extends CustomOptions = CustomOptions>(defaults: Partial<OptionFlag<NotArray<T>, P>> & {
26
+ default?: OptionFlag<NotArray<T>, P>['default'] | undefined;
27
+ multiple?: false | undefined;
28
+ required?: false | undefined;
29
+ }): FlagDefinition<T, P, {
30
+ multiple: false;
31
+ requiredOrDefaulted: false;
32
+ }>;
33
+ export declare function custom<T = string, P extends CustomOptions = CustomOptions>(defaults: Partial<OptionFlag<T[], P>> & {
34
+ default?: OptionFlag<T[], P>['default'] | undefined;
35
+ multiple: true;
36
+ required?: false | undefined;
37
+ }): FlagDefinition<T, P, {
38
+ multiple: true;
39
+ requiredOrDefaulted: false;
40
+ }>;
41
+ export declare function custom<T = string, P extends CustomOptions = CustomOptions>(): FlagDefinition<T, P, {
42
+ multiple: false;
43
+ requiredOrDefaulted: false;
44
+ }>;
30
45
  export declare function boolean<T = boolean>(options?: Partial<BooleanFlag<T>>): BooleanFlag<T>;
31
46
  export declare const integer: FlagDefinition<number, {
32
- min?: number | undefined;
33
47
  max?: number | undefined;
48
+ min?: number | undefined;
49
+ }, {
50
+ multiple: false;
51
+ requiredOrDefaulted: false;
34
52
  }>;
35
53
  export declare const directory: FlagDefinition<string, {
36
54
  exists?: boolean | undefined;
55
+ }, {
56
+ multiple: false;
57
+ requiredOrDefaulted: false;
37
58
  }>;
38
59
  export declare const file: FlagDefinition<string, {
39
60
  exists?: boolean | undefined;
61
+ }, {
62
+ multiple: false;
63
+ requiredOrDefaulted: false;
40
64
  }>;
41
65
  /**
42
66
  * Initializes a string as a URL. Throws an error
43
67
  * if the string is not a valid URL.
44
68
  */
45
- export declare const url: FlagDefinition<URL, Record<string, unknown>>;
46
- declare const stringFlag: FlagDefinition<string, Record<string, unknown>>;
47
- export { stringFlag as string };
69
+ export declare const url: FlagDefinition<URL, CustomOptions, {
70
+ multiple: false;
71
+ requiredOrDefaulted: false;
72
+ }>;
73
+ export declare const string: FlagDefinition<string, CustomOptions, {
74
+ multiple: false;
75
+ requiredOrDefaulted: false;
76
+ }>;
48
77
  export declare const version: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;
49
78
  export declare const help: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;
79
+ type ElementType<T extends ReadonlyArray<unknown>> = T[number];
80
+ export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<ElementType<T>[], P>> & {
81
+ multiple: true;
82
+ options: T;
83
+ } & ({
84
+ default: OptionFlag<ElementType<T>[], P>['default'] | undefined;
85
+ } | {
86
+ required: true;
87
+ })): FlagDefinition<(typeof defaults.options)[number], P, {
88
+ multiple: true;
89
+ requiredOrDefaulted: true;
90
+ }>;
91
+ export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<ElementType<T>, P>> & {
92
+ multiple?: false | undefined;
93
+ options: T;
94
+ } & ({
95
+ default: OptionFlag<ElementType<T>, P>['default'];
96
+ } | {
97
+ required: true;
98
+ })): FlagDefinition<(typeof defaults.options)[number], P, {
99
+ multiple: false;
100
+ requiredOrDefaulted: true;
101
+ }>;
102
+ export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<ElementType<T>, P>> & {
103
+ default?: OptionFlag<ElementType<T>, P>['default'] | undefined;
104
+ multiple?: false | undefined;
105
+ options: T;
106
+ required?: false | undefined;
107
+ }): FlagDefinition<(typeof defaults.options)[number], P, {
108
+ multiple: false;
109
+ requiredOrDefaulted: false;
110
+ }>;
111
+ export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<ElementType<T>[], P>> & {
112
+ default?: OptionFlag<ElementType<T>[], P>['default'] | undefined;
113
+ multiple: true;
114
+ options: T;
115
+ required?: false | undefined;
116
+ }): FlagDefinition<(typeof defaults.options)[number], P, {
117
+ multiple: true;
118
+ requiredOrDefaulted: false;
119
+ }>;
120
+ export {};
package/lib/flags.js CHANGED
@@ -1,21 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.help = exports.version = exports.string = exports.url = exports.file = exports.directory = exports.integer = exports.boolean = exports.custom = void 0;
4
- const url_1 = require("url");
5
- const help_1 = require("./help");
6
- const util_1 = require("./util");
3
+ exports.option = exports.help = exports.version = exports.string = exports.url = exports.file = exports.directory = exports.integer = exports.boolean = exports.custom = void 0;
4
+ /* eslint-disable valid-jsdoc */
5
+ const node_url_1 = require("node:url");
7
6
  const errors_1 = require("./errors");
7
+ const help_1 = require("./help");
8
+ const fs_1 = require("./util/fs");
9
+ /**
10
+ * Create a custom flag.
11
+ *
12
+ * @example
13
+ * type Id = string
14
+ * type IdOpts = { startsWith: string; length: number };
15
+ *
16
+ * export const myFlag = custom<Id, IdOpts>({
17
+ * parse: async (input, opts) => {
18
+ * if (input.startsWith(opts.startsWith) && input.length === opts.length) {
19
+ * return input
20
+ * }
21
+ *
22
+ * throw new Error('Invalid id')
23
+ * },
24
+ * })
25
+ */
8
26
  function custom(defaults) {
9
- return (options = {}) => {
10
- return {
11
- parse: async (input, _ctx, _opts) => input,
12
- ...defaults,
13
- ...options,
14
- input: [],
15
- multiple: Boolean(options.multiple === undefined ? defaults.multiple : options.multiple),
16
- type: 'option',
17
- };
18
- };
27
+ return (options = {}) => ({
28
+ parse: async (input, _ctx, _opts) => input,
29
+ ...defaults,
30
+ ...options,
31
+ input: [],
32
+ multiple: Boolean(options.multiple === undefined ? defaults?.multiple ?? false : options.multiple),
33
+ type: 'option',
34
+ });
19
35
  }
20
36
  exports.custom = custom;
21
37
  function boolean(options = {}) {
@@ -28,7 +44,7 @@ function boolean(options = {}) {
28
44
  }
29
45
  exports.boolean = boolean;
30
46
  exports.integer = custom({
31
- parse: async (input, _, opts) => {
47
+ async parse(input, _, opts) {
32
48
  if (!/^-?\d+$/.test(input))
33
49
  throw new errors_1.CLIError(`Expected an integer but received: ${input}`);
34
50
  const num = Number.parseInt(input, 10);
@@ -40,16 +56,16 @@ exports.integer = custom({
40
56
  },
41
57
  });
42
58
  exports.directory = custom({
43
- parse: async (input, _, opts) => {
59
+ async parse(input, _, opts) {
44
60
  if (opts.exists)
45
- return (0, util_1.dirExists)(input);
61
+ return (0, fs_1.dirExists)(input);
46
62
  return input;
47
63
  },
48
64
  });
49
65
  exports.file = custom({
50
- parse: async (input, _, opts) => {
66
+ async parse(input, _, opts) {
51
67
  if (opts.exists)
52
- return (0, util_1.fileExists)(input);
68
+ return (0, fs_1.fileExists)(input);
53
69
  return input;
54
70
  },
55
71
  });
@@ -58,37 +74,55 @@ exports.file = custom({
58
74
  * if the string is not a valid URL.
59
75
  */
60
76
  exports.url = custom({
61
- parse: async (input) => {
77
+ async parse(input) {
62
78
  try {
63
- return new url_1.URL(input);
79
+ return new node_url_1.URL(input);
64
80
  }
65
81
  catch {
66
- throw new Error(`Expected a valid url but received: ${input}`);
82
+ throw new errors_1.CLIError(`Expected a valid url but received: ${input}`);
67
83
  }
68
84
  },
69
85
  });
70
- const stringFlag = custom({});
71
- exports.string = stringFlag;
72
- const version = (opts = {}) => {
73
- return boolean({
74
- description: 'Show CLI version.',
75
- ...opts,
76
- parse: async (_, ctx) => {
77
- ctx.log(ctx.config.userAgent);
78
- ctx.exit(0);
79
- },
80
- });
81
- };
86
+ exports.string = custom();
87
+ const version = (opts = {}) => boolean({
88
+ description: 'Show CLI version.',
89
+ ...opts,
90
+ async parse(_, ctx) {
91
+ ctx.log(ctx.config.userAgent);
92
+ ctx.exit(0);
93
+ },
94
+ });
82
95
  exports.version = version;
83
- const help = (opts = {}) => {
84
- return boolean({
85
- description: 'Show CLI help.',
86
- ...opts,
87
- parse: async (_, cmd) => {
88
- const Help = await (0, help_1.loadHelpClass)(cmd.config);
89
- await new Help(cmd.config, cmd.config.pjson.helpOptions).showHelp(cmd.id ? [cmd.id, ...cmd.argv] : cmd.argv);
90
- cmd.exit(0);
91
- },
92
- });
93
- };
96
+ const help = (opts = {}) => boolean({
97
+ description: 'Show CLI help.',
98
+ ...opts,
99
+ async parse(_, cmd) {
100
+ const Help = await (0, help_1.loadHelpClass)(cmd.config);
101
+ await new Help(cmd.config, cmd.config.pjson.helpOptions).showHelp(cmd.id ? [cmd.id, ...cmd.argv] : cmd.argv);
102
+ cmd.exit(0);
103
+ },
104
+ });
94
105
  exports.help = help;
106
+ /**
107
+ * Create a custom flag that infers the flag type from the provided options.
108
+ *
109
+ * @example
110
+ * export default class MyCommand extends Command {
111
+ * static flags = {
112
+ * name: Flags.option({
113
+ * options: ['foo', 'bar'] as const,
114
+ * })(),
115
+ * }
116
+ * }
117
+ */
118
+ function option(defaults) {
119
+ return (options = {}) => ({
120
+ parse: async (input, _ctx, _opts) => input,
121
+ ...defaults,
122
+ ...options,
123
+ input: [],
124
+ multiple: Boolean(options.multiple === undefined ? defaults.multiple : options.multiple),
125
+ type: 'option',
126
+ });
127
+ }
128
+ exports.option = option;