@@ -203,6 +203,48 @@ export const unwrapSchema = (
203203 return schema . toJSONSchema ?.( ) ?? schema ?. toJsonSchema ?.( )
204204}
205205
206+ export const convertEnumToOpenApi = ( schema : any ) : any => {
207+ if ( ! schema || typeof schema !== 'object' ) return schema
208+
209+ if (
210+ schema [ Kind ] === 'Union' &&
211+ schema . anyOf &&
212+ Array . isArray ( schema . anyOf ) &&
213+ schema . anyOf . length > 0 &&
214+ schema . anyOf . every (
215+ ( item : any ) =>
216+ item && typeof item === 'object' && item . const !== undefined
217+ )
218+ ) {
219+ const enumValues = schema . anyOf . map ( ( item : any ) => item . const )
220+
221+ return {
222+ type : 'string' ,
223+ enum : enumValues
224+ }
225+ }
226+
227+ if ( schema . type === 'object' && schema . properties ) {
228+ const convertedProperties : any = { }
229+ for ( const [ key , value ] of Object . entries ( schema . properties ) ) {
230+ convertedProperties [ key ] = convertEnumToOpenApi ( value )
231+ }
232+ return {
233+ ...schema ,
234+ properties : convertedProperties
235+ }
236+ }
237+
238+ if ( schema . type === 'array' && schema . items ) {
239+ return {
240+ ...schema ,
241+ items : convertEnumToOpenApi ( schema . items )
242+ }
243+ }
244+
245+ return schema
246+ }
247+
206248/**
207249 * Converts Elysia routes to OpenAPI 3.0.3 paths schema
208250 * @param routes Array of Elysia route objects
@@ -342,16 +384,25 @@ export function toOpenAPISchema(
342384 definitions
343385 )
344386
345- if ( params && params . type === 'object' && params . properties )
387+ if ( params && params . type === 'object' && params . properties ) {
388+ const convertedProperties : any = { }
346389 for ( const [ paramName , paramSchema ] of Object . entries (
347390 params . properties
391+ ) ) {
392+ convertedProperties [ paramName ] =
393+ convertEnumToOpenApi ( paramSchema )
394+ }
395+
396+ for ( const [ paramName , paramSchema ] of Object . entries (
397+ convertedProperties
348398 ) )
349399 parameters . push ( {
350400 name : paramName ,
351401 in : 'path' ,
352402 required : true , // Path parameters are always required
353403 schema : paramSchema
354404 } )
405+ }
355406 }
356407
357408 // Handle query parameters
@@ -362,9 +413,17 @@ export function toOpenAPISchema(
362413 )
363414
364415 if ( query && query . type === 'object' && query . properties ) {
365- const required = query . required || [ ]
416+ const convertedProperties : any = { }
366417 for ( const [ queryName , querySchema ] of Object . entries (
367418 query . properties
419+ ) ) {
420+ convertedProperties [ queryName ] =
421+ convertEnumToOpenApi ( querySchema )
422+ }
423+
424+ const required = query . required || [ ]
425+ for ( const [ queryName , querySchema ] of Object . entries (
426+ convertedProperties
368427 ) )
369428 parameters . push ( {
370429 name : queryName ,
@@ -383,9 +442,17 @@ export function toOpenAPISchema(
383442 )
384443
385444 if ( headers && headers . type === 'object' && headers . properties ) {
386- const required = headers . required || [ ]
445+ const convertedProperties : any = { }
387446 for ( const [ headerName , headerSchema ] of Object . entries (
388447 headers . properties
448+ ) ) {
449+ convertedProperties [ headerName ] =
450+ convertEnumToOpenApi ( headerSchema )
451+ }
452+
453+ const required = headers . required || [ ]
454+ for ( const [ headerName , headerSchema ] of Object . entries (
455+ convertedProperties
389456 ) )
390457 parameters . push ( {
391458 name : headerName ,
@@ -404,9 +471,17 @@ export function toOpenAPISchema(
404471 )
405472
406473 if ( cookie && cookie . type === 'object' && cookie . properties ) {
407- const required = cookie . required || [ ]
474+ const convertedProperties : any = { }
408475 for ( const [ cookieName , cookieSchema ] of Object . entries (
409476 cookie . properties
477+ ) ) {
478+ convertedProperties [ cookieName ] =
479+ convertEnumToOpenApi ( cookieSchema )
480+ }
481+
482+ const required = cookie . required || [ ]
483+ for ( const [ cookieName , cookieSchema ] of Object . entries (
484+ convertedProperties
410485 ) )
411486 parameters . push ( {
412487 name : cookieName ,
@@ -425,11 +500,11 @@ export function toOpenAPISchema(
425500 const body = unwrapSchema ( hooks . body , vendors )
426501
427502 if ( body ) {
503+ const convertedBody = convertEnumToOpenApi ( body )
504+
428505 // @ts -ignore
429- const { type, description, $ref, ...options } = unwrapReference (
430- body ,
431- definitions
432- )
506+ const { type : _type , description, $ref, ...options } = convertedBody
507+ const type = _type as string | undefined
433508
434509 // @ts -ignore
435510 if ( hooks . parse ) {
@@ -447,26 +522,24 @@ export function toOpenAPISchema(
447522 switch ( parser . fn ) {
448523 case 'text' :
449524 case 'text/plain' :
450- content [ 'text/plain' ] = { schema : body }
525+ content [ 'text/plain' ] = { schema : convertedBody }
451526 continue
452527
453528 case 'urlencoded' :
454529 case 'application/x-www-form-urlencoded' :
455530 content [ 'application/x-www-form-urlencoded' ] = {
456- schema : body
531+ schema : convertedBody
457532 }
458533 continue
459534
460535 case 'json' :
461536 case 'application/json' :
462- content [ 'application/json' ] = { schema : body }
537+ content [ 'application/json' ] = { schema : convertedBody }
463538 continue
464539
465540 case 'formdata' :
466541 case 'multipart/form-data' :
467- content [ 'multipart/form-data' ] = {
468- schema : body
469- }
542+ content [ 'multipart/form-data' ] = { schema : convertedBody }
470543 continue
471544 }
472545 }
@@ -485,19 +558,17 @@ export function toOpenAPISchema(
485558 type === 'integer' ||
486559 type === 'boolean'
487560 ? {
488- 'text/plain' : {
489- schema : body
490- }
561+ 'text/plain' : convertedBody
491562 }
492563 : {
493564 'application/json' : {
494- schema : body
565+ schema : convertedBody
495566 } ,
496567 'application/x-www-form-urlencoded' : {
497- schema : body
568+ schema : convertedBody
498569 } ,
499570 'multipart/form-data' : {
500- schema : body
571+ schema : convertedBody
501572 }
502573 } ,
503574 required : true
@@ -522,9 +593,10 @@ export function toOpenAPISchema(
522593
523594 if ( ! response ) continue
524595
596+ const convertedResponse = convertEnumToOpenApi ( response )
525597 // @ts -ignore Must exclude $ref from root options
526- const { type, description, $ref, ...options } =
527- unwrapReference ( response , definitions )
598+ const { type : _type , description, $ref, ...options } = convertedResponse
599+ const type = _type as string | undefined
528600
529601 operation . responses [ status ] = {
530602 description :
@@ -533,19 +605,19 @@ export function toOpenAPISchema(
533605 type === 'void' ||
534606 type === 'null' ||
535607 type === 'undefined'
536- ? ( { type , description } as any )
608+ ? ( convertedResponse as any )
537609 : type === 'string' ||
538610 type === 'number' ||
539611 type === 'integer' ||
540612 type === 'boolean'
541613 ? {
542614 'text/plain' : {
543- schema : response
615+ schema : convertedResponse
544616 }
545617 }
546618 : {
547619 'application/json' : {
548- schema : response
620+ schema : convertedResponse
549621 }
550622 }
551623 }
@@ -554,12 +626,14 @@ export function toOpenAPISchema(
554626 const response = unwrapSchema ( hooks . response as any , vendors )
555627
556628 if ( response ) {
629+ const convertedResponse = convertEnumToOpenApi ( response )
630+
557631 // @ts -ignore
558632 const {
559633 type : _type ,
560634 description,
561635 ...options
562- } = unwrapReference ( response , definitions )
636+ } = convertedResponse
563637 const type = _type as string | undefined
564638
565639 // It's a single schema, default to 200
@@ -569,19 +643,19 @@ export function toOpenAPISchema(
569643 type === 'void' ||
570644 type === 'null' ||
571645 type === 'undefined'
572- ? ( { type , description } as any )
646+ ? ( convertedResponse as any )
573647 : type === 'string' ||
574648 type === 'number' ||
575649 type === 'integer' ||
576650 type === 'boolean'
577651 ? {
578652 'text/plain' : {
579- schema : response
653+ schema : convertedResponse
580654 }
581655 }
582656 : {
583657 'application/json' : {
584- schema : response
658+ schema : convertedResponse
585659 }
586660 }
587661 }
0 commit comments