@clerc/plugin-help 0.44.0 → 1.0.0-beta.2
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 +44 -64
- package/dist/index.js +181 -364
- package/package.json +14 -13
package/dist/index.d.ts
CHANGED
|
@@ -1,70 +1,50 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Plugin } from "@clerc/core";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
type?: "block";
|
|
5
|
-
title: string;
|
|
6
|
-
body: string[];
|
|
7
|
-
}
|
|
8
|
-
interface InlineSection {
|
|
9
|
-
type: "inline";
|
|
10
|
-
items: {
|
|
11
|
-
title: string;
|
|
12
|
-
body: string;
|
|
13
|
-
}[];
|
|
14
|
-
}
|
|
15
|
-
type Section = BlockSection | InlineSection;
|
|
16
|
-
interface Renderers {
|
|
17
|
-
renderSections?: (sections: Section[]) => Section[];
|
|
18
|
-
renderFlagName?: (name: string) => string;
|
|
19
|
-
renderType?: (type: any, hasDefault: boolean) => string;
|
|
20
|
-
renderDefault?: (default_: any) => string;
|
|
21
|
-
}
|
|
3
|
+
//#region ../parser/src/types.d.ts
|
|
22
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Defines how a string input is converted to the target type T.
|
|
7
|
+
*
|
|
8
|
+
* @template T The target type.
|
|
9
|
+
*/
|
|
10
|
+
type FlagTypeFunction<T = unknown> = (value: string) => T;
|
|
11
|
+
type FlagType<T = unknown> = FlagTypeFunction<T> | readonly [FlagTypeFunction<T>];
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/types.d.ts
|
|
14
|
+
interface Formatters {
|
|
15
|
+
formatFlagType: (type: FlagType) => string;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/formatters.d.ts
|
|
19
|
+
declare const defaultFormatters: Formatters;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/index.d.ts
|
|
23
22
|
declare module "@clerc/core" {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
interface CommandCustomOptions {
|
|
24
|
+
help?: {
|
|
25
|
+
showInHelp?: boolean;
|
|
26
|
+
notes?: string[];
|
|
27
|
+
examples?: [string, string][];
|
|
28
|
+
};
|
|
29
|
+
}
|
|
31
30
|
}
|
|
32
31
|
interface HelpPluginOptions {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* Whether to register the global help flag.
|
|
41
|
-
*
|
|
42
|
-
* @default true
|
|
43
|
-
*/
|
|
44
|
-
flag?: boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Whether to show help when no command is specified.
|
|
47
|
-
*
|
|
48
|
-
* @default true
|
|
49
|
-
*/
|
|
50
|
-
showHelpWhenNoCommand?: boolean;
|
|
51
|
-
/**
|
|
52
|
-
* Global notes.
|
|
53
|
-
*/
|
|
54
|
-
notes?: string[];
|
|
55
|
-
/**
|
|
56
|
-
* Global examples.
|
|
57
|
-
*/
|
|
58
|
-
examples?: [string, string][];
|
|
59
|
-
/**
|
|
60
|
-
* Banner.
|
|
61
|
-
*/
|
|
62
|
-
banner?: string;
|
|
63
|
-
/**
|
|
64
|
-
* Renderers.
|
|
65
|
-
*/
|
|
66
|
-
renderers?: Renderers;
|
|
32
|
+
command?: boolean;
|
|
33
|
+
flag?: boolean;
|
|
34
|
+
showHelpWhenNoCommandSpecified?: boolean;
|
|
35
|
+
notes?: string[];
|
|
36
|
+
examples?: [string, string][];
|
|
37
|
+
banner?: string;
|
|
38
|
+
formatters?: Partial<Formatters>;
|
|
67
39
|
}
|
|
68
|
-
declare const helpPlugin: ({
|
|
69
|
-
|
|
70
|
-
|
|
40
|
+
declare const helpPlugin: ({
|
|
41
|
+
command,
|
|
42
|
+
flag,
|
|
43
|
+
showHelpWhenNoCommandSpecified,
|
|
44
|
+
notes,
|
|
45
|
+
examples,
|
|
46
|
+
banner,
|
|
47
|
+
formatters
|
|
48
|
+
}?: HelpPluginOptions) => Plugin;
|
|
49
|
+
//#endregion
|
|
50
|
+
export { HelpPluginOptions, defaultFormatters, helpPlugin };
|
package/dist/index.js
CHANGED
|
@@ -1,372 +1,189 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
import { definePlugin, resolveCommand } from "@clerc/core";
|
|
2
|
+
import { formatFlagName, formatVersion, isTruthy, objectIsEmpty, toArray } from "@clerc/utils";
|
|
3
|
+
import stringWidth from "string-width";
|
|
4
|
+
import textTable from "text-table";
|
|
5
|
+
import * as yc from "yoctocolors";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"help.commands": "Commands:",
|
|
13
|
-
"help.globalFlags": "Global Flags:",
|
|
14
|
-
"help.flags": "Flags:",
|
|
15
|
-
"help.description": "Description:",
|
|
16
|
-
"help.usage": "Usage:",
|
|
17
|
-
"help.examples": "Examples:",
|
|
18
|
-
"help.notes": "Notes:",
|
|
19
|
-
"help.noDescription": "(No description)",
|
|
20
|
-
"help.notes.1": "If no command is specified, show help for the CLI.",
|
|
21
|
-
"help.notes.2": "If a command is specified, show help for the command.",
|
|
22
|
-
"help.notes.3": "-h is an alias for --help.",
|
|
23
|
-
"help.examples.1": "Show help",
|
|
24
|
-
"help.examples.2": "Show help for a specific command",
|
|
25
|
-
"help.commandDescription": "Show help",
|
|
26
|
-
"help.default": "Default: %s"
|
|
27
|
-
},
|
|
28
|
-
"zh-CN": {
|
|
29
|
-
"help.name": "\u540D\u79F0:",
|
|
30
|
-
"help.version": "\u7248\u672C:",
|
|
31
|
-
"help.subcommand": "\u5B50\u547D\u4EE4:",
|
|
32
|
-
"help.commands": "\u547D\u4EE4:",
|
|
33
|
-
"help.globalFlags": "\u5168\u5C40\u6807\u5FD7:",
|
|
34
|
-
"help.flags": "\u6807\u5FD7:",
|
|
35
|
-
"help.description": "\u63CF\u8FF0:",
|
|
36
|
-
"help.usage": "\u4F7F\u7528:",
|
|
37
|
-
"help.examples": "\u793A\u4F8B:",
|
|
38
|
-
"help.notes": "\u5907\u6CE8:",
|
|
39
|
-
"help.noDescription": "(\u65E0\u63CF\u8FF0)",
|
|
40
|
-
"help.notes.1": "\u5982\u679C\u6CA1\u6709\u6307\u5B9A\u5C55\u793A\u54EA\u4E2A\u547D\u4EE4\u7684\u5E2E\u52A9\u4FE1\u606F\uFF0C\u9ED8\u8BA4\u5C55\u793ACLI\u7684\u3002",
|
|
41
|
-
"help.notes.2": "\u5982\u679C\u6307\u5B9A\u4E86\u5219\u5C55\u793A\u8BE5\u547D\u4EE4\u5E2E\u52A9\u4FE1\u606F\u3002",
|
|
42
|
-
"help.notes.3": "-h \u662F --help \u7684\u4E00\u4E2A\u522B\u540D\u3002",
|
|
43
|
-
"help.examples.1": "\u5C55\u793A CLI \u7684\u5E2E\u52A9\u4FE1\u606F",
|
|
44
|
-
"help.examples.2": "\u5C55\u793A\u6307\u5B9A\u547D\u4EE4\u7684\u5E2E\u52A9\u4FE1\u606F",
|
|
45
|
-
"help.commandDescription": "\u5C55\u793A\u5E2E\u52A9\u4FE1\u606F",
|
|
46
|
-
"help.default": "\u9ED8\u8BA4\u503C: %s"
|
|
47
|
-
}
|
|
48
|
-
};
|
|
7
|
+
//#region src/utils.ts
|
|
8
|
+
function formatFlagType(type) {
|
|
9
|
+
if (typeof type === "function") return type.name;
|
|
10
|
+
return `Array<${type[0].name}>`;
|
|
11
|
+
}
|
|
49
12
|
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/formatters.ts
|
|
15
|
+
const defaultFormatters = { formatFlagType };
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/renderer.ts
|
|
50
19
|
const table = (items) => textTable(items, { stringLength: stringWidth });
|
|
51
20
|
const splitTable = (items) => table(items).split("\n");
|
|
52
|
-
const primitiveMap = /* @__PURE__ */ new Map([
|
|
53
|
-
[Boolean, void 0],
|
|
54
|
-
[String, "string"],
|
|
55
|
-
[Number, "number"]
|
|
56
|
-
]);
|
|
57
|
-
function stringifyType(type, hasDefault = false) {
|
|
58
|
-
const res = primitiveMap.has(type) ? primitiveMap.get(type) : "value";
|
|
59
|
-
return res ? hasDefault ? `[${res}]` : `<${res}>` : "";
|
|
60
|
-
}
|
|
61
|
-
function sortName(a, b) {
|
|
62
|
-
if (a === Root) {
|
|
63
|
-
return -1;
|
|
64
|
-
}
|
|
65
|
-
if (b === Root) {
|
|
66
|
-
return 1;
|
|
67
|
-
}
|
|
68
|
-
return a.length - b.length;
|
|
69
|
-
}
|
|
70
21
|
const DELIMITER = yc.yellow("-");
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
22
|
+
var HelpRenderer = class {
|
|
23
|
+
constructor(_formatters, _cli, _globalFlags, _command, _notes, _examples) {
|
|
24
|
+
this._formatters = _formatters;
|
|
25
|
+
this._cli = _cli;
|
|
26
|
+
this._globalFlags = _globalFlags;
|
|
27
|
+
this._command = _command;
|
|
28
|
+
this._notes = _notes;
|
|
29
|
+
this._examples = _examples;
|
|
30
|
+
}
|
|
31
|
+
render() {
|
|
32
|
+
return [
|
|
33
|
+
this.renderHeader(),
|
|
34
|
+
this.renderUsage(),
|
|
35
|
+
this.renderCommands(),
|
|
36
|
+
this.renderGlobalFlags(),
|
|
37
|
+
this.renderCommandFlags(),
|
|
38
|
+
this.renderNotes(),
|
|
39
|
+
this.renderExamples()
|
|
40
|
+
].filter(isTruthy).filter((section) => section.body.length > 0).map((section) => {
|
|
41
|
+
const body = Array.isArray(section.body) ? section.body.filter(Boolean).join("\n") : section.body;
|
|
42
|
+
if (!section.title) return body;
|
|
43
|
+
return `${yc.bold(section.title)}\n${body.split("\n").map((line) => ` ${line}`).join("\n")}`;
|
|
44
|
+
}).join("\n\n");
|
|
45
|
+
}
|
|
46
|
+
renderHeader() {
|
|
47
|
+
const { _name, _version, _description } = this._cli;
|
|
48
|
+
const command = this._command;
|
|
49
|
+
const description = command?.description ?? _description;
|
|
50
|
+
const formattedCommandName = command?.name ? ` ${yc.cyan(command.name)}` : "";
|
|
51
|
+
const headerLine = command ? `${yc.green(_name)}${formattedCommandName}` : `${yc.green(_name)} ${yc.yellow(formatVersion(_version))}`;
|
|
52
|
+
const alias = command?.alias ? `Alias${toArray(command.alias).length > 1 ? "es" : ""}: ${toArray(command.alias).map((a) => yc.cyan(a)).join(", ")}` : "";
|
|
53
|
+
return { body: [`${headerLine}${description ? ` ${DELIMITER} ${description}` : ""}`, alias] };
|
|
54
|
+
}
|
|
55
|
+
renderUsage() {
|
|
56
|
+
const { _scriptName } = this._cli;
|
|
57
|
+
const command = this._command;
|
|
58
|
+
let usage = `$ ${_scriptName}`;
|
|
59
|
+
if (command) {
|
|
60
|
+
usage += command.name ? ` ${command.name}` : "";
|
|
61
|
+
if (command.parameters) usage += ` ${command.parameters.join(" ")}`;
|
|
62
|
+
}
|
|
63
|
+
if (command?.flags && !objectIsEmpty(command.flags) || !objectIsEmpty(this._globalFlags)) usage += " [FLAGS]";
|
|
64
|
+
return {
|
|
65
|
+
title: "Usage",
|
|
66
|
+
body: [usage]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
renderCommands() {
|
|
70
|
+
const commands = this._cli._commands;
|
|
71
|
+
if (this._command || commands.size === 0) return;
|
|
72
|
+
return {
|
|
73
|
+
title: "Commands",
|
|
74
|
+
body: splitTable([...commands.values()].map((command) => {
|
|
75
|
+
if (command.__isAlias || command.help?.showInHelp === false) return null;
|
|
76
|
+
return [`${yc.cyan(command.name)}${command.alias ? ` (${toArray(command.alias).join(", ")})` : ""}`, command.description];
|
|
77
|
+
}).filter(isTruthy))
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
renderFlags(flags) {
|
|
81
|
+
return Object.entries(flags).map(([name, flag]) => {
|
|
82
|
+
const flagName = formatFlagName(name);
|
|
83
|
+
const aliases = (Array.isArray(flag.alias) ? flag.alias : flag.alias ? [flag.alias] : []).map(formatFlagName).join(", ");
|
|
84
|
+
const description = flag.description ?? "";
|
|
85
|
+
const type = this._formatters.formatFlagType(flag.type);
|
|
86
|
+
const defaultValue = flag.default === void 0 ? "" : `[default: ${String(flag.default)}]`;
|
|
87
|
+
return [
|
|
88
|
+
yc.blue([flagName, aliases].filter(Boolean).join(", ")),
|
|
89
|
+
yc.gray(type),
|
|
90
|
+
description,
|
|
91
|
+
yc.gray(defaultValue)
|
|
92
|
+
];
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
renderCommandFlags() {
|
|
96
|
+
const command = this._command;
|
|
97
|
+
if (!command?.flags || objectIsEmpty(command.flags)) return;
|
|
98
|
+
return {
|
|
99
|
+
title: "Flags",
|
|
100
|
+
body: splitTable(this.renderFlags(command.flags))
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
renderGlobalFlags() {
|
|
104
|
+
if (!this._globalFlags || objectIsEmpty(this._globalFlags)) return;
|
|
105
|
+
return {
|
|
106
|
+
title: "Global Flags",
|
|
107
|
+
body: splitTable(this.renderFlags(this._globalFlags))
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
renderNotes() {
|
|
111
|
+
if (!this._notes?.length) return;
|
|
112
|
+
return {
|
|
113
|
+
title: "Notes",
|
|
114
|
+
body: this._notes
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
renderExamples() {
|
|
118
|
+
if (!this._examples?.length) return;
|
|
119
|
+
return {
|
|
120
|
+
title: "Examples",
|
|
121
|
+
body: splitTable(this._examples.map(([command, description]) => {
|
|
122
|
+
return [
|
|
123
|
+
command,
|
|
124
|
+
DELIMITER,
|
|
125
|
+
description
|
|
126
|
+
];
|
|
127
|
+
}))
|
|
128
|
+
};
|
|
129
|
+
}
|
|
162
130
|
};
|
|
163
131
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
sections = renderers.renderSections(sections);
|
|
221
|
-
return render2(sections);
|
|
222
|
-
}
|
|
223
|
-
function generateSubcommandHelp(render2, ctx, command) {
|
|
224
|
-
var _a, _b, _c, _d, _e, _f;
|
|
225
|
-
const { cli } = ctx;
|
|
226
|
-
const { t } = cli.i18n;
|
|
227
|
-
const [subcommand] = resolveCommandStrict(cli._commands, command, t);
|
|
228
|
-
if (!subcommand) {
|
|
229
|
-
throw new NoSuchCommandError(formatCommandName(command), t);
|
|
230
|
-
}
|
|
231
|
-
const renderers = Object.assign(
|
|
232
|
-
/* @__PURE__ */ Object.create(null),
|
|
233
|
-
defaultRenderers,
|
|
234
|
-
(_a = subcommand.help) == null ? void 0 : _a.renderers
|
|
235
|
-
);
|
|
236
|
-
let sections = [];
|
|
237
|
-
if (command === Root) {
|
|
238
|
-
generateCliDetail(sections, cli);
|
|
239
|
-
} else {
|
|
240
|
-
generateCliDetail(sections, cli, {
|
|
241
|
-
...subcommand,
|
|
242
|
-
name: formatCommandName(command)
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
const parameters = (_c = (_b = subcommand.parameters) == null ? void 0 : _b.join(" ")) != null ? _c : void 0;
|
|
246
|
-
const commandName = command === Root ? "" : ` ${formatCommandName(command)}`;
|
|
247
|
-
const parametersString = parameters ? ` ${parameters}` : "";
|
|
248
|
-
const flagsString = subcommand.flags ? " [flags]" : "";
|
|
249
|
-
sections.push({
|
|
250
|
-
title: t("help.usage"),
|
|
251
|
-
body: [
|
|
252
|
-
yc.magenta(
|
|
253
|
-
`$ ${cli._scriptName}${commandName}${parametersString}${flagsString}`
|
|
254
|
-
)
|
|
255
|
-
]
|
|
256
|
-
});
|
|
257
|
-
const globalFlags = formatFlags(cli._flags, t, renderers);
|
|
258
|
-
if (globalFlags.length > 0) {
|
|
259
|
-
sections.push({
|
|
260
|
-
title: t("help.globalFlags"),
|
|
261
|
-
body: splitTable(globalFlags)
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
if (subcommand.flags) {
|
|
265
|
-
sections.push({
|
|
266
|
-
title: t("help.flags"),
|
|
267
|
-
body: splitTable(formatFlags(subcommand.flags, t, renderers))
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
if ((_d = subcommand == null ? void 0 : subcommand.help) == null ? void 0 : _d.notes) {
|
|
271
|
-
sections.push({
|
|
272
|
-
title: t("help.notes"),
|
|
273
|
-
body: subcommand.help.notes
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
if ((_e = subcommand == null ? void 0 : subcommand.help) == null ? void 0 : _e.examples) {
|
|
277
|
-
generateExamples(sections, (_f = subcommand == null ? void 0 : subcommand.help) == null ? void 0 : _f.examples, t);
|
|
278
|
-
}
|
|
279
|
-
sections = renderers.renderSections(sections);
|
|
280
|
-
return render2(sections);
|
|
281
|
-
}
|
|
282
|
-
const helpPlugin = ({
|
|
283
|
-
command = true,
|
|
284
|
-
flag = true,
|
|
285
|
-
showHelpWhenNoCommand = true,
|
|
286
|
-
notes,
|
|
287
|
-
examples,
|
|
288
|
-
banner,
|
|
289
|
-
renderers
|
|
290
|
-
} = {}) => definePlugin({
|
|
291
|
-
setup: (cli) => {
|
|
292
|
-
const { add, t } = cli.i18n;
|
|
293
|
-
add(locales);
|
|
294
|
-
function printHelp(s) {
|
|
295
|
-
banner && print(`${banner}
|
|
296
|
-
`);
|
|
297
|
-
print(s);
|
|
298
|
-
}
|
|
299
|
-
if (command) {
|
|
300
|
-
cli = cli.command("help", t("help.commandDescription"), {
|
|
301
|
-
parameters: ["[command...]"],
|
|
302
|
-
help: {
|
|
303
|
-
notes: [
|
|
304
|
-
t("help.notes.1"),
|
|
305
|
-
t("help.notes.2"),
|
|
306
|
-
t("help.notes.3")
|
|
307
|
-
],
|
|
308
|
-
examples: [
|
|
309
|
-
[`$ ${cli._scriptName} help`, t("help.examples.1")],
|
|
310
|
-
[`$ ${cli._scriptName} help <command>`, t("help.examples.2")],
|
|
311
|
-
[
|
|
312
|
-
`$ ${cli._scriptName} <command> --help`,
|
|
313
|
-
t("help.examples.2")
|
|
314
|
-
]
|
|
315
|
-
]
|
|
316
|
-
}
|
|
317
|
-
}).on("help", (ctx) => {
|
|
318
|
-
if (ctx.parameters.command.length > 0) {
|
|
319
|
-
printHelp(
|
|
320
|
-
generateSubcommandHelp(render, ctx, ctx.parameters.command)
|
|
321
|
-
);
|
|
322
|
-
} else {
|
|
323
|
-
printHelp(generateHelp(render, ctx, notes, examples, renderers));
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
if (flag) {
|
|
328
|
-
cli = cli.flag("help", t("help.commandDescription"), {
|
|
329
|
-
alias: "h",
|
|
330
|
-
type: Boolean,
|
|
331
|
-
default: false
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
cli.interceptor((ctx, next) => {
|
|
335
|
-
const shouldShowHelp = ctx.flags.help;
|
|
336
|
-
if (!ctx.hasRootOrAlias && ctx.raw._.length === 0 && showHelpWhenNoCommand && !shouldShowHelp) {
|
|
337
|
-
let str = `${t("core.noCommandGiven")}
|
|
338
|
-
|
|
339
|
-
`;
|
|
340
|
-
str += generateHelp(render, ctx, notes, examples, renderers);
|
|
341
|
-
str += "\n";
|
|
342
|
-
printHelp(str);
|
|
343
|
-
process.exit(1);
|
|
344
|
-
} else if (shouldShowHelp) {
|
|
345
|
-
if (ctx.raw._.length > 0) {
|
|
346
|
-
if (ctx.called === Root) {
|
|
347
|
-
printHelp(generateSubcommandHelp(render, ctx, ctx.raw._));
|
|
348
|
-
} else {
|
|
349
|
-
if (ctx.name === Root) {
|
|
350
|
-
printHelp(
|
|
351
|
-
generateHelp(render, ctx, notes, examples, renderers)
|
|
352
|
-
);
|
|
353
|
-
} else {
|
|
354
|
-
printHelp(generateSubcommandHelp(render, ctx, ctx.raw._));
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
} else {
|
|
358
|
-
if (ctx.hasRootOrAlias) {
|
|
359
|
-
printHelp(generateSubcommandHelp(render, ctx, Root));
|
|
360
|
-
} else {
|
|
361
|
-
printHelp(generateHelp(render, ctx, notes, examples, renderers));
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
} else {
|
|
365
|
-
next();
|
|
366
|
-
}
|
|
367
|
-
});
|
|
368
|
-
return cli;
|
|
369
|
-
}
|
|
370
|
-
});
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/index.ts
|
|
134
|
+
const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecified = true, notes, examples, banner, formatters } = {}) => definePlugin({ setup: (cli) => {
|
|
135
|
+
const mergedFormatters = {
|
|
136
|
+
...defaultFormatters,
|
|
137
|
+
...formatters
|
|
138
|
+
};
|
|
139
|
+
const generalHelpNotes = [
|
|
140
|
+
"If no command is specified, show help for the CLI.",
|
|
141
|
+
"If a command is specified, show help for the command.",
|
|
142
|
+
flag && "-h is an alias for --help."
|
|
143
|
+
].filter(isTruthy);
|
|
144
|
+
const generalHelpExamples = [
|
|
145
|
+
command && [`$ ${cli._scriptName} help`, "Show help"],
|
|
146
|
+
command && [`$ ${cli._scriptName} help <command>`, "Show help for a specific command"],
|
|
147
|
+
flag && [`$ ${cli._scriptName} <command> --help`, "Show help for a specific command"]
|
|
148
|
+
].filter(isTruthy);
|
|
149
|
+
const effectiveNotes = notes ?? generalHelpNotes;
|
|
150
|
+
const effectiveExamples = examples ?? generalHelpExamples;
|
|
151
|
+
function printHelp(s) {
|
|
152
|
+
if (banner) console.log(banner);
|
|
153
|
+
console.log(s);
|
|
154
|
+
}
|
|
155
|
+
if (command) cli.command("help", "Show help", {
|
|
156
|
+
parameters: ["[command...]"],
|
|
157
|
+
help: {
|
|
158
|
+
notes: generalHelpNotes,
|
|
159
|
+
examples: generalHelpExamples
|
|
160
|
+
}
|
|
161
|
+
}).on("help", (ctx) => {
|
|
162
|
+
const commandName = ctx.parameters.command;
|
|
163
|
+
let command$1;
|
|
164
|
+
if (commandName.length > 0) {
|
|
165
|
+
[command$1] = resolveCommand(cli._commands, commandName);
|
|
166
|
+
if (!command$1) {
|
|
167
|
+
console.error(`Command "${commandName.join(" ")}" not found.`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
printHelp(new HelpRenderer(mergedFormatters, cli, cli._globalFlags, command$1, command$1 ? command$1.help?.notes : effectiveNotes, command$1 ? command$1.help?.examples : effectiveExamples).render());
|
|
172
|
+
});
|
|
173
|
+
if (flag) cli.globalFlag("help", "Show help", {
|
|
174
|
+
alias: "h",
|
|
175
|
+
type: Boolean,
|
|
176
|
+
default: false
|
|
177
|
+
});
|
|
178
|
+
cli.interceptor({
|
|
179
|
+
enforce: "pre",
|
|
180
|
+
handler: async (ctx, next) => {
|
|
181
|
+
if (ctx.flags.help) printHelp(new HelpRenderer(mergedFormatters, cli, cli._globalFlags, ctx.command, ctx.command ? ctx.command.help?.notes : effectiveNotes, ctx.command ? ctx.command.help?.examples : effectiveExamples).render());
|
|
182
|
+
else if (showHelpWhenNoCommandSpecified && !ctx.command && ctx.rawParsed.parameters.length === 0) printHelp(new HelpRenderer(mergedFormatters, cli, cli._globalFlags, void 0, effectiveNotes, effectiveExamples).render());
|
|
183
|
+
else await next();
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
} });
|
|
371
187
|
|
|
372
|
-
|
|
188
|
+
//#endregion
|
|
189
|
+
export { defaultFormatters, helpPlugin };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clerc/plugin-help",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"author": "Ray <i@mk1.io> (https://github.com/so1ve)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Clerc plugin help",
|
|
@@ -25,13 +25,10 @@
|
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"sideEffects": false,
|
|
27
27
|
"exports": {
|
|
28
|
-
".":
|
|
29
|
-
"types": "./dist/index.d.ts",
|
|
30
|
-
"import": "./dist/index.js"
|
|
31
|
-
}
|
|
28
|
+
".": "./dist/index.js"
|
|
32
29
|
},
|
|
33
|
-
"main": "dist/index.js",
|
|
34
|
-
"module": "dist/index.js",
|
|
30
|
+
"main": "./dist/index.js",
|
|
31
|
+
"module": "./dist/index.js",
|
|
35
32
|
"types": "dist/index.d.ts",
|
|
36
33
|
"typesVersions": {
|
|
37
34
|
"*": {
|
|
@@ -48,17 +45,21 @@
|
|
|
48
45
|
"access": "public"
|
|
49
46
|
},
|
|
50
47
|
"dependencies": {
|
|
51
|
-
"@types/text-table": "^0.2.
|
|
52
|
-
"string-width": "^
|
|
48
|
+
"@types/text-table": "^0.2.5",
|
|
49
|
+
"string-width": "^8.1.0",
|
|
53
50
|
"text-table": "^0.2.0",
|
|
54
|
-
"yoctocolors": "^1.
|
|
55
|
-
"@clerc/utils": "0.
|
|
51
|
+
"yoctocolors": "^2.1.2",
|
|
52
|
+
"@clerc/utils": "1.0.0-beta.2"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@clerc/parser": "1.0.0-beta.2",
|
|
56
|
+
"@clerc/core": "1.0.0-beta.2"
|
|
56
57
|
},
|
|
57
58
|
"peerDependencies": {
|
|
58
59
|
"@clerc/core": "*"
|
|
59
60
|
},
|
|
60
61
|
"scripts": {
|
|
61
|
-
"build": "
|
|
62
|
-
"watch": "
|
|
62
|
+
"build": "tsdown",
|
|
63
|
+
"watch": "tsdown --watch"
|
|
63
64
|
}
|
|
64
65
|
}
|