diff --git a/README.md b/README.md index 3544056acf..68178013aa 100644 --- a/README.md +++ b/README.md @@ -831,6 +831,7 @@ validator.isHalfWidth(str); // Checks if the string contains any half-width char validator.isVariableWidth(str); // Checks if the string contains variable-width chars. validator.isHexColor(str); // Checks if the string is a hexadecimal color. validator.isHexadecimal(str); // Checks if the string is a hexadecimal number. +validator.isMACAddress(str); // Checks if the string is a MAC Address. validator.isIP(str, version); // Checks if the string is an IP (version 4 or 6). validator.isPort(str); // Check if the string is a valid port number. validator.isISBN(str, version); // Checks if the string is an ISBN (version 10 or 13). @@ -926,6 +927,7 @@ validator.isInstance(value, target); // Checks value is an instance of the targe | `@IsVariableWidth()` | Checks if the string contains a mixture of full and half-width chars. | | `@IsHexColor()` | Checks if the string is a hexadecimal color. | | `@IsHexadecimal()` | Checks if the string is a hexadecimal number. | +| `@IsMACAddress()` | Checks if the string is a MAC Address. | | `@IsIP(version?: "4"\|"6")` | Checks if the string is an IP (version 4 or 6). | | `@IsPort()` | Check if the string is a valid port number. | | `@IsISBN(version?: "10"\|"13")` | Checks if the string is an ISBN (version 10 or 13). | diff --git a/src/decorator/decorators.ts b/src/decorator/decorators.ts index 0adf1a13f2..793df42b0a 100644 --- a/src/decorator/decorators.ts +++ b/src/decorator/decorators.ts @@ -830,6 +830,21 @@ export function IsHexadecimal(validationOptions?: ValidationOptions) { }; } +/** + * Checks if the string is MAC Address. + */ +export function IsMACAddress(validationOptions?: ValidationOptions) { + return function (object: Object, propertyName: string) { + const args: ValidationMetadataArgs = { + type: ValidationTypes.IS_MAC_ADDRESS, + target: object.constructor, + propertyName: propertyName, + validationOptions: validationOptions + }; + getFromContainer(MetadataStorage).addValidationMetadata(new ValidationMetadata(args)); + }; +} + /** * Checks if the string is an IP (version 4 or 6). */ @@ -846,7 +861,6 @@ export function IsIP(version?: number, validationOptions?: ValidationOptions) { }; } - /** * Check if the string is a valid port number. */ diff --git a/src/validation/ValidationTypes.ts b/src/validation/ValidationTypes.ts index fee447d8be..97216fb9e3 100644 --- a/src/validation/ValidationTypes.ts +++ b/src/validation/ValidationTypes.ts @@ -67,6 +67,7 @@ export class ValidationTypes { static IS_VARIABLE_WIDTH = "isVariableWidth"; static IS_HEX_COLOR = "isHexColor"; static IS_HEXADECIMAL = "isHexadecimal"; + static IS_MAC_ADDRESS = "isMacAddress"; static IS_IP = "isIp"; static IS_PORT = "isPort"; static IS_ISBN = "isIsbn"; @@ -220,6 +221,8 @@ export class ValidationTypes { return eachPrefix + "$property must be a hexadecimal color"; case this.IS_HEXADECIMAL: return eachPrefix + "$property must be a hexadecimal number"; + case this.IS_MAC_ADDRESS: + return eachPrefix + "$property must be a MAC Address"; case this.IS_IP: return eachPrefix + "$property must be an ip address"; case this.IS_ISBN: diff --git a/src/validation/Validator.ts b/src/validation/Validator.ts index ba394ccec8..e575c3163e 100644 --- a/src/validation/Validator.ts +++ b/src/validation/Validator.ts @@ -218,6 +218,8 @@ export class Validator { return this.isHexColor(value); case ValidationTypes.IS_HEXADECIMAL: return this.isHexadecimal(value); + case ValidationTypes.IS_MAC_ADDRESS: + return this.isMACAddress(value); case ValidationTypes.IS_IP: return this.isIP(value, metadata.constraints[0]); case ValidationTypes.IS_PORT: @@ -663,6 +665,14 @@ export class Validator { return typeof value === "string" && this.validatorJs.isHexadecimal(value); } + /** + * Check if the string is a MAC address. + * If given value is not a string, then it returns false. + */ + isMACAddress(value: unknown): boolean { + return typeof value === "string" && this.validatorJs.isMACAddress(value); + } + /** * Checks if the string is an IP (version 4 or 6). * If given value is not a string, then it returns false. diff --git a/test/functional/validation-functions-and-decorators.spec.ts b/test/functional/validation-functions-and-decorators.spec.ts index e43034fff8..bae737748d 100644 --- a/test/functional/validation-functions-and-decorators.spec.ts +++ b/test/functional/validation-functions-and-decorators.spec.ts @@ -75,6 +75,7 @@ import { IsISO31661Alpha2, IsISO31661Alpha3, IsHash, + IsMACAddress, IsISSN, } from "../../src/decorator/decorators"; import {Validator} from "../../src/validation/Validator"; @@ -2025,6 +2026,55 @@ describe("IsHexadecimal", function() { }); +describe("IsMACAddress", function() { + + const validValues = [ + "ab:ab:ab:ab:ab:ab", + "FF:FF:FF:FF:FF:FF", + "01:02:03:04:05:ab", + "01:AB:03:04:05:06" + ]; + const invalidValues = [ + null, + undefined, + "abc", + "01:02:03:04:05", + "01:02:03:04::ab", + "1:2:3:4:5:6", + "AB:CD:EF:GH:01:02", + "A9C5 D4 9F EB D3", + "01-02 03:04 05 ab", + ]; + + class MyClass { + @IsMACAddress() + someProperty: string; + } + + it("should not fail if validator.validate said that its valid", function(done) { + checkValidValues(new MyClass(), validValues, done); + }); + + it("should fail if validator.validate said that its invalid", function(done) { + checkInvalidValues(new MyClass(), invalidValues, done); + }); + + it("should not fail if method in validator said that its valid", function() { + validValues.forEach(value => validator.isMACAddress(value).should.be.true); + }); + + it("should fail if method in validator said that its invalid", function() { + invalidValues.forEach(value => validator.isMACAddress(value).should.be.false); + }); + + it("should return error object with proper data", function(done) { + const validationType = "isMacAddress"; + const message = "someProperty must be a MAC Address"; + checkReturnedError(new MyClass(), invalidValues, validationType, message, done); + }); + +}); + describe("IsIP", function() { const validValues = [