1. pruf

pruf

pruf

Framework agnostic validation library in JavaScript

npm NPM Lines

Installation

 npm i --save pruf

Use

Import validate to validate objects by a set of rules

 import { validate, required, between, reporter } from "pruf";

const data = {
  name: "",
  data: { age: 14 },
  zip: 500,
};

const rule = {
  name: {
    required,
  },
  data: {
    age: {
      required,
      over16: (value) => value > 16,
    },
  },
  zip: {
    required: reporter(required, "Please enter ZIP"),
    between: reporter(between(999, 10000), "Invalid ZIP"),
  },
};

const result = validate(rule, data);

the validation results in a new object with valid-keys corresponding to the validations done.

 const result = {
  valid: false,
  name: {
    valid: false,
    required: false,
  },
  data: {
    valid: false,
    age: {
      valid: false,
      required: true,
      over16: false,
    },
  },
  zip: {
    valid: false,
    required: { valid: true },
    between: { valid: false, error: "Invalid ZIP" },
  },
};

Validation · validate()

Pruf provides you a simple way to validate data by a set of rules.

With validate(rule, data, options?) you validate an object data by a set of rules provided in a rule object. With an options object you can control some additional behaviour.

Set of rule · rule

The validation follows this set of rules. If a value in the rule object is a function this will be used as the validator for the corresponding data.
The return will have the same structure as the rule.

 const rule = {
  name: {
    required,
  },
  data: {
    age: {
      required,
      over16: (value) => value > 16,
    },
  },
  zip: {
    valid: false,
    required: { valid: true },
    between: { valid: false, error: "Invalid ZIP" },
  },
};

Data · data

Any kind of object. Including deeply nested objects.

 const data = {
  name: "",
  data: { age: 14 },
  zip: 500,
};

Options · options

Key validKey

string? — default: valid
The name of the key generated during validation.

Key includeKey

string? — default: include
The name of the key to detect groups during validation.

Key visitor

object? — default:

 {
  isValidator: ({ value }) => typeof value === "function",
  validate: ({ validator, data, parent, root }) => validator(data, { parent, root }),
}

A custom visitor (walker) can be defined to adjust the default behaviour to recognise validators and to validate the corresponding values.

 const rule = {
  name: {
    isTruthy: true,
  },
  age: {
    isFalsy: false,
  },
};
const data = {
  name: "Hello",
  age: null,
};

const visitor = {
  isValidator: ({ value }) => value === true || value === false,
  validate: ({ validator, data }) => {
    return validator === false ? !!data === false : !!data === true;
  },
};

const result = validate(rule, data, { visitor });

The visitor detects a validator by the boolean return of a function in the key isValidator.
The validation in the key validate can return a boolean or an object. If the return is an object the the key valid must be present (corresponding to validKey) .

 const result = {
  valid: true,
  name: {
    valid: true,
    isTruthy: true,
  },
  age: {
    valid: true,
    isFalsy: true,
  },
};

Return value · return

The result of the function returns a new object where each object will have a valid-key with the result of the validation of the values and sub-values. Each validator will leave a key in the object.

 const result = {
  valid: false,
  name: {
    valid: false,
    required: false,
  },
  data: {
    valid: false,
    age: {
      valid: false,
      required: true,
      over16: false,
    },
  },
  zip: {
    valid: false,
    required: { valid: true },
    between: { valid: false, error: "Invalid ZIP" },
  },
};

Validators

pruf comes with some often used validation functions.

Helper Parameters Description
required Checks if a value is given. Falsy values are evaluated true.
required([]) === true
required(0) === true
required(false) === true
between min, max Checks if a number is between min and max. Min and max are not included.

Validation messages · reporter

If an error-message on the result object is needed a helper function reporter is provided. The reporter transforms a validator result to a object with the message in an error key and a key valid with the result of the validator.

 import { validate, required, between, reporter } from "pruf";

const data = {
  zip: 500,
};

const rule = {
  zip: {
    required: required,
    between: reporter(between(999, 10000), "Invalid ZIP"),
  },
};

const result = validate(rule, data);
 const result = {
  zip: {
    valid: false,
    required: true,
    between: { valid: false, error: "Invalid ZIP" },
  },
};

Custom validators

Custom validations can be defined by adding simple functions:

 const isPruf = (value) => value === "pruf";

The validation can then be used like all other checks:

 const rule = {
  dataYeah: { required, isPruf },
  dataNo: { required, isPruf },
};

The first parameter to the validator is the value to validate. As second parameter is an object with keys parent and root.

 const isAllPruf = (value, { parent, root }) =>
  value === "pruf" && parent.test === "pruf" && root.test === "pruf";

Grouping

Sometimes it's useful to have validations grouped. This can be achieved if the key include is set with an array of include paths.

 const rule = {
  name: {
    firsName: {
      required,
    },
  },
  age: {
    required,
  },
  person: {
    include: ["name.firsName", "age"], // ← 💫 includes
  },
};
 const result = {
  valid: false,
  name: {
    valid: false,
    firsName: {
      valid: true,
      required: true,
    },
  },
  age: {
    valid: false,
    required: false,
  },
  person: {
    valid: false,
    "name.firsName": {
      valid: true,
      required: true,
    },
    age: {
      valid: false,
      required: false,
    },
  },
};

Credits

pruf is inspred by projects like vuelidate, formik and many others.

License & Authors

MIT · Started by signalwerk supported by contributors

Breaking changes

Version 2.x

The second argument for custom validators is now an object.

 // Verson 1.x
const isPruf = (value, parent) => value === "pruf";

// Verson 2.x
const isPruf = (value, { parent, root }) => value === "pruf";