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

makerule

v1.0.5

Published

A simple and functional validation library for creating custom validation rules

Downloads

136

Readme

makeRule

A simple and functional validation library for creating custom validation rules.

Installation

npm install makerule

The makeRule package comes with a minified version that can be added to the browser:

<script type="text/javascript" src="node_modules/makerule/dist/makeRule.min.js"></script>

Usage

makeRule allows you to create chainable functions that can be used to test values.

import makeRule from 'makerule';

// functions evaluate in order from left to right
var rule = makeRule.rule().isString().longerThan(5);

rule(3); // =>  { result: false, value: 3, test: 'isString' }
rule('nope'); // =>  { result: false, value: 'nope', test: 'longerThan' }
rule('123456'); // =>  { result: true, value: '123456' }

// Because rules are functional and chainable, you can extend them as you go.
var newRule = rule.shorterThan(10);
newRule('a string longer then 10 characters'); // =>  { result: false, value: 'a string longer then 10 characters', test: 'shorterThan' }

The result will return true if the value you pass to the rule is null or undefined. If the test requires a value, add .required() to the chain:

var rule = makerule.rule().isString();
rule(undefined); // => { result: true, value: undefined }

var ruleRequired = rule.required();
ruleRequired(undefined); // => { result: false, test: 'required', value: undefined }

You can also write your own tests. To do this, add .testWith() to the chain and pass the name of the test, and a predicate function or a regular expression. That function will receive the current value as an argument. Return a boolean true or false to describe if the test passed or failed.

var testForHiwithFunction = makerule.rule().isString().testWith('hasHi', value => (value.indexOf('hi') >= 0));

var testForHiWithRegExp = makerule.rule().isString().testWith('hasHi', /hi/);

testForHiwithFunction('hi there'); // => { result: true, value: 'hi there' }
testForHiWithRegExp('hi there'); // => { result: true, value: 'hi there' }

If you want to change the value as it passes through the tests, you can use .mapValue() and pass a function which should return another value. The value that you return will then be one used for the following tests in the chain.

// value will mapped to an integer before the isNumber test runs.
var mapTest = makerule.rule().isString().mapValue(value => parseInt(value, 10)).isNumber();
mapTest('10'); // => { result: true, value: 10 }

Using for validation

Most of the time when validating values, you will probably want to get some kind of error message out of it. The validateWith() helper function allows you to return error messages from failed tests within the result:

// make a test for passwords. testPasswordStrength would be a function which returns true if the password is strong.
var passwordRule = makeRule.rule().longerThan(6).testWith('passwordStrength', testPasswordStrength);

// pass the rule, and a map of tests to use, where the property key is the name of the test that might fail
var testPassword = makeRule.validateWith(passwordRule, { 
	longerThan: 'Your password must be longer then 6 characters',
	passwordStrength: 'Your password should contain at least one number and one capital letter'
});

testPassword('bad'); // => { result: false, value: 'bad', test: 'longerThan', message: 'Your password must be longer then 6 characters' }
testPassword('Areallyg00dp@ssw0rd'); // => { result: true, value: 'Areallyg00dp@ssw0rd' }

API

Making Rules

  • rule() - Creates a test function that you can chain together to create more complex tests. Returns a result object.
  • validateWith(rule, messageMap [, defaultMessage]) Returns a result object with an additional message parameter. The message parameter is equal to value of the test name that you have passed to messageMap. If the test name does not exist, the defaultMessage will be returned (or undefined if none is passed).

The Result Object

The result object comprises of a result, valueand test (if the test has failed):

{
	result // Boolean. Evaluates as "true" or "false" depending  on the outcome of the test
	value // The value that is returned from the tests. This can be different from the original value if you have used the mapValue method to change the value mid way through validation.
	test // String (optional). If the result is false, this will be the name of the test that failed.
}

General Tests

General:

  • equals(comparison) - Performs an === equality check between the value being tested and a comparison value.

Types:

  • isString() - Tests if the value is a string
  • isObject() - Tests if the value is an object (and not an Array or Null). Note that functions are objects, so passing a function as the value will pass for this test.
  • isArray() - Tests if the value is an Array.
  • isBool() - Tests if the value is a Boolean
  • isNumber() - Tests if the value is a real number (not NaN)
  • isInt() - Tests if the value is a number and an integer (does not have a decimal)
  • isFloat() - Tests if the value is a number and a float (has a decimal)

Strings:

  • isEmail() - Test if the value is an email
  • isCreditCard() - Check if the value string is a credit card
  • isDateString() - Check if the value is a date formatted like xx/yy/zz
  • isAlpha() - Check if the value string contains only letters (a-zA-Z)
  • isAlphanumeric() - Check if the value contains only letters and numbers
  • isDecimalString() - Check if the value (string) represents a decimal number, such as 0.1, .3, 1.1, 1.00003, 4.0, etc.
  • isNumeric() - Check if the value contains only numbers
  • isHexColor() - Check if the value is a hex colour.
  • isURL() - Check if the value is a URL

These tests are from the string validation library validator.js. Refer to that for more information.

String/Array:

  • longerThan(n) - Test if the value is longer than n. Compares with the .length property of the value.
  • shorterThan(n) - Test if the value is shorter than n. Compares with the .length property of the value.

Number:

  • divisableBy(n) - Check if the value is divisible by n.
  • greaterThan(n) - Check if the value is greater than n.
  • lessThan(n) - Check if the value is less than n.

Bool:

  • isTrue() - Check if the value is true. This is a strict === test.
  • isFalse() - Check if the value is false. This is a strict === test.

Object/Array:

  • contains([object, array, string]) - Tests if the value (as an object or array) contains n. If the value being tested is an array, n may be a string or array of things the value should contain. If the value is an object, n can be an object map that will be compared to the value.
  • isSame([object, array]) - Tests if the value (as an object or array) is the same as n. This is a recursive deep comparison.

Helper tests

  • testWith(testName, [fn, regexp]) - Tests a value using a predicate function or regular expression. If you pass a function, that function will receive the current value as the first arguement and must return true or false. If you pass a regular expression, the value will be tested against that regular expression.
  • mapValue(fn) - Changes the value being tested at that point in the chain where fn is a function that recieves the current value as the first argument and returns another value.
  • required() - Tests that the value is not undefined or Null. If you do not add required() to the chain, these values will pass through un-tested.

Custom tests setup

Testing using the provided test library might be enough for you, but if you want to save some kb or use your own testing library, makeRule allows you to import its validation functionality separately to its testing library.

To setup your own testing suite, only require/import the validator function. You can then pass an object map of your custom tests, where the key is the name of the test, and the test is a function that recieves thevalue as an argument, and returns true or false. Testing functions receive the value as their last argument. This means you can use other arguments when creating the rule to customize the test.

Custom validators still receive the standard helper functions testWith, mapValue, and required.


import Validator from 'makerule/validator' ;

// create a test map
var testMap = {
	isgreaterThan5 : value => (value >= 5),
	containsString: (str, value) => (value.indexOf(str) >= 0) // accepts an extra str argument
};

var validation = Validator(testMap);

var rule1 = validation.rule().required().isgreaterThan5();
var rule2 = validation.rule().containsString('awesome');

rule1(10) // => { result: true, value: 5 }
rule2('this is awesome') // => { result: true, value: 'this is awesome' }

The full test library is also available separately.

import Validator from 'makerule/validator' ;
import * as tests from 'makerule/tests' ;

// we can add some custom tests
tests.containsString = (str, value) => (value.indexOf(str) >= 0);

// we can now use our custom tests as well as the tests in the test library
var validation = Validator(tests);

A note on performace

While I haven't fully tested performance for this library, it is generally better to create your rules outside of any intensive looping or recursive code if you can avoid it.

	// This might be slow:
	var rules = [];
	while (rules.length < 100) {
		rules.push(makeRule.rule().isNumber().greaterThan(6));
	}

	// This is fast:
	var rule = makeRule.rule().isNumber().greaterThan(6);
	var results = [];
	while (results.length < 100) {
		results.push(rule(results.length));
	}

Running your tests however is optimised and usually extremely fast.

Tests

npm test