프로그래밍/NestJS
class-validator로 특정 날짜 검증하기
카카수(kakasoo)
2023. 1. 1. 12:02
반응형
@IsDate()
specificDate: Date;
날짜를 검증하기 위해서는 IsDate 데코레이터를 이용할 수 있다.
이렇게 작성할 경우 단순 String으로 된 Date는 무시당할 수 있기 때문에 Type 데코레이터도 필요하다.
날짜가 필수적인지 아닌지에 따라 아래와 같이 작성할 수 있다.
import { applyDecorators } from '@nestjs/common';
import { Type } from 'class-transformer';
import { IsDate, IsNotEmpty } from 'class-validator';
export function IsNotEmptyDate() {
return applyDecorators(
IsNotEmpty(),
IsDate(),
Type(() => Date),
);
}
import { applyDecorators } from '@nestjs/common';
import { Type } from 'class-transformer';
import { IsDate, IsOptional } from 'class-validator';
export function IsOptionalDate() {
return applyDecorators(
IsOptional(),
IsDate(),
Type(() => Date),
);
}
위는 필수적인 케이스고, 아래는 선택적인 케이스를 작성한 것이다.
이를 합쳐서 아래와 같이 인자를 받는 형태로 작성할 수 있다.
export function IsDateDecorator(isOptional: boolean = true) {
return applyDecorators(
isOptional ? IsOptional() : IsNotEmpty(),
IsDate(),
Type(() => Date),
);
}
하지만 날짜의 입력은, 서비스 특성에 따라 오늘 날짜를 포함한 시간대 이후를 받아야 할 수도 있다.
또한 시간 단위가 아니라 날짜 단위, 예컨대 23:59과 00:00를 1분 차이가 아니라 하루 차이로 볼 수도 있다.
이런 경우를 위해 아래와 같이 데코레이터를 만들 수 있다.
IsAfterDate decorator
import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';
export function getDifferTime(a: Date, b: Date, standard: 'day' | 'hour') {
if (standard === 'day') {
return a.getDate() - b.getDate();
} else if (standard === 'hour') {
const differTime = a.getTime() - b.getTime();
return differTime / (1000 * 60 * 60);
}
}
export function IsAfterDate(validationOptions?: { hours: number } & ValidationOptions) {
return function (object: Record<string, any>, propertyName: string) {
registerDecorator({
name: 'IsAfterDate',
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
constraints: [],
validator: {
validate(value: any, args: ValidationArguments) {
return value instanceof Date && getDifferTime(value, new Date(), 'hour') >= validationOptions.hours;
},
},
});
};
}
class-validator는 registerDecorator 를 통해 손쉽게 커스텀 데코레이터를 만들 수 있다.
위의 applyDecorator는 기존의 데코레이터를 합성하는 방식이지만,
registerDecorator는 기존에 없던 데코레이터를 만들 수 있기에 더 기능 확장에 용이하다.
반응형