class-validator icon indicating copy to clipboard operation
class-validator copied to clipboard

The names of the decorators are lost in the MetadataStorage

Open CyriacBr opened this issue 4 years ago • 8 comments

Description

Since the 0.12.x update, the names of the decorators are lost when stored. For example, when the IsString decorator is used, the metadata store a new entry with the type customValidation instead of isString. This seems to apply to all decorators, because of this line: https://github.com/typestack/class-validator/blob/1955250de64d76504df465aa02076a2e5b219bb7/src/register-decorator.ts#L80.

Reproduction

Inspect the stored metadata with getMetadataStorage().getTargetValidationMetadatas and you'll see that all entries' types are customValidation, instead of their decorator names.

Environment

  • [ ] nodejs: 10.18.1
  • [ ] browser: no
  • [ ] framework/library: standalone

class-validator version: 0.12.2

CyriacBr avatar May 30 '20 11:05 CyriacBr

@vlapo @NoNameProvided would you have an idea on that one please?

nolazybits avatar Jun 10 '20 22:06 nolazybits

Hi!

Can you please provide

  • the commit where the change was introduced
  • and your use-case (metadata storage is an internal part of the lib and it's not supposed to be consumed by anyone else than this lib)

NoNameProvided avatar Aug 08 '20 22:08 NoNameProvided

Hi. @NoNameProvided

The changes was introduced during the 0.12 update, removing all the decorator names from ValidatorType as you can see here. Because of this change and this line: type: options.name && ValidationTypes.isValid(options.name) ? options.name : ValidationTypes.CUSTOM_VALIDATION, all decorators seem to be saved in the medata store with "customValidation" as the type, instead of their respective names "isString", "isNumber", etc.

The use case if that my lib can read class-validator decorators for a specific class, and generate fixtures based on them, instead of using redundant decorators. (a @IsString() decorator specifically says that the prop is a string).:

class Author {
  @IsString()
  @Fixture()      // redundant
  name: string;

  @IsNumber()
  @Fixture()      // redundant
  age: number;
}

But now the names are lost, making it impossible to know which decorators were used at all.

I'm not sure if the store isn't supposed to be consumed by anyone, as it's publicly exported. And I'd rather it be kept like that, there's no harm in providing third party libs with the metadata store, in my opinion.

Regardless of my use case, I think it's "wrong", to discard the names of the decorators when saved in the store. One easy fix would be to add one more field to ValidationMetadataArgs:

const validationMetadataArgs: ValidationMetadataArgs = {
       name: options.name, // <=== we keep track of the decorator name
        type: options.name && ValidationTypes.isValid(options.name) ? options.name : ValidationTypes.CUSTOM_VALIDATION,
        target: options.target,
        propertyName: options.propertyName,
        validationOptions: options.options,
        constraintCls: constraintCls,
        constraints: options.constraints
    };
    getMetadataStorage().addValidationMetadata(new ValidationMetadata(validationMetadataArgs));

CyriacBr avatar Aug 09 '20 09:08 CyriacBr

Is there another way to extract the decorated property names? I was also using getTargetValidationMetadatas but it stopped working when I upgraded class-validator from 0.11.1 to 0.12.2. (My use case is plucking user-accessible fields for serialization.)

ferbs avatar Aug 18 '20 01:08 ferbs

Hi,

Ran into this fixing the inheritance issue #657. Given how ValidationType is used, it wasn't accurate to identify validators by it anyway. I've submitted PR #748 which persists validators name

NickKelly1 avatar Sep 08 '20 13:09 NickKelly1

@NickKelly1 @CyriacBr I have open the PR from your fork to @ts-revival/class-validator here https://github.com/ts-revival/class-validator/pull/9

following this comment https://github.com/typestack/class-validator/issues/812#issuecomment-739612691

nolazybits avatar Dec 07 '20 01:12 nolazybits

My workaround: ValidationTypes.isValid = () => true; But this seems to break validation (everything is valid now)

Clashsoft avatar Jun 05 '22 20:06 Clashsoft

@NickKelly1 @CyriacBr I have open the PR from your fork to @ts-revival/class-validator here ts-revival#9

I'm glad this was ported over, but you never released it :/ @nolazybits

Clashsoft avatar Jun 06 '22 17:06 Clashsoft

This feature/fix has been released in 0.14.0.

NoNameProvided avatar Dec 09 '22 18:12 NoNameProvided

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Jan 10 '23 01:01 github-actions[bot]