@oclif/core 3.0.3 → 3.0.5-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cli-ux/action/base.d.ts +12 -12
- package/lib/cli-ux/action/base.js +78 -78
- package/lib/cli-ux/stream.d.ts +1 -1
- package/lib/cli-ux/stream.js +3 -3
- package/lib/cli-ux/styled/table.js +64 -64
- package/lib/command.d.ts +8 -8
- package/lib/command.js +32 -32
- package/lib/config/config.d.ts +50 -50
- package/lib/config/config.js +210 -210
- package/lib/config/plugin-loader.d.ts +5 -5
- package/lib/config/plugin-loader.js +32 -32
- package/lib/config/plugin.d.ts +10 -10
- package/lib/config/plugin.js +145 -133
- package/lib/errors/errors/cli.d.ts +2 -2
- package/lib/errors/errors/cli.js +9 -9
- package/lib/flags.d.ts +9 -9
- package/lib/help/command.d.ts +2 -2
- package/lib/help/command.js +11 -11
- package/lib/help/docopts.d.ts +1 -1
- package/lib/help/docopts.js +20 -20
- package/lib/help/index.d.ts +3 -3
- package/lib/help/index.js +25 -25
- package/lib/interfaces/parser.d.ts +2 -1
- package/lib/interfaces/pjson.d.ts +6 -0
- package/lib/parser/parse.d.ts +2 -2
- package/lib/parser/parse.js +89 -89
- package/lib/performance.d.ts +2 -2
- package/lib/performance.js +2 -2
- package/lib/util/fs.d.ts +13 -1
- package/lib/util/fs.js +29 -14
- package/package.json +2 -3
package/lib/config/plugin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Plugin = void 0;
|
|
4
|
+
/* eslint-disable no-await-in-loop */
|
|
4
5
|
const globby_1 = require("globby");
|
|
5
6
|
const node_path_1 = require("node:path");
|
|
6
7
|
const node_util_1 = require("node:util");
|
|
@@ -33,45 +34,56 @@ function* up(from) {
|
|
|
33
34
|
}
|
|
34
35
|
yield from;
|
|
35
36
|
}
|
|
36
|
-
async function findSourcesRoot(root) {
|
|
37
|
+
async function findSourcesRoot(root, name) {
|
|
38
|
+
// If we know the plugin name then we just need to traverse the file
|
|
39
|
+
// system until we find the directory that matches the plugin name.
|
|
40
|
+
if (name) {
|
|
41
|
+
for (const next of up(root)) {
|
|
42
|
+
if (next.endsWith((0, node_path_1.basename)(name)))
|
|
43
|
+
return next;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// If there's no plugin name (typically just the root plugin), then we need
|
|
47
|
+
// to traverse the file system until we find a directory with a package.json
|
|
37
48
|
for (const next of up(root)) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
// Skip the bin directory
|
|
50
|
+
if ((0, node_path_1.basename)((0, node_path_1.dirname)(next)) === 'bin' &&
|
|
51
|
+
['dev', 'dev.cmd', 'dev.js', 'run', 'run.cmd', 'run.js'].includes((0, node_path_1.basename)(next))) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const cur = (0, node_path_1.join)(next, 'package.json');
|
|
56
|
+
if (await (0, fs_1.safeReadJson)(cur))
|
|
57
|
+
return (0, node_path_1.dirname)(cur);
|
|
58
|
+
}
|
|
59
|
+
catch { }
|
|
42
60
|
}
|
|
43
61
|
}
|
|
44
62
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* @param root string
|
|
48
|
-
* find package root
|
|
49
|
-
* for packages installed into node_modules this will go up directories until
|
|
50
|
-
* it finds a node_modules directory with the plugin installed into it
|
|
63
|
+
* Find package root for packages installed into node_modules. This will go up directories
|
|
64
|
+
* until it finds a node_modules directory with the plugin installed into it
|
|
51
65
|
*
|
|
52
66
|
* This is needed because some oclif plugins do not declare the `main` field in their package.json
|
|
53
67
|
* https://github.com/oclif/config/pull/289#issuecomment-983904051
|
|
68
|
+
*
|
|
69
|
+
* @returns string
|
|
70
|
+
* @param name string
|
|
71
|
+
* @param root string
|
|
54
72
|
*/
|
|
55
73
|
async function findRootLegacy(name, root) {
|
|
56
74
|
for (const next of up(root)) {
|
|
57
75
|
let cur;
|
|
58
76
|
if (name) {
|
|
59
77
|
cur = (0, node_path_1.join)(next, 'node_modules', name, 'package.json');
|
|
60
|
-
|
|
61
|
-
if (await (0, fs_1.exists)(cur))
|
|
78
|
+
if (await (0, fs_1.safeReadJson)(cur))
|
|
62
79
|
return (0, node_path_1.dirname)(cur);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (pkg.name === name)
|
|
67
|
-
return next;
|
|
68
|
-
}
|
|
69
|
-
catch { }
|
|
80
|
+
const pkg = await (0, fs_1.safeReadJson)((0, node_path_1.join)(next, 'package.json'));
|
|
81
|
+
if (pkg?.name === name)
|
|
82
|
+
return next;
|
|
70
83
|
}
|
|
71
84
|
else {
|
|
72
85
|
cur = (0, node_path_1.join)(next, 'package.json');
|
|
73
|
-
|
|
74
|
-
if (await (0, fs_1.exists)(cur))
|
|
86
|
+
if (await (0, fs_1.safeReadJson)(cur))
|
|
75
87
|
return (0, node_path_1.dirname)(cur);
|
|
76
88
|
}
|
|
77
89
|
}
|
|
@@ -83,7 +95,7 @@ async function findRoot(name, root) {
|
|
|
83
95
|
pkgPath = (0, util_2.resolvePackage)(name, { paths: [root] });
|
|
84
96
|
}
|
|
85
97
|
catch { }
|
|
86
|
-
return pkgPath ? findSourcesRoot((0, node_path_1.dirname)(pkgPath)) : findRootLegacy(name, root);
|
|
98
|
+
return pkgPath ? findSourcesRoot((0, node_path_1.dirname)(pkgPath), name) : findRootLegacy(name, root);
|
|
87
99
|
}
|
|
88
100
|
return findSourcesRoot(root);
|
|
89
101
|
}
|
|
@@ -97,11 +109,6 @@ const search = (cmd) => {
|
|
|
97
109
|
};
|
|
98
110
|
class Plugin {
|
|
99
111
|
options;
|
|
100
|
-
_base = `${_pjson.name}@${_pjson.version}`;
|
|
101
|
-
_commandsDir;
|
|
102
|
-
// eslint-disable-next-line new-cap
|
|
103
|
-
_debug = (0, util_2.Debug)();
|
|
104
|
-
flexibleTaxonomy;
|
|
105
112
|
alias;
|
|
106
113
|
alreadyLoaded = false;
|
|
107
114
|
children = [];
|
|
@@ -120,94 +127,40 @@ class Plugin {
|
|
|
120
127
|
valid = false;
|
|
121
128
|
version;
|
|
122
129
|
warned = false;
|
|
130
|
+
_base = `${_pjson.name}@${_pjson.version}`;
|
|
131
|
+
_commandsDir;
|
|
132
|
+
// eslint-disable-next-line new-cap
|
|
133
|
+
_debug = (0, util_2.Debug)();
|
|
134
|
+
flexibleTaxonomy;
|
|
123
135
|
constructor(options) {
|
|
124
136
|
this.options = options;
|
|
125
137
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
if (error.code === 'ENOENT') {
|
|
145
|
-
if (!dotfile)
|
|
146
|
-
return readManifest(true);
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
this.warn(error, 'readManifest');
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
const marker = performance_1.Performance.mark(performance_1.OCLIF_MARKER_OWNER, `plugin.manifest#${this.name}`, { plugin: this.name });
|
|
154
|
-
if (!ignoreManifest) {
|
|
155
|
-
const manifest = await readManifest();
|
|
156
|
-
if (manifest) {
|
|
157
|
-
marker?.addDetails({ commandCount: Object.keys(manifest.commands).length, fromCache: true });
|
|
158
|
-
marker?.stop();
|
|
159
|
-
return manifest;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
const manifest = {
|
|
163
|
-
commands: (await Promise.all(this.commandIDs.map(async (id) => {
|
|
164
|
-
try {
|
|
165
|
-
const cached = await (0, cache_command_1.cacheCommand)(await this.findCommand(id, { must: true }), this, respectNoCacheDefault);
|
|
166
|
-
if (this.flexibleTaxonomy) {
|
|
167
|
-
const permutations = (0, util_2.getCommandIdPermutations)(id);
|
|
168
|
-
const aliasPermutations = cached.aliases.flatMap((a) => (0, util_2.getCommandIdPermutations)(a));
|
|
169
|
-
return [id, { ...cached, aliasPermutations, permutations }];
|
|
170
|
-
}
|
|
171
|
-
return [id, cached];
|
|
172
|
-
}
|
|
173
|
-
catch (error) {
|
|
174
|
-
const scope = 'cacheCommand';
|
|
175
|
-
if (Boolean(errorOnManifestCreate) === false)
|
|
176
|
-
this.warn(error, scope);
|
|
177
|
-
else
|
|
178
|
-
throw this.addErrorScope(error, scope);
|
|
179
|
-
}
|
|
180
|
-
})))
|
|
181
|
-
// eslint-disable-next-line unicorn/no-await-expression-member, unicorn/prefer-native-coercion-functions
|
|
182
|
-
.filter((f) => Boolean(f))
|
|
183
|
-
.reduce((commands, [id, c]) => {
|
|
184
|
-
commands[id] = c;
|
|
185
|
-
return commands;
|
|
186
|
-
}, {}),
|
|
187
|
-
version: this.version,
|
|
188
|
-
};
|
|
189
|
-
marker?.addDetails({ commandCount: Object.keys(manifest.commands).length, fromCache: false });
|
|
138
|
+
get commandIDs() {
|
|
139
|
+
if (!this.commandsDir)
|
|
140
|
+
return [];
|
|
141
|
+
const marker = performance_1.Performance.mark(performance_1.OCLIF_MARKER_OWNER, `plugin.commandIDs#${this.name}`, { plugin: this.name });
|
|
142
|
+
this._debug(`loading IDs from ${this.commandsDir}`);
|
|
143
|
+
const patterns = ['**/*.+(js|cjs|mjs|ts|tsx)', '!**/*.+(d.ts|test.ts|test.js|spec.ts|spec.js)?(x)'];
|
|
144
|
+
const ids = (0, globby_1.sync)(patterns, { cwd: this.commandsDir }).map((file) => {
|
|
145
|
+
const p = (0, node_path_1.parse)(file);
|
|
146
|
+
const topics = p.dir.split('/');
|
|
147
|
+
const command = p.name !== 'index' && p.name;
|
|
148
|
+
const id = [...topics, command].filter(Boolean).join(':');
|
|
149
|
+
return id === '' ? '.' : id;
|
|
150
|
+
});
|
|
151
|
+
this._debug('found commands', ids);
|
|
152
|
+
marker?.addDetails({ count: ids.length });
|
|
190
153
|
marker?.stop();
|
|
191
|
-
return
|
|
154
|
+
return ids;
|
|
192
155
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
scope && `task: ${scope}`,
|
|
199
|
-
`plugin: ${this.name}`,
|
|
200
|
-
`root: ${this.root}`,
|
|
201
|
-
'See more details with DEBUG=*',
|
|
202
|
-
]).join('\n');
|
|
203
|
-
return err;
|
|
156
|
+
get commandsDir() {
|
|
157
|
+
if (this._commandsDir)
|
|
158
|
+
return this._commandsDir;
|
|
159
|
+
this._commandsDir = (0, ts_node_1.tsPath)(this.root, this.pjson.oclif.commands, this);
|
|
160
|
+
return this._commandsDir;
|
|
204
161
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
return;
|
|
208
|
-
if (typeof err === 'string')
|
|
209
|
-
err = new Error(err);
|
|
210
|
-
process.emitWarning(this.addErrorScope(err, scope));
|
|
162
|
+
get topics() {
|
|
163
|
+
return topicsToArray(this.pjson.oclif.topics || {});
|
|
211
164
|
}
|
|
212
165
|
async findCommand(id, opts = {}) {
|
|
213
166
|
const marker = performance_1.Performance.mark(performance_1.OCLIF_MARKER_OWNER, `plugin.findCommand#${this.name}.${id}`, {
|
|
@@ -291,32 +244,91 @@ class Plugin {
|
|
|
291
244
|
}))
|
|
292
245
|
.sort((a, b) => a.id.localeCompare(b.id));
|
|
293
246
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
247
|
+
async _manifest() {
|
|
248
|
+
const ignoreManifest = Boolean(this.options.ignoreManifest);
|
|
249
|
+
const errorOnManifestCreate = Boolean(this.options.errorOnManifestCreate);
|
|
250
|
+
const respectNoCacheDefault = Boolean(this.options.respectNoCacheDefault);
|
|
251
|
+
const readManifest = async (dotfile = false) => {
|
|
252
|
+
try {
|
|
253
|
+
const p = (0, node_path_1.join)(this.root, `${dotfile ? '.' : ''}oclif.manifest.json`);
|
|
254
|
+
const manifest = await (0, fs_1.readJson)(p);
|
|
255
|
+
if (!process.env.OCLIF_NEXT_VERSION && manifest.version.split('-')[0] !== this.version.split('-')[0]) {
|
|
256
|
+
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.`);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
this._debug('using manifest from', p);
|
|
260
|
+
this.hasManifest = true;
|
|
261
|
+
return manifest;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
if (error.code === 'ENOENT') {
|
|
266
|
+
if (!dotfile)
|
|
267
|
+
return readManifest(true);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
this.warn(error, 'readManifest');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
const marker = performance_1.Performance.mark(performance_1.OCLIF_MARKER_OWNER, `plugin.manifest#${this.name}`, { plugin: this.name });
|
|
275
|
+
if (!ignoreManifest) {
|
|
276
|
+
const manifest = await readManifest();
|
|
277
|
+
if (manifest) {
|
|
278
|
+
marker?.addDetails({ commandCount: Object.keys(manifest.commands).length, fromCache: true });
|
|
279
|
+
marker?.stop();
|
|
280
|
+
return manifest;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
const manifest = {
|
|
284
|
+
commands: (await Promise.all(this.commandIDs.map(async (id) => {
|
|
285
|
+
try {
|
|
286
|
+
const cached = await (0, cache_command_1.cacheCommand)(await this.findCommand(id, { must: true }), this, respectNoCacheDefault);
|
|
287
|
+
if (this.flexibleTaxonomy) {
|
|
288
|
+
const permutations = (0, util_2.getCommandIdPermutations)(id);
|
|
289
|
+
const aliasPermutations = cached.aliases.flatMap((a) => (0, util_2.getCommandIdPermutations)(a));
|
|
290
|
+
return [id, { ...cached, aliasPermutations, permutations }];
|
|
291
|
+
}
|
|
292
|
+
return [id, cached];
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
const scope = 'cacheCommand';
|
|
296
|
+
if (Boolean(errorOnManifestCreate) === false)
|
|
297
|
+
this.warn(error, scope);
|
|
298
|
+
else
|
|
299
|
+
throw this.addErrorScope(error, scope);
|
|
300
|
+
}
|
|
301
|
+
})))
|
|
302
|
+
// eslint-disable-next-line unicorn/no-await-expression-member, unicorn/prefer-native-coercion-functions
|
|
303
|
+
.filter((f) => Boolean(f))
|
|
304
|
+
.reduce((commands, [id, c]) => {
|
|
305
|
+
commands[id] = c;
|
|
306
|
+
return commands;
|
|
307
|
+
}, {}),
|
|
308
|
+
version: this.version,
|
|
309
|
+
};
|
|
310
|
+
marker?.addDetails({ commandCount: Object.keys(manifest.commands).length, fromCache: false });
|
|
309
311
|
marker?.stop();
|
|
310
|
-
return
|
|
312
|
+
return manifest;
|
|
311
313
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
314
|
+
addErrorScope(err, scope) {
|
|
315
|
+
err.name = `${err.name} Plugin: ${this.name}`;
|
|
316
|
+
err.detail = (0, util_1.compact)([
|
|
317
|
+
err.detail,
|
|
318
|
+
`module: ${this._base}`,
|
|
319
|
+
scope && `task: ${scope}`,
|
|
320
|
+
`plugin: ${this.name}`,
|
|
321
|
+
`root: ${this.root}`,
|
|
322
|
+
'See more details with DEBUG=*',
|
|
323
|
+
]).join('\n');
|
|
324
|
+
return err;
|
|
317
325
|
}
|
|
318
|
-
|
|
319
|
-
|
|
326
|
+
warn(err, scope) {
|
|
327
|
+
if (this.warned)
|
|
328
|
+
return;
|
|
329
|
+
if (typeof err === 'string')
|
|
330
|
+
err = new Error(err);
|
|
331
|
+
process.emitWarning(this.addErrorScope(err, scope));
|
|
320
332
|
}
|
|
321
333
|
}
|
|
322
334
|
exports.Plugin = Plugin;
|
|
@@ -12,13 +12,13 @@ export declare class CLIError extends Error implements OclifError {
|
|
|
12
12
|
constructor(error: Error | string, options?: {
|
|
13
13
|
exit?: false | number;
|
|
14
14
|
} & PrettyPrintableError);
|
|
15
|
+
get bang(): string | undefined;
|
|
16
|
+
get stack(): string;
|
|
15
17
|
/**
|
|
16
18
|
* @deprecated `render` Errors display should be handled by display function, like pretty-print
|
|
17
19
|
* @return {string} returns a string representing the dispay of the error
|
|
18
20
|
*/
|
|
19
21
|
render(): string;
|
|
20
|
-
get bang(): string | undefined;
|
|
21
|
-
get stack(): string;
|
|
22
22
|
}
|
|
23
23
|
export declare namespace CLIError {
|
|
24
24
|
class Warn extends CLIError {
|
package/lib/errors/errors/cli.js
CHANGED
|
@@ -30,6 +30,15 @@ class CLIError extends Error {
|
|
|
30
30
|
this.code = options.code;
|
|
31
31
|
this.suggestions = options.suggestions;
|
|
32
32
|
}
|
|
33
|
+
get bang() {
|
|
34
|
+
try {
|
|
35
|
+
return chalk_1.default.red(process.platform === 'win32' ? '»' : '›');
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
}
|
|
39
|
+
get stack() {
|
|
40
|
+
return (0, clean_stack_1.default)(super.stack, { pretty: true });
|
|
41
|
+
}
|
|
33
42
|
/**
|
|
34
43
|
* @deprecated `render` Errors display should be handled by display function, like pretty-print
|
|
35
44
|
* @return {string} returns a string representing the dispay of the error
|
|
@@ -45,15 +54,6 @@ class CLIError extends Error {
|
|
|
45
54
|
output = (0, indent_string_1.default)(output, 1);
|
|
46
55
|
return output;
|
|
47
56
|
}
|
|
48
|
-
get bang() {
|
|
49
|
-
try {
|
|
50
|
-
return chalk_1.default.red(process.platform === 'win32' ? '»' : '›');
|
|
51
|
-
}
|
|
52
|
-
catch { }
|
|
53
|
-
}
|
|
54
|
-
get stack() {
|
|
55
|
-
return (0, clean_stack_1.default)(super.stack, { pretty: true });
|
|
56
|
-
}
|
|
57
57
|
}
|
|
58
58
|
exports.CLIError = CLIError;
|
|
59
59
|
(function (CLIError) {
|
package/lib/flags.d.ts
CHANGED
|
@@ -76,31 +76,31 @@ export declare const string: FlagDefinition<string, CustomOptions, {
|
|
|
76
76
|
}>;
|
|
77
77
|
export declare const version: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;
|
|
78
78
|
export declare const help: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;
|
|
79
|
-
type
|
|
80
|
-
export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<
|
|
79
|
+
type ReadonlyElementOf<T extends ReadonlyArray<unknown>> = T[number];
|
|
80
|
+
export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<ReadonlyElementOf<T>[], P>> & {
|
|
81
81
|
multiple: true;
|
|
82
82
|
options: T;
|
|
83
83
|
} & ({
|
|
84
|
-
default: OptionFlag<
|
|
84
|
+
default: OptionFlag<ReadonlyElementOf<T>[], P>['default'] | undefined;
|
|
85
85
|
} | {
|
|
86
86
|
required: true;
|
|
87
87
|
})): FlagDefinition<(typeof defaults.options)[number], P, {
|
|
88
88
|
multiple: true;
|
|
89
89
|
requiredOrDefaulted: true;
|
|
90
90
|
}>;
|
|
91
|
-
export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<
|
|
91
|
+
export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<ReadonlyElementOf<T>, P>> & {
|
|
92
92
|
multiple?: false | undefined;
|
|
93
93
|
options: T;
|
|
94
94
|
} & ({
|
|
95
|
-
default: OptionFlag<
|
|
95
|
+
default: OptionFlag<ReadonlyElementOf<T>, P>['default'];
|
|
96
96
|
} | {
|
|
97
97
|
required: true;
|
|
98
98
|
})): FlagDefinition<(typeof defaults.options)[number], P, {
|
|
99
99
|
multiple: false;
|
|
100
100
|
requiredOrDefaulted: true;
|
|
101
101
|
}>;
|
|
102
|
-
export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<
|
|
103
|
-
default?: OptionFlag<
|
|
102
|
+
export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<ReadonlyElementOf<T>, P>> & {
|
|
103
|
+
default?: OptionFlag<ReadonlyElementOf<T>, P>['default'] | undefined;
|
|
104
104
|
multiple?: false | undefined;
|
|
105
105
|
options: T;
|
|
106
106
|
required?: false | undefined;
|
|
@@ -108,8 +108,8 @@ export declare function option<T extends readonly string[], P extends CustomOpti
|
|
|
108
108
|
multiple: false;
|
|
109
109
|
requiredOrDefaulted: false;
|
|
110
110
|
}>;
|
|
111
|
-
export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<
|
|
112
|
-
default?: OptionFlag<
|
|
111
|
+
export declare function option<T extends readonly string[], P extends CustomOptions>(defaults: Partial<OptionFlag<ReadonlyElementOf<T>[], P>> & {
|
|
112
|
+
default?: OptionFlag<ReadonlyElementOf<T>[], P>['default'] | undefined;
|
|
113
113
|
multiple: true;
|
|
114
114
|
options: T;
|
|
115
115
|
required?: false | undefined;
|
package/lib/help/command.d.ts
CHANGED
|
@@ -6,8 +6,6 @@ export declare class CommandHelp extends HelpFormatter {
|
|
|
6
6
|
config: Interfaces.Config;
|
|
7
7
|
opts: Interfaces.HelpOptions;
|
|
8
8
|
constructor(command: Command.Loadable, config: Interfaces.Config, opts: Interfaces.HelpOptions);
|
|
9
|
-
private formatIfCommand;
|
|
10
|
-
private isCommand;
|
|
11
9
|
protected aliases(aliases: string[] | undefined): string | undefined;
|
|
12
10
|
protected arg(arg: Command.Arg.Any): string;
|
|
13
11
|
protected args(args: Command.Arg.Any[]): [string, string | undefined][] | undefined;
|
|
@@ -29,5 +27,7 @@ export declare class CommandHelp extends HelpFormatter {
|
|
|
29
27
|
header: string;
|
|
30
28
|
}>;
|
|
31
29
|
protected usage(): string;
|
|
30
|
+
private formatIfCommand;
|
|
31
|
+
private isCommand;
|
|
32
32
|
}
|
|
33
33
|
export default CommandHelp;
|
package/lib/help/command.js
CHANGED
|
@@ -27,17 +27,6 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
27
27
|
this.config = config;
|
|
28
28
|
this.opts = opts;
|
|
29
29
|
}
|
|
30
|
-
formatIfCommand(example) {
|
|
31
|
-
example = this.render(example);
|
|
32
|
-
if (example.startsWith(this.config.bin))
|
|
33
|
-
return dim(`$ ${example}`);
|
|
34
|
-
if (example.startsWith(`$ ${this.config.bin}`))
|
|
35
|
-
return dim(example);
|
|
36
|
-
return example;
|
|
37
|
-
}
|
|
38
|
-
isCommand(example) {
|
|
39
|
-
return (0, strip_ansi_1.default)(this.formatIfCommand(example)).startsWith(`$ ${this.config.bin}`);
|
|
40
|
-
}
|
|
41
30
|
aliases(aliases) {
|
|
42
31
|
if (!aliases || aliases.length === 0)
|
|
43
32
|
return;
|
|
@@ -295,6 +284,17 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
295
284
|
.join('\n');
|
|
296
285
|
return body;
|
|
297
286
|
}
|
|
287
|
+
formatIfCommand(example) {
|
|
288
|
+
example = this.render(example);
|
|
289
|
+
if (example.startsWith(this.config.bin))
|
|
290
|
+
return dim(`$ ${example}`);
|
|
291
|
+
if (example.startsWith(`$ ${this.config.bin}`))
|
|
292
|
+
return dim(example);
|
|
293
|
+
return example;
|
|
294
|
+
}
|
|
295
|
+
isCommand(example) {
|
|
296
|
+
return (0, strip_ansi_1.default)(this.formatIfCommand(example)).startsWith(`$ ${this.config.bin}`);
|
|
297
|
+
}
|
|
298
298
|
}
|
|
299
299
|
exports.CommandHelp = CommandHelp;
|
|
300
300
|
exports.default = CommandHelp;
|
package/lib/help/docopts.d.ts
CHANGED
|
@@ -61,8 +61,8 @@ export declare class DocOpts {
|
|
|
61
61
|
private flagMap;
|
|
62
62
|
constructor(cmd: Command.Cached | Command.Class | Command.Loadable);
|
|
63
63
|
static generate(cmd: Command.Cached | Command.Class | Command.Loadable): string;
|
|
64
|
+
toString(): string;
|
|
64
65
|
private combineElementsToFlag;
|
|
65
66
|
private generateElements;
|
|
66
67
|
private groupFlagElements;
|
|
67
|
-
toString(): string;
|
|
68
68
|
}
|
package/lib/help/docopts.js
CHANGED
|
@@ -76,6 +76,26 @@ class DocOpts {
|
|
|
76
76
|
static generate(cmd) {
|
|
77
77
|
return new DocOpts(cmd).toString();
|
|
78
78
|
}
|
|
79
|
+
toString() {
|
|
80
|
+
const opts = this.cmd.id === '.' || this.cmd.id === '' ? [] : ['<%= command.id %>'];
|
|
81
|
+
if (this.cmd.args) {
|
|
82
|
+
const a = Object.values((0, ensure_arg_object_1.ensureArgObject)(this.cmd.args)).map((arg) => arg.required ? arg.name.toUpperCase() : `[${arg.name.toUpperCase()}]`) || [];
|
|
83
|
+
opts.push(...a);
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
opts.push(...Object.values(this.groupFlagElements()));
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// If there is an error, just return no usage so we don't fail command help.
|
|
90
|
+
opts.push(...this.flagList.map((flag) => {
|
|
91
|
+
const name = flag.char ? `-${flag.char}` : `--${flag.name}`;
|
|
92
|
+
if (flag.type === 'boolean')
|
|
93
|
+
return name;
|
|
94
|
+
return `${name}=<value>`;
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
return opts.join(' ');
|
|
98
|
+
}
|
|
79
99
|
combineElementsToFlag(elementMap, flagName, flagNames, unionString) {
|
|
80
100
|
if (!this.flagMap[flagName]) {
|
|
81
101
|
return;
|
|
@@ -134,25 +154,5 @@ class DocOpts {
|
|
|
134
154
|
}
|
|
135
155
|
return elementMap;
|
|
136
156
|
}
|
|
137
|
-
toString() {
|
|
138
|
-
const opts = this.cmd.id === '.' || this.cmd.id === '' ? [] : ['<%= command.id %>'];
|
|
139
|
-
if (this.cmd.args) {
|
|
140
|
-
const a = Object.values((0, ensure_arg_object_1.ensureArgObject)(this.cmd.args)).map((arg) => arg.required ? arg.name.toUpperCase() : `[${arg.name.toUpperCase()}]`) || [];
|
|
141
|
-
opts.push(...a);
|
|
142
|
-
}
|
|
143
|
-
try {
|
|
144
|
-
opts.push(...Object.values(this.groupFlagElements()));
|
|
145
|
-
}
|
|
146
|
-
catch {
|
|
147
|
-
// If there is an error, just return no usage so we don't fail command help.
|
|
148
|
-
opts.push(...this.flagList.map((flag) => {
|
|
149
|
-
const name = flag.char ? `-${flag.char}` : `--${flag.name}`;
|
|
150
|
-
if (flag.type === 'boolean')
|
|
151
|
-
return name;
|
|
152
|
-
return `${name}=<value>`;
|
|
153
|
-
}));
|
|
154
|
-
}
|
|
155
|
-
return opts.join(' ');
|
|
156
|
-
}
|
|
157
157
|
}
|
|
158
158
|
exports.DocOpts = DocOpts;
|
package/lib/help/index.d.ts
CHANGED
|
@@ -21,7 +21,8 @@ export declare abstract class HelpBase extends HelpFormatter {
|
|
|
21
21
|
export declare class Help extends HelpBase {
|
|
22
22
|
protected CommandHelpClass: typeof CommandHelp;
|
|
23
23
|
constructor(config: Interfaces.Config, opts?: Partial<Interfaces.HelpOptions>);
|
|
24
|
-
|
|
24
|
+
protected get sortedCommands(): Command.Loadable[];
|
|
25
|
+
protected get sortedTopics(): Interfaces.Topic[];
|
|
25
26
|
protected command(command: Command.Loadable): string;
|
|
26
27
|
protected description(c: Command.Loadable): string;
|
|
27
28
|
protected formatCommand(command: Command.Loadable): string;
|
|
@@ -36,8 +37,7 @@ export declare class Help extends HelpBase {
|
|
|
36
37
|
protected showRootHelp(): Promise<void>;
|
|
37
38
|
protected showTopicHelp(topic: Interfaces.Topic): Promise<void>;
|
|
38
39
|
protected summary(c: Command.Loadable): string | undefined;
|
|
39
|
-
|
|
40
|
-
protected get sortedTopics(): Interfaces.Topic[];
|
|
40
|
+
private get _topics();
|
|
41
41
|
}
|
|
42
42
|
interface HelpBaseDerived {
|
|
43
43
|
new (config: Interfaces.Config, opts?: Partial<Interfaces.HelpOptions>): HelpBase;
|
package/lib/help/index.js
CHANGED
|
@@ -45,18 +45,19 @@ class Help extends HelpBase {
|
|
|
45
45
|
constructor(config, opts = {}) {
|
|
46
46
|
super(config, opts);
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
get sortedCommands() {
|
|
49
|
+
let { commands } = this.config;
|
|
50
|
+
commands = commands.filter((c) => this.opts.all || !c.hidden);
|
|
51
|
+
commands = (0, util_1.sortBy)(commands, (c) => c.id);
|
|
52
|
+
commands = (0, util_1.uniqBy)(commands, (c) => c.id);
|
|
53
|
+
return commands;
|
|
54
|
+
}
|
|
55
|
+
get sortedTopics() {
|
|
56
|
+
let topics = this._topics;
|
|
57
|
+
topics = topics.filter((t) => this.opts.all || !t.hidden);
|
|
58
|
+
topics = (0, util_1.sortBy)(topics, (t) => t.name);
|
|
59
|
+
topics = (0, util_1.uniqBy)(topics, (t) => t.name);
|
|
60
|
+
return topics;
|
|
60
61
|
}
|
|
61
62
|
command(command) {
|
|
62
63
|
return this.formatCommand(command);
|
|
@@ -266,19 +267,18 @@ class Help extends HelpBase {
|
|
|
266
267
|
return this.render(c.summary.split('\n')[0]);
|
|
267
268
|
return c.description && this.render(c.description).split('\n')[0];
|
|
268
269
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
return topics;
|
|
270
|
+
/*
|
|
271
|
+
* _topics is to work around Interfaces.topics mistakenly including commands that do
|
|
272
|
+
* not have children, as well as topics. A topic has children, either commands or other topics. When
|
|
273
|
+
* this is fixed upstream config.topics should return *only* topics with children,
|
|
274
|
+
* and this can be removed.
|
|
275
|
+
*/
|
|
276
|
+
get _topics() {
|
|
277
|
+
return this.config.topics.filter((topic) => {
|
|
278
|
+
// it is assumed a topic has a child if it has children
|
|
279
|
+
const hasChild = this.config.topics.some((subTopic) => subTopic.name.includes(`${topic.name}:`));
|
|
280
|
+
return hasChild;
|
|
281
|
+
});
|
|
282
282
|
}
|
|
283
283
|
}
|
|
284
284
|
exports.Help = Help;
|