0.0.2 • Published 3 months ago

@modulify/validator v0.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

@modulify/validator

codecov Tests Status npm version

This library provides a declarative validation util.

The util does not provide any text messages in the constraints produced and gives only metadata that can be used to create a custom view for them.

Installation

Using yarn:

yarn add @modulify/validator

or, using npm:

npm install @modulify/validator --save

Usage

import {
  Collection,
  Exists,
  Length,
  createValidator,
} from '@modulify/validator'

const validator = createValidator()

const violations = validator.validate({
  form: {
    nickname: '',
    password: '',
  },
}, new Collection({
  form: [
    new Exists(),
    new Collection({
      nickname: new Length({ min: 4 }),
      password: new Length({ min: 6 }),
    }),
  ],
}), /* do not set or set to true for async validation */ false) /* [{
  by: '@modulify/validator/Length',
  value: '',
  path: ['form', 'nickname'],
  reason: 'min',
  meta: 4,
}, {
  by: '@modulify/validator/Length',
  value: '',
  path: ['form', 'password'],
  reason: 'min',
  meta: 6,
}] */

Constraints

Constraints provide information of how the value should be validated.

Available from the box:

  • Collection used for validating objects' structure;
  • Each used for validating arrays' elements; applies specified constraints to each element of an array;
  • Exists used for checking if a value is defined; useful for finding missing keys;
  • Length used for checking arrays' and string's length, available settings (all optional) are:
    • exact number, array or string should have exactly specified count of elements or characters;
    • max number, maximum elements in array or maximum characters in string;
    • min number, minimum elements in array or minimum characters in string;
  • OneOf used for restricting which values can be used.

There is no any basic constraint class to extend, but they should follow signature described in types/index.d.ts Constraint.

Validators

Validators provide validation logic that relies on information provided by constraints.

There is no any basic validator class to extend, but they should follow signature described in types/index.d.ts ConstraintValidator.

Provider

Provider is used to bind constraints with their validators, provides a validator for a constraint.

All providers should follow signature described in types/index.d.ts Provider.

This feature is responsible for extending validation capabilities. Custom provider can be passed into createValidator function or override method of Validator instance.

There is a built-in provider ProviderChain. It allows to "chain" providers if suitable validator was not found in currently used provider, it will try to find it in previous provider that was overridden by override method.

import type {
  Constraint,
  ConstraintValidator,
  ConstraintViolation,
  Key,
  Provider,
} from '@modulify/validator'

import {
  ProviderChain,
  createValidator,
} from '@modulify/validator'

class Email implements Constraint {
  public readonly name = '@app/validator/Email'

  toViolation (value: unknown, path: Key[]): ConstraintViolation {
    return {
      by: this.name,
      value,
      path,
    }
  }
}

class EmailValidator implements ConstraintValidator {
  private readonly _constraint: Email

  constructor (constraint: Email) {
    this._constraint = constraint
  }

  validate (value: unknown, path?: Key[]): ConstraintViolation | null {
    if (!(typeof value === 'string') || !/\S+@\S+\.\S+/.test(value)) {
      return this._constraint.toViolation(value, path)
    }

    return null
  }
}

then

const provider = new ProviderChain(new class implements Provider {
  get (constraint: Constraint) {
    return constraint instanceof Email ? new EmailValidator(constraint) : null
  }

  override (provider: Provider): Provider {
    return new ProviderChain(provider, this)
  }
})

or

const provider = new class implements Provider {
  get (constraint: Constraint) {
    return constraint instanceof Email ? new EmailValidator(constraint) : null
  }

  override (provider: Provider): Provider {
    return new ProviderChain(provider, this)
  }
}

and then

const validator = createValidator(provider)

or

const validator = createValidator()
const overridden = validator.override(provider) // it creates new validator instance, so validator !== overridden
0.0.2

3 months ago

0.0.1

3 months ago