@clerc/plugin-help 1.0.0-beta.12 → 1.0.0-beta.14

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,7 +1,9 @@
1
1
  import { Plugin } from "@clerc/core";
2
2
 
3
3
  //#region ../parser/src/types.d.ts
4
-
4
+ type FlagDefaultValue<T = unknown> = T | ((() => T) & {
5
+ display?: string;
6
+ });
5
7
  /**
6
8
  * Defines how a string input is converted to the target type T.
7
9
  *
@@ -12,13 +14,14 @@ type FlagTypeFunction<T = unknown> = ((value: string) => T) & {
12
14
  * Optional display name for the type, useful in help output.
13
15
  * If provided, this will be shown instead of the function name.
14
16
  */
15
- displayName?: string;
17
+ display?: string;
16
18
  };
17
19
  type FlagType<T = unknown> = FlagTypeFunction<T> | readonly [FlagTypeFunction<T>];
18
20
  //#endregion
19
21
  //#region src/types.d.ts
20
22
  interface Formatters {
21
23
  formatFlagType: (type: FlagType) => string;
24
+ formatFlagDefault: <T>(value: FlagDefaultValue<T>) => string;
22
25
  }
23
26
  /**
24
27
  * A group definition as a tuple of [key, displayName].
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { definePlugin, resolveCommand } from "@clerc/core";
1
+ import { NoSuchCommandError, definePlugin, resolveCommand } from "@clerc/core";
2
2
  import stringWidth from "string-width";
3
3
  import textTable from "text-table";
4
4
  import * as yc from "yoctocolors";
@@ -14,10 +14,14 @@ const objectIsEmpty = (obj) => Object.keys(obj).length === 0;
14
14
  //#endregion
15
15
  //#region src/utils.ts
16
16
  function formatFlagType(type) {
17
- if (typeof type === "function") return type.displayName ?? type.name;
17
+ if (typeof type === "function") return type.display ?? type.name;
18
18
  const innerType = type[0];
19
19
  return `Array<${innerType.displayName ?? innerType.name}>`;
20
20
  }
21
+ function formatFlagDefault(value) {
22
+ if (typeof value === "function" && "display" in value && value.display) return value.display;
23
+ return String(value);
24
+ }
21
25
  function formatCommandName(name) {
22
26
  if (name === "") return "(root)";
23
27
  return name;
@@ -25,7 +29,10 @@ function formatCommandName(name) {
25
29
 
26
30
  //#endregion
27
31
  //#region src/formatters.ts
28
- const defaultFormatters = { formatFlagType };
32
+ const defaultFormatters = {
33
+ formatFlagType,
34
+ formatFlagDefault
35
+ };
29
36
 
30
37
  //#endregion
31
38
  //#region src/renderer.ts
@@ -96,17 +103,36 @@ var HelpRenderer = class {
96
103
  body: [yc.magenta(usage)]
97
104
  };
98
105
  }
106
+ getSubcommands(parentCommandName) {
107
+ const subcommands = /* @__PURE__ */ new Map();
108
+ if (!parentCommandName) return subcommands;
109
+ const prefix = `${parentCommandName} `;
110
+ for (const [name, command] of this._cli._commands) if (name.startsWith(prefix) && name !== parentCommandName) {
111
+ const subcommandName = name.slice(prefix.length);
112
+ subcommands.set(subcommandName, command);
113
+ }
114
+ return subcommands;
115
+ }
99
116
  renderCommands() {
100
117
  const commands = this._cli._commands;
101
- if (this._command || commands.size === 0) return;
118
+ let commandsToShow;
119
+ let title = "Commands";
120
+ let prefix = "";
121
+ if (this._command) {
122
+ prefix = this._command.name ? `${this._command.name} ` : "";
123
+ title = "Subcommands";
124
+ commandsToShow = this.getSubcommands(this._command.name);
125
+ if (commandsToShow.size === 0) return;
126
+ } else commandsToShow = commands;
127
+ if (commandsToShow.size === 0) return;
102
128
  const groupedCommands = /* @__PURE__ */ new Map();
103
129
  const defaultCommands = [];
104
130
  let rootCommand = [];
105
- for (const command of commands.values()) {
131
+ for (const command of commandsToShow.values()) {
106
132
  if (command.__isAlias || command.help?.show === false) continue;
107
133
  const group = command.help?.group;
108
134
  validateGroup(group, this._commandGroups, "command", command.name);
109
- const item = [`${yc.cyan(formatCommandName(command.name))}${command.alias ? ` (${toArray(command.alias).join(", ")})` : ""}`, command.description];
135
+ const item = [`${yc.cyan(formatCommandName(command.name.slice(prefix.length)))}${command.alias ? ` (${toArray(command.alias).join(", ")})` : ""}`, command.description];
110
136
  if (command.name === "") rootCommand = item;
111
137
  else if (group && group !== DEFAULT_GROUP_KEY) {
112
138
  const groupItems = groupedCommands.get(group) ?? [];
@@ -128,7 +154,7 @@ var HelpRenderer = class {
128
154
  }
129
155
  }
130
156
  return {
131
- title: "Commands",
157
+ title,
132
158
  body
133
159
  };
134
160
  }
@@ -140,7 +166,7 @@ var HelpRenderer = class {
140
166
  yc.blue([flagName, aliases].filter(Boolean).join(", ")),
141
167
  yc.gray(type),
142
168
  flag.description,
143
- flag.default !== void 0 && yc.gray(`[default: ${String(flag.default)}]`)
169
+ flag.default !== void 0 && yc.gray(`[default: ${this._formatters.formatFlagDefault(flag.default)}]`)
144
170
  ].filter(isTruthy);
145
171
  }
146
172
  renderGroupedFlags(flags, groupMap, itemType) {
@@ -239,10 +265,7 @@ const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecifie
239
265
  let command$1;
240
266
  if (commandName.length > 0) {
241
267
  [command$1] = resolveCommand(cli._commands, commandName);
242
- if (!command$1) {
243
- console.error(`Command "${commandName.join(" ")}" not found.`);
244
- return;
245
- }
268
+ if (!command$1) throw new NoSuchCommandError(commandName.join(" "));
246
269
  }
247
270
  printHelp(new HelpRenderer(mergedFormatters, cli, cli._globalFlags, command$1, command$1 ? command$1.help?.notes : effectiveNotes, command$1 ? command$1.help?.examples : effectiveExamples, groups).render());
248
271
  });
@@ -252,10 +275,13 @@ const helpPlugin = ({ command = true, flag = true, showHelpWhenNoCommandSpecifie
252
275
  default: false
253
276
  });
254
277
  cli.interceptor({
255
- enforce: "pre",
278
+ enforce: "post",
256
279
  handler: async (ctx, next) => {
257
- 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, groups).render());
258
- else if (showHelpWhenNoCommandSpecified && !ctx.command && ctx.rawParsed.parameters.length === 0) printHelp(new HelpRenderer(mergedFormatters, cli, cli._globalFlags, void 0, effectiveNotes, effectiveExamples, groups).render());
280
+ if (ctx.flags.help) {
281
+ const command$1 = ctx.command;
282
+ if (!command$1 && ctx.rawParsed.parameters.length > 0) await next();
283
+ printHelp(new HelpRenderer(mergedFormatters, cli, cli._globalFlags, command$1, command$1 ? command$1.help?.notes : effectiveNotes, command$1 ? command$1.help?.examples : effectiveExamples, groups).render());
284
+ } else if (showHelpWhenNoCommandSpecified && !ctx.command && ctx.rawParsed.parameters.length === 0) printHelp(new HelpRenderer(mergedFormatters, cli, cli._globalFlags, void 0, effectiveNotes, effectiveExamples, groups).render());
259
285
  else await next();
260
286
  }
261
287
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerc/plugin-help",
3
- "version": "1.0.0-beta.12",
3
+ "version": "1.0.0-beta.14",
4
4
  "author": "Ray <i@mk1.io> (https://github.com/so1ve)",
5
5
  "type": "module",
6
6
  "description": "Clerc plugin help",
@@ -51,9 +51,10 @@
51
51
  "yoctocolors": "^2.1.2"
52
52
  },
53
53
  "devDependencies": {
54
- "@clerc/core": "1.0.0-beta.12",
55
- "@clerc/utils": "1.0.0-beta.12",
56
- "@clerc/parser": "1.0.0-beta.12"
54
+ "kons": "^0.7.1",
55
+ "@clerc/core": "1.0.0-beta.14",
56
+ "@clerc/utils": "1.0.0-beta.14",
57
+ "@clerc/parser": "1.0.0-beta.14"
57
58
  },
58
59
  "peerDependencies": {
59
60
  "@clerc/core": "*"