@@ -22,7 +22,27 @@ function getSchemaShape(schema: z.ZodType): Record<string, z.ZodType> {
2222 return { } ;
2323}
2424
25- function canZodOptsHandle ( fieldSchema : z . ZodType ) : boolean {
25+ /**
26+ * zod-opts supports z.array(z.string()) and z.array(z.number()) but not
27+ * z.array(z.enum([...])). For those, substitute z.array(z.string()) so
28+ * the CLI accepts space-separated values. The final schema.parse() in
29+ * parseCommand validates the enum values.
30+ */
31+ function coerceForZodOpts ( fieldSchema : z . ZodType ) : z . ZodType {
32+ const inner = unwrapSchema ( fieldSchema ) ;
33+ if ( inner instanceof z . ZodArray ) {
34+ const element = unwrapSchema ( inner . element as z . ZodType ) ;
35+ if ( element instanceof z . ZodEnum ) {
36+ const coerced = z . array ( z . string ( ) ) ;
37+ return fieldSchema instanceof z . ZodOptional
38+ ? coerced . optional ( )
39+ : coerced ;
40+ }
41+ }
42+ return fieldSchema ;
43+ }
44+
45+ function zodOptsProbe ( fieldSchema : z . ZodType ) : boolean {
2646 try {
2747 parser ( )
2848 . options ( { _probe : { type : fieldSchema . optional ( ) } } )
@@ -34,6 +54,12 @@ function canZodOptsHandle(fieldSchema: z.ZodType): boolean {
3454 }
3555}
3656
57+ function canZodOptsHandle ( fieldSchema : z . ZodType ) : boolean {
58+ if ( zodOptsProbe ( fieldSchema ) ) return true ;
59+ const coerced = coerceForZodOpts ( fieldSchema ) ;
60+ return coerced !== fieldSchema && zodOptsProbe ( coerced ) ;
61+ }
62+
3763// Only return scalar defaults for display in --help and COMMANDS.md.
3864// Complex defaults (objects, arrays) are omitted since those fields are
3965// rendered as JSON fallback inputs where showing a default isn't useful.
@@ -218,7 +244,7 @@ export function buildParser(
218244 } else {
219245 const fieldSchema = shape [ field . name ] ;
220246 if ( fieldSchema ) {
221- options [ field . name ] = { type : fieldSchema } ;
247+ options [ field . name ] = { type : coerceForZodOpts ( fieldSchema ) } ;
222248 }
223249 }
224250 }
0 commit comments