A Savory class validator for Deno.

Made for Deno CI codecov

Available decorators

Decorator Description
Type validation decorators
IsBoolean() Checks if a value is a boolean.
IsString() Checks if the string is a string.
IsNumber() Checks if the value is a number.
IsBigInt() Checks if the value is a big int.
IsArray() Checks if the value is an array
IsObject() Checks if the value is an object
IsSymbol() Checks if the value is a Symbol
IsUndefined() Checks if the value is undefined
Contains(seed [, options]) Check if the string contains the seed.

options is an object which defaults to { ignoreCase: false }.
IsAfter(date? string) Check if the string is a date that’s after the specified date (defaults to now).
IsAlpha(locale?: string) Check if the string contains only alphabets depending on the locale.

Locale is one of ['ar', 'ar-AE', 'ar-BH', 'ar-DZ', 'ar-EG', 'ar-IQ', 'ar-JO', 'ar-KW', 'ar-LB', 'ar-LY', 'ar-MA', 'ar-QA', 'ar-QM', 'ar-SA', 'ar-SD', 'ar-SY', 'ar-TN', 'ar-YE', 'bg-BG', 'cs-CZ', 'da-DK', 'de-DE', 'el-GR', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-ZA', 'en-ZM', 'es-ES', 'fa-IR', 'fr-FR', 'he', 'hu-HU', 'it-IT', 'ku-IQ', 'nb-NO', 'nl-NL', 'nn-NO', 'pl-PL', 'pl-Pl', 'pt-BR', 'pt-PT', 'ru-RU', 'sk-SK', 'sl-SI', 'sr-RS', 'sr-RSlatin', 'sv-SE', 'tr-TR', 'uk-UA'] and defaults to en-US.
IsAlphanumeric(locale?: string) Check if the string contains only alphabets and digits depending on the locale.

Locale is one of ['ar', 'ar-AE', 'ar-BH', 'ar-DZ', 'ar-EG', 'ar-IQ', 'ar-JO', 'ar-KW', 'ar-LB', 'ar-LY', 'ar-MA', 'ar-QA', 'ar-QM', 'ar-SA', 'ar-SD', 'ar-SY', 'ar-TN', 'ar-YE', 'bg-BG', 'cs-CZ', 'da-DK', 'de-DE', 'el-GR', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-ZA', 'en-ZM', 'es-ES', 'fa-IR', 'fr-FR', 'he', 'hu-HU', 'it-IT', 'ku-IQ', 'nb-NO', 'nl-NL', 'nn-NO', 'pl-PL', 'pl-Pl', 'pt-BR', 'pt-PT', 'ru-RU', 'sk-SK', 'sl-SI', 'sr-RS', 'sr-RSlatin', 'sv-SE', 'tr-TR', 'uk-UA'] and defaults to en-US.
IsAscii() Check if the string contains ASCII chars only.
IsBase32() Check if a string is base32 encoded.
IsBase64(options?: { urlSafe: boolean }) Check if a string is base64 encoded.

options is an object which defaults to { urlSafe: false }.
IsBefore(date?: string) Check if the string is a date that’s before the specified date (defaults to now).
IsBIC() Check if a string is a BIC (Bank Identification Code) or SWIFT code.
IsBoolean() Check if a string is a boolean.
IsBtcAddress() Check if the string is a valid BTC address.
ByteLength(options: { min: number, max: number? }) Check if the string’s length (in UTF-8 bytes) falls in a range.

options is an object which defaults to { min: 0, max: undefined }.
IsCreditCard() Check if the string is a valid Credit Card number.
IsCurrency(option) Check if the string is a valid currency amount.

options is an object which defaults to { symbol: '$', require_symbol: false, allow_space_after_symbol: false, symbol_after_digits: false, allow_negatives: true, parens_for_negatives: false, negative_sign_before_digits: false, negative_sign_after_digits: false, allow_negative_sign_placeholder: false, thousands_separator: ',', decimal_separator: '.', allow_decimal: true, require_decimal: false, digits_after_decimal: [2], allow_space_after_digits: false }.
Note: The array digits_after_decimal is filled with the exact number of digits allowed not a range, for example a range 1 to 3 will be given as [1, 2, 3].
isDataURI() Check if the string is in Data URI format.
isDate(format?: string) Check if the string is a valid date. Example [2002-07-15, new Date()].

format is a string that defaults to YYYY/MM/DD
IsDecimal(options? ) Check if the string represents a decimal number, such as 0.1, .3, 1.1, 1.00003, 4.0, etc.

options is an object which defaults to {force_decimal: false, decimal_digits: '1,', locale: 'en-US'}
locale determine the decimal separator and is one of ['ar', 'ar-AE', 'ar-BH', 'ar-DZ', 'ar-EG', 'ar-IQ', 'ar-JO', 'ar-KW', 'ar-LB', 'ar-LY', 'ar-MA', 'ar-QA', 'ar-QM', 'ar-SA', 'ar-SD', 'ar-SY', 'ar-TN', 'ar-YE', 'bg-BG', 'cs-CZ', 'da-DK', 'de-DE', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-ZA', 'en-ZM', 'es-ES', 'fr-FR', 'hu-HU', 'it-IT', 'ku-IQ', nb-NO', 'nl-NL', 'nn-NO', 'pl-PL', 'pt-BR', 'pt-PT', 'ru-RU', 'sl-SI', 'sr-RS', 'sr-RSlatin', 'sv-SE', 'tr-TR', 'uk-UA'].
Note: decimal_digits is given as a range like ‘1,3’, a specific value like ‘3’ or min like ‘1,’.
IsEmpty() Check if a string is empty.
IsHexColor() Check if the string represent a hex color.
IsIP() Check if the string is a valid ip address.
IsDivisibleBy(dividend: number) Check if the property is divisible by the given number.
IsPort() Check if the string is a valid port number (between 0 and 65535).
Number validation decorators
GreaterOrEqual(num: number) Checks if the value is greater than or equal to the specified number.
Greater(num: number) Checks if the value is greater than the specified number.
LowerOrEqual(num: number) Checks if the value is lower than or equal to the specified number.
Lower(num: number) Checks if the value is lower than the specified number.
String validation decorators
LengthGreaterOrEqual(num: number) Checks if the length is greater than or equal to the specified number.
LengthGreater(num: number) Checks if the length is greater than the specified number.
LengthLowerOrEqual(num: number) Checks if the length is lower than or equal to the specified number.
LengthLower(num: number) Checks if the length is lower than the specified number.
IsRegex(regex: RegExp) Checks if the string match the given RegExp.
IsEmail() Checks if the string is an email.
IsPhoneNumber(country: string) Checks if the string is a local phone number for a country. Country must be ISO 3166 c.a.d 2 letter code. Example: FR, US, UK, DE
IsInternationalPhoneNumber() Checks if the string is an international phone number with extension and with or without leading 0. Example: +330XXXXXXXXX or +33XXXXXXXXX
IsLowerCase() Checks if the string is in lower case.
IsUpperCase() Checks if the string is in uppercase.
Object validation decorators
Nested(class: Class) Checks if the property is a valid “instance” of Class. This means that all Validators of Class will be checked on the given object. The property can either be a plain object or a class instance

Usage

Create a Class using TypeScript Decorators and run validateObject.

If you need more built-in validators, please open an issue or create merge request

import {
    createValidator,
    IsEmail, // this is a decorator (PascalCase)
    isEmail, // this is a check function, called behavior (camelCase)
    IsString,
    LengthLowerOrEqual,
    validateObject,
} from 'https://deno.land/x/validatte/mod.ts';

// Custom validator with custom error message containing argument. <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi><mi>o</mi><mi>n</mi><mi>s</mi><mi>t</mi><mi>r</mi><mi>a</mi><mi>i</mi><mi>n</mi><mi>t</mi><mn>1</mn><mi>w</mi><mi>i</mi><mi>l</mi><mi>l</mi><mi>b</mi><mi>e</mi><mi>r</mi><mi>e</mi><mi>p</mi><mi>l</mi><mi>a</mi><mi>c</mi><mi>e</mi><mi>d</mi><mi>b</mi><mi>y</mi><mi>f</mi><mi>i</mi><mi>r</mi><mi>s</mi><mi>t</mi><mi>a</mi><mi>r</mi><mi>g</mi><mi>u</mi><mi>m</mi><mi>e</mi><mi>n</mi><mi>t</mi><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">constraint1 will be replaced by first argument. </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">co</span><span class="mord mathnormal">n</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">ain</span><span class="mord mathnormal">t</span><span class="mord">1</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">ll</span><span class="mord mathnormal">b</span><span class="mord mathnormal">ere</span><span class="mord mathnormal" style="margin-right:0.01968em;">pl</span><span class="mord mathnormal">a</span><span class="mord mathnormal">ce</span><span class="mord mathnormal">d</span><span class="mord mathnormal">b</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal">rs</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">gu</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord">.</span></span></span></span>constraint2 by second etc...
const IsWhiteListedEmailDomain = createValidator(
    (whiteListedDomain: string) => {
        return (prop) => {
            if (isEmail(prop)) {
                return false;
            }
            return prop.indexOf(`@${whiteListedDomain}`) !== -1;
        };
    },
    'Email shoud be from $constraint1 domain',
);

class User {
    @IsString()
    @IsEmail()
    @IsWhiteListedEmailDomain('mydomain.com')
    email!: string;
}

// ---------- //

// Valid
const user = new User();
user.email = 'myemailmydomain.com';
console.log(validateObject(user, User));
// []

// ---------- //

// Invalid
const failingUser = new User();
failingUser.email = 'wrongemail@email.com';
console.log(validateObject(failingUser, User));

/*
[
    {
        property: 'email',
        errorMessage: `Email shoud be from mydomain.com domain`,
        constraints: ['mydomain.com'],
    },
];
*/

Come with us on this awesome journey

We always welcome contributors, feel free to submit a new feature or report a bug on our Github Repository and join our discord

License

MIT