@oclif/core 2.14.0 → 3.0.0-beta.2
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.
- package/lib/cli-ux/action/spinner.js +1 -1
- package/lib/cli-ux/config.js +6 -5
- package/lib/cli-ux/prompt.js +2 -2
- package/lib/config/config.d.ts +2 -0
- package/lib/config/config.js +9 -44
- package/lib/config/plugin.d.ts +1 -0
- package/lib/config/plugin.js +2 -1
- package/lib/config/ts-node.d.ts +3 -2
- package/lib/config/ts-node.js +83 -36
- package/lib/errors/errors/cli.d.ts +1 -0
- package/lib/errors/errors/cli.js +1 -0
- package/lib/errors/index.d.ts +1 -0
- package/lib/errors/index.js +8 -1
- package/lib/errors/logger.js +3 -3
- package/lib/flags.js +1 -2
- package/lib/index.js +9 -0
- package/lib/interfaces/pjson.d.ts +1 -0
- package/lib/interfaces/plugin.d.ts +4 -2
- package/lib/interfaces/ts-config.d.ts +9 -0
- package/lib/main.d.ts +5 -10
- package/lib/main.js +9 -16
- package/lib/module-loader.js +9 -9
- package/package.json +12 -8
|
@@ -4,6 +4,7 @@ const chalk = require("chalk");
|
|
|
4
4
|
const supportsColor = require("supports-color");
|
|
5
5
|
const stripAnsi = require('strip-ansi');
|
|
6
6
|
const ansiStyles = require('ansi-styles');
|
|
7
|
+
const ansiEscapes = require('ansi-escapes');
|
|
7
8
|
const screen_1 = require("../../screen");
|
|
8
9
|
const spinners_1 = require("./spinners");
|
|
9
10
|
const base_1 = require("./base");
|
|
@@ -64,7 +65,6 @@ class SpinnerAction extends base_1.ActionBase {
|
|
|
64
65
|
_reset() {
|
|
65
66
|
if (!this.output)
|
|
66
67
|
return;
|
|
67
|
-
const ansiEscapes = require('ansi-escapes');
|
|
68
68
|
const lines = this._lines(this.output);
|
|
69
69
|
this._write(this.std, ansiEscapes.cursorLeft + ansiEscapes.cursorUp(lines) + ansiEscapes.eraseDown);
|
|
70
70
|
this.output = undefined;
|
package/lib/cli-ux/config.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.config = exports.Config = void 0;
|
|
4
|
+
const semver = require("semver");
|
|
4
5
|
const util_1 = require("../util");
|
|
5
6
|
const spinner_1 = require("./action/spinner");
|
|
6
7
|
const spinner_2 = require("./action/spinner");
|
|
7
8
|
const pride_spinner_1 = require("./action/pride-spinner");
|
|
9
|
+
const version = semver.parse((0, util_1.requireJson)(__dirname, '..', '..', 'package.json').version);
|
|
8
10
|
const g = global;
|
|
9
11
|
const globals = g['cli-ux'] || (g['cli-ux'] = {});
|
|
10
12
|
const actionType = (Boolean(process.stderr.isTTY) &&
|
|
@@ -36,11 +38,10 @@ class Config {
|
|
|
36
38
|
}
|
|
37
39
|
exports.Config = Config;
|
|
38
40
|
function fetch() {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
globals[major]
|
|
43
|
-
return globals[major];
|
|
41
|
+
if (globals[version.major])
|
|
42
|
+
return globals[version.major];
|
|
43
|
+
globals[version.major] = new Config();
|
|
44
|
+
return globals[version.major];
|
|
44
45
|
}
|
|
45
46
|
exports.config = fetch();
|
|
46
47
|
exports.default = exports.config;
|
package/lib/cli-ux/prompt.js
CHANGED
|
@@ -5,6 +5,8 @@ const Errors = require("../errors");
|
|
|
5
5
|
const config_1 = require("./config");
|
|
6
6
|
const chalk = require("chalk");
|
|
7
7
|
const stream_1 = require("./stream");
|
|
8
|
+
const ansiEscapes = require('ansi-escapes');
|
|
9
|
+
const passwordPrompt = require('password-prompt');
|
|
8
10
|
function normal(options, retries = 100) {
|
|
9
11
|
if (retries < 0)
|
|
10
12
|
throw new Error('no input');
|
|
@@ -56,7 +58,6 @@ async function single(options) {
|
|
|
56
58
|
return response;
|
|
57
59
|
}
|
|
58
60
|
function replacePrompt(prompt) {
|
|
59
|
-
const ansiEscapes = require('ansi-escapes');
|
|
60
61
|
stream_1.stderr.write(ansiEscapes.cursorHide + ansiEscapes.cursorUp(1) + ansiEscapes.cursorLeft + prompt +
|
|
61
62
|
ansiEscapes.cursorDown(1) + ansiEscapes.cursorLeft + ansiEscapes.cursorShow);
|
|
62
63
|
}
|
|
@@ -71,7 +72,6 @@ async function _prompt(name, inputOptions = {}) {
|
|
|
71
72
|
default: '',
|
|
72
73
|
...inputOptions,
|
|
73
74
|
};
|
|
74
|
-
const passwordPrompt = require('password-prompt');
|
|
75
75
|
switch (options.type) {
|
|
76
76
|
case 'normal':
|
|
77
77
|
return normal(options);
|
package/lib/config/config.d.ts
CHANGED
|
@@ -39,8 +39,10 @@ export declare class Config implements IConfig {
|
|
|
39
39
|
private _commands;
|
|
40
40
|
private _topics;
|
|
41
41
|
private _commandIDs;
|
|
42
|
+
private static _rootPlugin;
|
|
42
43
|
constructor(options: Options);
|
|
43
44
|
static load(opts?: LoadOptions): Promise<Config>;
|
|
45
|
+
static get rootPlugin(): Plugin.Plugin | undefined;
|
|
44
46
|
load(): Promise<void>;
|
|
45
47
|
loadPluginsAndCommands(): Promise<void>;
|
|
46
48
|
loadCorePlugins(): Promise<void>;
|
package/lib/config/config.js
CHANGED
|
@@ -15,12 +15,11 @@ const help_1 = require("../help");
|
|
|
15
15
|
const stream_1 = require("../cli-ux/stream");
|
|
16
16
|
const performance_1 = require("../performance");
|
|
17
17
|
const settings_1 = require("../settings");
|
|
18
|
-
const
|
|
19
|
-
const
|
|
18
|
+
const node_os_1 = require("node:os");
|
|
19
|
+
const node_path_1 = require("node:path");
|
|
20
20
|
// eslint-disable-next-line new-cap
|
|
21
21
|
const debug = (0, util_2.Debug)();
|
|
22
22
|
const _pjson = (0, util_3.requireJson)(__dirname, '..', '..', 'package.json');
|
|
23
|
-
const BASE = `${_pjson.name}@${_pjson.version}`;
|
|
24
23
|
function channelFromVersion(version) {
|
|
25
24
|
const m = version.match(/[^-]+(?:-([^.]+))?/);
|
|
26
25
|
return (m && m[1]) || 'stable';
|
|
@@ -61,7 +60,7 @@ class Permutations extends Map {
|
|
|
61
60
|
class Config {
|
|
62
61
|
constructor(options) {
|
|
63
62
|
this.options = options;
|
|
64
|
-
this._base =
|
|
63
|
+
this._base = `${_pjson.name}@${_pjson.version}`;
|
|
65
64
|
this.debug = 0;
|
|
66
65
|
this.plugins = [];
|
|
67
66
|
this.topicSeparator = ':';
|
|
@@ -70,24 +69,6 @@ class Config {
|
|
|
70
69
|
this.topicPermutations = new Permutations();
|
|
71
70
|
this._commands = new Map();
|
|
72
71
|
this._topics = new Map();
|
|
73
|
-
if (options.config) {
|
|
74
|
-
if (Array.isArray(options.config.plugins) && Array.isArray(this.plugins)) {
|
|
75
|
-
// incoming config is v2 with plugins array and this config is v2 with plugins array
|
|
76
|
-
Object.assign(this, options.config);
|
|
77
|
-
}
|
|
78
|
-
else if (Array.isArray(options.config.plugins) && !Array.isArray(this.plugins)) {
|
|
79
|
-
// incoming config is v2 with plugins array and this config is v3 with plugin Map
|
|
80
|
-
Object.assign(this, options.config, { plugins: new Map(options.config.plugins.map(p => [p.name, p])) });
|
|
81
|
-
}
|
|
82
|
-
else if (!Array.isArray(options.config.plugins) && Array.isArray(this.plugins)) {
|
|
83
|
-
// incoming config is v3 with plugin Map and this config is v2 with plugins array
|
|
84
|
-
Object.assign(this, options.config, { plugins: options.config.getPluginsList() });
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
// incoming config is v3 with plugin Map and this config is v3 with plugin Map
|
|
88
|
-
Object.assign(this, options.config);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
72
|
}
|
|
92
73
|
static async load(opts = module.filename || __dirname) {
|
|
93
74
|
// Handle the case when a file URL string is passed in such as 'import.meta.url'; covert to file path.
|
|
@@ -96,37 +77,21 @@ class Config {
|
|
|
96
77
|
}
|
|
97
78
|
if (typeof opts === 'string')
|
|
98
79
|
opts = { root: opts };
|
|
99
|
-
if (isConfig(opts))
|
|
100
|
-
const { lt } = await import('semver');
|
|
101
|
-
const currentConfigBase = BASE.replace('@oclif/core@', '');
|
|
102
|
-
const incomingConfigBase = opts._base.replace('@oclif/core@', '');
|
|
103
|
-
/**
|
|
104
|
-
* Reload the Config based on the version required by the command.
|
|
105
|
-
* This is needed because the command is given the Config instantiated
|
|
106
|
-
* by the root plugin, which may be a different version than the one
|
|
107
|
-
* required by the command.
|
|
108
|
-
*
|
|
109
|
-
* Doing this ensures that the command can freely use any method on Config that
|
|
110
|
-
* exists in the version of Config required by the command but may not exist on the
|
|
111
|
-
* root's instance of Config.
|
|
112
|
-
*/
|
|
113
|
-
if (lt(incomingConfigBase, currentConfigBase)) {
|
|
114
|
-
debug(`reloading config from ${opts._base} to ${BASE}`);
|
|
115
|
-
return new Config({ ...opts.options, config: opts });
|
|
116
|
-
}
|
|
80
|
+
if (isConfig(opts))
|
|
117
81
|
return opts;
|
|
118
|
-
}
|
|
119
82
|
const config = new Config(opts);
|
|
120
83
|
await config.load();
|
|
121
84
|
return config;
|
|
122
85
|
}
|
|
86
|
+
static get rootPlugin() {
|
|
87
|
+
return Config._rootPlugin;
|
|
88
|
+
}
|
|
123
89
|
// eslint-disable-next-line complexity
|
|
124
90
|
async load() {
|
|
125
|
-
if (this.options.config)
|
|
126
|
-
return;
|
|
127
91
|
settings_1.settings.performanceEnabled = (settings_1.settings.performanceEnabled === undefined ? this.options.enablePerf : settings_1.settings.performanceEnabled) ?? false;
|
|
128
92
|
const plugin = new Plugin.Plugin({ root: this.options.root });
|
|
129
93
|
await plugin.load();
|
|
94
|
+
Config._rootPlugin = plugin;
|
|
130
95
|
this.plugins.push(plugin);
|
|
131
96
|
this.root = plugin.root;
|
|
132
97
|
this.pjson = plugin.pjson;
|
|
@@ -523,7 +488,7 @@ class Config {
|
|
|
523
488
|
_shell() {
|
|
524
489
|
let shellPath;
|
|
525
490
|
const COMSPEC = process.env.COMSPEC;
|
|
526
|
-
const SHELL = process.env.SHELL ?? (0,
|
|
491
|
+
const SHELL = process.env.SHELL ?? (0, node_os_1.userInfo)().shell?.split(node_path_1.sep)?.pop();
|
|
527
492
|
if (SHELL) {
|
|
528
493
|
shellPath = SHELL.split('/');
|
|
529
494
|
}
|
package/lib/config/plugin.d.ts
CHANGED
package/lib/config/plugin.js
CHANGED
|
@@ -115,6 +115,7 @@ class Plugin {
|
|
|
115
115
|
this.root = root;
|
|
116
116
|
this._debug('reading %s plugin %s', this.type, root);
|
|
117
117
|
this.pjson = await (0, util_3.loadJSON)(path.join(root, 'package.json'));
|
|
118
|
+
this.moduleType = this.pjson.type === 'module' ? 'module' : 'commonjs';
|
|
118
119
|
this.name = this.pjson.name;
|
|
119
120
|
this.alias = this.options.name ?? this.pjson.name;
|
|
120
121
|
const pjsonPath = path.join(root, 'package.json');
|
|
@@ -149,7 +150,7 @@ class Plugin {
|
|
|
149
150
|
get commandsDir() {
|
|
150
151
|
if (this._commandsDir)
|
|
151
152
|
return this._commandsDir;
|
|
152
|
-
this._commandsDir = (0, ts_node_1.tsPath)(this.root, this.pjson.oclif.commands, this
|
|
153
|
+
this._commandsDir = (0, ts_node_1.tsPath)(this.root, this.pjson.oclif.commands, this);
|
|
153
154
|
return this._commandsDir;
|
|
154
155
|
}
|
|
155
156
|
get commandIDs() {
|
package/lib/config/ts-node.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { Plugin } from '../interfaces';
|
|
1
2
|
/**
|
|
2
3
|
* Convert a path from the compiled ./lib files to the ./src typescript source
|
|
3
4
|
* this is for developing typescript plugins/CLIs
|
|
4
5
|
* if there is a tsconfig and the original sources exist, it attempts to require ts-node
|
|
5
6
|
*/
|
|
6
|
-
export declare function tsPath(root: string, orig: string,
|
|
7
|
-
export declare function tsPath(root: string, orig: string | undefined,
|
|
7
|
+
export declare function tsPath(root: string, orig: string, plugin: Plugin): string;
|
|
8
|
+
export declare function tsPath(root: string, orig: string | undefined, plugin?: Plugin): string | undefined;
|
package/lib/config/ts-node.js
CHANGED
|
@@ -6,11 +6,15 @@ const path = require("path");
|
|
|
6
6
|
const settings_1 = require("../settings");
|
|
7
7
|
const util_1 = require("../util");
|
|
8
8
|
const util_2 = require("./util");
|
|
9
|
+
const config_1 = require("./config");
|
|
10
|
+
const errors_1 = require("../errors");
|
|
9
11
|
// eslint-disable-next-line new-cap
|
|
10
12
|
const debug = (0, util_2.Debug)('ts-node');
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
+
const TS_CONFIGS = {};
|
|
14
|
+
const REGISTERED = new Set();
|
|
13
15
|
function loadTSConfig(root) {
|
|
16
|
+
if (TS_CONFIGS[root])
|
|
17
|
+
return TS_CONFIGS[root];
|
|
14
18
|
const tsconfigPath = path.join(root, 'tsconfig.json');
|
|
15
19
|
let typescript;
|
|
16
20
|
try {
|
|
@@ -18,7 +22,7 @@ function loadTSConfig(root) {
|
|
|
18
22
|
}
|
|
19
23
|
catch {
|
|
20
24
|
try {
|
|
21
|
-
typescript = require(root
|
|
25
|
+
typescript = require(path.join(root, 'node_modules', 'typescript'));
|
|
22
26
|
}
|
|
23
27
|
catch { }
|
|
24
28
|
}
|
|
@@ -28,6 +32,7 @@ function loadTSConfig(root) {
|
|
|
28
32
|
throw new Error(`Could not read and parse tsconfig.json at ${tsconfigPath}, or it ` +
|
|
29
33
|
'did not contain a "compilerOptions" section.');
|
|
30
34
|
}
|
|
35
|
+
TS_CONFIGS[root] = tsconfig;
|
|
31
36
|
return tsconfig;
|
|
32
37
|
}
|
|
33
38
|
}
|
|
@@ -35,54 +40,96 @@ function registerTSNode(root) {
|
|
|
35
40
|
const tsconfig = loadTSConfig(root);
|
|
36
41
|
if (!tsconfig)
|
|
37
42
|
return;
|
|
43
|
+
if (REGISTERED.has(root))
|
|
44
|
+
return tsconfig;
|
|
38
45
|
debug('registering ts-node at', root);
|
|
39
46
|
const tsNodePath = require.resolve('ts-node', { paths: [root, __dirname] });
|
|
47
|
+
debug('ts-node path:', tsNodePath);
|
|
40
48
|
const tsNode = require(tsNodePath);
|
|
41
|
-
|
|
49
|
+
const typeRoots = [
|
|
50
|
+
path.join(root, 'node_modules', '@types'),
|
|
51
|
+
];
|
|
52
|
+
const rootDirs = [];
|
|
42
53
|
if (tsconfig.compilerOptions.rootDirs) {
|
|
43
|
-
|
|
54
|
+
for (const r of tsconfig.compilerOptions.rootDirs) {
|
|
55
|
+
rootDirs.push(path.join(root, r));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if (tsconfig.compilerOptions.rootDir) {
|
|
59
|
+
rootDirs.push(path.join(root, tsconfig.compilerOptions.rootDir));
|
|
44
60
|
}
|
|
45
61
|
else {
|
|
46
|
-
|
|
62
|
+
rootDirs.push(path.join(root, 'src'));
|
|
47
63
|
}
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
const conf = {
|
|
65
|
+
compilerOptions: {
|
|
66
|
+
esModuleInterop: tsconfig.compilerOptions.esModuleInterop,
|
|
67
|
+
target: tsconfig.compilerOptions.target ?? 'es2019',
|
|
68
|
+
experimentalDecorators: tsconfig.compilerOptions.experimentalDecorators ?? false,
|
|
69
|
+
emitDecoratorMetadata: tsconfig.compilerOptions.emitDecoratorMetadata ?? false,
|
|
70
|
+
module: tsconfig.compilerOptions.module ?? 'commonjs',
|
|
71
|
+
sourceMap: tsconfig.compilerOptions.sourceMap ?? true,
|
|
72
|
+
rootDirs,
|
|
73
|
+
typeRoots,
|
|
74
|
+
},
|
|
75
|
+
skipProject: true,
|
|
76
|
+
transpileOnly: true,
|
|
77
|
+
esm: tsconfig['ts-node']?.esm ?? true,
|
|
78
|
+
scope: true,
|
|
79
|
+
scopeDir: root,
|
|
80
|
+
cwd: root,
|
|
81
|
+
experimentalSpecifierResolution: tsconfig['ts-node']?.experimentalSpecifierResolution ?? 'explicit',
|
|
82
|
+
};
|
|
83
|
+
if (tsconfig.compilerOptions.moduleResolution) {
|
|
84
|
+
// @ts-expect-error TSNode.RegisterOptions.compilerOptions is typed as a plain object
|
|
85
|
+
conf.compilerOptions.moduleResolution = tsconfig.compilerOptions.moduleResolution;
|
|
67
86
|
}
|
|
68
|
-
|
|
69
|
-
|
|
87
|
+
if (tsconfig.compilerOptions.jsx) {
|
|
88
|
+
// @ts-expect-error TSNode.RegisterOptions.compilerOptions is typed as a plain object
|
|
89
|
+
conf.compilerOptions.jsx = tsconfig.compilerOptions.jsx;
|
|
70
90
|
}
|
|
91
|
+
tsNode.register(conf);
|
|
92
|
+
REGISTERED.add(root);
|
|
93
|
+
return tsconfig;
|
|
71
94
|
}
|
|
72
|
-
|
|
95
|
+
// eslint-disable-next-line complexity
|
|
96
|
+
function tsPath(root, orig, plugin) {
|
|
73
97
|
if (!orig)
|
|
74
98
|
return orig;
|
|
75
99
|
orig = orig.startsWith(root) ? orig : path.join(root, orig);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
//
|
|
82
|
-
if (
|
|
100
|
+
// NOTE: The order of these checks matter!
|
|
101
|
+
if (settings_1.settings.tsnodeEnabled === false) {
|
|
102
|
+
debug(`Skipping ts-node registration for ${root} because tsNodeEnabled is explicitly set to false`);
|
|
103
|
+
return orig;
|
|
104
|
+
}
|
|
105
|
+
// Skip ts-node registration if plugin is an ESM plugin executing from a CJS plugin
|
|
106
|
+
if (plugin?.moduleType === 'module' && config_1.Config.rootPlugin?.moduleType === 'commonjs') {
|
|
107
|
+
debug(`Skipping ts-node registration for ${root} because it's an ESM module but the root plugin is CommonJS`);
|
|
108
|
+
if (plugin.type === 'link')
|
|
109
|
+
(0, errors_1.memoizedWarn)(`${plugin.name} is a linked ESM module and cannot be auto-compiled from a CommonJS root plugin. Existing compiled source will be used instead.`);
|
|
83
110
|
return orig;
|
|
111
|
+
}
|
|
112
|
+
// If plugin is an ESM plugin being executed from an ESM root plugin, check to see if ts-node/esm loader has been set
|
|
113
|
+
// either in the NODE_OPTIONS env var or from the exec args. If the ts-node/esm loader has NOT been loaded then we want
|
|
114
|
+
// to skip ts-node registration so that it falls back on the compiled source.
|
|
115
|
+
if (plugin?.moduleType === 'module') {
|
|
116
|
+
const tsNodeEsmLoaderInExecArgv = process.execArgv.includes('--loader') && process.execArgv.includes('ts-node/esm');
|
|
117
|
+
const tsNodeEsmLoaderInNodeOptions = process.env.NODE_OPTIONS?.includes('--loader=ts-node/esm') ?? false;
|
|
118
|
+
if (!tsNodeEsmLoaderInExecArgv && !tsNodeEsmLoaderInNodeOptions) {
|
|
119
|
+
debug(`Skipping ts-node registration for ${root} because it's an ESM module but the ts-node/esm loader hasn't been run`);
|
|
120
|
+
debug('try setting NODE_OPTIONS="--loader ts-node/esm" in your environment.');
|
|
121
|
+
if (plugin.type === 'link') {
|
|
122
|
+
(0, errors_1.memoizedWarn)(`${plugin.name} is a linked ESM module and cannot be auto-compiled without setting NODE_OPTIONS="--loader=ts-node/esm" in the environment. Existing compiled source will be used instead.`);
|
|
123
|
+
}
|
|
124
|
+
return orig;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (settings_1.settings.tsnodeEnabled === undefined && (0, util_1.isProd)() && plugin?.type !== 'link') {
|
|
128
|
+
debug(`Skipping ts-node registration for ${root} because NODE_ENV is NOT "test" or "development"`);
|
|
129
|
+
return orig;
|
|
130
|
+
}
|
|
84
131
|
try {
|
|
85
|
-
const tsconfig =
|
|
132
|
+
const tsconfig = registerTSNode(root);
|
|
86
133
|
if (!tsconfig)
|
|
87
134
|
return orig;
|
|
88
135
|
const { rootDir, rootDirs, outDir } = tsconfig.compilerOptions;
|
|
@@ -8,6 +8,7 @@ export declare function addOclifExitCode(error: Record<string, any>, options?: {
|
|
|
8
8
|
export declare class CLIError extends Error implements OclifError {
|
|
9
9
|
oclif: OclifError['oclif'];
|
|
10
10
|
code?: string;
|
|
11
|
+
suggestions?: string[];
|
|
11
12
|
constructor(error: string | Error, options?: {
|
|
12
13
|
exit?: number | false;
|
|
13
14
|
} & PrettyPrintableError);
|
package/lib/errors/errors/cli.js
CHANGED
package/lib/errors/index.d.ts
CHANGED
package/lib/errors/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.warn = exports.error = exports.exit = exports.config = exports.Logger = exports.CLIError = exports.ModuleLoadError = exports.ExitError = exports.handle = void 0;
|
|
3
|
+
exports.memoizedWarn = exports.warn = exports.error = exports.exit = exports.config = exports.Logger = exports.CLIError = exports.ModuleLoadError = exports.ExitError = exports.handle = void 0;
|
|
4
4
|
var handle_1 = require("./handle");
|
|
5
5
|
Object.defineProperty(exports, "handle", { enumerable: true, get: function () { return handle_1.handle; } });
|
|
6
6
|
var exit_1 = require("./errors/exit");
|
|
@@ -60,3 +60,10 @@ function warn(input) {
|
|
|
60
60
|
config_2.config.errorLogger.log(err?.stack ?? '');
|
|
61
61
|
}
|
|
62
62
|
exports.warn = warn;
|
|
63
|
+
const WARNINGS = new Set();
|
|
64
|
+
function memoizedWarn(input) {
|
|
65
|
+
if (!WARNINGS.has(input))
|
|
66
|
+
warn(input);
|
|
67
|
+
WARNINGS.add(input);
|
|
68
|
+
}
|
|
69
|
+
exports.memoizedWarn = memoizedWarn;
|
package/lib/errors/logger.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Logger = void 0;
|
|
4
|
-
const fs = require("fs
|
|
5
|
-
const
|
|
4
|
+
const fs = require("fs-extra");
|
|
5
|
+
const path = require("path");
|
|
6
6
|
const stripAnsi = require("strip-ansi");
|
|
7
7
|
const timestamp = () => new Date().toISOString();
|
|
8
8
|
let timer;
|
|
@@ -35,7 +35,7 @@ class Logger {
|
|
|
35
35
|
return;
|
|
36
36
|
const mylines = this.buffer;
|
|
37
37
|
this.buffer = [];
|
|
38
|
-
await fs.
|
|
38
|
+
await fs.mkdirp(path.dirname(this.file));
|
|
39
39
|
await fs.appendFile(this.file, mylines.join('\n') + '\n');
|
|
40
40
|
});
|
|
41
41
|
await this.flushing;
|
package/lib/flags.js
CHANGED
|
@@ -84,8 +84,7 @@ const help = (opts = {}) => {
|
|
|
84
84
|
description: 'Show CLI help.',
|
|
85
85
|
...opts,
|
|
86
86
|
parse: async (_, cmd) => {
|
|
87
|
-
|
|
88
|
-
await new Help(cmd.config, cmd.config.pjson.helpOptions).showHelp(cmd.id ? [cmd.id, ...cmd.argv] : cmd.argv);
|
|
87
|
+
new help_1.Help(cmd.config).showHelp(cmd.id ? [cmd.id, ...cmd.argv] : cmd.argv);
|
|
89
88
|
cmd.exit(0);
|
|
90
89
|
},
|
|
91
90
|
});
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.stdout = exports.stderr = exports.execute = exports.ux = exports.flush = exports.settings = exports.toConfiguredId = exports.toStandardizedId = exports.tsPath = exports.toCached = exports.run = exports.Performance = exports.Plugin = exports.Parser = exports.Interfaces = exports.HelpBase = exports.Help = exports.loadHelpClass = exports.Flags = exports.Errors = exports.Config = exports.CommandHelp = exports.Command = exports.Args = void 0;
|
|
4
|
+
const semver = require("semver");
|
|
4
5
|
const command_1 = require("./command");
|
|
5
6
|
Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return command_1.Command; } });
|
|
6
7
|
const main_1 = require("./main");
|
|
@@ -33,6 +34,7 @@ const settings_1 = require("./settings");
|
|
|
33
34
|
Object.defineProperty(exports, "settings", { enumerable: true, get: function () { return settings_1.settings; } });
|
|
34
35
|
const ux = require("./cli-ux");
|
|
35
36
|
exports.ux = ux;
|
|
37
|
+
const util_2 = require("./util");
|
|
36
38
|
const stream_1 = require("./cli-ux/stream");
|
|
37
39
|
Object.defineProperty(exports, "stderr", { enumerable: true, get: function () { return stream_1.stderr; } });
|
|
38
40
|
Object.defineProperty(exports, "stdout", { enumerable: true, get: function () { return stream_1.stdout; } });
|
|
@@ -50,4 +52,11 @@ function checkCWD() {
|
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
}
|
|
55
|
+
function checkNodeVersion() {
|
|
56
|
+
const pjson = (0, util_2.requireJson)(__dirname, '..', 'package.json');
|
|
57
|
+
if (!semver.satisfies(process.versions.node, pjson.engines.node)) {
|
|
58
|
+
stream_1.stderr.write(`WARNING\nWARNING Node version must be ${pjson.engines.node} to use this CLI\nWARNING Current node version: ${process.versions.node}\nWARNING\n`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
53
61
|
checkCWD();
|
|
62
|
+
checkNodeVersion();
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Config } from './config';
|
|
2
1
|
import { Command } from '../command';
|
|
3
2
|
import { PJSON } from './pjson';
|
|
4
3
|
import { Topic } from './topic';
|
|
@@ -19,7 +18,6 @@ export interface Options extends PluginOptions {
|
|
|
19
18
|
channel?: string;
|
|
20
19
|
version?: string;
|
|
21
20
|
enablePerf?: boolean;
|
|
22
|
-
config?: Config;
|
|
23
21
|
}
|
|
24
22
|
export interface Plugin {
|
|
25
23
|
/**
|
|
@@ -51,6 +49,10 @@ export interface Plugin {
|
|
|
51
49
|
* examples: core, link, user, dev
|
|
52
50
|
*/
|
|
53
51
|
type: string;
|
|
52
|
+
/**
|
|
53
|
+
* Plugin is written in ESM or CommonJS
|
|
54
|
+
*/
|
|
55
|
+
moduleType: 'module' | 'commonjs';
|
|
54
56
|
/**
|
|
55
57
|
* base path of plugin
|
|
56
58
|
*/
|
|
@@ -7,5 +7,14 @@ export interface TSConfig {
|
|
|
7
7
|
esModuleInterop?: boolean;
|
|
8
8
|
experimentalDecorators?: boolean;
|
|
9
9
|
emitDecoratorMetadata?: boolean;
|
|
10
|
+
module?: string;
|
|
11
|
+
moduleResolution?: string;
|
|
12
|
+
sourceMap?: boolean;
|
|
13
|
+
jsx?: boolean;
|
|
14
|
+
};
|
|
15
|
+
'ts-node'?: {
|
|
16
|
+
esm?: boolean;
|
|
17
|
+
experimentalSpecifierResolution?: 'node' | 'explicit';
|
|
18
|
+
scope?: boolean;
|
|
10
19
|
};
|
|
11
20
|
}
|
package/lib/main.d.ts
CHANGED
|
@@ -11,46 +11,41 @@ export declare function run(argv?: string[], options?: Interfaces.LoadOptions):
|
|
|
11
11
|
*
|
|
12
12
|
* @example For ESM dev.js
|
|
13
13
|
* ```
|
|
14
|
-
* #!/usr/bin/env
|
|
15
|
-
* // eslint-disable-next-line node/shebang
|
|
14
|
+
* #!/usr/bin/env node
|
|
16
15
|
* (async () => {
|
|
17
16
|
* const oclif = await import('@oclif/core')
|
|
18
|
-
* await oclif.execute({
|
|
17
|
+
* await oclif.execute({development: true, dir: import.meta.url})
|
|
19
18
|
* })()
|
|
20
19
|
* ```
|
|
21
20
|
*
|
|
22
21
|
* @example For ESM run.js
|
|
23
22
|
* ```
|
|
24
23
|
* #!/usr/bin/env node
|
|
25
|
-
* // eslint-disable-next-line node/shebang
|
|
26
24
|
* (async () => {
|
|
27
25
|
* const oclif = await import('@oclif/core')
|
|
28
|
-
* await oclif.execute({
|
|
26
|
+
* await oclif.execute({dir: import.meta.url})
|
|
29
27
|
* })()
|
|
30
28
|
* ```
|
|
31
29
|
*
|
|
32
30
|
* @example For CJS dev.js
|
|
33
31
|
* ```
|
|
34
32
|
* #!/usr/bin/env node
|
|
35
|
-
* // eslint-disable-next-line node/shebang
|
|
36
33
|
* (async () => {
|
|
37
34
|
* const oclif = await import('@oclif/core')
|
|
38
|
-
* await oclif.execute({
|
|
35
|
+
* await oclif.execute({development: true, dir: __dirname})
|
|
39
36
|
* })()
|
|
40
37
|
* ```
|
|
41
38
|
*
|
|
42
39
|
* @example For CJS run.js
|
|
43
40
|
* ```
|
|
44
41
|
* #!/usr/bin/env node
|
|
45
|
-
* // eslint-disable-next-line node/shebang
|
|
46
42
|
* (async () => {
|
|
47
43
|
* const oclif = await import('@oclif/core')
|
|
48
|
-
* await oclif.execute({
|
|
44
|
+
* await oclif.execute({dir: __dirname})
|
|
49
45
|
* })()
|
|
50
46
|
* ```
|
|
51
47
|
*/
|
|
52
48
|
export declare function execute(options: {
|
|
53
|
-
type: 'cjs' | 'esm';
|
|
54
49
|
dir: string;
|
|
55
50
|
args?: string[];
|
|
56
51
|
loadOptions?: Interfaces.LoadOptions;
|
package/lib/main.js
CHANGED
|
@@ -8,9 +8,9 @@ const config_1 = require("./config");
|
|
|
8
8
|
const help_1 = require("./help");
|
|
9
9
|
const settings_1 = require("./settings");
|
|
10
10
|
const _1 = require(".");
|
|
11
|
-
const path_1 = require("path");
|
|
12
11
|
const stream_1 = require("./cli-ux/stream");
|
|
13
12
|
const performance_1 = require("./performance");
|
|
13
|
+
const debug = require('debug')('oclif:main');
|
|
14
14
|
const log = (message = '', ...args) => {
|
|
15
15
|
message = typeof message === 'string' ? message : (0, util_1.inspect)(message);
|
|
16
16
|
stream_1.stdout.write((0, util_1.format)(message, ...args) + '\n');
|
|
@@ -45,6 +45,9 @@ async function run(argv, options) {
|
|
|
45
45
|
await performance_1.Performance.collect();
|
|
46
46
|
performance_1.Performance.debug();
|
|
47
47
|
};
|
|
48
|
+
debug(`process.execPath: ${process.execPath}`);
|
|
49
|
+
debug(`process.execArgv: ${process.execArgv}`);
|
|
50
|
+
debug('process.argv: %O', process.argv);
|
|
48
51
|
argv = argv ?? process.argv.slice(2);
|
|
49
52
|
// Handle the case when a file URL string or URL is passed in such as 'import.meta.url'; covert to file path.
|
|
50
53
|
if (options && ((typeof options === 'string' && options.startsWith('file://')) || options instanceof url_2.URL)) {
|
|
@@ -93,9 +96,6 @@ async function run(argv, options) {
|
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
98
|
exports.run = run;
|
|
96
|
-
function getTsConfigPath(dir, type) {
|
|
97
|
-
return type === 'cjs' ? (0, path_1.join)(dir, '..', 'tsconfig.json') : (0, path_1.join)((0, path_1.dirname)((0, url_1.fileURLToPath)(dir)), '..', 'tsconfig.json');
|
|
98
|
-
}
|
|
99
99
|
/**
|
|
100
100
|
* Load and run oclif CLI
|
|
101
101
|
*
|
|
@@ -104,41 +104,37 @@ function getTsConfigPath(dir, type) {
|
|
|
104
104
|
*
|
|
105
105
|
* @example For ESM dev.js
|
|
106
106
|
* ```
|
|
107
|
-
* #!/usr/bin/env
|
|
108
|
-
* // eslint-disable-next-line node/shebang
|
|
107
|
+
* #!/usr/bin/env node
|
|
109
108
|
* (async () => {
|
|
110
109
|
* const oclif = await import('@oclif/core')
|
|
111
|
-
* await oclif.execute({
|
|
110
|
+
* await oclif.execute({development: true, dir: import.meta.url})
|
|
112
111
|
* })()
|
|
113
112
|
* ```
|
|
114
113
|
*
|
|
115
114
|
* @example For ESM run.js
|
|
116
115
|
* ```
|
|
117
116
|
* #!/usr/bin/env node
|
|
118
|
-
* // eslint-disable-next-line node/shebang
|
|
119
117
|
* (async () => {
|
|
120
118
|
* const oclif = await import('@oclif/core')
|
|
121
|
-
* await oclif.execute({
|
|
119
|
+
* await oclif.execute({dir: import.meta.url})
|
|
122
120
|
* })()
|
|
123
121
|
* ```
|
|
124
122
|
*
|
|
125
123
|
* @example For CJS dev.js
|
|
126
124
|
* ```
|
|
127
125
|
* #!/usr/bin/env node
|
|
128
|
-
* // eslint-disable-next-line node/shebang
|
|
129
126
|
* (async () => {
|
|
130
127
|
* const oclif = await import('@oclif/core')
|
|
131
|
-
* await oclif.execute({
|
|
128
|
+
* await oclif.execute({development: true, dir: __dirname})
|
|
132
129
|
* })()
|
|
133
130
|
* ```
|
|
134
131
|
*
|
|
135
132
|
* @example For CJS run.js
|
|
136
133
|
* ```
|
|
137
134
|
* #!/usr/bin/env node
|
|
138
|
-
* // eslint-disable-next-line node/shebang
|
|
139
135
|
* (async () => {
|
|
140
136
|
* const oclif = await import('@oclif/core')
|
|
141
|
-
* await oclif.execute({
|
|
137
|
+
* await oclif.execute({dir: __dirname})
|
|
142
138
|
* })()
|
|
143
139
|
* ```
|
|
144
140
|
*/
|
|
@@ -146,9 +142,6 @@ async function execute(options) {
|
|
|
146
142
|
if (options.development) {
|
|
147
143
|
// In dev mode -> use ts-node and dev plugins
|
|
148
144
|
process.env.NODE_ENV = 'development';
|
|
149
|
-
require('ts-node').register({
|
|
150
|
-
project: getTsConfigPath(options.dir, options.type),
|
|
151
|
-
});
|
|
152
145
|
settings_1.settings.debug = true;
|
|
153
146
|
}
|
|
154
147
|
await run(options.args ?? process.argv.slice(2), options.loadOptions ?? options.dir)
|
package/lib/module-loader.js
CHANGED
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const url = require("url");
|
|
5
|
-
const
|
|
5
|
+
const fs = require("fs-extra");
|
|
6
6
|
const errors_1 = require("./errors");
|
|
7
|
-
const
|
|
7
|
+
const config_1 = require("./config");
|
|
8
8
|
const getPackageType = require('get-package-type');
|
|
9
9
|
/**
|
|
10
10
|
* Defines file extension resolution when source files do not have an extension.
|
|
11
11
|
*/
|
|
12
12
|
// eslint-disable-next-line camelcase
|
|
13
13
|
const s_EXTENSIONS = ['.ts', '.js', '.mjs', '.cjs'];
|
|
14
|
+
const isPlugin = (config) => {
|
|
15
|
+
return config.type !== undefined;
|
|
16
|
+
};
|
|
14
17
|
/**
|
|
15
18
|
* Provides a static class with several utility methods to work with Oclif config / plugin to load ESM or CJS Node
|
|
16
19
|
* modules and source files.
|
|
@@ -120,21 +123,18 @@ class ModuleLoader {
|
|
|
120
123
|
static resolvePath(config, modulePath) {
|
|
121
124
|
let isESM;
|
|
122
125
|
let filePath;
|
|
123
|
-
const isPlugin = (config) => {
|
|
124
|
-
return config.type !== undefined;
|
|
125
|
-
};
|
|
126
126
|
try {
|
|
127
127
|
filePath = require.resolve(modulePath);
|
|
128
128
|
isESM = ModuleLoader.isPathModule(filePath);
|
|
129
129
|
}
|
|
130
130
|
catch {
|
|
131
|
-
filePath = isPlugin(config) ?
|
|
131
|
+
filePath = (isPlugin(config) ? (0, config_1.tsPath)(config.root, modulePath, config) : (0, config_1.tsPath)(config.root, modulePath)) ?? modulePath;
|
|
132
132
|
let fileExists = false;
|
|
133
133
|
let isDirectory = false;
|
|
134
|
-
if (
|
|
134
|
+
if (fs.existsSync(filePath)) {
|
|
135
135
|
fileExists = true;
|
|
136
136
|
try {
|
|
137
|
-
if (
|
|
137
|
+
if (fs.lstatSync(filePath)?.isDirectory?.()) {
|
|
138
138
|
fileExists = false;
|
|
139
139
|
isDirectory = true;
|
|
140
140
|
}
|
|
@@ -167,7 +167,7 @@ class ModuleLoader {
|
|
|
167
167
|
// eslint-disable-next-line camelcase
|
|
168
168
|
for (const extension of s_EXTENSIONS) {
|
|
169
169
|
const testPath = `${filePath}${extension}`;
|
|
170
|
-
if (
|
|
170
|
+
if (fs.existsSync(testPath)) {
|
|
171
171
|
return testPath;
|
|
172
172
|
}
|
|
173
173
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oclif/core",
|
|
3
3
|
"description": "base library for oclif CLIs",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.0-beta.2",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/oclif/core/issues",
|
|
7
7
|
"dependencies": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"cli-progress": "^3.12.0",
|
|
15
15
|
"debug": "^4.3.4",
|
|
16
16
|
"ejs": "^3.1.8",
|
|
17
|
+
"fs-extra": "^9.1.0",
|
|
17
18
|
"get-package-type": "^0.1.0",
|
|
18
19
|
"globby": "^11.1.0",
|
|
19
20
|
"hyperlinker": "^1.0.0",
|
|
@@ -23,7 +24,7 @@
|
|
|
23
24
|
"natural-orderby": "^2.0.3",
|
|
24
25
|
"object-treeify": "^1.1.33",
|
|
25
26
|
"password-prompt": "^1.1.2",
|
|
26
|
-
"semver": "^7.5.
|
|
27
|
+
"semver": "^7.5.3",
|
|
27
28
|
"slice-ansi": "^4.0.0",
|
|
28
29
|
"string-width": "^4.2.3",
|
|
29
30
|
"strip-ansi": "^6.0.1",
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
"@types/chai-as-promised": "^7.1.5",
|
|
47
48
|
"@types/clean-stack": "^2.1.1",
|
|
48
49
|
"@types/ejs": "^3.1.2",
|
|
50
|
+
"@types/fs-extra": "^9.0.13",
|
|
49
51
|
"@types/indent-string": "^4.0.1",
|
|
50
52
|
"@types/js-yaml": "^3.12.7",
|
|
51
53
|
"@types/mocha": "^8.2.3",
|
|
@@ -53,7 +55,7 @@
|
|
|
53
55
|
"@types/node": "^16",
|
|
54
56
|
"@types/node-notifier": "^8.0.2",
|
|
55
57
|
"@types/proxyquire": "^1.3.28",
|
|
56
|
-
"@types/semver": "^7.5.
|
|
58
|
+
"@types/semver": "^7.5.0",
|
|
57
59
|
"@types/shelljs": "^0.8.11",
|
|
58
60
|
"@types/slice-ansi": "^4.0.0",
|
|
59
61
|
"@types/strip-ansi": "^5.2.1",
|
|
@@ -64,13 +66,14 @@
|
|
|
64
66
|
"chai": "^4.3.7",
|
|
65
67
|
"chai-as-promised": "^7.1.1",
|
|
66
68
|
"commitlint": "^12.1.4",
|
|
69
|
+
"cross-env": "^7.0.3",
|
|
67
70
|
"eslint": "^7.32.0",
|
|
68
71
|
"eslint-config-oclif": "^4.0.0",
|
|
69
72
|
"eslint-config-oclif-typescript": "^1.0.3",
|
|
70
73
|
"fancy-test": "^2.0.16",
|
|
71
74
|
"globby": "^11.1.0",
|
|
72
75
|
"husky": "6",
|
|
73
|
-
"mocha": "^
|
|
76
|
+
"mocha": "^10.2.0",
|
|
74
77
|
"nock": "^13.3.0",
|
|
75
78
|
"proxyquire": "^2.1.3",
|
|
76
79
|
"shelljs": "^0.8.5",
|
|
@@ -108,14 +111,15 @@
|
|
|
108
111
|
"scripts": {
|
|
109
112
|
"build": "shx rm -rf lib && tsc",
|
|
110
113
|
"commitlint": "commitlint",
|
|
114
|
+
"compile": "tsc",
|
|
111
115
|
"lint": "eslint . --ext .ts --config .eslintrc",
|
|
112
116
|
"posttest": "yarn lint",
|
|
113
|
-
"compile": "tsc",
|
|
114
117
|
"prepack": "yarn run build",
|
|
115
|
-
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
|
|
116
|
-
"test:e2e": "mocha --forbid-only \"test/**/*.e2e.ts\" --timeout 1200000",
|
|
117
118
|
"pretest": "yarn build --noEmit && tsc -p test --noEmit --skipLibCheck",
|
|
118
|
-
"test:
|
|
119
|
+
"test:e2e": "mocha --forbid-only \"test/**/*.e2e.ts\" --parallel --timeout 1200000",
|
|
120
|
+
"test:esm-cjs": "cross-env DEBUG=e2e:* ts-node test/integration/esm-cjs.ts",
|
|
121
|
+
"test:perf": "ts-node test/perf/parser.perf.ts",
|
|
122
|
+
"test": "mocha --forbid-only \"test/**/*.test.ts\""
|
|
119
123
|
},
|
|
120
124
|
"types": "lib/index.d.ts"
|
|
121
125
|
}
|