gunshi 0.17.0 → 0.19.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.
@@ -1,6 +1,6 @@
1
- import { COMMAND_OPTIONS_DEFAULT, COMMON_OPTIONS, create, resolveLazyCommand } from "./utils-BYPzZy9X.js";
2
- import { createCommandContext } from "./context-BROXRnNP.js";
3
- import { renderHeader, renderUsage, renderValidationErrors } from "./renderer-pNEj3FtQ.js";
1
+ import { COMMAND_OPTIONS_DEFAULT, COMMON_ARGS, create, resolveLazyCommand } from "./utils-DWRmOGGa.js";
2
+ import { createCommandContext } from "./context-CBDAvGDh.js";
3
+ import { renderHeader, renderUsage, renderValidationErrors } from "./renderer-BDs5T_Z4.js";
4
4
  import { parseArgs, resolveArgs } from "args-tokens";
5
5
 
6
6
  //#region src/cli.ts
@@ -11,21 +11,24 @@ import { parseArgs, resolveArgs } from "args-tokens";
11
11
  * @param opts A {@link CommandOptions | command options}
12
12
  * @returns A rendered usage or undefined. if you will use {@link CommandOptions.usageSilent} option, it will return rendered usage string.
13
13
  */
14
- async function cli(args, entry, opts = {}) {
15
- const tokens = parseArgs(args);
14
+ async function cli(argv, entry, opts = {}) {
15
+ const tokens = parseArgs(argv);
16
16
  const subCommand = getSubCommand(tokens);
17
17
  const resolvedCommandOptions = resolveCommandOptions(opts, entry);
18
- const [name, command] = await resolveCommand(subCommand, entry, resolvedCommandOptions);
18
+ const [name, command] = await resolveCommand(subCommand, entry, resolvedCommandOptions, true);
19
19
  if (!command) throw new Error(`Command not found: ${name || ""}`);
20
- const options = resolveArgOptions(command.options);
21
- const { values, positionals, rest, error } = resolveArgs(options, tokens, { optionGrouping: true });
20
+ const args = resolveArguments(command.args);
21
+ const { values, positionals, rest, error } = resolveArgs(args, tokens, {
22
+ optionGrouping: true,
23
+ skipPositional: resolvedCommandOptions.subCommands.size > 0 ? 0 : -1
24
+ });
22
25
  const omitted = !subCommand;
23
26
  const ctx = await createCommandContext({
24
- options,
27
+ args,
25
28
  values,
26
29
  positionals,
27
30
  rest,
28
- args,
31
+ argv,
29
32
  tokens,
30
33
  omitted,
31
34
  command,
@@ -47,10 +50,11 @@ async function cli(args, entry, opts = {}) {
47
50
  await showValidationErrors(ctx, error);
48
51
  return;
49
52
  }
53
+ if (!command.run) throw new Error(`'run' not found on Command \`${name || ""}\``);
50
54
  await command.run(ctx);
51
55
  }
52
- function resolveArgOptions(options) {
53
- return Object.assign(create(), options, COMMON_OPTIONS);
56
+ function resolveArguments(options) {
57
+ return Object.assign(create(), options, COMMON_ARGS);
54
58
  }
55
59
  function resolveCommandOptions(options, entry) {
56
60
  const subCommands = new Map(options.subCommands);
@@ -87,15 +91,15 @@ async function showValidationErrors(ctx, error) {
87
91
  const render = ctx.env.renderValidationErrors || renderValidationErrors;
88
92
  ctx.log(await render(ctx, error));
89
93
  }
90
- async function resolveCommand(sub, entry, options) {
94
+ async function resolveCommand(sub, entry, options, needRunResolving = false) {
91
95
  const omitted = !sub;
92
96
  if (typeof entry === "function") return [void 0, { run: entry }];
93
- else if (omitted) return typeof entry === "object" ? [resolveEntryName(entry), await resolveLazyCommand(entry)] : [void 0, void 0];
97
+ else if (omitted) return typeof entry === "object" ? [resolveEntryName(entry), await resolveLazyCommand(entry, "", needRunResolving)] : [void 0, void 0];
94
98
  else {
95
- if (options.subCommands == null || options.subCommands.size === 0) return [resolveEntryName(entry), await resolveLazyCommand(entry)];
99
+ if (options.subCommands == null || options.subCommands.size === 0) return [resolveEntryName(entry), await resolveLazyCommand(entry, "", needRunResolving)];
96
100
  const cmd = options.subCommands?.get(sub);
97
101
  if (cmd == null) return [sub, void 0];
98
- return [sub, await resolveLazyCommand(cmd, sub)];
102
+ return [sub, await resolveLazyCommand(cmd, sub, needRunResolving)];
99
103
  }
100
104
  }
101
105
  function resolveEntryName(entry) {
@@ -1,14 +1,17 @@
1
- import { BUILT_IN_PREFIX, COMMAND_OPTIONS_DEFAULT, DEFAULT_LOCALE$1 as DEFAULT_LOCALE, NOOP, create, deepFreeze, log, mapResourceWithBuiltinKey, resolveLazyCommand, resolveOptionKey } from "./utils-BYPzZy9X.js";
1
+ import { BUILT_IN_PREFIX, COMMAND_OPTIONS_DEFAULT, DEFAULT_LOCALE$1 as DEFAULT_LOCALE, NOOP, create, deepFreeze, log, mapResourceWithBuiltinKey, resolveArgKey, resolveLazyCommand } from "./utils-DWRmOGGa.js";
2
2
 
3
3
  //#region src/locales/en-US.json
4
4
  var COMMAND = "COMMAND";
5
5
  var COMMANDS = "COMMANDS";
6
6
  var SUBCOMMAND = "SUBCOMMAND";
7
7
  var USAGE = "USAGE";
8
+ var ARGUMENTS = "ARGUMENTS";
8
9
  var OPTIONS = "OPTIONS";
9
10
  var EXAMPLES = "EXAMPLES";
10
11
  var FORMORE = "For more info, run any command with the `--help` flag:";
11
12
  var NEGATABLE = "Negatable of";
13
+ var DEFAULT = "default";
14
+ var CHOICES = "choices";
12
15
  var help = "Display this help message";
13
16
  var version = "Display this version";
14
17
  var en_US_default = {
@@ -16,10 +19,13 @@ var en_US_default = {
16
19
  COMMANDS,
17
20
  SUBCOMMAND,
18
21
  USAGE,
22
+ ARGUMENTS,
19
23
  OPTIONS,
20
24
  EXAMPLES,
21
25
  FORMORE,
22
26
  NEGATABLE,
27
+ DEFAULT,
28
+ CHOICES,
23
29
  help,
24
30
  version
25
31
  };
@@ -66,11 +72,11 @@ const BUILT_IN_PREFIX_CODE = BUILT_IN_PREFIX.codePointAt(0);
66
72
  * @param param A {@link CommandContextParams | parameters} to create a {@link CommandContext | command context}
67
73
  * @returns A {@link CommandContext | command context}, which is readonly
68
74
  */
69
- async function createCommandContext({ options, values, positionals, rest, args, tokens, command, commandOptions, omitted = false }) {
75
+ async function createCommandContext({ args, values, positionals, rest, argv, tokens, command, commandOptions, omitted = false }) {
70
76
  /**
71
77
  * normailize the options schema and values, to avoid prototype pollution
72
78
  */
73
- const _options = Object.entries(options).reduce((acc, [key, value]) => {
79
+ const _args = Object.entries(args).reduce((acc, [key, value]) => {
74
80
  acc[key] = Object.assign(create(), value);
75
81
  return acc;
76
82
  }, create());
@@ -124,11 +130,11 @@ async function createCommandContext({ options, values, positionals, rest, args,
124
130
  omitted,
125
131
  locale,
126
132
  env,
127
- options: _options,
133
+ args: _args,
128
134
  values,
129
135
  positionals,
130
136
  rest,
131
- _: args,
137
+ _: argv,
132
138
  tokens,
133
139
  log: commandOptions.usageSilent ? NOOP : log,
134
140
  loadCommands,
@@ -137,12 +143,12 @@ async function createCommandContext({ options, values, positionals, rest, args,
137
143
  /**
138
144
  * load the command resources
139
145
  */
140
- const loadedOptionsResources = Object.entries(options).map(([key, option]) => {
141
- const description = option.description || "";
146
+ const loadedOptionsResources = Object.entries(args).map(([key, arg]) => {
147
+ const description = arg.description || "";
142
148
  return [key, description];
143
149
  });
144
150
  const defaultCommandResource = loadedOptionsResources.reduce((res, [key, value]) => {
145
- res[resolveOptionKey(key)] = value;
151
+ res[resolveArgKey(key)] = value;
146
152
  return res;
147
153
  }, create());
148
154
  defaultCommandResource.description = command.description || "";
package/lib/context.d.ts CHANGED
@@ -1,20 +1,23 @@
1
- import { Command, CommandContext, CommandOptions } from "./types.d-DomXJWKH.js";
2
- import { ArgOptions, ArgToken, ArgValues } from "args-tokens";
1
+ import { Command, CommandContext, CommandOptions } from "./types-BVZKXMbJ.js";
2
+ import { ArgToken, ArgValues, Args } from "args-tokens";
3
3
 
4
4
  //#region src/context.d.ts
5
5
  /**
6
6
  * Parameters of {@link createCommandContext}
7
7
  */
8
8
 
9
- interface CommandContextParams<Options extends ArgOptions, Values> {
9
+ /**
10
+ * Parameters of {@link createCommandContext}
11
+ */
12
+ interface CommandContextParams<A extends Args, V> {
10
13
  /**
11
- * An options of target command
14
+ * An arguments of target command
12
15
  */
13
- options: Options;
16
+ args: A;
14
17
  /**
15
18
  * A values of target command
16
19
  */
17
- values: Values;
20
+ values: V;
18
21
  /**
19
22
  * A positionals arguments, which passed to the target command
20
23
  */
@@ -26,7 +29,7 @@ interface CommandContextParams<Options extends ArgOptions, Values> {
26
29
  /**
27
30
  * Original command line arguments
28
31
  */
29
- args: string[];
32
+ argv: string[];
30
33
  /**
31
34
  * Argument tokens that are parsed by the `parseArgs` function
32
35
  */
@@ -38,26 +41,26 @@ interface CommandContextParams<Options extends ArgOptions, Values> {
38
41
  /**
39
42
  * A target {@link Command | command}
40
43
  */
41
- command: Command<Options>;
44
+ command: Command<A>;
42
45
  /**
43
46
  * A command options, which is spicialized from `cli` function
44
47
  */
45
- commandOptions: CommandOptions<Options>;
46
- } /**
47
- * Create a {@link CommandContext | command context}
48
- * @param param A {@link CommandContextParams | parameters} to create a {@link CommandContext | command context}
49
- * @returns A {@link CommandContext | command context}, which is readonly
50
- */
51
-
52
- declare function createCommandContext<Options extends ArgOptions = ArgOptions, Values extends ArgValues<Options> = ArgValues<Options>>({
53
- options,
48
+ commandOptions: CommandOptions<A>;
49
+ }
50
+ /**
51
+ * Create a {@link CommandContext | command context}
52
+ * @param param A {@link CommandContextParams | parameters} to create a {@link CommandContext | command context}
53
+ * @returns A {@link CommandContext | command context}, which is readonly
54
+ */
55
+ declare function createCommandContext<A extends Args = Args, V extends ArgValues<A> = ArgValues<A>>({
56
+ args,
54
57
  values,
55
58
  positionals,
56
59
  rest,
57
- args,
60
+ argv,
58
61
  tokens,
59
62
  command,
60
63
  commandOptions,
61
64
  omitted
62
- }: CommandContextParams<Options, Values>): Promise<Readonly<CommandContext<Options, Values>>>; //#endregion
65
+ }: CommandContextParams<A, V>): Promise<Readonly<CommandContext<A, V>>>; //#endregion
63
66
  export { createCommandContext };
package/lib/context.js CHANGED
@@ -1,4 +1,4 @@
1
- import "./utils-BYPzZy9X.js";
2
- import { createCommandContext } from "./context-BROXRnNP.js";
1
+ import "./utils-DWRmOGGa.js";
2
+ import { createCommandContext } from "./context-CBDAvGDh.js";
3
3
 
4
4
  export { createCommandContext };
@@ -0,0 +1,26 @@
1
+ import { Command, CommandLoader, LazyCommand } from "./types-BVZKXMbJ.js";
2
+ import { ArgSchema, ArgValues as ArgValues$1, Args, Args as Args$1 } from "args-tokens";
3
+
4
+ //#region src/definition.d.ts
5
+ /**
6
+ * Define a {@link Command | command} with type inference
7
+ * @param definition A {@link Command | command} definition
8
+ * @returns A {@link Command | command} definition with type inference
9
+ */
10
+
11
+ /**
12
+ * Define a {@link Command | command} with type inference
13
+ * @param definition A {@link Command | command} definition
14
+ * @returns A {@link Command | command} definition with type inference
15
+ */
16
+ declare function define<A extends Args = Args>(definition: Command<A>): Command<A>;
17
+ /**
18
+ * Define a {@link LazyCommand | lazy command} with command loader, which is attached with command definition as usage metadata.
19
+ * @param loader A {@link CommandLoader | command loader}
20
+ * @param definition A {@link Command | command} definition
21
+ * @returns A {@link LazyCommand | lazy command} loader
22
+ */
23
+ declare function lazy<A extends Args = Args>(loader: CommandLoader<A>, definition?: Command<A>): LazyCommand<A>;
24
+
25
+ //#endregion
26
+ export { ArgSchema, ArgValues$1 as ArgValues, Args$1 as Args, define as define$1, lazy as lazy$1 };
@@ -0,0 +1,28 @@
1
+ //#region src/definition.ts
2
+ /**
3
+ * Define a {@link Command | command} with type inference
4
+ * @param definition A {@link Command | command} definition
5
+ * @returns A {@link Command | command} definition with type inference
6
+ */
7
+ function define(definition) {
8
+ return definition;
9
+ }
10
+ /**
11
+ * Define a {@link LazyCommand | lazy command} with command loader, which is attached with command definition as usage metadata.
12
+ * @param loader A {@link CommandLoader | command loader}
13
+ * @param definition A {@link Command | command} definition
14
+ * @returns A {@link LazyCommand | lazy command} loader
15
+ */
16
+ function lazy(loader, definition) {
17
+ if (definition != null) {
18
+ loader.commandName = definition.name;
19
+ loader.description = definition.description;
20
+ loader.args = definition.args;
21
+ loader.examples = definition.examples;
22
+ loader.resource = definition.resource;
23
+ }
24
+ return loader;
25
+ }
26
+
27
+ //#endregion
28
+ export { define, lazy };
@@ -1,3 +1,3 @@
1
- import "./types.d-DomXJWKH.js";
2
- import { ArgOptionSchema, ArgOptions, ArgValues, define$1 as define } from "./definition.d-wYlroF3H.js";
3
- export { ArgOptionSchema, ArgOptions, ArgValues, define };
1
+ import "./types-BVZKXMbJ.js";
2
+ import { ArgSchema, ArgValues, Args, define$1 as define, lazy$1 as lazy } from "./definition-Bdw7cMea.js";
3
+ export { ArgSchema, ArgValues, Args, define, lazy };
package/lib/definition.js CHANGED
@@ -1,3 +1,3 @@
1
- import { define } from "./definition-VzcnM0si.js";
1
+ import { define, lazy } from "./definition-DyVBFqB7.js";
2
2
 
3
- export { define };
3
+ export { define, lazy };
@@ -1,5 +1,5 @@
1
- import { Command, CommandOptions } from "./types.d-DomXJWKH.js";
2
- import { ArgOptions } from "args-tokens";
1
+ import { Command, CommandOptions } from "./types-BVZKXMbJ.js";
2
+ import { Args } from "args-tokens";
3
3
 
4
4
  //#region src/generator.d.ts
5
5
  /**
@@ -10,7 +10,14 @@ import { ArgOptions } from "args-tokens";
10
10
  * @returns A rendered usage.
11
11
  */
12
12
 
13
- declare function generate<Options extends ArgOptions = ArgOptions>(command: string | null, entry: Command<Options>, opts?: CommandOptions<Options>): Promise<string>;
13
+ /**
14
+ * Generate the command usage.
15
+ * @param command - usage generate command, if you want to generate the usage of the default command where there are target commands and sub-commands, specify `null`.
16
+ * @param entry - A {@link Command | entry command}
17
+ * @param opts - A {@link CommandOptions | command options}
18
+ * @returns A rendered usage.
19
+ */
20
+ declare function generate<A extends Args = Args>(command: string | null, entry: Command<A>, opts?: CommandOptions<A>): Promise<string>;
14
21
 
15
22
  //#endregion
16
23
  export { generate };
package/lib/generator.js CHANGED
@@ -1,7 +1,7 @@
1
- import { create } from "./utils-BYPzZy9X.js";
2
- import "./context-BROXRnNP.js";
3
- import "./renderer-pNEj3FtQ.js";
4
- import { cli } from "./cli-D2dWSSRj.js";
1
+ import { create } from "./utils-DWRmOGGa.js";
2
+ import "./context-CBDAvGDh.js";
3
+ import "./renderer-BDs5T_Z4.js";
4
+ import { cli } from "./cli-m93bHwFR.js";
5
5
 
6
6
  //#region src/generator.ts
7
7
  /**
package/lib/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { Command, CommandBuiltinKeys, CommandBuiltinOptionsKeys, CommandBuiltinResourceKeys, CommandContext, CommandEnvironment, CommandOptionKeys, CommandOptions, CommandResource, CommandResourceFetcher, CommandRunner, Commandable, DEFAULT_LOCALE, GenerateNamespacedKey, KeyOfArgOptions, LazyCommand, RemovedIndex, TranslationAdapter, TranslationAdapterFactory, TranslationAdapterFactoryOptions } from "./types.d-DomXJWKH.js";
2
- import { define$1 as define } from "./definition.d-wYlroF3H.js";
3
- import { ArgOptionSchema, ArgOptions, ArgOptions as ArgOptions$1, ArgValues, parseArgs, resolveArgs } from "args-tokens";
1
+ import { Command, CommandArgKeys, CommandBuiltinArgsKeys, CommandBuiltinKeys, CommandBuiltinResourceKeys, CommandContext, CommandEnvironment, CommandLoader, CommandOptions, CommandResource, CommandResourceFetcher, CommandRunner, Commandable, DEFAULT_LOCALE, GenerateNamespacedKey, KeyOfArgs, LazyCommand, RemovedIndex, TranslationAdapter, TranslationAdapterFactory, TranslationAdapterFactoryOptions } from "./types-BVZKXMbJ.js";
2
+ import { define$1 as define, lazy$1 as lazy } from "./definition-Bdw7cMea.js";
3
+ import { ArgSchema, ArgValues, Args, Args as Args$1, parseArgs, resolveArgs } from "args-tokens";
4
4
 
5
5
  //#region src/cli.d.ts
6
6
  /**
@@ -11,7 +11,14 @@ import { ArgOptionSchema, ArgOptions, ArgOptions as ArgOptions$1, ArgValues, par
11
11
  * @returns A rendered usage or undefined. if you will use {@link CommandOptions.usageSilent} option, it will return rendered usage string.
12
12
  */
13
13
 
14
- declare function cli<Options extends ArgOptions$1 = ArgOptions$1>(args: string[], entry: Command<Options> | CommandRunner<Options>, opts?: CommandOptions<Options>): Promise<string | undefined>;
14
+ /**
15
+ * Run the command.
16
+ * @param args Command line arguments
17
+ * @param entry A {@link Command | entry command} or an {@link CommandRunner | inline command runner}
18
+ * @param opts A {@link CommandOptions | command options}
19
+ * @returns A rendered usage or undefined. if you will use {@link CommandOptions.usageSilent} option, it will return rendered usage string.
20
+ */
21
+ declare function cli<A extends Args$1 = Args$1>(argv: string[], entry: Command<A> | CommandRunner<A>, opts?: CommandOptions<A>): Promise<string | undefined>;
15
22
 
16
23
  //#endregion
17
24
  //#region src/translation.d.ts
@@ -25,4 +32,4 @@ declare class DefaultTranslation implements TranslationAdapter {
25
32
  }
26
33
 
27
34
  //#endregion
28
- export { ArgOptionSchema, ArgOptions, ArgValues, Command, CommandBuiltinKeys, CommandBuiltinOptionsKeys, CommandBuiltinResourceKeys, CommandContext, CommandEnvironment, CommandOptionKeys, CommandOptions, CommandResource, CommandResourceFetcher, CommandRunner, Commandable, DEFAULT_LOCALE, DefaultTranslation, GenerateNamespacedKey, KeyOfArgOptions, LazyCommand, RemovedIndex, TranslationAdapter, TranslationAdapterFactory, TranslationAdapterFactoryOptions, cli, define, parseArgs, resolveArgs };
35
+ export { ArgSchema, ArgValues, Args, Command, CommandArgKeys, CommandBuiltinArgsKeys, CommandBuiltinKeys, CommandBuiltinResourceKeys, CommandContext, CommandEnvironment, CommandLoader, CommandOptions, CommandResource, CommandResourceFetcher, CommandRunner, Commandable, DEFAULT_LOCALE, DefaultTranslation, GenerateNamespacedKey, KeyOfArgs, LazyCommand, RemovedIndex, TranslationAdapter, TranslationAdapterFactory, TranslationAdapterFactoryOptions, cli, define, lazy, parseArgs, resolveArgs };
package/lib/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { DEFAULT_LOCALE$1 as DEFAULT_LOCALE } from "./utils-BYPzZy9X.js";
2
- import { DefaultTranslation } from "./context-BROXRnNP.js";
3
- import { define } from "./definition-VzcnM0si.js";
4
- import "./renderer-pNEj3FtQ.js";
5
- import { cli } from "./cli-D2dWSSRj.js";
1
+ import { DEFAULT_LOCALE$1 as DEFAULT_LOCALE } from "./utils-DWRmOGGa.js";
2
+ import { DefaultTranslation } from "./context-CBDAvGDh.js";
3
+ import { define, lazy } from "./definition-DyVBFqB7.js";
4
+ import "./renderer-BDs5T_Z4.js";
5
+ import { cli } from "./cli-m93bHwFR.js";
6
6
  import { parseArgs, resolveArgs } from "args-tokens";
7
7
 
8
- export { DEFAULT_LOCALE, DefaultTranslation, cli, define, parseArgs, resolveArgs };
8
+ export { DEFAULT_LOCALE, DefaultTranslation, cli, define, lazy, parseArgs, resolveArgs };
@@ -3,10 +3,13 @@
3
3
  "COMMANDS": "COMMANDS",
4
4
  "SUBCOMMAND": "SUBCOMMAND",
5
5
  "USAGE": "USAGE",
6
+ "ARGUMENTS": "ARGUMENTS",
6
7
  "OPTIONS": "OPTIONS",
7
8
  "EXAMPLES": "EXAMPLES",
8
9
  "FORMORE": "For more info, run any command with the `--help` flag:",
9
10
  "NEGATABLE": "Negatable of",
11
+ "DEFAULT": "default",
12
+ "CHOICES": "choices",
10
13
  "help": "Display this help message",
11
14
  "version": "Display this version"
12
15
  }
@@ -3,10 +3,13 @@
3
3
  "COMMANDS": "コマンド",
4
4
  "SUBCOMMAND": "サブコマンド",
5
5
  "USAGE": "使い方",
6
+ "ARGUMENTS": "引数",
6
7
  "OPTIONS": "オプション",
7
8
  "EXAMPLES": "例",
8
9
  "FORMORE": "詳細は、コマンドと`--help`フラグを実行してください:",
9
10
  "NEGATABLE": "否定可能な",
11
+ "DEFAULT": "デフォルト",
12
+ "CHOICES": "選択肢",
10
13
  "help": "このヘルプメッセージを表示",
11
14
  "version": "このバージョンを表示"
12
15
  }
@@ -1,4 +1,4 @@
1
- import { create, resolveBuiltInKey, resolveOptionKey } from "./utils-BYPzZy9X.js";
1
+ import { COMMON_ARGS, create, resolveArgKey, resolveBuiltInKey } from "./utils-DWRmOGGa.js";
2
2
 
3
3
  //#region src/renderer/header.ts
4
4
  /**
@@ -13,6 +13,7 @@ function renderHeader(ctx) {
13
13
 
14
14
  //#endregion
15
15
  //#region src/renderer/usage.ts
16
+ const COMMON_ARGS_KEYS = Object.keys(COMMON_ARGS);
16
17
  /**
17
18
  * Render the usage.
18
19
  * @param ctx A {@link CommandContext | command context}
@@ -26,20 +27,32 @@ async function renderUsage(ctx) {
26
27
  }
27
28
  messages.push(...await renderUsageSection(ctx), "");
28
29
  if (ctx.omitted && await hasCommands(ctx)) messages.push(...await renderCommandsSection(ctx), "");
29
- if (hasOptions(ctx)) messages.push(...await renderOptionsSection(ctx), "");
30
+ if (hasPositionalArgs(ctx)) messages.push(...await renderPositionalArgsSection(ctx), "");
31
+ if (hasOptionalArgs(ctx)) messages.push(...await renderOptionalArgsSection(ctx), "");
30
32
  const examples = renderExamplesSection(ctx);
31
33
  if (examples.length > 0) messages.push(...examples, "");
32
34
  return messages.join("\n");
33
35
  }
34
36
  /**
35
- * Render the options section
37
+ * Render the positional arguments section
38
+ * @param ctx A {@link CommandContext | command context}
39
+ * @returns A rendered arguments section
40
+ */
41
+ async function renderPositionalArgsSection(ctx) {
42
+ const messages = [];
43
+ messages.push(`${ctx.translate(resolveBuiltInKey("ARGUMENTS"))}:`);
44
+ messages.push(await generatePositionalArgsUsage(ctx));
45
+ return messages;
46
+ }
47
+ /**
48
+ * Render the optional arguments section
36
49
  * @param ctx A {@link CommandContext | command context}
37
50
  * @returns A rendered options section
38
51
  */
39
- async function renderOptionsSection(ctx) {
52
+ async function renderOptionalArgsSection(ctx) {
40
53
  const messages = [];
41
54
  messages.push(`${ctx.translate(resolveBuiltInKey("OPTIONS"))}:`);
42
- messages.push(await generateOptionsUsage(ctx, getOptionsPairs(ctx)));
55
+ messages.push(await generateOptionalArgsUsage(ctx, getOptionalArgsPairs(ctx)));
43
56
  return messages;
44
57
  }
45
58
  /**
@@ -64,14 +77,14 @@ function renderExamplesSection(ctx) {
64
77
  async function renderUsageSection(ctx) {
65
78
  const messages = [`${ctx.translate(resolveBuiltInKey("USAGE"))}:`];
66
79
  if (ctx.omitted) {
67
- const defaultCommand = `${resolveEntry(ctx)}${await hasCommands(ctx) ? ` [${resolveSubCommand(ctx)}]` : ""} ${hasOptions(ctx) ? `<${ctx.translate(resolveBuiltInKey("OPTIONS"))}>` : ""} `;
80
+ const defaultCommand = `${resolveEntry(ctx)}${await hasCommands(ctx) ? ` [${resolveSubCommand(ctx)}]` : ""} ${[generateOptionsSymbols(ctx), generatePositionalSymbols(ctx)].filter(Boolean).join(" ")}`;
68
81
  messages.push(defaultCommand.padStart(ctx.env.leftMargin + defaultCommand.length));
69
82
  if (await hasCommands(ctx)) {
70
83
  const commandsUsage = `${resolveEntry(ctx)} <${ctx.translate(resolveBuiltInKey("COMMANDS"))}>`;
71
84
  messages.push(commandsUsage.padStart(ctx.env.leftMargin + commandsUsage.length));
72
85
  }
73
86
  } else {
74
- const usageStr = `${resolveEntry(ctx)} ${resolveSubCommand(ctx)} ${generateOptionsSymbols(ctx)}`;
87
+ const usageStr = `${resolveEntry(ctx)} ${resolveSubCommand(ctx)} ${[generateOptionsSymbols(ctx), generatePositionalSymbols(ctx)].filter(Boolean).join(" ")}`;
75
88
  messages.push(usageStr.padStart(ctx.env.leftMargin + usageStr.length));
76
89
  }
77
90
  return messages;
@@ -143,12 +156,20 @@ async function hasCommands(ctx) {
143
156
  return loadedCommands.length > 1;
144
157
  }
145
158
  /**
146
- * Check if the command has options
159
+ * Check if the command has optional arguments
147
160
  * @param ctx A {@link CommandContext | command context}
148
161
  * @returns True if the command has options
149
162
  */
150
- function hasOptions(ctx) {
151
- return !!(ctx.options && Object.keys(ctx.options).length > 0);
163
+ function hasOptionalArgs(ctx) {
164
+ return !!(ctx.args && Object.values(ctx.args).some((arg) => arg.type !== "positional"));
165
+ }
166
+ /**
167
+ * Check if the command has positional arguments
168
+ * @param ctx A {@link CommandContext | command context}
169
+ * @returns True if the command has options
170
+ */
171
+ function hasPositionalArgs(ctx) {
172
+ return !!(ctx.args && Object.values(ctx.args).some((arg) => arg.type === "positional"));
152
173
  }
153
174
  /**
154
175
  * Check if all options have default values
@@ -156,7 +177,7 @@ function hasOptions(ctx) {
156
177
  * @returns True if all options have default values
157
178
  */
158
179
  function hasAllDefaultOptions(ctx) {
159
- return !!(ctx.options && Object.values(ctx.options).every((opt) => opt.default));
180
+ return !!(ctx.args && Object.values(ctx.args).every((arg) => arg.default));
160
181
  }
161
182
  /**
162
183
  * Generate options symbols for usage
@@ -164,7 +185,7 @@ function hasAllDefaultOptions(ctx) {
164
185
  * @returns Options symbols for usage
165
186
  */
166
187
  function generateOptionsSymbols(ctx) {
167
- return hasOptions(ctx) ? hasAllDefaultOptions(ctx) ? `[${ctx.translate(resolveBuiltInKey("OPTIONS"))}]` : `<${ctx.translate(resolveBuiltInKey("OPTIONS"))}>` : "";
188
+ return hasOptionalArgs(ctx) ? hasAllDefaultOptions(ctx) ? `[${ctx.translate(resolveBuiltInKey("OPTIONS"))}]` : `<${ctx.translate(resolveBuiltInKey("OPTIONS"))}>` : "";
168
189
  }
169
190
  function makeShortLongOptionPair(schema, name) {
170
191
  let key = `--${name}`;
@@ -172,47 +193,79 @@ function makeShortLongOptionPair(schema, name) {
172
193
  return key;
173
194
  }
174
195
  /**
175
- * Get options pairs for usage
196
+ * Get optional arguments pairs for usage
176
197
  * @param ctx A {@link CommandContext | command context}
177
198
  * @returns Options pairs for usage
178
199
  */
179
- function getOptionsPairs(ctx) {
180
- return Object.entries(ctx.options).reduce((acc, [name, value]) => {
200
+ function getOptionalArgsPairs(ctx) {
201
+ return Object.entries(ctx.args).reduce((acc, [name, value]) => {
202
+ if (value.type === "positional") return acc;
181
203
  let key = makeShortLongOptionPair(value, name);
182
204
  if (value.type !== "boolean") key = value.default ? `${key} [${name}]` : `${key} <${name}>`;
183
205
  acc[name] = key;
184
- if (value.type === "boolean" && value.negatable && !(name === "help" || name === "version")) acc[`no-${name}`] = `--no-${name}`;
206
+ if (value.type === "boolean" && value.negatable && !COMMON_ARGS_KEYS.includes(name)) acc[`no-${name}`] = `--no-${name}`;
185
207
  return acc;
186
208
  }, create());
187
209
  }
188
210
  const resolveNegatableKey = (key) => key.split("no-")[1];
189
211
  function resolveNegatableType(key, ctx) {
190
- return ctx.options[key.startsWith("no-") ? resolveNegatableKey(key) : key].type;
212
+ return ctx.args[key.startsWith("no-") ? resolveNegatableKey(key) : key].type;
213
+ }
214
+ function generateDefaultDisplayValue(ctx, schema) {
215
+ return `${ctx.translate(resolveBuiltInKey("DEFAULT"))}: ${schema.default}`;
216
+ }
217
+ function resolveDisplayValue(ctx, key) {
218
+ if (COMMON_ARGS_KEYS.includes(key)) return "";
219
+ const schema = ctx.args[key];
220
+ if ((schema.type === "boolean" || schema.type === "number" || schema.type === "string") && schema.default !== void 0) return `(${generateDefaultDisplayValue(ctx, schema)})`;
221
+ if (schema.type === "enum") {
222
+ const _default = schema.default !== void 0 ? generateDefaultDisplayValue(ctx, schema) : "";
223
+ const choices = `${ctx.translate(resolveBuiltInKey("CHOICES"))}: ${schema.choices.join(" | ")}`;
224
+ return `(${_default ? `${_default}, ${choices}` : choices})`;
225
+ }
226
+ return "";
191
227
  }
192
228
  /**
193
- * Generate options usage
229
+ * Generate optional arguments usage
194
230
  * @param ctx A {@link CommandContext | command context}
195
231
  * @param optionsPairs Options pairs for usage
196
232
  * @returns Generated options usage
197
233
  */
198
- async function generateOptionsUsage(ctx, optionsPairs) {
234
+ async function generateOptionalArgsUsage(ctx, optionsPairs) {
199
235
  const optionsMaxLength = Math.max(...Object.entries(optionsPairs).map(([_, value]) => value.length));
200
- const optionSchemaMaxLength = ctx.env.usageOptionType ? Math.max(...Object.entries(optionsPairs).map(([key, _]) => resolveNegatableType(key, ctx).length)) : 0;
236
+ const optionSchemaMaxLength = ctx.env.usageOptionType ? Math.max(...Object.entries(optionsPairs).map(([key]) => resolveNegatableType(key, ctx).length)) : 0;
201
237
  const usages = await Promise.all(Object.entries(optionsPairs).map(([key, value]) => {
202
- let rawDesc = ctx.translate(resolveOptionKey(key));
238
+ let rawDesc = ctx.translate(resolveArgKey(key));
203
239
  if (!rawDesc && key.startsWith("no-")) {
204
240
  const name = resolveNegatableKey(key);
205
- const schema = ctx.options[name];
241
+ const schema = ctx.args[name];
206
242
  const optionKey = makeShortLongOptionPair(schema, name);
207
243
  rawDesc = `${ctx.translate(resolveBuiltInKey("NEGATABLE"))} ${optionKey}`;
208
244
  }
209
245
  const optionsSchema = ctx.env.usageOptionType ? `[${resolveNegatableType(key, ctx)}] ` : "";
246
+ const valueDesc = key.startsWith("no-") ? "" : resolveDisplayValue(ctx, key);
210
247
  const desc = `${optionsSchema ? optionsSchema.padEnd(optionSchemaMaxLength + 3) : ""}${rawDesc}`;
211
- const option = `${value.padEnd(optionsMaxLength + ctx.env.middleMargin)}${desc}`;
248
+ const option = `${value.padEnd(optionsMaxLength + ctx.env.middleMargin)}${desc}${valueDesc ? ` ${valueDesc}` : ""}`;
212
249
  return `${option.padStart(ctx.env.leftMargin + option.length)}`;
213
250
  }));
214
251
  return usages.join("\n");
215
252
  }
253
+ function getPositionalArgs(ctx) {
254
+ return Object.entries(ctx.args).filter(([_, schema]) => schema.type === "positional");
255
+ }
256
+ async function generatePositionalArgsUsage(ctx) {
257
+ const positionals = getPositionalArgs(ctx);
258
+ const argsMaxLength = Math.max(...positionals.map(([name]) => name.length));
259
+ const usages = await Promise.all(positionals.map(([name]) => {
260
+ const desc = ctx.translate(resolveArgKey(name)) || ctx.args[name].description || "";
261
+ const arg = `${name.padEnd(argsMaxLength + ctx.env.middleMargin)} ${desc}`;
262
+ return `${arg.padStart(ctx.env.leftMargin + arg.length)}`;
263
+ }));
264
+ return usages.join("\n");
265
+ }
266
+ function generatePositionalSymbols(ctx) {
267
+ return hasPositionalArgs(ctx) ? getPositionalArgs(ctx).map(([name]) => `<${name}>`).join(" ") : "";
268
+ }
216
269
 
217
270
  //#endregion
218
271
  //#region src/renderer/validation.ts
package/lib/renderer.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { CommandContext } from "./types.d-DomXJWKH.js";
2
- import { ArgOptions } from "args-tokens";
1
+ import { CommandContext } from "./types-BVZKXMbJ.js";
2
+ import { Args } from "args-tokens";
3
3
 
4
4
  //#region src/renderer/header.d.ts
5
5
  /**
@@ -8,26 +8,31 @@ import { ArgOptions } from "args-tokens";
8
8
  * @returns A rendered header.
9
9
  */
10
10
 
11
- declare function renderHeader<Options extends ArgOptions = ArgOptions>(ctx: Readonly<CommandContext<Options>>): Promise<string>;
11
+ /**
12
+ * Render the header.
13
+ * @param ctx A {@link CommandContext | command context}
14
+ * @returns A rendered header.
15
+ */
16
+ declare function renderHeader<A extends Args = Args>(ctx: Readonly<CommandContext<A>>): Promise<string>;
12
17
 
13
18
  //#endregion
14
19
  //#region src/renderer/usage.d.ts
15
20
  /**
16
- * Render the usage.
17
- * @param ctx A {@link CommandContext | command context}
18
- * @returns A rendered usage.
19
- */
20
- declare function renderUsage<Options extends ArgOptions = ArgOptions>(ctx: Readonly<CommandContext<Options>>): Promise<string>;
21
+ * Render the usage.
22
+ * @param ctx A {@link CommandContext | command context}
23
+ * @returns A rendered usage.
24
+ */
25
+ declare function renderUsage<A extends Args = Args>(ctx: Readonly<CommandContext<A>>): Promise<string>;
21
26
 
22
27
  //#endregion
23
28
  //#region src/renderer/validation.d.ts
24
29
  /**
25
- * Render the validation errors.
26
- * @param ctx A {@link CommandContext | command context}
27
- * @param error An {@link AggregateError} of option in `args-token` validation
28
- * @returns A rendered validation error.
29
- */
30
- declare function renderValidationErrors<Options extends ArgOptions = ArgOptions>(_ctx: CommandContext<Options>, error: AggregateError): Promise<string>;
30
+ * Render the validation errors.
31
+ * @param ctx A {@link CommandContext | command context}
32
+ * @param error An {@link AggregateError} of option in `args-token` validation
33
+ * @returns A rendered validation error.
34
+ */
35
+ declare function renderValidationErrors<A extends Args = Args>(_ctx: CommandContext<A>, error: AggregateError): Promise<string>;
31
36
 
32
37
  //#endregion
33
38
  export { renderHeader, renderUsage, renderValidationErrors };
package/lib/renderer.js CHANGED
@@ -1,4 +1,4 @@
1
- import "./utils-BYPzZy9X.js";
2
- import { renderHeader, renderUsage, renderValidationErrors } from "./renderer-pNEj3FtQ.js";
1
+ import "./utils-DWRmOGGa.js";
2
+ import { renderHeader, renderUsage, renderValidationErrors } from "./renderer-BDs5T_Z4.js";
3
3
 
4
4
  export { renderHeader, renderUsage, renderValidationErrors };
@@ -1,18 +1,18 @@
1
- import { ArgOptions, ArgToken, ArgValues } from "args-tokens";
1
+ import { ArgToken, ArgValues, Args } from "args-tokens";
2
2
 
3
3
  //#region rolldown:runtime
4
4
  declare namespace constants_d_exports {
5
- export { BUILT_IN_KEY_SEPARATOR, BUILT_IN_PREFIX, COMMAND_BUILTIN_RESOURCE_KEYS, COMMAND_OPTIONS_DEFAULT, COMMON_OPTIONS, DEFAULT_LOCALE, NOOP, OPTION_PREFIX };
5
+ export { ARG_PREFIX, BUILT_IN_KEY_SEPARATOR, BUILT_IN_PREFIX, COMMAND_BUILTIN_RESOURCE_KEYS, COMMAND_OPTIONS_DEFAULT, COMMON_ARGS, DEFAULT_LOCALE, NOOP };
6
6
  }
7
7
  /**
8
- * The default locale string, which format is BCP 47 language tag.
9
- */
8
+ * The default locale string, which format is BCP 47 language tag.
9
+ */
10
10
  declare const DEFAULT_LOCALE = "en-US";
11
11
  declare const BUILT_IN_PREFIX = "_";
12
- declare const OPTION_PREFIX = "Option";
12
+ declare const ARG_PREFIX = "arg";
13
13
  declare const BUILT_IN_KEY_SEPARATOR = ":";
14
14
  declare const NOOP: () => void;
15
- type CommonOptionType = {
15
+ type CommonArgType = {
16
16
  readonly help: {
17
17
  readonly type: 'boolean';
18
18
  readonly short: 'h';
@@ -24,52 +24,45 @@ type CommonOptionType = {
24
24
  readonly description: string;
25
25
  };
26
26
  };
27
- declare const COMMON_OPTIONS: CommonOptionType;
28
- declare const COMMAND_OPTIONS_DEFAULT: CommandOptions<ArgOptions>;
29
- declare const COMMAND_BUILTIN_RESOURCE_KEYS: readonly ["USAGE", "COMMAND", "SUBCOMMAND", "COMMANDS", "OPTIONS", "EXAMPLES", "FORMORE", "NEGATABLE"];
27
+ declare const COMMON_ARGS: CommonArgType;
28
+ declare const COMMAND_OPTIONS_DEFAULT: CommandOptions<Args>;
29
+ declare const COMMAND_BUILTIN_RESOURCE_KEYS: readonly ["USAGE", "COMMAND", "SUBCOMMAND", "COMMANDS", "ARGUMENTS", "OPTIONS", "EXAMPLES", "FORMORE", "NEGATABLE", "DEFAULT", "CHOICES"];
30
30
 
31
31
  //#endregion
32
32
  //#region src/types.d.ts
33
33
  type Awaitable<T> = T | Promise<T>;
34
34
  type RemoveIndexSignature<T> = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K] };
35
-
36
35
  /**
37
- * Remove index signature from object or record type.
38
- */
36
+ * Remove index signature from object or record type.
37
+ */
39
38
  type RemovedIndex<T> = RemoveIndexSignature<{ [K in keyof T]: T[K] }>;
40
- type KeyOfArgOptions<Options extends ArgOptions> = keyof Options | { [K in keyof Options]: Options[K]['type'] extends 'boolean' ? Options[K]['negatable'] extends true ? `no-${Extract<K, string>}` : never : never }[keyof Options];
41
-
39
+ type KeyOfArgs<A extends Args> = keyof A | { [K in keyof A]: A[K]['type'] extends 'boolean' ? A[K]['negatable'] extends true ? `no-${Extract<K, string>}` : never : never }[keyof A];
42
40
  /**
43
- * Generate a namespaced key.
44
- */
41
+ * Generate a namespaced key.
42
+ */
45
43
  type GenerateNamespacedKey<Key extends string, Prefixed extends string = typeof BUILT_IN_PREFIX> = `${Prefixed}${typeof BUILT_IN_KEY_SEPARATOR}${Key}`;
46
-
47
44
  /**
48
- * Command i18n built-in options keys.
49
- */
50
- type CommandBuiltinOptionsKeys = keyof (typeof constants_d_exports)['COMMON_OPTIONS'];
51
-
45
+ * Command i18n built-in arguments keys.
46
+ */
47
+ type CommandBuiltinArgsKeys = keyof (typeof constants_d_exports)['COMMON_ARGS'];
52
48
  /**
53
- * Command i18n built-in resource keys.
54
- */
49
+ * Command i18n built-in resource keys.
50
+ */
55
51
  type CommandBuiltinResourceKeys = (typeof constants_d_exports)['COMMAND_BUILTIN_RESOURCE_KEYS'][number];
56
-
57
52
  /**
58
- * Command i18n built-in keys.
59
- * The command i18n built-in keys are used to {@link CommandContext.translate | translate} function.
60
- */
61
- type CommandBuiltinKeys = GenerateNamespacedKey<CommandBuiltinOptionsKeys> | GenerateNamespacedKey<CommandBuiltinResourceKeys> | 'description' | 'examples';
62
-
53
+ * Command i18n built-in keys.
54
+ * The command i18n built-in keys are used to {@link CommandContext.translate | translate} function.
55
+ */
56
+ type CommandBuiltinKeys = GenerateNamespacedKey<CommandBuiltinArgsKeys> | GenerateNamespacedKey<CommandBuiltinResourceKeys> | 'description' | 'examples';
63
57
  /**
64
- * Command i18n option keys.
65
- * The command i18n option keys are used to {@link CommandContext.translate | translate} function.
66
- */
67
- type CommandOptionKeys<Options extends ArgOptions> = GenerateNamespacedKey<KeyOfArgOptions<RemovedIndex<Options>>, typeof OPTION_PREFIX>;
68
-
58
+ * Command i18n option keys.
59
+ * The command i18n option keys are used to {@link CommandContext.translate | translate} function.
60
+ */
61
+ type CommandArgKeys<A extends Args> = GenerateNamespacedKey<KeyOfArgs<RemovedIndex<A>>, typeof ARG_PREFIX>;
69
62
  /**
70
- * Command environment.
71
- */
72
- interface CommandEnvironment<Options extends ArgOptions = ArgOptions> {
63
+ * Command environment.
64
+ */
65
+ interface CommandEnvironment<A extends Args = Args> {
73
66
  /**
74
67
  * Current working directory.
75
68
  * @see {@link CommandOptions.cwd}
@@ -109,10 +102,16 @@ interface CommandEnvironment<Options extends ArgOptions = ArgOptions> {
109
102
  * @see {@link CommandOptions.usageOptionType}
110
103
  */
111
104
  usageOptionType: boolean;
105
+ /**
106
+ * Whether to display the option value.
107
+ * @default true
108
+ * @see {@link CommandOptions.usageOptionValue}
109
+ */
110
+ usageOptionValue: boolean;
112
111
  /**
113
112
  * Whether to display the command usage.
114
113
  * @default false
115
- * @see {@link}
114
+ * @see {@link CommandOptions.usageSilent}
116
115
  */
117
116
  usageSilent: boolean;
118
117
  /**
@@ -123,21 +122,20 @@ interface CommandEnvironment<Options extends ArgOptions = ArgOptions> {
123
122
  /**
124
123
  * Render function the command usage.
125
124
  */
126
- renderUsage: ((ctx: CommandContext<Options>) => Promise<string>) | null | undefined;
125
+ renderUsage: ((ctx: CommandContext<A>) => Promise<string>) | null | undefined;
127
126
  /**
128
127
  * Render function the header section in the command usage.
129
128
  */
130
- renderHeader: ((ctx: CommandContext<Options>) => Promise<string>) | null | undefined;
129
+ renderHeader: ((ctx: CommandContext<A>) => Promise<string>) | null | undefined;
131
130
  /**
132
131
  * Render function the validation errors.
133
132
  */
134
- renderValidationErrors: ((ctx: CommandContext<Options>, error: AggregateError) => Promise<string>) | null | undefined;
133
+ renderValidationErrors: ((ctx: CommandContext<A>, error: AggregateError) => Promise<string>) | null | undefined;
135
134
  }
136
-
137
135
  /**
138
- * Command options.
139
- */
140
- interface CommandOptions<Options extends ArgOptions = ArgOptions> {
136
+ * Command options.
137
+ */
138
+ interface CommandOptions<A extends Args = Args> {
141
139
  /**
142
140
  * Current working directory.
143
141
  */
@@ -172,9 +170,13 @@ interface CommandOptions<Options extends ArgOptions = ArgOptions> {
172
170
  */
173
171
  middleMargin?: number;
174
172
  /**
175
- * Whether to display the usage option type.
173
+ * Whether to display the usage optional argument type.
176
174
  */
177
175
  usageOptionType?: boolean;
176
+ /**
177
+ * Whether to display the optional argument value.
178
+ */
179
+ usageOptionValue?: boolean;
178
180
  /**
179
181
  * Whether to display the command usage.
180
182
  */
@@ -182,25 +184,25 @@ interface CommandOptions<Options extends ArgOptions = ArgOptions> {
182
184
  /**
183
185
  * Render function the command usage.
184
186
  */
185
- renderUsage?: ((ctx: Readonly<CommandContext<Options>>) => Promise<string>) | null;
187
+ renderUsage?: ((ctx: Readonly<CommandContext<A>>) => Promise<string>) | null;
186
188
  /**
187
189
  * Render function the header section in the command usage.
188
190
  */
189
- renderHeader?: ((ctx: Readonly<CommandContext<Options>>) => Promise<string>) | null;
191
+ renderHeader?: ((ctx: Readonly<CommandContext<A>>) => Promise<string>) | null;
190
192
  /**
191
193
  * Render function the validation errors.
192
194
  */
193
- renderValidationErrors?: ((ctx: Readonly<CommandContext<Options>>, error: AggregateError) => Promise<string>) | null;
195
+ renderValidationErrors?: ((ctx: Readonly<CommandContext<A>>, error: AggregateError) => Promise<string>) | null;
194
196
  /**
195
197
  * Translation adapter factory.
196
198
  */
197
199
  translationAdapterFactory?: TranslationAdapterFactory;
198
200
  }
199
201
  /**
200
- * Command context.
201
- * Command context is the context of the command execution.
202
- */
203
- interface CommandContext<Options extends ArgOptions = ArgOptions, Values = ArgValues<Options>> {
202
+ * Command context.
203
+ * Command context is the context of the command execution.
204
+ */
205
+ interface CommandContext<A extends Args = Args, V = ArgValues<A>> {
204
206
  /**
205
207
  * Command name, that is the command that is executed.
206
208
  * The command name is same {@link CommandEnvironment.name}.
@@ -219,17 +221,17 @@ interface CommandContext<Options extends ArgOptions = ArgOptions, Values = ArgVa
219
221
  * Command environment, that is the environment of the command that is executed.
220
222
  * The command environment is same {@link CommandEnvironment}.
221
223
  */
222
- env: Readonly<CommandEnvironment<Options>>;
224
+ env: Readonly<CommandEnvironment<A>>;
223
225
  /**
224
- * Command options, that is the options of the command that is executed.
225
- * The command options is same {@link Command.options}.
226
+ * Command arguments, that is the arguments of the command that is executed.
227
+ * The command arguments is same {@link Command.args}.
226
228
  */
227
- options: Options;
229
+ args: A;
228
230
  /**
229
231
  * Command values, that is the values of the command that is executed.
230
- * Resolve values with `resolveArgs` from command arguments and {@link Command.options}.
232
+ * Resolve values with `resolveArgs` from command arguments and {@link Command.args}.
231
233
  */
232
- values: Values;
234
+ values: V;
233
235
  /**
234
236
  * Command positionals arguments, that is the positionals of the command that is executed.
235
237
  * Resolve positionals with `resolveArgs` from command arguments.
@@ -264,19 +266,19 @@ interface CommandContext<Options extends ArgOptions = ArgOptions, Values = ArgVa
264
266
  * The loaded commands are cached and returned when called again.
265
267
  * @returns loaded commands.
266
268
  */
267
- loadCommands: () => Promise<Command<Options>[]>;
269
+ loadCommands: () => Promise<Command<A>[]>;
268
270
  /**
269
271
  * Translate function.
270
272
  * @param key the key to be translated
271
273
  * @param values the values to be formatted
272
274
  * @returns A translated string.
273
275
  */
274
- translate: <T extends string = CommandBuiltinKeys, O = CommandOptionKeys<Options>, Key = CommandBuiltinKeys | O | T>(key: Key, values?: Record<string, unknown>) => string;
275
- } /**
276
- * Command interface.
277
- */
278
-
279
- interface Command<Options extends ArgOptions = ArgOptions> {
276
+ translate: <T extends string = CommandBuiltinKeys, O = CommandArgKeys<A>, K = CommandBuiltinKeys | O | T>(key: K, values?: Record<string, unknown>) => string;
277
+ }
278
+ /**
279
+ * Command interface.
280
+ */
281
+ interface Command<A extends Args = Args> {
280
282
  /**
281
283
  * Command name.
282
284
  * It's used to find command line arguments to execute from sub commands, and it's recommended to specify.
@@ -288,10 +290,10 @@ interface Command<Options extends ArgOptions = ArgOptions> {
288
290
  */
289
291
  description?: string;
290
292
  /**
291
- * Command options.
292
- * Each option can include a description property to describe the option in usage.
293
+ * Command arguments.
294
+ * Each argument can include a description property to describe the argument in usage.
293
295
  */
294
- options?: Options;
296
+ args?: A;
295
297
  /**
296
298
  * Command examples.
297
299
  * examples of how to use the command.
@@ -300,16 +302,16 @@ interface Command<Options extends ArgOptions = ArgOptions> {
300
302
  /**
301
303
  * Command runner. it's the command to be executed
302
304
  */
303
- run: CommandRunner<Options>;
305
+ run?: CommandRunner<A>;
304
306
  /**
305
307
  * Command resource fetcher.
306
308
  */
307
- resource?: CommandResourceFetcher<Options>;
308
- } /**
309
- * Command resource.
310
- */
311
-
312
- type CommandResource<Options extends ArgOptions = ArgOptions> = {
309
+ resource?: CommandResourceFetcher<A>;
310
+ }
311
+ /**
312
+ * Command resource.
313
+ */
314
+ type CommandResource<A extends Args = Args> = {
313
315
  /**
314
316
  * Command description.
315
317
  */
@@ -318,22 +320,22 @@ type CommandResource<Options extends ArgOptions = ArgOptions> = {
318
320
  * Examples usage.
319
321
  */
320
322
  examples: string;
321
- } & { [Option in GenerateNamespacedKey<KeyOfArgOptions<RemovedIndex<Options>>, typeof OPTION_PREFIX>]: string } & {
323
+ } & { [Arg in GenerateNamespacedKey<KeyOfArgs<RemovedIndex<A>>, typeof ARG_PREFIX>]: string } & {
322
324
  [key: string]: string;
323
- }; /**
324
- * Command resource fetcher.
325
- * @param ctx A {@link CommandContext | command context}
326
- * @returns A fetched {@link CommandResource | command resource}.
327
- */
328
-
329
- type CommandResourceFetcher<Options extends ArgOptions = ArgOptions, Values = ArgValues<Options>> = (ctx: Readonly<CommandContext<Options, Values>>) => Promise<CommandResource<Options>>; /**
330
- * Translation adapter factory.
331
- */
332
-
333
- type TranslationAdapterFactory = (options: TranslationAdapterFactoryOptions) => TranslationAdapter; /**
334
- * Translation adapter factory options.
335
- */
336
-
325
+ };
326
+ /**
327
+ * Command resource fetcher.
328
+ * @param ctx A {@link CommandContext | command context}
329
+ * @returns A fetched {@link CommandResource | command resource}.
330
+ */
331
+ type CommandResourceFetcher<A extends Args = Args, V = ArgValues<A>> = (ctx: Readonly<CommandContext<A, V>>) => Promise<CommandResource<A>>;
332
+ /**
333
+ * Translation adapter factory.
334
+ */
335
+ type TranslationAdapterFactory = (options: TranslationAdapterFactoryOptions) => TranslationAdapter;
336
+ /**
337
+ * Translation adapter factory options.
338
+ */
337
339
  interface TranslationAdapterFactoryOptions {
338
340
  /**
339
341
  * A locale.
@@ -343,12 +345,12 @@ interface TranslationAdapterFactoryOptions {
343
345
  * A fallback locale.
344
346
  */
345
347
  fallbackLocale: string;
346
- } /**
347
- * Translation adapter.
348
- * This adapter is used to custom message formatter like {@link https://github.com/intlify/vue-i18n/blob/master/spec/syntax.ebnf | Intlify message format}, {@link https://github.com/tc39/proposal-intl-messageformat | `Intl.MessageFormat` (MF2)}, and etc.
349
- * This adapter will support localization with your preferred message format.
350
- */
351
-
348
+ }
349
+ /**
350
+ * Translation adapter.
351
+ * This adapter is used to custom message formatter like {@link https://github.com/intlify/vue-i18n/blob/master/spec/syntax.ebnf | Intlify message format}, {@link https://github.com/tc39/proposal-intl-messageformat | `Intl.MessageFormat` (MF2)}, and etc.
352
+ * This adapter will support localization with your preferred message format.
353
+ */
352
354
  interface TranslationAdapter<MessageResource = string> {
353
355
  /**
354
356
  * Get a resource of locale.
@@ -377,19 +379,29 @@ interface TranslationAdapter<MessageResource = string> {
377
379
  * @returns A translated message, if message is not translated, return `undefined`.
378
380
  */
379
381
  translate(locale: string, key: string, values?: Record<string, unknown>): string | undefined;
380
- } /**
381
- * Command runner.
382
- * @param ctx A {@link CommandContext | command context}
383
- */
384
-
385
- type CommandRunner<Options extends ArgOptions = ArgOptions> = (ctx: Readonly<CommandContext<Options>>) => Awaitable<void>; /**
386
- * Lazy command interface.
387
- * Lazy command that's not loaded until it is executed.
388
- */
389
-
390
- type LazyCommand<Options extends ArgOptions = ArgOptions> = () => Awaitable<Command<Options>>; /**
391
- * Define a command type.
392
- */
393
-
394
- type Commandable<Options extends ArgOptions> = Command<Options> | LazyCommand<Options>; //#endregion
395
- export { Command, CommandBuiltinKeys, CommandBuiltinOptionsKeys, CommandBuiltinResourceKeys, CommandContext, CommandEnvironment, CommandOptionKeys, CommandOptions, CommandResource, CommandResourceFetcher, CommandRunner, Commandable, DEFAULT_LOCALE, GenerateNamespacedKey, KeyOfArgOptions, LazyCommand, RemovedIndex, TranslationAdapter, TranslationAdapterFactory, TranslationAdapterFactoryOptions };
382
+ }
383
+ /**
384
+ * Command runner.
385
+ * @param ctx A {@link CommandContext | command context}
386
+ */
387
+ type CommandRunner<A extends Args = Args> = (ctx: Readonly<CommandContext<A>>) => Awaitable<void>;
388
+ type CommandLoader<A extends Args = Args> = () => Awaitable<Command<A> | CommandRunner<A>>;
389
+ /**
390
+ * Lazy command interface.
391
+ * Lazy command that's not loaded until it is executed.
392
+ */
393
+ type LazyCommand<A extends Args = Args> = {
394
+ /**
395
+ * Command load function
396
+ */
397
+ (): Awaitable<Command<A> | CommandRunner<A>>;
398
+ /**
399
+ * Command name
400
+ */
401
+ commandName?: string;
402
+ } & Omit<Command<A>, 'run' | 'name'>;
403
+ /**
404
+ * Define a command type.
405
+ */
406
+ type Commandable<A extends Args> = Command<A> | LazyCommand<A>; //#endregion
407
+ export { Command, CommandArgKeys, CommandBuiltinArgsKeys, CommandBuiltinKeys, CommandBuiltinResourceKeys, CommandContext, CommandEnvironment, CommandLoader, CommandOptions, CommandResource, CommandResourceFetcher, CommandRunner, Commandable, DEFAULT_LOCALE, GenerateNamespacedKey, KeyOfArgs, LazyCommand, RemovedIndex, TranslationAdapter, TranslationAdapterFactory, TranslationAdapterFactoryOptions };
@@ -4,10 +4,10 @@
4
4
  */
5
5
  const DEFAULT_LOCALE = "en-US";
6
6
  const BUILT_IN_PREFIX = "_";
7
- const OPTION_PREFIX = "Option";
7
+ const ARG_PREFIX = "arg";
8
8
  const BUILT_IN_KEY_SEPARATOR = ":";
9
9
  const NOOP = () => {};
10
- const COMMON_OPTIONS = {
10
+ const COMMON_ARGS = {
11
11
  help: {
12
12
  type: "boolean",
13
13
  short: "h",
@@ -29,6 +29,7 @@ const COMMAND_OPTIONS_DEFAULT = {
29
29
  leftMargin: 2,
30
30
  middleMargin: 10,
31
31
  usageOptionType: false,
32
+ usageOptionValue: true,
32
33
  renderHeader: void 0,
33
34
  renderUsage: void 0,
34
35
  renderValidationErrors: void 0,
@@ -37,16 +38,38 @@ const COMMAND_OPTIONS_DEFAULT = {
37
38
 
38
39
  //#endregion
39
40
  //#region src/utils.ts
40
- async function resolveLazyCommand(cmd, name) {
41
- const resolved = Object.assign(create(), typeof cmd == "function" ? await cmd() : cmd);
42
- if (resolved.name == null && name) resolved.name = name;
43
- return deepFreeze(resolved);
41
+ async function resolveLazyCommand(cmd, name, needRunResolving = false) {
42
+ let command;
43
+ if (typeof cmd === "function") {
44
+ command = Object.assign(create(), {
45
+ name: cmd.commandName,
46
+ description: cmd.description,
47
+ args: cmd.args,
48
+ examples: cmd.examples,
49
+ resource: cmd.resource
50
+ });
51
+ if (needRunResolving) {
52
+ const loaded = await cmd();
53
+ if (typeof loaded === "function") command.run = loaded;
54
+ else if (typeof loaded === "object") {
55
+ if (loaded.run == null) throw new TypeError(`'run' is required in command: ${cmd.name || name}`);
56
+ command.run = loaded.run;
57
+ command.name = loaded.name;
58
+ command.description = loaded.description;
59
+ command.args = loaded.args;
60
+ command.examples = loaded.examples;
61
+ command.resource = loaded.resource;
62
+ } else throw new TypeError(`Cannot resolve command: ${cmd.name || name}`);
63
+ }
64
+ } else command = Object.assign(create(), cmd);
65
+ if (command.name == null && name) command.name = name;
66
+ return deepFreeze(command);
44
67
  }
45
68
  function resolveBuiltInKey(key) {
46
69
  return `${BUILT_IN_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
47
70
  }
48
- function resolveOptionKey(key) {
49
- return `${OPTION_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
71
+ function resolveArgKey(key) {
72
+ return `${ARG_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
50
73
  }
51
74
  function mapResourceWithBuiltinKey(resource) {
52
75
  return Object.entries(resource).reduce((acc, [key, value]) => {
@@ -70,4 +93,4 @@ function deepFreeze(obj) {
70
93
  }
71
94
 
72
95
  //#endregion
73
- export { BUILT_IN_PREFIX, COMMAND_OPTIONS_DEFAULT, COMMON_OPTIONS, DEFAULT_LOCALE as DEFAULT_LOCALE$1, NOOP, create, deepFreeze, log, mapResourceWithBuiltinKey, resolveBuiltInKey, resolveLazyCommand, resolveOptionKey };
96
+ export { BUILT_IN_PREFIX, COMMAND_OPTIONS_DEFAULT, COMMON_ARGS, DEFAULT_LOCALE as DEFAULT_LOCALE$1, NOOP, create, deepFreeze, log, mapResourceWithBuiltinKey, resolveArgKey, resolveBuiltInKey, resolveLazyCommand };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gunshi",
3
3
  "description": "Modern javascript command-line library",
4
- "version": "0.17.0",
4
+ "version": "0.19.0",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
7
7
  "email": "kawakazu80@gmail.com"
@@ -30,6 +30,7 @@
30
30
  "node": ">= 20"
31
31
  },
32
32
  "type": "module",
33
+ "sideEffects": false,
33
34
  "files": [
34
35
  "lib"
35
36
  ],
@@ -77,7 +78,7 @@
77
78
  }
78
79
  },
79
80
  "dependencies": {
80
- "args-tokens": "^0.16.0"
81
+ "args-tokens": "^0.17.1"
81
82
  },
82
83
  "devDependencies": {
83
84
  "@eslint/markdown": "^6.4.0",
@@ -85,10 +86,10 @@
85
86
  "@kazupon/eslint-config": "^0.29.0",
86
87
  "@kazupon/prettier-config": "^0.1.1",
87
88
  "@types/node": "^22.15.3",
88
- "@vitest/eslint-plugin": "^1.1.43",
89
+ "@vitest/eslint-plugin": "^1.1.44",
89
90
  "bumpp": "^10.1.0",
90
- "deno": "^2.2.12",
91
- "eslint": "^9.25.1",
91
+ "deno": "^2.3.1",
92
+ "eslint": "^9.26.0",
92
93
  "eslint-config-prettier": "^10.1.2",
93
94
  "eslint-import-resolver-typescript": "^4.3.4",
94
95
  "eslint-plugin-import": "^2.31.0",
@@ -98,27 +99,27 @@
98
99
  "eslint-plugin-regexp": "^2.7.0",
99
100
  "eslint-plugin-unicorn": "^58.0.0",
100
101
  "eslint-plugin-unused-imports": "^4.1.4",
101
- "eslint-plugin-vue": "^10.0.1",
102
+ "eslint-plugin-vue": "^10.1.0",
102
103
  "eslint-plugin-vue-composable": "^1.0.0",
103
104
  "eslint-plugin-yml": "^1.18.0",
104
105
  "gh-changelogen": "^0.2.8",
105
106
  "jsr": "^0.13.4",
106
107
  "jsr-exports-lint": "^0.2.0",
107
- "knip": "^5.50.5",
108
+ "knip": "^5.53.0",
108
109
  "lint-staged": "^15.5.1",
109
110
  "messageformat": "4.0.0-10",
110
111
  "pkg-pr-new": "^0.0.43",
111
112
  "prettier": "^3.5.3",
112
113
  "publint": "^0.3.12",
113
- "tsdown": "^0.10.0",
114
- "typedoc": "^0.28.3",
114
+ "tsdown": "^0.10.2",
115
+ "typedoc": "^0.28.4",
115
116
  "typedoc-plugin-markdown": "^4.6.3",
116
117
  "typedoc-vitepress-theme": "^1.1.2",
117
118
  "typescript": "^5.8.3",
118
119
  "typescript-eslint": "^8.31.1",
119
120
  "vitepress": "^1.6.3",
120
121
  "vitepress-plugin-group-icons": "^1.5.2",
121
- "vitepress-plugin-llms": "^1.1.1",
122
+ "vitepress-plugin-llms": "^1.1.3",
122
123
  "vitest": "^3.1.2",
123
124
  "vue": "^3.5.13"
124
125
  },
@@ -1,12 +0,0 @@
1
- //#region src/definition.ts
2
- /**
3
- * Define a {@link Command | command} with type inference
4
- * @param definition A {@link Command | command} definition
5
- * @returns A {@link Command | command} definition with type inference
6
- */
7
- function define(definition) {
8
- return definition;
9
- }
10
-
11
- //#endregion
12
- export { define };
@@ -1,12 +0,0 @@
1
- import { Command } from "./types.d-DomXJWKH.js";
2
- import { ArgOptionSchema, ArgOptions, ArgOptions as ArgOptions$1, ArgValues as ArgValues$1 } from "args-tokens";
3
-
4
- //#region src/definition.d.ts
5
- /**
6
- * Define a {@link Command | command} with type inference
7
- * @param definition A {@link Command | command} definition
8
- * @returns A {@link Command | command} definition with type inference
9
- */
10
-
11
- declare function define<Options extends ArgOptions = ArgOptions>(definition: Command<Options>): Command<Options>; //#endregion
12
- export { ArgOptionSchema, ArgOptions$1 as ArgOptions, ArgValues$1 as ArgValues, define as define$1 };