@n7e/validation
TypeScript icon, indicating that this package has built-in type declarations

0.1.0 • Public • Published

Validation

An extensible object validation library.

For further insights, read on.

Installation

To install this library use your favorite package manager. No additional steps are required to start using the library.

npm install @n7e/validation

This library is implemented in TypeScript but can be used with JavaScript without any additional steps.

Validator

The protagonist of this library is the validator. Validators lets you validate arbitrary objects against a set of provided rules. All validators implement the Validator interface. To reference it simply import it and use it as a type.

import { Validator } from "@n7e/validation";

function doSomethingWith(validator: Validator): void {
    // ...
}

Validator is just an interface describing the functionality of a validator. To create validators use a validator factory or validator builder.

To validate an object use the validate method:

const rules = {
    key: "present"
};

validator.validate({key: "value"}, rules);

The rules follow a defined format.

If the object is valid according to all the provided rules nothing happens. However, if one or more rules are broken an Issues error is thrown. Depending on the validation strategy being used the error contains all or some of the broken rules with a short description of each issue.

To make things easy the Issues error provides an easy-to-read format when serialized to JSON:

{
    "key": [
        "Must be present"
    ]
}

Validation Strategy

When validating an object one or more properties may break the given rules. Whether the validator continues to check for additional issues and issues on additional properties is defined by a ValidationStrategy.

A validation strategy can be passed to the validate() method when invoked. You can also configure a validators default validation strategy using a validator builder.

The available validation strategies are:

ValidationStrategy.STOP_AT_FIRST_INVALID_RULE
Throws an exception at the first failed rule.
ValidationStrategy.STOP_AT_FIRST_INVALID_PROPERTY
Validates all rules for a property before throwing an exception if any of them failed.
ValidationStrategy.RUN_ALL_RULES
Runs all rules for all properties and throws an exception if any of them failed.

Validator Factory

To create a pre-configured validator instance you should use a ValidatorFactory.

import type { ValidatorFactory } from "@n7e/validation";

function someFunction(validatorFactory: ValidatorFactory): void {
    const validator = validatorFactory.createValidator();
    
    // ...
}

ValidatorFactory is just an interface describing the functionality of a validation factory. To create a validator factory instance you need to reference a specific implementation.

Default Validator Factory

There's a provided default validator factory that creates a validator instance with all available rules.

import { DefaultValidatorFactory } from "@n7e/validation";

const validator = new DefaultValidatorFactory().createValidator();

Validator Builder

To configure and build a custom validator instance you should use a ValidatorBuilder.

import { ValidationStrategy } from "@n7e/validation";

validatorBuilder
    .withRule(new SomeCustomRule())
    .withRule("custom-rule", (value, parameters) => {})
    .withDefaultStrategy(ValidationStrategy.STOP_AT_FIRST_INVALID_RULE);

A validator builder can be passed around and incrementally augmented to eventually produce a desired validator.

const validator = validatorBuilder.build();

ValidatorBuilder is just an interface describing the functionality of a validation builder. To create a validator builder instance you need to reference a specific implementation.

Default Validator Builder

There's a provided implementation of ValidatorBuilder ready to use.

import { DefaultValidatorBuilder } from "@n7e/validation";

const validatorBuilder = new DefaultValidatorBuilder();

// Add any desired rules and other configuration...

const validator = validatorBuilder.build();

Rules

A rule is a single property criteria that must be adhered to. The simplest example is the present rule that ensures that the property exists on the object being validated.

Rule Format

To define the rules a property needs to adhere to a defined format needs to be followed:

           "type:string,array"
             ^        ^
             |        |
      Rule identifier |
                      |
              Optional parameters

Any whitespace around rule parameters is trimmed.

Rules are separated by a single | character. Here are some examples:

Single rule without parameters
"present"
Multiple rules without parameters
"present|numeric"
Single rule with a parameter
"type:string"
Single rule with multiple parameters
"type:string,array,date"
Multiple rules with parameters
"present|type:string,array|min:5"

Available Rules

There's a provided set of available validation rules. Validators created with the default validator factory will include all available validation rules.

Present

Verifies that a property is present.

// This will fail.
validator.validate({}, {key: "present"});

If a property is absent only the present rule will be checked so this will pass:

validator.validate({}, {key: "numeric"});

Type

Verifies that values are of a certain type.

// This will pass.
validator.validate({key: "value"}, {key: "type:string"});

The type can be any of the possible JavaScript typeof values:

  • string
  • number
  • object
  • function
  • undefined
  • boolean
  • symbol
  • bigint

Or any from the extended list below:

  • array
  • date
  • null

Pass multiple types to verify that the value is one of many possible types:

// This will pass.
validator.validate({key: "value"}, {key: "type:array,boolean,string"});

Numeric

Verifies that values are numeric.

// This will pass.
validator.validate({key: "5"}, {key: "numeric"});

Min

Verifies that values are at least a given value.

// This will pass.
validator.validate({key: 5}, {key: "min:5"});

If the value is a string, a collection (array, set, map etc. basically any object with a length or size property) or an iterator the size of the value will be compared to the minimum value. In any other case the value will be compared as is.

// This will fail since the length of the string is 1.
validator.validate({key: "7"}, {key: "min:5"});

Max

Verifies that values are at most a given value.

// This will pass.
validator.validate({key: 5}, {key: "max:5"});

If the value is a string, a collection (array, set, map etc. basically any object with a length or size property) or an iterator the size of the value will be compared to the minimum value. In any other case the value will be compared as is.

// This will pass since the length of the string is 1.
validator.validate({key: "7"}, {key: "max:5"});

UUID

Verifies that values are UUIDs.

// This will pass.
validator.validate({key: "00000000-0000-0000-0000-000000000000"}, {key: "uuid"});

This rule accepts nil UUIDs.

Custom Rules

You can easily add your own rules and use them using the defined format. To do so either create a rule class or a rule function and register it using a validator builder.

Rule Class

Create a class that implements the Rule interface (This will work with JavaScript as well, just omit the types):

class CustomRule implements Rule {
    public readonly identifier = "custom-rule";
    
    public check(value: unknown, parameters: Array<string>): void {
        // If the value is invalid throw an Issue error with a short description
        // of the issue, otherwise do nothing.
    }
}

To make it available to the validator register the rule using a validator builder:

const validator = validatorBuilder
    .withRule(new CustomRule())
    .build();

validator.validate({}, {key: "custom-rule"});

Rule Function

Provide an identifier and a function to a validator builder to make the rule available to the validator:

const validator = validatorBuilder
    .withRule("custom-rule", (value, parameters) => {
        // If the value is invalid throw an Issue error with a short description
        // of the issue, otherwise do nothing.
    })
    .build();

validator.validate({}, {key: "custom-rule"});

Readme

Keywords

Package Sidebar

Install

npm i @n7e/validation

Weekly Downloads

1

Version

0.1.0

License

MIT

Unpacked Size

54.9 kB

Total Files

65

Last publish

Collaborators

  • martin-n7e