@@ -128,6 +128,7 @@ schemaFaker.option({
128128
129129let QUERYPARAM = 'query' ,
130130 CONVERSION = 'conversion' ,
131+ TYPES_GENERATION = 'typesGeneration' ,
131132 HEADER = 'header' ,
132133 PATHPARAM = 'path' ,
133134 SCHEMA_TYPES = {
@@ -493,6 +494,30 @@ let QUERYPARAM = 'query',
493494 * @returns {Object } Resolved schema
494495 */
495496 resolveAllOfSchema = ( context , schema , stack = 0 , resolveFor = CONVERSION , seenRef = { } , currentPath = '' ) => {
497+ /*
498+ For TYPES_GENERATION, we do not want to merge the allOf schemas
499+ instead we want to keep them separate so that we can generate types like:
500+ allOf: [
501+ { $ref: '#/components/schemas/User' },
502+ {
503+ type: 'object',
504+ properties: {
505+ timestamp: { type: 'string', format: 'date-time' }
506+ }
507+ }
508+ ]
509+ If we merge the schemas, we will loose the information that the schema was
510+ a combination of multiple schemas
511+ */
512+ if ( resolveFor === TYPES_GENERATION ) {
513+ return {
514+ allOf : _ . map ( schema . allOf , ( schema ) => {
515+ // eslint-disable-next-line no-use-before-define
516+ return _resolveSchema ( context , schema , stack , resolveFor , _ . cloneDeep ( seenRef ) , currentPath ) ;
517+ } )
518+ } ;
519+ }
520+
496521 try {
497522 return mergeAllOf ( _ . assign ( schema , {
498523 allOf : _ . map ( schema . allOf , ( schema ) => {
@@ -543,7 +568,6 @@ let QUERYPARAM = 'query',
543568
544569 stack ++ ;
545570
546- // eslint-disable-next-line one-var
547571 const compositeKeyword = schema . anyOf ? 'anyOf' : 'oneOf' ,
548572 { concreteUtils } = context ;
549573
@@ -618,7 +642,6 @@ let QUERYPARAM = 'query',
618642 writeOnlyPropCache : context . writeOnlyPropCache
619643 } ;
620644
621- // eslint-disable-next-line one-var
622645 const newReadPropCache = context . readOnlyPropCache ,
623646 newWritePropCache = context . writeOnlyPropCache ;
624647
@@ -684,7 +707,7 @@ let QUERYPARAM = 'query',
684707 let { parametersResolution } = context . computedOptions ;
685708
686709 // Override default value to schema for CONVERSION only for parmeter resolution set to schema
687- if ( resolveFor === CONVERSION && parametersResolution === 'schema' ) {
710+ if ( ( resolveFor === CONVERSION || resolveFor === TYPES_GENERATION ) && parametersResolution === 'schema' ) {
688711 if ( ! schema . hasOwnProperty ( 'format' ) ) {
689712 schema . default = '<' + schema . type + '>' ;
690713 }
@@ -743,16 +766,42 @@ let QUERYPARAM = 'query',
743766 * @returns {Object } The processed schema details.
744767 */
745768 processSchema = ( resolvedSchema ) => {
769+ if ( resolvedSchema . anyOf ) {
770+ return {
771+ anyOf : resolvedSchema . anyOf . map ( ( schema ) => {
772+ return processSchema ( schema ) ;
773+ } )
774+ } ;
775+ }
776+
777+ if ( resolvedSchema . oneOf ) {
778+ return {
779+ oneOf : resolvedSchema . oneOf . map ( ( schema ) => {
780+ return processSchema ( schema ) ;
781+ } )
782+ } ;
783+ }
784+
785+ if ( resolvedSchema . allOf ) {
786+ return {
787+ allOf : resolvedSchema . allOf . map ( ( schema ) => {
788+ return processSchema ( schema ) ;
789+ } )
790+ } ;
791+ }
792+
746793 if ( resolvedSchema . type === 'object' && resolvedSchema . properties ) {
747794 const schemaDetails = {
795+ description : resolvedSchema . description ,
796+ title : resolvedSchema . title ,
748797 type : resolvedSchema . type ,
749798 properties : { } ,
750799 required : [ ]
751800 } ,
752801 requiredProperties = new Set ( resolvedSchema . required || [ ] ) ;
753802
754803 for ( let [ propName , propValue ] of Object . entries ( resolvedSchema . properties ) ) {
755- if ( ! propValue . type ) {
804+ if ( ! propValue . type && ! propValue . anyOf && ! propValue . oneOf && ! propValue . allOf ) {
756805 continue ;
757806 }
758807 const propertyDetails = {
@@ -772,7 +821,23 @@ let QUERYPARAM = 'query',
772821 if ( requiredProperties . has ( propName ) ) {
773822 schemaDetails . required . push ( propName ) ;
774823 }
775- if ( propValue . properties ) {
824+
825+ if ( propValue . anyOf ) {
826+ propertyDetails . anyOf = propValue . anyOf . map ( ( schema ) => {
827+ return processSchema ( schema ) ;
828+ } ) ;
829+ }
830+ else if ( propValue . oneOf ) {
831+ propertyDetails . oneOf = propValue . oneOf . map ( ( schema ) => {
832+ return processSchema ( schema ) ;
833+ } ) ;
834+ }
835+ else if ( propValue . allOf ) {
836+ propertyDetails . allOf = propValue . allOf . map ( ( schema ) => {
837+ return processSchema ( schema ) ;
838+ } ) ;
839+ }
840+ else if ( propValue . properties ) {
776841 let processedProperties = processSchema ( propValue ) ;
777842 propertyDetails . properties = processedProperties . properties ;
778843 if ( processedProperties . required ) {
@@ -1113,16 +1178,24 @@ let QUERYPARAM = 'query',
11131178 * Gets the description of the parameter.
11141179 * If the parameter is required, it prepends a `(Requried)` before the parameter description
11151180 * If the parameter type is enum, it appends the possible enum values
1181+ * @param {object } context - Global context object controlling behavior
11161182 * @param {object } parameter - input param for which description needs to be returned
11171183 * @returns {string } description of the parameters
11181184 */
1119- getParameterDescription = ( parameter ) => {
1185+ getParameterDescription = ( context , parameter ) => {
11201186 if ( ! _ . isObject ( parameter ) ) {
11211187 return '' ;
11221188 }
11231189
1124- return ( parameter . required ? '(Required) ' : '' ) + ( parameter . description || '' ) +
1125- ( parameter . enum ? ' (This can only be one of ' + parameter . enum + ')' : '' ) ;
1190+ const requiredPrefix = ( context && ! context . enableTypeFetching && parameter . required ? '(Required) ' : '' ) ,
1191+ desc = parameter . description || '' ;
1192+
1193+ let enumDescription = '' ;
1194+ if ( parameter && parameter . schema && parameter . schema . enum && ! ( context && context . enableTypeFetching ) ) {
1195+ enumDescription = ' (This can only be one of ' + parameter . schema . enum + ')' ;
1196+ }
1197+
1198+ return requiredPrefix + desc + enumDescription ;
11261199 } ,
11271200
11281201 /**
@@ -1141,7 +1214,7 @@ let QUERYPARAM = 'query',
11411214 { enableOptionalParameters } = context . computedOptions ;
11421215
11431216 let serialisedValue = '' ,
1144- description = getParameterDescription ( param ) ,
1217+ description = getParameterDescription ( context , param ) ,
11451218 paramName = _ . get ( param , 'name' ) ,
11461219 disabled = ! enableOptionalParameters && _ . get ( param , 'required' ) !== true ,
11471220 pmParams = [ ] ,
@@ -1421,7 +1494,6 @@ let QUERYPARAM = 'query',
14211494 } ) ;
14221495 } ) ;
14231496
1424- // eslint-disable-next-line one-var
14251497 let responseExample ,
14261498 responseExampleData ;
14271499
@@ -1482,6 +1554,21 @@ let QUERYPARAM = 'query',
14821554 return [ { [ bodyKey ] : bodyData } ] ;
14831555 }
14841556
1557+ // For type fetching, process the original schema before any modifications
1558+ // This is done to preserve the anyOf, oneOf etc in the original schema
1559+ // since they are otherwise flattened while resolving the schema
1560+ if ( context . enableTypeFetching && requestBodySchema ) {
1561+ const originalSchema = requestBodySchema . schema || requestBodySchema ,
1562+ resolvedSchema = resolveSchema (
1563+ context ,
1564+ originalSchema ,
1565+ { resolveFor : TYPES_GENERATION } ) ;
1566+
1567+ if ( resolvedSchema . type || resolvedSchema . anyOf || resolvedSchema . oneOf || resolvedSchema . allOf ) {
1568+ resolvedSchemaTypes . push ( processSchema ( resolvedSchema ) ) ;
1569+ }
1570+ }
1571+
14851572 if ( requestBodySchema . $ref ) {
14861573 requestBodySchema = resolveSchema (
14871574 context ,
@@ -1611,11 +1698,6 @@ let QUERYPARAM = 'query',
16111698
16121699 }
16131700
1614- if ( context . enableTypeFetching && requestBodySchema . type !== undefined ) {
1615- const requestBodySchemaTypes = processSchema ( requestBodySchema ) ;
1616- resolvedSchemaTypes . push ( requestBodySchemaTypes ) ;
1617- }
1618-
16191701 // Generate multiple examples when either request or response contains more than one example
16201702 if (
16211703 isExampleBody &&
@@ -1772,7 +1854,7 @@ let QUERYPARAM = 'query',
17721854 paramSchema . required = _ . has ( paramSchema , 'required' ) ?
17731855 paramSchema . required :
17741856 _ . indexOf ( requestBodySchema . required , key ) !== - 1 ;
1775- description = getParameterDescription ( paramSchema ) ;
1857+ description = getParameterDescription ( context , paramSchema ) ;
17761858
17771859 if ( typeof _ . get ( encoding , `[${ key } ].contentType` ) === 'string' ) {
17781860 contentType = encoding [ key ] . contentType ;
@@ -2027,8 +2109,8 @@ let QUERYPARAM = 'query',
20272109 type : schema . type ,
20282110 format : schema . format ,
20292111 default : schema . default ,
2030- required : param . required || false ,
2031- deprecated : param . deprecated || false ,
2112+ required : param . required ,
2113+ deprecated : param . deprecated ,
20322114 enum : schema . enum || undefined ,
20332115 minLength : schema . minLength ,
20342116 maxLength : schema . maxLength ,
@@ -2054,14 +2136,18 @@ let QUERYPARAM = 'query',
20542136 param = resolveSchema ( context , param ) ;
20552137 }
20562138
2057- if ( _ . has ( param . schema , '$ref' ) ) {
2058- param . schema = resolveSchema ( context , param . schema ) ;
2059- }
2060-
20612139 if ( param . in !== QUERYPARAM || ( ! includeDeprecated && param . deprecated ) ) {
20622140 return ;
20632141 }
20642142
2143+ const shouldResolveSchema = _ . has ( param , 'schema' ) &&
2144+ ( _ . has ( param . schema , '$ref' ) || _ . has ( param . schema , 'anyOf' ) ||
2145+ _ . has ( param . schema , 'oneOf' ) || _ . has ( param . schema , 'allOf' ) ) ;
2146+
2147+ if ( shouldResolveSchema ) {
2148+ param . schema = resolveSchema ( context , param . schema ) ;
2149+ }
2150+
20652151 let queryParamTypeInfo = { } ,
20662152 properties = { } ,
20672153 paramValue = resolveValueOfParameter ( context , param ) ;
@@ -2103,14 +2189,19 @@ let QUERYPARAM = 'query',
21032189 param = resolveSchema ( context , param ) ;
21042190 }
21052191
2106- if ( _ . has ( param . schema , '$ref' ) ) {
2107- param . schema = resolveSchema ( context , param . schema ) ;
2108- }
2109-
21102192 if ( param . in !== PATHPARAM ) {
21112193 return ;
21122194 }
21132195
2196+
2197+ const shouldResolveSchema = _ . has ( param , 'schema' ) &&
2198+ ( _ . has ( param . schema , '$ref' ) || _ . has ( param . schema , 'anyOf' ) ||
2199+ _ . has ( param . schema , 'oneOf' ) || _ . has ( param . schema , 'allOf' ) ) ;
2200+
2201+ if ( shouldResolveSchema ) {
2202+ param . schema = resolveSchema ( context , param . schema ) ;
2203+ }
2204+
21142205 let pathParamTypeInfo = { } ,
21152206 properties = { } ,
21162207 paramValue = resolveValueOfParameter ( context , param ) ;
@@ -2180,14 +2271,18 @@ let QUERYPARAM = 'query',
21802271 param = resolveSchema ( context , param ) ;
21812272 }
21822273
2183- if ( _ . has ( param . schema , '$ref' ) ) {
2184- param . schema = resolveSchema ( context , param . schema ) ;
2185- }
2186-
21872274 if ( param . in !== HEADER || ( ! includeDeprecated && param . deprecated ) ) {
21882275 return ;
21892276 }
21902277
2278+ const shouldResolveSchema = _ . has ( param , 'schema' ) &&
2279+ ( _ . has ( param . schema , '$ref' ) || _ . has ( param . schema , 'anyOf' ) ||
2280+ _ . has ( param . schema , 'oneOf' ) || _ . has ( param . schema , 'allOf' ) ) ;
2281+
2282+ if ( shouldResolveSchema ) {
2283+ param . schema = resolveSchema ( context , param . schema ) ;
2284+ }
2285+
21912286 if ( ! keepImplicitHeaders && _ . includes ( IMPLICIT_HEADERS , _ . toLower ( _ . get ( param , 'name' ) ) ) ) {
21922287 return ;
21932288 }
@@ -2340,14 +2435,25 @@ let QUERYPARAM = 'query',
23402435
23412436 headers . push ( ...serialisedHeader ) ;
23422437
2343- if ( headerData && headerData . name && headerData . schema && headerData . schema . type ) {
2344- const { schema } = headerData ;
2438+ if ( headerData && headerData . name && headerData . schema ) {
2439+ let { schema } = headerData ;
2440+ const shouldResolveSchema = _ . has ( schema , '$ref' ) || _ . has ( schema , 'anyOf' ) ||
2441+ _ . has ( schema , 'oneOf' ) || _ . has ( schema , 'allOf' ) ;
2442+
2443+ if ( shouldResolveSchema ) {
2444+ schema = resolveSchema ( context , schema ) ;
2445+ }
2446+
2447+ if ( ! schema . type ) {
2448+ return ;
2449+ }
2450+
23452451 properties = {
23462452 type : schema . type ,
23472453 format : schema . format ,
23482454 default : schema . default ,
2349- required : schema . required || false ,
2350- deprecated : schema . deprecated || false ,
2455+ required : schema . required ,
2456+ deprecated : schema . deprecated ,
23512457 enum : schema . enum || undefined ,
23522458 minLength : schema . minLength ,
23532459 maxLength : schema . maxLength ,
0 commit comments