@clerc/plugin-help 0.11.1 → 0.12.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 CHANGED
@@ -1,21 +1,21 @@
1
1
  import * as _clerc_core from '@clerc/core';
2
2
  import { Clerc } from '@clerc/core';
3
3
 
4
- interface Options {
4
+ interface HelpPluginOptions {
5
5
  /**
6
- * Register a help command or not.
6
+ * Whether to registr the help command.
7
+ * @default true
7
8
  */
8
9
  command?: boolean;
9
10
  /**
10
- * Examples
11
- * Syntax: [example command, description]
11
+ * Global notes.
12
12
  */
13
- examples?: [string, string][];
13
+ notes?: string[];
14
14
  /**
15
- * Notes
15
+ * Global examples.
16
16
  */
17
- notes?: string[];
17
+ examples?: [string, string][];
18
18
  }
19
- declare const helpPlugin: (_options?: Options) => _clerc_core.Plugin<Clerc<{}>, Clerc<{}>>;
19
+ declare const helpPlugin: ({ command, notes, examples, }?: HelpPluginOptions) => _clerc_core.Plugin<Clerc<{}>, Clerc<{}>>;
20
20
 
21
- export { helpPlugin };
21
+ export { HelpPluginOptions, helpPlugin };
package/dist/index.js CHANGED
@@ -1,177 +1,210 @@
1
- import { definePlugin, resolveRootCommands, resolveCommand, NoSuchCommandError, SingleCommand } from '@clerc/core';
2
- import { mustArray, gracefulFlagName, gracefulVersion, generateCommandRecordFromCommandArray } from '@clerc/utils';
1
+ import { definePlugin, resolveCommand, NoSuchCommandError } from '@clerc/core';
2
+ import { gracefulFlagName } from '@clerc/utils';
3
3
  import pc from 'picocolors';
4
+ import { Table } from '@clerc/toolkit';
4
5
 
5
- function generateNameAndAliasFromCommands(commands) {
6
- return Object.fromEntries(
7
- Object.entries(commands).map(([name, command]) => [name, [name, ...command.alias ? mustArray(command.alias) : []].join(", ")])
8
- );
9
- }
10
- function generateFlagNameAndAliasFromCommand(command) {
11
- return Object.fromEntries(
12
- Object.entries(command.flags || {}).map(
13
- ([name, flag]) => {
14
- const nameAndAlias = [name];
15
- if (flag.alias) {
16
- nameAndAlias.push(...mustArray(flag.alias));
17
- }
18
- return [name, nameAndAlias.map(gracefulFlagName).join(", ")];
19
- }
20
- )
21
- );
22
- }
23
- function getPadLength(strings) {
24
- const maxLength = Math.max(...strings.map((n) => n.length));
25
- return Math.floor((maxLength + 4) / 4) * 4;
26
- }
27
- const mergeFlags = (ctx) => ({ ...ctx.flags, ...ctx.unknownFlags });
28
-
29
- const newline = () => {
30
- console.log();
6
+ const table = (...items) => {
7
+ const table2 = new Table({
8
+ chars: {
9
+ "top": "",
10
+ "top-mid": "",
11
+ "top-left": "",
12
+ "top-right": "",
13
+ "bottom": "",
14
+ "bottom-mid": "",
15
+ "bottom-left": "",
16
+ "bottom-right": "",
17
+ "left": "",
18
+ "left-mid": "",
19
+ "mid": "",
20
+ "mid-mid": "",
21
+ "right": "",
22
+ "right-mid": "",
23
+ "middle": " "
24
+ },
25
+ style: { "padding-left": 0, "padding-right": 0 }
26
+ });
27
+ table2.push(...items);
28
+ return table2;
31
29
  };
32
- const getExamples = (cli) => [
33
- [`${cli._name} help`, "Displays help of the cli"],
34
- [`${cli._name} -h`, "Displays help of the cli"],
35
- [`${cli._name} help help`, "Displays help of the help command"]
36
- ];
37
- const defaultOptions = {
38
- command: true,
39
- examples: [],
40
- notes: []
30
+
31
+ const render = (sections) => {
32
+ const rendered = [];
33
+ for (const section of sections) {
34
+ if (section.type === "block" || !section.type) {
35
+ const indent = " ".repeat(4);
36
+ const formattedBody = section.body.map((line) => indent + line);
37
+ formattedBody.unshift("");
38
+ const body = formattedBody.join("\n");
39
+ rendered.push(table([pc.bold(section.title)], [body]).toString());
40
+ } else if (section.type === "inline") {
41
+ const formattedBody = section.items.map((item) => [pc.bold(item.title), item.body]);
42
+ const tableGenerated = table(...formattedBody);
43
+ rendered.push(tableGenerated.toString());
44
+ }
45
+ rendered.push("");
46
+ }
47
+ return rendered.join("\n");
41
48
  };
42
- const helpPlugin = (_options) => definePlugin({
43
- setup: (cli) => {
44
- const { command, ...rest } = { ...defaultOptions, ..._options };
45
- cli.inspector((inspectorCtx, next) => {
46
- if (command && !inspectorCtx.isSingleCommand) {
47
- cli = cli.command("help", "Show help", {
48
- examples: getExamples(cli),
49
- parameters: [
50
- "[command...]"
51
- ]
52
- }).on("help", (ctx2) => {
53
- showHelp(ctx2, rest);
54
- });
55
- }
56
- const ctx = inspectorCtx;
57
- const flags = mergeFlags(ctx);
58
- if (flags.h || flags.help) {
59
- if (ctx.isSingleCommand) {
60
- showSingleCommandHelp(ctx);
61
- return;
62
- }
63
- if (ctx.name === "help") {
64
- showSubcommandHelp(ctx);
65
- return;
66
- }
67
- if (ctx.resolved) {
68
- showSubcommandHelp(ctx);
69
- } else {
70
- showHelp(ctx, rest);
71
- }
72
- return;
73
- }
74
- if (!ctx.resolved && ctx.raw._.length === 0 && Object.keys(flags).length === 0) {
75
- showHelp(ctx, rest);
76
- return;
77
- }
78
- next();
49
+
50
+ const DELIMITER = pc.yellow("-");
51
+ const generateCliDetail = (sections, cli, subcommand) => {
52
+ const items = [
53
+ {
54
+ title: pc.gray("Name:"),
55
+ body: pc.red(cli._name)
56
+ },
57
+ {
58
+ title: pc.gray("Version:"),
59
+ body: pc.yellow(cli._version)
60
+ }
61
+ ];
62
+ if (subcommand) {
63
+ items.push({
64
+ title: pc.gray("Subcommand:"),
65
+ body: pc.green(subcommand)
79
66
  });
80
- return cli;
81
67
  }
82
- });
83
- function showHelp(ctx, { examples, notes }) {
68
+ sections.push({
69
+ type: "inline",
70
+ items
71
+ });
72
+ sections.push({
73
+ title: "Description:",
74
+ body: [cli._description]
75
+ });
76
+ };
77
+ const generateExamples = (sections, examples) => {
78
+ const examplesFormatted = examples.map(([command, description]) => [command, DELIMITER, description]);
79
+ sections.push({
80
+ title: "Examples:",
81
+ body: table(...examplesFormatted).toString().split("\n")
82
+ });
83
+ };
84
+ const showHelp = (ctx, notes, examples) => {
84
85
  const { cli } = ctx;
85
- if (ctx.raw.parameters.length > 0) {
86
- showSubcommandHelp(ctx);
87
- return;
86
+ const sections = [];
87
+ generateCliDetail(sections, cli);
88
+ if (ctx.isSingleCommand) {
89
+ sections.push({
90
+ title: "Usage:",
91
+ body: [`$ ${cli._name} [options]`]
92
+ });
93
+ } else {
94
+ sections.push({
95
+ title: "Usage:",
96
+ body: [`$ ${cli._name} [command] [options]`]
97
+ });
88
98
  }
89
- cli._name && console.log(`${pc.green(cli._name)} ${gracefulVersion(cli._version)}`);
90
- if (cli._description) {
91
- console.log(cli._description);
92
- newline();
99
+ if (!ctx.isSingleCommand) {
100
+ sections.push({
101
+ title: "Commands:",
102
+ body: Object.values(cli._commands).map((command) => {
103
+ return table([pc.cyan(command.name), DELIMITER, command.description]).toString();
104
+ })
105
+ });
93
106
  }
94
- console.log(pc.yellow("USAGE:"));
95
- console.log(` ${cli._name || "<CLI NAME>"} <SUBCOMMAND> [OPTIONS]`);
96
- newline();
97
- console.log(pc.yellow("COMMANDS:"));
98
- const commandNameAndAlias = generateNameAndAliasFromCommands(generateCommandRecordFromCommandArray(resolveRootCommands(cli._commands)));
99
- const commandsPadLength = getPadLength(Object.values(commandNameAndAlias));
100
- for (const [name, nameAndAlias] of Object.entries(commandNameAndAlias)) {
101
- console.log(` ${pc.green(nameAndAlias.padEnd(commandsPadLength))}${cli._commands[name].description}`);
107
+ if (notes) {
108
+ sections.push({
109
+ title: "Notes:",
110
+ body: notes
111
+ });
102
112
  }
103
- if (examples.length > 0) {
104
- newline();
105
- console.log(pc.yellow("EXAMPLES:"));
106
- const examplesPadLength = getPadLength(examples.map((e) => e[0]));
107
- for (const [exampleCommand, exampleDescription] of examples) {
108
- console.log(` ${exampleCommand.padEnd(examplesPadLength)}${exampleDescription}`);
109
- }
113
+ if (examples) {
114
+ generateExamples(sections, examples);
110
115
  }
111
- showCommandNotes(notes);
112
- }
113
- function showCommandExamples(examples) {
114
- if (examples && examples.length > 0) {
115
- newline();
116
- console.log(pc.yellow("EXAMPLES:"));
117
- const examplesPadLength = getPadLength(examples.map((e) => e[0]));
118
- for (const [exampleCommand, exampleDescription] of examples) {
119
- console.log(` ${exampleCommand.padEnd(examplesPadLength)}${exampleDescription}`);
120
- }
116
+ console.log(render(sections));
117
+ };
118
+ const showSubcommandHelp = (ctx, command) => {
119
+ var _a;
120
+ const { cli } = ctx;
121
+ const subcommand = resolveCommand(cli._commands, command);
122
+ if (!subcommand) {
123
+ throw new NoSuchCommandError(command.join(" "));
121
124
  }
122
- }
123
- function showCommandNotes(notes) {
124
- if (notes && notes.length > 0) {
125
- newline();
126
- console.log(pc.yellow("NOTES:"));
127
- for (const note of notes) {
128
- console.log(` ${note}`);
129
- }
125
+ const sections = [];
126
+ generateCliDetail(sections, cli, subcommand.name);
127
+ const parameters = ((_a = subcommand.parameters) == null ? void 0 : _a.join(", ")) || "";
128
+ sections.push({
129
+ title: "Usage:",
130
+ body: [`$ ${cli._name} ${subcommand.name}${parameters ? ` ${parameters}` : ""} [options]`]
131
+ });
132
+ if (subcommand.flags) {
133
+ sections.push({
134
+ title: "Flags:",
135
+ body: Object.entries(subcommand.flags).map(([name, flag]) => {
136
+ const flagNameWithAlias = [gracefulFlagName(name)];
137
+ if (flag.alias) {
138
+ flagNameWithAlias.push(gracefulFlagName(flag.alias));
139
+ }
140
+ const items = [pc.blue(flagNameWithAlias.join(", "))];
141
+ if (flag.description) {
142
+ items.push(DELIMITER, flag.description);
143
+ }
144
+ if (flag.type) {
145
+ const type = Array.isArray(flag.type) ? `Array<${flag.type[0].name}>` : flag.type.name;
146
+ items.push(pc.gray(`(${type})`));
147
+ }
148
+ return table(items).toString();
149
+ })
150
+ });
130
151
  }
131
- }
132
- function showSubcommandHelp(ctx) {
133
- const { cli } = ctx;
134
- const commandName = ctx.parameters.command;
135
- const commandToShowHelp = resolveCommand(cli._commands, commandName);
136
- if (!commandToShowHelp) {
137
- throw new NoSuchCommandError(commandName.join(" "));
152
+ if (subcommand.notes) {
153
+ sections.push({
154
+ title: "Notes:",
155
+ body: subcommand.notes
156
+ });
138
157
  }
139
- console.log(`${pc.green(`${cli._name} ${commandToShowHelp.name}`)} ${gracefulVersion(cli._version)}`);
140
- commandToShowHelp.description && console.log(commandToShowHelp.description);
141
- newline();
142
- console.log(pc.yellow("USAGE:"));
143
- console.log(` ${cli._name} ${commandToShowHelp.name} [PARAMETERS] [FLAGS]`);
144
- const flagNameAndAlias = generateFlagNameAndAliasFromCommand(commandToShowHelp);
145
- if (Object.keys(flagNameAndAlias).length > 0) {
146
- newline();
147
- console.log(pc.yellow("FLAGS:"));
148
- const flagsPadLength = getPadLength(Object.values(flagNameAndAlias));
149
- for (const [name, nameAndAlias] of Object.entries(flagNameAndAlias)) {
150
- console.log(` ${pc.green(nameAndAlias.padEnd(flagsPadLength))}${commandToShowHelp.flags[name].description}`);
151
- }
158
+ if (subcommand.examples) {
159
+ generateExamples(sections, subcommand.examples);
152
160
  }
153
- showCommandExamples(commandToShowHelp.examples);
154
- showCommandNotes(commandToShowHelp.notes);
155
- }
156
- function showSingleCommandHelp(ctx) {
157
- const { cli } = ctx;
158
- const singleCommand = cli._commands[SingleCommand];
159
- console.log(`${pc.green(`${cli._name} ${gracefulVersion(cli._version)}`)}`);
160
- singleCommand.description && console.log(singleCommand.description);
161
- newline();
162
- console.log(pc.yellow("USAGE:"));
163
- console.log(` ${cli._name} [PARAMETERS] [FLAGS]`);
164
- const flagNameAndAlias = generateFlagNameAndAliasFromCommand(singleCommand);
165
- if (Object.keys(flagNameAndAlias).length > 0) {
166
- newline();
167
- console.log(pc.yellow("FLAGS:"));
168
- const flagsPadLength = getPadLength(Object.values(flagNameAndAlias));
169
- for (const [name, nameAndAlias] of Object.entries(flagNameAndAlias)) {
170
- console.log(` ${pc.green(nameAndAlias.padEnd(flagsPadLength))}${singleCommand.flags[name].description}`);
171
- }
161
+ console.log(render(sections));
162
+ };
163
+ const helpPlugin = ({
164
+ command = true,
165
+ notes,
166
+ examples
167
+ } = {}) => definePlugin({
168
+ setup: (cli) => {
169
+ cli = cli.inspector({
170
+ enforce: "post",
171
+ fn: (ctx, next) => {
172
+ if (command && !ctx.isSingleCommand) {
173
+ cli = cli.command("help", "Show help", {
174
+ parameters: [
175
+ "[command...]"
176
+ ],
177
+ notes: [
178
+ "If no command is specified, show help for the CLI.",
179
+ "If a command is specified, show help for the command.",
180
+ "-h is an alias for --help."
181
+ ],
182
+ examples: [
183
+ [`$ ${cli._name} help`, "Show help"],
184
+ [`$ ${cli._name} help <command>`, "Show help for a specific command"],
185
+ [`$ ${cli._name} <command> --help`, "Show help for a specific command"]
186
+ ]
187
+ }).on("help", (ctx2) => {
188
+ if (ctx2.parameters.command.length) {
189
+ showSubcommandHelp(ctx2, ctx2.parameters.command);
190
+ } else {
191
+ showHelp(ctx2, notes, examples);
192
+ }
193
+ });
194
+ }
195
+ if (ctx.raw.mergedFlags.h || ctx.raw.mergedFlags.help) {
196
+ if (ctx.raw._.length) {
197
+ showSubcommandHelp(ctx, ctx.raw._);
198
+ } else {
199
+ showHelp(ctx, notes, examples);
200
+ }
201
+ return;
202
+ }
203
+ next();
204
+ }
205
+ });
206
+ return cli;
172
207
  }
173
- showCommandExamples(singleCommand.examples);
174
- showCommandNotes(singleCommand.notes);
175
- }
208
+ });
176
209
 
177
210
  export { helpPlugin };
package/dist/index.mjs CHANGED
@@ -1,177 +1,210 @@
1
- import { definePlugin, resolveRootCommands, resolveCommand, NoSuchCommandError, SingleCommand } from '@clerc/core';
2
- import { mustArray, gracefulFlagName, gracefulVersion, generateCommandRecordFromCommandArray } from '@clerc/utils';
1
+ import { definePlugin, resolveCommand, NoSuchCommandError } from '@clerc/core';
2
+ import { gracefulFlagName } from '@clerc/utils';
3
3
  import pc from 'picocolors';
4
+ import { Table } from '@clerc/toolkit';
4
5
 
5
- function generateNameAndAliasFromCommands(commands) {
6
- return Object.fromEntries(
7
- Object.entries(commands).map(([name, command]) => [name, [name, ...command.alias ? mustArray(command.alias) : []].join(", ")])
8
- );
9
- }
10
- function generateFlagNameAndAliasFromCommand(command) {
11
- return Object.fromEntries(
12
- Object.entries(command.flags || {}).map(
13
- ([name, flag]) => {
14
- const nameAndAlias = [name];
15
- if (flag.alias) {
16
- nameAndAlias.push(...mustArray(flag.alias));
17
- }
18
- return [name, nameAndAlias.map(gracefulFlagName).join(", ")];
19
- }
20
- )
21
- );
22
- }
23
- function getPadLength(strings) {
24
- const maxLength = Math.max(...strings.map((n) => n.length));
25
- return Math.floor((maxLength + 4) / 4) * 4;
26
- }
27
- const mergeFlags = (ctx) => ({ ...ctx.flags, ...ctx.unknownFlags });
28
-
29
- const newline = () => {
30
- console.log();
6
+ const table = (...items) => {
7
+ const table2 = new Table({
8
+ chars: {
9
+ "top": "",
10
+ "top-mid": "",
11
+ "top-left": "",
12
+ "top-right": "",
13
+ "bottom": "",
14
+ "bottom-mid": "",
15
+ "bottom-left": "",
16
+ "bottom-right": "",
17
+ "left": "",
18
+ "left-mid": "",
19
+ "mid": "",
20
+ "mid-mid": "",
21
+ "right": "",
22
+ "right-mid": "",
23
+ "middle": " "
24
+ },
25
+ style: { "padding-left": 0, "padding-right": 0 }
26
+ });
27
+ table2.push(...items);
28
+ return table2;
31
29
  };
32
- const getExamples = (cli) => [
33
- [`${cli._name} help`, "Displays help of the cli"],
34
- [`${cli._name} -h`, "Displays help of the cli"],
35
- [`${cli._name} help help`, "Displays help of the help command"]
36
- ];
37
- const defaultOptions = {
38
- command: true,
39
- examples: [],
40
- notes: []
30
+
31
+ const render = (sections) => {
32
+ const rendered = [];
33
+ for (const section of sections) {
34
+ if (section.type === "block" || !section.type) {
35
+ const indent = " ".repeat(4);
36
+ const formattedBody = section.body.map((line) => indent + line);
37
+ formattedBody.unshift("");
38
+ const body = formattedBody.join("\n");
39
+ rendered.push(table([pc.bold(section.title)], [body]).toString());
40
+ } else if (section.type === "inline") {
41
+ const formattedBody = section.items.map((item) => [pc.bold(item.title), item.body]);
42
+ const tableGenerated = table(...formattedBody);
43
+ rendered.push(tableGenerated.toString());
44
+ }
45
+ rendered.push("");
46
+ }
47
+ return rendered.join("\n");
41
48
  };
42
- const helpPlugin = (_options) => definePlugin({
43
- setup: (cli) => {
44
- const { command, ...rest } = { ...defaultOptions, ..._options };
45
- cli.inspector((inspectorCtx, next) => {
46
- if (command && !inspectorCtx.isSingleCommand) {
47
- cli = cli.command("help", "Show help", {
48
- examples: getExamples(cli),
49
- parameters: [
50
- "[command...]"
51
- ]
52
- }).on("help", (ctx2) => {
53
- showHelp(ctx2, rest);
54
- });
55
- }
56
- const ctx = inspectorCtx;
57
- const flags = mergeFlags(ctx);
58
- if (flags.h || flags.help) {
59
- if (ctx.isSingleCommand) {
60
- showSingleCommandHelp(ctx);
61
- return;
62
- }
63
- if (ctx.name === "help") {
64
- showSubcommandHelp(ctx);
65
- return;
66
- }
67
- if (ctx.resolved) {
68
- showSubcommandHelp(ctx);
69
- } else {
70
- showHelp(ctx, rest);
71
- }
72
- return;
73
- }
74
- if (!ctx.resolved && ctx.raw._.length === 0 && Object.keys(flags).length === 0) {
75
- showHelp(ctx, rest);
76
- return;
77
- }
78
- next();
49
+
50
+ const DELIMITER = pc.yellow("-");
51
+ const generateCliDetail = (sections, cli, subcommand) => {
52
+ const items = [
53
+ {
54
+ title: pc.gray("Name:"),
55
+ body: pc.red(cli._name)
56
+ },
57
+ {
58
+ title: pc.gray("Version:"),
59
+ body: pc.yellow(cli._version)
60
+ }
61
+ ];
62
+ if (subcommand) {
63
+ items.push({
64
+ title: pc.gray("Subcommand:"),
65
+ body: pc.green(subcommand)
79
66
  });
80
- return cli;
81
67
  }
82
- });
83
- function showHelp(ctx, { examples, notes }) {
68
+ sections.push({
69
+ type: "inline",
70
+ items
71
+ });
72
+ sections.push({
73
+ title: "Description:",
74
+ body: [cli._description]
75
+ });
76
+ };
77
+ const generateExamples = (sections, examples) => {
78
+ const examplesFormatted = examples.map(([command, description]) => [command, DELIMITER, description]);
79
+ sections.push({
80
+ title: "Examples:",
81
+ body: table(...examplesFormatted).toString().split("\n")
82
+ });
83
+ };
84
+ const showHelp = (ctx, notes, examples) => {
84
85
  const { cli } = ctx;
85
- if (ctx.raw.parameters.length > 0) {
86
- showSubcommandHelp(ctx);
87
- return;
86
+ const sections = [];
87
+ generateCliDetail(sections, cli);
88
+ if (ctx.isSingleCommand) {
89
+ sections.push({
90
+ title: "Usage:",
91
+ body: [`$ ${cli._name} [options]`]
92
+ });
93
+ } else {
94
+ sections.push({
95
+ title: "Usage:",
96
+ body: [`$ ${cli._name} [command] [options]`]
97
+ });
88
98
  }
89
- cli._name && console.log(`${pc.green(cli._name)} ${gracefulVersion(cli._version)}`);
90
- if (cli._description) {
91
- console.log(cli._description);
92
- newline();
99
+ if (!ctx.isSingleCommand) {
100
+ sections.push({
101
+ title: "Commands:",
102
+ body: Object.values(cli._commands).map((command) => {
103
+ return table([pc.cyan(command.name), DELIMITER, command.description]).toString();
104
+ })
105
+ });
93
106
  }
94
- console.log(pc.yellow("USAGE:"));
95
- console.log(` ${cli._name || "<CLI NAME>"} <SUBCOMMAND> [OPTIONS]`);
96
- newline();
97
- console.log(pc.yellow("COMMANDS:"));
98
- const commandNameAndAlias = generateNameAndAliasFromCommands(generateCommandRecordFromCommandArray(resolveRootCommands(cli._commands)));
99
- const commandsPadLength = getPadLength(Object.values(commandNameAndAlias));
100
- for (const [name, nameAndAlias] of Object.entries(commandNameAndAlias)) {
101
- console.log(` ${pc.green(nameAndAlias.padEnd(commandsPadLength))}${cli._commands[name].description}`);
107
+ if (notes) {
108
+ sections.push({
109
+ title: "Notes:",
110
+ body: notes
111
+ });
102
112
  }
103
- if (examples.length > 0) {
104
- newline();
105
- console.log(pc.yellow("EXAMPLES:"));
106
- const examplesPadLength = getPadLength(examples.map((e) => e[0]));
107
- for (const [exampleCommand, exampleDescription] of examples) {
108
- console.log(` ${exampleCommand.padEnd(examplesPadLength)}${exampleDescription}`);
109
- }
113
+ if (examples) {
114
+ generateExamples(sections, examples);
110
115
  }
111
- showCommandNotes(notes);
112
- }
113
- function showCommandExamples(examples) {
114
- if (examples && examples.length > 0) {
115
- newline();
116
- console.log(pc.yellow("EXAMPLES:"));
117
- const examplesPadLength = getPadLength(examples.map((e) => e[0]));
118
- for (const [exampleCommand, exampleDescription] of examples) {
119
- console.log(` ${exampleCommand.padEnd(examplesPadLength)}${exampleDescription}`);
120
- }
116
+ console.log(render(sections));
117
+ };
118
+ const showSubcommandHelp = (ctx, command) => {
119
+ var _a;
120
+ const { cli } = ctx;
121
+ const subcommand = resolveCommand(cli._commands, command);
122
+ if (!subcommand) {
123
+ throw new NoSuchCommandError(command.join(" "));
121
124
  }
122
- }
123
- function showCommandNotes(notes) {
124
- if (notes && notes.length > 0) {
125
- newline();
126
- console.log(pc.yellow("NOTES:"));
127
- for (const note of notes) {
128
- console.log(` ${note}`);
129
- }
125
+ const sections = [];
126
+ generateCliDetail(sections, cli, subcommand.name);
127
+ const parameters = ((_a = subcommand.parameters) == null ? void 0 : _a.join(", ")) || "";
128
+ sections.push({
129
+ title: "Usage:",
130
+ body: [`$ ${cli._name} ${subcommand.name}${parameters ? ` ${parameters}` : ""} [options]`]
131
+ });
132
+ if (subcommand.flags) {
133
+ sections.push({
134
+ title: "Flags:",
135
+ body: Object.entries(subcommand.flags).map(([name, flag]) => {
136
+ const flagNameWithAlias = [gracefulFlagName(name)];
137
+ if (flag.alias) {
138
+ flagNameWithAlias.push(gracefulFlagName(flag.alias));
139
+ }
140
+ const items = [pc.blue(flagNameWithAlias.join(", "))];
141
+ if (flag.description) {
142
+ items.push(DELIMITER, flag.description);
143
+ }
144
+ if (flag.type) {
145
+ const type = Array.isArray(flag.type) ? `Array<${flag.type[0].name}>` : flag.type.name;
146
+ items.push(pc.gray(`(${type})`));
147
+ }
148
+ return table(items).toString();
149
+ })
150
+ });
130
151
  }
131
- }
132
- function showSubcommandHelp(ctx) {
133
- const { cli } = ctx;
134
- const commandName = ctx.parameters.command;
135
- const commandToShowHelp = resolveCommand(cli._commands, commandName);
136
- if (!commandToShowHelp) {
137
- throw new NoSuchCommandError(commandName.join(" "));
152
+ if (subcommand.notes) {
153
+ sections.push({
154
+ title: "Notes:",
155
+ body: subcommand.notes
156
+ });
138
157
  }
139
- console.log(`${pc.green(`${cli._name} ${commandToShowHelp.name}`)} ${gracefulVersion(cli._version)}`);
140
- commandToShowHelp.description && console.log(commandToShowHelp.description);
141
- newline();
142
- console.log(pc.yellow("USAGE:"));
143
- console.log(` ${cli._name} ${commandToShowHelp.name} [PARAMETERS] [FLAGS]`);
144
- const flagNameAndAlias = generateFlagNameAndAliasFromCommand(commandToShowHelp);
145
- if (Object.keys(flagNameAndAlias).length > 0) {
146
- newline();
147
- console.log(pc.yellow("FLAGS:"));
148
- const flagsPadLength = getPadLength(Object.values(flagNameAndAlias));
149
- for (const [name, nameAndAlias] of Object.entries(flagNameAndAlias)) {
150
- console.log(` ${pc.green(nameAndAlias.padEnd(flagsPadLength))}${commandToShowHelp.flags[name].description}`);
151
- }
158
+ if (subcommand.examples) {
159
+ generateExamples(sections, subcommand.examples);
152
160
  }
153
- showCommandExamples(commandToShowHelp.examples);
154
- showCommandNotes(commandToShowHelp.notes);
155
- }
156
- function showSingleCommandHelp(ctx) {
157
- const { cli } = ctx;
158
- const singleCommand = cli._commands[SingleCommand];
159
- console.log(`${pc.green(`${cli._name} ${gracefulVersion(cli._version)}`)}`);
160
- singleCommand.description && console.log(singleCommand.description);
161
- newline();
162
- console.log(pc.yellow("USAGE:"));
163
- console.log(` ${cli._name} [PARAMETERS] [FLAGS]`);
164
- const flagNameAndAlias = generateFlagNameAndAliasFromCommand(singleCommand);
165
- if (Object.keys(flagNameAndAlias).length > 0) {
166
- newline();
167
- console.log(pc.yellow("FLAGS:"));
168
- const flagsPadLength = getPadLength(Object.values(flagNameAndAlias));
169
- for (const [name, nameAndAlias] of Object.entries(flagNameAndAlias)) {
170
- console.log(` ${pc.green(nameAndAlias.padEnd(flagsPadLength))}${singleCommand.flags[name].description}`);
171
- }
161
+ console.log(render(sections));
162
+ };
163
+ const helpPlugin = ({
164
+ command = true,
165
+ notes,
166
+ examples
167
+ } = {}) => definePlugin({
168
+ setup: (cli) => {
169
+ cli = cli.inspector({
170
+ enforce: "post",
171
+ fn: (ctx, next) => {
172
+ if (command && !ctx.isSingleCommand) {
173
+ cli = cli.command("help", "Show help", {
174
+ parameters: [
175
+ "[command...]"
176
+ ],
177
+ notes: [
178
+ "If no command is specified, show help for the CLI.",
179
+ "If a command is specified, show help for the command.",
180
+ "-h is an alias for --help."
181
+ ],
182
+ examples: [
183
+ [`$ ${cli._name} help`, "Show help"],
184
+ [`$ ${cli._name} help <command>`, "Show help for a specific command"],
185
+ [`$ ${cli._name} <command> --help`, "Show help for a specific command"]
186
+ ]
187
+ }).on("help", (ctx2) => {
188
+ if (ctx2.parameters.command.length) {
189
+ showSubcommandHelp(ctx2, ctx2.parameters.command);
190
+ } else {
191
+ showHelp(ctx2, notes, examples);
192
+ }
193
+ });
194
+ }
195
+ if (ctx.raw.mergedFlags.h || ctx.raw.mergedFlags.help) {
196
+ if (ctx.raw._.length) {
197
+ showSubcommandHelp(ctx, ctx.raw._);
198
+ } else {
199
+ showHelp(ctx, notes, examples);
200
+ }
201
+ return;
202
+ }
203
+ next();
204
+ }
205
+ });
206
+ return cli;
172
207
  }
173
- showCommandExamples(singleCommand.examples);
174
- showCommandNotes(singleCommand.notes);
175
- }
208
+ });
176
209
 
177
210
  export { helpPlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerc/plugin-help",
3
- "version": "0.11.1",
3
+ "version": "0.12.0",
4
4
  "author": "Ray <nn_201312@163.com> (https://github.com/so1ve)",
5
5
  "description": "Clerc plugin help",
6
6
  "keywords": [
@@ -51,11 +51,12 @@
51
51
  "@clerc/core": "*"
52
52
  },
53
53
  "dependencies": {
54
- "picocolors": "^1.0.0",
55
- "@clerc/utils": "0.11.1"
54
+ "@clerc/toolkit": "0.12.0",
55
+ "@clerc/utils": "0.12.0",
56
+ "picocolors": "^1.0.0"
56
57
  },
57
58
  "devDependencies": {
58
- "@clerc/core": "0.11.1"
59
+ "@clerc/core": "0.12.0"
59
60
  },
60
61
  "scripts": {
61
62
  "build": "puild",