@ts-awesome/validate
v1.5.1
Published
TypeScript friendly minimalistic validation library
Downloads
405
Readme
@ts-awesome/validate
TypeScript friendly minimalistic validation library
This library inspired by validate.js. Kudos to ansman for great work!
Key features:
- simplistic validator
- model validation
- reactive validation
Bare use
import {singe, presence, email} from "@ts-awesome/validate";
const input: string;
const result = single(input, presence(), email());
if (result !== true) {
console.log(input, 'is invalid:', ...result);
}
Let's check a form
import {multi, presence, email, alphaNum, password} from "@ts-awesome/validate";
const input: Record<string, unknown>;
const schema = {
username: [presence(), alphaNum()],
email: [presence(), email()],
password: [presence(), password()],
}
const result = multi(input, schema);
if (result !== true) {
console.log('input is invalid:', ...result);
}
For more control over validation format please check validate
utility.
Use with IoC
Single value validator
import {Container} from "inversify";
import {
SingleValidator,
IValidator,
presence,
email,
uuid,
} from "@ts-awesome/validate";
container
.bind<IValidator<string>>(ValidatorSymbol)
.toConstantValue(new SingleValidator(presence(), email()))
.whenTargetNamed('email');
container
.bind<IValidator<string>>(ValidatorSymbol)
.toConstantValue(new SingleValidator(presence(), uuid()))
.whenTargetNamed('uuid');
Model validator
import {Container} from "inversify";
import {
ModelValidator,
IValidator,
presence,
email,
password,
alphaNum,
validate
} from "@ts-awesome/validate";
class Model {
@validate([presence(), alphaNum()])
username!: string;
@validate([presence(), email()])
email!: string;
@validate([presence(), password()])
password!: string;
}
container
.bind<IValidator<Model>>(ValidatorSymbolFor(Model))
.toConstantValue(new ModelValidator(Model));
ValidateAutomate
For reactive environments there is a need for continuous validation. ValidateAutomate comes to resque.
import {ValidateAutomate, validate} from "@ts-awesome/validate";
class Model {
@validate('Username', [presence(), alphaNum()])
username!: string;
@validate('E-mail', [presence(), email()])
email!: string;
@validate('Password', [presence(), password()])
password!: string;
}
const automate = new ValidateAutomate(Model);
automate.values.username // current entered value
automate.errors.username // current error or undefined
automate.update.username('new value'); // update value and re-validate
// partial update and validate
automate.update({
username: 'else',
email: 'wrong'
});
automate.attempted // true if automate.validate() was tried
automate.valid // if currently everything is valid
automate.global // any global error
automate.set(true, 'some global error'); // set global error
automate.clear(true); // clear global error
automate.set('username', 'custom error'); // set error for username
automate.clear('username'); // clear errors for username
automate.reset(); // reset all errors and attempted
const model = automate.read(); // read model if this.validate() === true
Use with MobX
import { ValidateAutomate } from "@ts-awesome/validate"
import { makeAutoObservable, observable } from "mobx"
declare type Class<T> = new (...args: unknown[]) => T;
export class ObservableValidateAutomate<T> extends ValidateAutomate<T> {
constructor(model: Class<T>, onInit?: () => void) {
super(model, onInit)
makeObservable(this, {
_state: observable.deep,
_errors: observable.deep,
_attempted: observable,
_global: observable,
_runInAction: action,
set: action,
clear: action,
reset: action,
values: computed,
errors: computed,
} as never)
}
}
Available validator factories
alphaNum
- checks if provide value has no special chars: !@#$%^&*(),.?":{}|<>]array
- checks array, length and element constraints can be specifiedboolean
- checks boolean valuesdatetime
- checks timestampsdate
- checks datestime
- checks timeemail
- checks emailformat
- checks regexlength
- checks value.length, works on anything with lengthmodel
- checks value to comply with model constraintsnotNull
- check for !== nullnumericality
- checks numberspassword
- checks passwords, also exportsisStrongPassword
andgetPasswordComplexity
utilitiespresence
- checks for !== undefinedprimary
- obsoleterequired
- obsoletetype
- checks value typeurl
- checks urluuid
- checks uuidexclusion
- checks against blacklist, rejects if on the listinclusion
- checks against whitelist, accepts if on the list
Please note that validator factory return configured validator that can be used
as standalone validator. Keep in mind that validator return undefined
if valid
or string with error.
import {numericality} from "@ts-awesome/validate";
const validator = numericality({onlyInteger: true, greaterThan: 5, even: true});
const valid = validator(7);
Custom validators
Validator is a function that follows interface.
interface Validator<T = unknown> {
(
value: T, // value to examine
key: string, // attribute name where value is stored
attributes: Readonly<Record<string, unknown>>, // all attributes
globalOptions: Readonly<GlobalOptions>
): undefined | true | string | readonly string[];
}
It should return undefined
or null
or true
if valid.
It should return error as string
or readonly string[]
.
Let's create a validator that checks if password and passwordRepeat are equal
import {Validator} from "@ts-awesome/validate";
import {isDefined, error, passoword, validate} from "@ts-awesome/validate/dist/validators/utils";
function equalTo<T>(field: keyof T): Validator<unknown> {
return function EqualToValidator(value, key, attributes) {
if (!isDefined(value))
return;
if (value !== attributes[field]) {
return "must be a same as " + field;
}
}
}
class Model {
@validate([presence(), password()])
password!: string;
@validate('Password Repeat', [presence(), equalTo<Model>('password')])
passwordRepeat!: string;
}
License
May be freely distributed under the MIT license.
Copyright (c) 2022 Volodymyr Iatsyshyn and other contributors