11import { z } from "zod"
2- import { isZodError , ValidationError } from "./error"
2+ import { isZodError , ParseError , ValidationError } from "./error"
33import { HelpGenerator } from "./help"
4- import MassargOption , { MassargFlag , OptionConfig , TypedOptionConfig } from "./option"
4+ import MassargOption , {
5+ MassargFlag ,
6+ OptionConfig ,
7+ TypedOptionConfig ,
8+ MassargHelpFlag ,
9+ } from "./option"
510import { setOrPush } from "./utils"
611
712export const CommandConfig = < RunArgs extends z . ZodType > ( args : RunArgs ) =>
@@ -13,6 +18,9 @@ export const CommandConfig = <RunArgs extends z.ZodType>(args: RunArgs) =>
1318 . function ( )
1419 . args ( args , z . any ( ) )
1520 . returns ( z . union ( [ z . promise ( z . void ( ) ) , z . void ( ) ] ) ) as z . ZodType < Runner < z . infer < RunArgs > > > ,
21+ bindHelpCommand : z . boolean ( ) . optional ( ) ,
22+ bindHelpOption : z . boolean ( ) . optional ( ) ,
23+ // argsHint: z.string().optional(),
1624 } )
1725
1826export type CommandConfig < T = unknown > = z . infer < ReturnType < typeof CommandConfig < z . ZodType < T > > > >
@@ -39,6 +47,12 @@ export default class MassargCommand<Args extends ArgsObject = ArgsObject> {
3947 this . description = options . description
4048 this . aliases = options . aliases ?? [ ]
4149 this . _run = options . run
50+ if ( options . bindHelpCommand ) {
51+ this . command ( new MassargHelpCommand ( ) )
52+ }
53+ if ( options . bindHelpOption ) {
54+ this . option ( new MassargHelpFlag ( ) )
55+ }
4256 }
4357
4458 command < A extends ArgsObject = Args > ( config : CommandConfig < A > ) : MassargCommand < Args >
@@ -122,7 +136,12 @@ export default class MassargCommand<Args extends ArgsObject = ArgsObject> {
122136 if ( command ) {
123137 return command . parse ( _argv , this . args , parent ?? this )
124138 }
125- // TODO pass all un-handled args to an "args" option
139+ const defaultOption = this . options . find ( ( o ) => o . isDefault )
140+ if ( defaultOption ) {
141+ console . log ( "Parsing default option" )
142+ _argv = this . parseOption ( `--${ defaultOption . name } ` , [ arg , ..._argv ] )
143+ continue
144+ }
126145 }
127146 if ( this . _run ) {
128147 this . _run ( { ...args , ...this . args } as Args , parent ?? this )
@@ -138,6 +157,7 @@ export default class MassargCommand<Args extends ArgsObject = ArgsObject> {
138157 message : "Unknown option" ,
139158 } )
140159 }
160+ console . log ( "parseOption" , [ arg , ...argv ] )
141161 const res = option . _parseDetails ( [ arg , ...argv ] )
142162 this . args [ res . key as keyof Args ] = setOrPush < Args [ keyof Args ] > (
143163 res . value ,
@@ -189,22 +209,24 @@ export default class MassargCommand<Args extends ArgsObject = ArgsObject> {
189209}
190210
191211export class MassargHelpCommand < T extends ArgsObject = ArgsObject > extends MassargCommand < T > {
192- constructor ( config : Partial < Omit < CommandConfig < T > , "run" > > ) {
212+ constructor ( config : Partial < Omit < CommandConfig < T > , "run" > > = { } ) {
193213 super ( {
194214 name : "help" ,
195215 aliases : [ "h" ] ,
196- description : "Print help" ,
216+ description : "Print help for this command, or a subcommand if specified" ,
217+ // argsHint: "[command]",
197218 run : ( args , parent ) => {
198219 if ( args . command ) {
199220 const command = parent . commands . find ( ( c ) => c . name === args . command )
200221 if ( command ) {
201222 command . printHelp ( )
202223 return
203224 } else {
204- throw new ValidationError ( {
225+ throw new ParseError ( {
205226 path : [ "command" ] ,
206227 code : "unknown_command" ,
207228 message : "Unknown command" ,
229+ received : args . command ,
208230 } )
209231 }
210232 }
0 commit comments