- v1.11.2Latest
- v1.11.1
- v1.11.0
- v1.10.2
- v1.10.1
- v1.10.0
- v1.9.0
- v1.8.0
- v1.6.0
- v1.5.1
- v1.5.0
- v1.3.3
- v1.1.0
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v1.0.0-alpha.6
- v1.0.0-alpha.5
- v1.0.0-alpha.4
- v1.0.0-alpha.3
- v1.0.0-alpha.2
- v1.0.0-alpha.1
- v1.0.0-alpha
- v0.3.1
- v0.3.0
- v0.2.6
- v0.2.5
- v0.2.4
- v0.2.3
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.2
- v0.1.1
- v0.1.0
- v0.0.0
🦩 Funval
A minimalist library for data validation using functions interfaces.
Funval is a minimalist validation library that seamlessly integrates with your business logic. Using only plain functions, Funval knows how to validate your data and automatically generates TypeScript interfaces to reduce code duplications and complexity.
function ValidNumber(input: unknown): number {
const value = Number(input);
if (isNaN(value)) {
throw new TypeError('Invalid number');
}
return value;
}
Main Features
- Easy to Read - Uses functions as types (including
String
,Number
,Boolean
, etc…) - Reusable Interfaces - Create new validator using plain functions in seconds.
- TypeScript Validation - Detect errors during compile time.
- Function Composition - Pipe multiple validators to generate new ones.
- Asynchronous & Synchronous Support - Automatically detected promises.
- Pure Javascript - Also works without TypeScript.
Install
npm i funval
Usage
import { Schema, Optional, Or, Type, Integer, Between } from 'funval';
const UserSchema = {
name: Optional(String),
username: /^[a-z0-9]{3,10}$/,
status: Or('active' as 'active', 'suspended' as 'suspended'),
amount: input => Between(1, 50)(Integer(input)),
};
const validator = Schema(UserSchema);
let user: Type<typeof UserSchema>;
try {
user = validator({
username: 'john1',
// @ts-ignore Type '"unregistered"' is not assignable to type '"active" | "suspended"'.
status: 'unregistered',
amount: 20,
});
} catch (err) {
console.error(err.message, err.paths);
}
Creating Validators
A validator is any function that can return a value without throwing any exceptions:
import * as EmailValidator from 'email-validator';
function Email(input: string): string {
if (!EmailValidator.validate(input)) {
throw new TypeError(`Invalid email address: "${input}"`);
}
return input;
}
You can use the above validator on schemas as an Email
type:
const UserSchema = {
email: Email,
};
const validator = Schema(UserSchema);
Asynchronous Validators
Asynchronous validators are supported by returning a Promise
(or PromiseLike
) values:
import fetch from 'node-fetch';
async function AvailableUsername(input: string): Promise<string> {
const res = await fetch(`/check-username?username=${encodeURIComponent(input)}`);
if (!res.ok) {
throw new TypeError(`Username "${input}" is already taken`);
}
return input;
}
Funval automatically detects promise and convert the return type of the Validator
to promise as well:
const UserSchema = {
username: AvailableUsername,
};
const validator = Schema(UserSchema);
const user = await validator({ username: 'test' });
If you prefer, you can safely convert any validator to an asynchronous validator using the Async
helper:
import { Async, Schema } from 'funval';
const UserSchema = {
email: Email,
};
const validator = Async(Schema(UserSchema));
// will catch instead of throwing
validator({ email: 'invalid-email' }).catch(err => console.err(err));
Available Validators
All the available validators ordered by type:
Schema -
Schema
,Maybe
,Optional
,Default
,Required
,Truthy
,Or
,ArrayOf
,TypeOf
,Any
,Override
Test
Comparison -
Equals
,GreaterThan
,GreaterThanEqual
,LessThan
,LessThanEqual
,Between
Strings -
ContentString
,TrimString
StringRange
StringMatch
Booleans -
Bool
Schema
import { Schema } from 'funval';
declare function Schema(schema: any, error?: string | Error): Validator;
Validate inputs using the given schema.
Throws: If the input does not match the given schema.
Maybe
import { Maybe } from 'funval';
declare function Maybe(schema: any, error?: string | Error): Validator;
Same as Schema
but ignores undefined
or omitted inputs.
Throws: If the input tested and does not match the given schema.
Optional
import { Optional } from 'funval';
declare function Optional(schema: any, error?: string | Error): Validator;
Same as Schema
but ignores undefined
, null
or omitted inputs.
Throws: If the input tested and does not match the given schema.
Default
import { Default } from 'funval';
declare function Default(schema: any, value: any): Validator;
Validate inputs using the given schema or use the given value if input equals to undefined
or
omitted.
Throws: If the input tested and does not match the given schema.
Required
import { Required } from 'funval';
declare function Required(schema: any, error?: string | Error): Validator;
Validate inputs using the given schema.
Throws: If input is undefined
or does not match the given schema.
Truthy
import { Truthy } from 'funval';
declare function Truthy<T>(input: T): T;
Validate input is truthy.
Throws: If input is not truthy.
Or
import { Or } from 'funval';
declare function Or(...candidates: any[]): Validator;
Validate inputs using any of the given candidates.
Throws: If the input does not match to any of the given schemas.
ArrayOf
import { ArrayOf } from 'funval';
declare function ArrayOf(itemSchema: any, error?: string | Error): Validator;
Validate the input is an array and that each item matches the given schema.
Throws: If the given input is not an array or one of the items not matches the item schema.
TypeOf
import { TypeOf } from 'funval';
declare function TypeOf(
typeOf:
| 'string'
| 'number'
| 'object'
| 'boolean'
| 'undefined'
| 'symbol'
| 'bigint',
error?: string | Error,
): Validator;
Check the input type is equals to the given type.
Throws: If the input type is different from the given type.
Any
import { Any } from 'funval';
declare function Any(input: any): any;
Allow any type of input.
Throws: Never.
Override
import { Override } from 'funval';
declare function Override(value: any): Validator;
Override any input and returns the given value.
Throws: Never.
Test
import { Test } from 'funval';
declare function Test<T>(test: (input: T) => unknown, error?: string | Error): Validator;
Return the input value as is, only if the test function returns a truthy value.
Throws: If the test function throws or the test function return a non-truthy value.
Equals
import { Equals } from 'funval';
declare function Equals(value: any, error?: string | Error): Validator;
Check the input is strictly equals to the given value.
Throws: If the input does not equal to the given value.
GreaterThan
import { GreaterThan } from 'funval';
declare function GreaterThan(value: any, error?: string | Error): Validator;
Check the input is greater than the given value.
Throws: If the input does not greater than the given value.
GreaterThanEqual
import { GreaterThanEqual } from 'funval';
declare function GreaterThanEqual(value: any, error?: string | Error): Validator;
Check the input is greater than or equals the given value.
Throws: If the input does not greater than or equals the given value.
LessThan
import { LessThan } from 'funval';
declare function LessThan(value: any, error?: string | Error): Validator;
Check the input is less than the given value.
Throws: If the input does not less than the given value.
LessThanEqual
import { LessThanEqual } from 'funval';
declare function LessThanEqual(value: any, error?: string | Error): Validator;
Check the input is less than or equals the given value.
Throws: If the input does not less than or equals the given value.
Between
import { Between } from 'funval';
declare function Between(minValue: any | null, maxValue: any | null, error?: string | Error):
Validator;
Check the input is between the given boundaries.
Throws: If the input is not between the given boundaries.
ContentString
import { ContentString } from 'funval';
declare function ContentString(input: unknown): string;
Converts any input to a valid string.
Throws: If input is either null
, undefined
, an object without proper toString
implementation, empty or a whitespace string.
TrimString
import { TrimString } from 'funval';
declare function TrimString(input: unknown): string;
Same as ContentString
, but trim
the output as well.
Throws: If input is either null
, undefined
, an object without proper toString
implementation, empty or a whitespace string.
StringRange
import { StringRange } from 'funval';
declare function StringRange(
minLength: number | null,
maxLength: number | null,
error?: string | Error,
): Validator;
Converts any input to a valid string and make sure the string is in the given boundaries.
Throws: If input is either null
, undefined
, an object without proper toString
implementation, empty string, whitespace string, or string outside of the given boundaries.
StringMatch
import { StringMatch } from 'funval';
declare function StringMatch(regex: RegEx, error?: string | Error): Validator;
Validate the input is matches the given regular expression.
Throws: If input does not match the given regular expression.
Float
import { Float } from 'funval';
declare function Float(input: unknown): number;
Converts any input to a valid float number.
Throws: If the input can not convert to a valid number.
Integer
import { Integer } from 'funval';
declare function Integer(input: unknown): number;
Converts any input to a valid integer number.
Throws: If the input can not convert to a valid number or the number is not an integer.
Bool
import { Bool } from 'funval';
declare function Bool(input: unknown): boolean;
Converts any input to a valid boolean.
Throws: If the input can not convert unambiguously to a boolean.