Package Exports
- safen
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (safen) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Safen
Super Fast Complex Object Validator for Javascript(& Typescript).
Install
npm install safen --save
Usage
Import,
import * as safen from "safen"
// or
const safen = require("safen")
then,
const validator = safen.create({
"username": "(string & email & length_between:12,100) | null",
"password?": "string & length_between:8,20",
"areas[1:]": {
lat: "number & between:-90,90",
lng: "number & between:-180,180",
},
"env": {
referer: "url",
ip: "ip:v4",
os: {
name: "in:window,osx,android,iphone",
version: "string",
},
browser: {
name: "in:chrome,firefox,edge,ie",
version: "string",
},
},
})
validator.assert({
username: "corgidisco@gmail.com",
areas: [
{lat: 0, lng: 0},
],
env: {
referer: "http://corgidisco.github.io",
ip: "127.0.0.1",
os: {
name: "osx",
version: "10.13.1",
},
browser: {
name: "chrome",
version: "62.0.3202.94",
},
},
}) // ok
There are two method in Safen, named validate
, assert
. validate
is return boolean, assert
occure Exception.
const validator = safen.create("(string & email & length_between:12,100) | null")
// validate method
expect(validator.validate("corgidisco@gmail.com")).toBeTruthy()
expect(validator.validate(null)).toBeTruthy()
expect(validator.validate("corgidisco")).toBeFalsy() // return false!!!
// assert method
validator.assert("corgidisco@gmail.com") // safe
validator.assert(null) // safe
try {
validator.assert("corgidisco") // // not safe!
} catch (e) {
expect(e).toBeInstanceOf(safen.InvalidValueError)
}
Support Validators
Type
Validator | Description |
---|---|
bool | check if it is a boolean (alias to boolean ). |
boolean | check if it is a boolean . |
float | check if it is a float . |
int | check if it is a integer (alias to integer ). |
integer | check if it is a integer . |
number | check if it is a number . |
null | check if it is a null . |
string | check if it is a string . |
symbol | check if it is a symbol . |
Validator | Description | Example |
---|---|---|
afte:{date = now} | check if the string is a date that's after the specified date. |
after , after:"2017-10-01" , after:"2017-10-01 14:30:00" |
alpha | check if the string contains only letters([a-zA-Z]). |
alpha |
alphanum | check if the string contains only letters and numbers([a-zA-Z0-9]) |
alphanum |
always_false | return always false, for debugging. | always_false |
always_true | return always true, for debugging. | always_true |
ascii | check if the string contains only ascii characters. |
ascii |
base64 | check if the string is Base64. |
base64 |
before:{date = now} | check if the string is a date that's before the specified date. |
before:2017-10-01 , before:2017-10-01 14:30:00 |
between:{min},{max} | check if the value(string , number ) is between {min} and {max} . |
between:aaa,zzz , between:1,100 |
creditcard | check if the string is valid Credit Card number. cf. 0000-0000-0000-0000 |
creditcard |
date | check if the string is valid Date string(RFC2822, ISO8601). cf. 2018-12-25 , 12/25/2018 , Dec 25, 2018 |
date |
check if the string is valid E-mail string. |
email |
|
finite | check if the number is not NaN , Infinity , -Infinity . |
finite |
hexcolor | check if the string is valid Hex Color string. cf. #ffffff |
hexcolor |
in:{...params} | check if the value(any ) is in an array {params} . |
in:1,2,3 , in:safari,edge,firefox,"other browser" |
ip:{version = all} | check if the string is valid UUID.version is one of all (default), v4 , and v6 . |
ip , ip:v4 , ip:v6 |
json | check if the string is valid JSON. |
json |
jwt | check if the string is valid JWT. |
jwt |
length:{size} | check if the value(string )'s length is {size} . |
length:16 |
length_between:{min},{max} | check if the value(string )'s length is between {min} and {max} . |
length_between:4,20 |
length_max:{max} | check if the value(string )'s length is less than {max} . |
length_max:20 |
length_min:{min} | check if the value(string )'s length is greater than {min} . |
length_min:4 |
lowercase | check if the string is lowercase. |
lowercase |
macaddress | check if the string is valid Mac Address. |
macaddress |
max:{max} | check if the value(string , number ) is less than {min}. |
max:5 |
min:{min} | check if the value(string , number ) is greater than {max}. |
min:3 |
nan | check if the value(any ) is NaN. |
nan |
port | check if the string is valid PORT(0-65535). |
port |
uppercase | check if the string is uppercase. |
uppercase |
url | check if the string is valid URL. |
url |
uuid:{version = all} | check if the string is valid UUID.version is one of all (default), v3 , v4 , and v5 . |
uuid , uuid:v3 , uuid:v4 , uuid:v5 |
Rule Examples
Type Syntax
You can easily set the validation by supporting the and
, or
syntax.
const validator = safen.create({
username: "(string & email & length_between:12,100) | null",
})
validator.assert({
username: "corgidisco@gmail.com",
}) // ok
validator.assert({
username: null,
}) // ok
try {
validator.assert({
username: "corgidisco",
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "username",
reason: "email",
params: [],
message: "The username must be a valid email address.",
},
{
path: "username",
reason: "null",
params: [],
message: "The username must be a null.",
},
])
}
}
Optional
The optional grammar is available through the "?" character. You can allow no key value in the object, or undefined.
const validator = safen.create({
"username": "string & length_between:4,20",
"password?": "length_between:8,20", // optional
})
validator.assert({
username: "corgidisco",
password: "password!@#",
}) // ok
validator.assert({
username: "corgidisco",
// undefined password is OK.
}) // ok
validator.assert({
username: "corgidisco",
password: undefined, // undefined password is also OK.
}) // ok
try {
validator.assert({
// undefined username is not ok.
password: "password!@#",
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "username",
reason: "required",
params: [],
message: "The username is required.",
},
])
}
}
try {
validator.assert({
username: "corgidisco",
password: null, // null is not allowed
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "password",
reason: "length",
params: [],
message: "The username is required.",
},
])
}
}
Object in Object
Objects in objects are also easy to use. In addition, the error message makes it easy to check the error path.
const validator = safen.create({
username: "string & length_between:4,20",
areas: {
lat: "number & between:-90,90",
lng: "number & between:-180,180",
},
})
validator.assert({
username: "corgidisco",
areas: {
lat: 37,
lng: 126,
},
}) // ok
try {
validator.assert({
username: "corgidisco",
areas: {
lat: "37",
lng: 126,
},
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "areas.lat",
reason: "number",
params: [],
message: "The areas.lat must be a number.",
},
])
}
}
validator.assert({
username: "corgidisco",
areas: {
lat: 37,
lng: 126,
},
}) // ok
Array Support
Simple Array
const validator = safen.create({
"areas[]": { // array
lat: "number",
lng: "number",
},
})
validator.assert({
areas: [], // empty is OK
}) // ok
validator.assert({
areas: [
{lat: 37, lng: 126},
{lat: 31, lng: 125},
],
}) // ok
try {
validator.assert({
areas: "",
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "areas",
reason: "array",
params: [],
message: "The areas must be an array.",
},
])
}
}
Array With Range - Fixed
const validator = safen.create({
"areas[2]": { // array
lat: "number",
lng: "number",
},
})
validator.assert({
areas: [
{lat: 37, lng: 126},
{lat: 31, lng: 125},
],
}) // ok
try {
validator.assert({
areas: [
{lat: 37, lng: 126},
{lat: 31, lng: 125},
{lat: 31, lng: 125},
],
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "areas",
reason: "array_length",
params: [2],
message: "The areas's length must be 2.",
},
])
}
}
try {
validator.assert({
areas: [
{lat: 37, lng: 126},
],
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "areas",
reason: "array_length",
params: [2],
message: "The areas's length must be 2.",
},
])
}
}
Array With Range - Min
const validator = safen.create({
"areas[1:]": { // array
lat: "number",
lng: "number",
},
})
validator.assert({
areas: [
{lat: 31, lng: 125},
],
}) // ok
validator.assert({
areas: [
{lat: 37, lng: 126},
{lat: 31, lng: 125},
],
}) // ok
try {
validator.assert({
areas: [],
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "areas",
reason: "array_length_min",
params: [1],
message: "The areas's length must be at least 1.",
},
])
}
}
Array With Range - Max
const validator = safen.create({
"areas[:2]": { // array
lat: "number",
lng: "number",
},
})
validator.assert({
areas: [
{lat: 31, lng: 125},
],
}) // ok
validator.assert({
areas: [
{lat: 37, lng: 126},
{lat: 31, lng: 125},
],
}) // ok
try {
validator.assert({
areas: [
{lat: 37, lng: 126},
{lat: 31, lng: 125},
{lat: 32, lng: 121},
],
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "areas",
reason: "array_length_max",
params: [2],
message: "The areas's length may not be greater than 2.",
},
])
}
}
Array With Range - Between
const validator = safen.create({
"areas[1:2]": { // array
lat: "number",
lng: "number",
},
})
validator.assert({
areas: [
{lat: 31, lng: 125},
],
}) // ok
validator.assert({
areas: [
{lat: 37, lng: 126},
{lat: 31, lng: 125},
],
}) // ok
try {
validator.assert({
areas: [],
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "areas",
reason: "array_length_between",
params: [1, 2],
message: "The areas's length must be between 1 and 2.",
},
])
}
}
try {
validator.assert({
areas: [
{lat: 37, lng: 126},
{lat: 31, lng: 125},
{lat: 32, lng: 121},
],
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "areas",
reason: "array_length_between",
params: [1, 2],
message: "The areas's length must be between 1 and 2.",
},
])
}
}
Array with Multi Dimension
const validator = safen.create({
"areas[][]": { // array
lat: "number",
lng: "number",
},
})
validator.assert({
areas: [
[
{lat: 37, lng: 126},
{lat: 31, lng: 125},
],
[
{lat: 37, lng: 126},
{lat: 31, lng: 125},
],
],
}) // ok
try {
validator.assert({
areas: [
{lat: 37, lng: 126},
{lat: 31, lng: 125},
],
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "areas.0",
reason: "array",
params: [],
message: "The areas.0 must be an array.",
},
{
path: "areas.1",
reason: "array",
params: [],
message: "The areas.1 must be an array.",
},
])
}
}
Custom Validation
.. :-)
Custom Error Messages
If needed, you can add custom error messages.
const validator = safen.create({
username: "email",
}, {
messages: {
email: [
"this is a custom error message in :path.", // exist `:path`
"this is a custom error message.", // no `:path`
],
},
})
try {
validator.assert({
username: "corgidisco",
}) // fail
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{
path: "username",
reason: "email",
params: [],
message: "this is a custom error message in username.",
},
])
}
}
The :attribute
will be replaced by field name. For example :
const validator = safen.create({
foo: "email",
bar: "between:1,2",
baz: "in:a,b,c",
}, {
messages: {
required: ["The :path is required.", "It is required."],
between: ["The :path must be between :param0 and :param1.", "It must be between :param0 and :param1."],
in: ["The :path does not exist in :params.", "It does not exist in :params."],
},
})
try {
validator.assert({
// foo
bar: 4,
baz: "d",
})
} catch (e) {
if (e instanceof safen.InvalidValueError) {
expect(e.errors).toEqual([
{path: "foo", reason: "required", params: [], message: "The foo is required."},
{path: "bar", reason: "between", params: [1, 2], message: "The bar must be between 1 and 2."},
{path: "baz", reason: "in", params: ["a", "b", "c"], message: "The baz does not exist in [\"a\",\"b\",\"c\"]."},
])
}
}
License
MIT