11import { z } from "zod"
22import { ValidationError } from "./error"
3- import MassargOption , { MassargFlag , MassargNumber , OptionConfig , OptionType } from "./option"
4- import { isZodError } from "./utils"
3+ import MassargOption , { MassargFlag , MassargNumber , OptionConfig , TypedOptionConfig } from "./option"
4+ import { generateCommandsHelpTable , generateOptionsHelpTable , isZodError } from "./utils"
55
66export const CommandConfig = < RunArgs extends z . ZodType > ( args : RunArgs ) =>
77 z . object ( {
@@ -18,14 +18,16 @@ export type CommandConfig<T = unknown> = z.infer<ReturnType<typeof CommandConfig
1818
1919export type ArgsObject = Record < string , unknown >
2020
21+ // export type RunFn<Args extends ArgsObject> = (options: Args) => Promise<void> | void
22+
2123export default class MassargCommand < Args extends ArgsObject = ArgsObject > {
2224 name : string
2325 description : string
24- private aliases : string [ ]
26+ aliases : string [ ]
2527 private _run ?: ( options : Args ) => Promise < void > | void
26- private options : MassargOption [ ] = [ ]
27- private commands : MassargCommand < any > [ ] = [ ]
28- private args : Partial < Args > = { }
28+ options : MassargOption [ ] = [ ]
29+ commands : MassargCommand < any > [ ] = [ ]
30+ args : Partial < Args > = { }
2931
3032 constructor ( options : CommandConfig < Args > ) {
3133 CommandConfig ( z . any ( ) ) . parse ( options )
@@ -35,9 +37,9 @@ export default class MassargCommand<Args extends ArgsObject = ArgsObject> {
3537 this . _run = options . run
3638 }
3739
38- command ( config : CommandConfig < Args > ) : MassargCommand < Args >
39- command ( config : MassargCommand < Args > ) : MassargCommand < Args >
40- command ( config : CommandConfig < Args > | MassargCommand < Args > ) : MassargCommand < Args > {
40+ command < A extends ArgsObject = Args > ( config : CommandConfig < A > ) : MassargCommand < Args >
41+ command < A extends ArgsObject = Args > ( config : MassargCommand < A > ) : MassargCommand < Args >
42+ command < A extends ArgsObject = Args > ( config : CommandConfig < A > | MassargCommand < A > ) : MassargCommand < Args > {
4143 try {
4244 const command = config instanceof MassargCommand ? config : new MassargCommand ( config )
4345 this . commands . push ( command )
@@ -55,23 +57,10 @@ export default class MassargCommand<Args extends ArgsObject = ArgsObject> {
5557 }
5658
5759 option < T = string > ( config : MassargOption < T > ) : MassargCommand < Args >
58- option < T = string > ( config : OptionConfig < T > & { type ?: OptionType } ) : MassargCommand < Args >
59- option < T = string > ( config : ( OptionConfig < T > & { type ?: OptionType } ) | MassargOption < T > ) : MassargCommand < Args > {
60- const factory = ( ) => {
61- if ( ! ( "type" in config ) ) {
62- return new MassargOption ( config as OptionConfig < T > )
63- }
64- switch ( config . type ) {
65- case "string" :
66- return new MassargOption < string > ( config as OptionConfig < string > )
67- case "number" :
68- return new MassargNumber ( config as OptionConfig < number > )
69- case "boolean" :
70- return new MassargFlag ( config )
71- }
72- }
60+ option < T = string > ( config : TypedOptionConfig < T > ) : MassargCommand < Args >
61+ option < T = string > ( config : TypedOptionConfig < T > | MassargOption < T > ) : MassargCommand < Args > {
7362 try {
74- const option = config instanceof MassargOption ? config : factory ( )
63+ const option = config instanceof MassargOption ? config : MassargOption . fromTypedConfig ( config )
7564 this . options . push ( option as MassargOption )
7665 return this
7766 } catch ( e ) {
@@ -100,7 +89,8 @@ export default class MassargCommand<Args extends ArgsObject = ArgsObject> {
10089 while ( _argv . length ) {
10190 const arg = _argv . shift ( ) !
10291 console . log ( "parsing:" , arg , _argv )
103- if ( arg . startsWith ( "-" ) ) {
92+ const found = this . options . some ( ( o ) => o . _isOption ( arg ) )
93+ if ( found ) {
10494 console . log ( "option:" , arg , _argv )
10595 _argv = this . parseOption ( arg , _argv )
10696 continue
@@ -121,15 +111,21 @@ export default class MassargCommand<Args extends ArgsObject = ArgsObject> {
121111 }
122112
123113 private parseOption ( arg : string , argv : string [ ] ) : string [ ] {
124- const option = this . options . find (
125- ( o ) => ( arg . startsWith ( "--" ) && o . name === arg . slice ( 2 ) ) || o . aliases . includes ( arg . slice ( 1 ) ) ,
126- )
114+ const option = this . options . find ( ( o ) => o . _match ( arg ) )
115+
127116 if ( ! option ) {
128117 // TODO create custom error object
129118 throw new Error ( `Unknown option ${ arg } ` )
130119 }
131120 const res = option . valueFromArgv ( [ arg , ...argv ] )
132- this . args [ res . key as keyof Args ] = res . value as Args [ keyof Args ]
121+ console . log ( "option class name" , option . constructor . name )
122+ if ( option . isArray ) {
123+ this . args [ res . key as keyof Args ] ??= [ ] as Args [ keyof Args ]
124+ const _a = this . args [ res . key as keyof Args ] as unknown [ ]
125+ _a . push ( res . value ) as Args [ keyof Args ]
126+ } else {
127+ this . args [ res . key as keyof Args ] = res . value as Args [ keyof Args ]
128+ }
133129 console . log ( "option response:" , { value : res . value , argv : res . argv } )
134130 return res . argv
135131 }
@@ -139,6 +135,22 @@ export default class MassargCommand<Args extends ArgsObject = ArgsObject> {
139135 console . log ( argv )
140136 return { } as Args
141137 }
138+
139+ helpString ( ) : string {
140+ const options = generateOptionsHelpTable ( this . options )
141+ const commands = generateCommandsHelpTable ( this . commands )
142+ return [
143+ `${ this . name } - ${ this . description } ` ,
144+ commands . length && "" ,
145+ commands . length && `Commands for ${ this . name } :` ,
146+ commands . length && commands ,
147+ options . length && "" ,
148+ options . length && `Options for ${ this . name } :` ,
149+ options . length && options ,
150+ ]
151+ . filter ( ( s ) => typeof s === "string" )
152+ . join ( "\n" )
153+ }
142154}
143155
144156export { MassargCommand }
0 commit comments