<commit_before># skadi

[![npm version](https://badge.fury.io/js/skadi.svg)](https://badge.fury.io/js/skadi)
[![Dependency Status](https://david-dm.org/jeffijoe/skadi.svg)](https://david-dm.org/jeffijoe/skadi)
[![devDependency Status](https://david-dm.org/jeffijoe/skadi/dev-status.svg)](https://david-dm.org/jeffijoe/skadi#info=devDependencies)
[![Build Status](https://travis-ci.org/jeffijoe/skadi.svg?branch=master)](https://travis-ci.org/jeffijoe/skadi)
[![Coverage Status](https://coveralls.io/repos/github/jeffijoe/skadi/badge.svg?branch=master)](https://coveralls.io/github/jeffijoe/skadi?branch=master)
[![Code Climate](https://codeclimate.com/github/jeffijoe/skadi/badges/gpa.svg)](https://codeclimate.com/github/jeffijoe/skadi)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)

A simple object validator/sanitizer based on `is-my-json-valid`.

# Installation

```bash
npm install skadi --save
```

# Usage

```javascript
// Import
const { createValidator, ValidationError } = require('skadi')

// Create a validator using a JSON-schema.
const myValidator = createValidator({
  type: 'object',
  additionalProperties: false,
  properties: {
    name: {
      type: 'string',
      required: true
    }
  }
})

// Use it
const input = {
  name: 'Test',
  otherStuffThatIsNotRelevant: 'hehe'
}

const result = myValidator(input)
// << { name: 'Test' }
```

When used like above, validation errors will throw.

```javascript
try {
  myValidator({ anInvalid: 'object', because: 'it has no name' })
} catch (err) {
  console.log(err instanceof ValidationError) // << true
  console.log(err.errors) // << [{ field: 'name', message: 'is required' }]
}

```

Alternative usage:

```javascript
const context = myValidator.context({ })
console.log(context.valid()) // << false
console.log(context.errors) // << [{ field: 'name', message: 'is required' }]

const anotherContext = myValidator.context({ name: 'Skadi', other: 'stuff' })
console.log(anotherContext.valid()) // << true
console.log(anotherContext.pick()) // << { name: 'Skadi' }

// We can add errors manually..
anotherContext.errors.push({ field: 'name', message: 'Too cool, man' })
console.log(anotherContext.valid()) // << false
```

# Use Case: custom, async validation.

Because you can add errors manually, custom validation becomes easy (JSON-schema does not allow this).

Here's an example that makes the validator async.

```javascript
// Factory function that returns a validator.
// It takes a db so we can look up a user.
function createMyAwesomeValidator(db) {
  const validator = createValidator({
    type: 'object',
    properties: {
      username: {
        type: 'string',
        required: true
      }
    }
  })

  return (objToValidate) => {
    const context = validator.context(objToValidate)

    // Check if username is taken. This is async.
    return db.users.findWhere({ username: objToValidate.username })
      .then((user) => {
        if (!user) {
          context.errors.push({
            field: 'username',
            message: 'This username is taken!'
          })
        }

        // .end() will do the same as calling
        // validator(obj) directly: sanitize and return the object
        // if successful, throw if not.
        return context.end()
      })
  }
}

// Create our validator..
const myAwesomeValidator = createMyAwesomeValidator(someDbModule)<commit_msg>Added shortcut example.<commit_after># skadi

[![npm version](https://badge.fury.io/js/skadi.svg)](https://badge.fury.io/js/skadi)
[![Dependency Status](https://david-dm.org/jeffijoe/skadi.svg)](https://david-dm.org/jeffijoe/skadi)
[![devDependency Status](https://david-dm.org/jeffijoe/skadi/dev-status.svg)](https://david-dm.org/jeffijoe/skadi#info=devDependencies)
[![Build Status](https://travis-ci.org/jeffijoe/skadi.svg?branch=master)](https://travis-ci.org/jeffijoe/skadi)
[![Coverage Status](https://coveralls.io/repos/github/jeffijoe/skadi/badge.svg?branch=master)](https://coveralls.io/github/jeffijoe/skadi?branch=master)
[![Code Climate](https://codeclimate.com/github/jeffijoe/skadi/badges/gpa.svg)](https://codeclimate.com/github/jeffijoe/skadi)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)

A simple object validator/sanitizer based on `is-my-json-valid`.

# Installation

```bash
npm install skadi --save
```

# Usage

```javascript
// Import
const { createValidator, ValidationError } = require('skadi')

// Create a validator using a JSON-schema.
const myValidator = createValidator({
  type: 'object',
  additionalProperties: false,
  properties: {
    name: {
      type: 'string',
      required: true
    }
  }
})

// Use it
const input = {
  name: 'Test',
  otherStuffThatIsNotRelevant: 'hehe'
}

const result = myValidator(input)
// << { name: 'Test' }
```

When used like above, validation errors will throw.

```javascript
try {
  myValidator({ anInvalid: 'object', because: 'it has no name' })
} catch (err) {
  console.log(err instanceof ValidationError) // << true
  console.log(err.errors) // << [{ field: 'name', message: 'is required' }]
}

```

Alternative usage:

```javascript
const context = myValidator.context({ })
console.log(context.valid()) // << false
console.log(context.errors) // << [{ field: 'name', message: 'is required' }]

const anotherContext = myValidator.context({ name: 'Skadi', other: 'stuff' })
console.log(anotherContext.valid()) // << true
console.log(anotherContext.pick()) // << { name: 'Skadi' }

// We can add errors manually..
anotherContext.errors.push({ field: 'name', message: 'Too cool, man' })
console.log(anotherContext.valid()) // << false
```

# Use Case: custom, async validation.

Because you can add errors manually, custom validation becomes easy (JSON-schema does not allow this).

Here's an example that makes the validator async.

```javascript
// Factory function that returns a validator.
// It takes a db so we can look up a user.
function createMyAwesomeValidator(db) {
  const validator = createValidator({
    type: 'object',
    properties: {
      username: 'string!' // shortcut, see https://github.com/yanick/json-schema-shorthand#required-property
    }
  })

  return (objToValidate) => {
    const context = validator.context(objToValidate)

    // Check if username is taken. This is async.
    return db.users.findWhere({ username: objToValidate.username })
      .then((user) => {
        if (!user) {
          context.errors.push({
            field: 'username',
            message: 'This username is taken!'
          })
        }

        // .end() will do the same as calling
        // validator(obj) directly: sanitize and return the object
        // if successful, throw if not.
        return context.end()
      })
  }
}

// Create our validator..
const myAwesomeValidator = createMyAwesomeValidator(someDbModule)
{'fraction_non_alphanumeric': 0.15903197925669835, 'fraction_numerical': 0.0005762028233938346, 'mean_word_length': 3.6754208754208753, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 7, 'https://': 27, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1477230', 'n_tokens_mistral': 2270, 'n_tokens_neox': 2188, 'n_words': 507}