Description
Super Fast Complex Object Validator for Javascript(& Typescript).
Safen supports the syntax similar to the type script interface. This makes it easy to create complex validation rules.
Safen alternatives and similar modules
Based on the "Data Validation" category.
Alternatively, view Safen alternatives based on common mentions on social networks and blogs.
-
joi
DISCONTINUED. The most powerful data validation library for JS [Moved to: https://github.com/hapijs/joi] -
ajv
The fastest JSON schema Validator. Supports JSON Schema draft-04/06/07/2019-09/2020-12 and JSON Type Definition (RFC8927)
InfluxDB - Purpose built for real-time analytics at any scale.
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of Safen or a related project?
Popular Comparisons
README
Super Fast Object Validatorfor Javascript(& Typescript).
Safen supports the syntax similar to the type script interface. This makes it easy to create validation rules.
- How to use
- Syntax
- Custom Tester
- Custom Error Messages
- Support Validators
- Comparison
- How Safen works
- Examples
- License
1.x
Please check this link for the 1.x version of the README.
How to use
Setup
install,
npm install safen --save
import,
import * as safen from "safen"
// or
const safen = require("safen")
then,
const validator = safen.sfl`{
username: (string & email & length_between(12, 100)) | null,
password?: string & length_between(8, 20),
areas: {
lat: number & between(-90, 90),
lng: number & between(-180, 180),
}[1:] | null,
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: "[email protected]",
areas: [
{lat: 0, lng: 0},
],
env: {
referer: "http://wan2land.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
returns boolean
and assert
throws Exception.
validate method
const validator = safen.sfl<string | null>`(string & email & length_between(12, 100)) | null`
// in javascript,
// const validator = safen.sfl`(string & email & length_between(12, 100)) | null`
// const validator = safen.create(`(string & email & length_between(12, 100)) | null`)
// typescript with Generic
if (validator.validate(data)) {
// now data is string!
}
validator.validate("[email protected]") // return true
validator.validate(null) // return true
validator.validate("wan2land") // return false, it is not email!
assert method
const validator = safen.sfl<string | null>`(string & email & length_between(12, 100)) | null`
// in javascript,
// const validator = safen.sfl`(string & email & length_between(12, 100)) | null`
// const validator = safen.create(`(string & email & length_between(12, 100)) | null`)
validator.assert("[email protected]") // nothing happens
validator.assert(null) // nothing happens
validator.assert("wan2land") // safen.InvalidValudError occured!
Syntax
Type Syntax
You can easily set the validation by supporting the and
, or
syntax.
const validator = safen.sfl`{
username: (string & email & length_between(12, 100)) | null,
}`
validator.assert({
username: "[email protected]",
}) // ok
validator.assert({
username: null,
}) // ok
try {
validator.assert({
username: "wan2land",
}) // 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.",
},
])
}
}
Object Syntax
Optional field
The "?" character can be used to define optional field, which allows no key value or undefined for objects.
const validator = safen.sfl`{
username: string & length_between(4, 20),
password?: length_between(8, 20),
}`
validator.assert({
username: "wan2land",
password: "password!@#",
}) // ok
validator.assert({
username: "wan2land",
// undefined password is OK.
}) // ok
validator.assert({
username: "wan2land",
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: "wan2land",
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.",
},
])
}
}
Nested object
Validating nested objects also can be easily done. In addition, the error message makes it easier to check the error path.
const validator = safen.sfl`{
username: string & length_between(4, 20),
areas: {
lat: number & between(-90, 90),
lng: number & between(-180, 180),
},
}`
validator.assert({
username: "wan2land",
areas: {
lat: 37,
lng: 126,
},
}) // ok
try {
validator.assert({
username: "wan2land",
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: "wan2land",
areas: {
lat: 37,
lng: 126,
},
}) // ok
Array Syntax
Simple array
const validator = safen.sfl`{
areas: {
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.",
},
])
}
}
Fixed size array
const validator = safen.sfl`{
areas: {
lat: number,
lng: number,
}[2],
}`
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 minimum size
const validator = safen.sfl`{
areas: {
lat: number,
lng: number,
}[1:],
}`
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 maximum size
const validator = safen.sfl`{
areas: {
lat: number,
lng: number,
}[:2],
}`
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.",
},
])
}
}
Sized array
const validator = safen.sfl`{
areas: {
lat: number,
lng: number,
}[1:2],
}`
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.",
},
])
}
}
Nested array
const validator = safen.sfl`{
areas: {
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 Tester
Custom tester is written in template format like below:
const oddTester: safen.Tester = (value, params, gen) => {
return `(Number.isInteger(${value}) && ${value} % 2 === 1)`
}
const evenTester: safen.Tester = (value, params, gen) => {
return `(Number.isInteger(${value}) && ${value} % 2 === 0)`
}
const validation = safen.create(`{
even: even,
odd: odd,
}`, {
testers: {
odd: oddTester,
even: evenTester,
},
})
expect(validation.validate({even: 2, odd: 1})).toBeTruthy()
expect(validation.validate({even: 1, odd: 1})).toBeFalsy()
expect(validation.validate({even: 2, odd: 2})).toBeFalsy()
expect(validation.validate({even: 1, odd: 2})).toBeFalsy()
A more complex example is:
- example of
params
andgen
: [before tester](./src/testers/before.ts)
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: "wan2land",
}) // 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 :params
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\"]."},
])
}
}
Support Validators
Type Validations
Validator | Description |
---|---|
bool | check if it is a boolean (alias to boolean ). |
boolean | check if it is a boolean . |
false | check if it is a false . |
float | check if it is a float (alias to number ). |
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 . |
object | check if it is a object . |
string | check if it is a string . |
symbol | check if it is a symbol . |
true | check if it is a true . |
Other Validations
Validator | Description | Example |
---|---|---|
after({date = now}) | check if string is a date and is after than specified date. |
after , after("2017-10-01") , after("2017-10-01 14:30:00") |
alpha | check if string contains only letters([a-zA-Z]). |
alpha |
alphanum | check if 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 |
any | return always true. | any |
ascii | check if string contains only ascii characters. |
ascii |
base64 | check if string is Base64. |
base64 |
before({date = now}) | check if 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 value(string , number ) is between {min} and {max} . |
between("aaa","zzz") , between(1,100) |
creditcard | check if string is valid Credit Card number. cf. 0000-0000-0000-0000 |
creditcard |
date | check if string is valid Date string(RFC2822, ISO8601). cf. 2018-12-25 , 12/25/2018 , Dec 25, 2018 |
date |
check if string is valid E-mail string. |
email |
|
finite | check if number is not NaN , Infinity , -Infinity . |
finite |
hexcolor | check if string is valid Hex Color string. cf. #ffffff |
hexcolor |
in({...params}) | check if value(any ) is in an array {params} . |
in(1,2,3) , in("safari","edge","firefox","other browser") |
ip({version = all}) | check if string is valid UUID.version is one of all (default), v4 , and v6 . |
ip , ip("v4") , ip("v6") |
json | check if string is valid JSON. |
json |
jwt | check if string is valid JWT. |
jwt |
length({size}) | check if value(string )'s length is {size} . |
length(16) |
length_between({min},{max}) | check if value(string )'s length is between {min} and {max} . |
length_between(4,20) |
length_max({max}) | check if value(string )'s length is less than {max} . |
length_max(20) |
length_min({min}) | check if value(string )'s length is greater than {min} . |
length_min(4) |
lowercase | check if string is lowercase. |
lowercase |
macaddress | check if string is valid Mac Address. |
macaddress |
max({max}) | check if value(string , number ) is less than {min}. |
max(5) |
min({min}) | check if value(string , number ) is greater than {max}. |
min(3) |
nan | check if value(any ) is NaN. |
nan |
re | check if value(any ) match RegExp(alias to regexp ). |
re(/.+/) |
regex | check if value(any ) match RegExp(alias to regexp ). |
regex(/.+/) |
regexp | check if value(any ) match RegExp. |
regexp(/.+/) |
port | check if string is valid PORT(0-65535). |
port |
uppercase | check if string is uppercase. |
uppercase |
url | check if string is valid URL. |
url |
uuid({version = all}) | check if string is valid UUID.version is one of all (default), v3 , v4 , and v5 . |
uuid , uuid("v3") , uuid("v4") , uuid("v5") |
Comparison
Using another library? Safen is lot easier to use.
{
username: (string & email & length_between(12, 100)) | null,
password?: string & length_between(8, 20),
areas: {
lat: number & between(-90, 90),
lng: number & between(-180, 180),
}[1:] | null,
env: {
referer: url,
ip: ip("v4"),
os: {
name: in("window", "osx", "android", "iphone"),
version: string,
},
browser: {
name: in("chrome", "firefox", "edge", "ie"),
version: string,
},
},
}
Compare with JSON Schema
Show JSON Schema Source
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"username",
"areas",
"env"
],
"properties": {
"username": {
"type": ["string", "null"],
"format": "email",
"minLength": 12,
"maxLength": 100
},
"password": {
"type": "string",
"minLength": 8,
"maxLength": 20
},
"areas": {
"type": ["array", "null"],
"items": {
"type": "object",
"required": [
"lat",
"lng"
],
"properties": {
"lat": {
"type": "integer",
"minimum": -90,
"maximum": 90
},
"lng": {
"type": "integer",
"minimum": -180,
"maximum": 180
}
}
}
},
"env": {
"type": "object",
"required": [
"referer",
"ip",
"os",
"browser"
],
"properties": {
"referer": {
"type": "string",
"format": "uri"
},
"ip": {
"type": "string",
"format": "ipv4"
},
"os": {
"type": "object",
"required": [
"name",
"version"
],
"properties": {
"name": {
"type": "string",
"enum": ["window", "osx", "android", "iphone"],
},
"version": {
"type": "string",
"pattern": "^(.*)$"
}
}
},
"browser": {
"type": "object",
"required": [
"name",
"version"
],
"properties": {
"name": {
"type": "string",
"enum": ["chrome", "firefox", "edge", "ie"],
},
"version": {
"type": "string",
"pattern": "^(.*)$"
}
}
}
}
}
}
}
Compare with JOI
JOI is the most popular object schema validation library.
Show JOI Source
Joi.object().keys({
username: Joi.string().required().allow(null).email().min(12).max(100),
password: Joi.string().min(8).max(20),
areas: Joi.array().required().allow(null).min(1).items(Joi.object().keys({
lat: Joi.number().required().min(-90).max(90),
lng: Joi.number().required().min(-180).max(180),
})),
env: Joi.object().required().keys({
referer: Joi.string().uri().required(),
ip: Joi.string().required().ip({version: ["ipv4"]}),
os: Joi.object().required().keys({
name: Joi.any().required().only("window", "osx", "android", "iphone"),
version: Joi.string().required(),
}),
browser: Joi.object().required().keys({
name: Joi.any().required().only("chrome", "firefox", "edge", "ie"),
version: Joi.string().required(),
}),
}),
})
How Safen works
Safen parses the grammar and internally generates an AST(Abstract Syntax Tree) similar to the Json Schema.
{
username: (string & email) | null,
areas: {
lat?: number & between(-90, 90),
lng?: number & between(-180, 180),
}[1]
}
The generated AST is as follows:
Show AST
{
"type": "object",
"properties": {
"username": {
"optional": false,
"value": {
"type": "or",
"params": [
{
"type": "and",
"params": [
{
"type": "scalar",
"name": "string",
"params": []
},
{
"type": "scalar",
"name": "email",
"params": []
}
]
},
{
"type": "scalar",
"name": "null",
"params": []
}
]
}
},
"areas": {
"optional": false,
"value": {
"type": "array",
"min": 1,
"max": 1,
"value": {
"type": "object",
"properties": {
"lat": {
"optional": true,
"value": {
"type": "and",
"params": [
{
"type": "scalar",
"name": "number",
"params": []
},
{
"type": "scalar",
"name": "between",
"params": [
-90,
90
]
}
]
}
},
"lng": {
"optional": true,
"value": {
"type": "and",
"params": [
{
"type": "scalar",
"name": "number",
"params": []
},
{
"type": "scalar",
"name": "between",
"params": [
-180,
180
]
}
]
}
}
}
}
}
}
}
}
Safen generates native validate
and assert
functions based on AST, which make safen lightning fast.
Native validate
function sample:
Show generated validate function.
function(v) {
return (function() {
if (typeof v !== "object" || v === null) {
return false
}
if (typeof v.username === "undefined") {
return false
}
if (!((((typeof(v.username) === "string") && /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(v.username)) || v.username === null))) {
return false
}
if (typeof v.areas === "undefined") {
return false
}
if (!((function() {
if (!Array.isArray(v.areas) || v.areas.length < 1 || v.areas.length > 1) {
return false
}
for (var t0 = 0; t0 < v.areas.length; t0++) {
if (!((function() {
if (typeof v.areas[t0] !== "object" || v.areas[t0] === null) {
return false
}
if (typeof v.areas[t0].lat !== "undefined") {
if (!(((typeof(v.areas[t0].lat) === "number") && (v.areas[t0].lat >= -90 && v.areas[t0].lat <= 90)))) {
return false
}
}
if (typeof v.areas[t0].lng !== "undefined") {
if (!(((typeof(v.areas[t0].lng) === "number") && (v.areas[t0].lng >= -180 && v.areas[t0].lng <= 180)))) {
return false
}
};
return true
})())) {
return false
}
}
return true
})())) {
return false
};
return true
})()
}
Native assert
function sample:
Show generated assert function.
function (v) {
var path = [];
var errors = (function() {
var t0 = [];
if (typeof v !== "object" || v === null) {
return [{
message: message(path.join("").replace(/^\./, ""), "object", []),
path: path.join("").replace(/^\./, ""),
reason: "object",
params: []
}]
}
path.push(".username");
if (typeof v.username !== "undefined") {
t0 = t0.concat((function() {
var t1 = [],
t2 = (function() {
var t3 = (function() {
if (!((typeof(v.username) === "string"))) {
return [{
message: message(path.join("").replace(/^\./, ""), "string", []),
path: path.join("").replace(/^\./, ""),
reason: "string",
params: []
}]
}
return []
})();
if (t3.length) {
return t3
}
t3 = (function() {
if (!(/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(v.username))) {
return [{
message: message(path.join("").replace(/^\./, ""), "email", []),
path: path.join("").replace(/^\./, ""),
reason: "email",
params: []
}]
}
return []
})();
if (t3.length) {
return t3
}
return []
})();
if (t2.length === 0) {
return []
}
t1 = t1.concat(t2);
t2 = (function() {
if (!(v.username === null)) {
return [{
message: message(path.join("").replace(/^\./, ""), "null", []),
path: path.join("").replace(/^\./, ""),
reason: "null",
params: []
}]
}
return []
})();
if (t2.length === 0) {
return []
}
t1 = t1.concat(t2);
return t1
})())
} else {
t0.push({
message: message(path.join("").replace(/^\./, ""), "required", []),
path: path.join("").replace(/^\./, ""),
reason: "required",
params: []
})
}
path.pop();
path.push(".areas");
if (typeof v.areas !== "undefined") {
t0 = t0.concat((function() {
if (!Array.isArray(v.areas)) {
return [{
message: message(path.join("").replace(/^\./, ""), "array", []),
path: path.join("").replace(/^\./, ""),
reason: "array",
params: []
}]
}
if (v.areas.length !== 1) {
return [{
message: message(path.join("").replace(/^\./, ""), "array_length", [1]),
path: path.join("").replace(/^\./, ""),
reason: "array_length",
params: [1]
}]
}
var t4 = [];
for (var t5 = 0; t5 < v.areas.length; t5++) {
path.push("[" + t5 + "]");
t4 = t4.concat((function() {
var t6 = [];
if (typeof v.areas[t5] !== "object" || v.areas[t5] === null) {
return [{
message: message(path.join("").replace(/^\./, ""), "object", []),
path: path.join("").replace(/^\./, ""),
reason: "object",
params: []
}]
}
path.push(".lat");
if (typeof v.areas[t5].lat !== "undefined") {
t6 = t6.concat((function() {
var t7 = (function() {
if (!((typeof(v.areas[t5].lat) === "number"))) {
return [{
message: message(path.join("").replace(/^\./, ""), "number", []),
path: path.join("").replace(/^\./, ""),
reason: "number",
params: []
}]
}
return []
})();
if (t7.length) {
return t7
}
t7 = (function() {
if (!((v.areas[t5].lat >= -90 && v.areas[t5].lat <= 90))) {
return [{
message: message(path.join("").replace(/^\./, ""), "between", [-90, 90]),
path: path.join("").replace(/^\./, ""),
reason: "between",
params: [-90, 90]
}]
}
return []
})();
if (t7.length) {
return t7
}
return []
})())
}
path.pop();
path.push(".lng");
if (typeof v.areas[t5].lng !== "undefined") {
t6 = t6.concat((function() {
var t8 = (function() {
if (!((typeof(v.areas[t5].lng) === "number"))) {
return [{
message: message(path.join("").replace(/^\./, ""), "number", []),
path: path.join("").replace(/^\./, ""),
reason: "number",
params: []
}]
}
return []
})();
if (t8.length) {
return t8
}
t8 = (function() {
if (!((v.areas[t5].lng >= -180 && v.areas[t5].lng <= 180))) {
return [{
message: message(path.join("").replace(/^\./, ""), "between", [-180, 180]),
path: path.join("").replace(/^\./, ""),
reason: "between",
params: [-180, 180]
}]
}
return []
})();
if (t8.length) {
return t8
}
return []
})())
}
path.pop();
return t6
})());
path.pop()
}
return t4
})())
} else {
t0.push({
message: message(path.join("").replace(/^\./, ""), "required", []),
path: path.join("").replace(/^\./, ""),
reason: "required",
params: []
})
}
path.pop();
return t0
})();
if (errors.length) throw new InvalidValueError(errors)
}
Examples
- [with express](./examples/with-express)
- [with axios](./examples/with-axios)
License
MIT
*Note that all licence references and agreements mentioned in the Safen README section above
are relevant to that project's source code only.