@@ -5,6 +5,19 @@ import { SwaggerRouterMetadata } from '../types/index.js';
55import { ConduitRoute } from '../classes/index.js' ;
66import { importDbTypes } from '../utils/types.js' ;
77import { processSwaggerParams } from './SimpleTypeParamUtils.js' ;
8+ import { mapGrpcErrorToHttp } from './util.js' ;
9+
10+ interface SwaggerExample {
11+ name : string ;
12+ message : string ;
13+ conduitCode : string ;
14+ }
15+
16+ interface SwaggerResponseContent {
17+ schema : { $ref : string } ;
18+ example ?: SwaggerExample ;
19+ examples ?: Record < string , { value : SwaggerExample } > ;
20+ }
821
922export class SwaggerGenerator {
1023 private _swaggerDoc : Indexable ;
@@ -31,6 +44,24 @@ export class SwaggerGenerator {
3144 ModelId : {
3245 type : 'string' ,
3346 } ,
47+ ErrorResponse : {
48+ type : 'object' ,
49+ properties : {
50+ name : {
51+ type : 'string' ,
52+ description : 'HTTP error name' ,
53+ } ,
54+ message : {
55+ type : 'string' ,
56+ description : 'Error message' ,
57+ } ,
58+ conduitCode : {
59+ type : 'string' ,
60+ description : 'Conduit internal error code' ,
61+ } ,
62+ } ,
63+ required : [ 'httpCode' , 'conduitCode' , 'description' ] ,
64+ } ,
3465 } ,
3566 securitySchemes : this . _routerMetadata . securitySchemes ,
3667 } ,
@@ -152,6 +183,70 @@ export class SwaggerGenerator {
152183 this . _swaggerDoc . paths [ path ] = { } ;
153184 this . _swaggerDoc . paths [ path ] [ method ] = routeDoc ;
154185 }
186+
187+ const errors = route . input . errors || [ ] ;
188+ const errorGroups : Record <
189+ string ,
190+ Record <
191+ string ,
192+ { name : string ; message : string ; conduitCode : string ; description : string } [ ]
193+ >
194+ > = { } ;
195+ for ( const error of errors ) {
196+ const { conduitCode, grpcCode, message, description } = error ;
197+ const { name, status } = mapGrpcErrorToHttp ( grpcCode ) ;
198+ if ( ! errorGroups [ status ] ) errorGroups [ status ] = { } ;
199+ if ( ! errorGroups [ status ] [ conduitCode ] ) errorGroups [ status ] [ conduitCode ] = [ ] ;
200+ errorGroups [ status ] [ conduitCode ] . push ( {
201+ name,
202+ message,
203+ conduitCode,
204+ description,
205+ } ) ;
206+ }
207+
208+ for ( const status in errorGroups ) {
209+ const allExamples : {
210+ name : string ;
211+ message : string ;
212+ conduitCode : string ;
213+ description : string ;
214+ } [ ] = [ ] ;
215+ for ( const conduitCode in errorGroups [ status ] ) {
216+ allExamples . push ( ...errorGroups [ status ] [ conduitCode ] ) ;
217+ }
218+ const responseContent : { 'application/json' : SwaggerResponseContent } = {
219+ 'application/json' : {
220+ schema : {
221+ $ref : '#/components/schemas/ErrorResponse' ,
222+ } ,
223+ } ,
224+ } ;
225+ if ( allExamples . length === 1 ) {
226+ responseContent [ 'application/json' ] [ 'example' ] = {
227+ name : allExamples [ 0 ] . name ,
228+ message : allExamples [ 0 ] . message ,
229+ conduitCode : allExamples [ 0 ] . conduitCode ,
230+ } ;
231+ } else if ( allExamples . length > 1 ) {
232+ responseContent [ 'application/json' ] [ 'examples' ] = { } ;
233+ allExamples . forEach ( example => {
234+ const { name, message, conduitCode, description } = example ;
235+ if ( responseContent [ 'application/json' ] [ 'examples' ] ) {
236+ responseContent [ 'application/json' ] [ 'examples' ] [ description ] = {
237+ value : {
238+ name,
239+ message,
240+ conduitCode,
241+ } ,
242+ } ;
243+ }
244+ } ) ;
245+ }
246+ routeDoc . responses [ status ] = {
247+ content : responseContent ,
248+ } ;
249+ }
155250 }
156251
157252 private _extractMethod ( action : string ) {
0 commit comments