Skip to content

Commit

Permalink
Merge pull request #536 from tomchinery/feature/#195-api-extension-de…
Browse files Browse the repository at this point in the history
…corator

feat(api-extension): add support for open api extensions via decorator (#195)
  • Loading branch information
kamilmysliwiec committed Feb 23, 2020
2 parents 1c4bde3 + f3fea1e commit c6067c6
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 2 deletions.
3 changes: 3 additions & 0 deletions e2e/api-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@
"/api/cats": {
"post": {
"operationId": "CatsController_create",
"x-foo": {
"test": "bar "
},
"summary": "Create cat",
"parameters": [],
"requestBody": {
Expand Down
2 changes: 2 additions & 0 deletions e2e/src/cats/cats.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ApiOperation,
ApiResponse,
ApiSecurity,
ApiExtension,
ApiTags
} from '../../../lib';
import { CatsService } from './cats.service';
Expand All @@ -28,6 +29,7 @@ export class CatsController {
type: () => Cat
})
@ApiResponse({ status: 403, description: 'Forbidden.' })
@ApiExtension('x-foo', { test: 'bar ' })
async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
return this.catsService.create(createCatDto);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ export const DECORATORS = {
API_MODEL_PROPERTIES_ARRAY: `${DECORATORS_PREFIX}/apiModelPropertiesArray`,
API_SECURITY: `${DECORATORS_PREFIX}/apiSecurity`,
API_EXCLUDE_ENDPOINT: `${DECORATORS_PREFIX}/apiExcludeEndpoint`,
API_EXTRA_MODELS: `${DECORATORS_PREFIX}/apiExtraModels`
API_EXTRA_MODELS: `${DECORATORS_PREFIX}/apiExtraModels`,
API_EXTENSION: `${DECORATORS_PREFIX}/apiExtension`
};
18 changes: 18 additions & 0 deletions lib/decorators/api-extension.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { DECORATORS } from '../constants';
import { createMixedDecorator } from './helpers';

export function ApiExtension(extensionKey: string, extensionProperties: any) {
if (!extensionKey.startsWith('x-')) {
throw new Error(
'Extension key is not prefixed. Please ensure you prefix it with `x-`.'
);
}

const extensionObject = {
[extensionKey]: {
...extensionProperties
}
};

return createMixedDecorator(DECORATORS.API_EXTENSION, extensionObject);
}
1 change: 1 addition & 0 deletions lib/decorators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export * from './api-query.decorator';
export * from './api-response.decorator';
export * from './api-security.decorator';
export * from './api-use-tags.decorator';
export * from './api-extension.decorator';
4 changes: 3 additions & 1 deletion lib/swagger-explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,12 @@ export class SwaggerExplorer {
method
) as RequestMethod;
const fullPath = globalPath + this.validateRoutePath(routePath);
const apiExtension = Reflect.getMetadata(DECORATORS.API_EXTENSION, method);
return {
method: RequestMethod[requestMethod].toLowerCase(),
path: fullPath === '' ? '/' : fullPath,
operationId: this.getOperationId(instance, method)
operationId: this.getOperationId(instance, method),
...apiExtension
};
}

Expand Down

0 comments on commit c6067c6

Please sign in to comment.