9
9
getDecoratorArguments ,
10
10
getDecoratorName ,
11
11
getMainCommentOfNode ,
12
+ getTsDocReturnsOrErrorOfNode ,
12
13
getTsDocTagsOfNode
13
14
} from '../utils/ast-utils' ;
14
15
import {
@@ -139,14 +140,34 @@ export class ControllerClassVisitor extends AbstractFileVisitor {
139
140
typeChecker ,
140
141
metadata
141
142
) ;
143
+
144
+ const apiResponseDecoratorsArray = this . createApiResponseDecorator (
145
+ factory ,
146
+ compilerNode ,
147
+ decorators ,
148
+ options ,
149
+ sourceFile ,
150
+ typeChecker ,
151
+ metadata
152
+ ) ;
153
+
142
154
const removeExistingApiOperationDecorator =
143
155
apiOperationDecoratorsArray . length > 0 ;
144
156
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
+ }
150
171
151
172
const modifiers = ts . getModifiers ( compilerNode ) ?? [ ] ;
152
173
const objectLiteralExpr = this . createDecoratorObjectLiteralExpr (
@@ -160,6 +181,7 @@ export class ControllerClassVisitor extends AbstractFileVisitor {
160
181
) ;
161
182
const updatedDecorators = [
162
183
...apiOperationDecoratorsArray ,
184
+ ...apiResponseDecoratorsArray ,
163
185
...existingDecorators ,
164
186
factory . createDecorator (
165
187
factory . createCallExpression (
@@ -302,6 +324,74 @@ export class ControllerClassVisitor extends AbstractFileVisitor {
302
324
}
303
325
}
304
326
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
+
305
395
createDecoratorObjectLiteralExpr (
306
396
factory : ts . NodeFactory ,
307
397
node : ts . MethodDeclaration ,
0 commit comments