Adding Swagger decorators to NestJS module for reuse

Viewed 672

I'd like to create a shared library for reuse in a related Express NestJS app. In order to do so and gain type introspection + examples on nested objects in the input/output, I am struggling to maintain information from the imported package that works just fine.

Here's a sample of my efforts that work locally when I pass in this class directly on the controller. However, when running this from a file that has only this exported, I lose the examples + introspection. I believe there is either an error in my typescript build that is causing metadata/decorators to be cut out, or there is a problem in my nest build in the api file, that causes the types to be lost.

My typed response classes (abbreviated) are here (identical when in the file or imported):

  export class ExtendedRelatedSubClass extends RelatedSubClass {
    private static exampleSubClass: RelatedSubClass = getRelatedSubClassMock()
  
    @ApiProperty({ example: ExtendedRelatedSubClass.exampleSubClass.randomProp })
    public randomProp: string
  }

  export class ExtendedUserResponse extends UserResponse {
    private static exampleUser: UserResponse = getUserMock()
  
    @ApiProperty({ example: ExtendedAccountHolderResponse.exampleAccountHolder.address })
    public address: ExtendedAddressResponse = new ExtendedAddressResponse()
  
    @ApiProperty({ example: ExtendedAccountHolderResponse.exampleAccountHolder.legalInformation })
    public relatedSubClass: ExtendedRelatedSubClass = new ExtendedRelatedSubClass()
  }

The class is then used on a controller like so:

export const userFilteredProps = [
  'randomSubClass',
] as const

export class FilteredUserResponse extends PickType(
  ExtendedUserResponse,
  userFilteredProps
) {}

@Controller('/:market/users')
export class UsersController {
  constructor(protected readonly userService: UserService) {}

  @Get('/')
  @HttpCode(200)
  public async getUser(
    @Param() params: MarketParam,
  ): Promise<FilteredUserResponse> {
}

My attempt at creating an external module does not maintain this integrity of the examples/decorators and has this tsconfig (I completely lose typing and examples when it is imported into the old file):

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"]
}

My nest-cli file for swagger:

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "entryFile": "create-swagger-app",
  "compilerOptions": {
    "plugins": [{
      "name": "@nestjs/swagger",
      "options": {
        "controllerFileNameSuffix": ".controller.ts",
        "classValidatorShim": true,
        "dtoFileNameSuffix": [".response.ts", ".request.ts"]
      }
    }]
  }
}

Are there any issues with how the file is being exported from the package? I have tried both nest build and yarn build with no success.

Could there be more parameters in my nest cli swagger build that are needed as well?

0 Answers
Related