File tree 2 files changed +56
-3
lines changed
packages/zod-openapi/src/lib
2 files changed +56
-3
lines changed Original file line number Diff line number Diff line change @@ -823,4 +823,35 @@ describe('zodOpenapi', () => {
823
823
format : 'binary' ,
824
824
} ) ;
825
825
} ) ;
826
+
827
+ it ( 'can summarize unions of zod literals as an enum' , ( ) => {
828
+ expect ( generateSchema ( z . union ( [ z . literal ( 'h' ) , z . literal ( 'i' ) ] ) ) ) . toEqual ( {
829
+ type : 'string' ,
830
+ enum : [ 'h' , 'i' ]
831
+ } ) ;
832
+
833
+ expect ( generateSchema ( z . union ( [ z . literal ( 3 ) , z . literal ( 4 ) ] ) ) ) . toEqual ( {
834
+ type : 'number' ,
835
+ enum : [ 3 , 4 ]
836
+ } ) ;
837
+
838
+ // should this just remove the enum? true | false is exhaustive...
839
+ expect ( generateSchema ( z . union ( [ z . literal ( true ) , z . literal ( false ) ] ) ) ) . toEqual ( {
840
+ type : 'boolean' ,
841
+ enum : [ true , false ]
842
+ } ) ;
843
+
844
+ expect ( generateSchema ( z . union ( [ z . literal ( 5 ) , z . literal ( 'i' ) ] ) ) ) . toEqual ( {
845
+ oneOf : [
846
+ {
847
+ type : 'number' ,
848
+ enum : [ 5 ]
849
+ } ,
850
+ {
851
+ type : 'string' ,
852
+ enum : [ 'i' ]
853
+ }
854
+ ]
855
+ } ) ;
856
+ } )
826
857
} ) ;
Original file line number Diff line number Diff line change @@ -388,11 +388,33 @@ function parseUnion({
388
388
zodRef,
389
389
useOutput,
390
390
} : ParsingArgs < z . ZodUnion < [ z . ZodTypeAny , ...z . ZodTypeAny [ ] ] > > ) : SchemaObject {
391
+ const contents = zodRef . _def . options ;
392
+ if ( contents . reduce ( ( prev , content ) => prev && content . _def . typeName === 'ZodLiteral' , true ) ) {
393
+ // special case to transform unions of literals into enums
394
+ const literals = contents as unknown as z . ZodLiteral < OpenApiZodAny > [ ] ;
395
+ const type = literals
396
+ . reduce ( ( prev , content ) =>
397
+ ! prev || prev === typeof content . _def . value ?
398
+ typeof content . _def . value :
399
+ null ,
400
+ null as null | string
401
+ ) ;
402
+
403
+ if ( type ) {
404
+ return merge (
405
+ {
406
+ type : type as 'string' | 'number' | 'boolean' ,
407
+ enum : literals . map ( ( literal ) => literal . _def . value )
408
+ } ,
409
+ zodRef . description ? { description : zodRef . description } : { } ,
410
+ ...schemas
411
+ ) ;
412
+ }
413
+ }
414
+
391
415
return merge (
392
416
{
393
- oneOf : (
394
- zodRef as z . ZodUnion < [ z . ZodTypeAny , ...z . ZodTypeAny [ ] ] >
395
- ) . _def . options . map ( ( schema ) => generateSchema ( schema , useOutput ) ) ,
417
+ oneOf : contents . map ( ( schema ) => generateSchema ( schema , useOutput ) ) ,
396
418
} ,
397
419
zodRef . description ? { description : zodRef . description } : { } ,
398
420
...schemas
You can’t perform that action at this time.
0 commit comments