Skip to content

Commit

Permalink
fix(core): Add new decorator ApiCallbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
MiguelSavignano committed Feb 9, 2023
1 parent 1b38cea commit 207e7a6
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 2 deletions.
46 changes: 45 additions & 1 deletion e2e/api-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,51 @@
{
"basic": []
}
]
],
"callbacks": {
"myEvent": {
"{$request.body#/callbackUrl}": {
"post": {
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Cat"
}
}
}
},
"responses": {
"200": {
"description": "Your server returns this code if it accepts the callback"
}
}
}
}
},
"mySecondEvent": {
"{$request.body#/callbackUrl}": {
"post": {
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Cat"
}
}
}
},
"responses": {
"200": {
"description": "Your server returns this code if it accepts the callback"
}
}
}
}
}
}
},
"get": {
"operationId": "CatsController_findAll",
Expand Down
26 changes: 25 additions & 1 deletion e2e/src/cats/cats.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import {
ApiQuery,
ApiResponse,
ApiSecurity,
ApiTags
ApiTags,
ApiCallbacks,
getSchemaPath
} from '../../../lib';
import { CatsService } from './cats.service';
import { Cat } from './classes/cat.class';
Expand All @@ -30,6 +32,28 @@ import { LettersEnum, PaginationQuery } from './dto/pagination-query.dto';
export class CatsController {
constructor(private readonly catsService: CatsService) {}

@ApiCallbacks({
name: 'mySecondEvent',
callbackUrl: '{$request.body#/callbackUrl}',
method: 'post',
requestBody: {
type: Cat
},
expectedResponse: {
status: 200
}
})
@ApiCallbacks({
name: 'myEvent',
callbackUrl: '{$request.body#/callbackUrl}',
method: 'post',
requestBody: {
type: Cat
},
expectedResponse: {
status: 200
}
})
@ApiTags('create cats')
@Post()
@ApiOperation({ summary: 'Create cat' })
Expand Down
14 changes: 14 additions & 0 deletions e2e/validate-schema.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ describe('Validate OpenAPI schema', () => {
api.info.version
);
expect(api.info.title).toEqual('Cats example');
expect(
api.paths['/api/cats']['post']['callbacks']['myEvent'][
'{$request.body#/callbackUrl}'
]['post']['requestBody']['content']['application/json']['schema'][
'properties'
]['breed']['type']
).toEqual('string');
expect(
api.paths['/api/cats']['post']['callbacks']['mySecondEvent'][
'{$request.body#/callbackUrl}'
]['post']['requestBody']['content']['application/json']['schema'][
'properties'
]['breed']['type']
).toEqual('string');
expect(api.paths['/api/cats']['get']['x-codeSamples'][0]['lang']).toEqual(
'JavaScript'
);
Expand Down
1 change: 1 addition & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const DECORATORS = {
API_PRODUCES: `${DECORATORS_PREFIX}/apiProduces`,
API_CONSUMES: `${DECORATORS_PREFIX}/apiConsumes`,
API_TAGS: `${DECORATORS_PREFIX}/apiUseTags`,
API_CALLBACKS: `${DECORATORS_PREFIX}/apiCallbacks`,
API_PARAMETERS: `${DECORATORS_PREFIX}/apiParameters`,
API_HEADERS: `${DECORATORS_PREFIX}/apiHeaders`,
API_MODEL_PROPERTIES: `${DECORATORS_PREFIX}/apiModelProperties`,
Expand Down
7 changes: 7 additions & 0 deletions lib/decorators/api-callbacks.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { DECORATORS } from '../constants';
import { createMixedDecorator } from './helpers';
import { CallBackObject } from '../interfaces/callback-object.interface'

export function ApiCallbacks(...callbackObject: Array<CallBackObject<any>>) {
return createMixedDecorator(DECORATORS.API_CALLBACKS, callbackObject);
}
1 change: 1 addition & 0 deletions lib/decorators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export * from './api-query.decorator';
export * from './api-response.decorator';
export * from './api-security.decorator';
export * from './api-use-tags.decorator';
export * from './api-callbacks.decorator';
export * from './api-extension.decorator';
49 changes: 49 additions & 0 deletions lib/explorers/api-callbacks.explorer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Type } from '@nestjs/common';
import { DECORATORS } from '../constants';
import { getSchemaPath } from '../utils';
import { CallBackObject } from '../interfaces/callback-object.interface'

export const exploreApiCallbacksMetadata = (
instance: object,
prototype: Type<unknown>,
method: object
) => {
const callbacksData = Reflect.getMetadata(DECORATORS.API_CALLBACKS, method);
if (!callbacksData) return callbacksData;

return callbacksData.reduce((acc, callbackData: CallBackObject<string | Function>) => {
const {
name: eventName,
callbackUrl,
method: callbackMethod,
requestBody,
expectedResponse
} = callbackData;
return {
...acc,
[eventName]: {
[callbackUrl]: {
[callbackMethod]: {
requestBody: {
required: true,
content: {
'application/json': {
schema: {
$ref: getSchemaPath(requestBody.type)
}
}
}
},
responses: {
[expectedResponse.status]: {
description:
expectedResponse.description ||
'Your server returns this code if it accepts the callback'
}
}
}
}
}
};
}, {});
};
3 changes: 3 additions & 0 deletions lib/extra/swagger-shim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ export function ApiSecurity() {
export function ApiTags() {
return () => {};
}
export function ApiCallbacks() {
return () => {};
}
export function ApiExtension() {
return () => {};
}
Expand Down
12 changes: 12 additions & 0 deletions lib/interfaces/callback-object.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface CallBackObject<T> {
name: string,
callbackUrl: string,
method: string,
requestBody: {
type: T
},
expectedResponse: {
status: number
description?: string
},
}
1 change: 1 addition & 0 deletions lib/interfaces/denormalized-doc-resolvers.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export interface DenormalizedDocResolvers {
root: Function[];
security: Function[];
tags: Function[];
callbacks: Function[];
responses: Function[];
}
2 changes: 2 additions & 0 deletions lib/swagger-explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
} from 'lodash';
import * as pathToRegexp from 'path-to-regexp';
import { DECORATORS } from './constants';
import { exploreApiCallbacksMetadata } from './explorers/api-callbacks.explorer';
import { exploreApiExcludeControllerMetadata } from './explorers/api-exclude-controller.explorer';
import { exploreApiExcludeEndpointMetadata } from './explorers/api-exclude-endpoint.explorer';
import {
Expand Down Expand Up @@ -96,6 +97,7 @@ export class SwaggerExplorer {
],
security: [exploreApiSecurityMetadata],
tags: [exploreApiTagsMetadata],
callbacks: [exploreApiCallbacksMetadata],
responses: [exploreApiResponseMetadata.bind(null, this.schemas)]
};
return this.generateDenormalizedDocument(
Expand Down

0 comments on commit 207e7a6

Please sign in to comment.