@vlr/validity
TypeScript icon, indicating that this package has built-in type declarations

4.0.0 • Public • Published

@vlr/validity

basic validation library

creating a validator

lets say you have a typescript type

export interface Person {
  name: string;  
  address: string;  
  age: number;
  foodTaste?: string;
}

And you want to decide if object is valid or not, based on following rules:
a. Name is required and can't be longer than 20 characters
b. Address is required.
c. Age is not negative and less than 100.
c. Food taste is not constrained to anything, not required.

To create such a validator:

import {Validator, ObjectValidator, required, maxLength, equalOrMoreThan, lessThan} from '@vlr/validity'
const personValidator: Validator<Person> = {
  name: [required(), maxLength(20)],
  address: required(),
  age: [equalOrGreater(0), lessThan(100)]
};

validating an object

To validate an object:

import { validate } from '@vlr/validity';
function isMyPersonValid(somePerson: Person): boolean {
  const result: Validation<Person> = validate(personValidator, somePerson);
  return result._valid;
}

To get validation messages

const nameMessages = validate(personValidator, somePerson).name._messages;

overriding validation messages

By default, validation messages are supposed to be translated/localized, so basic message for "required" validator is "validation.required" You can override that message like this.

const personValidator: Validator<Person> = {
  name: required('name is required'),
  address: required('address is required'),
};

nesting objects

export interface Vehicle {
   licencePlate: string;
   driver: Person;
   passenger: Person;
}

const vehicleValidator: Validator<Vehicle> = {
  licencePlate: // some complex custom validation here,
  driver: [required(), personValidator]
  passenger: personValidator
};

Note: when passenger is null, then result.passenger._valid will be evaluated to true, otherwise it is calculated by validation rules.

nesting arrays

export interface Company {
  title: string;
  employees: Person[];
}
const companyValidator: Validator<Company> = {
  title: required(),
  employees: [required(), arrayValidator<Person>(personValidator)]
};

const firstEmployeeValid = result.employees[0]._valid;

creating custom validator

import { validator } from '@vlr/validity';

const licensePlateValidator = validator<string>(isLicensePlateValid, 'license plate is invalid');

function isLicensePlateValid(plate: string): boolean {
  custom logic
}

const vehicleValidator: Validator<Vehicle> = {
  licencePlate: licensePlateValidator
};

cross-field validation

For example, if you need to check that field of an object should be no higher than the other field, i.e. one field is editable and the other comes from DB. For such case you can create validator like this

import { validator } from '@vlr/validity';

interface MyType {
  value: number;
  limit: number;  
}


const myTypeValidator: Validator<MyType> = {
  value: validator((value, obj) => value <= obj.limit, 'value should not be higher than limit');
};

dynamically enabling-disabling validators

"enabledIf" can be used to enable/disable validators coming after it, useful if item is hidden from view this construct will not disable validators before it in the array.

import { validator } from '@vlr/validity';

interface MyType {
  value: number;
  limit: number;
  isHidden: boolean;  
}

const validators: ChildValidator<string, MyType> = [enabledIf(<>)]

const myTypeValidator: Validator<MyType> = {
  value: [enabledIf((value, obj) => !obj.isHidden), required()]
};

"required" validator has its own disabling mechanism

const myTypeValidator: Validator<MyType> = {
  // null here is a placeholder for a message
  value: [required(null, (value, obj) => !obj.isHidden)]
};

Dependencies (2)

Dev Dependencies (21)

Package Sidebar

Install

npm i @vlr/validity

Weekly Downloads

2

Version

4.0.0

License

MIT

Unpacked Size

156 kB

Total Files

332

Last publish

Collaborators

  • vlr