@oclif/core 3.0.0-beta.2 → 3.0.0-beta.21
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/README.md +10 -6
- package/flush.js +1 -1
- package/handle.js +1 -1
- package/lib/args.d.ts +1 -1
- package/lib/args.js +17 -18
- package/lib/cli-ux/action/base.d.ts +3 -5
- package/lib/cli-ux/action/base.js +32 -26
- package/lib/cli-ux/action/simple.js +13 -18
- package/lib/cli-ux/action/spinner.d.ts +4 -2
- package/lib/cli-ux/action/spinner.js +27 -19
- package/lib/cli-ux/action/spinners.js +1 -1
- package/lib/cli-ux/action/types.d.ts +5 -0
- package/lib/cli-ux/action/types.js +2 -0
- package/lib/cli-ux/config.d.ts +0 -1
- package/lib/cli-ux/config.js +17 -21
- package/lib/cli-ux/exit.d.ts +1 -1
- package/lib/cli-ux/exit.js +4 -1
- package/lib/cli-ux/flush.d.ts +1 -0
- package/lib/cli-ux/flush.js +28 -0
- package/lib/cli-ux/index.d.ts +10 -30
- package/lib/cli-ux/index.js +32 -75
- package/lib/cli-ux/list.js +3 -3
- package/lib/cli-ux/prompt.js +32 -22
- package/lib/cli-ux/stream.js +1 -0
- package/lib/cli-ux/styled/index.d.ts +5 -6
- package/lib/cli-ux/styled/index.js +11 -11
- package/lib/cli-ux/styled/json.js +8 -5
- package/lib/cli-ux/styled/object.js +7 -9
- package/lib/cli-ux/styled/table.d.ts +4 -4
- package/lib/cli-ux/styled/table.js +61 -64
- package/lib/cli-ux/styled/tree.js +1 -3
- package/lib/cli-ux/wait.js +3 -5
- package/lib/command.d.ts +15 -19
- package/lib/command.js +117 -96
- package/lib/config/config.d.ts +16 -23
- package/lib/config/config.js +180 -334
- package/lib/config/index.d.ts +1 -1
- package/lib/config/index.js +1 -2
- package/lib/config/plugin-loader.d.ts +30 -0
- package/lib/config/plugin-loader.js +145 -0
- package/lib/config/plugin.d.ts +6 -11
- package/lib/config/plugin.js +112 -78
- package/lib/config/ts-node.d.ts +2 -1
- package/lib/config/ts-node.js +64 -51
- package/lib/config/util.d.ts +1 -11
- package/lib/config/util.js +6 -59
- package/lib/errors/config.js +1 -1
- package/lib/errors/errors/cli.d.ts +1 -1
- package/lib/errors/errors/cli.js +18 -14
- package/lib/errors/errors/exit.d.ts +0 -3
- package/lib/errors/errors/exit.js +1 -1
- package/lib/errors/errors/module-load.d.ts +0 -3
- package/lib/errors/errors/module-load.js +1 -1
- package/lib/errors/errors/pretty-print.js +11 -9
- package/lib/errors/handle.d.ts +12 -2
- package/lib/errors/handle.js +28 -18
- package/lib/errors/index.d.ts +2 -2
- package/lib/errors/index.js +20 -19
- package/lib/errors/logger.js +9 -8
- package/lib/execute.d.ts +49 -0
- package/lib/execute.js +63 -0
- package/lib/flags.d.ts +102 -31
- package/lib/flags.js +81 -46
- package/lib/help/command.d.ts +2 -0
- package/lib/help/command.js +68 -53
- package/lib/help/docopts.js +9 -13
- package/lib/help/formatter.d.ts +1 -1
- package/lib/help/formatter.js +35 -24
- package/lib/help/index.d.ts +7 -3
- package/lib/help/index.js +77 -55
- package/lib/help/root.js +7 -9
- package/lib/help/util.d.ts +1 -7
- package/lib/help/util.js +8 -28
- package/lib/index.d.ts +19 -18
- package/lib/index.js +36 -48
- package/lib/interfaces/config.d.ts +30 -30
- package/lib/interfaces/errors.d.ts +1 -1
- package/lib/interfaces/hooks.d.ts +3 -3
- package/lib/interfaces/index.d.ts +14 -14
- package/lib/interfaces/parser.d.ts +188 -116
- package/lib/interfaces/pjson.d.ts +2 -1
- package/lib/interfaces/plugin.d.ts +10 -1
- package/lib/main.d.ts +0 -48
- package/lib/main.js +11 -66
- package/lib/module-loader.d.ts +68 -79
- package/lib/module-loader.js +183 -150
- package/lib/parser/errors.d.ts +3 -3
- package/lib/parser/errors.js +17 -10
- package/lib/parser/help.js +5 -5
- package/lib/parser/parse.d.ts +3 -0
- package/lib/parser/parse.js +114 -115
- package/lib/parser/validate.js +45 -25
- package/lib/performance.d.ts +5 -1
- package/lib/performance.js +40 -19
- package/lib/util/aggregate-flags.d.ts +2 -0
- package/lib/util/aggregate-flags.js +13 -0
- package/lib/util/cache-command.d.ts +3 -0
- package/lib/util/cache-command.js +109 -0
- package/lib/util/cache-default-value.d.ts +2 -0
- package/lib/util/cache-default-value.js +28 -0
- package/lib/util/ensure-arg-object.d.ts +12 -0
- package/lib/util/ensure-arg-object.js +14 -0
- package/lib/util/fs.d.ts +7 -0
- package/lib/util/fs.js +54 -0
- package/lib/util/os.d.ts +19 -0
- package/lib/util/os.js +28 -0
- package/lib/{util.d.ts → util/util.d.ts} +6 -15
- package/lib/util/util.js +98 -0
- package/package.json +32 -34
- package/lib/cli-ux/action/pride-spinner.d.ts +0 -4
- package/lib/cli-ux/action/pride-spinner.js +0 -30
- package/lib/util.js +0 -126
package/lib/config/index.d.ts
CHANGED
package/lib/config/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.tsPath = exports.Plugin = exports.
|
|
3
|
+
exports.tsPath = exports.Plugin = exports.Config = void 0;
|
|
4
4
|
var config_1 = require("./config");
|
|
5
5
|
Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
|
|
6
|
-
Object.defineProperty(exports, "toCached", { enumerable: true, get: function () { return config_1.toCached; } });
|
|
7
6
|
var plugin_1 = require("./plugin");
|
|
8
7
|
Object.defineProperty(exports, "Plugin", { enumerable: true, get: function () { return plugin_1.Plugin; } });
|
|
9
8
|
var ts_node_1 = require("./ts-node");
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Plugin as IPlugin } from '../interfaces/plugin';
|
|
2
|
+
type PluginLoaderOptions = {
|
|
3
|
+
root: string;
|
|
4
|
+
plugins?: IPlugin[] | PluginsMap;
|
|
5
|
+
};
|
|
6
|
+
type LoadOpts = {
|
|
7
|
+
devPlugins?: boolean;
|
|
8
|
+
userPlugins?: boolean;
|
|
9
|
+
dataDir: string;
|
|
10
|
+
rootPlugin: IPlugin;
|
|
11
|
+
force?: boolean;
|
|
12
|
+
};
|
|
13
|
+
type PluginsMap = Map<string, IPlugin>;
|
|
14
|
+
export default class PluginLoader {
|
|
15
|
+
options: PluginLoaderOptions;
|
|
16
|
+
plugins: PluginsMap;
|
|
17
|
+
errors: (string | Error)[];
|
|
18
|
+
private pluginsProvided;
|
|
19
|
+
constructor(options: PluginLoaderOptions);
|
|
20
|
+
loadRoot(): Promise<IPlugin>;
|
|
21
|
+
loadChildren(opts: LoadOpts): Promise<{
|
|
22
|
+
plugins: PluginsMap;
|
|
23
|
+
errors: (string | Error)[];
|
|
24
|
+
}>;
|
|
25
|
+
private loadCorePlugins;
|
|
26
|
+
private loadDevPlugins;
|
|
27
|
+
private loadUserPlugins;
|
|
28
|
+
private loadPlugins;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const Plugin = tslib_1.__importStar(require("./plugin"));
|
|
5
|
+
const util_1 = require("./util");
|
|
6
|
+
const performance_1 = require("../performance");
|
|
7
|
+
const util_2 = require("../util/util");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const fs_1 = require("../util/fs");
|
|
10
|
+
// eslint-disable-next-line new-cap
|
|
11
|
+
const debug = (0, util_1.Debug)();
|
|
12
|
+
class PluginLoader {
|
|
13
|
+
options;
|
|
14
|
+
plugins = new Map();
|
|
15
|
+
errors = [];
|
|
16
|
+
pluginsProvided = false;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.options = options;
|
|
19
|
+
if (options.plugins) {
|
|
20
|
+
this.pluginsProvided = true;
|
|
21
|
+
this.plugins = Array.isArray(options.plugins) ? new Map(options.plugins.map((p) => [p.name, p])) : options.plugins;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async loadRoot() {
|
|
25
|
+
let rootPlugin;
|
|
26
|
+
if (this.pluginsProvided) {
|
|
27
|
+
const plugins = [...this.plugins.values()];
|
|
28
|
+
rootPlugin = plugins.find((p) => p.root === this.options.root) ?? plugins[0];
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const marker = performance_1.Performance.mark('plugin.load#root');
|
|
32
|
+
rootPlugin = new Plugin.Plugin({ root: this.options.root, isRoot: true });
|
|
33
|
+
await rootPlugin.load();
|
|
34
|
+
marker?.addDetails({
|
|
35
|
+
hasManifest: rootPlugin.hasManifest ?? false,
|
|
36
|
+
commandCount: rootPlugin.commands.length,
|
|
37
|
+
topicCount: rootPlugin.topics.length,
|
|
38
|
+
type: rootPlugin.type,
|
|
39
|
+
usesMain: Boolean(rootPlugin.pjson.main),
|
|
40
|
+
name: rootPlugin.name,
|
|
41
|
+
});
|
|
42
|
+
marker?.stop();
|
|
43
|
+
}
|
|
44
|
+
this.plugins.set(rootPlugin.name, rootPlugin);
|
|
45
|
+
return rootPlugin;
|
|
46
|
+
}
|
|
47
|
+
async loadChildren(opts) {
|
|
48
|
+
if (!this.pluginsProvided || opts.force) {
|
|
49
|
+
await this.loadUserPlugins(opts);
|
|
50
|
+
await this.loadDevPlugins(opts);
|
|
51
|
+
await this.loadCorePlugins(opts);
|
|
52
|
+
}
|
|
53
|
+
return { plugins: this.plugins, errors: this.errors };
|
|
54
|
+
}
|
|
55
|
+
async loadCorePlugins(opts) {
|
|
56
|
+
if (opts.rootPlugin.pjson.oclif.plugins) {
|
|
57
|
+
await this.loadPlugins(opts.rootPlugin.root, 'core', opts.rootPlugin.pjson.oclif.plugins);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async loadDevPlugins(opts) {
|
|
61
|
+
if (opts.devPlugins !== false) {
|
|
62
|
+
// do not load oclif.devPlugins in production
|
|
63
|
+
if ((0, util_2.isProd)())
|
|
64
|
+
return;
|
|
65
|
+
try {
|
|
66
|
+
const { devPlugins } = opts.rootPlugin.pjson.oclif;
|
|
67
|
+
if (devPlugins)
|
|
68
|
+
await this.loadPlugins(opts.rootPlugin.root, 'dev', devPlugins);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
process.emitWarning(error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async loadUserPlugins(opts) {
|
|
76
|
+
if (opts.userPlugins !== false) {
|
|
77
|
+
try {
|
|
78
|
+
const userPJSONPath = (0, node_path_1.join)(opts.dataDir, 'package.json');
|
|
79
|
+
debug('reading user plugins pjson %s', userPJSONPath);
|
|
80
|
+
const pjson = await (0, fs_1.readJson)(userPJSONPath);
|
|
81
|
+
if (!pjson.oclif)
|
|
82
|
+
pjson.oclif = { schema: 1 };
|
|
83
|
+
if (!pjson.oclif.plugins)
|
|
84
|
+
pjson.oclif.plugins = [];
|
|
85
|
+
await this.loadPlugins(userPJSONPath, 'user', pjson.oclif.plugins.filter((p) => p.type === 'user'));
|
|
86
|
+
await this.loadPlugins(userPJSONPath, 'link', pjson.oclif.plugins.filter((p) => p.type === 'link'));
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (error.code !== 'ENOENT')
|
|
90
|
+
process.emitWarning(error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async loadPlugins(root, type, plugins, parent) {
|
|
95
|
+
if (!plugins || plugins.length === 0)
|
|
96
|
+
return;
|
|
97
|
+
const mark = performance_1.Performance.mark(`config.loadPlugins#${type}`);
|
|
98
|
+
debug('loading plugins', plugins);
|
|
99
|
+
await Promise.all((plugins || []).map(async (plugin) => {
|
|
100
|
+
try {
|
|
101
|
+
const name = typeof plugin === 'string' ? plugin : plugin.name;
|
|
102
|
+
const opts = {
|
|
103
|
+
name,
|
|
104
|
+
type,
|
|
105
|
+
root,
|
|
106
|
+
};
|
|
107
|
+
if (typeof plugin !== 'string') {
|
|
108
|
+
opts.tag = plugin.tag || opts.tag;
|
|
109
|
+
opts.root = plugin.root || opts.root;
|
|
110
|
+
}
|
|
111
|
+
if (parent) {
|
|
112
|
+
opts.parent = parent;
|
|
113
|
+
}
|
|
114
|
+
if (this.plugins.has(name))
|
|
115
|
+
return;
|
|
116
|
+
const pluginMarker = performance_1.Performance.mark(`plugin.load#${name}`);
|
|
117
|
+
const instance = new Plugin.Plugin(opts);
|
|
118
|
+
await instance.load();
|
|
119
|
+
pluginMarker?.addDetails({
|
|
120
|
+
hasManifest: instance.hasManifest,
|
|
121
|
+
commandCount: instance.commands.length,
|
|
122
|
+
topicCount: instance.topics.length,
|
|
123
|
+
type: instance.type,
|
|
124
|
+
usesMain: Boolean(instance.pjson.main),
|
|
125
|
+
name: instance.name,
|
|
126
|
+
});
|
|
127
|
+
pluginMarker?.stop();
|
|
128
|
+
this.plugins.set(instance.name, instance);
|
|
129
|
+
if (parent) {
|
|
130
|
+
instance.parent = parent;
|
|
131
|
+
if (!parent.children)
|
|
132
|
+
parent.children = [];
|
|
133
|
+
parent.children.push(instance);
|
|
134
|
+
}
|
|
135
|
+
await this.loadPlugins(instance.root, type, instance.pjson.oclif.plugins || [], instance);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
this.errors.push(error);
|
|
139
|
+
}
|
|
140
|
+
}));
|
|
141
|
+
mark?.addDetails({ pluginCount: plugins.length });
|
|
142
|
+
mark?.stop();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.default = PluginLoader;
|
package/lib/config/plugin.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { CLIError } from '../errors';
|
|
2
1
|
import { Plugin as IPlugin, PluginOptions } from '../interfaces/plugin';
|
|
2
|
+
import { Command } from '../command';
|
|
3
3
|
import { Manifest } from '../interfaces/manifest';
|
|
4
4
|
import { PJSON } from '../interfaces/pjson';
|
|
5
5
|
import { Topic } from '../interfaces/topic';
|
|
6
|
-
import { Command } from '../command';
|
|
7
6
|
export declare class Plugin implements IPlugin {
|
|
8
7
|
options: PluginOptions;
|
|
9
8
|
_base: string;
|
|
@@ -25,17 +24,13 @@ export declare class Plugin implements IPlugin {
|
|
|
25
24
|
parent: Plugin | undefined;
|
|
26
25
|
children: Plugin[];
|
|
27
26
|
hasManifest: boolean;
|
|
27
|
+
isRoot: boolean;
|
|
28
28
|
private _commandsDir;
|
|
29
|
+
private flexibleTaxonomy;
|
|
29
30
|
protected _debug: (..._: any) => void;
|
|
30
31
|
protected warned: boolean;
|
|
31
32
|
constructor(options: PluginOptions);
|
|
32
|
-
|
|
33
|
-
* Loads a plugin
|
|
34
|
-
* @param isWritingManifest - if true, exclude selected data from manifest
|
|
35
|
-
* default is false to maintain backwards compatibility
|
|
36
|
-
* @returns Promise<void>
|
|
37
|
-
*/
|
|
38
|
-
load(isWritingManifest?: boolean): Promise<void>;
|
|
33
|
+
load(): Promise<void>;
|
|
39
34
|
get topics(): Topic[];
|
|
40
35
|
get commandsDir(): string | undefined;
|
|
41
36
|
get commandIDs(): string[];
|
|
@@ -45,7 +40,7 @@ export declare class Plugin implements IPlugin {
|
|
|
45
40
|
findCommand(id: string, opts?: {
|
|
46
41
|
must: boolean;
|
|
47
42
|
}): Promise<Command.Class | undefined>;
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
private _manifest;
|
|
44
|
+
private warn;
|
|
50
45
|
private addErrorScope;
|
|
51
46
|
}
|
package/lib/config/plugin.js
CHANGED
|
@@ -2,43 +2,43 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Plugin = void 0;
|
|
4
4
|
const errors_1 = require("../errors");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const util_2 = require("./util");
|
|
10
|
-
const ts_node_1 = require("./ts-node");
|
|
11
|
-
const util_3 = require("./util");
|
|
12
|
-
const util_4 = require("../util");
|
|
5
|
+
const util_1 = require("./util");
|
|
6
|
+
const util_2 = require("../util/util");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const fs_1 = require("../util/fs");
|
|
13
9
|
const module_loader_1 = require("../module-loader");
|
|
14
10
|
const performance_1 = require("../performance");
|
|
15
|
-
const
|
|
11
|
+
const cache_command_1 = require("../util/cache-command");
|
|
12
|
+
const node_util_1 = require("node:util");
|
|
13
|
+
const globby_1 = require("globby");
|
|
14
|
+
const ts_node_1 = require("./ts-node");
|
|
15
|
+
const _pjson = (0, fs_1.requireJson)(__dirname, '..', '..', 'package.json');
|
|
16
16
|
function topicsToArray(input, base) {
|
|
17
17
|
if (!input)
|
|
18
18
|
return [];
|
|
19
19
|
base = base ? `${base}:` : '';
|
|
20
20
|
if (Array.isArray(input)) {
|
|
21
|
-
return [...input,
|
|
21
|
+
return [...input, input.flatMap((t) => topicsToArray(t.subtopics, `${base}${t.name}`))];
|
|
22
22
|
}
|
|
23
|
-
return
|
|
23
|
+
return Object.keys(input).flatMap((k) => {
|
|
24
24
|
input[k].name = k;
|
|
25
25
|
return [{ ...input[k], name: `${base}${k}` }, ...topicsToArray(input[k].subtopics, `${base}${input[k].name}`)];
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
// essentially just "cd .."
|
|
29
29
|
function* up(from) {
|
|
30
|
-
while (
|
|
30
|
+
while ((0, node_path_1.dirname)(from) !== from) {
|
|
31
31
|
yield from;
|
|
32
|
-
from =
|
|
32
|
+
from = (0, node_path_1.dirname)(from);
|
|
33
33
|
}
|
|
34
34
|
yield from;
|
|
35
35
|
}
|
|
36
36
|
async function findSourcesRoot(root) {
|
|
37
37
|
for (const next of up(root)) {
|
|
38
|
-
const cur =
|
|
38
|
+
const cur = (0, node_path_1.join)(next, 'package.json');
|
|
39
39
|
// eslint-disable-next-line no-await-in-loop
|
|
40
|
-
if (await (0,
|
|
41
|
-
return
|
|
40
|
+
if (await (0, fs_1.exists)(cur))
|
|
41
|
+
return (0, node_path_1.dirname)(cur);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
@@ -56,23 +56,23 @@ async function findRootLegacy(name, root) {
|
|
|
56
56
|
for (const next of up(root)) {
|
|
57
57
|
let cur;
|
|
58
58
|
if (name) {
|
|
59
|
-
cur =
|
|
59
|
+
cur = (0, node_path_1.join)(next, 'node_modules', name, 'package.json');
|
|
60
60
|
// eslint-disable-next-line no-await-in-loop
|
|
61
|
-
if (await (0,
|
|
62
|
-
return
|
|
61
|
+
if (await (0, fs_1.exists)(cur))
|
|
62
|
+
return (0, node_path_1.dirname)(cur);
|
|
63
63
|
try {
|
|
64
64
|
// eslint-disable-next-line no-await-in-loop
|
|
65
|
-
const pkg = await (0,
|
|
65
|
+
const pkg = await (0, fs_1.readJson)((0, node_path_1.join)(next, 'package.json'));
|
|
66
66
|
if (pkg.name === name)
|
|
67
67
|
return next;
|
|
68
68
|
}
|
|
69
69
|
catch { }
|
|
70
70
|
}
|
|
71
71
|
else {
|
|
72
|
-
cur =
|
|
72
|
+
cur = (0, node_path_1.join)(next, 'package.json');
|
|
73
73
|
// eslint-disable-next-line no-await-in-loop
|
|
74
|
-
if (await (0,
|
|
75
|
-
return
|
|
74
|
+
if (await (0, fs_1.exists)(cur))
|
|
75
|
+
return (0, node_path_1.dirname)(cur);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -80,51 +80,75 @@ async function findRoot(name, root) {
|
|
|
80
80
|
if (name) {
|
|
81
81
|
let pkgPath;
|
|
82
82
|
try {
|
|
83
|
-
pkgPath = (0,
|
|
83
|
+
pkgPath = (0, util_1.resolvePackage)(name, { paths: [root] });
|
|
84
84
|
}
|
|
85
85
|
catch { }
|
|
86
|
-
return pkgPath ? findSourcesRoot(
|
|
86
|
+
return pkgPath ? findSourcesRoot((0, node_path_1.dirname)(pkgPath)) : findRootLegacy(name, root);
|
|
87
87
|
}
|
|
88
88
|
return findSourcesRoot(root);
|
|
89
89
|
}
|
|
90
|
+
const cachedCommandCanBeUsed = (manifest, id) => Boolean(manifest?.commands[id] && 'isESM' in manifest.commands[id] && 'relativePath' in manifest.commands[id]);
|
|
91
|
+
const search = (cmd) => {
|
|
92
|
+
if (typeof cmd.run === 'function')
|
|
93
|
+
return cmd;
|
|
94
|
+
if (cmd.default && cmd.default.run)
|
|
95
|
+
return cmd.default;
|
|
96
|
+
return Object.values(cmd).find((cmd) => typeof cmd.run === 'function');
|
|
97
|
+
};
|
|
90
98
|
class Plugin {
|
|
99
|
+
options;
|
|
100
|
+
_base = `${_pjson.name}@${_pjson.version}`;
|
|
101
|
+
name;
|
|
102
|
+
version;
|
|
103
|
+
pjson;
|
|
104
|
+
type;
|
|
105
|
+
moduleType;
|
|
106
|
+
root;
|
|
107
|
+
alias;
|
|
108
|
+
tag;
|
|
109
|
+
manifest;
|
|
110
|
+
commands;
|
|
111
|
+
hooks;
|
|
112
|
+
valid = false;
|
|
113
|
+
alreadyLoaded = false;
|
|
114
|
+
parent;
|
|
115
|
+
children = [];
|
|
116
|
+
hasManifest = false;
|
|
117
|
+
isRoot = false;
|
|
118
|
+
_commandsDir;
|
|
119
|
+
flexibleTaxonomy;
|
|
120
|
+
// eslint-disable-next-line new-cap
|
|
121
|
+
_debug = (0, util_1.Debug)();
|
|
122
|
+
warned = false;
|
|
91
123
|
constructor(options) {
|
|
92
124
|
this.options = options;
|
|
93
|
-
// static loadedPlugins: {[name: string]: Plugin} = {}
|
|
94
|
-
this._base = `${_pjson.name}@${_pjson.version}`;
|
|
95
|
-
this.valid = false;
|
|
96
|
-
this.alreadyLoaded = false;
|
|
97
|
-
this.children = [];
|
|
98
|
-
this.hasManifest = false;
|
|
99
|
-
// eslint-disable-next-line new-cap
|
|
100
|
-
this._debug = (0, util_2.Debug)();
|
|
101
|
-
this.warned = false;
|
|
102
125
|
}
|
|
103
|
-
|
|
104
|
-
* Loads a plugin
|
|
105
|
-
* @param isWritingManifest - if true, exclude selected data from manifest
|
|
106
|
-
* default is false to maintain backwards compatibility
|
|
107
|
-
* @returns Promise<void>
|
|
108
|
-
*/
|
|
109
|
-
async load(isWritingManifest) {
|
|
126
|
+
async load() {
|
|
110
127
|
this.type = this.options.type || 'core';
|
|
111
128
|
this.tag = this.options.tag;
|
|
112
|
-
|
|
129
|
+
this.isRoot = this.options.isRoot ?? false;
|
|
130
|
+
if (this.options.parent)
|
|
131
|
+
this.parent = this.options.parent;
|
|
132
|
+
// Linked plugins already have a root so there's no need to search for it.
|
|
133
|
+
// However there could be child plugins nested inside the linked plugin, in which
|
|
134
|
+
// case we still need to search for the child plugin's root.
|
|
135
|
+
const root = this.type === 'link' && !this.parent ? this.options.root : await findRoot(this.options.name, this.options.root);
|
|
113
136
|
if (!root)
|
|
114
|
-
throw new
|
|
137
|
+
throw new errors_1.CLIError(`could not find package.json with ${(0, node_util_1.inspect)(this.options)}`);
|
|
115
138
|
this.root = root;
|
|
116
139
|
this._debug('reading %s plugin %s', this.type, root);
|
|
117
|
-
this.pjson = await (0,
|
|
140
|
+
this.pjson = await (0, fs_1.readJson)((0, node_path_1.join)(root, 'package.json'));
|
|
141
|
+
this.flexibleTaxonomy = this.options?.flexibleTaxonomy || this.pjson.oclif?.flexibleTaxonomy || false;
|
|
118
142
|
this.moduleType = this.pjson.type === 'module' ? 'module' : 'commonjs';
|
|
119
143
|
this.name = this.pjson.name;
|
|
120
144
|
this.alias = this.options.name ?? this.pjson.name;
|
|
121
|
-
const pjsonPath =
|
|
145
|
+
const pjsonPath = (0, node_path_1.join)(root, 'package.json');
|
|
122
146
|
if (!this.name)
|
|
123
|
-
throw new
|
|
124
|
-
if (!(0,
|
|
147
|
+
throw new errors_1.CLIError(`no name in ${pjsonPath}`);
|
|
148
|
+
if (!(0, util_2.isProd)() && !this.pjson.files)
|
|
125
149
|
this.warn(`files attribute must be specified in ${pjsonPath}`);
|
|
126
150
|
// eslint-disable-next-line new-cap
|
|
127
|
-
this._debug = (0,
|
|
151
|
+
this._debug = (0, util_1.Debug)(this.name);
|
|
128
152
|
this.version = this.pjson.version;
|
|
129
153
|
if (this.pjson.oclif) {
|
|
130
154
|
this.valid = true;
|
|
@@ -132,10 +156,9 @@ class Plugin {
|
|
|
132
156
|
else {
|
|
133
157
|
this.pjson.oclif = this.pjson['cli-engine'] || {};
|
|
134
158
|
}
|
|
135
|
-
this.hooks = (0,
|
|
136
|
-
this.manifest = await this._manifest(
|
|
137
|
-
this.commands = Object
|
|
138
|
-
.entries(this.manifest.commands)
|
|
159
|
+
this.hooks = (0, util_2.mapValues)(this.pjson.oclif.hooks || {}, (i) => (Array.isArray(i) ? i : [i]));
|
|
160
|
+
this.manifest = await this._manifest();
|
|
161
|
+
this.commands = Object.entries(this.manifest.commands)
|
|
139
162
|
.map(([id, c]) => ({
|
|
140
163
|
...c,
|
|
141
164
|
pluginAlias: this.alias,
|
|
@@ -158,16 +181,12 @@ class Plugin {
|
|
|
158
181
|
return [];
|
|
159
182
|
const marker = performance_1.Performance.mark(`plugin.commandIDs#${this.name}`, { plugin: this.name });
|
|
160
183
|
this._debug(`loading IDs from ${this.commandsDir}`);
|
|
161
|
-
const patterns = [
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
];
|
|
165
|
-
const ids = globby.sync(patterns, { cwd: this.commandsDir })
|
|
166
|
-
.map(file => {
|
|
167
|
-
const p = path.parse(file);
|
|
184
|
+
const patterns = ['**/*.+(js|cjs|mjs|ts|tsx)', '!**/*.+(d.ts|test.ts|test.js|spec.ts|spec.js)?(x)'];
|
|
185
|
+
const ids = (0, globby_1.sync)(patterns, { cwd: this.commandsDir }).map((file) => {
|
|
186
|
+
const p = (0, node_path_1.parse)(file);
|
|
168
187
|
const topics = p.dir.split('/');
|
|
169
188
|
const command = p.name !== 'index' && p.name;
|
|
170
|
-
const id = [...topics, command].filter(
|
|
189
|
+
const id = [...topics, command].filter(Boolean).join(':');
|
|
171
190
|
return id === '' ? '.' : id;
|
|
172
191
|
});
|
|
173
192
|
this._debug('found commands', ids);
|
|
@@ -180,30 +199,28 @@ class Plugin {
|
|
|
180
199
|
const fetch = async () => {
|
|
181
200
|
if (!this.commandsDir)
|
|
182
201
|
return;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
if (cmd.default && cmd.default.run)
|
|
187
|
-
return cmd.default;
|
|
188
|
-
return Object.values(cmd).find((cmd) => typeof cmd.run === 'function');
|
|
189
|
-
};
|
|
190
|
-
let m;
|
|
202
|
+
let module;
|
|
203
|
+
let isESM;
|
|
204
|
+
let filePath;
|
|
191
205
|
try {
|
|
192
|
-
|
|
193
|
-
|
|
206
|
+
;
|
|
207
|
+
({ isESM, module, filePath } = cachedCommandCanBeUsed(this.manifest, id)
|
|
208
|
+
? await (0, module_loader_1.loadWithDataFromManifest)(this.manifest.commands[id], this.root)
|
|
209
|
+
: await (0, module_loader_1.loadWithData)(this, (0, node_path_1.join)(this.commandsDir ?? this.pjson.oclif.commands, ...id.split(':'))));
|
|
194
210
|
this._debug(isESM ? '(import)' : '(require)', filePath);
|
|
195
|
-
m = module;
|
|
196
211
|
}
|
|
197
212
|
catch (error) {
|
|
198
213
|
if (!opts.must && error.code === 'MODULE_NOT_FOUND')
|
|
199
214
|
return;
|
|
200
215
|
throw error;
|
|
201
216
|
}
|
|
202
|
-
const cmd = search(
|
|
217
|
+
const cmd = search(module);
|
|
203
218
|
if (!cmd)
|
|
204
219
|
return;
|
|
205
220
|
cmd.id = id;
|
|
206
221
|
cmd.plugin = this;
|
|
222
|
+
cmd.isESM = isESM;
|
|
223
|
+
cmd.relativePath = (0, node_path_1.relative)(this.root, filePath || '').split(node_path_1.sep);
|
|
207
224
|
return cmd;
|
|
208
225
|
};
|
|
209
226
|
const cmd = await fetch();
|
|
@@ -212,11 +229,14 @@ class Plugin {
|
|
|
212
229
|
marker?.stop();
|
|
213
230
|
return cmd;
|
|
214
231
|
}
|
|
215
|
-
async _manifest(
|
|
232
|
+
async _manifest() {
|
|
233
|
+
const ignoreManifest = Boolean(this.options.ignoreManifest);
|
|
234
|
+
const errorOnManifestCreate = Boolean(this.options.errorOnManifestCreate);
|
|
235
|
+
const respectNoCacheDefault = Boolean(this.options.respectNoCacheDefault);
|
|
216
236
|
const readManifest = async (dotfile = false) => {
|
|
217
237
|
try {
|
|
218
|
-
const p =
|
|
219
|
-
const manifest = await (0,
|
|
238
|
+
const p = (0, node_path_1.join)(this.root, `${dotfile ? '.' : ''}oclif.manifest.json`);
|
|
239
|
+
const manifest = await (0, fs_1.readJson)(p);
|
|
220
240
|
if (!process.env.OCLIF_NEXT_VERSION && manifest.version.split('-')[0] !== this.version.split('-')[0]) {
|
|
221
241
|
process.emitWarning(`Mismatched version in ${this.name} plugin manifest. Expected: ${this.version} Received: ${manifest.version}\nThis usually means you have an oclif.manifest.json file that should be deleted in development. This file should be automatically generated when publishing.`);
|
|
222
242
|
}
|
|
@@ -249,16 +269,23 @@ class Plugin {
|
|
|
249
269
|
version: this.version,
|
|
250
270
|
commands: (await Promise.all(this.commandIDs.map(async (id) => {
|
|
251
271
|
try {
|
|
252
|
-
|
|
272
|
+
const cached = await (0, cache_command_1.cacheCommand)(await this.findCommand(id, { must: true }), this, respectNoCacheDefault);
|
|
273
|
+
if (this.flexibleTaxonomy) {
|
|
274
|
+
const permutations = (0, util_1.getCommandIdPermutations)(id);
|
|
275
|
+
const aliasPermutations = cached.aliases.flatMap((a) => (0, util_1.getCommandIdPermutations)(a));
|
|
276
|
+
return [id, { ...cached, permutations, aliasPermutations }];
|
|
277
|
+
}
|
|
278
|
+
return [id, cached];
|
|
253
279
|
}
|
|
254
280
|
catch (error) {
|
|
255
|
-
const scope = '
|
|
281
|
+
const scope = 'cacheCommand';
|
|
256
282
|
if (Boolean(errorOnManifestCreate) === false)
|
|
257
283
|
this.warn(error, scope);
|
|
258
284
|
else
|
|
259
285
|
throw this.addErrorScope(error, scope);
|
|
260
286
|
}
|
|
261
287
|
})))
|
|
288
|
+
// eslint-disable-next-line unicorn/no-await-expression-member, unicorn/prefer-native-coercion-functions
|
|
262
289
|
.filter((f) => Boolean(f))
|
|
263
290
|
.reduce((commands, [id, c]) => {
|
|
264
291
|
commands[id] = c;
|
|
@@ -278,7 +305,14 @@ class Plugin {
|
|
|
278
305
|
}
|
|
279
306
|
addErrorScope(err, scope) {
|
|
280
307
|
err.name = `${err.name} Plugin: ${this.name}`;
|
|
281
|
-
err.detail = (0,
|
|
308
|
+
err.detail = (0, util_2.compact)([
|
|
309
|
+
err.detail,
|
|
310
|
+
`module: ${this._base}`,
|
|
311
|
+
scope && `task: ${scope}`,
|
|
312
|
+
`plugin: ${this.name}`,
|
|
313
|
+
`root: ${this.root}`,
|
|
314
|
+
'See more details with DEBUG=*',
|
|
315
|
+
]).join('\n');
|
|
282
316
|
return err;
|
|
283
317
|
}
|
|
284
318
|
}
|
package/lib/config/ts-node.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Plugin } from '../interfaces';
|
|
1
|
+
import { Plugin, TSConfig } from '../interfaces';
|
|
2
|
+
export declare const TS_CONFIGS: Record<string, TSConfig>;
|
|
2
3
|
/**
|
|
3
4
|
* Convert a path from the compiled ./lib files to the ./src typescript source
|
|
4
5
|
* this is for developing typescript plugins/CLIs
|