1+ import defu from '@dword-design/defu' ;
12import {
23 Command as CommanderCommand ,
34 Option as CommanderOption ,
@@ -22,25 +23,40 @@ export type Command = {
2223} ;
2324
2425export type Config = {
25- version : string ;
26- name : string ;
26+ version ? : string ;
27+ name ? : string ;
2728 commands : Command [ ] ;
2829 options : Option [ ] ;
29- arguments : string ;
30- usage : string ;
30+ arguments ? : string ;
31+ usage ? : string ;
3132 allowUnknownOption : boolean ;
32- action : Handler ;
33- defaultCommandName : string ;
33+ action ? : Handler ;
34+ defaultCommandName ? : string ;
3435} ;
3536
36- const applyOptions = ( program , options : Option [ ] = [ ] ) => {
37- if ( ! Array . isArray ( options ) ) {
38- options = Object . entries < Option > ( options ) . map ( ( [ name , option ] ) => ( {
39- name,
40- ...option ,
41- } ) ) ;
42- }
37+ export type CommandObjectInput = Omit < Command , 'options' > & {
38+ options ?: OptionsInput ;
39+ } ;
40+
41+ export type CommandObjectInObjectInput = Omit < Option , 'name' > &
42+ Partial < Pick < Option , 'name' > > ;
43+
44+ export type CommandInObjectInput = CommandObjectInput | Handler ;
45+
46+ export type CommandsInput =
47+ | CommandObjectInput [ ]
48+ | Record < string , CommandInObjectInput > ;
49+
50+ export type OptionInObjectInput = Omit < Option , 'name' > &
51+ Partial < Pick < Option , 'name' > > ;
52+
53+ export type OptionsInput = Option [ ] | Record < string , OptionInObjectInput > ;
54+ type ConfigInput = Omit < Partial < Config > , 'commands' | 'options' > & {
55+ commands ?: CommandsInput ;
56+ options ?: OptionsInput ;
57+ } ;
4358
59+ const applyOptions = ( program , options : Option [ ] = [ ] ) => {
4460 for ( const option of options ) {
4561 const commanderOption = new CommanderOption (
4662 option . name ,
@@ -57,17 +73,50 @@ const applyOptions = (program, options: Option[] = []) => {
5773 }
5874} ;
5975
60- type ConfigInput = Partial < Config > ;
76+ const getNormalizedOptions = ( options ?: OptionsInput ) : Option [ ] => {
77+ if ( options === undefined ) {
78+ return [ ] ;
79+ }
80+
81+ if ( Array . isArray ( options ) ) {
82+ return options ;
83+ }
6184
62- export default ( config : ConfigInput = { } ) => {
63- config = { commands : [ ] , options : [ ] , ...config } ;
85+ return Object . entries ( options ) . map ( ( [ name , option ] ) =>
86+ defu ( option , { name } ) ,
87+ ) ;
88+ } ;
6489
65- if ( ! Array . isArray ( config . commands ) ) {
66- config . commands = Object . entries < Command > ( config . commands ) . map (
67- ( [ name , command ] ) => ( { name, ...command } ) ,
68- ) ;
90+ const getNormalizedCommands = ( commands ?: CommandsInput ) : Command [ ] => {
91+ if ( commands === undefined ) {
92+ return [ ] ;
6993 }
7094
95+ if ( Array . isArray ( commands ) ) {
96+ return commands . map ( command => ( {
97+ ...command ,
98+ options : getNormalizedOptions ( command . options ) ,
99+ } ) ) ;
100+ }
101+
102+ return Object . entries ( commands ) . map ( ( [ name , command ] ) => ( {
103+ name,
104+ ...( typeof command === 'function'
105+ ? { handler : command , options : [ ] }
106+ : { ...command , options : getNormalizedOptions ( command . options ) } ) ,
107+ } ) ) ;
108+ } ;
109+
110+ export default ( configInput : ConfigInput = { } ) => {
111+ const config : Config = defu (
112+ {
113+ ...configInput ,
114+ commands : getNormalizedCommands ( configInput . commands ) ,
115+ options : getNormalizedOptions ( configInput . options ) ,
116+ } ,
117+ { allowUnknownOption : false } ,
118+ ) ;
119+
71120 const program = new CommanderCommand ( ) ;
72121
73122 if ( config . version ) {
0 commit comments