waechter

simple, functional, sync/async validation for Node.js and browsers

Usage no npm install needed!

<script type="module">
  import waechter from 'https://cdn.skypack.dev/waechter';
</script>

README

waechter

ALPHA NPM Package Build Status Dependencies

simple, functional, sync/async validation for Node.js and browsers

inspired by Prismatic/schema

waechter is german for guardian

npm install waechter
bower install waechter

lib/waechter.js supports AMD. if AMD is not available it sets the global variable waechter.

require:

> var waechter = require('waechter');

predicates

a predicate is a function that takes a value and returns a boolean indicating whether that value is valid.

is.js is a big collection of predicates.
waechter doesn't reinvent the wheel and uses is.js predicates:

> var isjs = require('isjs');

> isjs.email('i am definitely not an email address');
false

> isjs.email('example@example.com');
true

validators

a validator is a function that takes a value and returns nothing (null or undefined) if the value is valid. otherwise it returns a value describing the error. that value is usually a string that is a helpful error message or an object whose values are error messages.

you can make a validator from a predicate using waechter.predicateToValidator

> var validateEmail = waechter.predicateToValidator(
  // the predicate
  isjs.email,
  // the value that is returned when the predicate returns false
  'must be an email address'
);

you can then use the validator to validate some data:

> validateEmail('i am definitely not an email address');
'must be an email address'

> validateEmail('example@example.com');
null

these validators are builtin

  • waechter.exist
  • waechter.string
  • waechter.stringNotEmpty
  • waechter.email
  • waechter.stringMinLength(min)
  • waechter.number
  • waechter.numberWithin(min, max) (range is exclusive)
  • waechter.true
  • waechter.false
  • waechter.undefined
  • waechter.null
  • waechter.boolean

you can easily make your own validators using waechter.predicateToValidator.

composing validators

waechter.and(validators...) returns a validator that returns null if all validators return null and otherwise returns the first error.

waechter.or(validators...) returns a validator that returns null if at least one of the validators returns null and otherwise returns an array of errors.

use waechter.undefinedOr(validators...) to make things optional.

schemas

a schema is an object whose values are validators:

> var userSchema = {
  email: waechter.email,
  password: waechter.stringNotEmpty
};

you can make a validator from a schema:

> var validateUser = waechter.schemaToValidator(userSchema);

you can then use that validator to validate the structure of objects:

> validateUser({
  email: 'invalid'
});
{
  email: 'must be an email address',
  password: 'must not be null or undefined'
}
> validateUser({
  email: 'test@example.com',
  password: 'topsecret'
});
null

keys that are not present in the schema are not allowed in the data:

> validateUser({
  email: 'test@example.com',
  password: 'topsecret'
  is_admin: true
});
{
  is_admin: 'disallowed key'
}

async validators

an async validator is like a validator but returns a promise.

you can lazily (only when needed) run async validators after sync validators like so:

> var userSchema = {
  email: waechter.email,
  password: waechter.stringNotEmpty
};

> var userSchemaAsync = {
  email: function(email) {
    return doesUserWithEmailAlreadyExistInDatabase(email).then(function(exists) {
      if (exists) {
        return 'taken';
      }
    });
  }
};

> validateUser = waechter.schemasToLazyAsyncValidator(
  userSchema,
  userSchemaAsync
);

you can mix schemas with sync and async validators in the arguments to waechter.schemasToLazyAsyncValidator.

validators in later schemas are only run for keys that have no errors yet:

> validateUser({
  email: 'invalid'
}).then(function(errors) {
  > errors
  {
    email: 'must be an email address',
    password: 'must not be null or undefined'
  }
});

here the validator userSchemaAsync.email wasn't called.

> validateUser({
  email: 'taken@example.com'
}).then(function(errors) {
  > errors
  {
    email: 'taken',
    password: 'must not be null or undefined'
  }
});

this time the validator userSchemaAsync.email was called.

see the tests for more usage examples.

license: MIT