npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

c2v

v1.3.0

Published

modular, extensible, intuitive and expressive - javascript validator

Downloads

262

Readme

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: '[email protected]',
});

// >> 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