@clerc/plugin-help 1.0.0-beta.9 → 1.0.1
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 +202 -72
- 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,57 @@ 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
|
-
const {
|
|
100
|
+
const { _scriptName, _version, _description } = this._cli;
|
|
63
101
|
const command = this._command;
|
|
64
|
-
const description = command
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const alias = command?.alias ? `Alias${toArray(command.alias).length > 1 ? "es" : ""}: ${toArray(command.alias).map((a) => yc.cyan(a)).join(", ")}` : void 0;
|
|
102
|
+
const description = command ? command.description : _description;
|
|
103
|
+
const headerLine = `${!command || command.name === "" ? tint.bold(_scriptName) : tint.dim(_scriptName)}${command?.name ? ` ${tint.bold(command.name)}` : ""}${command ? "" : ` ${formatVersion(_version)}`}`;
|
|
104
|
+
const alias = command?.alias ? `Alias${toArray(command.alias).length > 1 ? "es" : ""}: ${toArray(command.alias).map((a) => tint.bold(a)).join(", ")}` : void 0;
|
|
68
105
|
return { body: [`${headerLine}${description ? ` ${DELIMITER} ${description}` : ""}`, alias] };
|
|
69
106
|
}
|
|
70
107
|
renderUsage() {
|
|
@@ -73,58 +110,122 @@ var HelpRenderer = class {
|
|
|
73
110
|
let usage = `$ ${_scriptName}`;
|
|
74
111
|
if (command) {
|
|
75
112
|
if (command.name) usage += ` ${command.name}`;
|
|
76
|
-
if (command.parameters)
|
|
77
|
-
|
|
78
|
-
|
|
113
|
+
if (command.parameters) {
|
|
114
|
+
const doubleDashIndex = command.parameters.indexOf(DOUBLE_DASH);
|
|
115
|
+
const hasRequiredAfterDoubleDash = doubleDashIndex !== -1 && command.parameters.slice(doubleDashIndex + 1).some((parameter) => {
|
|
116
|
+
return (typeof parameter === "string" ? parameter : parameter.key).startsWith("<");
|
|
117
|
+
});
|
|
118
|
+
const items = command.parameters.map((parameter) => {
|
|
119
|
+
let key = typeof parameter === "string" ? parameter : parameter.key;
|
|
120
|
+
if (parameter === DOUBLE_DASH) key = hasRequiredAfterDoubleDash ? DOUBLE_DASH : `[${DOUBLE_DASH}]`;
|
|
121
|
+
return key;
|
|
122
|
+
});
|
|
123
|
+
usage += ` ${items.join(" ")}`;
|
|
124
|
+
}
|
|
125
|
+
} 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>")}`;
|
|
126
|
+
if (command?.flags && !objectIsEmpty(command.flags) || !objectIsEmpty(this._globalFlags)) usage += ` ${tint.dim("[flags]")}`;
|
|
79
127
|
return {
|
|
80
128
|
title: "Usage",
|
|
81
|
-
body: [
|
|
129
|
+
body: [usage]
|
|
82
130
|
};
|
|
83
131
|
}
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
132
|
+
renderParameters() {
|
|
133
|
+
const command = this._command;
|
|
134
|
+
if (!command?.parameters || command.parameters.length === 0) return;
|
|
135
|
+
return {
|
|
136
|
+
title: "Parameters",
|
|
137
|
+
body: splitTable(command.parameters.filter((parameter) => parameter !== DOUBLE_DASH).map(normalizeParameterValue).map(({ key, type, description }) => {
|
|
138
|
+
const formattedType = type ? this._formatters.formatTypeValue(type) : "string";
|
|
139
|
+
return [
|
|
140
|
+
tint.bold(key),
|
|
141
|
+
tint.dim(formattedType),
|
|
142
|
+
description
|
|
143
|
+
].filter(isTruthy);
|
|
144
|
+
}))
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
getSubcommands(parentCommandName) {
|
|
148
|
+
const subcommands = /* @__PURE__ */ new Map();
|
|
149
|
+
if (parentCommandName === "") return subcommands;
|
|
150
|
+
const prefix = `${parentCommandName} `;
|
|
151
|
+
for (const [name, command] of this._cli._commands) if (name.startsWith(prefix)) {
|
|
152
|
+
const subcommandName = name.slice(prefix.length);
|
|
153
|
+
subcommands.set(subcommandName, command);
|
|
154
|
+
}
|
|
155
|
+
return subcommands;
|
|
156
|
+
}
|
|
157
|
+
buildGroupedCommandsBody(commandsToShow, prefix) {
|
|
87
158
|
const groupedCommands = /* @__PURE__ */ new Map();
|
|
88
159
|
const defaultCommands = [];
|
|
89
|
-
|
|
160
|
+
let rootCommand = [];
|
|
161
|
+
for (const command of commandsToShow.values()) {
|
|
90
162
|
if (command.__isAlias || command.help?.show === false) continue;
|
|
91
163
|
const group = command.help?.group;
|
|
92
164
|
validateGroup(group, this._commandGroups, "command", command.name);
|
|
93
|
-
const item = [`${
|
|
94
|
-
if (
|
|
165
|
+
const item = [`${tint.bold(formatCommandName(command.name.slice(prefix.length)))}${command.alias ? ` (${toArray(command.alias).join(", ")})` : ""}`, command.description].filter(isTruthy);
|
|
166
|
+
if (command.name === "") rootCommand = item;
|
|
167
|
+
else if (group && group !== DEFAULT_GROUP_KEY) {
|
|
95
168
|
const groupItems = groupedCommands.get(group) ?? [];
|
|
96
169
|
groupItems.push(item);
|
|
97
170
|
groupedCommands.set(group, groupItems);
|
|
98
171
|
} else defaultCommands.push(item);
|
|
99
172
|
}
|
|
100
173
|
const body = [];
|
|
174
|
+
const defaultGroup = [];
|
|
175
|
+
if (rootCommand.length > 0) defaultGroup.push(rootCommand);
|
|
176
|
+
if (defaultCommands.length > 0) defaultGroup.push(...defaultCommands);
|
|
177
|
+
if (defaultGroup.length > 0) body.push(...splitTable(defaultGroup));
|
|
101
178
|
for (const [key, name] of this._commandGroups) {
|
|
102
179
|
const items = groupedCommands.get(key);
|
|
103
180
|
if (items && items.length > 0) {
|
|
104
181
|
if (body.length > 0) body.push("");
|
|
105
|
-
body.push(`${
|
|
182
|
+
body.push(`${tint.dim(name)}`);
|
|
106
183
|
body.push(...splitTable(items).map(withIndent));
|
|
107
184
|
}
|
|
108
185
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
186
|
+
return body;
|
|
187
|
+
}
|
|
188
|
+
renderAvailableSubcommands(parentCommandName) {
|
|
189
|
+
const subcommands = this.getSubcommands(parentCommandName);
|
|
190
|
+
if (subcommands.size === 0) return null;
|
|
191
|
+
const prefix = `${parentCommandName} `;
|
|
192
|
+
const body = this.buildGroupedCommandsBody(subcommands, prefix);
|
|
193
|
+
if (body.length === 0) return null;
|
|
194
|
+
const sections = [{ body: `${this._cli._scriptName} ${tint.bold(parentCommandName)} not found` }, {
|
|
195
|
+
title: "Available Subcommands",
|
|
196
|
+
body
|
|
197
|
+
}];
|
|
198
|
+
return this.renderSections(sections);
|
|
199
|
+
}
|
|
200
|
+
renderCommands() {
|
|
201
|
+
const commands = this._cli._commands;
|
|
202
|
+
let commandsToShow;
|
|
203
|
+
let title = "Commands";
|
|
204
|
+
let prefix = "";
|
|
205
|
+
if (this._command) {
|
|
206
|
+
prefix = this._command.name ? `${this._command.name} ` : "";
|
|
207
|
+
title = "Subcommands";
|
|
208
|
+
commandsToShow = this.getSubcommands(this._command.name);
|
|
209
|
+
if (commandsToShow.size === 0) return;
|
|
210
|
+
} else commandsToShow = commands;
|
|
211
|
+
if (commandsToShow.size === 0) return;
|
|
212
|
+
const body = this.buildGroupedCommandsBody(commandsToShow, prefix);
|
|
114
213
|
return {
|
|
115
|
-
title
|
|
214
|
+
title,
|
|
116
215
|
body
|
|
117
216
|
};
|
|
118
217
|
}
|
|
119
218
|
renderFlagItem(name, flag) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
219
|
+
flag = normalizeFlagValue(flag);
|
|
220
|
+
let flagName = formatFlagName(name);
|
|
221
|
+
if (flag.short) flagName += `, ${formatFlagName(flag.short)}`;
|
|
222
|
+
const type = this._formatters.formatTypeValue(flag.type);
|
|
223
|
+
const default_ = flag.default !== void 0 && tint.dim(`[default: ${tint.bold(this._formatters.formatFlagDefault(flag.default))}]`);
|
|
123
224
|
return [
|
|
124
|
-
|
|
125
|
-
|
|
225
|
+
tint.bold(flagName),
|
|
226
|
+
tint.dim(type),
|
|
126
227
|
flag.description,
|
|
127
|
-
|
|
228
|
+
default_
|
|
128
229
|
].filter(isTruthy);
|
|
129
230
|
}
|
|
130
231
|
renderGroupedFlags(flags, groupMap, itemType) {
|
|
@@ -141,19 +242,15 @@ var HelpRenderer = class {
|
|
|
141
242
|
} else defaultFlags.push(item);
|
|
142
243
|
}
|
|
143
244
|
const body = [];
|
|
245
|
+
if (defaultFlags.length > 0) body.push(...splitTable(defaultFlags));
|
|
144
246
|
for (const [key, name] of groupMap) {
|
|
145
247
|
const items = groupedFlags.get(key);
|
|
146
248
|
if (items && items.length > 0) {
|
|
147
249
|
if (body.length > 0) body.push("");
|
|
148
|
-
body.push(`${
|
|
250
|
+
body.push(`${tint.dim(name)}`);
|
|
149
251
|
body.push(...splitTable(items).map(withIndent));
|
|
150
252
|
}
|
|
151
253
|
}
|
|
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
254
|
return body;
|
|
158
255
|
}
|
|
159
256
|
renderCommandFlags() {
|
|
@@ -179,10 +276,11 @@ var HelpRenderer = class {
|
|
|
179
276
|
};
|
|
180
277
|
}
|
|
181
278
|
renderExamples() {
|
|
182
|
-
|
|
279
|
+
const examples = this._getExamples();
|
|
280
|
+
if (!examples?.length) return;
|
|
183
281
|
return {
|
|
184
282
|
title: "Examples",
|
|
185
|
-
body: splitTable(
|
|
283
|
+
body: splitTable(examples.map(([command, description]) => {
|
|
186
284
|
return [
|
|
187
285
|
command,
|
|
188
286
|
DELIMITER,
|
|
@@ -193,9 +291,20 @@ var HelpRenderer = class {
|
|
|
193
291
|
}
|
|
194
292
|
};
|
|
195
293
|
|
|
294
|
+
//#endregion
|
|
295
|
+
//#region src/store.ts
|
|
296
|
+
function addStoreApi(cli, { groups }) {
|
|
297
|
+
cli.store.help = { addGroup: (options) => {
|
|
298
|
+
if (options.commands) groups.commands = [...groups.commands ?? [], ...options.commands];
|
|
299
|
+
if (options.flags) groups.flags = [...groups.flags ?? [], ...options.flags];
|
|
300
|
+
if (options.globalFlags) groups.globalFlags = [...groups.globalFlags ?? [], ...options.globalFlags];
|
|
301
|
+
} };
|
|
302
|
+
}
|
|
303
|
+
|
|
196
304
|
//#endregion
|
|
197
305
|
//#region src/index.ts
|
|
198
|
-
const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecified = true, notes, examples,
|
|
306
|
+
const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecified = true, notes, examples, header, footer, formatters, groups = {} } = {}) => definePlugin({ setup: (cli) => {
|
|
307
|
+
addStoreApi(cli, { groups });
|
|
199
308
|
const mergedFormatters = {
|
|
200
309
|
...defaultFormatters,
|
|
201
310
|
...formatters
|
|
@@ -205,22 +314,32 @@ const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecifie
|
|
|
205
314
|
"If a command is specified, show help for the command.",
|
|
206
315
|
flag && "-h is an alias for --help."
|
|
207
316
|
].filter(isTruthy);
|
|
208
|
-
const
|
|
317
|
+
const getGeneralHelpExamples = () => [
|
|
209
318
|
command && [`$ ${cli._scriptName} help`, "Show help"],
|
|
210
319
|
command && [`$ ${cli._scriptName} help <command>`, "Show help for a specific command"],
|
|
211
320
|
flag && [`$ ${cli._scriptName} <command> --help`, "Show help for a specific command"]
|
|
212
321
|
].filter(isTruthy);
|
|
213
322
|
const effectiveNotes = notes ?? generalHelpNotes;
|
|
214
|
-
const
|
|
323
|
+
const getEffectiveExamples = () => examples ?? getGeneralHelpExamples();
|
|
215
324
|
function printHelp(s) {
|
|
216
|
-
if (
|
|
325
|
+
if (header) console.log(header);
|
|
217
326
|
console.log(s);
|
|
327
|
+
if (footer) console.log(footer);
|
|
328
|
+
}
|
|
329
|
+
const renderer = new HelpRenderer(mergedFormatters, cli, cli._globalFlags, () => groups, getEffectiveExamples, effectiveNotes);
|
|
330
|
+
function tryPrintSubcommandsHelp(commandName) {
|
|
331
|
+
const subcommandsOutput = renderer.renderAvailableSubcommands(commandName);
|
|
332
|
+
if (subcommandsOutput) {
|
|
333
|
+
printHelp(subcommandsOutput);
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
return false;
|
|
218
337
|
}
|
|
219
338
|
if (command) cli.command("help", "Show help", {
|
|
220
339
|
parameters: ["[command...]"],
|
|
221
340
|
help: {
|
|
222
341
|
notes: generalHelpNotes,
|
|
223
|
-
examples:
|
|
342
|
+
examples: getGeneralHelpExamples()
|
|
224
343
|
}
|
|
225
344
|
}).on("help", (ctx) => {
|
|
226
345
|
const commandName = ctx.parameters.command;
|
|
@@ -228,23 +347,34 @@ const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecifie
|
|
|
228
347
|
if (commandName.length > 0) {
|
|
229
348
|
[command$1] = resolveCommand(cli._commands, commandName);
|
|
230
349
|
if (!command$1) {
|
|
231
|
-
|
|
232
|
-
return;
|
|
350
|
+
const parentCommandName = commandName.join(" ");
|
|
351
|
+
if (tryPrintSubcommandsHelp(parentCommandName)) return;
|
|
352
|
+
throw new NoSuchCommandError(parentCommandName);
|
|
233
353
|
}
|
|
234
354
|
}
|
|
235
|
-
|
|
355
|
+
renderer.setCommand(command$1);
|
|
356
|
+
printHelp(renderer.render());
|
|
236
357
|
});
|
|
237
358
|
if (flag) cli.globalFlag("help", "Show help", {
|
|
238
|
-
|
|
359
|
+
short: "h",
|
|
239
360
|
type: Boolean,
|
|
240
361
|
default: false
|
|
241
362
|
});
|
|
242
363
|
cli.interceptor({
|
|
243
|
-
enforce: "
|
|
364
|
+
enforce: "post",
|
|
244
365
|
handler: async (ctx, next) => {
|
|
245
|
-
if (ctx.flags.help)
|
|
246
|
-
|
|
247
|
-
|
|
366
|
+
if (ctx.flags.help) {
|
|
367
|
+
const command$1 = ctx.command;
|
|
368
|
+
if (!command$1 && ctx.rawParsed.parameters.length > 0) {
|
|
369
|
+
if (tryPrintSubcommandsHelp(ctx.rawParsed.parameters.join(" "))) return;
|
|
370
|
+
await next();
|
|
371
|
+
}
|
|
372
|
+
renderer.setCommand(command$1);
|
|
373
|
+
printHelp(renderer.render());
|
|
374
|
+
} else if (showHelpWhenNoCommandSpecified && !ctx.command && ctx.rawParsed.parameters.length === 0) {
|
|
375
|
+
console.log("No command specified. Showing help:\n");
|
|
376
|
+
printHelp(renderer.render());
|
|
377
|
+
} else await next();
|
|
248
378
|
}
|
|
249
379
|
});
|
|
250
380
|
} });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clerc/plugin-help",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
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.9"
|
|
51
|
+
"text-table": "^0.2.0"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|
|
55
|
-
"
|
|
56
|
-
"@clerc/core": "1.0.
|
|
54
|
+
"kons": "^0.7.1",
|
|
55
|
+
"@clerc/core": "1.0.1",
|
|
56
|
+
"@clerc/utils": "1.0.1",
|
|
57
|
+
"@clerc/parser": "1.0.1"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
59
60
|
"@clerc/core": "*"
|
|
60
|
-
},
|
|
61
|
-
"scripts": {
|
|
62
|
-
"build": "tsdown",
|
|
63
|
-
"watch": "tsdown --watch"
|
|
64
61
|
}
|
|
65
62
|
}
|