@@ -34,6 +34,9 @@ class DefinitionGenerator {
3434
3535 this . schemaHandler = new SchemaHandler ( serverless , this . openAPI ) ;
3636
37+ this . operationIdMap = { } ;
38+ this . functionMap = { } ;
39+
3740 this . operationIds = [ ] ;
3841 this . schemaIDs = [ ] ;
3942
@@ -92,6 +95,8 @@ class DefinitionGenerator {
9295 throw err ;
9396 } ) ;
9497
98+ this . cleanupLinks ( ) ;
99+
95100 if ( this . serverless . service . custom . documentation . servers ) {
96101 const servers = this . createServers (
97102 this . serverless . service . custom . documentation . servers
@@ -156,6 +161,7 @@ class DefinitionGenerator {
156161 async createPaths ( ) {
157162 const paths = { } ;
158163 const httpFunctions = this . getHTTPFunctions ( ) ;
164+
159165 for ( const httpFunction of httpFunctions ) {
160166 for ( const event of httpFunction . event ) {
161167 if ( event ?. http ?. documentation || event ?. httpApi ?. documentation ) {
@@ -164,21 +170,11 @@ class DefinitionGenerator {
164170 event ?. http ?. documentation || event ?. httpApi ?. documentation ;
165171
166172 this . currentFunctionName = httpFunction . functionInfo . name ;
167-
168- let opId ;
169- if (
170- this . operationIds . includes ( httpFunction . functionInfo . name ) === false
171- ) {
172- opId = httpFunction . functionInfo . name ;
173- this . operationIds . push ( opId ) ;
174- } else {
175- opId = `${ httpFunction . functionInfo . name } -${ uuid ( ) } ` ;
176- }
173+ this . operationName = httpFunction . operationName ;
177174
178175 const path = await this . createOperationObject (
179176 event ?. http ?. method || event ?. httpApi ?. method ,
180- documentation ,
181- opId
177+ documentation
182178 ) . catch ( ( err ) => {
183179 throw err ;
184180 } ) ;
@@ -282,11 +278,25 @@ class DefinitionGenerator {
282278 Object . assign ( this . openAPI , { tags : tags } ) ;
283279 }
284280
285- async createOperationObject ( method , documentation , name = uuid ( ) ) {
281+ async createOperationObject ( method , documentation ) {
282+ let operationId = documentation ?. operationId || this . operationName ;
283+ if ( this . operationIds . includes ( operationId ) ) {
284+ operationId += `-${ uuid ( ) } ` ;
285+ }
286+
287+ const arr = this . functionMap [ this . operationName ] ;
288+ arr . push ( operationId ) ;
289+ this . functionMap [ this . operationName ] = arr ;
290+
291+ this . operationIds . push ( operationId ) ;
292+ Object . assign ( this . operationIdMap , {
293+ [ operationId ] : this . operationName ,
294+ } ) ;
295+
286296 const obj = {
287297 summary : documentation . summary || "" ,
288298 description : documentation . description || "" ,
289- operationId : documentation . operationId || name ,
299+ operationId : operationId ,
290300 parameters : [ ] ,
291301 tags : documentation . tags || [ ] ,
292302 } ;
@@ -472,6 +482,10 @@ class DefinitionGenerator {
472482 }
473483 }
474484
485+ if ( response . links ) {
486+ obj . links = this . createLinks ( response . links ) ;
487+ }
488+
475489 Object . assign ( responses , { [ response . statusCode ] : obj } ) ;
476490 }
477491
@@ -691,6 +705,36 @@ class DefinitionGenerator {
691705 return params ;
692706 }
693707
708+ createLinks ( links ) {
709+ const linksObj = { } ;
710+ for ( const link in links ) {
711+ const linkObj = links [ link ] ;
712+ const obj = { } ;
713+
714+ obj . operationId = linkObj . operation ;
715+
716+ if ( linkObj . description ) {
717+ obj . description = linkObj . description ;
718+ }
719+
720+ if ( linkObj . server ) {
721+ obj . server = this . createServers ( linkObj . server ) ;
722+ }
723+
724+ if ( linkObj . parameters ) {
725+ obj . parameters = linkObj . parameters ;
726+ }
727+
728+ if ( linkObj . requestBody ) {
729+ obj . requestBody = linkObj . requestBody ;
730+ }
731+
732+ Object . assign ( linksObj , { [ link ] : obj } ) ;
733+ }
734+
735+ return linksObj ;
736+ }
737+
694738 addToComponents ( type , schema , name ) {
695739 const schemaObj = {
696740 [ name ] : schema ,
@@ -863,6 +907,27 @@ class DefinitionGenerator {
863907 return examplesObj ;
864908 }
865909
910+ cleanupLinks ( ) {
911+ for ( const path of Object . keys ( this . openAPI . paths ) ) {
912+ for ( const [ name , value ] of Object . entries ( this . openAPI . paths [ path ] ) ) {
913+ for ( const [ statusCode , responseObj ] of Object . entries (
914+ value . responses
915+ ) ) {
916+ if ( responseObj . links ) {
917+ for ( const [ linkName , linkObj ] of Object . entries (
918+ responseObj . links
919+ ) ) {
920+ const opId = linkObj . operationId ;
921+ if ( this . functionMap [ opId ] ) {
922+ linkObj . operationId = this . functionMap [ opId ] [ 0 ] ;
923+ }
924+ }
925+ }
926+ }
927+ }
928+ }
929+ }
930+
866931 getHTTPFunctions ( ) {
867932 const isHttpFunction = ( funcType ) => {
868933 const keys = Object . keys ( funcType ) ;
@@ -883,7 +948,18 @@ class DefinitionGenerator {
883948 } )
884949 . map ( ( functionType ) => {
885950 const event = functionType . events . filter ( isHttpFunction ) ;
951+ const name = functionType . name
952+ . split (
953+ `${ this . serverless . service . service } -${ this . serverless . service . provider . stage } -`
954+ )
955+ . at ( - 1 ) ;
956+
957+ Object . assign ( this . functionMap , {
958+ [ name ] : [ ] ,
959+ } ) ;
960+
886961 return {
962+ operationName : name ,
887963 functionInfo : functionType ,
888964 handler : functionType . handler ,
889965 name : functionType . name ,
0 commit comments