From ca676b33e8fb4c3addcd4cac02262abcbab52510 Mon Sep 17 00:00:00 2001 From: Ales Albert KILBERGR Date: Tue, 16 Jul 2024 12:19:21 +0200 Subject: [PATCH 1/3] feat: IsBigInt decorator --- src/decorator/decorators.ts | 1 + src/decorator/typechecker/IsBigInt.ts | 27 +++++++++++++++ ...alidation-functions-and-decorators.spec.ts | 34 +++++++++++++++++++ tsconfig.json | 4 +-- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/decorator/typechecker/IsBigInt.ts diff --git a/src/decorator/decorators.ts b/src/decorator/decorators.ts index d449e9301a..1ce4c1a4c9 100644 --- a/src/decorator/decorators.ts +++ b/src/decorator/decorators.ts @@ -121,6 +121,7 @@ export * from './string/is-iso4217-currency-code'; // Type checkers // ------------------------------------------------------------------------- +export * from './typechecker/IsBigInt'; export * from './typechecker/IsBoolean'; export * from './typechecker/IsDate'; export * from './typechecker/IsNumber'; diff --git a/src/decorator/typechecker/IsBigInt.ts b/src/decorator/typechecker/IsBigInt.ts new file mode 100644 index 0000000000..6742a00f14 --- /dev/null +++ b/src/decorator/typechecker/IsBigInt.ts @@ -0,0 +1,27 @@ +import { ValidationOptions } from '../ValidationOptions'; +import { buildMessage, ValidateBy } from '../common/ValidateBy'; + +export const IS_BIGINT = 'isBigInt'; + +/** + * Checks if the value is a bigint + */ +export function isBigInt(val: unknown): val is bigint { + return typeof val === 'bigint'; +} + +/** + * Checks if the value is a bigint + */ +export function IsBigInt(validationOptions?: ValidationOptions): PropertyDecorator { + return ValidateBy( + { + name: IS_BIGINT, + validator: { + validate: (value, args): boolean => isBigInt(value), + defaultMessage: buildMessage(eachPrefix => eachPrefix + '$property must be a bigint number', validationOptions), + }, + }, + validationOptions + ); +} diff --git a/test/functional/validation-functions-and-decorators.spec.ts b/test/functional/validation-functions-and-decorators.spec.ts index 78ceddcd6d..2f4eaa147c 100644 --- a/test/functional/validation-functions-and-decorators.spec.ts +++ b/test/functional/validation-functions-and-decorators.spec.ts @@ -67,6 +67,7 @@ import { ArrayNotContains, ArrayUnique, IsArray, + IsBigInt, IsDateString, IsInstance, IsPhoneNumber, @@ -79,6 +80,7 @@ import { isDefined, isNumber, isURL, + isBigInt, isBoolean, isString, isInt, @@ -757,6 +759,38 @@ describe('IsInt', () => { }); }); +describe('IsBigInt', () => { + const validValues = [2n, 4n, 100n, 1000n]; + const invalidValues = ['01', '-01', '000', '100e10', '123.123', ' ', '', 10, 2.5, -0.1]; + + class MyClass { + @IsBigInt() + someProperty: string; + } + + it('should not fail if validator.validate said that its valid', () => { + return checkValidValues(new MyClass(), validValues); + }); + + it('should fail if validator.validate said that its invalid', () => { + return checkInvalidValues(new MyClass(), invalidValues); + }); + + it('should not fail if method in validator said that its valid', () => { + validValues.forEach(value => expect(isBigInt(value)).toBeTruthy()); + }); + + it('should fail if method in validator said that its invalid', () => { + invalidValues.forEach(value => expect(isBigInt(value as any)).toBeFalsy()); + }); + + it('should return error object with proper data', () => { + const validationType = 'isBigInt'; + const message = 'someProperty must be a bigint number'; + return checkReturnedError(new MyClass(), invalidValues, validationType, message); + }); +}); + describe('IsString', () => { const validValues = ['true', 'false', 'hello', '0', '', '1']; const invalidValues = [true, false, 1, 2, null, undefined]; diff --git a/tsconfig.json b/tsconfig.json index c9f3bd3b42..9e61b3c433 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,8 +2,8 @@ "compilerOptions": { "module": "commonjs", "moduleResolution": "node", - "target": "es2018", - "lib": ["es2018"], + "target": "es2020", + "lib": ["es2020"], "outDir": "build/node", "rootDir": "./src", "strict": true, From 8055612b4bac1f2603707ed5905afde2ceb1f32f Mon Sep 17 00:00:00 2001 From: Ales Albert KILBERGR Date: Tue, 16 Jul 2024 12:25:25 +0200 Subject: [PATCH 2/3] fix: avoid build target bump to es2020 --- test/functional/validation-functions-and-decorators.spec.ts | 4 +++- tsconfig.json | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/functional/validation-functions-and-decorators.spec.ts b/test/functional/validation-functions-and-decorators.spec.ts index 2f4eaa147c..9d29b08b2c 100644 --- a/test/functional/validation-functions-and-decorators.spec.ts +++ b/test/functional/validation-functions-and-decorators.spec.ts @@ -760,7 +760,9 @@ describe('IsInt', () => { }); describe('IsBigInt', () => { - const validValues = [2n, 4n, 100n, 1000n]; + // By casting bigints via function instead of `2n` annotation we can avoid + // to bump the typescript build target from es2018 to es2020 + const validValues = [BigInt(2), BigInt(4), BigInt(100), BigInt(1000)]; const invalidValues = ['01', '-01', '000', '100e10', '123.123', ' ', '', 10, 2.5, -0.1]; class MyClass { diff --git a/tsconfig.json b/tsconfig.json index 9e61b3c433..c9f3bd3b42 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,8 +2,8 @@ "compilerOptions": { "module": "commonjs", "moduleResolution": "node", - "target": "es2020", - "lib": ["es2020"], + "target": "es2018", + "lib": ["es2018"], "outDir": "build/node", "rootDir": "./src", "strict": true, From 96c9a537bffd01a704f9896345d264032d743781 Mon Sep 17 00:00:00 2001 From: Ales Albert KILBERGR Date: Tue, 16 Jul 2024 12:29:48 +0200 Subject: [PATCH 3/3] docs: update documentation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 886712dd76..5b1164fed1 100644 --- a/README.md +++ b/README.md @@ -811,6 +811,7 @@ isBoolean(value); | `@IsString()` | Checks if the value is a string. | | `@IsNumber(options: IsNumberOptions)` | Checks if the value is a number. | | `@IsInt()` | Checks if the value is an integer number. | +| `@IsBigInt()` | Checks if the value is a bigint number. | | `@IsArray()` | Checks if the value is an array | | `@IsEnum(entity: object)` | Checks if the value is a valid enum | | **Number validation decorators** |