Code Monkey home page Code Monkey logo

d8a's Introduction

d8a

Data validation library.

Install

npm i d8a

Spec

These are the built in validations:

// Write a spec with specified fields, here for 'name'
{
  name: {
    required: true,  // Value must be defined
    eq: 5,           // Equal to, default
    ne: 5,           // Not equal to
    gt: 5,           // Greater than
    lt: 5,           // Less than
    gte: 5,          // Greater than or equal to
    lte: 5,          // Less than or equal to
    in: [1, 2, 3],   // Must be in list
    nin: [1, 2, 3],  // Must not be in list
    length: 5,       // Length of string must be
    min: 5,          // Minimum length of string
    max: 5,          // Maximum length of string
    match: /regex/,  // Must match regex
    matcher: async function(val, opt) {
      // Validation fails on truthy value
      if (!val) {
        return 'val is not found'
      }
      // Return nothing or undefined to pass
    },
    is: 'boolean',  // Must be true or false
    is: 'string',   // Must be a string
    is: 'number',   // Must be a number, integer or decimal (float)
    is: 'integer',  // Must be an integer
    is: 'decimal',  // Must be a decimal number
    is: 'date',     // Must be a date
    is: 'id',       // Must be an id
    is: 'object',   // Must be an object
    is: 'array',    // Must an array
    is: 'email',    // Must be an email address
    is: 'url'       // Must be a URL
    is: 'slug'      // Must be a slug
    is: 'domain'    // Must be a domain
    is: 'undefined' // Must be undefined
    is: 'null'      // Must be null

    // Can have multiple types
    is: ['string', 'number']

    // isnt is the opposite of is
    isnt: 'null'    // Must not be null
  }
}

Validate

const { validate } = require('d8a')

let spec = {
  val: {
    required: true
  }
}
let data = {
  val: 'hello'
}
let opt = {}
let error = await validate(spec, data, opt)

// Returns null if no errors found
if (error === null) {
  console.log('No errors')
} else {
  console.log(error.val)
  // Prints: ['is required']) if val is not defined
}

Options

The third parameter to the validate function are the options:

validate({}, {}, {

  // Language used for locales
  // default is 'en' (English)
  lang: 'en',

  // Skip the validation if the value is undefined
  // default is false
  lax: false,

  // Custom translate function
  t: async function(key, ...args) {},

  // Custom locales, example
  locales: {
    en: {
      validation: {
        unique: 'must be unique'
      }
    }
  }
})

Extension function

You can extend the validations with your own validator functions:

// Write a validator function
async function unique({
  spec,
  data,
  opt,
  lang,
  t,
  errors,
  add,
  field,
  type,
  want, // the value we want
  got   // the value of the data
}) {
  // Example:
  add(field, 'must be unique')
}

// Create ext object for option
const ext = {
  unique: {
    type: 'bool', // The accepted value type for this function
    fn: unique
  }
}

// Pass ext option
const error = await validate({}, {}, { ext })

Locales

The default locales are found here:

const { locales } = require('d8a')

They look like this:

// Default locale translations
{
  en: {
    validation: {
      required: 'is required',
      eq: 'must be equal to %s',
      ne: 'must not be equal to %s',
      gt: 'must be greater than %s',
      lt: 'must be less than %s',
      gte: 'must be greater than or equal to %s',
      lte: 'must be less than or equal to %s',
      in: 'must be one of %s',
      nin: 'must not be one of %s',
      length: 'length must be %s',
      min: 'minimum length is %s',
      max: 'maximum length is %s',
      match: "must match '%s'",
      is: "must be %s",
      isnt: "must not be %s",
      boolean: 'boolean',
      string: 'string',
      number: 'number',
      integer: 'integer',
      decimal: 'decimal',
      date: 'date',
      id: 'id',
      object: 'object',
      array: 'array',
      email: 'email',
      url: 'URL',
      undefined: 'undefined',
      null: 'null'
    }
  }
}

You can add your own locales and translation function like this:

const myLocales = {
  en: {
    validation: {
      required: 'must be included'
    }
  }
}

function translate(key, ...args) {
  return myLocales[key] || key
}

let spec = {}, data = {}
const error = await validate(spec, data, { t: translate })

If you need custom error messages for a certain field, you can do it by adding an object as value that looks like this:

const spec = {
  email: {
    required: {
      $val: true,
      message: 'must be custom'
    }
  }
}

MIT Licensed. Enjoy!

d8a's People

Contributors

acmb avatar eldoy avatar

Stargazers

 avatar

Watchers

 avatar  avatar

d8a's Issues

Multiple types

Support for array in is for allowing multiple types:

is: ['string', 'number']

Are some of them incompatible maybe?

isnt

Should there be an isnt validator? Which is the opposite of is?

$name.isnt: undefined

Alias for boolean and haka

I haka the field is called 'bool', but in d8a it is called 'boolean'. We should create an alias for 'boolean' called 'bool' so it's the same.

Multiple validations

What if we need multiple in for example?

in: [1, 2, 3],
in: [6, 7, 8]

Could we do this?

in: [
  [1, 2, 3],
  [6, 7, 8]
]

or higher up?

values: {
  name: {
    in: [1, 2, 3]
  }
}

becomes

values: {
  name: [
    { in: [1, 2, 3] },
    { in: [5, 6, 7] }
  ]
}

?

Is this getting out of hand? Need a new syntax alltogether?

exist validator

This is common:

matcher: async function(schema_id, $) {
          const count = await $.db('schema').count({ id: schema_id })
          if (!count) {
            return 'schema does not exist'
          }

Can we have this instead?

exist: 'schema'

'does not exist'

Required true in strict mode

Now strict mode just ignores required: true, but what if we just want to make sure a value is defined? required: true in strict mode could be used for that.

Rename validators

Less writing is faster, more fun.

required > has or just 'be'
matcher > something shorter, run maybe? match? or use 'be' for this?
match > test, pattern, format?

so,
required > has
matcher > be
match > keep it

alternative:
is > be
required > is
matcher > has?

Or type?

is > type
matcher > is
required > has?

ignore > skipif? or breakon? unless?

A few enhancements

  1. eq to assert deepEqual? or exact validator?
  2. tests for nested data, including [0] syntax for arrays
  3. eq default?
error.message: validation error

same as

error.message:
  eq: validation error

Use types for validations

Types have been added, but are not currently in use. Could be used for automatically validating the type? Option or default?

Could have extra types + compound types?

possible new types:

is: 'array > string', array > number' string array, number array
is: 'string|number' > string or number

ignore

Sometimes we need to ignore if empty:

preview: {
  match: $.tools.regexp.subdomain
}

This works great if we have a value, but if we want to set it to an empty string then it we don't want it to kick in.

Can we have something like this?

preview: {
  ignore: '',
  ignore: 5,
  ignore: [0, '0', null], // ignore if the value is one of these
  match: $.tools.regexp.subdomain
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.