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

@cesium133/forgjs

v2.2.0

Published

forgJs is a javascript lightweight object validator.

Downloads

5,943

Readme

forgJs logo

ForgJs is a JavaScript lightweight object validator. Go check the Quick start section and start coding with love :heart:

email

password

number

url

See more live examples here

Quick start

Install it via npm by running npm i @cesium133/forgjs

Your first validator

  const { Validator, Rule } = require('@cesium133/forgjs');

const emailRule = new Rule({
    type: 'email',
    user: user => user === 'dedede',
    domain: domain => ['outlook', 'gmail', 'yahoo'].indexOf(domain) !== -1,
}, null);

const passwordRule = new Rule({
    type: 'password',
    minLength: 8,
    uppercase: 1,
    numbers: 1,
    matchesOneOf: ['@', '_', '-', '.', '!'],
}, null);

const vComplex = new Validator({
    age: new Rule({ type: 'int', min: 18, max: 99 }),
    dateOfBirth: new Rule({ type: 'date' }),
    array: new Rule({ type: 'array', of: new Rule({ type: 'string' }) }),
    email: emailRule,
    password: passwordRule
});

vComplex.test({
    age: 26,
    dateOfBirth: new Date(1995, 10, 3),
    array: ['1'],
    email: '[email protected];',
    password: 'ad1_A@@Axs',
}); /// returns true

Error handling

You can get custom error messages by doing this:

const vComplexe = new Validator({
    age: new Rule({
      type: 'int', min: 18, max: 99,
    }, 'age must be integer and between 18 and 99'),
    dateOfBirth: new Rule({ type: 'date' }, 'date must be a date'),
  });

  vComplexe.getErrors({
    age: 16,
    dateOfBirth: 123,
  }); // ['age must be integer and between 18 and 99', 'date must be a date']

Test over an array

You can test over multiple arrays using this method:

const vComplexe = new Validator({
    age: new Rule({
      type: 'int', min: 18, max: 99,
    }),
  });

  vComplexe.testAll([{
    age: 19,
  }, {
    age: 16,
  }]);  // returns 1

Rules

A Rule object validates a single value, it can be used like this:

  const { Validator, Rule } = require('@cesium133/forgjs');
  const floatRule = new Rule({
    type: 'float',
    min: 100,
  }, null);

  floatRule.test(2.001); /// returns true;

The only required value is type!

You can make a rule by simply passing a string if you only need to check the type : new Rule('int');

int

  • min (int)
  • max (int)
  • equal (int)

boolean

  • toBe (boolean)

string

  • minLength (int)
  • maxLength (int)
  • equal (string)
  • match: (regex)
  • notEmpty (bool)

email

  • minLength (int)
  • maxLength (int)
  • equal (string)
  • match: (regex)
  • notEmpty (bool)
  • user (function(user))
  • domain (function(domain))
  const emailRule = new Rule({
    type: 'email',
    user: user => user === 'dedede',
    domain: domain => ['outlook', 'gmail', 'yahoo'].indexOf(domain) !== -1,
  }, null);

  emailRule.test('[email protected]'); // returns true

password

  • minLength (int)
  • maxLength (int)
  • equal (string)
  • match: (regex)
  • notEmpty (bool)
  • uppercase (int)
  • number (int)
  • mathesOneOf (Array)
  • matchesAllOf (Array)
  const passwordRule = new Rule({
    type: 'password',
    minLength: 8,
    uppercase: 1,
    numbers: 1,
    matchesOneOf: ['@', '_', '-', '.', '!'],
  }, null);

  passwordRule.test('@_-bddcd6A'); // returns true

url

  • minLength (int)
  • maxLength (int)
  • equal (string)
  • match: (regex)
  • notEmpty (bool)
  • protocol (function(protocol))
  • domain (function(domain))
  const urlRule = new Rule({
    type: 'url',
    protocol: prot => prot === 'https',
    domain: domain => domain === 'google.fr',
  }, null);

  urlRule.test('https://google.fr'); // returns true

date

  • after (date)
  • before (date)
  • between (Array of dates like this [date, date])
  • equal (date)

float

  • min (Number)
  • max (Number)
  • equal (float)

array

  • of (Rule or Validator object)
  • notEmpty (bool)
  • length (int)

The of rule checks every element of the array against the rule.

function

  • result

To explain result, what's better than an example:

  const { Validator, Rule } = require('@cesium133/forgjs');

  function someFunctionThatReturnsAnInt(int) {
    return int * 5;
  }

  const functionTest = new Rule({
    type: 'function',
    result: {
      of: 5,
      toBe: new Rule('int'),
    },
  }, null);

  functionTest.test(someFunctionThatReturnsAnInt); /// returns true;

string-int, string-float, string-date, string-boolean

These types 'inherit' from string, they have both the properties, here are some examples:

string-int

const stringInt = new Rule({
  type: 'string-int',
  minLength: 2,
  min: 5,
}, null);

stringInt.test(2) // returns false 2 is not a string
stringInt.test('2a') // returns false '2a' is not a int
stringInt.test('2.1') // returns false '2.1' is not a int
stringInt.test('5') // returns false length of '5' is smaller than 2
stringInt.test('50') // returns true

string-boolean

const stringBoolean = new Rule({
  type: 'string-boolean',
  toBe: true
}, null);

stringBoolean.test(true) // returns false true is not a boolean
stringBoolean.test('false') // returns false 'false' is not true
stringBoolean.test('true') // returns true
const stringDate = new Rule({
  type: 'string-date',
  after: new Date(2019, 11, 1),
}, null);

stringDate.test(new Date(2018, 11, 1)) // returns false new Date(2018, 11, 1) is not a string
stringDate.test('some string') // returns false 'some string' is not a valid date
stringDate.test('2018-12-17') // returns false '2018-12-17' is not after new Date(2019, 11, 1)
stringDate.test('2020-01-01') // returns true

Forgjs tries to cast the value to the right type before passing it to the validation function please be careful!

Here is an example where Javascript behaviour makes the test wrong:

const stringDate = new Rule({
  type: 'string-date',
  equal: new Date(2019, 10, 1), // month in js strart at 0
}, null);

stringDate.test('2019-11-01') // returns false
stringDate.test('2019-11-01T00:00') // returns true


// this is because:

new Date(2019, 10, 1) - new Date('2019-11-01') // equals  3600000 thats exactly 1 hour

new Date(2019, 10, 1) - new Date('2019-11-01T00:00') // equals 0

Multiple types

You can check for multiple types with OR or AND operators like this:

  const intRule = new Rule({
    type: 'int|float|number',
  }, null);

  intRule.test(2) // returns true

This means the test should verify the int, float or number rule

  const intRule = new Rule({
    type: 'int&number',
  }, null);
  intRule.test(2.1); // returns false

The result doesn't match the int rule

Common properties

Every type has these properties:

  • optional
  • custom
  • oneOf

optional

If optional is set to true the element is optional and an undefined value is considered correct. Example:

const { Validator, Rule } = require('@cesium133/forgjs');

const intRule = new Rule({
    type: 'int',
    optional: true,
  }, null);
intRule.test(); // returns true

custom

Custom allows you to write your own rule, an example is better than a long explanation:

  const { Validator, Rule } = require('@cesium133/forgjs');
  
  function isCorrectAge(age, object) {
    if (age === Math.floor((new Date() - object.dateOfBirth) / 1000 / 60 / 60 / 24 / 30 / 12)) {
      return true;
    }
    return false;
  }
  const vComplexe = new Validator({
    age: new Rule({
      type: 'int', min: 18, max: 99, custom: isCorrectAge,
    }),
    dateOfBirth: new Rule({ type: 'date' }),
  });

  vComplexe.test({
    age: 23,
    dateOfBirth: new Date(1995, 10, 3),
    array: ['1'],
  }); // returns true

oneOf

One of checks if the element is in a array

  const floatRule = new Rule({
    type: 'float',
    oneOf: [3.5, 100.1, 7.2, 0.1],
  }, null);
  floatRule.test(100.1); // returns true

Make a new type

Creating a new type is done using the Rule class like this:

  const { Validator, Rule } = require('@cesium133/forgjs'); 
  
  Rule.addCustom('customInteger', {
    min: (val, min) => val - min > 0,
    max: (val, max) => val - max < 0,
    equal: (val, equal) => val === equal,
    type: val => Number.isInteger(val) && val > 0 && val < 100,
  });

  const customInteger = new Rule({
    type: 'customInteger',
    min: 10,
  }, null);

  customInteger.test(11) // returns true

  customInteger.test(200) // returns false

How to contribute

Thank you everyone for contributing to make this code better, if you have suggestions or ideas to improve the code please feel free to leave a comment here #29. Rules:

1 Please use this template which will help developers to test and better understand your request

const someRule= new Rule({
    type: 'yourType',
    prop1: val1,
    prop2: val2, ...
  }, null);

  someRule.test(validValue) // returns true
  someRule.test(invalidValue) // returns false

2 Please if you think a comment is a good feature to be added like the comment instead of creating a new one.

3 Before submitting a new comment check if the same comment is not already present

4 If you submit a PR (pull request) and you only change the Readme please add [ci skip] to your commit message

5 If you have any questions ask them in the FAQ

6 Please have fun, and if you feel like not following the rules then don't follow them

Contact

Follow me on twitter at @forg_js