@clerc/plugin-help 1.0.0-beta.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +20 -9
- package/dist/index.js +199 -70
- package/package.json +7 -10
package/dist/index.d.ts
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
import { Plugin } from "@clerc/core";
|
|
2
2
|
|
|
3
3
|
//#region ../parser/src/types.d.ts
|
|
4
|
-
|
|
4
|
+
interface FlagDefaultValueFunction<T> {
|
|
5
|
+
(): T;
|
|
6
|
+
display?: string;
|
|
7
|
+
}
|
|
8
|
+
type FlagDefaultValue<T = unknown> = T | FlagDefaultValueFunction<T>;
|
|
5
9
|
/**
|
|
6
10
|
* Defines how a string input is converted to the target type T.
|
|
7
11
|
*
|
|
8
12
|
* @template T The target type.
|
|
9
13
|
*/
|
|
10
|
-
|
|
14
|
+
interface TypeFunction<T = unknown> {
|
|
15
|
+
(value: string): T;
|
|
11
16
|
/**
|
|
12
17
|
* Optional display name for the type, useful in help output.
|
|
13
18
|
* If provided, this will be shown instead of the function name.
|
|
14
19
|
*/
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
type
|
|
20
|
+
display?: string;
|
|
21
|
+
}
|
|
22
|
+
type TypeValue<T = unknown> = TypeFunction<T> | readonly [TypeFunction<T>];
|
|
18
23
|
//#endregion
|
|
19
24
|
//#region src/types.d.ts
|
|
20
25
|
interface Formatters {
|
|
21
|
-
|
|
26
|
+
formatTypeValue: (type: TypeValue) => string;
|
|
27
|
+
formatFlagDefault: <T>(value: FlagDefaultValue<T>) => string;
|
|
22
28
|
}
|
|
23
29
|
/**
|
|
24
30
|
* A group definition as a tuple of [key, displayName].
|
|
@@ -118,9 +124,13 @@ interface HelpPluginOptions {
|
|
|
118
124
|
*/
|
|
119
125
|
examples?: [string, string][];
|
|
120
126
|
/**
|
|
121
|
-
*
|
|
127
|
+
* Header to show before the help output.
|
|
128
|
+
*/
|
|
129
|
+
header?: string;
|
|
130
|
+
/**
|
|
131
|
+
* Footer to show after the help output.
|
|
122
132
|
*/
|
|
123
|
-
|
|
133
|
+
footer?: string;
|
|
124
134
|
/**
|
|
125
135
|
* Custom formatters for rendering help.
|
|
126
136
|
*/
|
|
@@ -139,7 +149,8 @@ declare const helpPlugin: ({
|
|
|
139
149
|
showHelpWhenNoCommandSpecified,
|
|
140
150
|
notes,
|
|
141
151
|
examples,
|
|
142
|
-
|
|
152
|
+
header,
|
|
153
|
+
footer,
|
|
143
154
|
formatters,
|
|
144
155
|
groups
|
|
145
156
|
}?: HelpPluginOptions) => Plugin;
|
package/dist/index.js
CHANGED
|
@@ -1,26 +1,45 @@
|
|
|
1
|
-
import { definePlugin, resolveCommand } from "@clerc/core";
|
|
2
|
-
import
|
|
1
|
+
import { DOUBLE_DASH, NoSuchCommandError, definePlugin, normalizeFlagValue, normalizeParameterValue, resolveCommand } from "@clerc/core";
|
|
2
|
+
import * as tint from "@uttr/tint";
|
|
3
3
|
import stringWidth from "string-width";
|
|
4
4
|
import textTable from "text-table";
|
|
5
|
-
import * as yc from "yoctocolors";
|
|
6
5
|
|
|
6
|
+
//#region ../utils/src/index.ts
|
|
7
|
+
const toArray = (a) => Array.isArray(a) ? a : [a];
|
|
8
|
+
const kebabCase = (s) => s.replace(/([A-Z])/g, (_, c) => `-${c.toLowerCase()}`);
|
|
9
|
+
const formatFlagName = (n) => n.length <= 1 ? `-${n}` : `--${kebabCase(n)}`;
|
|
10
|
+
const formatVersion = (v) => v.length === 0 ? "" : v.startsWith("v") ? v : `v${v}`;
|
|
11
|
+
const isTruthy = Boolean;
|
|
12
|
+
const objectIsEmpty = (obj) => Object.keys(obj).length === 0;
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
7
15
|
//#region src/utils.ts
|
|
8
|
-
function
|
|
9
|
-
if (typeof type === "function") return type.
|
|
16
|
+
function formatTypeValue(type) {
|
|
17
|
+
if (typeof type === "function") return type.display ?? type.name;
|
|
10
18
|
const innerType = type[0];
|
|
11
19
|
return `Array<${innerType.displayName ?? innerType.name}>`;
|
|
12
20
|
}
|
|
21
|
+
function formatFlagDefault(value) {
|
|
22
|
+
if (typeof value === "function" && "display" in value && value.display) return value.display;
|
|
23
|
+
return String(value);
|
|
24
|
+
}
|
|
25
|
+
function formatCommandName(name) {
|
|
26
|
+
if (name === "") return "(root)";
|
|
27
|
+
return name;
|
|
28
|
+
}
|
|
13
29
|
|
|
14
30
|
//#endregion
|
|
15
31
|
//#region src/formatters.ts
|
|
16
|
-
const defaultFormatters = {
|
|
32
|
+
const defaultFormatters = {
|
|
33
|
+
formatTypeValue,
|
|
34
|
+
formatFlagDefault
|
|
35
|
+
};
|
|
17
36
|
|
|
18
37
|
//#endregion
|
|
19
38
|
//#region src/renderer.ts
|
|
20
39
|
const DEFAULT_GROUP_KEY = "default";
|
|
21
40
|
const table = (items) => textTable(items, { stringLength: stringWidth });
|
|
22
41
|
const splitTable = (items) => table(items).split("\n");
|
|
23
|
-
const DELIMITER =
|
|
42
|
+
const DELIMITER = "-";
|
|
24
43
|
const INDENT = " ".repeat(2);
|
|
25
44
|
const withIndent = (str) => `${INDENT}${str}`;
|
|
26
45
|
function groupDefinitionsToMap(definitions) {
|
|
@@ -32,39 +51,58 @@ function validateGroup(group, groupMap, itemType, itemName) {
|
|
|
32
51
|
if (group && group !== DEFAULT_GROUP_KEY && !groupMap.has(group)) throw new Error(`Unknown ${itemType} group "${group}" for "${itemName}". Available groups: ${[...groupMap.keys()].join(", ") || "(none)"}`);
|
|
33
52
|
}
|
|
34
53
|
var HelpRenderer = class {
|
|
35
|
-
|
|
54
|
+
_command;
|
|
55
|
+
get _commandGroups() {
|
|
56
|
+
return groupDefinitionsToMap(this._getGroups().commands);
|
|
57
|
+
}
|
|
58
|
+
get _flagGroups() {
|
|
59
|
+
return groupDefinitionsToMap(this._getGroups().flags);
|
|
60
|
+
}
|
|
61
|
+
get _globalFlagGroups() {
|
|
62
|
+
return groupDefinitionsToMap(this._getGroups().globalFlags);
|
|
63
|
+
}
|
|
64
|
+
constructor(_formatters, _cli, _globalFlags, _getGroups, _getExamples, _notes) {
|
|
36
65
|
this._formatters = _formatters;
|
|
37
66
|
this._cli = _cli;
|
|
38
67
|
this._globalFlags = _globalFlags;
|
|
39
|
-
this.
|
|
68
|
+
this._getGroups = _getGroups;
|
|
69
|
+
this._getExamples = _getExamples;
|
|
40
70
|
this._notes = _notes;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
71
|
+
}
|
|
72
|
+
setCommand(command) {
|
|
73
|
+
if (command) {
|
|
74
|
+
this._command = command;
|
|
75
|
+
this._getExamples = () => command?.help?.examples;
|
|
76
|
+
this._notes = command?.help?.notes;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
renderSections(sections) {
|
|
80
|
+
return sections.filter(isTruthy).map((section) => {
|
|
81
|
+
const body = Array.isArray(section.body) ? section.body.filter((s) => s !== void 0).join("\n") : section.body;
|
|
82
|
+
if (!section.title) return body;
|
|
83
|
+
return `${tint.underline.bold(section.title)}\n${body.split("\n").map(withIndent).join("\n")}`;
|
|
84
|
+
}).join("\n\n");
|
|
45
85
|
}
|
|
46
86
|
render() {
|
|
47
|
-
|
|
87
|
+
const sections = [
|
|
48
88
|
this.renderHeader(),
|
|
49
89
|
this.renderUsage(),
|
|
50
|
-
this.
|
|
51
|
-
this.renderGlobalFlags(),
|
|
90
|
+
this.renderParameters(),
|
|
52
91
|
this.renderCommandFlags(),
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}).join("\n\n");
|
|
92
|
+
this.renderGlobalFlags(),
|
|
93
|
+
this.renderCommands(),
|
|
94
|
+
this.renderExamples(),
|
|
95
|
+
this.renderNotes()
|
|
96
|
+
];
|
|
97
|
+
return this.renderSections(sections);
|
|
60
98
|
}
|
|
61
99
|
renderHeader() {
|
|
62
100
|
const { _name, _version, _description } = this._cli;
|
|
63
101
|
const command = this._command;
|
|
64
|
-
const description = command
|
|
65
|
-
const formattedCommandName = command?.name ? ` ${
|
|
66
|
-
const headerLine = command ? `${
|
|
67
|
-
const alias = command?.alias ? `Alias${toArray(command.alias).length > 1 ? "es" : ""}: ${toArray(command.alias).map((a) =>
|
|
102
|
+
const description = command ? command.description : _description;
|
|
103
|
+
const formattedCommandName = command?.name ? ` ${tint.bold(command.name)}` : "";
|
|
104
|
+
const headerLine = command ? `${tint.dim(_name)}${formattedCommandName}` : `${tint.bold(_name)} ${formatVersion(_version)}`;
|
|
105
|
+
const alias = command?.alias ? `Alias${toArray(command.alias).length > 1 ? "es" : ""}: ${toArray(command.alias).map((a) => tint.bold(a)).join(", ")}` : void 0;
|
|
68
106
|
return { body: [`${headerLine}${description ? ` ${DELIMITER} ${description}` : ""}`, alias] };
|
|
69
107
|
}
|
|
70
108
|
renderUsage() {
|
|
@@ -73,58 +111,122 @@ var HelpRenderer = class {
|
|
|
73
111
|
let usage = `$ ${_scriptName}`;
|
|
74
112
|
if (command) {
|
|
75
113
|
if (command.name) usage += ` ${command.name}`;
|
|
76
|
-
if (command.parameters)
|
|
77
|
-
|
|
78
|
-
|
|
114
|
+
if (command.parameters) {
|
|
115
|
+
const doubleDashIndex = command.parameters.indexOf(DOUBLE_DASH);
|
|
116
|
+
const hasRequiredAfterDoubleDash = doubleDashIndex !== -1 && command.parameters.slice(doubleDashIndex + 1).some((parameter) => {
|
|
117
|
+
return (typeof parameter === "string" ? parameter : parameter.key).startsWith("<");
|
|
118
|
+
});
|
|
119
|
+
const items = command.parameters.map((parameter) => {
|
|
120
|
+
let key = typeof parameter === "string" ? parameter : parameter.key;
|
|
121
|
+
if (parameter === DOUBLE_DASH) key = hasRequiredAfterDoubleDash ? DOUBLE_DASH : `[${DOUBLE_DASH}]`;
|
|
122
|
+
return key;
|
|
123
|
+
});
|
|
124
|
+
usage += ` ${items.join(" ")}`;
|
|
125
|
+
}
|
|
126
|
+
} else if (this._cli._commands.size > 0 && !(this._cli._commands.has("") && this._cli._commands.size === 1)) usage += this._cli._commands.has("") ? ` ${tint.dim("[command]")}` : ` ${tint.dim("<command>")}`;
|
|
127
|
+
if (command?.flags && !objectIsEmpty(command.flags) || !objectIsEmpty(this._globalFlags)) usage += ` ${tint.dim("[flags]")}`;
|
|
79
128
|
return {
|
|
80
129
|
title: "Usage",
|
|
81
|
-
body: [
|
|
130
|
+
body: [usage]
|
|
82
131
|
};
|
|
83
132
|
}
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
133
|
+
renderParameters() {
|
|
134
|
+
const command = this._command;
|
|
135
|
+
if (!command?.parameters || command.parameters.length === 0) return;
|
|
136
|
+
return {
|
|
137
|
+
title: "Parameters",
|
|
138
|
+
body: splitTable(command.parameters.filter((parameter) => parameter !== DOUBLE_DASH).map(normalizeParameterValue).map(({ key, type, description }) => {
|
|
139
|
+
const formattedType = type ? this._formatters.formatTypeValue(type) : "string";
|
|
140
|
+
return [
|
|
141
|
+
tint.bold(key),
|
|
142
|
+
tint.dim(formattedType),
|
|
143
|
+
description
|
|
144
|
+
].filter(isTruthy);
|
|
145
|
+
}))
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
getSubcommands(parentCommandName) {
|
|
149
|
+
const subcommands = /* @__PURE__ */ new Map();
|
|
150
|
+
if (parentCommandName === "") return subcommands;
|
|
151
|
+
const prefix = `${parentCommandName} `;
|
|
152
|
+
for (const [name, command] of this._cli._commands) if (name.startsWith(prefix)) {
|
|
153
|
+
const subcommandName = name.slice(prefix.length);
|
|
154
|
+
subcommands.set(subcommandName, command);
|
|
155
|
+
}
|
|
156
|
+
return subcommands;
|
|
157
|
+
}
|
|
158
|
+
buildGroupedCommandsBody(commandsToShow, prefix) {
|
|
87
159
|
const groupedCommands = /* @__PURE__ */ new Map();
|
|
88
160
|
const defaultCommands = [];
|
|
89
|
-
|
|
161
|
+
let rootCommand = [];
|
|
162
|
+
for (const command of commandsToShow.values()) {
|
|
90
163
|
if (command.__isAlias || command.help?.show === false) continue;
|
|
91
164
|
const group = command.help?.group;
|
|
92
165
|
validateGroup(group, this._commandGroups, "command", command.name);
|
|
93
|
-
const item = [`${
|
|
94
|
-
if (
|
|
166
|
+
const item = [`${tint.bold(formatCommandName(command.name.slice(prefix.length)))}${command.alias ? ` (${toArray(command.alias).join(", ")})` : ""}`, command.description].filter(isTruthy);
|
|
167
|
+
if (command.name === "") rootCommand = item;
|
|
168
|
+
else if (group && group !== DEFAULT_GROUP_KEY) {
|
|
95
169
|
const groupItems = groupedCommands.get(group) ?? [];
|
|
96
170
|
groupItems.push(item);
|
|
97
171
|
groupedCommands.set(group, groupItems);
|
|
98
172
|
} else defaultCommands.push(item);
|
|
99
173
|
}
|
|
100
174
|
const body = [];
|
|
175
|
+
const defaultGroup = [];
|
|
176
|
+
if (rootCommand.length > 0) defaultGroup.push(rootCommand);
|
|
177
|
+
if (defaultCommands.length > 0) defaultGroup.push(...defaultCommands);
|
|
178
|
+
if (defaultGroup.length > 0) body.push(...splitTable(defaultGroup));
|
|
101
179
|
for (const [key, name] of this._commandGroups) {
|
|
102
180
|
const items = groupedCommands.get(key);
|
|
103
181
|
if (items && items.length > 0) {
|
|
104
182
|
if (body.length > 0) body.push("");
|
|
105
|
-
body.push(`${
|
|
183
|
+
body.push(`${tint.dim(name)}`);
|
|
106
184
|
body.push(...splitTable(items).map(withIndent));
|
|
107
185
|
}
|
|
108
186
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
187
|
+
return body;
|
|
188
|
+
}
|
|
189
|
+
renderAvailableSubcommands(parentCommandName) {
|
|
190
|
+
const subcommands = this.getSubcommands(parentCommandName);
|
|
191
|
+
if (subcommands.size === 0) return null;
|
|
192
|
+
const prefix = `${parentCommandName} `;
|
|
193
|
+
const body = this.buildGroupedCommandsBody(subcommands, prefix);
|
|
194
|
+
if (body.length === 0) return null;
|
|
195
|
+
const sections = [{ body: `${this._cli._name} ${tint.bold(parentCommandName)} not found` }, {
|
|
196
|
+
title: "Available Subcommands",
|
|
197
|
+
body
|
|
198
|
+
}];
|
|
199
|
+
return this.renderSections(sections);
|
|
200
|
+
}
|
|
201
|
+
renderCommands() {
|
|
202
|
+
const commands = this._cli._commands;
|
|
203
|
+
let commandsToShow;
|
|
204
|
+
let title = "Commands";
|
|
205
|
+
let prefix = "";
|
|
206
|
+
if (this._command) {
|
|
207
|
+
prefix = this._command.name ? `${this._command.name} ` : "";
|
|
208
|
+
title = "Subcommands";
|
|
209
|
+
commandsToShow = this.getSubcommands(this._command.name);
|
|
210
|
+
if (commandsToShow.size === 0) return;
|
|
211
|
+
} else commandsToShow = commands;
|
|
212
|
+
if (commandsToShow.size === 0) return;
|
|
213
|
+
const body = this.buildGroupedCommandsBody(commandsToShow, prefix);
|
|
114
214
|
return {
|
|
115
|
-
title
|
|
215
|
+
title,
|
|
116
216
|
body
|
|
117
217
|
};
|
|
118
218
|
}
|
|
119
219
|
renderFlagItem(name, flag) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
220
|
+
flag = normalizeFlagValue(flag);
|
|
221
|
+
let flagName = formatFlagName(name);
|
|
222
|
+
if (flag.short) flagName += `, ${formatFlagName(flag.short)}`;
|
|
223
|
+
const type = this._formatters.formatTypeValue(flag.type);
|
|
224
|
+
const default_ = flag.default !== void 0 && tint.dim(`[default: ${tint.bold(this._formatters.formatFlagDefault(flag.default))}]`);
|
|
123
225
|
return [
|
|
124
|
-
|
|
125
|
-
|
|
226
|
+
tint.bold(flagName),
|
|
227
|
+
tint.dim(type),
|
|
126
228
|
flag.description,
|
|
127
|
-
|
|
229
|
+
default_
|
|
128
230
|
].filter(isTruthy);
|
|
129
231
|
}
|
|
130
232
|
renderGroupedFlags(flags, groupMap, itemType) {
|
|
@@ -141,19 +243,15 @@ var HelpRenderer = class {
|
|
|
141
243
|
} else defaultFlags.push(item);
|
|
142
244
|
}
|
|
143
245
|
const body = [];
|
|
246
|
+
if (defaultFlags.length > 0) body.push(...splitTable(defaultFlags));
|
|
144
247
|
for (const [key, name] of groupMap) {
|
|
145
248
|
const items = groupedFlags.get(key);
|
|
146
249
|
if (items && items.length > 0) {
|
|
147
250
|
if (body.length > 0) body.push("");
|
|
148
|
-
body.push(`${
|
|
251
|
+
body.push(`${tint.dim(name)}`);
|
|
149
252
|
body.push(...splitTable(items).map(withIndent));
|
|
150
253
|
}
|
|
151
254
|
}
|
|
152
|
-
if (defaultFlags.length > 0) if (body.length > 0) {
|
|
153
|
-
body.push("");
|
|
154
|
-
body.push(`${yc.dim("Other")}`);
|
|
155
|
-
body.push(...splitTable(defaultFlags).map(withIndent));
|
|
156
|
-
} else body.push(...splitTable(defaultFlags));
|
|
157
255
|
return body;
|
|
158
256
|
}
|
|
159
257
|
renderCommandFlags() {
|
|
@@ -179,10 +277,11 @@ var HelpRenderer = class {
|
|
|
179
277
|
};
|
|
180
278
|
}
|
|
181
279
|
renderExamples() {
|
|
182
|
-
|
|
280
|
+
const examples = this._getExamples();
|
|
281
|
+
if (!examples?.length) return;
|
|
183
282
|
return {
|
|
184
283
|
title: "Examples",
|
|
185
|
-
body: splitTable(
|
|
284
|
+
body: splitTable(examples.map(([command, description]) => {
|
|
186
285
|
return [
|
|
187
286
|
command,
|
|
188
287
|
DELIMITER,
|
|
@@ -193,9 +292,20 @@ var HelpRenderer = class {
|
|
|
193
292
|
}
|
|
194
293
|
};
|
|
195
294
|
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/store.ts
|
|
297
|
+
function addStoreApi(cli, { groups }) {
|
|
298
|
+
cli.store.help = { addGroup: (options) => {
|
|
299
|
+
if (options.commands) groups.commands = [...groups.commands ?? [], ...options.commands];
|
|
300
|
+
if (options.flags) groups.flags = [...groups.flags ?? [], ...options.flags];
|
|
301
|
+
if (options.globalFlags) groups.globalFlags = [...groups.globalFlags ?? [], ...options.globalFlags];
|
|
302
|
+
} };
|
|
303
|
+
}
|
|
304
|
+
|
|
196
305
|
//#endregion
|
|
197
306
|
//#region src/index.ts
|
|
198
|
-
const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecified = true, notes, examples,
|
|
307
|
+
const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecified = true, notes, examples, header, footer, formatters, groups = {} } = {}) => definePlugin({ setup: (cli) => {
|
|
308
|
+
addStoreApi(cli, { groups });
|
|
199
309
|
const mergedFormatters = {
|
|
200
310
|
...defaultFormatters,
|
|
201
311
|
...formatters
|
|
@@ -205,22 +315,32 @@ const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecifie
|
|
|
205
315
|
"If a command is specified, show help for the command.",
|
|
206
316
|
flag && "-h is an alias for --help."
|
|
207
317
|
].filter(isTruthy);
|
|
208
|
-
const
|
|
318
|
+
const getGeneralHelpExamples = () => [
|
|
209
319
|
command && [`$ ${cli._scriptName} help`, "Show help"],
|
|
210
320
|
command && [`$ ${cli._scriptName} help <command>`, "Show help for a specific command"],
|
|
211
321
|
flag && [`$ ${cli._scriptName} <command> --help`, "Show help for a specific command"]
|
|
212
322
|
].filter(isTruthy);
|
|
213
323
|
const effectiveNotes = notes ?? generalHelpNotes;
|
|
214
|
-
const
|
|
324
|
+
const getEffectiveExamples = () => examples ?? getGeneralHelpExamples();
|
|
215
325
|
function printHelp(s) {
|
|
216
|
-
if (
|
|
326
|
+
if (header) console.log(header);
|
|
217
327
|
console.log(s);
|
|
328
|
+
if (footer) console.log(footer);
|
|
329
|
+
}
|
|
330
|
+
const renderer = new HelpRenderer(mergedFormatters, cli, cli._globalFlags, () => groups, getEffectiveExamples, effectiveNotes);
|
|
331
|
+
function tryPrintSubcommandsHelp(commandName) {
|
|
332
|
+
const subcommandsOutput = renderer.renderAvailableSubcommands(commandName);
|
|
333
|
+
if (subcommandsOutput) {
|
|
334
|
+
printHelp(subcommandsOutput);
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
return false;
|
|
218
338
|
}
|
|
219
339
|
if (command) cli.command("help", "Show help", {
|
|
220
340
|
parameters: ["[command...]"],
|
|
221
341
|
help: {
|
|
222
342
|
notes: generalHelpNotes,
|
|
223
|
-
examples:
|
|
343
|
+
examples: getGeneralHelpExamples()
|
|
224
344
|
}
|
|
225
345
|
}).on("help", (ctx) => {
|
|
226
346
|
const commandName = ctx.parameters.command;
|
|
@@ -228,22 +348,31 @@ const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecifie
|
|
|
228
348
|
if (commandName.length > 0) {
|
|
229
349
|
[command$1] = resolveCommand(cli._commands, commandName);
|
|
230
350
|
if (!command$1) {
|
|
231
|
-
|
|
232
|
-
return;
|
|
351
|
+
const parentCommandName = commandName.join(" ");
|
|
352
|
+
if (tryPrintSubcommandsHelp(parentCommandName)) return;
|
|
353
|
+
throw new NoSuchCommandError(parentCommandName);
|
|
233
354
|
}
|
|
234
355
|
}
|
|
235
|
-
|
|
356
|
+
renderer.setCommand(command$1);
|
|
357
|
+
printHelp(renderer.render());
|
|
236
358
|
});
|
|
237
359
|
if (flag) cli.globalFlag("help", "Show help", {
|
|
238
|
-
|
|
360
|
+
short: "h",
|
|
239
361
|
type: Boolean,
|
|
240
362
|
default: false
|
|
241
363
|
});
|
|
242
364
|
cli.interceptor({
|
|
243
|
-
enforce: "
|
|
365
|
+
enforce: "post",
|
|
244
366
|
handler: async (ctx, next) => {
|
|
245
|
-
if (ctx.flags.help)
|
|
246
|
-
|
|
367
|
+
if (ctx.flags.help) {
|
|
368
|
+
const command$1 = ctx.command;
|
|
369
|
+
if (!command$1 && ctx.rawParsed.parameters.length > 0) {
|
|
370
|
+
if (tryPrintSubcommandsHelp(ctx.rawParsed.parameters.join(" "))) return;
|
|
371
|
+
await next();
|
|
372
|
+
}
|
|
373
|
+
renderer.setCommand(command$1);
|
|
374
|
+
printHelp(renderer.render());
|
|
375
|
+
} else if (showHelpWhenNoCommandSpecified && !ctx.command && ctx.rawParsed.parameters.length === 0) printHelp(renderer.render());
|
|
247
376
|
else await next();
|
|
248
377
|
}
|
|
249
378
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clerc/plugin-help",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"author": "Ray <i@mk1.io> (https://github.com/so1ve)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Clerc plugin help",
|
|
@@ -46,20 +46,17 @@
|
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@types/text-table": "^0.2.5",
|
|
49
|
+
"@uttr/tint": "^0.1.3",
|
|
49
50
|
"string-width": "^8.1.0",
|
|
50
|
-
"text-table": "^0.2.0"
|
|
51
|
-
"yoctocolors": "^2.1.2",
|
|
52
|
-
"@clerc/utils": "1.0.0-beta.8"
|
|
51
|
+
"text-table": "^0.2.0"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|
|
55
|
-
"
|
|
56
|
-
"@clerc/parser": "1.0.0
|
|
54
|
+
"kons": "^0.7.1",
|
|
55
|
+
"@clerc/parser": "1.0.0",
|
|
56
|
+
"@clerc/utils": "1.0.0",
|
|
57
|
+
"@clerc/core": "1.0.0"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
59
60
|
"@clerc/core": "*"
|
|
60
|
-
},
|
|
61
|
-
"scripts": {
|
|
62
|
-
"build": "tsdown",
|
|
63
|
-
"watch": "tsdown --watch"
|
|
64
61
|
}
|
|
65
62
|
}
|