@gunshi/plugin 0.27.0-alpha.9 → 0.27.0-beta.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.
Files changed (4) hide show
  1. package/README.md +1014 -9
  2. package/lib/index.d.ts +772 -149
  3. package/lib/index.js +49 -22
  4. package/package.json +6 -6
package/lib/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- //#region ../../node_modules/.pnpm/args-tokens@0.22.0/node_modules/args-tokens/lib/parser-Cbxholql.d.ts
1
+ //#region ../../node_modules/.pnpm/args-tokens@0.23.0/node_modules/args-tokens/lib/parser-C6MbpZjd.d.ts
2
2
  //#region src/parser.d.ts
3
3
  /**
4
4
  * Entry point of argument parser.
5
+ *
5
6
  * @module
6
7
  */
7
8
  /**
@@ -14,6 +15,7 @@
14
15
  */
15
16
  /**
16
17
  * Argument token Kind.
18
+ *
17
19
  * - `option`: option token, support short option (e.g. `-x`) and long option (e.g. `--foo`)
18
20
  * - `option-terminator`: option terminator (`--`) token, see guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
19
21
  * - `positional`: positional token
@@ -53,91 +55,462 @@ interface ArgToken {
53
55
  * Parser Options.
54
56
  */
55
57
  //#endregion
56
- //#region ../../node_modules/.pnpm/args-tokens@0.22.0/node_modules/args-tokens/lib/resolver-BoS-UnqX.d.ts
58
+ //#region ../../node_modules/.pnpm/args-tokens@0.23.0/node_modules/args-tokens/lib/resolver-D64nGlCD.d.ts
57
59
  //#region src/resolver.d.ts
58
60
 
59
61
  /**
60
- * An argument schema
61
- * This schema is similar to the schema of the `node:utils`.
62
- * difference is that:
63
- * - `required` property and `description` property are added
64
- * - `type` is not only 'string' and 'boolean', but also 'number', 'enum', 'positional', 'custom' too.
65
- * - `default` property type, not support multiple types
62
+ * An argument schema definition for command-line argument parsing.
63
+ *
64
+ * This schema is similar to the schema of Node.js `util.parseArgs` but with extended features:
65
+ * - Additional `required` and `description` properties
66
+ * - Extended `type` support: 'string', 'boolean', 'number', 'enum', 'positional', 'custom'
67
+ * - Simplified `default` property (single type, not union types)
68
+ *
69
+ * @example
70
+ * Basic string argument:
71
+ * ```ts
72
+ * const schema: ArgSchema = {
73
+ * type: 'string',
74
+ * description: 'Server hostname',
75
+ * default: 'localhost'
76
+ * }
77
+ * ```
78
+ *
79
+ * @example
80
+ * Required number argument with alias:
81
+ * ```ts
82
+ * const schema: ArgSchema = {
83
+ * type: 'number',
84
+ * short: 'p',
85
+ * description: 'Port number to listen on',
86
+ * required: true
87
+ * }
88
+ * ```
89
+ *
90
+ * @example
91
+ * Enum argument with choices:
92
+ * ```ts
93
+ * const schema: ArgSchema = {
94
+ * type: 'enum',
95
+ * choices: ['info', 'warn', 'error'],
96
+ * description: 'Logging level',
97
+ * default: 'info'
98
+ * }
99
+ * ```
66
100
  */
67
101
  interface ArgSchema {
68
102
  /**
69
- * Type of argument.
103
+ * Type of the argument value.
104
+ *
105
+ * - `'string'`: Text value (default if not specified)
106
+ * - `'boolean'`: `true`/`false` flag (can be negatable with `--no-` prefix)
107
+ * - `'number'`: Numeric value (parsed as integer or float)
108
+ * - `'enum'`: One of predefined string values (requires `choices` property)
109
+ * - `'positional'`: Non-option argument by position
110
+ * - `'custom'`: Custom parsing with user-defined `parse` function
111
+ *
112
+ * @example
113
+ * Different argument types:
114
+ * ```ts
115
+ * {
116
+ * name: { type: 'string' }, // --name value
117
+ * verbose: { type: 'boolean' }, // --verbose or --no-verbose
118
+ * port: { type: 'number' }, // --port 3000
119
+ * level: { type: 'enum', choices: ['debug', 'info'] },
120
+ * file: { type: 'positional' }, // first positional arg
121
+ * config: { type: 'custom', parse: JSON.parse }
122
+ * }
123
+ * ```
70
124
  */
71
125
  type: 'string' | 'boolean' | 'number' | 'enum' | 'positional' | 'custom';
72
126
  /**
73
- * A single character alias for the argument.
127
+ * Single character alias for the long option name.
128
+ *
129
+ * As example, allows users to use `-x` instead of `--extended-option`.
130
+ * Only valid for non-positional argument types.
131
+ *
132
+ * @example
133
+ * Short alias usage:
134
+ * ```ts
135
+ * {
136
+ * verbose: {
137
+ * type: 'boolean',
138
+ * short: 'v' // Enables both --verbose and -v
139
+ * },
140
+ * port: {
141
+ * type: 'number',
142
+ * short: 'p' // Enables both --port 3000 and -p 3000
143
+ * }
144
+ * }
145
+ * ```
74
146
  */
75
147
  short?: string;
76
148
  /**
77
- * A description of the argument.
149
+ * Human-readable description of the argument's purpose.
150
+ *
151
+ * Used for help text generation and documentation.
152
+ * Should be concise but descriptive enough to understand the argument's role.
153
+ *
154
+ * @example
155
+ * Descriptive help text:
156
+ * ```ts
157
+ * {
158
+ * config: {
159
+ * type: 'string',
160
+ * description: 'Path to configuration file'
161
+ * },
162
+ * timeout: {
163
+ * type: 'number',
164
+ * description: 'Request timeout in milliseconds'
165
+ * }
166
+ * }
167
+ * ```
78
168
  */
79
169
  description?: string;
80
170
  /**
81
- * Whether the argument is required or not.
171
+ * Marks the argument as required.
172
+ *
173
+ * When `true`, the argument must be provided by the user.
174
+ * If missing, an `ArgResolveError` with type 'required' will be thrown.
175
+ *
176
+ * Note: Only `true` is allowed (not `false`) to make intent explicit.
177
+ *
178
+ * @example
179
+ * Required arguments:
180
+ * ```ts
181
+ * {
182
+ * input: {
183
+ * type: 'string',
184
+ * required: true, // Must be provided: --input file.txt
185
+ * description: 'Input file path'
186
+ * },
187
+ * source: {
188
+ * type: 'positional',
189
+ * required: true // First positional argument must exist
190
+ * }
191
+ * }
192
+ * ```
82
193
  */
83
194
  required?: true;
84
195
  /**
85
- * Whether the argument allow multiple values or not.
196
+ * Allows the argument to accept multiple values.
197
+ *
198
+ * When `true`, the resolved value becomes an array.
199
+ * For options: can be specified multiple times (--tag foo --tag bar)
200
+ * For positional: collects remaining positional arguments
201
+ *
202
+ * Note: Only `true` is allowed (not `false`) to make intent explicit.
203
+ *
204
+ * @example
205
+ * Multiple values:
206
+ * ```ts
207
+ * {
208
+ * tags: {
209
+ * type: 'string',
210
+ * multiple: true, // --tags foo --tags bar → ['foo', 'bar']
211
+ * description: 'Tags to apply'
212
+ * },
213
+ * files: {
214
+ * type: 'positional',
215
+ * multiple: true // Collects all remaining positional args
216
+ * }
217
+ * }
218
+ * ```
86
219
  */
87
220
  multiple?: true;
88
221
  /**
89
- * Whether the negatable option for `boolean` type
222
+ * Enables negation for boolean arguments using `--no-` prefix.
223
+ *
224
+ * When `true`, allows users to explicitly set the boolean to `false`
225
+ * using `--no-option-name`. When `false` or omitted, only positive
226
+ * form is available.
227
+ *
228
+ * Only applicable to `type: 'boolean'` arguments.
229
+ *
230
+ * @example
231
+ * Negatable boolean:
232
+ * ```ts
233
+ * {
234
+ * color: {
235
+ * type: 'boolean',
236
+ * negatable: true,
237
+ * default: true,
238
+ * description: 'Enable colorized output'
239
+ * }
240
+ * // Usage: --color (true), --no-color (false)
241
+ * }
242
+ * ```
90
243
  */
91
244
  negatable?: boolean;
92
245
  /**
93
- * The allowed values of the argument, and string only. This property is only used when the type is 'enum'.
246
+ * Array of allowed string values for enum-type arguments.
247
+ *
248
+ * Required when `type: 'enum'`. The argument value must be one of these choices,
249
+ * otherwise an `ArgResolveError` with type 'type' will be thrown.
250
+ *
251
+ * Supports both mutable arrays and readonly arrays for type safety.
252
+ *
253
+ * @example
254
+ * Enum choices:
255
+ * ```ts
256
+ * {
257
+ * logLevel: {
258
+ * type: 'enum',
259
+ * choices: ['debug', 'info', 'warn', 'error'] as const,
260
+ * default: 'info',
261
+ * description: 'Logging verbosity level'
262
+ * },
263
+ * format: {
264
+ * type: 'enum',
265
+ * choices: ['json', 'yaml', 'toml'],
266
+ * description: 'Output format'
267
+ * }
268
+ * }
269
+ * ```
94
270
  */
95
271
  choices?: string[] | readonly string[];
96
272
  /**
97
- * The default value of the argument.
98
- * if the type is 'enum', the default value must be one of the allowed values.
273
+ * Default value used when the argument is not provided.
274
+ *
275
+ * The type must match the argument's `type` property:
276
+ * - `string` type: string default
277
+ * - `boolean` type: boolean default
278
+ * - `number` type: number default
279
+ * - `enum` type: must be one of the `choices` values
280
+ * - `positional`/`custom` type: any appropriate default
281
+ *
282
+ * @example
283
+ * Default values by type:
284
+ * ```ts
285
+ * {
286
+ * host: {
287
+ * type: 'string',
288
+ * default: 'localhost' // string default
289
+ * },
290
+ * verbose: {
291
+ * type: 'boolean',
292
+ * default: false // boolean default
293
+ * },
294
+ * port: {
295
+ * type: 'number',
296
+ * default: 8080 // number default
297
+ * },
298
+ * level: {
299
+ * type: 'enum',
300
+ * choices: ['low', 'high'],
301
+ * default: 'low' // must be in choices
302
+ * }
303
+ * }
304
+ * ```
99
305
  */
100
306
  default?: string | boolean | number;
101
307
  /**
102
- * Whether to convert the argument name to kebab-case.
308
+ * Converts the argument name from camelCase to kebab-case for CLI usage.
309
+ *
310
+ * When `true`, a property like `maxCount` becomes available as `--max-count`.
311
+ * This allows [CAC](https://github.com/cacjs/cac) user-friendly property names while maintaining CLI conventions.
312
+ *
313
+ * Can be overridden globally with `resolveArgs({ toKebab: true })`.
314
+ *
315
+ * Note: Only `true` is allowed (not `false`) to make intent explicit.
316
+ *
317
+ * @example
318
+ * Kebab-case conversion:
319
+ * ```ts
320
+ * {
321
+ * maxRetries: {
322
+ * type: 'number',
323
+ * toKebab: true, // Accessible as --max-retries
324
+ * description: 'Maximum retry attempts'
325
+ * },
326
+ * enableLogging: {
327
+ * type: 'boolean',
328
+ * toKebab: true // Accessible as --enable-logging
329
+ * }
330
+ * }
331
+ * ```
103
332
  */
104
333
  toKebab?: true;
105
334
  /**
106
- * A function to parse the value of the argument. if the type is 'custom', this function is required.
107
- * If argument value will be invalid, this function have to throw an error.
108
- * @param value
109
- * @returns Parsed value
110
- * @throws An Error, If the value is invalid. Error type should be `Error` or extends it
335
+ * Names of other options that conflict with this option.
336
+ *
337
+ * When this option is used together with any of the conflicting options,
338
+ * an `ArgResolveError` with type 'conflict' will be thrown.
339
+ *
340
+ * Conflicts only need to be defined on one side - if option A defines a conflict
341
+ * with option B, the conflict is automatically detected when both are used,
342
+ * regardless of whether B also defines a conflict with A.
343
+ *
344
+ * Supports both single option name or array of option names.
345
+ * Option names must match the property keys in the schema object exactly
346
+ * (no automatic conversion between camelCase and kebab-case).
347
+ *
348
+ * @example
349
+ * Single conflict (bidirectional definition):
350
+ * ```ts
351
+ * {
352
+ * summer: {
353
+ * type: 'boolean',
354
+ * conflicts: 'autumn' // Cannot use --summer with --autumn
355
+ * },
356
+ * autumn: {
357
+ * type: 'boolean',
358
+ * conflicts: 'summer' // Can define on both sides for clarity
359
+ * }
360
+ * }
361
+ * ```
362
+ *
363
+ * @example
364
+ * Single conflict (one-way definition):
365
+ * ```ts
366
+ * {
367
+ * summer: {
368
+ * type: 'boolean',
369
+ * conflicts: 'autumn' // Only defined on summer side
370
+ * },
371
+ * autumn: {
372
+ * type: 'boolean'
373
+ * // No conflicts defined, but still cannot use with --summer
374
+ * }
375
+ * }
376
+ * // Usage: --summer --autumn will throw error
377
+ * // Error: "Optional argument '--summer' conflicts with '--autumn'"
378
+ * ```
379
+ *
380
+ * @example
381
+ * Multiple conflicts:
382
+ * ```ts
383
+ * {
384
+ * port: {
385
+ * type: 'number',
386
+ * conflicts: ['socket', 'pipe'], // Cannot use with --socket or --pipe
387
+ * description: 'TCP port number'
388
+ * },
389
+ * socket: {
390
+ * type: 'string',
391
+ * conflicts: ['port', 'pipe'], // Cannot use with --port or --pipe
392
+ * description: 'Unix socket path'
393
+ * },
394
+ * pipe: {
395
+ * type: 'string',
396
+ * conflicts: ['port', 'socket'], // Cannot use with --port or --socket
397
+ * description: 'Named pipe path'
398
+ * }
399
+ * }
400
+ * // These three options are mutually exclusive
401
+ * ```
402
+ *
403
+ * @example
404
+ * With kebab-case conversion:
405
+ * ```ts
406
+ * {
407
+ * summerSeason: {
408
+ * type: 'boolean',
409
+ * toKebab: true, // Accessible as --summer-season
410
+ * conflicts: 'autumnSeason' // Must use property key, not CLI name
411
+ * },
412
+ * autumnSeason: {
413
+ * type: 'boolean',
414
+ * toKebab: true // Accessible as --autumn-season
415
+ * }
416
+ * }
417
+ * // Error: "Optional argument '--summer-season' conflicts with '--autumn-season'"
418
+ * ```
419
+ */
420
+ conflicts?: string | string[];
421
+ /**
422
+ * Custom parsing function for `type: 'custom'` arguments.
423
+ *
424
+ * Required when `type: 'custom'`. Receives the raw string value and must
425
+ * return the parsed result. Should throw an Error (or subclass) if parsing fails.
426
+ *
427
+ * The function's return type becomes the resolved argument type.
428
+ *
429
+ * @param value - Raw string value from command line
430
+ * @returns Parsed value of any type
431
+ * @throws Error or subclass when value is invalid
432
+ *
433
+ * @example
434
+ * Custom parsing functions:
435
+ * ```ts
436
+ * {
437
+ * config: {
438
+ * type: 'custom',
439
+ * parse: (value: string) => {
440
+ * try {
441
+ * return JSON.parse(value) // Parse JSON config
442
+ * } catch {
443
+ * throw new Error('Invalid JSON configuration')
444
+ * }
445
+ * },
446
+ * description: 'JSON configuration object'
447
+ * },
448
+ * date: {
449
+ * type: 'custom',
450
+ * parse: (value: string) => {
451
+ * const date = new Date(value)
452
+ * if (isNaN(date.getTime())) {
453
+ * throw new Error('Invalid date format')
454
+ * }
455
+ * return date
456
+ * }
457
+ * }
458
+ * }
459
+ * ```
111
460
  */
112
461
  parse?: (value: string) => any;
113
462
  }
114
463
  /**
115
464
  * An object that contains {@link ArgSchema | argument schema}.
465
+ *
466
+ * This type is used to define the structure and validation rules for command line arguments.
116
467
  */
117
468
  interface Args {
118
469
  [option: string]: ArgSchema;
119
470
  }
120
471
  /**
121
472
  * An object that contains the values of the arguments.
473
+ *
474
+ * @typeParam T - {@link Args | Arguments} which is an object that defines the command line arguments.
122
475
  */
123
476
  type ArgValues<T> = T extends Args ? ResolveArgValues<T, { [Arg in keyof T]: ExtractOptionValue<T[Arg]> }> : {
124
477
  [option: string]: string | boolean | number | (string | boolean | number)[] | undefined;
125
478
  };
126
479
  type IsFunction<T> = T extends ((...args: any[]) => any) ? true : false;
127
480
  /**
481
+ * Extracts the value type from the argument schema.
482
+ *
483
+ * @typeParam A - {@link ArgSchema | Argument schema} which is an object that defines command line arguments.
484
+ *
128
485
  * @internal
129
486
  */
130
487
  type ExtractOptionValue<A extends ArgSchema> = A['type'] extends 'string' ? ResolveOptionValue<A, string> : A['type'] extends 'boolean' ? ResolveOptionValue<A, boolean> : A['type'] extends 'number' ? ResolveOptionValue<A, number> : A['type'] extends 'positional' ? ResolveOptionValue<A, string> : A['type'] extends 'enum' ? A['choices'] extends string[] | readonly string[] ? ResolveOptionValue<A, A['choices'][number]> : never : A['type'] extends 'custom' ? IsFunction<A['parse']> extends true ? ResolveOptionValue<A, ReturnType<NonNullable<A['parse']>>> : never : ResolveOptionValue<A, string | boolean | number>;
131
488
  type ResolveOptionValue<A extends ArgSchema, T> = A['multiple'] extends true ? T[] : T;
132
489
  /**
490
+ * Resolved argument values.
491
+ *
492
+ * @typeParam A - {@link Arguments | Args} which is an object that defines the command line arguments.
493
+ * @typeParam V - Resolvable argument values.
494
+ *
133
495
  * @internal
134
496
  */
135
497
  type ResolveArgValues<A extends Args, V extends Record<keyof A, unknown>> = { -readonly [Arg in keyof A]?: V[Arg] } & FilterArgs<A, V, 'default'> & FilterArgs<A, V, 'required'> & FilterPositionalArgs<A, V> extends infer P ? { [K in keyof P]: P[K] } : never;
136
498
  /**
499
+ * Filters the arguments based on their default values.
500
+ *
501
+ * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
502
+ * @typeParam V - Resolvable argument values.
503
+ * @typeParam K - Key of the {@link ArgSchema | argument schema} to filter by.
504
+ *
137
505
  * @internal
138
506
  */
139
507
  type FilterArgs<A extends Args, V extends Record<keyof A, unknown>, K extends keyof ArgSchema> = { [Arg in keyof A as A[Arg][K] extends {} ? Arg : never]: V[Arg] };
140
508
  /**
509
+ * Filters positional arguments from the argument schema.
510
+ *
511
+ * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
512
+ * @typeParam V - Resolvable argument values.
513
+ *
141
514
  * @internal
142
515
  */
143
516
  type FilterPositionalArgs<A extends Args, V extends Record<keyof A, unknown>> = { [Arg in keyof A as A[Arg]['type'] extends 'positional' ? Arg : never]: V[Arg] };
@@ -150,10 +523,15 @@ type FilterPositionalArgs<A extends Args, V extends Record<keyof A, unknown>> =
150
523
  *
151
524
  * Each property indicates whether the corresponding argument was explicitly
152
525
  * provided (true) or is using a default value or not provided (false).
526
+ *
527
+ * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
153
528
  */
154
529
  type ArgExplicitlyProvided<A extends Args> = { [K in keyof A]: boolean };
155
530
  /**
156
531
  * Resolve command line arguments.
532
+ *
533
+ * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
534
+ *
157
535
  * @param args - An arguments that contains {@link ArgSchema | arguments schema}.
158
536
  * @param tokens - An array of {@link ArgToken | tokens}.
159
537
  * @param resolveArgs - An arguments that contains {@link ResolveArgs | resolve arguments}.
@@ -185,77 +563,106 @@ type ArgExplicitlyProvided<A extends Args> = { [K in keyof A]: boolean };
185
563
  //#region ../gunshi/src/plugin/context.d.ts
186
564
  /**
187
565
  * Type helper to create GunshiParams from extracted args and extensions
566
+ *
188
567
  * @internal
189
568
  */
190
569
  type ExtractedParams<G extends GunshiParamsConstraint, L extends Record<string, unknown> = {}> = {
191
570
  args: ExtractArgs<G>;
192
- extensions: ExtractExtensions$1<G> & L;
571
+ extensions: ExtractExtensions<G> & L;
193
572
  };
194
573
  /**
195
574
  * Gunshi plugin context interface.
575
+ *
576
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command parameters.
577
+ *
196
578
  * @since v0.27.0
197
579
  */
198
580
  interface PluginContext<G extends GunshiParamsConstraint = DefaultGunshiParams> {
199
581
  /**
200
582
  * Get the global options
583
+ *
201
584
  * @returns A map of global options.
202
585
  */
203
586
  readonly globalOptions: Map<string, ArgSchema>;
204
587
  /**
205
588
  * Get the registered sub commands
589
+ *
206
590
  * @returns A map of sub commands.
207
591
  */
208
592
  readonly subCommands: ReadonlyMap<string, Command<G> | LazyCommand<G>>;
209
593
  /**
210
594
  * Add a global option.
211
- * @param name An option name
212
- * @param schema An {@link ArgSchema} for the option
595
+ *
596
+ * @param name - An option name
597
+ * @param schema - An {@linkcode ArgSchema} for the option
213
598
  */
214
599
  addGlobalOption(name: string, schema: ArgSchema): void;
215
600
  /**
216
601
  * Add a sub command.
217
- * @param name Command name
218
- * @param command Command definition
602
+ *
603
+ * @param name - Command name
604
+ * @param command - Command definition
219
605
  */
220
606
  addCommand(name: string, command: Command<G> | LazyCommand<G>): void;
221
607
  /**
222
608
  * Check if a command exists.
223
- * @param name Command name
609
+ *
610
+ * @param name - Command name
224
611
  * @returns True if the command exists, false otherwise
225
612
  */
226
613
  hasCommand(name: string): boolean;
227
614
  /**
228
615
  * Decorate the header renderer.
616
+ *
617
+ * @typeParam L - An extensions type to specify the shape of {@linkcode CommandContext}'s extensions.
618
+ *
229
619
  * @param decorator - A decorator function that wraps the base header renderer.
230
620
  */
231
621
  decorateHeaderRenderer<L extends Record<string, unknown> = DefaultGunshiParams['extensions']>(decorator: (baseRenderer: (ctx: Readonly<CommandContext<ExtractedParams<G, L>>>) => Promise<string>, ctx: Readonly<CommandContext<ExtractedParams<G, L>>>) => Promise<string>): void;
232
622
  /**
233
623
  * Decorate the usage renderer.
624
+ *
625
+ * @typeParam L - An extensions type to specify the shape of {@linkcode CommandContext}'s extensions.
626
+ *
234
627
  * @param decorator - A decorator function that wraps the base usage renderer.
235
628
  */
236
629
  decorateUsageRenderer<L extends Record<string, unknown> = DefaultGunshiParams['extensions']>(decorator: (baseRenderer: (ctx: Readonly<CommandContext<ExtractedParams<G, L>>>) => Promise<string>, ctx: Readonly<CommandContext<ExtractedParams<G, L>>>) => Promise<string>): void;
237
630
  /**
238
631
  * Decorate the validation errors renderer.
632
+ *
633
+ * @typeParam L - An extensions type to specify the shape of {@linkcode CommandContext}'s extensions.
634
+ *
239
635
  * @param decorator - A decorator function that wraps the base validation errors renderer.
240
636
  */
241
637
  decorateValidationErrorsRenderer<L extends Record<string, unknown> = DefaultGunshiParams['extensions']>(decorator: (baseRenderer: (ctx: Readonly<CommandContext<ExtractedParams<G, L>>>, error: AggregateError) => Promise<string>, ctx: Readonly<CommandContext<ExtractedParams<G, L>>>, error: AggregateError) => Promise<string>): void;
242
638
  /**
243
639
  * Decorate the command execution.
640
+ *
244
641
  * Decorators are applied in reverse order (last registered is executed first).
642
+ *
643
+ * @typeParam L - An extensions type to specify the shape of {@linkcode CommandContext}'s extensions.
644
+ *
245
645
  * @param decorator - A decorator function that wraps the command runner
246
646
  */
247
647
  decorateCommand<L extends Record<string, unknown> = DefaultGunshiParams['extensions']>(decorator: (baseRunner: (ctx: Readonly<CommandContext<ExtractedParams<G, L>>>) => Awaitable<void | string>) => (ctx: Readonly<CommandContext<ExtractedParams<G, L>>>) => Awaitable<void | string>): void;
248
648
  }
249
- /**
250
- * Factory function for creating a plugin context.
251
- * @param decorators - A {@link Decorators} instance.
252
- * @param initialSubCommands - Initial sub commands map.
253
- * @returns A new {@link PluginContext} instance.
254
- */
255
649
  //#endregion
256
650
  //#region ../gunshi/src/plugin/core.d.ts
651
+ type ProcessDependency<D, A extends ExtendContext> = D extends string ? D extends keyof A ? { [K in D]: A[K] } : {} : D extends {
652
+ id: infer ID;
653
+ optional?: any;
654
+ } ? ID extends string ? ID extends keyof A ? D extends {
655
+ optional: true;
656
+ } ? { [K in ID]: A[K] | undefined } : { [K in ID]: A[K] } : {} : never : never;
657
+ /**
658
+ * Helper type to infer dependency extensions with optional support
659
+ *
660
+ * @internal
661
+ */
662
+ type InferDependencyExtensions<D extends ReadonlyArray<PluginDependency | string>, A extends ExtendContext> = D extends readonly [] ? {} : D extends readonly [infer First, ...infer Rest] ? ProcessDependency<First, A> & (Rest extends ReadonlyArray<PluginDependency | string> ? InferDependencyExtensions<Rest, A> : {}) : {};
257
663
  /**
258
664
  * Plugin dependency definition
665
+ *
259
666
  * @since v0.27.0
260
667
  */
261
668
  interface PluginDependency {
@@ -265,34 +672,68 @@ interface PluginDependency {
265
672
  id: string;
266
673
  /**
267
674
  * Optional dependency flag.
268
- * If true, the plugin will not throw an error if the dependency is not found.
675
+ * If `true`, the plugin will not throw an error if the dependency is not found
269
676
  */
270
677
  optional?: boolean;
271
678
  }
272
679
  /**
273
680
  * Plugin function type
681
+ *
682
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the {@linkcode PluginContext}.
683
+ *
274
684
  * @since v0.27.0
275
685
  */
276
686
  type PluginFunction<G extends GunshiParams = DefaultGunshiParams> = (ctx: Readonly<PluginContext<G>>) => Awaitable<void>;
277
687
  /**
278
- * Plugin extension for CommandContext
688
+ * Plugin extension
689
+ *
690
+ * @typeParam T - The type of the extension object returned by the plugin extension function.
691
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of {@linkcode CommandContextCore}.
692
+ *
693
+ * @param ctx - The {@linkcode CommandContextCore | command context} core
694
+ * @param cmd - The {@linkcode Command | command} to which the plugin is being applied
695
+ * @returns An object of type T that represents the extension provided by the plugin
696
+ *
279
697
  * @since v0.27.0
280
698
  */
281
699
  type PluginExtension<T = Record<string, unknown>, G extends GunshiParams = DefaultGunshiParams> = (ctx: CommandContextCore<G>, cmd: Command<G>) => Awaitable<T>;
282
700
  /**
283
- * Plugin extension callback type
701
+ * Plugin extension callback, which is called when the plugin is extended with `extension` option.
702
+ *
703
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of {@linkcode CommandContext} and {@linkcode Command}.
704
+ *
705
+ * @param ctx - The {@linkcode CommandContext | command context}
706
+ * @param cmd - The {@linkcode Command | command}
707
+ *
284
708
  * @since v0.27.0
285
709
  */
286
710
  type OnPluginExtension<G extends GunshiParams = DefaultGunshiParams> = (ctx: Readonly<CommandContext<G>>, cmd: Readonly<Command<G>>) => Awaitable<void>;
711
+ type IsStringLiteral<S extends string> = string extends S ? false : true;
712
+ type MergeExtension<Id, ResolvedDepExt extends ExtendContext, PluginExt extends ExtendContext> = Id extends infer I ? I extends string ? IsStringLiteral<I> extends true ? ResolvedDepExt & { [K in I]: PluginExt } : ResolvedDepExt : ResolvedDepExt : ResolvedDepExt;
287
713
  /**
288
714
  * Plugin definition options
715
+ *
289
716
  * @since v0.27.0
290
717
  */
291
- interface PluginOptions<T extends Record<string, unknown> = Record<never, never>, G extends GunshiParams = DefaultGunshiParams> {
718
+ interface PluginOptions<DepExt extends ExtendContext = DefaultGunshiParams['extensions'],
719
+ // for plugin dependency extensions
720
+ Id extends string = string,
721
+ // for plugin id
722
+ Deps extends ReadonlyArray<PluginDependency | string> = (PluginDependency | string)[],
723
+ // for plugin dependencies
724
+ Ext extends Record<string, unknown> = {},
725
+ // for plugin extension type
726
+ ResolvedDepExt extends GunshiParams = GunshiParams<{
727
+ args: Args;
728
+ extensions: InferDependencyExtensions<Deps, DepExt>;
729
+ }>, PluginExt extends PluginExtension<Ext, ResolvedDepExt> = PluginExtension<Ext, ResolvedDepExt>, MergedExt extends GunshiParams = GunshiParams<{
730
+ args: Args;
731
+ extensions: MergeExtension<Id, InferDependencyExtensions<Deps, DepExt>, Awaited<ReturnType<PluginExt>>>;
732
+ }>> {
292
733
  /**
293
734
  * Plugin unique identifier
294
735
  */
295
- id: string;
736
+ id: Id;
296
737
  /**
297
738
  * Plugin name
298
739
  */
@@ -300,24 +741,28 @@ interface PluginOptions<T extends Record<string, unknown> = Record<never, never>
300
741
  /**
301
742
  * Plugin dependencies
302
743
  */
303
- dependencies?: (PluginDependency | string)[];
744
+ dependencies?: Deps;
304
745
  /**
305
746
  * Plugin setup function
306
747
  */
307
- setup?: PluginFunction<G>;
748
+ setup?: PluginFunction<MergedExt>;
308
749
  /**
309
750
  * Plugin extension
310
751
  */
311
- extension?: PluginExtension<T, G>;
752
+ extension?: PluginExt;
312
753
  /**
313
754
  * Callback for when the plugin is extended with `extension` option.
314
755
  */
315
- onExtension?: OnPluginExtension<G>;
756
+ onExtension?: OnPluginExtension<MergedExt>;
316
757
  }
317
758
  /**
318
759
  * Gunshi plugin, which is a function that receives a PluginContext.
319
- * @param ctx - A {@link PluginContext}.
320
- * @returns An {@link Awaitable} that resolves when the plugin is loaded.
760
+ *
761
+ * @typeParam E - A type extending {@link GunshiParams} to specify the shape of {@linkcode CommandContext}'s extensions.
762
+ *
763
+ * @param ctx - A {@linkcode PluginContext}.
764
+ * @returns An {@linkcode Awaitable} that resolves when the plugin is loaded.
765
+ *
321
766
  * @since v0.27.0
322
767
  */
323
768
  type Plugin<E extends GunshiParams['extensions'] = DefaultGunshiParams['extensions']> = PluginFunction & {
@@ -327,68 +772,153 @@ type Plugin<E extends GunshiParams['extensions'] = DefaultGunshiParams['extensio
327
772
  extension?: CommandContextExtension<E>;
328
773
  };
329
774
  /**
330
- * Plugin return type with extension
331
- * @internal
775
+ * Plugin return type with extension, which includes the plugin ID, name, dependencies, and extension.
776
+ *
777
+ * This type is used to define a plugin at `plugin` function.
778
+ *
779
+ * @typeParam E - A type extending {@link GunshiParams} to specify the shape of {@linkcode CommandContext}'s extensions.
332
780
  */
333
781
  interface PluginWithExtension<E extends GunshiParams['extensions'] = DefaultGunshiParams['extensions']> extends Plugin<E> {
782
+ /**
783
+ * Plugin identifier
784
+ */
334
785
  id: string;
786
+ /**
787
+ * Plugin name
788
+ */
335
789
  name: string;
790
+ /**
791
+ * Plugin dependencies
792
+ */
336
793
  dependencies?: (PluginDependency | string)[];
794
+ /**
795
+ * Plugin extension
796
+ */
337
797
  extension: CommandContextExtension<E>;
338
798
  }
339
799
  /**
340
- * Plugin return type without extension
341
- * @internal
800
+ * Plugin return type without extension, which includes the plugin ID, name, and dependencies, but no extension.
801
+ *
802
+ * This type is used to define a plugin at `plugin` function without extension.
803
+ *
804
+ * @typeParam E - A type extending {@link GunshiParams} to specify the shape of {@linkcode CommandContext}'s extensions.
342
805
  */
343
806
  interface PluginWithoutExtension<E extends GunshiParams['extensions'] = DefaultGunshiParams['extensions']> extends Plugin<E> {
807
+ /**
808
+ * Plugin identifier
809
+ */
344
810
  id: string;
811
+ /**
812
+ * Plugin name
813
+ */
345
814
  name: string;
815
+ /**
816
+ * Plugin dependencies
817
+ */
346
818
  dependencies?: (PluginDependency | string)[];
347
819
  }
348
820
  /**
349
- * Define a plugin with extension capabilities
350
- * @param options - {@link PluginOptions | plugin options}
351
- * @return A defined plugin with extension capabilities.
821
+ * Define a plugin with extension compatibility and typed dependency extensions
822
+ *
823
+ * @typeParam Context - A type extending {@linkcode ExtendContext} to specify the shape of plugin dependency extensions.
824
+ * @typeParam Id - A string type to specify the plugin ID.
825
+ * @typeParam Deps - A readonly array of {@linkcode PluginDependency} or string to specify the plugin dependencies.
826
+ * @typeParam Extension - A type to specify the shape of the plugin extension object.
827
+ *
828
+ * @param options - {@linkcode PluginOptions | plugin options}
829
+ * @returns A defined plugin with extension
830
+ *
352
831
  * @since v0.27.0
353
832
  */
354
- declare function plugin<I extends string, P extends PluginExtension<any, DefaultGunshiParams>>(options: {
355
- id: I;
833
+ declare function plugin<Context extends ExtendContext = DefaultGunshiParams['extensions'],
834
+ // for plugin dependency extensions
835
+ Id extends string = string,
836
+ // for plugin id
837
+ Deps extends ReadonlyArray<PluginDependency | string> = [],
838
+ // for plugin dependencies
839
+ Extension extends {} = {},
840
+ // for plugin extension type
841
+ ResolvedDepExtensions extends GunshiParams = GunshiParams<{
842
+ args: Args;
843
+ extensions: InferDependencyExtensions<Deps, Context>;
844
+ }>, PluginExt extends PluginExtension<Extension, DefaultGunshiParams> = PluginExtension<Extension, ResolvedDepExtensions>, MergedExtensions extends GunshiParams = GunshiParams<{
845
+ args: Args;
846
+ extensions: MergeExtension<Id, InferDependencyExtensions<Deps, Context>, Awaited<ReturnType<PluginExt>>>;
847
+ }>>(options: {
848
+ id: Id;
356
849
  name?: string;
357
- dependencies?: (PluginDependency | string)[];
850
+ dependencies?: Deps;
358
851
  setup?: (ctx: Readonly<PluginContext<GunshiParams<{
359
852
  args: Args;
360
- extensions: { [K in I]: Awaited<ReturnType<P>> };
853
+ extensions: MergeExtension<Id, InferDependencyExtensions<Deps, Context>, Awaited<ReturnType<PluginExt>>>;
361
854
  }>>>) => Awaitable<void>;
362
- extension: P;
363
- onExtension?: OnPluginExtension<{
364
- args: Args;
365
- extensions: { [K in I]: Awaited<ReturnType<P>> };
366
- }>;
367
- }): PluginWithExtension<Awaited<ReturnType<P>>>;
855
+ extension: PluginExt;
856
+ onExtension?: OnPluginExtension<MergedExtensions>;
857
+ }): PluginWithExtension<Awaited<ReturnType<PluginExt>>>;
368
858
  /**
369
- * Define a plugin without extension capabilities
370
- * @param options - {@link PluginOptions | plugin options} without extension
371
- * @returns A defined plugin without extension capabilities.
859
+ * Define a plugin without extension and typed dependency extensions
860
+ *
861
+ * @typeParam Context - A type extending {@linkcode ExtendContext} to specify the shape of plugin dependency extensions.
862
+ * @typeParam Id - A string type to specify the plugin ID.
863
+ * @typeParam Deps - A readonly array of {@linkcode PluginDependency} or string to specify the plugin dependencies.
864
+ * @typeParam Extension - A type to specify the shape of the plugin extension object.
865
+ *
866
+ * @param options - {@linkcode PluginOptions | plugin options} without extension
867
+ * @returns A defined plugin without extension
868
+ *
372
869
  * @since v0.27.0
373
870
  */
374
- declare function plugin(options: {
375
- id: string;
871
+ declare function plugin<Context extends ExtendContext = DefaultGunshiParams['extensions'],
872
+ // for plugin dependency extensions
873
+ Id extends string = string,
874
+ // for plugin id
875
+ Deps extends ReadonlyArray<PluginDependency | string> = [],
876
+ // for plugin dependencies
877
+ Extension extends Record<string, unknown> = {},
878
+ // for plugin extension type
879
+ ResolvedDepExtensions extends GunshiParams = GunshiParams<{
880
+ args: Args;
881
+ extensions: InferDependencyExtensions<Deps, Context>;
882
+ }>, PluginExt extends PluginExtension<Extension, DefaultGunshiParams> = PluginExtension<Extension, ResolvedDepExtensions>, MergedExtensions extends GunshiParams = GunshiParams<{
883
+ args: Args;
884
+ extensions: MergeExtension<Id, InferDependencyExtensions<Deps, Context>, Awaited<ReturnType<PluginExt>>>;
885
+ }>>(options: {
886
+ id: Id;
376
887
  name?: string;
377
- dependencies?: (PluginDependency | string)[];
378
- setup?: (ctx: Readonly<PluginContext<DefaultGunshiParams>>) => Awaitable<void>;
379
- onExtension?: OnPluginExtension<DefaultGunshiParams>;
888
+ dependencies?: Deps;
889
+ setup?: (ctx: Readonly<PluginContext<GunshiParams<{
890
+ args: Args;
891
+ extensions: MergeExtension<Id, InferDependencyExtensions<Deps, Context>, Awaited<ReturnType<PluginExt>>>;
892
+ }>>>) => Awaitable<void>;
893
+ onExtension?: OnPluginExtension<MergedExtensions>;
380
894
  }): PluginWithoutExtension<DefaultGunshiParams['extensions']>;
381
895
  //#endregion
382
896
  //#region ../gunshi/src/types.d.ts
897
+ /**
898
+ * Awaitable type.
899
+ *
900
+ * @typeParam T - The type of the value that can be awaited.
901
+ */
383
902
  type Awaitable<T> = T | Promise<T>;
384
903
  /**
385
- * Extend command context type. This type is used to extend the command context with additional properties at {@link CommandContext.extensions}.
904
+ * Prettify a type by flattening its structure.
905
+ *
906
+ * @typeParam T - The type to be prettified.
907
+ */
908
+ type Prettify<T> = { [K in keyof T]: T[K] } & {};
909
+ /**
910
+ * Extend command context type. This type is used to extend the command context with additional properties at {@linkcode CommandContext.extensions}.
911
+ *
386
912
  * @since v0.27.0
387
913
  */
388
914
  type ExtendContext = Record<string, unknown>;
389
915
  /**
390
916
  * Gunshi unified parameter type.
917
+ *
391
918
  * This type combines both argument definitions and command context extensions.
919
+ *
920
+ * @typeParam P - The type of parameters, which can include `args` and `extensions`.
921
+ *
392
922
  * @since v0.27.0
393
923
  */
394
924
  interface GunshiParams<P extends {
@@ -399,50 +929,65 @@ interface GunshiParams<P extends {
399
929
  extensions: {};
400
930
  }> {
401
931
  /**
402
- * Command argument definitions
932
+ * Command argument definitions.
403
933
  */
404
934
  args: P extends {
405
935
  args: infer A extends Args;
406
936
  } ? A : Args;
407
937
  /**
408
- * Command context extensions
938
+ * Command context extensions.
409
939
  */
410
940
  extensions: P extends {
411
941
  extensions: infer E extends ExtendContext;
412
942
  } ? E : {};
413
943
  }
414
944
  /**
415
- * Default Gunshi parameters
945
+ * Default Gunshi parameters.
946
+ *
416
947
  * @since v0.27.0
417
948
  */
418
949
  type DefaultGunshiParams = GunshiParams;
419
950
  /**
420
951
  * Generic constraint for command-related types.
421
- * This type constraint allows both GunshiParams and objects with extensions.
952
+ *
953
+ * This type constraint allows both {@linkcode GunshiParams} and objects with extensions.
954
+ *
422
955
  * @since v0.27.0
423
956
  */
424
957
  type GunshiParamsConstraint = GunshiParams<any> | {
958
+ args: Args;
959
+ } | {
425
960
  extensions: ExtendContext;
426
961
  };
427
962
  /**
428
- * Type helper to extract args from G
963
+ * Type helper to extract args
964
+ *
965
+ * @typeParam G - The type of {@linkcode GunshiParams} or an object with {@linkcode Args}.
966
+ *
429
967
  * @internal
430
968
  */
431
- type ExtractArgs<G> = G extends GunshiParams<any> ? G['args'] : Args;
969
+ type ExtractArgs<G> = G extends GunshiParams<any> ? G['args'] : G extends {
970
+ args: infer A extends Args;
971
+ } ? A : Args;
432
972
  /**
433
- * Type helper to extract explicitly provided argument flags from G
973
+ * Type helper to extract explicitly provided argument flags.
974
+ *
975
+ * @typeParam G - The type of {@linkcode GunshiParams}.
976
+ *
434
977
  * @internal
435
978
  */
436
979
  type ExtractArgExplicitlyProvided<G> = ArgExplicitlyProvided<ExtractArgs<G>>;
437
980
  /**
438
981
  * Type helper to extract extensions from G
982
+ *
439
983
  * @internal
440
984
  */
441
- type ExtractExtensions$1<G> = G extends GunshiParams<any> ? G['extensions'] : G extends {
985
+ type ExtractExtensions<G> = G extends GunshiParams<any> ? G['extensions'] : G extends {
442
986
  extensions: infer E;
443
987
  } ? E : {};
444
988
  /**
445
989
  * Type helper to normalize G to GunshiParams
990
+ *
446
991
  * @internal
447
992
  */
448
993
  type NormalizeToGunshiParams<G> = G extends GunshiParams<any> ? G : G extends {
@@ -453,62 +998,73 @@ type NormalizeToGunshiParams<G> = G extends GunshiParams<any> ? G : G extends {
453
998
  }> : DefaultGunshiParams;
454
999
  /**
455
1000
  * Command environment.
1001
+ *
1002
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command environments.
456
1003
  */
457
1004
  interface CommandEnvironment<G extends GunshiParamsConstraint = DefaultGunshiParams> {
458
1005
  /**
459
1006
  * Current working directory.
460
- * @see {@link CliOptions.cwd}
1007
+ *
1008
+ * @see {@linkcode CliOptions.cwd}
461
1009
  */
462
1010
  cwd: string | undefined;
463
1011
  /**
464
1012
  * Command name.
465
- * @see {@link CliOptions.name}
1013
+ *
1014
+ * @see {@linkcode CliOptions.name}
466
1015
  */
467
1016
  name: string | undefined;
468
1017
  /**
469
1018
  * Command description.
470
- * @see {@link CliOptions.description}
471
1019
  *
1020
+ * @see {@linkcode CliOptions.description}
472
1021
  */
473
1022
  description: string | undefined;
474
1023
  /**
475
1024
  * Command version.
476
- * @see {@link CliOptions.version}
1025
+ *
1026
+ * @see {@linkcode CliOptions.version}
477
1027
  */
478
1028
  version: string | undefined;
479
1029
  /**
480
1030
  * Left margin of the command output.
1031
+ *
481
1032
  * @default 2
482
- * @see {@link CliOptions.leftMargin}
1033
+ * @see {@linkcode CliOptions.leftMargin}
483
1034
  */
484
1035
  leftMargin: number;
485
1036
  /**
486
1037
  * Middle margin of the command output.
1038
+ *
487
1039
  * @default 10
488
- * @see {@link CliOptions.middleMargin}
1040
+ * @see {@linkcode CliOptions.middleMargin}
489
1041
  */
490
1042
  middleMargin: number;
491
1043
  /**
492
1044
  * Whether to display the usage option type.
1045
+ *
493
1046
  * @default false
494
- * @see {@link CliOptions.usageOptionType}
1047
+ * @see {@linkcode CliOptions.usageOptionType}
495
1048
  */
496
1049
  usageOptionType: boolean;
497
1050
  /**
498
1051
  * Whether to display the option value.
1052
+ *
499
1053
  * @default true
500
- * @see {@link CliOptions.usageOptionValue}
1054
+ * @see {@linkcode CliOptions.usageOptionValue}
501
1055
  */
502
1056
  usageOptionValue: boolean;
503
1057
  /**
504
1058
  * Whether to display the command usage.
1059
+ *
505
1060
  * @default false
506
- * @see {@link CliOptions.usageSilent}
1061
+ * @see {@linkcode CliOptions.usageSilent}
507
1062
  */
508
1063
  usageSilent: boolean;
509
1064
  /**
510
1065
  * Sub commands.
511
- * @see {@link CliOptions.subCommands}
1066
+ *
1067
+ * @see {@linkcode CliOptions.subCommands}
512
1068
  */
513
1069
  subCommands: Map<string, Command<any> | LazyCommand<any>> | undefined;
514
1070
  /**
@@ -525,25 +1081,30 @@ interface CommandEnvironment<G extends GunshiParamsConstraint = DefaultGunshiPar
525
1081
  renderValidationErrors: ((ctx: Readonly<CommandContext<G>>, error: AggregateError) => Promise<string>) | null | undefined;
526
1082
  /**
527
1083
  * Hook that runs before any command execution
528
- * @see {@link CliOptions.onBeforeCommand}
1084
+ *
1085
+ * @see {@linkcode CliOptions.onBeforeCommand}
529
1086
  * @since v0.27.0
530
1087
  */
531
1088
  onBeforeCommand: ((ctx: Readonly<CommandContext<G>>) => Awaitable<void>) | undefined;
532
1089
  /**
533
1090
  * Hook that runs after successful command execution
534
- * @see {@link CliOptions.onAfterCommand}
1091
+ *
1092
+ * @see {@linkcode CliOptions.onAfterCommand}
535
1093
  * @since v0.27.0
536
1094
  */
537
1095
  onAfterCommand: ((ctx: Readonly<CommandContext<G>>, result: string | undefined) => Awaitable<void>) | undefined;
538
1096
  /**
539
1097
  * Hook that runs when a command throws an error
540
- * @see {@link CliOptions.onErrorCommand}
1098
+ *
1099
+ * @see {@linkcode CliOptions.onErrorCommand}
541
1100
  * @since v0.27.0
542
1101
  */
543
1102
  onErrorCommand: ((ctx: Readonly<CommandContext<G>>, error: Error) => Awaitable<void>) | undefined;
544
1103
  }
545
1104
  /**
546
- * CLI options of `cli` function.
1105
+ * CLI options of {@linkcode cli} function.
1106
+ *
1107
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of cli options.
547
1108
  */
548
1109
  interface CliOptions<G extends GunshiParamsConstraint = DefaultGunshiParams> {
549
1110
  /**
@@ -566,7 +1127,7 @@ interface CliOptions<G extends GunshiParamsConstraint = DefaultGunshiParams> {
566
1127
  /**
567
1128
  * Sub commands.
568
1129
  */
569
- subCommands?: Map<string, Command<any> | LazyCommand<any>>;
1130
+ subCommands?: Record<string, Command<any> | LazyCommand<any>> | Map<string, Command<any> | LazyCommand<any>>;
570
1131
  /**
571
1132
  * Left margin of the command output.
572
1133
  */
@@ -599,19 +1160,29 @@ interface CliOptions<G extends GunshiParamsConstraint = DefaultGunshiParams> {
599
1160
  * Render function the validation errors.
600
1161
  */
601
1162
  renderValidationErrors?: ((ctx: Readonly<CommandContext<G>>, error: AggregateError) => Promise<string>) | null;
1163
+ /**
1164
+ * Whether to fallback to entry command when the sub-command is not found.
1165
+ *
1166
+ * @default false
1167
+ * @since v0.27.0
1168
+ */
1169
+ fallbackToEntry?: boolean;
602
1170
  /**
603
1171
  * User plugins.
1172
+ *
604
1173
  * @since v0.27.0
605
1174
  */
606
1175
  plugins?: Plugin[];
607
1176
  /**
608
1177
  * Hook that runs before any command execution
1178
+ *
609
1179
  * @param ctx - The command context
610
1180
  * @since v0.27.0
611
1181
  */
612
1182
  onBeforeCommand?: (ctx: Readonly<CommandContext<G>>) => Awaitable<void>;
613
1183
  /**
614
1184
  * Hook that runs after successful command execution
1185
+ *
615
1186
  * @param ctx - The command context
616
1187
  * @param result - The command execution result
617
1188
  * @since v0.27.0
@@ -619,6 +1190,7 @@ interface CliOptions<G extends GunshiParamsConstraint = DefaultGunshiParams> {
619
1190
  onAfterCommand?: (ctx: Readonly<CommandContext<G>>, result: string | undefined) => Awaitable<void>;
620
1191
  /**
621
1192
  * Hook that runs when a command throws an error
1193
+ *
622
1194
  * @param ctx - The command context
623
1195
  * @param error - The error thrown during execution
624
1196
  * @since v0.27.0
@@ -627,31 +1199,37 @@ interface CliOptions<G extends GunshiParamsConstraint = DefaultGunshiParams> {
627
1199
  }
628
1200
  /**
629
1201
  * Command call mode.
1202
+ *
1203
+ * - `entry`: The command is executed as an entry command.
1204
+ * - `subCommand`: The command is executed as a sub-command.
630
1205
  */
631
1206
  type CommandCallMode = 'entry' | 'subCommand' | 'unexpected';
632
1207
  /**
633
1208
  * Command context.
1209
+ *
634
1210
  * Command context is the context of the command execution.
1211
+ *
1212
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command context.
635
1213
  */
636
1214
  interface CommandContext<G extends GunshiParamsConstraint = DefaultGunshiParams> {
637
1215
  /**
638
1216
  * Command name, that is the command that is executed.
639
- * The command name is same {@link CommandEnvironment.name}.
1217
+ * The command name is same {@linkcode CommandEnvironment.name}.
640
1218
  */
641
1219
  name: string | undefined;
642
1220
  /**
643
1221
  * Command description, that is the description of the command that is executed.
644
- * The command description is same {@link CommandEnvironment.description}.
1222
+ * The command description is same {@linkcode CommandEnvironment.description}.
645
1223
  */
646
1224
  description: string | undefined;
647
1225
  /**
648
1226
  * Command environment, that is the environment of the command that is executed.
649
- * The command environment is same {@link CommandEnvironment}.
1227
+ * The command environment is same {@linkcode CommandEnvironment}.
650
1228
  */
651
1229
  env: Readonly<CommandEnvironment<G>>;
652
1230
  /**
653
1231
  * Command arguments, that is the arguments of the command that is executed.
654
- * The command arguments is same {@link Command.args}.
1232
+ * The command arguments is same {@linkcode Command.args}.
655
1233
  */
656
1234
  args: ExtractArgs<G>;
657
1235
  /**
@@ -665,7 +1243,7 @@ interface CommandContext<G extends GunshiParamsConstraint = DefaultGunshiParams>
665
1243
  explicit: ExtractArgExplicitlyProvided<G>;
666
1244
  /**
667
1245
  * Command values, that is the values of the command that is executed.
668
- * Resolve values with `resolveArgs` from command arguments and {@link Command.args}.
1246
+ * Resolve values with `resolveArgs` from command arguments and {@linkcode Command.args}.
669
1247
  */
670
1248
  values: ArgValues<ExtractArgs<G>>;
671
1249
  /**
@@ -697,22 +1275,24 @@ interface CommandContext<G extends GunshiParamsConstraint = DefaultGunshiParams>
697
1275
  callMode: CommandCallMode;
698
1276
  /**
699
1277
  * Whether to convert the camel-case style argument name to kebab-case.
700
- * This context value is set from {@link Command.toKebab} option.
1278
+ * This context value is set from {@linkcode Command.toKebab} option.
701
1279
  */
702
1280
  toKebab?: boolean;
703
1281
  /**
704
1282
  * Output a message.
705
- * If {@link CommandEnvironment.usageSilent} is true, the message is not output.
706
- * @param message an output message, @see {@link console.log}
707
- * @param optionalParams an optional parameters, @see {@link console.log}
708
- * @internal
1283
+ *
1284
+ * If {@linkcode CommandEnvironment.usageSilent} is true, the message is not output.
1285
+ *
1286
+ * @param message - an output message, see {@linkcode console.log}
1287
+ * @param optionalParams - an optional parameters, see {@linkcode console.log}
709
1288
  */
710
1289
  log: (message?: any, ...optionalParams: any[]) => void;
711
1290
  /**
712
1291
  * Command context extensions.
1292
+ *
713
1293
  * @since v0.27.0
714
1294
  */
715
- extensions: keyof ExtractExtensions$1<G> extends never ? undefined : ExtractExtensions$1<G>;
1295
+ extensions: keyof ExtractExtensions<G> extends never ? any : ExtractExtensions<G>;
716
1296
  /**
717
1297
  * Validation error from argument parsing.
718
1298
  * This will be set if argument validation fails during CLI execution.
@@ -721,20 +1301,38 @@ interface CommandContext<G extends GunshiParamsConstraint = DefaultGunshiParams>
721
1301
  }
722
1302
  /**
723
1303
  * CommandContextCore type (base type without extensions)
1304
+ *
1305
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command context.
1306
+ *
724
1307
  * @since v0.27.0
725
1308
  */
726
1309
  type CommandContextCore<G extends GunshiParamsConstraint = DefaultGunshiParams> = Readonly<CommandContext<G>>;
727
1310
  /**
728
1311
  * Command context extension
1312
+ *
1313
+ * @typeParam E - A type extending {@linkcode GunshiParams.extensions} to specify the shape of the extension.
1314
+ *
729
1315
  * @since v0.27.0
730
1316
  */
731
1317
  interface CommandContextExtension<E extends GunshiParams['extensions'] = DefaultGunshiParams['extensions']> {
1318
+ /**
1319
+ * Plugin identifier
1320
+ */
732
1321
  readonly key: symbol;
1322
+ /**
1323
+ * Plugin extension factory
1324
+ */
733
1325
  readonly factory: (ctx: CommandContextCore, cmd: Command) => Awaitable<E>;
1326
+ /**
1327
+ * Plugin extension factory after hook
1328
+ */
734
1329
  readonly onFactory?: (ctx: Readonly<CommandContext>, cmd: Readonly<Command>) => Awaitable<void>;
735
1330
  }
736
1331
  /**
737
1332
  * Rendering control options
1333
+ *
1334
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of render options.
1335
+ *
738
1336
  * @since v0.27.0
739
1337
  */
740
1338
  interface RenderingOptions<G extends GunshiParamsConstraint = DefaultGunshiParams> {
@@ -762,6 +1360,8 @@ interface RenderingOptions<G extends GunshiParamsConstraint = DefaultGunshiParam
762
1360
  }
763
1361
  /**
764
1362
  * Command interface.
1363
+ *
1364
+ * @typeParam G - The Gunshi parameters constraint
765
1365
  */
766
1366
  interface Command<G extends GunshiParamsConstraint = DefaultGunshiParams> {
767
1367
  /**
@@ -790,89 +1390,108 @@ interface Command<G extends GunshiParamsConstraint = DefaultGunshiParams> {
790
1390
  run?: CommandRunner<G>;
791
1391
  /**
792
1392
  * Whether to convert the camel-case style argument name to kebab-case.
793
- * If you will set to `true`, All {@link Command.args} names will be converted to kebab-case.
1393
+ * If you will set to `true`, All {@linkcode Command.args} names will be converted to kebab-case.
794
1394
  */
795
1395
  toKebab?: boolean;
796
1396
  /**
797
1397
  * Whether this is an internal command.
798
1398
  * Internal commands are not shown in help usage.
1399
+ *
799
1400
  * @default false
800
1401
  * @since v0.27.0
801
1402
  */
802
1403
  internal?: boolean;
803
1404
  /**
804
1405
  * Whether this command is an entry command.
1406
+ *
805
1407
  * @default undefined
806
1408
  * @since v0.27.0
807
1409
  */
808
1410
  entry?: boolean;
809
1411
  /**
810
1412
  * Rendering control options
1413
+ *
811
1414
  * @since v0.27.0
812
1415
  */
813
1416
  rendering?: RenderingOptions<G>;
814
1417
  }
815
1418
  /**
816
1419
  * Lazy command interface.
1420
+ *
817
1421
  * Lazy command that's not loaded until it is executed.
1422
+ *
1423
+ * @typeParam G - The Gunshi parameters constraint
1424
+ * @typeParam D - The partial command definition provided to lazy function
818
1425
  */
819
- type LazyCommand<G extends GunshiParamsConstraint = DefaultGunshiParams> = {
1426
+ type LazyCommand<G extends GunshiParamsConstraint = DefaultGunshiParams, D extends Partial<Command<G>> = {}> = {
820
1427
  /**
821
1428
  * Command load function
822
1429
  */
823
1430
  (): Awaitable<Command<G> | CommandRunner<G>>;
824
- /**
825
- * Command name
826
- */
1431
+ } & (D extends {
1432
+ name: infer N;
1433
+ } ? {
1434
+ commandName: N;
1435
+ } : {
827
1436
  commandName?: string;
828
- } & Omit<Command<G>, 'run' | 'name'>;
829
- /**
830
- * Define a command type.
831
- */
832
-
1437
+ }) & Omit<D, 'name' | 'run'> & Partial<Omit<Command<G>, keyof D | 'run' | 'name'>>;
833
1438
  /**
834
1439
  * Command examples fetcher.
835
- * @param ctx A {@link CommandContext | command context}
1440
+ *
1441
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command context.
1442
+ *
1443
+ * @param ctx - A {@link CommandContext | command context}
836
1444
  * @returns A fetched command examples.
837
1445
  */
838
1446
  type CommandExamplesFetcher<G extends GunshiParamsConstraint = DefaultGunshiParams> = (ctx: Readonly<CommandContext<G>>) => Awaitable<string>;
839
1447
  /**
840
1448
  * Command runner.
841
- * @param ctx A {@link CommandContext | command context}
1449
+ *
1450
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command context.
1451
+ *
1452
+ * @param ctx - A {@link CommandContext | command context}
842
1453
  * @returns void or string (for CLI output)
843
1454
  */
844
1455
  type CommandRunner<G extends GunshiParamsConstraint = DefaultGunshiParams> = (ctx: Readonly<CommandContext<G>>) => Awaitable<string | void>;
845
- /**
846
- * Command loader.
847
- * A function that returns a command or command runner.
848
- * This is used to lazily load commands.
849
- * @returns A command or command runner
850
- */
851
-
852
1456
  /**
853
1457
  * Command decorator.
1458
+ *
854
1459
  * A function that wraps a command runner to add or modify its behavior.
855
- * @param baseRunner The base command runner to decorate
1460
+ *
1461
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command context.
1462
+ *
1463
+ * @param baseRunner - The base command runner to decorate
856
1464
  * @returns The decorated command runner
1465
+ *
857
1466
  * @since v0.27.0
858
1467
  */
859
1468
  type CommandDecorator<G extends GunshiParamsConstraint = DefaultGunshiParams> = (baseRunner: (ctx: Readonly<CommandContext<G>>) => Awaitable<string | void>) => (ctx: Readonly<CommandContext<G>>) => Awaitable<string | void>;
860
1469
  /**
861
1470
  * Renderer decorator type.
1471
+ *
862
1472
  * A function that wraps a base renderer to add or modify its behavior.
863
- * @param baseRenderer The base renderer function to decorate
864
- * @param ctx The command context
1473
+ *
1474
+ * @typeParam T - The type of the rendered result.
1475
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command context.
1476
+ *
1477
+ * @param baseRenderer - The base renderer function to decorate
1478
+ * @param ctx - The command context
865
1479
  * @returns The decorated result
1480
+ *
866
1481
  * @since v0.27.0
867
1482
  */
868
1483
  type RendererDecorator<T, G extends GunshiParamsConstraint = DefaultGunshiParams> = (baseRenderer: (ctx: Readonly<CommandContext<G>>) => Promise<T>, ctx: Readonly<CommandContext<G>>) => Promise<T>;
869
1484
  /**
870
1485
  * Validation errors renderer decorator type.
871
1486
  * A function that wraps a validation errors renderer to add or modify its behavior.
872
- * @param baseRenderer The base validation errors renderer function to decorate
873
- * @param ctx The command context
874
- * @param error The aggregate error containing validation errors
1487
+ *
1488
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command context.
1489
+ *
1490
+ * @param baseRenderer - The base validation errors renderer function to decorate
1491
+ * @param ctx - The command context
1492
+ * @param error - The aggregate error containing validation errors
875
1493
  * @returns The decorated result
1494
+ *
876
1495
  * @since v0.27.0
877
1496
  */
878
1497
  type ValidationErrorsDecorator<G extends GunshiParamsConstraint = DefaultGunshiParams> = (baseRenderer: (ctx: Readonly<CommandContext<G>>, error: AggregateError) => Promise<string>, ctx: Readonly<CommandContext<G>>, error: AggregateError) => Promise<string>;
@@ -884,55 +1503,58 @@ declare const CLI_OPTIONS_DEFAULT: CliOptions<DefaultGunshiParams>;
884
1503
  //#region ../gunshi/src/context.d.ts
885
1504
  /**
886
1505
  * Extract extension return types from extensions record
1506
+ *
887
1507
  * @internal
888
1508
  */
889
- type ExtractExtensions<E extends Record<string, CommandContextExtension>> = { [K in keyof E]: E[K] extends CommandContextExtension<infer T> ? T : never };
1509
+ type ExtractExtensions$1<E extends Record<string, CommandContextExtension>> = { [K in keyof E]: E[K] extends CommandContextExtension<infer T> ? T : never };
890
1510
  /**
891
1511
  * Parameters of {@link createCommandContext}
892
1512
  */
893
1513
  interface CommandContextParams<G extends GunshiParams | {
1514
+ args: Args;
1515
+ } | {
894
1516
  extensions: ExtendContext;
895
1517
  }, V extends ArgValues<ExtractArgs<G>>, C extends Command<G> | LazyCommand<G> = Command<G>, E extends Record<string, CommandContextExtension> = Record<string, CommandContextExtension>> {
896
1518
  /**
897
1519
  * An arguments of target command
898
1520
  */
899
- args: ExtractArgs<G>;
1521
+ args?: ExtractArgs<G>;
900
1522
  /**
901
1523
  * Explicitly provided arguments
902
1524
  */
903
- explicit: ExtractArgExplicitlyProvided<G>;
1525
+ explicit?: ExtractArgExplicitlyProvided<G>;
904
1526
  /**
905
1527
  * A values of target command
906
1528
  */
907
- values: V;
1529
+ values?: V;
908
1530
  /**
909
1531
  * A positionals arguments, which passed to the target command
910
1532
  */
911
- positionals: string[];
1533
+ positionals?: string[];
912
1534
  /**
913
1535
  * A rest arguments, which passed to the target command
914
1536
  */
915
- rest: string[];
1537
+ rest?: string[];
916
1538
  /**
917
1539
  * Original command line arguments
918
1540
  */
919
- argv: string[];
1541
+ argv?: string[];
920
1542
  /**
921
1543
  * Argument tokens that are parsed by the `parseArgs` function
922
1544
  */
923
- tokens: ArgToken[];
1545
+ tokens?: ArgToken[];
924
1546
  /**
925
1547
  * Whether the command is omitted
926
1548
  */
927
- omitted: boolean;
1549
+ omitted?: boolean;
928
1550
  /**
929
1551
  * Command call mode.
930
1552
  */
931
- callMode: CommandCallMode;
1553
+ callMode?: CommandCallMode;
932
1554
  /**
933
1555
  * A target command
934
1556
  */
935
- command: C;
1557
+ command?: C;
936
1558
  /**
937
1559
  * Plugin extensions to apply as the command context extension.
938
1560
  */
@@ -940,16 +1562,17 @@ interface CommandContextParams<G extends GunshiParams | {
940
1562
  /**
941
1563
  * A command options, which is spicialized from `cli` function
942
1564
  */
943
- cliOptions: CliOptions<G>;
1565
+ cliOptions?: CliOptions<G>;
944
1566
  /**
945
1567
  * Validation error from argument parsing.
946
1568
  */
947
1569
  validationError?: AggregateError;
948
1570
  }
949
1571
  /**
950
- * Create a {@link CommandContext | command context}
951
- * @param param A {@link CommandContextParams | parameters} to create a {@link CommandContext | command context}
952
- * @returns A {@link CommandContext | command context}, which is readonly
1572
+ * Create a command context.
1573
+ *
1574
+ * @param param - A {@link CommandContextParams | parameters} to create a command context.
1575
+ * @returns A {@link CommandContext | command context}, which is readonly.
953
1576
  */
954
1577
  declare function createCommandContext<G extends GunshiParamsConstraint = DefaultGunshiParams, V extends ArgValues<ExtractArgs<G>> = ArgValues<ExtractArgs<G>>, C extends Command<G> | LazyCommand<G> = Command<G>, E extends Record<string, CommandContextExtension> = {}>({
955
1578
  args,
@@ -965,9 +1588,9 @@ declare function createCommandContext<G extends GunshiParamsConstraint = Default
965
1588
  callMode,
966
1589
  omitted,
967
1590
  validationError
968
- }: CommandContextParams<G, V, C, E>): Promise<{} extends ExtractExtensions<E> ? Readonly<CommandContext<G>> : Readonly<CommandContext<GunshiParams<{
1591
+ }: CommandContextParams<G, V, C, E>): Promise<{} extends ExtractExtensions$1<E> ? Readonly<CommandContext<G>> : Readonly<CommandContext<GunshiParams<{
969
1592
  args: ExtractArgs<G>;
970
- extensions: ExtractExtensions<E>;
1593
+ extensions: ExtractExtensions$1<E>;
971
1594
  }>>>>;
972
1595
  //#endregion
973
- export { ANONYMOUS_COMMAND_NAME, type ArgSchema, type ArgToken, type ArgValues, type Args, Awaitable, CLI_OPTIONS_DEFAULT, Command, CommandContext, CommandContextCore, CommandContextExtension, CommandDecorator, CommandExamplesFetcher, CommandRunner, DefaultGunshiParams, ExtendContext, ExtractArgs, GunshiParams, GunshiParamsConstraint, LazyCommand, NormalizeToGunshiParams, OnPluginExtension, Plugin, PluginContext, PluginDependency, PluginExtension, PluginFunction, PluginOptions, PluginWithExtension, PluginWithoutExtension, RendererDecorator, ValidationErrorsDecorator, createCommandContext, plugin };
1596
+ export { ANONYMOUS_COMMAND_NAME, type ArgSchema, type ArgToken, type ArgValues, type Args, Awaitable, CLI_OPTIONS_DEFAULT, Command, CommandContext, CommandContextCore, CommandContextExtension, CommandContextParams, CommandDecorator, CommandExamplesFetcher, CommandRunner, DefaultGunshiParams, ExtendContext, ExtractArgs, ExtractExtensions, GunshiParams, GunshiParamsConstraint, LazyCommand, NormalizeToGunshiParams, OnPluginExtension, Plugin, PluginContext, PluginDependency, PluginExtension, PluginFunction, PluginOptions, PluginWithExtension, PluginWithoutExtension, Prettify, RendererDecorator, ValidationErrorsDecorator, createCommandContext, plugin };