0.0.12 • Published 1 year ago

chained-validation-rules v0.0.12

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

Chained validation rules

Facilitates the validation of strings by chaining series of rules.

Translations

Release Notes 0.0.12

  • Added predefined rule number Pattern.
  • The structure of the default messages has been changed.

Installation

npm i chained-validation-rules

Starting

My first validator

import { Validator } from 'chained-validation-rules';

// Instantiating a new validator
const validator = new Validator();

// First rule, it will only be approved if the string to evaluate contains some character, otherwise it will show the 
// message "The text is required"
validator.rule('The text is required', evaluate => {
  return !!evaluate;
});

// Second rule, it will only be approved if the string to be evaluated is equal to "xxx", otherwise it will show the
// message "The text is different from xxx"
validator.rule('The text is different from xxx', evaluate => {
  return evaluate === 'xxx';
})

The validator rule function allows you to create specific validation rules, associated with an error message in case that this validation is not fulfilled.

Note:
  • An indeterminate number of rules can be added.
  • Rules will be evaluated in the order in which they were added.
  • When a rule fails, the rest are ignored.
  • A string is considered valid only if it passes all the rules.

Simplifying code

You can create a Validator instance using the pattern builder with .ValidatorBuilder().

import { ValidatorBuilder } from 'chained-validation-rules';

const validator = new ValidatorBuilder()
  .rule('The text is required', evaluate => !!evaluate)
  .rule('The text is different from xxx', evaluate => evaluate === 'xxx')
  .build();

Predefined rules

Validator offers a series of predefined rules, trying to cover the most common validation cases.

RuleDescription
emailValidates that the string has an email format
textLengthValidates that the string has an exact length of characters
maxLengthValidates that the length of the string is not greater than the condition
minLengthValidates that the length of the string is not less than the condition
rangeLengthValidates that the length of the String is in the established range
reValidates that the string matches the regular expression
requiredValidates that the string is different from null, empty or undefined
linkValidates that the String is a link format
wwwLinkValidates that the String is a link with www format
httpLinkValidates that the String is a link with http format
httpsLinkValidates that the String is a link with https format
ipValidates that the String is an ip format
ipv4Validates that the String is an ipv4 format
ipv6Validates that the String is an ipv6 format
nameValidates that the String is a proper name
timeValidates that the String is a time format
time12Validates that the String is a time with 12-hour format
time24Validates that the String is a time with 24-hour format
onlyNumbersValidates that the String to evaluate only contains numeric characters
onlyLettersValidates that the String contains only letters
onlyAlphanumericValidates that the String contains only alphanumeric characters
notContainValidates that the String does not contain any character included in the condition
shouldOnlyContainValidates that the String only contains characters included in the condition
mustContainOneValidates that the String contains at least one character included in the condition
mustContainMinValidates that the String contains at least a minimum number of characters included in the condition
minValueValidates that the value of the String is not less than the condition
maxValueValidates that the value of the String is not greater than the condition
rangeValueValidates that the value of the String is in the established range
numberValidates that the String is a numeric format
numberPatternValidates that the String matches the pattern, replacing the x's with numbers

Predefined rules can simplify the definition of a Validator.

import { ValidatorBuilder } from 'chained-validation-rules';

const validator = new ValidatorBuilder()
        .required('Required')
        .minLength(6, 'At least 6 characters required')
        .build();

Default messages

The messages in the predefined rules are optional, so you can simplify the implementations as follows.

import { ValidatorBuilder } from 'chained-validation-rules';

const validator = new ValidatorBuilder()
        .required()
        .minLength(6)
        .build();

The default messages are found in the messagesEn objects for English messages, and in messagesEs for Spanish messages, both implement the Messages interface.

RuleEnglish (default)Spanish
isMathNot matchNo coinciden
emailEmail invalidCorreo electrónico inválido
textLengthIt requires %length charactersSe requiere %length caracteres
maxLength%max or less characters requiredSe requiere %max o menos caracteres
minLength%min or more characters are requiredSe requiere %min o más caracteres
rangeLengthThe text must contain between %min to %max charactersEl texto debe contener entre %min a %max caracteres
reThe value does not match the regular expression %regExpEl valor no coincide con la expresión regular %regExp
requiredRequiredRequerido
linkInvalid linkEnlace inválido
wwwLinkInvalid www linkEnlace www inválido
httpLinkInvalid http linkEnlace http inválido
httpsLinkInvalid https linkEnlace https inválido
ipInvalid IPIP inválida
ipv4Invalid IPv4IPv4 inválida
ipv6Invalid IPv6IPv6 inválida
nameInvalid personal nameNombre personal inválido
timeTime invalidHora inválida
time12Invalid 12 hour formatFormato 12 horas inválido
time24Invalid 12 hour formatFormato 12 horas inválido
onlyNumbersOnly numbersSolo números
onlyLettersOnly lettersSolo letras
onlyAlphanumericJust alphanumeric charactersSolo caracteres alfanuméricos
notContainThe following characters aren't admitted %alphabetNo se admiten los siguientes caracteres %alphabet
shouldOnlyContainThey are just admitted the following characters %alphabetSolo se admiten los siguientes caracteres %alphabet
mustContainOneAt least one of the following characters is required: %alphabetSe requiere al menos uno de los siguientes caracteres: %alphabet
mustContainMinAt least %min of the following characters are required: %alphabetSe requiere al menos %min de los siguientes caracteres: %alphabet
minValueThe value cannot be less than %minEl valor no puede ser menor a %min
maxValueThe value cannot be greater than %maxEl valor no puede ser mayor a %max
rangeValueThe value must be between %min and %maxEl valor debe estar entre %min y %max
numberIt is not a numberNo es un número
numberPatternDoes not match pattern %patternNo coincide con el patrón %pattern
Note:
  • The % followed by the variable name will be replaced by the condition passed in the predefined rule.
  • The message passed directly into the rule has priority over the default messages.

Change default messages

Validator has a static variable called .messages which receives an object of type Messages as a parameter.

import { Validator } from 'chained-validation-rules';

Validator.messages = {
  onlyAlphanumericMessage: 'Custom message',
  onlyLettersMessage: 'Custom message',
  onlyNumbersMessage: 'Custom message',
  compareMessage: 'Custom message',
  requiredMessage: 'Custom message',
  minLengthMessage: 'Custom message',
  maxLengthMessage: 'Custom message',
  rangeLengthMessage: 'Custom message',
  textLengthMessage: 'Custom message',
  emailMessage: 'Custom message',
  reMessage: 'Custom message',
  numberMessage: 'Custom message',
  linkMessage: 'Custom message',
  wwwLinkMessage: 'Custom message',
  httpLinkMessage: 'Custom message',
  httpsLinkMessage: 'Custom message',
  ipMessage: 'Custom message',
  ipv4Message: 'Custom message',
  ipv6Message: 'Custom message',
  nameMessage: 'Custom message',
  timeMessage: 'Custom message',
  time12Message: 'Custom message',
  time24Message: 'Custom message',
  notContainMessage: 'Custom message',
  shouldOnlyContainMessage: 'Custom message',
  mustContainOneMessage: 'Custom message',
  mustContainMinMessage: 'Custom message',
  minValueMessage: 'Custom message',
  maxValueMessage: 'Custom message',
  rangeValueMessage: 'Custom message',
  numberPatternMessage: 'Custom message',
}

Changing the message language

import { Validator, messagesEs } from 'chained-validation-rules';

Validator.messages = messagesEs

Validating a string

Working with events

The .isValid method is used to find out if the string is valid.

import { ValidatorBuilder } from 'chained-validation-rules';

const validator = new ValidatorBuilder()
  .rule('The text is different from xxx', evaluate => evaluate === 'xxx')
  .build();

function submit() {
  validator.isValid('yyy'); // false
  validator.isValid('xxx'); // true
}

In case you want to compare two strings, which is very useful to validate passwords, you can use the method .isMath. Optionally, an error message can be defined by defining the .notMatchMessage property for the error message if it doesn't match.

import { ValidatorBuilder } from 'chained-validation-rules';

const validator = new ValidatorBuilder()
  .rule('The text is different from xxx', evaluate => evaluate === 'xxx')
  .setNotMatchMessage('Not match')
  .build();

function submit() {
  validator.isMatch('abc', 'xyz'); // false
  validator.isMatch('abc', 'abc'); // true
}

The .onInvalidEvaluation event is executed when a rule fails when it is evaluated and returns the error message associated.

import { ValidatorBuilder } from 'chained-validation-rules';

const validator = new ValidatorBuilder()
  .rule('The text is different from xxx', evaluate => evaluate === 'xxx')
  .addOnInvalidEvaluation( (message: string) => console.log(message) ) // It is only executed if the validation of some rule fails
  .build();

function submit() {
  validator.isValid('yyy');
}

Work with exceptions

If you prefer not to use the .onInvalidEvaluation event, you can use the .validOrFail and .compareOrFail methods replacing the .isValid and .isMatch methods respectively.

The main difference is that these methods do not return any value and if they fail, they throw an exception to the type InvalidEvaluationError containing the error message from the rule along with the value of the string to be evaluated and a key which works as an identifier.

import { ValidatorBuilder, InvalidEvaluationError } from 'chained-validation-rules';

const validator = new ValidatorBuilder()
  .rule('The text is different from xxx', evaluate => evaluate === 'xxx')
  .build();

function submit() {
  try {
    validator.validOrFail('textKey', 'yyy');
    // or
    validator.compareOrFail('textKey', 'xxx', 'yyy');
    // TODO ...
  } catch (e) {
    if (e instanceof InvalidEvaluationError) {
      console.log(`key: ${e.key}, value: ${e.value}, error message: ${e.message}`)
    }
  }
}

recommendations

Commonly, there are several instances of strings to which to apply the same validation rules. for these cases it is recommended to define Validators per context, in order to define our Validator once and reuse it. This logic is possible, since Validator includes a .copy method which generates copies of it.

validators.ts

import { ValidatorBuilder } from 'chained-validation-rules';

export const email = new ValidatorBuilder()
  .required()
  .email()
  .build();

export const password = new ValidatorBuilder()
  .required()
  .minLength(12)
  .mustContainMin(3, 'abcdefghijklmnopqrstuvwxyz')
  .mustContainMin(3, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
  .mustContainMin(3, '0123456789')
  .mustContainMin(3, '@~_/')
  .build();

login.ts (example with events)

import { ValidatorBuilder, InvalidEvaluationError } from 'chained-validation-rules';
import { email as _email, password } from './validators.ts';

let email: string, psw: string, pswConfirmation: string = '';

const emailValidator: Validator = _email.copy();
const pswValidator: Validator = password.copy()

emailValidator.onInvalidEvaluation = (error: string) => {
  // TODO handle error for email
}
pswValidator.onInvalidEvaluation = (error: string) => {
  // TODO handle error for password
}

function submit() {
  if (
    !emailValidator.isValid(email) || 
    !pswValidator.isMatch(psw, pswConfirmation)
  ) return;
  // TODO proceed with submit
}

login.ts (example with exception)

import { ValidatorBuilder, InvalidEvaluationError } from 'chained-validation-rules';
import { email as _email, password } from './validators.ts';

let email: string, psw: string, pswConfirmation: string = '';

const emailValidator: Validator = _email.copy();
const pswValidator: Validator = password.copy()

function submit() {
  try {
    emailValidator.validOrFail('email', email);
    pswValidator.compareOrFail('psw', psw, pswConfirmation);
    // TODO proceed with submit
  } catch (e) {
    if (e instanceof InvalidEvaluationError) {
      switch (e.key) {
        case 'email':
          // TODO handle error for email
          break;
        case 'psw':
          // TODO handle error for password
          break;
      }
    }
  }
}
0.0.12

1 year ago

0.0.11

1 year ago

0.0.10

1 year ago

0.0.9

1 year ago

0.0.8

1 year ago

0.0.7

1 year ago

0.0.6

1 year ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago