@@ -31,6 +31,10 @@ interface IBuildParametersArguments {
3131
3232const PATH_VARIABLES_REGEX = / : ( [ A - Z a - z ] + ) / g
3333
34+ function resolveBodySchemaName ( route : Route ) : string {
35+ return `${ route . operationName } Body` ;
36+ }
37+
3438function translateScalarType ( scalarType : string ) : string {
3539 switch ( scalarType ) {
3640 case 'Int' :
@@ -74,6 +78,19 @@ function buildObjectDefinition(node: any): any {
7478 return objectDoc ;
7579}
7680
81+ function buildBodyDefinition ( variables : IOperationVariable [ ] , refLocation : string ) : any {
82+ const bodyDoc : any = { } ;
83+
84+ bodyDoc . type = 'object' ;
85+ bodyDoc . properties = { } ;
86+
87+ variables . forEach ( ( field : IOperationVariable ) => {
88+ bodyDoc . properties [ field . name ] = buildSchemaParameter ( field , refLocation ) ;
89+ } ) ;
90+
91+ return bodyDoc ;
92+ }
93+
7794function buildDefinition ( node : any ) : any {
7895 switch ( node . kind ) {
7996 case 'INPUT_OBJECT' :
@@ -107,32 +124,31 @@ function openApiPath(path: string): string {
107124 return path . replace ( PATH_VARIABLES_REGEX , '{$1}' ) ;
108125}
109126
127+ function buildSchemaParameter ( variableDefinition : IOperationVariable , refLocation : string ) : IParameterArraySchema | IParameterItemTypeOrRef {
128+ if ( variableDefinition . array ) {
129+ return {
130+ type : 'array' ,
131+ items : {
132+ '$ref' : `${ refLocation } /${ variableDefinition . type } `
133+ } ,
134+ } ;
135+ }
136+
137+ return {
138+ '$ref' : `${ refLocation } /${ variableDefinition . type } `
139+ } ;
140+ }
141+
110142// TODO: Return Type and Attempt to get description from graphql
111143function buildParametersArray ( { variableDefinitions, variableLocation, refLocation } : IBuildParametersArguments ) : IParameter [ ] {
112144 return variableDefinitions . map (
113- ( variableDefinition : IOperationVariable ) : IParameter => {
114- const parameter : IParameter = {
115- name : variableDefinition . name ,
116- required : variableDefinition . required ,
117- // default: variableDefinition.defaultValue,
118- in : variableLocation ,
119- } ;
120-
121- if ( variableDefinition . array ) {
122- parameter . schema = {
123- type : 'array' ,
124- items : {
125- '$ref' : `${ refLocation } /${ variableDefinition . type } `
126- } ,
127- } ;
128- } else {
129- parameter . schema = {
130- '$ref' : `${ refLocation } /${ variableDefinition . type } `
131- } ;
132- }
133-
134- return parameter ;
135- }
145+ ( variableDefinition : IOperationVariable ) : IParameter => ( {
146+ name : variableDefinition . name ,
147+ required : variableDefinition . required ,
148+ in : variableLocation ,
149+ schema : buildSchemaParameter ( variableDefinition , refLocation ) ,
150+ // default: variableDefinition.defaultValue,
151+ } )
136152 ) ;
137153}
138154
@@ -322,6 +338,7 @@ export class V3 extends MountableDocument {
322338 const { options } = this ;
323339
324340 const doc : any = { } ;
341+ const refLocation = '#/components/schemas' ;
325342
326343 doc . openapi = '3.0.0' ;
327344 doc . info = { } ;
@@ -368,25 +385,31 @@ export class V3 extends MountableDocument {
368385 ...buildParametersArray ( {
369386 variableDefinitions : route . queryVariables ,
370387 variableLocation : 'query' ,
371- refLocation : '#/components/schemas' ,
388+ refLocation,
372389 } )
373390 ) ;
374391
375392 routeDoc . parameters . push (
376393 ...buildParametersArray ( {
377394 variableDefinitions : route . pathVariables ,
378395 variableLocation : 'path' ,
379- refLocation : '#/components/schemas' ,
396+ refLocation,
380397 } )
381398 ) ;
382399
383- routeDoc . parameters . push (
384- ...buildParametersArray ( {
385- variableDefinitions : route . bodyVariables ,
386- variableLocation : 'body' ,
387- refLocation : '#/components/schemas' ,
388- } )
389- ) ;
400+ if ( route . bodyVariables . length ) {
401+ const schemaName = resolveBodySchemaName ( route ) ;
402+
403+ routeDoc . requestBody = {
404+ content : {
405+ 'application/json' : {
406+ schema : {
407+ "$ref" : `${ refLocation } /${ schemaName } `
408+ } ,
409+ } ,
410+ } ,
411+ } ;
412+ }
390413 } ) ;
391414
392415 doc . components = { } ;
@@ -401,6 +424,17 @@ export class V3 extends MountableDocument {
401424 doc . components . schemas [ variableName ] = buildDefinition ( variableDefinition ) ;
402425 } ) ;
403426
427+ // Build out definitions for each route to contain a "body" schema in case it's used
428+ // for anything besides GET
429+ router . routes . forEach (
430+ ( route ) => {
431+ const schemaName = resolveBodySchemaName ( route ) ;
432+
433+ doc . components . schemas [ schemaName ] =
434+ buildBodyDefinition ( route . bodyVariables , refLocation ) ;
435+ }
436+ ) ;
437+
404438 return doc ;
405439 } catch ( error ) {
406440 return {
0 commit comments