c2v
TypeScript icon, indicating that this package has built-in type declarations

1.3.0 • Public • Published

c2v is async and expressive validation library for nodejs apps

Install

using yarn yarn add c2v or using npm npm i c2v

Usage

Typescript or ES6

import c2v from "c2v"

or using ES5

const c2v = require('c2v')

Basic example

for a basic employee model that has a first name, last name, email and birthdate

import c2v, { Context } from "c2v"
 
const schema = c2v.obj.keys({
    // must be a string with minimum length of 2 letters and maximum length of 32
    firstName: c2v.str.minLength(2).maxLength(32),
    lastName: c2v.str.minLength(8).maxLength(64),
    // email address
    email: c2v.str.email(),
    // validates a date in a form of unix seconds
    birthdate: c2v.date.format(DF.Unix),
})
 
const result = await Context.validate(schema, {
    firstName: 'cyber',
    lastName: 'crafts',
    email: 'contact@cyber-crafts.com',
});
 
// >> result will be
{
    success: false,
    errors: [{
        dataPath: "/lastName",      // << where the error happened
        rule: "string.minLength",   // << what rule did it break
        params: { limit: 8 }        // << the rule configuration was used while validation
    }],
    messages: []
}

validators

validators or (type validators) are a set of classes used to validate a certain data type, all validators extend base class BaseValidator and by default all validators add a validation rule to check the data type on constructor

validators shorthands

ObjectValidator class (shorthand c2v.obj): holds validation rules related to objects

ArrayValidator class (shorthand c2v.arr): holds validation rules related to arrays

StringValidator class (shorthand c2v.str): holds validation rules related to strings

NumberValidator class (shorthand c2v.num): holds validation rules related to numbers, also c2v.int is shorthand for new NumberValidator(true) which adds one more check to see if a given value in an integer

DateValidator class (shorthand c2v.date): holds validation rules related to dates

BooleanValidator class (shorthand c2v.bool): holds validation rules related to booleans

object validator

requires

In the example above the library will validate only existing fields against their validators, that's why the only error is on lastName property

The requires rule will cause a validation error if any of its arguments is missing from the object

c2v.obj.requires('firstName', 'lastName', 'email', 'birthdate').keys({
  firstName: c2v.str.minLength(2).maxLength(32),
  lastName: c2v.str.minLength(8).maxLength(64),
  email: c2v.str.email(),
  birthdate: c2v.date.format(DF.Unix),
})

umm looks good, but not very real world scenario yet, what if we want to require a fields conditionally.

requiresWithAny

require the existence of conditional fields if any of the assertion fields exist

// on this example "prop1" and "prop2" will be required if "assertionProp1" **or** "assertionProp2" exist on object
c2v.obj.requiresWithAny(["prop1","prop2"],["assertionProp1","assertionProp2"])
    .keys({
      requiredProp1: c2v...,
      requiredProp2: c2v...,
      assertionProp1: c2v...,
      assertionProp2: c2v...
    })

requiresWithAll

same as previous rule but the difference is that requiresWithAll will require conditional fields only if all assertion fields are present on object while requiresWithAny will require them if any of the assertion fields is present on the object.

// on this example "prop1" and "prop2" will only be required when "assertionProp1" and "assertionProp2" already exist on object
c2v.obj.requiresWithAll(["prop1","prop2"],["assertionProp1","assertionProp2"])
    .keys({
      requiredProp1: c2v...,
      requiredProp2: c2v...,
      assertionProp1: c2v...,
      assertionProp2: c2v...
    })

requiresIfAny

this is a more advanced use case this will require centain properties on current object if a condition is satisfied, so for the sake of example let's assume that we need the national Id of the employee if he is older than 45 years

c2v.obj.requires('firstName', 'lastName', 'email', 'birthdate')
    .requiresIfAny(['nationalId'], {
      path: '/birthdate',   // assertion property path (json-pointer)
      validator: c2v.date.format(DF.Unix).furtherThanFromNow(-45, "years") // assertion rule
    }).keys({
      firstName: c2v.str.minLength(2).maxLength(32),
      lastName: c2v.str.minLength(8).maxLength(64),
      email: c2v.str.email(),
      birthdate: c2v.date.format(DF.Unix),
      nationalId: c2v.str.length(26),
    })

array validator

array validator can assert array properties like the number of items in the array, but it also can validate a certain entries

minItems and maxItems

asserts the array to be at least or at most of certain length

c2v.arr.minItems(2).maxItems(3)

allItems

asserts that all array items meet a certain schema

in this example all array items must be valid email addresses

c2v.arr.allItems(c2v.string.email())

items

asserts certain items each against a certain schema, let's say that we are validating a GPS location coordinates

c2v.arr.minItems(2).maxItems(2)        // restricting the array to only 2 entries
    .items({
        0: c2v.num.min(-180).max(180),   // validating first entry as longtude
        1: c2v.num.min(-90).max(90),     // validating second entry as latitude
    })

string validator

length

asserts if the field under validation is of certain length

const schema = c2v.str.length(3);

minLength and maxLength

asserts if the field under validation is of at least of certain length and at most of certain length respectively

const schema = c2v.str.minLength(2).maxLength(32);

matches

asserts if the field under validation matches a certain regular expression

const schema = c2v.str.matches(/[0-9]{5}/);

this will validate the string to contain only numbers and contain only 5 letters

url

asserts if the field under validation is a valid url

const schema = c2v.str.url();

email

asserts if the field under validation is a valid email address

const schema = c2v.str.email();

confirmed

asserts if the field under validation exists with the name <field>_confirmation and its value is equal to the original <field>'s value

this validation rule might me removed in the future

number validator

min and max

asserts that the field under validation is more than or less than a certain value

c2v.num.min(128).max(256) // 128 is valid and 256 is valid

both rules accept a second parameter exclusive if true then the validated value must not equal the min or the max limit to be valid

c2v.num.min(128, true).max(256) // 128 is invalid

multipleOf

asserts that the field under validation is a multiple of a given number

c2v.num.multipleOf(3) // 3, 6, 9 etc are valid values

date validator

format

asserts that the field under validation is represented in a known format

if not set this defaults to DF.ISO8601 which is YYYY-MM-DD

before and after

asserts that the field under validation is before or after a centain date respectively

// validates if the value is a date after "2018-07-01" before "2018-08-01"
c2v.date.after("2018-07-01").before("2018-08-01");

closerThanFromNow

asserts that the date under valiadtion is between now and the duration, if the duration has a negative value then the validator will assume you want to assert that the value is between now and the given duration in the past

// any value between now and next 7 days
c2v.date.closerThanFromNow(7, "days")
// any value between now and past 7 days
c2v.date.closerThanFromNow(-7, "days")

furtherThanFromNow

asserts that the date under valiadtion is further than the given duration, if the duration has a negative value then the validator will assume you want to assert that the value is further than the given duration in the past

// any value after 7 days from now
c2v.date.furtherThanFromNow(7, "days")
// any value before 7 days from now
c2v.date.furtherThanFromNow(-7, "days")

reusable validators

we can reuse already existing validators on other validators like following

let's assume that we need to create a validator to validate GPS coordinates

// coordinates.js
export default c2v.arr.minItems(2).maxItems(2).items({
  0: c2v.num.min(-180).max(180),    // longitude
  1: c2v.num.min(-90).max(90),      // latitude
});
// this will require an array of 2 items like: [135, 45]
 
 
// on other file
import coordinates from './coordinates'
 
const warehouseSchema = c2v.obj.keys({
    ...
    location: coordinates
    ...
})

// upcoming

context

custom validators

Package Sidebar

Install

npm i c2v

Weekly Downloads

5

Version

1.3.0

License

MIT

Unpacked Size

141 kB

Total Files

76

Last publish

Collaborators

  • romany-saad