Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save micaiah-effiong/cea6ec9c270091c4a1850b28a026ca58 to your computer and use it in GitHub Desktop.

Select an option

Save micaiah-effiong/cea6ec9c270091c4a1850b28a026ca58 to your computer and use it in GitHub Desktop.
transforms response entity for swagger docs decorators
import { Type } from '@nestjs/common';
import {
ApiProperty,
ApiPropertyOptions,
ApiResponse,
ApiResponseOptions,
} from '@nestjs/swagger';
export const CustomApiResponseArray = <T>(
entity: Type<T>,
propertyOption: ApiPropertyOptions = {},
responseOptions: ResponseTransformerOptions = {},
) => {
const { statusCode, ..._options } = responseOptions;
class PayloadArray {
@ApiProperty({ type: Number, example: statusCode || 200 })
statusCode!: number;
@ApiProperty({ type: entity, isArray: true, ...propertyOption })
result!: T[];
@ApiProperty({ type: String, nullable: true })
message?: string;
}
/**
* This line changes the constructor name from [Payload]
* to the name of the given entity, with an appended paylaod
*
* If entity is User, this becomes UserPayloadArray
*/
Object.defineProperty(PayloadArray, 'name', {
value: entity['name'] + 'PayloadArray',
});
return ApiResponse({
type: PayloadArray,
..._options,
});
};
export const CustomApiResponse = <T>(
entity: Type<T>,
propertyOption: ApiPropertyOptions = {},
responseOptions: ResponseTransformerOptions = {},
) => {
const { statusCode, ..._options } = responseOptions;
class Payload {
@ApiProperty({ type: Number, example: statusCode || 200 })
statusCode!: number;
@ApiProperty({ type: entity, ...propertyOption })
result!: T;
@ApiProperty({ type: String, nullable: true })
message?: string;
}
/**
* This line changes the constructor name from [Payload]
* to the name of the given entity, with an appended paylaod
*
* If entity is User, this becomes UserPayload
*/
Object.defineProperty(Payload, 'name', { value: entity['name'] + 'Payload' });
return ApiResponse({
type: Payload,
..._options,
});
};
type ResponseTransformerOptions = Omit<ApiResponseOptions, 'type'> & {
statusCode?: number;
};
@micaiah-effiong
Copy link
Author

How to use

class User {
  @ApiProperty({ format: 'uuid' })
  @IsUUID()
  id: string;

  @ApiProperty({ format: 'email' })
  email: string;
}

@ApiOkResponse({ schema: ApiResponseTransformer(User) })
@Post(':id')
async update(
  @Param('id') id: string,
  @Body() createUserDto: unknown,
  @Request() req: Request,
) {
  // *** your code goes here ***
}

@micaiah-effiong
Copy link
Author

How to use v2
This version uses the custom response as a decorator

class User {
  @ApiProperty({ format: 'uuid' })
  @IsUUID()
  id: string;

  @ApiProperty({ format: 'email' })
  email: string;
}

@CustomApiResponse(User)
@Post(':id')
async update(
  @Param('id') id: string,
  @Body() createUserDto: unknown,
  @Request() req: Request,
) {
  // *** your code goes here ***
}

@micaiah-effiong
Copy link
Author

I made a little update to resolve typescript errors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment