Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
[email protected] /home/pierre_t/Bureau/dev/ApiSport
└── [email protected]

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?

like image 230
papillon Avatar asked Apr 03 '19 09:04

papillon


2 Answers

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.

like image 92
Kim Kern Avatar answered Nov 06 '22 14:11

Kim Kern


The question has already been answered, but for future reference of people with the same problem...

The class-validator allows you to bypass the validation of certain property (whitelisting) special flags to validate any property.

As the docs:

This will strip all properties that don't have any decorators. If no other decorator is suitable for your property, you can use @Allow decorator

e.g:

import {validate, Allow, Min} from "class-validator";

export class Post {

    @Allow()
    title: string;

    @Min(0)
    views: number;

    nonWhitelistedProperty: number;
}
like image 1
Mathiasfc Avatar answered Nov 06 '22 15:11

Mathiasfc