javascriptnode.jstypescriptnestjsclass-validator

No metadata found for class-validator


I am trying to use a ValidationPipe but no matter how I write my code I get the following warning when sending a request: No metadata found. There is more than once class-validator version installed probably. You need to flatten your dependencies.

My route looks something like this:

@Get()
@UsePipes(new ValidationPipe({ transform: true }))
async findAll(@Query() queryDto: QueryDto) {
    return await this.myService.findAll(queryDto);
}

And my DTO looks something like this:

export class queryDto
{
    @ApiModelProperty({
        description: 'Maximum number of results',
        type: Number,
        example: 50,
        default: 50,
        required: false
    })
    readonly limit: number = 50;
}

I tried using the ValidationPipe several ways, following the doc, but nothing works for me. I know it does not work because although the request gets a response, the default value that I wrote in my DTO for the property limit, which is 50, is not used when the query is empty. Therefore, when no limit is provided in the query, limit's value is undefined, whereas it should be 50 (which means the ValidationPipe is not used).

My package.json seems correct:

npm ls class-validator
api-sport@0.0.1 /home/pierre_t/Bureau/dev/ApiSport
└── class-validator@0.9.1

Full package.json:

{
  "name": "api-sport",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "license": "MIT",
  "scripts": {
    "build": "tsc -p tsconfig.build.json",
    "format": "prettier --write \"src/**/*.ts\"",
    "start": "ts-node -r tsconfig-paths/register src/main.ts",
    "start:dev": "nodemon",
    "start:debug": "nodemon --config nodemon-debug.json",
    "start:prod": "pm2 start ./src/main.js --no-daemon",
    "lint": "tslint -p tsconfig.json -c tslint.json",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  "dependencies": {
    "@nestjs/common": "^6.0.5",
    "@nestjs/core": "^6.0.5",
    "@nestjs/platform-express": "^6.0.5",
    "@nestjs/swagger": "^3.0.1",
    "@nestjs/typeorm": "^6.0.0",
    "@types/lodash": "^4.14.123",
    "class-transformer": "^0.2.0",
    "class-validator": "^0.9.1",
    "dotenv": "^7.0.0",
    "hbs": "^4.0.3",
    "mysql": "^2.16.0",
    "pm2": "^3.4.1",
    "reflect-metadata": "^0.1.12",
    "rimraf": "^2.6.2",
    "rxjs": "^6.3.3",
    "swagger-ui-express": "^4.0.2",
    "typeorm": "^0.2.16"
  },
  "devDependencies": {
    "@nestjs/testing": "^6.0.5",
    "@types/express": "^4.16.0",
    "@types/jest": "^23.3.13",
    "@types/node": "^10.14.4",
    "@types/supertest": "^2.0.7",
    "jest": "^23.6.0",
    "nodemon": "^1.18.9",
    "prettier": "^1.15.3",
    "supertest": "^3.4.1",
    "ts-jest": "^23.10.5",
    "ts-node": "^7.0.1",
    "tsconfig-paths": "^3.7.0",
    "tslint": "5.12.1",
    "typescript": "^3.4.1"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".spec.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}

Why do I get this message and how can I use ValidationPipe?


Solution

  • This is because you are using class-validator but without any validations, see this issue:

    Basically, it warns that you don't have any metadatas in the storage, which means you haven't used any decorator from class-validator. That means you don't perform any validation, so you should just pass validate: false option to buildSchema to disable automatic validation.

    I'm not sure if you can turn of validation for nest's ValidationPipe, but alternatively you can just add an assertion to your dto (if it makes sense), e.g.:

    import { Min } from 'class-validator';
    export class QueryDto {
        @Min(1)
        readonly limit: number = 50;
    }
    

    By the way: Since your @Query will only have string properties, you'll probably want to transform your limit from string to number. Have a look at this answer.