Skip to content

Commit

Permalink
create new decorator with isenum and metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
portuu3 committed Oct 10, 2024
1 parent 6e40a02 commit 15e347c
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,23 @@ import {
BadRequestException,
} from '@nestjs/common';
import { of } from 'rxjs';
import { IsEnum, IsNumber, IsString, Min } from 'class-validator';
import { IsNumber, IsString, Min } from 'class-validator';
import { JobStatus } from '../../common/enums/job';
import { UserType } from '../../common/enums/user';
import { ApiProperty } from '@nestjs/swagger';
import { EnumMetadata } from '../utils/enums';
import { IsEnumWithMetadata } from '../utils/enums';

export class MockDto {
@ApiProperty({
enum: JobStatus,
})
@IsEnum(JobStatus)
@EnumMetadata(JobStatus)
@IsEnumWithMetadata(JobStatus)
public status: JobStatus;

@ApiProperty({
enum: UserType,
})
@IsEnum(UserType)
@EnumMetadata(UserType)
@IsEnumWithMetadata(UserType)
public userType: UserType;

@ApiProperty()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
IsEnum,
IsNumber,
IsOptional,
Max,
Min,
IsArray,
} from 'class-validator';
import { IsNumber, IsOptional, Max, Min, IsArray } from 'class-validator';
import { Type } from 'class-transformer';
import { SortDirection } from '../enums/collection';
import { IsEnumWithMetadata } from '../utils/enums';

export class PageDto<T> {
@ApiProperty()
Expand Down Expand Up @@ -67,7 +61,7 @@ export abstract class PageOptionsDto {
pageSize?: number = 5;

@ApiPropertyOptional({ enum: SortDirection, default: SortDirection.ASC })
@IsEnum(SortDirection)
@IsEnumWithMetadata(SortDirection)
@IsOptional()
sort?: SortDirection = SortDirection.ASC;

Expand Down
51 changes: 48 additions & 3 deletions packages/apps/job-launcher/server/src/common/utils/enums.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,52 @@
import {
registerDecorator,
ValidationOptions,
ValidationArguments,
} from 'class-validator';
import 'reflect-metadata';

export function EnumMetadata(enumType: any) {
return function (target: any, propertyKey: string) {
Reflect.defineMetadata('custom:enum', enumType, target, propertyKey);
export function IsEnumWithMetadata(
enumType: any,
validationOptions?: ValidationOptions,
) {
// eslint-disable-next-line @typescript-eslint/ban-types
return function (object: Object, propertyName: string) {
// Attach enum metadata to the property
Reflect.defineMetadata('custom:enum', enumType, object, propertyName);

// Register the validation logic using class-validator
registerDecorator({
name: 'isEnumWithMetadata',
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
validator: {
validate(value: any, args: ValidationArguments) {
// Retrieve enum type from metadata
const enumType = Reflect.getMetadata(
'custom:enum',
args.object,
args.property,
);
if (!enumType) {
return false; // If no enum metadata is found, validation fails
}

// Validate value is part of the enum
const enumValues = Object.values(enumType);
return enumValues.includes(value);
},
defaultMessage(args: ValidationArguments) {
// Default message if validation fails
const enumType = Reflect.getMetadata(
'custom:enum',
args.object,
args.property,
);
const enumValues = Object.values(enumType).join(', ');
return `${args.property} must be a valid enum value. Valid values: [${enumValues}]`;
},
},
});
};
}
40 changes: 20 additions & 20 deletions packages/apps/job-launcher/server/src/modules/job/job.dto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
IsArray,
IsEnum,
IsNumber,
IsPositive,
IsString,
Expand Down Expand Up @@ -37,10 +36,11 @@ import {
import { Transform } from 'class-transformer';
import { AWSRegions, StorageProviders } from '../../common/enums/storage';
import { PageOptionsDto } from '../../common/pagination/pagination.dto';
import { IsEnumWithMetadata } from '../../common/utils/enums';

export class JobDto {
@ApiProperty({ enum: ChainId, required: false, name: 'chain_id' })
@IsEnum(ChainId)
@IsEnumWithMetadata(ChainId)
@IsOptional()
public chainId?: ChainId;

Expand Down Expand Up @@ -80,7 +80,7 @@ export class JobQuickLaunchDto extends JobDto {
name: 'request_type',
enum: JobRequestType,
})
@IsEnum(JobRequestType)
@IsEnumWithMetadata(JobRequestType)
public requestType: JobRequestType;

@ApiProperty({ name: 'manifest_url' })
Expand Down Expand Up @@ -119,17 +119,17 @@ export class JobFortuneDto extends JobDto {
public fundAmount: number;

@ApiProperty({ enum: JobCurrency })
@IsEnum(JobCurrency)
@IsEnumWithMetadata(JobCurrency)
public currency: JobCurrency;
}

export class StorageDataDto {
@ApiProperty({ enum: StorageProviders })
@IsEnum(StorageProviders)
@IsEnumWithMetadata(StorageProviders)
public provider: StorageProviders;

@ApiProperty({ enum: AWSRegions })
@IsEnum(AWSRegions)
@IsEnumWithMetadata(AWSRegions)
public region: AWSRegions | null;

@ApiProperty({ name: 'bucket_name' })
Expand Down Expand Up @@ -202,7 +202,7 @@ export class JobCvatDto extends JobDto {
public userGuide: string;

@ApiProperty({ enum: JobRequestType })
@IsEnum(JobRequestType)
@IsEnumWithMetadata(JobRequestType)
public type: JobRequestType;

@ApiProperty({ name: 'fund_amount' })
Expand All @@ -211,7 +211,7 @@ export class JobCvatDto extends JobDto {
public fundAmount: number;

@ApiProperty({ enum: JobCurrency })
@IsEnum(JobCurrency)
@IsEnumWithMetadata(JobCurrency)
public currency: JobCurrency;
}

Expand Down Expand Up @@ -285,7 +285,7 @@ export class ManifestDetails {
public requesterAddress: string;

@ApiProperty({ description: 'Request type', name: 'request_type' })
@IsEnum(JobRequestType)
@IsEnumWithMetadata(JobRequestType)
public requestType: JobRequestType;

@ApiProperty({
Expand Down Expand Up @@ -359,7 +359,7 @@ export class CommonDetails {
public amountOfTasks?: number;

@ApiProperty({ description: 'Status of the job' })
@IsEnum(JobStatus)
@IsEnumWithMetadata(JobStatus)
public status: JobStatus;

@ApiProperty({
Expand Down Expand Up @@ -404,7 +404,7 @@ export class FortuneManifestDto {
public fundAmount: number;

@ApiProperty({ enum: JobRequestType, name: 'request_type' })
@IsEnum(JobRequestType)
@IsEnumWithMetadata(JobRequestType)
public requestType: JobRequestType;

@IsArray()
Expand Down Expand Up @@ -435,7 +435,7 @@ export class Annotation {
@IsString()
public user_guide: string;

@IsEnum(JobRequestType)
@IsEnumWithMetadata(JobRequestType)
public type: JobRequestType;

@IsNumber()
Expand Down Expand Up @@ -514,7 +514,7 @@ export class GetJobsDto extends PageOptionsDto {
default: JobSortField.CREATED_AT,
})
@IsOptional()
@IsEnum(JobSortField)
@IsEnumWithMetadata(JobSortField)
sortField?: JobSortField = JobSortField.CREATED_AT;

@ApiPropertyOptional({
Expand All @@ -537,7 +537,7 @@ export class GetJobsDto extends PageOptionsDto {
chainId?: ChainId[];

@ApiPropertyOptional({ enum: JobStatusFilter })
@IsEnum(JobStatusFilter)
@IsEnumWithMetadata(JobStatusFilter)
@IsOptional()
status?: JobStatusFilter;
}
Expand All @@ -555,23 +555,23 @@ export class JobCaptchaAdvancedDto {
enum: WorkerLanguage,
name: 'worker_language',
})
@IsEnum(WorkerLanguage)
@IsEnumWithMetadata(WorkerLanguage)
@IsOptional()
workerLanguage?: WorkerLanguage;

@ApiProperty({
enum: WorkerLocation,
name: 'workerocation',
})
@IsEnum(WorkerLocation)
@IsEnumWithMetadata(WorkerLocation)
@IsOptional()
workerLocation?: WorkerLocation;

@ApiProperty({
enum: WorkerBrowser,
name: 'target_browser',
})
@IsEnum(WorkerBrowser)
@IsEnumWithMetadata(WorkerBrowser)
@IsOptional()
targetBrowser?: WorkerBrowser;
}
Expand All @@ -581,7 +581,7 @@ export class JobCaptchaAnnotationsDto {
enum: JobCaptchaShapeType,
name: 'type_of_job',
})
@IsEnum(JobCaptchaShapeType)
@IsEnumWithMetadata(JobCaptchaShapeType)
typeOfJob: JobCaptchaShapeType;

@ApiProperty({ name: 'task_bid_price' })
Expand Down Expand Up @@ -675,7 +675,7 @@ class RequesterRestrictedAnswer {
}

class RequestConfig {
@IsEnum(JobCaptchaShapeType)
@IsEnumWithMetadata(JobCaptchaShapeType)
shape_type?: JobCaptchaShapeType;

@IsNumber()
Expand Down Expand Up @@ -724,7 +724,7 @@ export class HCaptchaManifestDto {
@IsString()
job_mode: string;

@IsEnum(JobCaptchaRequestType)
@IsEnumWithMetadata(JobCaptchaRequestType)
request_type: JobCaptchaRequestType;

@IsObject()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsNumber, IsString, Min } from 'class-validator';
import { IsNumber, IsString, Min } from 'class-validator';
import { Currency } from '../../common/enums/payment';
import { ChainId } from '@human-protocol/sdk';
import { IsEnumWithMetadata } from '../../common/utils/enums';

export class PaymentFiatConfirmDto {
@ApiProperty({ name: 'payment_id' })
Expand All @@ -18,7 +19,7 @@ export class PaymentFiatCreateDto {
@ApiProperty({
enum: Currency,
})
@IsEnum(Currency)
@IsEnumWithMetadata(Currency)
public currency: Currency;
}

Expand All @@ -27,7 +28,7 @@ export class PaymentCryptoCreateDto {
enum: ChainId,
name: 'chain_id',
})
@IsEnum(ChainId)
@IsEnumWithMetadata(ChainId)
public chainId: ChainId;

@ApiProperty({ name: 'transaction_hash' })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsEmail, IsEnum, IsOptional, IsString } from 'class-validator';
import { IsEmail, IsOptional, IsString } from 'class-validator';
import { Transform } from 'class-transformer';
import { UserStatus, UserType } from '../../common/enums/user';
import { ValidatePasswordDto } from '../auth/auth.dto';
import { Currency } from '../../common/enums/payment';
import { IsEnumWithMetadata } from '../../common/utils/enums';

export class UserCreateDto extends ValidatePasswordDto {
@ApiProperty()
Expand Down Expand Up @@ -31,7 +32,7 @@ export class UserUpdateDto {
@ApiPropertyOptional({
enum: UserStatus,
})
@IsEnum(UserStatus)
@IsEnumWithMetadata(UserStatus)
public status?: UserStatus;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { ChainId } from '@human-protocol/sdk';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
IsEnum,
IsObject,
IsString,
IsBoolean,
IsOptional,
IsEthereumAddress,
} from 'class-validator';
import { EventType, OracleType } from '../../common/enums/webhook';

import { IsEnumWithMetadata } from '../../common/utils/enums';
export class FailedEventData {
@ApiProperty()
@IsString()
Expand All @@ -21,19 +20,19 @@ export type EventData = FailedEventData;

export class WebhookDto {
@ApiProperty()
@IsEnum(ChainId)
@IsEnumWithMetadata(ChainId)
public chainId: ChainId;

@ApiProperty()
@IsEnum(EventType)
@IsEnumWithMetadata(EventType)
public eventType: EventType;

@ApiProperty()
@IsString()
public escrowAddress: string;

@ApiProperty()
@IsEnum(OracleType)
@IsEnumWithMetadata(OracleType)
public oracleType: OracleType;

@ApiProperty()
Expand All @@ -43,7 +42,7 @@ export class WebhookDto {

export class WebhookDataDto {
@ApiProperty({ enum: ChainId, name: 'chain_id' })
@IsEnum(ChainId)
@IsEnumWithMetadata(ChainId)
public chainId: ChainId;

@ApiProperty({ name: 'escrow_address' })
Expand All @@ -52,7 +51,7 @@ export class WebhookDataDto {
public escrowAddress: string;

@ApiProperty({ enum: EventType, name: 'event_type' })
@IsEnum(EventType)
@IsEnumWithMetadata(EventType)
public eventType: EventType;

@ApiPropertyOptional({ name: 'event_data' })
Expand Down

0 comments on commit 15e347c

Please sign in to comment.