Skip to content

Commit

Permalink
fix: renamed decorators
Browse files Browse the repository at this point in the history
  • Loading branch information
rubiin committed Sep 23, 2023
1 parent f80e0ad commit 17cfae1
Show file tree
Hide file tree
Showing 16 changed files with 67 additions and 37 deletions.
8 changes: 4 additions & 4 deletions docs/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ Most decorators are combination of multiple decorators to make code more lesser
| `@IsNumberField(options?:IsNumberFieldOptions)` | Checks if given value is number, is required and has supplied min and max value |
| `@IsStringField(options?: IsStringFieldOptions)` | Checks if given value is string, is required and has supplied minlength and maxlength |
| `@IsEnumField(options?: IsEnumFieldOptions)` | Checks if value is an enum and is required |
| `@IsAfter(value)` | Checks if given date is after the passed date |
| `@IsAfterDateField(value)` | Checks if given date is after the passed date |
| `@IsDateInFormat(format)` | Checks if date string is in provided date format |
| `@IsEqualTo(value)` | Checks if value is in equal to the passed value |
| `@IsEqualToField(value)` | Checks if value is in equal to the passed value |
| `@IsGreaterThan(values)` | Checks if value is greater than the passed number value |
| `@IsPassword()` | Checks if value is a valid password |
| `@IsUsername()` | Checks if value is a valid username |
| `@IsPasswordField()` | Checks if value is a valid password |
| `@IsUsernameField()` | Checks if value is a valid username |
| `@IsProfane()` | Checks if value has curse words |
| `@IsUnique()` | Checks if value is unique. Queries database to do so. |
| `@UUIDParam(value)` | Checks if passed param is a valid uuid v4 |
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ultimate-nest",
"version": "1.20.0",
"version": "1.23.0",
"description": "NestJS + MikroORM blog example with batteries included",
"license": "MIT",
"author": {
Expand Down Expand Up @@ -120,7 +120,7 @@
"passport-magic-login": "^1.2.2",
"pino-http": "^8.5.0",
"pino-pretty": "^10.2.0",
"poolifier": "^2.7.1",
"poolifier": "^2.7.2",
"preview-email": "^3.0.19",
"prom-client": "^14.2.0",
"pug": "^3.0.2",
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions src/common/@types/interfaces/validator.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ export interface NumberFieldOptions extends BaseValidator, BaseArrayValidator {
positive?: boolean
}

export type MinMaxLengthOptions = Pick<StringFieldOptions, "each" | "minLength" | "maxLength">;

export interface FileValidator {
fileType?: RegExp | string
fileSize?: number
required?: boolean
}

export type MinMaxLengthOptions = Pick<StringFieldOptions, "each" | "minLength" | "maxLength">;

export type DateFieldOptions = BaseValidator & BaseArrayValidator;

export type EnumFieldOptions = DateFieldOptions;
export type EmailFieldOptions = DateFieldOptions;
export type UUIDFieldOptions = DateFieldOptions;
4 changes: 2 additions & 2 deletions src/common/decorators/validation/is-after.validator.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {Validator} from 'class-validator';
import {IsAfter} from './is-after.validator';
import {IsAfterField} from './is-after.validator';

const validator = new Validator();

describe('IsAfter', () => {
class MyClass {
startDate!: Date;

@IsAfter('startDate')
@IsAfterField('startDate')
endDate!: Date;
}

Expand Down
12 changes: 12 additions & 0 deletions src/common/decorators/validation/is-after.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,15 @@ export const IsAfter = (
});
};
};


// // add typesafe property string

// export const IsAfterField = <T>(property: keyof T, validationOptions?: ValidationOptions) => {
// return applyDecorators(
// IsNotEmpty({
// message: validationI18nMessage("validation.isNotEmpty"),
// }),
// IsAfter(String(property), validationOptions),
// );
// };
2 changes: 1 addition & 1 deletion src/common/decorators/validation/is-email.validator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { applyDecorators } from "@nestjs/common";
import { ArrayNotEmpty, IsArray, IsEmail, IsNotEmpty, IsOptional } from "class-validator";
import { Transform } from "class-transformer";
import type { EnumFieldOptions as EmailFieldOptions } from "@common/@types";
import type { EmailFieldOptions } from "@common/@types";
import { validationI18nMessage } from "@lib/i18n";

export const IsEmailField = (options_?: EmailFieldOptions) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {Validator} from 'class-validator';
import {IsEqualTo} from './is-equal-to.validator';
import {IsEqualToField} from './is-equal-to.validator';

const validator = new Validator();

describe('IsEqualTo', () => {
describe('IsEqualToField', () => {
class MyClass {
password!: string;

@IsEqualTo('password')
@IsEqualToField('password')
confirmPassword!: string;
}

Expand Down
2 changes: 1 addition & 1 deletion src/common/decorators/validation/is-equal-to.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class IsEqualToConstraint implements ValidatorConstraintInterface {
}
}

export const IsEqualTo = (
export const IsEqualToField = (
property: string,
validationOptions?: ValidationOptions,
): PropertyDecorator => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {Validator} from 'class-validator';
import {IsPassword} from './is-password.validator';
import { Validator } from 'class-validator';
import { IsPasswordField } from './is-password.validator';

const validator = new Validator();

describe('IsPassword', () => {
class MyClass {
@IsPassword()
@IsPasswordField()
password: string;
}

Expand Down
18 changes: 18 additions & 0 deletions src/common/decorators/validation/is-password.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import type {
ValidatorConstraintInterface,
} from "class-validator";
import {
IsNotEmpty,
ValidatorConstraint,
registerDecorator,
} from "class-validator";
import { applyDecorators } from "@nestjs/common";
import { MinMaxLength } from "./min-max-length.decorator";
import { PASSWORD_REGEX } from "@common/constant";
import { validationI18nMessage } from "@lib/i18n";

/**
*
Expand Down Expand Up @@ -43,3 +47,17 @@ export const IsPassword = (validationOptions?: ValidationOptions): PropertyDecor
});
};
};


export const IsPasswordField = (validationOptions?: ValidationOptions & { minLength?: number; maxLength?: number }) => {
return applyDecorators(
IsNotEmpty({
message: validationI18nMessage("validation.isNotEmpty"),
}),
MinMaxLength({
minLength: validationOptions.minLength ?? 8,
maxLength: validationOptions.maxLength ?? 40,
}),
IsPassword(validationOptions),
);
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {Validator} from 'class-validator';
import {IsUsername} from './is-username.validator';
import {IsUsernameField} from './is-username.validator';

const validator = new Validator();

describe('IsUserName', () => {
class MyClass {
@IsUsername()
@IsUsernameField()
username: string;
}

Expand Down
6 changes: 3 additions & 3 deletions src/common/decorators/validation/is-username.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ export const IsUsername = (validationOptions?: ValidationOptions): PropertyDecor
};
};

export const IsUsernameField = (validationOptions?: ValidationOptions) => {
export const IsUsernameField = (validationOptions?: ValidationOptions & { minLength?: number; maxLength?: number } ) => {
return applyDecorators(
IsNotEmpty({
message: validationI18nMessage("validation.isNotEmpty"),
}),
MinMaxLength({
minLength: 5,
maxLength: 20,
minLength: validationOptions.minLength ?? 5,
maxLength: validationOptions.maxLength ?? 50,
}),
IsUsername(validationOptions),
);
Expand Down
4 changes: 2 additions & 2 deletions src/common/decorators/validation/is-uuid.validator.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { applyDecorators } from "@nestjs/common";
import { ArrayNotEmpty, IsArray, IsNotEmpty, IsOptional, IsUUID } from "class-validator";
import type { EnumFieldOptions as UUIDFieldOptions } from "@common/@types";
import type { UUIDFieldOptions } from "@common/@types";
import { validationI18nMessage } from "@lib/i18n";

/**
* It's a decorator that validates that the field is an uuid value
* It's a decorator that validates that the field is an uuid value (v4) or an array of uuid values (v4)
* @param options_ - UUIDFieldOptions
* @returns A decorator function that takes in a target, propertyKey, and descriptor.
*/
Expand Down
9 changes: 4 additions & 5 deletions src/modules/auth/dtos/reset-password.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PickType } from "@nestjs/swagger";
import { IsNotEmpty } from "class-validator";
import { IsEqualTo, IsPassword, IsStringField } from "@common/decorators";
import { IsEqualToField, IsPasswordField, IsStringField } from "@common/decorators";
import { validationI18nMessage } from "@lib/i18n";

export class ResetPasswordDto {
Expand All @@ -18,8 +18,7 @@ export class ResetPasswordDto {
* New password of user
* @example SomeThingNew7^#%
*/
@IsStringField({ minLength: 8, maxLength: 50 })
@IsPassword({ message: validationI18nMessage("validation.isPassword") })
@IsPasswordField({ message: validationI18nMessage("validation.isPassword") })
password!: string;

/**
Expand All @@ -28,7 +27,7 @@ export class ResetPasswordDto {
*/

@IsNotEmpty({ message: validationI18nMessage("validation.isNotEmpty") })
@IsEqualTo("password")
@IsEqualToField("password")
confirmPassword!: string;
}

Expand All @@ -40,6 +39,6 @@ export class ChangePasswordDto extends PickType(ResetPasswordDto, [
* Password of user
* @example SomeThingNew7^#%
*/
@IsNotEmpty({ message: validationI18nMessage("validation.isNotEmpty") })
@IsPasswordField({ message: validationI18nMessage("validation.isPassword") })
oldPassword!: string;
}
5 changes: 2 additions & 3 deletions src/modules/user/dtos/create-user.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Roles } from "@common/@types";
import {
IsEmailField,
IsEnumField,
IsPassword,
IsPasswordField,
IsStringField,
IsUnique,
IsUsernameField,
Expand Down Expand Up @@ -85,8 +85,7 @@ export class CreateUserDto {
* @example SomePassword@123
*/

@IsStringField({ minLength: 8, maxLength: 50 })
@IsPassword({ message: validationI18nMessage("validation.isPassword") })
@IsPasswordField({ message: validationI18nMessage("validation.isPassword") })
password!: string;

/**
Expand Down

0 comments on commit 17cfae1

Please sign in to comment.