@clerc/plugin-help 1.0.0-beta.3 → 1.0.0-beta.30
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 -68
- package/package.json +6 -9
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,47 @@
|
|
|
1
|
-
import { definePlugin, resolveCommand } from "@clerc/core";
|
|
2
|
-
import { formatFlagName, formatVersion, isTruthy, objectIsEmpty, toArray } from "@clerc/utils";
|
|
1
|
+
import { DOUBLE_DASH, NoSuchCommandError, definePlugin, normalizeFlagValue, normalizeParameterValue, resolveCommand } from "@clerc/core";
|
|
3
2
|
import stringWidth from "string-width";
|
|
4
3
|
import textTable from "text-table";
|
|
5
4
|
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 = "-";
|
|
43
|
+
const INDENT = " ".repeat(2);
|
|
44
|
+
const withIndent = (str) => `${INDENT}${str}`;
|
|
24
45
|
function groupDefinitionsToMap(definitions) {
|
|
25
46
|
const map = /* @__PURE__ */ new Map();
|
|
26
47
|
if (definitions) for (const [key, name] of definitions) map.set(key, name);
|
|
@@ -30,39 +51,58 @@ function validateGroup(group, groupMap, itemType, itemName) {
|
|
|
30
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)"}`);
|
|
31
52
|
}
|
|
32
53
|
var HelpRenderer = class {
|
|
33
|
-
|
|
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) {
|
|
34
65
|
this._formatters = _formatters;
|
|
35
66
|
this._cli = _cli;
|
|
36
67
|
this._globalFlags = _globalFlags;
|
|
37
|
-
this.
|
|
68
|
+
this._getGroups = _getGroups;
|
|
69
|
+
this._getExamples = _getExamples;
|
|
38
70
|
this._notes = _notes;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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 `${yc.underline(yc.bold(section.title))}\n${body.split("\n").map(withIndent).join("\n")}`;
|
|
84
|
+
}).join("\n\n");
|
|
43
85
|
}
|
|
44
86
|
render() {
|
|
45
|
-
|
|
87
|
+
const sections = [
|
|
46
88
|
this.renderHeader(),
|
|
47
89
|
this.renderUsage(),
|
|
48
|
-
this.
|
|
49
|
-
this.renderGlobalFlags(),
|
|
90
|
+
this.renderParameters(),
|
|
50
91
|
this.renderCommandFlags(),
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}).join("\n\n");
|
|
92
|
+
this.renderGlobalFlags(),
|
|
93
|
+
this.renderCommands(),
|
|
94
|
+
this.renderExamples(),
|
|
95
|
+
this.renderNotes()
|
|
96
|
+
];
|
|
97
|
+
return this.renderSections(sections);
|
|
58
98
|
}
|
|
59
99
|
renderHeader() {
|
|
60
100
|
const { _name, _version, _description } = this._cli;
|
|
61
101
|
const command = this._command;
|
|
62
|
-
const description = command
|
|
63
|
-
const formattedCommandName = command?.name ? ` ${yc.
|
|
64
|
-
const headerLine = command ? `${yc.
|
|
65
|
-
const alias = command?.alias ? `Alias${toArray(command.alias).length > 1 ? "es" : ""}: ${toArray(command.alias).map((a) => yc.
|
|
102
|
+
const description = command ? command.description : _description;
|
|
103
|
+
const formattedCommandName = command?.name ? ` ${yc.bold(command.name)}` : "";
|
|
104
|
+
const headerLine = command ? `${yc.dim(_name)}${formattedCommandName}` : `${yc.bold(_name)} ${formatVersion(_version)}`;
|
|
105
|
+
const alias = command?.alias ? `Alias${toArray(command.alias).length > 1 ? "es" : ""}: ${toArray(command.alias).map((a) => yc.bold(a)).join(", ")}` : void 0;
|
|
66
106
|
return { body: [`${headerLine}${description ? ` ${DELIMITER} ${description}` : ""}`, alias] };
|
|
67
107
|
}
|
|
68
108
|
renderUsage() {
|
|
@@ -71,58 +111,122 @@ var HelpRenderer = class {
|
|
|
71
111
|
let usage = `$ ${_scriptName}`;
|
|
72
112
|
if (command) {
|
|
73
113
|
if (command.name) usage += ` ${command.name}`;
|
|
74
|
-
if (command.parameters)
|
|
75
|
-
|
|
76
|
-
|
|
114
|
+
if (command.parameters) {
|
|
115
|
+
const doubleDashIndex = command.parameters.indexOf(DOUBLE_DASH);
|
|
116
|
+
const hasRequiredAfterDoubleDash = doubleDashIndex !== -1 && command.parameters.slice(doubleDashIndex + 1).some((p) => {
|
|
117
|
+
return (typeof p === "string" ? p : p.key).startsWith("<");
|
|
118
|
+
});
|
|
119
|
+
const items = command.parameters.map((p) => {
|
|
120
|
+
let key = typeof p === "string" ? p : p.key;
|
|
121
|
+
if (key === 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("") ? ` ${yc.dim("[command]")}` : ` ${yc.dim("<command>")}`;
|
|
127
|
+
if (command?.flags && !objectIsEmpty(command.flags) || !objectIsEmpty(this._globalFlags)) usage += ` ${yc.dim("[flags]")}`;
|
|
77
128
|
return {
|
|
78
129
|
title: "Usage",
|
|
79
130
|
body: [usage]
|
|
80
131
|
};
|
|
81
132
|
}
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
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.map(normalizeParameterValue).filter((parameter) => parameter.key !== DOUBLE_DASH).map(({ key, type, description }) => {
|
|
139
|
+
const formattedType = type ? this._formatters.formatTypeValue(type) : "string";
|
|
140
|
+
return [
|
|
141
|
+
yc.bold(key),
|
|
142
|
+
yc.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) {
|
|
85
159
|
const groupedCommands = /* @__PURE__ */ new Map();
|
|
86
160
|
const defaultCommands = [];
|
|
87
|
-
|
|
161
|
+
let rootCommand = [];
|
|
162
|
+
for (const command of commandsToShow.values()) {
|
|
88
163
|
if (command.__isAlias || command.help?.show === false) continue;
|
|
89
164
|
const group = command.help?.group;
|
|
90
165
|
validateGroup(group, this._commandGroups, "command", command.name);
|
|
91
|
-
const item = [`${yc.
|
|
92
|
-
if (
|
|
166
|
+
const item = [`${yc.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) {
|
|
93
169
|
const groupItems = groupedCommands.get(group) ?? [];
|
|
94
170
|
groupItems.push(item);
|
|
95
171
|
groupedCommands.set(group, groupItems);
|
|
96
172
|
} else defaultCommands.push(item);
|
|
97
173
|
}
|
|
98
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));
|
|
99
179
|
for (const [key, name] of this._commandGroups) {
|
|
100
180
|
const items = groupedCommands.get(key);
|
|
101
181
|
if (items && items.length > 0) {
|
|
102
182
|
if (body.length > 0) body.push("");
|
|
103
183
|
body.push(`${yc.dim(name)}`);
|
|
104
|
-
|
|
184
|
+
body.push(...splitTable(items).map(withIndent));
|
|
105
185
|
}
|
|
106
186
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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} ${yc.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);
|
|
112
214
|
return {
|
|
113
|
-
title
|
|
215
|
+
title,
|
|
114
216
|
body
|
|
115
217
|
};
|
|
116
218
|
}
|
|
117
219
|
renderFlagItem(name, flag) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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 && yc.dim(`[default: ${yc.bold(this._formatters.formatFlagDefault(flag.default))}]`);
|
|
121
225
|
return [
|
|
122
|
-
yc.
|
|
123
|
-
yc.
|
|
226
|
+
yc.bold(flagName),
|
|
227
|
+
yc.dim(type),
|
|
124
228
|
flag.description,
|
|
125
|
-
|
|
229
|
+
default_
|
|
126
230
|
].filter(isTruthy);
|
|
127
231
|
}
|
|
128
232
|
renderGroupedFlags(flags, groupMap, itemType) {
|
|
@@ -139,19 +243,15 @@ var HelpRenderer = class {
|
|
|
139
243
|
} else defaultFlags.push(item);
|
|
140
244
|
}
|
|
141
245
|
const body = [];
|
|
246
|
+
if (defaultFlags.length > 0) body.push(...splitTable(defaultFlags));
|
|
142
247
|
for (const [key, name] of groupMap) {
|
|
143
248
|
const items = groupedFlags.get(key);
|
|
144
249
|
if (items && items.length > 0) {
|
|
145
250
|
if (body.length > 0) body.push("");
|
|
146
251
|
body.push(`${yc.dim(name)}`);
|
|
147
|
-
|
|
252
|
+
body.push(...splitTable(items).map(withIndent));
|
|
148
253
|
}
|
|
149
254
|
}
|
|
150
|
-
if (defaultFlags.length > 0) if (body.length > 0) {
|
|
151
|
-
body.push("");
|
|
152
|
-
body.push(`${yc.dim("Other")}`);
|
|
153
|
-
for (const line of splitTable(defaultFlags)) body.push(` ${line}`);
|
|
154
|
-
} else body.push(...splitTable(defaultFlags));
|
|
155
255
|
return body;
|
|
156
256
|
}
|
|
157
257
|
renderCommandFlags() {
|
|
@@ -177,10 +277,11 @@ var HelpRenderer = class {
|
|
|
177
277
|
};
|
|
178
278
|
}
|
|
179
279
|
renderExamples() {
|
|
180
|
-
|
|
280
|
+
const examples = this._getExamples();
|
|
281
|
+
if (!examples?.length) return;
|
|
181
282
|
return {
|
|
182
283
|
title: "Examples",
|
|
183
|
-
body: splitTable(
|
|
284
|
+
body: splitTable(examples.map(([command, description]) => {
|
|
184
285
|
return [
|
|
185
286
|
command,
|
|
186
287
|
DELIMITER,
|
|
@@ -191,9 +292,20 @@ var HelpRenderer = class {
|
|
|
191
292
|
}
|
|
192
293
|
};
|
|
193
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
|
+
|
|
194
305
|
//#endregion
|
|
195
306
|
//#region src/index.ts
|
|
196
|
-
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 });
|
|
197
309
|
const mergedFormatters = {
|
|
198
310
|
...defaultFormatters,
|
|
199
311
|
...formatters
|
|
@@ -203,22 +315,32 @@ const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecifie
|
|
|
203
315
|
"If a command is specified, show help for the command.",
|
|
204
316
|
flag && "-h is an alias for --help."
|
|
205
317
|
].filter(isTruthy);
|
|
206
|
-
const
|
|
318
|
+
const getGeneralHelpExamples = () => [
|
|
207
319
|
command && [`$ ${cli._scriptName} help`, "Show help"],
|
|
208
320
|
command && [`$ ${cli._scriptName} help <command>`, "Show help for a specific command"],
|
|
209
321
|
flag && [`$ ${cli._scriptName} <command> --help`, "Show help for a specific command"]
|
|
210
322
|
].filter(isTruthy);
|
|
211
323
|
const effectiveNotes = notes ?? generalHelpNotes;
|
|
212
|
-
const
|
|
324
|
+
const getEffectiveExamples = () => examples ?? getGeneralHelpExamples();
|
|
213
325
|
function printHelp(s) {
|
|
214
|
-
if (
|
|
326
|
+
if (header) console.log(header);
|
|
215
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;
|
|
216
338
|
}
|
|
217
339
|
if (command) cli.command("help", "Show help", {
|
|
218
340
|
parameters: ["[command...]"],
|
|
219
341
|
help: {
|
|
220
342
|
notes: generalHelpNotes,
|
|
221
|
-
examples:
|
|
343
|
+
examples: getGeneralHelpExamples()
|
|
222
344
|
}
|
|
223
345
|
}).on("help", (ctx) => {
|
|
224
346
|
const commandName = ctx.parameters.command;
|
|
@@ -226,22 +348,31 @@ const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecifie
|
|
|
226
348
|
if (commandName.length > 0) {
|
|
227
349
|
[command$1] = resolveCommand(cli._commands, commandName);
|
|
228
350
|
if (!command$1) {
|
|
229
|
-
|
|
230
|
-
return;
|
|
351
|
+
const parentCommandName = commandName.join(" ");
|
|
352
|
+
if (tryPrintSubcommandsHelp(parentCommandName)) return;
|
|
353
|
+
throw new NoSuchCommandError(parentCommandName);
|
|
231
354
|
}
|
|
232
355
|
}
|
|
233
|
-
|
|
356
|
+
renderer.setCommand(command$1);
|
|
357
|
+
printHelp(renderer.render());
|
|
234
358
|
});
|
|
235
359
|
if (flag) cli.globalFlag("help", "Show help", {
|
|
236
|
-
|
|
360
|
+
short: "h",
|
|
237
361
|
type: Boolean,
|
|
238
362
|
default: false
|
|
239
363
|
});
|
|
240
364
|
cli.interceptor({
|
|
241
|
-
enforce: "
|
|
365
|
+
enforce: "post",
|
|
242
366
|
handler: async (ctx, next) => {
|
|
243
|
-
if (ctx.flags.help)
|
|
244
|
-
|
|
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());
|
|
245
376
|
else await next();
|
|
246
377
|
}
|
|
247
378
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clerc/plugin-help",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.30",
|
|
4
4
|
"author": "Ray <i@mk1.io> (https://github.com/so1ve)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Clerc plugin help",
|
|
@@ -48,18 +48,15 @@
|
|
|
48
48
|
"@types/text-table": "^0.2.5",
|
|
49
49
|
"string-width": "^8.1.0",
|
|
50
50
|
"text-table": "^0.2.0",
|
|
51
|
-
"yoctocolors": "^2.1.2"
|
|
52
|
-
"@clerc/utils": "1.0.0-beta.3"
|
|
51
|
+
"yoctocolors": "^2.1.2"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|
|
55
|
-
"
|
|
56
|
-
"@clerc/
|
|
54
|
+
"kons": "^0.7.1",
|
|
55
|
+
"@clerc/core": "1.0.0-beta.30",
|
|
56
|
+
"@clerc/utils": "1.0.0-beta.30",
|
|
57
|
+
"@clerc/parser": "1.0.0-beta.30"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
59
60
|
"@clerc/core": "*"
|
|
60
|
-
},
|
|
61
|
-
"scripts": {
|
|
62
|
-
"build": "tsdown",
|
|
63
|
-
"watch": "tsdown --watch"
|
|
64
61
|
}
|
|
65
62
|
}
|