diff --git a/packages/common/pipes/file/parse-file.pipe.ts b/packages/common/pipes/file/parse-file.pipe.ts index d2ea60e505b..6fa0b6b6bcd 100644 --- a/packages/common/pipes/file/parse-file.pipe.ts +++ b/packages/common/pipes/file/parse-file.pipe.ts @@ -17,7 +17,7 @@ import { ParseFileOptions } from './parse-file-options.interface'; * @publicApi */ @Injectable() -export class ParseFilePipe implements PipeTransform { +export class ParseFilePipe implements PipeTransform { protected exceptionFactory: (error: string) => any; private readonly validators: FileValidator[]; private readonly fileIsRequired: boolean; @@ -38,7 +38,7 @@ export class ParseFilePipe implements PipeTransform { this.fileIsRequired = fileIsRequired ?? true; } - async transform(value: any): Promise { + async transform(value: unknown): Promise { const areThereAnyFilesIn = this.thereAreNoFilesIn(value); if (areThereAnyFilesIn && this.fileIsRequired) { @@ -51,7 +51,7 @@ export class ParseFilePipe implements PipeTransform { return value; } - private async validateFilesOrFile(value: any): Promise { + private async validateFilesOrFile(value: unknown): Promise { if (Array.isArray(value)) { await Promise.all(value.map(f => this.validate(f))); } else { @@ -59,21 +59,21 @@ export class ParseFilePipe implements PipeTransform { } } - private thereAreNoFilesIn(value: any): boolean { + private thereAreNoFilesIn(value: unknown): boolean { const isEmptyArray = Array.isArray(value) && isEmpty(value); const isEmptyObject = isObject(value) && isEmpty(Object.keys(value)); return isUndefined(value) || isEmptyArray || isEmptyObject; } - protected async validate(file: any): Promise { + protected async validate(file: unknown): Promise { for (const validator of this.validators) { await this.validateOrThrow(file, validator); } return file; } - private async validateOrThrow(file: any, validator: FileValidator) { - const isValid = await validator.isValid(file); + private async validateOrThrow(file: unknown, validator: FileValidator) { + const isValid = await validator.isValid(file as any); if (!isValid) { const errorMessage = validator.buildErrorMessage(file); diff --git a/packages/common/pipes/parse-array.pipe.ts b/packages/common/pipes/parse-array.pipe.ts index 5bc5bd029a3..4d9103828ea 100644 --- a/packages/common/pipes/parse-array.pipe.ts +++ b/packages/common/pipes/parse-array.pipe.ts @@ -76,7 +76,7 @@ export class ParseArrayPipe implements PipeTransform { * @param value currently processed route argument * @param metadata contains metadata about the currently processed route argument */ - async transform(value: any, metadata: ArgumentMetadata): Promise { + async transform(value: unknown, metadata: ArgumentMetadata): Promise { if (!value && !this.options.optional) { throw this.exceptionFactory(VALIDATION_ERROR_MESSAGE); } else if (isNil(value) && this.options.optional) { @@ -147,7 +147,9 @@ export class ParseArrayPipe implements PipeTransform { } return targetArray; } else { - value = await Promise.all(value.map(toClassInstance)); + value = await Promise.all( + (value as Array).map(toClassInstance), + ); } } return value; diff --git a/packages/common/pipes/parse-bool.pipe.ts b/packages/common/pipes/parse-bool.pipe.ts index 177ee7cbeeb..5a1e8370bf8 100644 --- a/packages/common/pipes/parse-bool.pipe.ts +++ b/packages/common/pipes/parse-bool.pipe.ts @@ -41,10 +41,7 @@ export interface ParseBoolPipeOptions { * @publicApi */ @Injectable() -export class ParseBoolPipe implements PipeTransform< - string | boolean, - Promise -> { +export class ParseBoolPipe implements PipeTransform { protected exceptionFactory: (error: string) => any; constructor(@Optional() protected readonly options?: ParseBoolPipeOptions) { @@ -64,9 +61,9 @@ export class ParseBoolPipe implements PipeTransform< * @param metadata contains metadata about the currently processed route argument */ async transform( - value: string | boolean, + value: unknown, metadata: ArgumentMetadata, - ): Promise { + ): Promise { if (isNil(value) && this.options?.optional) { return value; } @@ -86,7 +83,7 @@ export class ParseBoolPipe implements PipeTransform< * @returns `true` if `value` is said 'true', ie., if it is equal to the boolean * `true` or the string `"true"` */ - protected isTrue(value: string | boolean): boolean { + protected isTrue(value: unknown): boolean { return value === true || value === 'true'; } @@ -95,7 +92,7 @@ export class ParseBoolPipe implements PipeTransform< * @returns `true` if `value` is said 'false', ie., if it is equal to the boolean * `false` or the string `"false"` */ - protected isFalse(value: string | boolean): boolean { + protected isFalse(value: unknown): boolean { return value === false || value === 'false'; } } diff --git a/packages/common/pipes/parse-date.pipe.ts b/packages/common/pipes/parse-date.pipe.ts index 22f3bf25c50..89314d89c7a 100644 --- a/packages/common/pipes/parse-date.pipe.ts +++ b/packages/common/pipes/parse-date.pipe.ts @@ -5,7 +5,7 @@ import { ErrorHttpStatusCode, HttpErrorByCode, } from '../utils/http-error-by-code.util'; -import { isNil } from '../utils/shared.utils'; +import { isNil, isNumber, isString } from '../utils/shared.utils'; export interface ParseDatePipeOptions { /** @@ -31,9 +31,7 @@ export interface ParseDatePipeOptions { } @Injectable() -export class ParseDatePipe implements PipeTransform< - string | number | undefined | null -> { +export class ParseDatePipe implements PipeTransform { protected exceptionFactory: (error: string) => any; constructor(private readonly options: ParseDatePipeOptions = {}) { @@ -52,9 +50,7 @@ export class ParseDatePipe implements PipeTransform< * @param value currently processed route argument * @param metadata contains metadata about the currently processed route argument */ - transform( - value: string | number | undefined | null, - ): Date | null | undefined { + transform(value: unknown): Date | null | undefined { if (this.options.optional && isNil(value)) { return this.options.default ? this.options.default() : value; } @@ -63,7 +59,10 @@ export class ParseDatePipe implements PipeTransform< throw this.exceptionFactory('Validation failed (no Date provided)'); } - const transformedValue = new Date(value); + const transformedValue = + isString(value) || isNumber(value) || value instanceof Date + ? new Date(value) + : new Date(NaN); if (isNaN(transformedValue.getTime())) { throw this.exceptionFactory('Validation failed (invalid date format)'); diff --git a/packages/common/pipes/parse-enum.pipe.ts b/packages/common/pipes/parse-enum.pipe.ts index 47f3c263abe..9699225d1b6 100644 --- a/packages/common/pipes/parse-enum.pipe.ts +++ b/packages/common/pipes/parse-enum.pipe.ts @@ -64,7 +64,10 @@ export class ParseEnumPipe implements PipeTransform { * @param value currently processed route argument * @param metadata contains metadata about the currently processed route argument */ - async transform(value: T, metadata: ArgumentMetadata): Promise { + async transform( + value: unknown, + metadata: ArgumentMetadata, + ): Promise { if (isNil(value) && this.options?.optional) { return value; } @@ -73,10 +76,10 @@ export class ParseEnumPipe implements PipeTransform { 'Validation failed (enum string is expected)', ); } - return value; + return value as T; } - protected isEnum(value: T): boolean { + protected isEnum(value: unknown): boolean { const enumValues = Object.keys(this.enumType as object).map( item => this.enumType[item], ); diff --git a/packages/common/pipes/parse-float.pipe.ts b/packages/common/pipes/parse-float.pipe.ts index 04f5e97e27e..70368bdaca6 100644 --- a/packages/common/pipes/parse-float.pipe.ts +++ b/packages/common/pipes/parse-float.pipe.ts @@ -37,7 +37,7 @@ export interface ParseFloatPipeOptions { * @publicApi */ @Injectable() -export class ParseFloatPipe implements PipeTransform { +export class ParseFloatPipe implements PipeTransform { protected exceptionFactory: (error: string) => any; constructor(@Optional() protected readonly options?: ParseFloatPipeOptions) { @@ -57,7 +57,10 @@ export class ParseFloatPipe implements PipeTransform { * @param value currently processed route argument * @param metadata contains metadata about the currently processed route argument */ - async transform(value: string, metadata: ArgumentMetadata): Promise { + async transform( + value: unknown, + metadata: ArgumentMetadata, + ): Promise { if (isNil(value) && this.options?.optional) { return value; } @@ -66,17 +69,17 @@ export class ParseFloatPipe implements PipeTransform { 'Validation failed (numeric string is expected)', ); } - return parseFloat(value); + return parseFloat(String(value)); } /** * @param value currently processed route argument * @returns `true` if `value` is a valid float number */ - protected isNumeric(value: string): boolean { + protected isNumeric(value: unknown): boolean { return ( ['string', 'number'].includes(typeof value) && - !isNaN(parseFloat(value)) && + !isNaN(parseFloat(String(value))) && isFinite(value as any) ); } diff --git a/packages/common/pipes/parse-int.pipe.ts b/packages/common/pipes/parse-int.pipe.ts index d74aa0205ab..8276348a32c 100644 --- a/packages/common/pipes/parse-int.pipe.ts +++ b/packages/common/pipes/parse-int.pipe.ts @@ -41,7 +41,7 @@ export interface ParseIntPipeOptions { * @publicApi */ @Injectable() -export class ParseIntPipe implements PipeTransform { +export class ParseIntPipe implements PipeTransform { protected exceptionFactory: (error: string) => any; constructor(@Optional() protected readonly options?: ParseIntPipeOptions) { @@ -61,7 +61,10 @@ export class ParseIntPipe implements PipeTransform { * @param value currently processed route argument * @param metadata contains metadata about the currently processed route argument */ - async transform(value: string, metadata: ArgumentMetadata): Promise { + async transform( + value: unknown, + metadata: ArgumentMetadata, + ): Promise { if (isNil(value) && this.options?.optional) { return value; } @@ -70,17 +73,17 @@ export class ParseIntPipe implements PipeTransform { 'Validation failed (numeric string is expected)', ); } - return parseInt(value, 10); + return parseInt(String(value), 10); } /** * @param value currently processed route argument * @returns `true` if `value` is a valid integer number */ - protected isNumeric(value: string): boolean { + protected isNumeric(value: unknown): boolean { return ( ['string', 'number'].includes(typeof value) && - /^-?\d+$/.test(value) && + /^-?\d+$/.test(String(value)) && isFinite(value as any) ); } diff --git a/packages/common/pipes/parse-uuid.pipe.ts b/packages/common/pipes/parse-uuid.pipe.ts index 1c67860b9cf..96f9e5799dd 100644 --- a/packages/common/pipes/parse-uuid.pipe.ts +++ b/packages/common/pipes/parse-uuid.pipe.ts @@ -45,7 +45,7 @@ export interface ParseUUIDPipeOptions { * @publicApi */ @Injectable() -export class ParseUUIDPipe implements PipeTransform { +export class ParseUUIDPipe implements PipeTransform { protected static uuidRegExps = { 3: /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i, 4: /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i, @@ -70,7 +70,10 @@ export class ParseUUIDPipe implements PipeTransform { (error => new HttpErrorByCode[errorHttpStatusCode](error)); } - async transform(value: string, metadata: ArgumentMetadata): Promise { + async transform( + value: unknown, + metadata: ArgumentMetadata, + ): Promise { if (isNil(value) && this.options?.optional) { return value; } @@ -81,7 +84,7 @@ export class ParseUUIDPipe implements PipeTransform { } is expected)`, ); } - return value; + return value as string; } protected isUUID(str: unknown, version = 'all') { diff --git a/packages/common/pipes/validation.pipe.ts b/packages/common/pipes/validation.pipe.ts index 0911231a248..05faf204e6b 100644 --- a/packages/common/pipes/validation.pipe.ts +++ b/packages/common/pipes/validation.pipe.ts @@ -44,7 +44,7 @@ let classTransformer: TransformerPackage = {} as any; * @publicApi */ @Injectable() -export class ValidationPipe implements PipeTransform { +export class ValidationPipe implements PipeTransform { protected isTransformEnabled: boolean; protected isDetailedOutputDisabled?: boolean; protected validatorOptions: ValidatorOptions; @@ -104,7 +104,7 @@ export class ValidationPipe implements PipeTransform { ); } - public async transform(value: any, metadata: ArgumentMetadata) { + public async transform(value: unknown, metadata: ArgumentMetadata) { if (this.expectedType) { metadata = { ...metadata, metatype: this.expectedType }; } @@ -191,7 +191,7 @@ export class ValidationPipe implements PipeTransform { return !types.some(t => metatype === t) && !isNil(metatype); } - protected transformPrimitive(value: any, metadata: ArgumentMetadata) { + protected transformPrimitive(value: unknown, metadata: ArgumentMetadata) { if (!metadata.data) { // leave top-level query/param objects unmodified return value; @@ -217,7 +217,7 @@ export class ValidationPipe implements PipeTransform { // they were not defined return undefined; } - return +value; + return +(value as any); } if (metatype === String && !isUndefined(value)) { return String(value); @@ -226,7 +226,7 @@ export class ValidationPipe implements PipeTransform { } protected toEmptyIfNil( - value: T, + value: unknown, metatype: Type | object, ): R | object | string { if (!isNil(value)) {