quick validation/filtering of objects and http params against a schema
JavaScript HTML
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
dist
examples
lib
test
.gitignore
.travis.yml
LICENSE
README.md
package.json
schema.js

README.md

schemajs Build Status

validate objects (including http request params) against a schema. includes express middleware.

Installing

npm install schemajs

FEATURES

  • validates schema for deep objects and arrays as well
  • schema is in JSON, making it portable
  • properties, types and filters are extensible

EXAMPLE USAGE - validate an object

var schema  = require("./path/to/schemajs");
var model   = schema.create(
{
  name:    {type:"string", filters:"trim", properties:{max:255}, required:true},
  email:   {type:"email", filters:"trim", required:true},
  wins:    {type:"int", filters:["trim", "toInt"], default:0},
  average: {type:"float", filters:["trim", "toFloat"], default:0}
});

var form = model.validate({name:" your name ", email:" name@example.com "});

// form.valid  - boolean, true if object matches schema
// form.data   - contains filtered version of the object {name:"your name", email:"name@example.com", wins:0, average:0}
// form.errors - contains associative array of any errors found

If you pass {strict: true} as additional arguments into Schema#validate, the validation will fail if there are additional keys in the object which are not defined in the schema.

EXAMPLE USAGE - in expressjs, validate the request parameters

var schema  = require("./path/to/schemajs");
var query   = schema.create(
{
  wins:    {type:"int", filters:"toInt"},
  query:   {type:"string", filters:"trim", required:true, error:"invalid query"}
});

app.get("/users", schema.middleware(query), function(req, res)
{
  // schema validation is attached to req.form
  if(req.form.valid)
  {
    db_lookup({query:req.form.data.query, wins: req.form.data.wins});
  }
  else
  {
    next(new Error("invalid request"));
    //next(req.form.errors, 400);
  }
});

API

schema.test(schema)

quickly test an individual schema

field = schema.test("email@email.com", {type:"email", trim:true, properties:{min:5}});

schema.create(schema)

schema for a simple object of one integer value

schema =
{
         // [string] value for acceppted parameters of the object you want to test
  "wins":
  {
    // [string (built in types) or function (custom types)] the type declaration for accepted values
    "type": "int",

    // [string (built in filters) or function (custom filters) or array (mix and match!)] 
    // OPTIONAL, filters to process and optionally modify values
    "filters": ["trim", "toInt", custom_filter],

    // [anything] 
    // OPTIONAL, the default value if none is supplied by the object
    "default": 0,

    // [boolean] 
    // OPTIONAL, if true, this parameter must exist to validate
    "required": true,

    // [boolean] 
    // OPTIONAL, if true, this parameter can be null, despite any other rules
    "allownull": true,

    // [object] 
    // OPTIONAL, functions are custom property checks, else a built in property will be looked up
    "properties": {max:100, min:0, special:custom_property},

    // [string, object] OPTIONAL, if there is an error, you can override the message that is returned
    // use a string or the "default" key to use the default error message
    // keys can be any property key that was used as well as "filters", "required", "type"
    "error": {max: "too many wins", min: "too few wins", "default": "something is wrong with your wins value"}
  }
};

schema with embedded schemas for object and array types

schema =
{
  "user":
  {
    "type":  "object",
    "schema":
    {
      "name":  { type: "string", properties: { max: 255 }, required: true},
      "email": { type: "email", error: "email is not a valid email address"}
    },
    "error": "user needs an email and a name"
  },

  "tags":
  {
    "type":  "array",
    "schema":
    {
      "type": "string"
    },
    "properties":  { max: 10, min: 3},
    "error": { max: "too many tags", min: "too few tags" }
  }
};

schema.types

built in types

[string+, string (empty string allowed), alpha, alphanum, email, object, array, date, number, int, boolean, url, zipcode]

to extend, add a function onto schema.types that accepts a value and returns a boolean if the type matches

test is run AFTER schema.filters are run

schema.types.awesome = function(value)
{
  if(isAwesome(value))
    return true;
  else
    return false;
}

schema.filters

built in filters:

[toInt, toFloat, toString, toDate, toBoolean (converts on/off, true/false, 1/0, yes/no to bools), trim, lowercase, uppercase]

to extend, add a function onto schema.filters that takes in a value and returns the updated value

filters are run BEFORE schema.test is run

schema.filters.surround = function(value)
{
  if(value == needs_surrounding)
    return "----" + value + "----";
  else
    return value;
}

schema.properties

built in properties

[max, min, regex, in]

to extend, add a function onto schema.properties that takes in a value and any additional arguments

properties are run AFTER test and filters

schema.properties.unique = function(value)
{
  if(isArray(value) && allUnique(value))
    return true;
  else
    return false;
}

schema.properties.notIn = function(value, badwords)
{
  if(badwords.indexOf(value) != -1)
    return false;
  else
    return true;
}

Browser usage

You can use it in the browser by using browserify, however if that's too much work just use https://wzrd.in/. There is also an example

ideas

  • dependency property making one parameters existance depend on another
  • more types (phone numbers, credit card, ip address)
  • more filters (camelcase, encode/unencode)
  • more properties