99 getDecoratorArguments ,
1010 getDecoratorName ,
1111 getMainCommentOfNode ,
12+ getTsDocReturnsOrErrorOfNode ,
1213 getTsDocTagsOfNode
1314} from '../utils/ast-utils' ;
1415import {
@@ -139,14 +140,34 @@ export class ControllerClassVisitor extends AbstractFileVisitor {
139140 typeChecker ,
140141 metadata
141142 ) ;
143+
144+ const apiResponseDecoratorsArray = this . createApiResponseDecorator (
145+ factory ,
146+ compilerNode ,
147+ decorators ,
148+ options ,
149+ sourceFile ,
150+ typeChecker ,
151+ metadata
152+ ) ;
153+
142154 const removeExistingApiOperationDecorator =
143155 apiOperationDecoratorsArray . length > 0 ;
144156
145- const existingDecorators = removeExistingApiOperationDecorator
146- ? decorators . filter (
147- ( item ) => getDecoratorName ( item ) !== ApiOperation . name
148- )
149- : decorators ;
157+ const removeExistingApiResponseDecorator =
158+ apiResponseDecoratorsArray . length > 0 ;
159+
160+ let existingDecorators = decorators ;
161+ if (
162+ removeExistingApiOperationDecorator ||
163+ removeExistingApiResponseDecorator
164+ ) {
165+ existingDecorators = decorators . filter (
166+ ( item ) =>
167+ getDecoratorName ( item ) !== ApiOperation . name &&
168+ getDecoratorName ( item ) !== ApiResponse . name
169+ ) ;
170+ }
150171
151172 const modifiers = ts . getModifiers ( compilerNode ) ?? [ ] ;
152173 const objectLiteralExpr = this . createDecoratorObjectLiteralExpr (
@@ -160,6 +181,7 @@ export class ControllerClassVisitor extends AbstractFileVisitor {
160181 ) ;
161182 const updatedDecorators = [
162183 ...apiOperationDecoratorsArray ,
184+ ...apiResponseDecoratorsArray ,
163185 ...existingDecorators ,
164186 factory . createDecorator (
165187 factory . createCallExpression (
@@ -302,6 +324,74 @@ export class ControllerClassVisitor extends AbstractFileVisitor {
302324 }
303325 }
304326
327+ createApiResponseDecorator (
328+ factory : ts . NodeFactory ,
329+ node : ts . MethodDeclaration ,
330+ decorators : readonly ts . Decorator [ ] ,
331+ options : PluginOptions ,
332+ sourceFile : ts . SourceFile ,
333+ typeChecker : ts . TypeChecker ,
334+ metadata : ClassMetadata
335+ ) {
336+ if ( ! options . introspectComments ) {
337+ return [ ] ;
338+ }
339+ const apiResponseDecorator = getDecoratorOrUndefinedByNames (
340+ [ ApiResponse . name ] ,
341+ decorators ,
342+ factory
343+ ) ;
344+ let apiResponseExistingProps :
345+ | ts . NodeArray < ts . PropertyAssignment >
346+ | undefined = undefined ;
347+
348+ if ( apiResponseDecorator && ! options . readonly ) {
349+ const apiResponseExpr = head ( getDecoratorArguments ( apiResponseDecorator ) ) ;
350+ if ( apiResponseExpr ) {
351+ apiResponseExistingProps =
352+ apiResponseExpr . properties as ts . NodeArray < ts . PropertyAssignment > ;
353+ }
354+ }
355+
356+ const tags = getTsDocReturnsOrErrorOfNode ( node ) ;
357+ if ( ! tags . length ) {
358+ return [ ] ;
359+ }
360+
361+ return tags . map ( ( tag ) => {
362+ const properties = [
363+ ...( apiResponseExistingProps ?? factory . createNodeArray ( ) )
364+ ] ;
365+ properties . push (
366+ factory . createPropertyAssignment (
367+ 'status' ,
368+ factory . createNumericLiteral ( tag . status )
369+ )
370+ ) ;
371+ properties . push (
372+ factory . createPropertyAssignment (
373+ 'description' ,
374+ factory . createNumericLiteral ( tag . description )
375+ )
376+ ) ;
377+ const objectLiteralExpr = factory . createObjectLiteralExpression (
378+ compact ( properties )
379+ ) ;
380+ const methodKey = node . name . getText ( ) ;
381+ metadata [ methodKey ] = objectLiteralExpr ;
382+
383+ const apiResponseDecoratorArguments : ts . NodeArray < ts . Expression > =
384+ factory . createNodeArray ( [ objectLiteralExpr ] ) ;
385+ return factory . createDecorator (
386+ factory . createCallExpression (
387+ factory . createIdentifier ( `${ OPENAPI_NAMESPACE } .${ ApiResponse . name } ` ) ,
388+ undefined ,
389+ apiResponseDecoratorArguments
390+ )
391+ ) ;
392+ } ) ;
393+ }
394+
305395 createDecoratorObjectLiteralExpr (
306396 factory : ts . NodeFactory ,
307397 node : ts . MethodDeclaration ,
0 commit comments