Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: custom decorators ignore stopAtFirstError option #2234

Open
EizFeren opened this issue Sep 7, 2023 · 1 comment
Open

fix: custom decorators ignore stopAtFirstError option #2234

EizFeren opened this issue Sep 7, 2023 · 1 comment
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.

Comments

@EizFeren
Copy link

EizFeren commented Sep 7, 2023

Description

I've got a strange bug, when my custom decorators are stopping each other even with stopAtFirstError option set to false. Perharps standard class validator default decorators working as expected.

Minimal code-snippet showcasing the problem

class SomeDto {
  @IsStrongPassword({
    minNumbers: 1,
    minLowercase: 0,
    minUppercase: 0,
    minSymbols: 0,
  }, {
    message: 'VALIDATION_PASSWORD_STRENTGH',
  })
  @MaxLength(20, {
    message: 'VALIDATION_PASSWORD_LENGTH_MAX',
  })
  @MinLength(8, {
    message: 'VALIDATION_PASSWORD_LENGTH_MIN',
  })
  @Requires('currentPassword', { // custom decorator, checks `currentPassword` field is defined
    message: 'VALIDATION_CURRENT_PASSWORD_MISSING',
  })
  @Requires('newPasswordRepeat', { // custom decorator, checks `newPasswordRepeat` field is defined
    message: 'VALIDATION_PASSWORD_REPEAT_MISSING',
  })
  @IsOptional()
  newPassword?: string;
}

Input, provided for this dto:

{
  "newPassword": "qwe"
}

Custom decorator definition:

import {
  registerDecorator,
  ValidationArguments,
  ValidationOptions,
  ValidatorConstraint,
  ValidatorConstraintInterface,
} from 'class-validator';

export function Requires(property: string, validationOptions?: ValidationOptions) {
  return (object: any, propertyName: string) => {
    registerDecorator({
      target: object.constructor,
      propertyName,
      options: validationOptions,
      constraints: [
        property,
      ],
      validator: RequiresConstraint,
    });
  };
}

@ValidatorConstraint({
  name: 'Requires',
})
class RequiresConstraint implements ValidatorConstraintInterface {
  validate(value: any, args: ValidationArguments) {
    const [ relatedPropertyName ] = args.constraints;
    const relatedValue = (args.object as any)[relatedPropertyName];

    return relatedValue !== undefined;
  }
}

Expected behavior

I'm expecting all custom decorator checks to be done, as below:

{
  "messages": [
    "VALIDATION_CURRENT_PASSWORD_MISSING",
    "VALIDATION_PASSWORD_REPEAT_MISSING",
    "VALIDATION_PASSWORD_LENGTH_MIN",
    "VALIDATION_PASSWORD_STRENGTH"
  ]
}

Actual behavior

Check for newPasswordRepeat field was skipped

{
  "messages": [
    "VALIDATION_CURRENT_PASSWORD_MISSING",
    "VALIDATION_PASSWORD_LENGTH_MIN",
    "VALIDATION_PASSWORD_STRENGTH"
  ]
}
@EizFeren EizFeren added status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature. labels Sep 7, 2023
@EizFeren
Copy link
Author

EizFeren commented Sep 7, 2023

I've tried also with class validator Validate decorator and custom constraint (RequiresConstraint in example above), same result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.
Development

No branches or pull requests

1 participant