diff --git a/spec/exclude-swagger/exclude-swagger.spec.ts b/spec/exclude-swagger/exclude-swagger.spec.ts index 457e92c..7a6c31e 100644 --- a/spec/exclude-swagger/exclude-swagger.spec.ts +++ b/spec/exclude-swagger/exclude-swagger.spec.ts @@ -101,14 +101,14 @@ describe('exclude swagger by route', () => { content: { 'application/json': { schema: { - $ref: '#/components/schemas/CreateBaseBodyDto', + $ref: '#/components/schemas/PickTypeClass', anyOf: [ { - $ref: '#/components/schemas/CreateBaseBodyDto', + $ref: '#/components/schemas/PickTypeClass', }, { items: { - $ref: '#/components/schemas/CreateBaseBodyDto', + $ref: '#/components/schemas/PickTypeClass', }, type: 'array', }, diff --git a/spec/swagger-decorator/swagger-decorator.controller.ts b/spec/swagger-decorator/swagger-decorator.controller.ts index 1c75294..04de816 100644 --- a/spec/swagger-decorator/swagger-decorator.controller.ts +++ b/spec/swagger-decorator/swagger-decorator.controller.ts @@ -2,6 +2,7 @@ import { Controller } from '@nestjs/common'; import { ApiParam } from '@nestjs/swagger'; import { ParamsRequestInterceptor } from './params.request.interceptor'; +import { UpdateRequestDto } from './update-request.dto'; import { Crud } from '../../src/lib/crud.decorator'; import { CrudController } from '../../src/lib/interface'; import { BaseEntity } from '../base/base.entity'; @@ -22,6 +23,11 @@ import { BaseService } from '../base/base.service'; interceptors: [ParamsRequestInterceptor], decorators: [ApiParam({ name: 'key', required: true })], }, + update: { + swagger: { + body: UpdateRequestDto, + }, + }, }, }) @Controller('swagger-decorator/:key') diff --git a/spec/swagger-decorator/swagger-decorator.spec.ts b/spec/swagger-decorator/swagger-decorator.spec.ts index 3574931..af05ccc 100644 --- a/spec/swagger-decorator/swagger-decorator.spec.ts +++ b/spec/swagger-decorator/swagger-decorator.spec.ts @@ -1,13 +1,18 @@ import { HttpStatus, INestApplication } from '@nestjs/common'; +import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper'; +import { DenormalizedDoc } from '@nestjs/swagger/dist/interfaces/denormalized-doc.interface'; +import { RequestBodyObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface'; import { Test, TestingModule } from '@nestjs/testing'; import request from 'supertest'; +import { SwaggerDecoratorController } from './swagger-decorator.controller'; import { SwaggerDecoratorModule } from './swagger-decorator.module'; import { BaseEntity } from '../base/base.entity'; import { TestHelper } from '../test.helper'; describe('SwaggerDecorator', () => { let app: INestApplication; + let routeSet: Record; beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ @@ -15,8 +20,14 @@ describe('SwaggerDecorator', () => { }).compile(); app = moduleFixture.createNestApplication(); + const controller = moduleFixture.get(SwaggerDecoratorController); await app.init(); + + routeSet = TestHelper.getSwaggerExplorer({ + instance: controller, + metatype: SwaggerDecoratorController, + } as InstanceWrapper); }); afterAll(async () => { @@ -43,4 +54,10 @@ describe('SwaggerDecorator', () => { .expect(HttpStatus.OK); expect(readOneBody.name).toEqual('name'); }); + + it('should be override swagger decorator', async () => { + expect((routeSet['patch /swagger-decorator/{key}/{id}'].root?.requestBody as RequestBodyObject)?.description).toEqual( + 'UpdateBaseDto', + ); + }); }); diff --git a/spec/swagger-decorator/update-request.dto.ts b/spec/swagger-decorator/update-request.dto.ts new file mode 100644 index 0000000..dc67bd3 --- /dev/null +++ b/spec/swagger-decorator/update-request.dto.ts @@ -0,0 +1,8 @@ +import { ApiPropertyOptional } from '@nestjs/swagger'; + +import { BaseEntity } from '../base/base.entity'; + +export class UpdateRequestDto implements Partial { + @ApiPropertyOptional({ description: 'optional name', type: String }) + name: string; +} diff --git a/src/lib/crud.route.factory.ts b/src/lib/crud.route.factory.ts index 282e38d..efb5228 100644 --- a/src/lib/crud.route.factory.ts +++ b/src/lib/crud.route.factory.ts @@ -330,6 +330,10 @@ export class CrudRouteFactory { } if (CRUD_POLICY[method].useBody) { const bodyType = (() => { + const customBody = this.crudOptions.routes?.[method]?.swagger?.body; + if (customBody != null) { + return customBody; + } if (method === Method.SEARCH) { return RequestSearchDto; } diff --git a/src/lib/interface/decorator-option.interface.ts b/src/lib/interface/decorator-option.interface.ts index 23b4139..cebe657 100644 --- a/src/lib/interface/decorator-option.interface.ts +++ b/src/lib/interface/decorator-option.interface.ts @@ -24,6 +24,10 @@ interface RouteBaseOption { * Configures the Swagger documentation for the route's response */ response?: Type; + /** + * Configures the Swagger documentation for the route's request body + */ + body?: Type; }; /** * Configures the keys of entity to exclude from the route's response