@oclif/core 3.0.0-beta.9 → 3.0.1

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 +45 -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
package/lib/main.js CHANGED
@@ -1,17 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.versionAddition = exports.helpAddition = void 0;
4
- const url_1 = require("url");
5
- const util_1 = require("util");
6
- const url_2 = require("url");
3
+ exports.run = exports.versionAddition = exports.helpAddition = void 0;
4
+ const node_url_1 = require("node:url");
5
+ const node_util_1 = require("node:util");
6
+ const stream_1 = require("./cli-ux/stream");
7
7
  const config_1 = require("./config");
8
8
  const help_1 = require("./help");
9
- const stream_1 = require("./ux/stream");
10
9
  const performance_1 = require("./performance");
11
10
  const debug = require('debug')('oclif:main');
12
11
  const log = (message = '', ...args) => {
13
- message = typeof message === 'string' ? message : (0, util_1.inspect)(message);
14
- stream_1.stdout.write((0, util_1.format)(message, ...args) + '\n');
12
+ message = typeof message === 'string' ? message : (0, node_util_1.inspect)(message);
13
+ stream_1.stdout.write((0, node_util_1.format)(message, ...args) + '\n');
15
14
  };
16
15
  const helpAddition = (argv, config) => {
17
16
  if (argv.length === 0 && !config.pjson.oclif.default)
@@ -35,26 +34,27 @@ const versionAddition = (argv, config) => {
35
34
  };
36
35
  exports.versionAddition = versionAddition;
37
36
  async function run(argv, options) {
38
- const marker = performance_1.default.mark('main.run');
39
- const initMarker = performance_1.default.mark('main.run#init');
37
+ const marker = performance_1.Performance.mark(performance_1.OCLIF_MARKER_OWNER, 'main.run');
38
+ const initMarker = performance_1.Performance.mark(performance_1.OCLIF_MARKER_OWNER, 'main.run#init');
40
39
  const collectPerf = async () => {
41
40
  marker?.stop();
42
- initMarker?.stop();
43
- await performance_1.default.collect();
44
- performance_1.default.debug();
41
+ if (!initMarker?.stopped)
42
+ initMarker?.stop();
43
+ await performance_1.Performance.collect();
44
+ performance_1.Performance.debug();
45
45
  };
46
46
  debug(`process.execPath: ${process.execPath}`);
47
47
  debug(`process.execArgv: ${process.execArgv}`);
48
48
  debug('process.argv: %O', process.argv);
49
49
  argv = argv ?? process.argv.slice(2);
50
50
  // Handle the case when a file URL string or URL is passed in such as 'import.meta.url'; covert to file path.
51
- if (options && ((typeof options === 'string' && options.startsWith('file://')) || options instanceof url_2.URL)) {
52
- options = (0, url_1.fileURLToPath)(options);
51
+ if (options && ((typeof options === 'string' && options.startsWith('file://')) || options instanceof node_url_1.URL)) {
52
+ options = (0, node_url_1.fileURLToPath)(options);
53
53
  }
54
54
  const config = await config_1.Config.load(options ?? require.main?.filename ?? __dirname);
55
55
  let [id, ...argvSlice] = (0, help_1.normalizeArgv)(config, argv);
56
56
  // run init hook
57
- await config.runHook('init', { id, argv: argvSlice });
57
+ await config.runHook('init', { argv: argvSlice, id });
58
58
  // display version if applicable
59
59
  if ((0, exports.versionAddition)(argv, config)) {
60
60
  log(config.userAgent);
@@ -93,4 +93,4 @@ async function run(argv, options) {
93
93
  await collectPerf();
94
94
  }
95
95
  }
96
- exports.default = run;
96
+ exports.run = run;
@@ -1,81 +1,71 @@
1
+ import { Command } from './command';
1
2
  import { Config as IConfig, Plugin as IPlugin } from './interfaces';
2
3
  /**
3
- * Provides a static class with several utility methods to work with Oclif config / plugin to load ESM or CJS Node
4
- * modules and source files.
4
+ * Loads and returns a module.
5
5
  *
6
- * @author Michael Leahy <support@typhonjs.io> (https://github.com/typhonrt)
6
+ * Uses `getPackageType` to determine if `type` is set to 'module. If so loads '.js' files as ESM otherwise uses
7
+ * a bare require to load as CJS. Also loads '.mjs' files as ESM.
8
+ *
9
+ * Uses dynamic import to load ESM source or require for CommonJS.
10
+ *
11
+ * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
12
+ * provides a consistent stack trace and info.
13
+ *
14
+ * @param {IConfig|IPlugin} config - Oclif config or plugin config.
15
+ * @param {string} modulePath - NPM module name or file path to load.
16
+ *
17
+ * @returns {Promise<*>} The entire ESM module from dynamic import or CJS module by require.
18
+ */
19
+ export declare function load(config: IConfig | IPlugin, modulePath: string): Promise<any>;
20
+ /**
21
+ * Loads a module and returns an object with the module and data about the module.
22
+ *
23
+ * Uses `getPackageType` to determine if `type` is set to `module`. If so loads '.js' files as ESM otherwise uses
24
+ * a bare require to load as CJS. Also loads '.mjs' files as ESM.
25
+ *
26
+ * Uses dynamic import to load ESM source or require for CommonJS.
27
+ *
28
+ * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
29
+ * provides a consistent stack trace and info.
30
+ *
31
+ * @param {IConfig|IPlugin} config - Oclif config or plugin config.
32
+ * @param {string} modulePath - NPM module name or file path to load.
33
+ *
34
+ * @returns {Promise<{isESM: boolean, module: *, filePath: string}>} An object with the loaded module & data including
35
+ * file path and whether the module is ESM.
36
+ */
37
+ export declare function loadWithData(config: IConfig | IPlugin, modulePath: string): Promise<{
38
+ filePath: string;
39
+ isESM: boolean;
40
+ module: any;
41
+ }>;
42
+ /**
43
+ * Loads a module and returns an object with the module and data about the module.
44
+ *
45
+ * Uses cached `isESM` and `relativePath` in plugin manifest to determine if dynamic import (isESM = true)
46
+ * or require (isESM = false | undefined) should be used.
47
+ *
48
+ * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
49
+ * provides a consistent stack trace and info.
50
+ *
51
+ * @param {Command.Cached} cached - Cached command data from plugin manifest.
52
+ * @param {string} modulePath - NPM module name or file path to load.
53
+ *
54
+ * @returns {Promise<{isESM: boolean, module: *, filePath: string}>} An object with the loaded module & data including
55
+ * file path and whether the module is ESM.
56
+ */
57
+ export declare function loadWithDataFromManifest(cached: Command.Cached, modulePath: string): Promise<{
58
+ filePath: string;
59
+ isESM: boolean;
60
+ module: any;
61
+ }>;
62
+ /**
63
+ * For `.js` files uses `getPackageType` to determine if `type` is set to `module` in associated `package.json`. If
64
+ * the `modulePath` provided ends in `.mjs` it is assumed to be ESM.
65
+ *
66
+ * @param {string} filePath - File path to test.
67
+ *
68
+ * @returns {boolean} The modulePath is an ES Module.
69
+ * @see https://www.npmjs.com/package/get-package-type
7
70
  */
8
- export default class ModuleLoader {
9
- /**
10
- * Loads and returns a module.
11
- *
12
- * Uses `getPackageType` to determine if `type` is set to 'module. If so loads '.js' files as ESM otherwise uses
13
- * a bare require to load as CJS. Also loads '.mjs' files as ESM.
14
- *
15
- * Uses dynamic import to load ESM source or require for CommonJS.
16
- *
17
- * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
18
- * provides a consistent stack trace and info.
19
- *
20
- * @param {IConfig|IPlugin} config - Oclif config or plugin config.
21
- * @param {string} modulePath - NPM module name or file path to load.
22
- *
23
- * @returns {Promise<*>} The entire ESM module from dynamic import or CJS module by require.
24
- */
25
- static load(config: IConfig | IPlugin, modulePath: string): Promise<any>;
26
- /**
27
- * Loads a module and returns an object with the module and data about the module.
28
- *
29
- * Uses `getPackageType` to determine if `type` is set to `module`. If so loads '.js' files as ESM otherwise uses
30
- * a bare require to load as CJS. Also loads '.mjs' files as ESM.
31
- *
32
- * Uses dynamic import to load ESM source or require for CommonJS.
33
- *
34
- * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
35
- * provides a consistent stack trace and info.
36
- *
37
- * @param {IConfig|IPlugin} config - Oclif config or plugin config.
38
- * @param {string} modulePath - NPM module name or file path to load.
39
- *
40
- * @returns {Promise<{isESM: boolean, module: *, filePath: string}>} An object with the loaded module & data including
41
- * file path and whether the module is ESM.
42
- */
43
- static loadWithData(config: IConfig | IPlugin, modulePath: string): Promise<{
44
- isESM: boolean;
45
- module: any;
46
- filePath: string;
47
- }>;
48
- /**
49
- * For `.js` files uses `getPackageType` to determine if `type` is set to `module` in associated `package.json`. If
50
- * the `modulePath` provided ends in `.mjs` it is assumed to be ESM.
51
- *
52
- * @param {string} filePath - File path to test.
53
- *
54
- * @returns {boolean} The modulePath is an ES Module.
55
- * @see https://www.npmjs.com/package/get-package-type
56
- */
57
- static isPathModule(filePath: string): boolean;
58
- /**
59
- * Resolves a modulePath first by `require.resolve` to allow Node to resolve an actual module. If this fails then
60
- * the `modulePath` is resolved from the root of the provided config. `Config.tsPath` is used for initial resolution.
61
- * If this file path does not exist then several extensions are tried from `s_EXTENSIONS` in order: '.js', '.mjs',
62
- * '.cjs'. After a file path has been selected `isPathModule` is used to determine if the file is an ES Module.
63
- *
64
- * @param {IConfig|IPlugin} config - Oclif config or plugin config.
65
- * @param {string} modulePath - File path to load.
66
- *
67
- * @returns {{isESM: boolean, filePath: string}} An object including file path and whether the module is ESM.
68
- */
69
- static resolvePath(config: IConfig | IPlugin, modulePath: string): {
70
- isESM: boolean;
71
- filePath: string;
72
- };
73
- /**
74
- * Try adding the different extensions from `s_EXTENSIONS` to find the file.
75
- *
76
- * @param {string} filePath - File path to load.
77
- *
78
- * @returns {string | null} Modified file path including extension or null if file is not found.
79
- */
80
- static findFile(filePath: string): string | null;
81
- }
71
+ export declare function isPathModule(filePath: string): boolean;
@@ -1,177 +1,210 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const path = require("path");
4
- const url = require("url");
5
- const fs_1 = require("fs");
3
+ exports.isPathModule = exports.loadWithDataFromManifest = exports.loadWithData = exports.load = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const node_url_1 = require("node:url");
7
+ const ts_node_1 = require("./config/ts-node");
6
8
  const errors_1 = require("./errors");
7
- const config_1 = require("./config");
8
9
  const getPackageType = require('get-package-type');
9
10
  /**
10
11
  * Defines file extension resolution when source files do not have an extension.
11
12
  */
12
13
  // eslint-disable-next-line camelcase
13
14
  const s_EXTENSIONS = ['.ts', '.js', '.mjs', '.cjs'];
14
- const isPlugin = (config) => {
15
- return config.type !== undefined;
16
- };
15
+ const isPlugin = (config) => config.type !== undefined;
17
16
  /**
18
- * Provides a static class with several utility methods to work with Oclif config / plugin to load ESM or CJS Node
19
- * modules and source files.
17
+ * Loads and returns a module.
20
18
  *
21
- * @author Michael Leahy <support@typhonjs.io> (https://github.com/typhonrt)
19
+ * Uses `getPackageType` to determine if `type` is set to 'module. If so loads '.js' files as ESM otherwise uses
20
+ * a bare require to load as CJS. Also loads '.mjs' files as ESM.
21
+ *
22
+ * Uses dynamic import to load ESM source or require for CommonJS.
23
+ *
24
+ * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
25
+ * provides a consistent stack trace and info.
26
+ *
27
+ * @param {IConfig|IPlugin} config - Oclif config or plugin config.
28
+ * @param {string} modulePath - NPM module name or file path to load.
29
+ *
30
+ * @returns {Promise<*>} The entire ESM module from dynamic import or CJS module by require.
22
31
  */
23
- // eslint-disable-next-line unicorn/no-static-only-class
24
- class ModuleLoader {
25
- /**
26
- * Loads and returns a module.
27
- *
28
- * Uses `getPackageType` to determine if `type` is set to 'module. If so loads '.js' files as ESM otherwise uses
29
- * a bare require to load as CJS. Also loads '.mjs' files as ESM.
30
- *
31
- * Uses dynamic import to load ESM source or require for CommonJS.
32
- *
33
- * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
34
- * provides a consistent stack trace and info.
35
- *
36
- * @param {IConfig|IPlugin} config - Oclif config or plugin config.
37
- * @param {string} modulePath - NPM module name or file path to load.
38
- *
39
- * @returns {Promise<*>} The entire ESM module from dynamic import or CJS module by require.
40
- */
41
- static async load(config, modulePath) {
42
- let filePath;
43
- let isESM;
44
- try {
45
- ({ isESM, filePath } = ModuleLoader.resolvePath(config, modulePath));
46
- // It is important to await on import to catch the error code.
47
- return isESM ? await import(url.pathToFileURL(filePath).href) : require(filePath);
48
- }
49
- catch (error) {
50
- if (error.code === 'MODULE_NOT_FOUND' || error.code === 'ERR_MODULE_NOT_FOUND') {
51
- throw new errors_1.ModuleLoadError(`${isESM ? 'import()' : 'require'} failed to load ${filePath || modulePath}`);
52
- }
53
- throw error;
54
- }
32
+ async function load(config, modulePath) {
33
+ let filePath;
34
+ let isESM;
35
+ try {
36
+ ;
37
+ ({ filePath, isESM } = resolvePath(config, modulePath));
38
+ return isESM ? await import((0, node_url_1.pathToFileURL)(filePath).href) : require(filePath);
55
39
  }
56
- /**
57
- * Loads a module and returns an object with the module and data about the module.
58
- *
59
- * Uses `getPackageType` to determine if `type` is set to `module`. If so loads '.js' files as ESM otherwise uses
60
- * a bare require to load as CJS. Also loads '.mjs' files as ESM.
61
- *
62
- * Uses dynamic import to load ESM source or require for CommonJS.
63
- *
64
- * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
65
- * provides a consistent stack trace and info.
66
- *
67
- * @param {IConfig|IPlugin} config - Oclif config or plugin config.
68
- * @param {string} modulePath - NPM module name or file path to load.
69
- *
70
- * @returns {Promise<{isESM: boolean, module: *, filePath: string}>} An object with the loaded module & data including
71
- * file path and whether the module is ESM.
72
- */
73
- static async loadWithData(config, modulePath) {
74
- let filePath;
75
- let isESM;
76
- try {
77
- ({ isESM, filePath } = ModuleLoader.resolvePath(config, modulePath));
78
- const module = isESM ? await import(url.pathToFileURL(filePath).href) : require(filePath);
79
- return { isESM, module, filePath };
40
+ catch (error) {
41
+ if (error.code === 'MODULE_NOT_FOUND' || error.code === 'ERR_MODULE_NOT_FOUND') {
42
+ throw new errors_1.ModuleLoadError(`${isESM ? 'import()' : 'require'} failed to load ${filePath || modulePath}`);
80
43
  }
81
- catch (error) {
82
- if (error.code === 'MODULE_NOT_FOUND' || error.code === 'ERR_MODULE_NOT_FOUND') {
83
- throw new errors_1.ModuleLoadError(`${isESM ? 'import()' : 'require'} failed to load ${filePath || modulePath}: ${error.message}`);
84
- }
85
- throw error;
44
+ throw error;
45
+ }
46
+ }
47
+ exports.load = load;
48
+ /**
49
+ * Loads a module and returns an object with the module and data about the module.
50
+ *
51
+ * Uses `getPackageType` to determine if `type` is set to `module`. If so loads '.js' files as ESM otherwise uses
52
+ * a bare require to load as CJS. Also loads '.mjs' files as ESM.
53
+ *
54
+ * Uses dynamic import to load ESM source or require for CommonJS.
55
+ *
56
+ * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
57
+ * provides a consistent stack trace and info.
58
+ *
59
+ * @param {IConfig|IPlugin} config - Oclif config or plugin config.
60
+ * @param {string} modulePath - NPM module name or file path to load.
61
+ *
62
+ * @returns {Promise<{isESM: boolean, module: *, filePath: string}>} An object with the loaded module & data including
63
+ * file path and whether the module is ESM.
64
+ */
65
+ async function loadWithData(config, modulePath) {
66
+ let filePath;
67
+ let isESM;
68
+ try {
69
+ ;
70
+ ({ filePath, isESM } = resolvePath(config, modulePath));
71
+ const module = isESM ? await import((0, node_url_1.pathToFileURL)(filePath).href) : require(filePath);
72
+ return { filePath, isESM, module };
73
+ }
74
+ catch (error) {
75
+ if (error.code === 'MODULE_NOT_FOUND' || error.code === 'ERR_MODULE_NOT_FOUND') {
76
+ throw new errors_1.ModuleLoadError(`${isESM ? 'import()' : 'require'} failed to load ${filePath || modulePath}: ${error.message}`);
86
77
  }
78
+ throw error;
79
+ }
80
+ }
81
+ exports.loadWithData = loadWithData;
82
+ /**
83
+ * Loads a module and returns an object with the module and data about the module.
84
+ *
85
+ * Uses cached `isESM` and `relativePath` in plugin manifest to determine if dynamic import (isESM = true)
86
+ * or require (isESM = false | undefined) should be used.
87
+ *
88
+ * A unique error, ModuleLoadError, combines both CJS and ESM loader module not found errors into a single error that
89
+ * provides a consistent stack trace and info.
90
+ *
91
+ * @param {Command.Cached} cached - Cached command data from plugin manifest.
92
+ * @param {string} modulePath - NPM module name or file path to load.
93
+ *
94
+ * @returns {Promise<{isESM: boolean, module: *, filePath: string}>} An object with the loaded module & data including
95
+ * file path and whether the module is ESM.
96
+ */
97
+ async function loadWithDataFromManifest(cached, modulePath) {
98
+ const { id, isESM, relativePath } = cached;
99
+ if (!relativePath) {
100
+ throw new errors_1.ModuleLoadError(`Cached command ${id} does not have a relative path`);
87
101
  }
88
- /**
89
- * For `.js` files uses `getPackageType` to determine if `type` is set to `module` in associated `package.json`. If
90
- * the `modulePath` provided ends in `.mjs` it is assumed to be ESM.
91
- *
92
- * @param {string} filePath - File path to test.
93
- *
94
- * @returns {boolean} The modulePath is an ES Module.
95
- * @see https://www.npmjs.com/package/get-package-type
96
- */
97
- static isPathModule(filePath) {
98
- const extension = path.extname(filePath).toLowerCase();
99
- switch (extension) {
100
- case '.js':
101
- case '.jsx':
102
- case '.ts':
103
- case '.tsx':
104
- return getPackageType.sync(filePath) === 'module';
105
- case '.mjs':
106
- case '.mts':
107
- return true;
108
- default:
109
- return false;
102
+ if (isESM === undefined) {
103
+ throw new errors_1.ModuleLoadError(`Cached command ${id} does not have the isESM property set`);
104
+ }
105
+ const filePath = (0, node_path_1.join)(modulePath, relativePath.join(node_path_1.sep));
106
+ try {
107
+ const module = isESM ? await import((0, node_url_1.pathToFileURL)(filePath).href) : require(filePath);
108
+ return { filePath, isESM, module };
109
+ }
110
+ catch (error) {
111
+ if (error.code === 'MODULE_NOT_FOUND' || error.code === 'ERR_MODULE_NOT_FOUND') {
112
+ throw new errors_1.ModuleLoadError(`${isESM ? 'import()' : 'require'} failed to load ${filePath || modulePath}: ${error.message}`);
110
113
  }
114
+ throw error;
111
115
  }
112
- /**
113
- * Resolves a modulePath first by `require.resolve` to allow Node to resolve an actual module. If this fails then
114
- * the `modulePath` is resolved from the root of the provided config. `Config.tsPath` is used for initial resolution.
115
- * If this file path does not exist then several extensions are tried from `s_EXTENSIONS` in order: '.js', '.mjs',
116
- * '.cjs'. After a file path has been selected `isPathModule` is used to determine if the file is an ES Module.
117
- *
118
- * @param {IConfig|IPlugin} config - Oclif config or plugin config.
119
- * @param {string} modulePath - File path to load.
120
- *
121
- * @returns {{isESM: boolean, filePath: string}} An object including file path and whether the module is ESM.
122
- */
123
- static resolvePath(config, modulePath) {
124
- let isESM;
125
- let filePath;
126
- try {
127
- filePath = require.resolve(modulePath);
128
- isESM = ModuleLoader.isPathModule(filePath);
116
+ }
117
+ exports.loadWithDataFromManifest = loadWithDataFromManifest;
118
+ /**
119
+ * For `.js` files uses `getPackageType` to determine if `type` is set to `module` in associated `package.json`. If
120
+ * the `modulePath` provided ends in `.mjs` it is assumed to be ESM.
121
+ *
122
+ * @param {string} filePath - File path to test.
123
+ *
124
+ * @returns {boolean} The modulePath is an ES Module.
125
+ * @see https://www.npmjs.com/package/get-package-type
126
+ */
127
+ function isPathModule(filePath) {
128
+ const extension = (0, node_path_1.extname)(filePath).toLowerCase();
129
+ switch (extension) {
130
+ case '.js':
131
+ case '.jsx':
132
+ case '.ts':
133
+ case '.tsx': {
134
+ return getPackageType.sync(filePath) === 'module';
129
135
  }
130
- catch {
131
- filePath = (isPlugin(config) ? (0, config_1.tsPath)(config.root, modulePath, config) : (0, config_1.tsPath)(config.root, modulePath)) ?? modulePath;
132
- let fileExists = false;
133
- let isDirectory = false;
134
- if ((0, fs_1.existsSync)(filePath)) {
135
- fileExists = true;
136
- try {
137
- if ((0, fs_1.lstatSync)(filePath)?.isDirectory?.()) {
138
- fileExists = false;
139
- isDirectory = true;
140
- }
136
+ case '.mjs':
137
+ case '.mts': {
138
+ return true;
139
+ }
140
+ default: {
141
+ return false;
142
+ }
143
+ }
144
+ }
145
+ exports.isPathModule = isPathModule;
146
+ /**
147
+ * Resolves a modulePath first by `require.resolve` to allow Node to resolve an actual module. If this fails then
148
+ * the `modulePath` is resolved from the root of the provided config. `Config.tsPath` is used for initial resolution.
149
+ * If this file path does not exist then several extensions are tried from `s_EXTENSIONS` in order: '.js', '.mjs',
150
+ * '.cjs'. After a file path has been selected `isPathModule` is used to determine if the file is an ES Module.
151
+ *
152
+ * @param {IConfig|IPlugin} config - Oclif config or plugin config.
153
+ * @param {string} modulePath - File path to load.
154
+ *
155
+ * @returns {{isESM: boolean, filePath: string}} An object including file path and whether the module is ESM.
156
+ */
157
+ function resolvePath(config, modulePath) {
158
+ let isESM;
159
+ let filePath;
160
+ try {
161
+ filePath = require.resolve(modulePath);
162
+ isESM = isPathModule(filePath);
163
+ }
164
+ catch {
165
+ filePath =
166
+ (isPlugin(config) ? (0, ts_node_1.tsPath)(config.root, modulePath, config) : (0, ts_node_1.tsPath)(config.root, modulePath)) ?? modulePath;
167
+ let fileExists = false;
168
+ let isDirectory = false;
169
+ if ((0, node_fs_1.existsSync)(filePath)) {
170
+ fileExists = true;
171
+ try {
172
+ if ((0, node_fs_1.lstatSync)(filePath)?.isDirectory?.()) {
173
+ fileExists = false;
174
+ isDirectory = true;
141
175
  }
142
- catch { }
143
176
  }
144
- if (!fileExists) {
145
- // Try all supported extensions.
146
- let foundPath = ModuleLoader.findFile(filePath);
147
- if (!foundPath && isDirectory) {
148
- // Since filePath is a directory, try looking for index file.
149
- foundPath = ModuleLoader.findFile(path.join(filePath, 'index'));
150
- }
151
- if (foundPath) {
152
- filePath = foundPath;
153
- }
177
+ catch { }
178
+ }
179
+ if (!fileExists) {
180
+ // Try all supported extensions.
181
+ let foundPath = findFile(filePath);
182
+ if (!foundPath && isDirectory) {
183
+ // Since filePath is a directory, try looking for index file.
184
+ foundPath = findFile((0, node_path_1.join)(filePath, 'index'));
185
+ }
186
+ if (foundPath) {
187
+ filePath = foundPath;
154
188
  }
155
- isESM = ModuleLoader.isPathModule(filePath);
156
189
  }
157
- return { isESM, filePath };
190
+ isESM = isPathModule(filePath);
158
191
  }
159
- /**
160
- * Try adding the different extensions from `s_EXTENSIONS` to find the file.
161
- *
162
- * @param {string} filePath - File path to load.
163
- *
164
- * @returns {string | null} Modified file path including extension or null if file is not found.
165
- */
166
- static findFile(filePath) {
167
- // eslint-disable-next-line camelcase
168
- for (const extension of s_EXTENSIONS) {
169
- const testPath = `${filePath}${extension}`;
170
- if ((0, fs_1.existsSync)(testPath)) {
171
- return testPath;
172
- }
192
+ return { filePath, isESM };
193
+ }
194
+ /**
195
+ * Try adding the different extensions from `s_EXTENSIONS` to find the file.
196
+ *
197
+ * @param {string} filePath - File path to load.
198
+ *
199
+ * @returns {string | null} Modified file path including extension or null if file is not found.
200
+ */
201
+ function findFile(filePath) {
202
+ // eslint-disable-next-line camelcase
203
+ for (const extension of s_EXTENSIONS) {
204
+ const testPath = `${filePath}${extension}`;
205
+ if ((0, node_fs_1.existsSync)(testPath)) {
206
+ return testPath;
173
207
  }
174
- return null;
175
208
  }
209
+ return null;
176
210
  }
177
- exports.default = ModuleLoader;
@@ -1,12 +1,12 @@
1
1
  import { CLIError } from '../errors';
2
- import { OptionFlag, Flag } from '../interfaces';
2
+ import { Flag, OptionFlag } from '../interfaces';
3
3
  import { Arg, ArgInput, CLIParseErrorOptions } from '../interfaces/parser';
4
4
  export { CLIError } from '../errors';
5
5
  export type Validation = {
6
6
  name: string;
7
- status: 'success' | 'failed';
8
- validationFn: string;
9
7
  reason?: string;
8
+ status: 'failed' | 'success';
9
+ validationFn: string;
10
10
  };
11
11
  export declare class CLIParseError extends CLIError {
12
12
  parse: CLIParseErrorOptions['parse'];
@@ -22,7 +22,7 @@ export declare class InvalidArgsSpecError extends CLIParseError {
22
22
  }
23
23
  export declare class RequiredArgsError extends CLIParseError {
24
24
  args: Arg<any>[];
25
- constructor({ args, parse, flagsWithMultiple }: CLIParseErrorOptions & {
25
+ constructor({ args, flagsWithMultiple, parse, }: CLIParseErrorOptions & {
26
26
  args: Arg<any>[];
27
27
  flagsWithMultiple?: string[];
28
28
  });
@@ -35,13 +35,13 @@ export declare class RequiredFlagError extends CLIParseError {
35
35
  }
36
36
  export declare class UnexpectedArgsError extends CLIParseError {
37
37
  args: unknown[];
38
- constructor({ parse, args }: CLIParseErrorOptions & {
38
+ constructor({ args, parse }: CLIParseErrorOptions & {
39
39
  args: unknown[];
40
40
  });
41
41
  }
42
42
  export declare class NonExistentFlagsError extends CLIParseError {
43
43
  flags: string[];
44
- constructor({ parse, flags }: CLIParseErrorOptions & {
44
+ constructor({ flags, parse }: CLIParseErrorOptions & {
45
45
  flags: string[];
46
46
  });
47
47
  }
@@ -52,7 +52,7 @@ export declare class ArgInvalidOptionError extends CLIParseError {
52
52
  constructor(arg: Arg<any>, input: string);
53
53
  }
54
54
  export declare class FailedFlagValidationError extends CLIParseError {
55
- constructor({ parse, failed }: CLIParseErrorOptions & {
55
+ constructor({ failed, parse }: CLIParseErrorOptions & {
56
56
  failed: Validation[];
57
57
  });
58
58
  }