@@ -58,6 +58,13 @@ interface ZodTypeInfo {
5858 isOptional : boolean
5959}
6060
61+ const resolveDefaultValue = ( def : ZodDef , fallback : unknown ) : unknown => {
62+ if ( def . defaultValue ) {
63+ return def . defaultValue ( )
64+ }
65+ return fallback
66+ }
67+
6168const unwrapZodTypeRecursive = (
6269 current : z . ZodTypeAny ,
6370 isOptional : boolean ,
@@ -71,12 +78,7 @@ const unwrapZodTypeRecursive = (
7178 return { defaultValue, inner : current , isOptional : true }
7279 }
7380 if ( def . typeName === 'ZodDefault' ) {
74- const newDefault = ( ( ) => {
75- if ( def . defaultValue ) {
76- return def . defaultValue ( )
77- }
78- return defaultValue
79- } ) ( )
81+ const newDefault = resolveDefaultValue ( def , defaultValue )
8082 if ( def . innerType ) {
8183 return unwrapZodTypeRecursive ( def . innerType , true , newDefault )
8284 }
@@ -87,33 +89,33 @@ const unwrapZodTypeRecursive = (
8789
8890const unwrapZodType = ( schema : z . ZodTypeAny ) : ZodTypeInfo => unwrapZodTypeRecursive ( schema , false )
8991
90- const getZodTypeOption = ( schema : z . ZodTypeAny ) : YargsOptions => {
91- const { inner, isOptional, defaultValue } = unwrapZodType ( schema )
92- const innerDef = ( inner as { _def : ZodDef } ) . _def
93- const option : YargsOptions = { }
92+ const resolveZodYargsType = ( typeName : string | undefined ) : 'string' | 'number' | 'boolean' | 'array' =>
93+ match ( typeName )
94+ . with ( 'ZodString' , ( ) => 'string' as const )
95+ . with ( 'ZodNumber' , ( ) => 'number' as const )
96+ . with ( 'ZodBoolean' , ( ) => 'boolean' as const )
97+ . with ( 'ZodArray' , ( ) => 'array' as const )
98+ . otherwise ( ( ) => 'string' as const )
9499
100+ const buildBaseOption = ( innerDef : ZodDef , defaultValue : unknown ) : YargsOptions => {
101+ const option : YargsOptions = { }
95102 if ( innerDef . description ) {
96103 option . describe = innerDef . description
97104 }
98-
99105 if ( defaultValue !== undefined ) {
100106 option . default = defaultValue
101107 }
108+ return option
109+ }
102110
103- const { typeName } = innerDef
104- const typeResult = match ( typeName )
105- . with ( 'ZodString' , ( ) => 'string' as const )
106- . with ( 'ZodNumber' , ( ) => 'number' as const )
107- . with ( 'ZodBoolean' , ( ) => 'boolean' as const )
108- . with ( 'ZodArray' , ( ) => 'array' as const )
109- . otherwise ( ( ) => 'string' as const )
110-
111- option . type = typeResult
112-
111+ const getZodTypeOption = ( schema : z . ZodTypeAny ) : YargsOptions => {
112+ const { inner, isOptional, defaultValue } = unwrapZodType ( schema )
113+ const innerDef = ( inner as { _def : ZodDef } ) . _def
114+ const option = buildBaseOption ( innerDef , defaultValue )
115+ option . type = resolveZodYargsType ( innerDef . typeName )
113116 if ( ! isOptional ) {
114117 option . demandOption = true
115118 }
116-
117119 return option
118120}
119121
@@ -222,12 +224,15 @@ const registerResolvedCommand = (options: RegisterResolvedCommandOptions): void
222224 )
223225}
224226
225- const registerCommands = (
226- instance : Argv ,
227- commands : CommandMap ,
228- resolved : ResolvedRef ,
227+ interface RegisterCommandsOptions {
228+ commands : CommandMap
229+ instance : Argv
229230 parentPath : string [ ]
230- ) : void => {
231+ resolved : ResolvedRef
232+ }
233+
234+ const registerCommands = ( options : RegisterCommandsOptions ) : void => {
235+ const { instance, commands, resolved, parentPath } = options
231236 const commandEntries = Object . entries ( commands )
232237 . filter ( ( [ , entry ] ) => ! isAutoloadMarker ( entry ) )
233238 . filter ( ( [ , entry ] ) => isCommand ( entry ) )
@@ -330,17 +335,12 @@ const loadConfig = async <TSchema extends z.ZodType>(
330335 configOptions : CliConfigOptions < TSchema > | undefined ,
331336 defaultName : string
332337) : Promise < Record < string , unknown > > => {
333- if ( ! configOptions ) {
334- return { }
335- }
336- const { schema } = configOptions
337- if ( ! schema ) {
338+ if ( ! configOptions || ! configOptions . schema ) {
338339 return { }
339340 }
340- const configName = configOptions . name ?? defaultName
341341 const configClient = createConfigClient ( {
342- name : configName ,
343- schema : schema ,
342+ name : configOptions . name ?? defaultName ,
343+ schema : configOptions . schema ,
344344 } )
345345 const [ configError , configResult ] = await configClient . load ( )
346346 if ( configError || ! configResult ) {
@@ -384,7 +384,7 @@ const runCli = async (
384384 'Autoload from directory path is not yet supported. Use a CommandMap object instead.'
385385 )
386386 } else if ( options . commands && typeof options . commands === 'object' ) {
387- registerCommands ( instance , options . commands , resolved , [ ] )
387+ registerCommands ( { commands : options . commands , instance , parentPath : [ ] , resolved } )
388388 instance . demandCommand ( SECOND_INDEX , 'You must specify a command.' )
389389 }
390390
@@ -438,4 +438,5 @@ const cli: CliFn = (options) => {
438438}
439439
440440export default cli
441+ // eslint-disable-next-line eslint-plugin-import/no-named-export
441442export { cli }
0 commit comments