diff --git a/src/bounties/dto/create-bounty.dto.ts b/src/bounties/dto/create-bounty.dto.ts index 24d5276..a0b5f4d 100644 --- a/src/bounties/dto/create-bounty.dto.ts +++ b/src/bounties/dto/create-bounty.dto.ts @@ -5,6 +5,7 @@ import { IsMoneyAmount, IsSupportedEscrowAsset, } from '../../common/validators/money.validator'; +import { IsFutureDate } from '../../common/validators/date.validator'; export class CreateBountyDto { @ApiProperty({ @@ -35,5 +36,6 @@ export class CreateBountyDto { @ApiProperty({ required: false }) @IsOptional() @IsISO8601() + @IsFutureDate() deadline?: string; } diff --git a/src/common/validators/date.validator.ts b/src/common/validators/date.validator.ts new file mode 100644 index 0000000..2645069 --- /dev/null +++ b/src/common/validators/date.validator.ts @@ -0,0 +1,33 @@ +import { + registerDecorator, + ValidationOptions, + ValidatorConstraint, + ValidatorConstraintInterface, + ValidationArguments, +} from 'class-validator'; + +@ValidatorConstraint({ name: 'isFutureDate', async: false }) +export class IsFutureDateConstraint implements ValidatorConstraintInterface { + validate(propertyValue: string, args: ValidationArguments) { + if (!propertyValue) return true; + const date = new Date(propertyValue); + if (isNaN(date.getTime())) return false; + return date.getTime() > Date.now(); + } + + defaultMessage(args: ValidationArguments) { + return 'Deadline must be in the future'; + } +} + +export function IsFutureDate(validationOptions?: ValidationOptions) { + return function (object: Object, propertyName: string) { + registerDecorator({ + target: object.constructor, + propertyName: propertyName, + options: validationOptions, + constraints: [], + validator: IsFutureDateConstraint, + }); + }; +}