@@ -203,6 +203,48 @@ export const unwrapSchema = (
203203 return schema . toJSONSchema ?.( ) ?? schema ?. toJsonSchema ?.( )
204204}
205205
206+ 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,10 @@ export function toOpenAPISchema(
425500 const body = unwrapSchema ( hooks . body , vendors )
426501
427502 if ( body ) {
503+ const convertedBody = convertEnumToOpenAPI ( body )
428504 // @ts -ignore
429- const { type, description, $ref, ...options } = unwrapReference (
430- body ,
431- definitions
432- )
505+ const { type : _type , description, $ref, ...options } = convertedBody
506+ const type = _type as string | undefined
433507
434508 // @ts -ignore
435509 if ( hooks . parse ) {
@@ -447,26 +521,24 @@ export function toOpenAPISchema(
447521 switch ( parser . fn ) {
448522 case 'text' :
449523 case 'text/plain' :
450- content [ 'text/plain' ] = { schema : body }
524+ content [ 'text/plain' ] = { schema : convertedBody }
451525 continue
452526
453527 case 'urlencoded' :
454528 case 'application/x-www-form-urlencoded' :
455529 content [ 'application/x-www-form-urlencoded' ] = {
456- schema : body
530+ schema : convertedBody
457531 }
458532 continue
459533
460534 case 'json' :
461535 case 'application/json' :
462- content [ 'application/json' ] = { schema : body }
536+ content [ 'application/json' ] = { schema : convertedBody }
463537 continue
464538
465539 case 'formdata' :
466540 case 'multipart/form-data' :
467- content [ 'multipart/form-data' ] = {
468- schema : body
469- }
541+ content [ 'multipart/form-data' ] = { schema : convertedBody }
470542 continue
471543 }
472544 }
@@ -485,19 +557,17 @@ export function toOpenAPISchema(
485557 type === 'integer' ||
486558 type === 'boolean'
487559 ? {
488- 'text/plain' : {
489- schema : body
490- }
560+ 'text/plain' : convertedBody
491561 }
492562 : {
493563 'application/json' : {
494- schema : body
564+ schema : convertedBody
495565 } ,
496566 'application/x-www-form-urlencoded' : {
497- schema : body
567+ schema : convertedBody
498568 } ,
499569 'multipart/form-data' : {
500- schema : body
570+ schema : convertedBody
501571 }
502572 } ,
503573 required : true
@@ -522,9 +592,10 @@ export function toOpenAPISchema(
522592
523593 if ( ! response ) continue
524594
595+ const convertedResponse = convertEnumToOpenAPI ( response )
525596 // @ts -ignore Must exclude $ref from root options
526- const { type, description, $ref, ...options } =
527- unwrapReference ( response , definitions )
597+ const { type : _type , description, $ref, ...options } = convertedResponse
598+ const type = _type as string | undefined
528599
529600 operation . responses [ status ] = {
530601 description :
@@ -533,19 +604,19 @@ export function toOpenAPISchema(
533604 type === 'void' ||
534605 type === 'null' ||
535606 type === 'undefined'
536- ? ( { type , description } as any )
607+ ? ( convertedResponse as any )
537608 : type === 'string' ||
538609 type === 'number' ||
539610 type === 'integer' ||
540611 type === 'boolean'
541612 ? {
542613 'text/plain' : {
543- schema : response
614+ schema : convertedResponse
544615 }
545616 }
546617 : {
547618 'application/json' : {
548- schema : response
619+ schema : convertedResponse
549620 }
550621 }
551622 }
@@ -554,12 +625,14 @@ export function toOpenAPISchema(
554625 const response = unwrapSchema ( hooks . response as any , vendors )
555626
556627 if ( response ) {
628+ const convertedResponse = convertEnumToOpenAPI ( response )
629+
557630 // @ts -ignore
558631 const {
559632 type : _type ,
560633 description,
561634 ...options
562- } = unwrapReference ( response , definitions )
635+ } = convertedResponse
563636 const type = _type as string | undefined
564637
565638 // It's a single schema, default to 200
@@ -569,19 +642,19 @@ export function toOpenAPISchema(
569642 type === 'void' ||
570643 type === 'null' ||
571644 type === 'undefined'
572- ? ( { type , description } as any )
645+ ? ( convertedResponse as any )
573646 : type === 'string' ||
574647 type === 'number' ||
575648 type === 'integer' ||
576649 type === 'boolean'
577650 ? {
578651 'text/plain' : {
579- schema : response
652+ schema : convertedResponse
580653 }
581654 }
582655 : {
583656 'application/json' : {
584- schema : response
657+ schema : convertedResponse
585658 }
586659 }
587660 }
0 commit comments