介绍
joi允许您使用简单、直观和可读的语言描述数据。
示例
const Joi = require('joi');
const schema = Joi.object({
username: Joi.string()
.alphanum()
.min(3)
.max(30)
.required(),
password: Joi.string()
.pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),
repeat_password: Joi.ref('password'),
access_token: [
Joi.string(),
Joi.number()
],
birth_year: Joi.number()
.integer()
.min(1900)
.max(2013),
email: Joi.string()
.email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })
})
.with('username', 'birth_year')
.xor('password', 'access_token')
.with('password', 'repeat_password');
schema.validate({ username: 'abc', birth_year: 1994 });
// -> { value: { username: 'abc', birth_year: 1994 } }
schema.validate({});
// -> { value: {}, error: '"username" is required' }
// Also -
try {
const value = await schema.validateAsync({ username: 'abc', birth_year: 1994 });
}
catch (err)
上述模式定义了以下约束:
username
- 一个必填字符串
- 只能包含字母数字字符
- 至少3个字符长,但不超过30个字符
- 必须有birth_year字段
password
- 字符串
- 必须满足自定义正则表达式模式
- 不能与access_token字段一起出现
- 必须带有repeat_password并与之相等
access_token
- 无约束字符串或数字
birth_year
- 1900和2013之间的整数
email
- 有效的电子邮件地址字符串
- 必须有两个域部分,例如example.com
- TLD必须是.com或.net
一般用法
使用过程分为两步:
首先,使用提供的类型和约束构造模式:
const schema = Joi.object({
a: Joi.string()
});
请注意,joi模式对象是不可变的,这意味着添加的每个附加规则(例如,.min(5))将返回一个新的模式对象。
其次,根据定义的模式验证该值:
const { error, value } = schema.validate({ a: 'a string' });
如果输入有效,则错误error将未定义。
如果输入无效,错误error将被分配一个ValidationError对象,以提供更多信息。
模式可以是一个简单的JavaScript对象,其中每个键都被分配了一个joi类型,也可以是直接的joi类型:
const schema = Joi.string().min(10);
如果模式是joi类型,则该模式,可以直接在类型上调用validate(value)。传递非类型模式对象时,模块将其内部转换为object()类型,等效于:
const schema = Joi.object().keys({
a: Joi.string()
});
验证schema对象时:
- 默认情况下,值(或对象的键)是可选的。
Joi.string().validate(undefined); // validates fine
要禁止此行为,您可以将schema设置为required(),或者在传递选项时将presence设置为“required”:
Joi.string().required().validate(undefined);
// or
Joi.string().validate(undefined, /* options */ { presence: "required" });
- 默认情况下,字符串是utf-8编码的。
- 规则以相加的方式定义,并按顺序求值,首先是包含规则,然后是独占规则。
assert()
assert(value, schema, [message], [options])
根据schema验证值,如果验证失败,则抛出,其中:
- value-要验证的值。
- schema-验证模式。可以是joi类型的对象,也可以是使用joi为每个键指定joi类型对象的普通对象。编译(注意重复编译相同模式的成本)。
- message-在错误消息前面添加的可选消息字符串前缀。也可以是错误对象。
- options-可选选项对象,传入any.validate
Joi.assert('x', Joi.number());
attempt()
attempt(value, schema, [message], [options])
根据schema验证值,返回有效对象,并在验证失败时抛出,其中:
- value-要验证的值。
- schema-验证模式。可以是joi类型的对象,也可以是使用joi为每个键指定joi类型对象的普通对象。编译(注意重复编译相同模式的成本)。
- message-在错误消息前面添加的可选消息字符串前缀。也可以是错误对象。
- options-可选选项对象,传入any.validate
Joi.attempt('x', Joi.number()); // throws error
const result = Joi.attempt('4', Joi.number()); // result -> 4
cache.provision()
cache.provision([options])
提供用于缓存简单输入(未定义、空、字符串、数字和布尔)的简单LRU缓存,其中:
options-可选设置:
- max-删除最少使用的项之前要存储在缓存中的项数。默认为1000
checkPreferences()
checkPreferences(prefs)
检查提供的首选项是否有效,其中:
- prefs-要验证的首选项对象。
如果prefs对象无效,则引发异常。
提供该方法以执行any.validate()和any.validateAsync()方法。由于性能原因,不会自动执行验证。相反,手动验证一次传递的首选项并重新使用。
compile()
compile(schema, [options])
将文字模式定义转换为joi模式对象(如果已为joi架构对象,则将其返回),其中:
- schema-要编译的架构定义。
options-可选设置:
- legacy-如果为true,并且提供的架构(或包含部分)使用较旧版本的joi,则将返回与较旧版本兼容的已编译架构。如果为false,则始终使用当前版本编译架构,如果找到较旧的架构组件,则会引发错误。
const definition = ['key', 5, { a: true, b: [/^a/, 'boom'] }];
const schema = Joi.compile(definition);
// Same as:
const schema = Joi.alternatives().try(
Joi.string().valid('key'),
Joi.number().valid(5),
Joi.object({
a: Joi.boolean().valid(true),
b: Joi.alternatives().try(
Joi.string().pattern(/^a/),
Joi.string().valid('boom')
)
})
);
defaults()
defaults(modifier)
创建一个新的joi实例,将提供的修饰符函数应用于每个新模式,其中:
- modifier-具有签名函数(模式)的函数,必须返回模式对象。
const custom = Joi.defaults((schema) => {
switch (schema.type) {
case 'string':
return schema.allow('');
case 'object':
return schema.min(1);
default:
return schema;
}
});
const schema = custom.object(); // Returns Joi.object().min(1)
expression(template, [options]) - aliases: x
使用模板字符串生成动态表达式,其中:
- template-使用模板语法的模板字符串。
- options-创建内部引用时使用的可选设置。支持与ref()相同的选项。
模板语法
模板语法使用{}和{{}}封闭公式来引用值,并执行数字和字符串操作。单大括号{}保持公式结果不变,而双大括号{{}}HTML转义公式结果(除非模板用于错误消息且errors.escapeHtml首选项标志设置为false)。
如果公式是前缀为:(例如,{:#ref}或{{:#ref}}的单个引用,则其值将根据包装验证设置包装。#label变量始终根据wrap设置包装。
公式使用简单的数学语法,如a+b*2,其中命名的公式变量是引用。大多数引用可以按原样使用,但有些引用可能会造成公式语法的歧义,必须用[]大括号括起来(例如[.])。
公式只能对空、布尔、数字和字符串进行运算。如果任何操作涉及字符串,所有其他数字将被转换为字符串(因为内部实现使用简单的JavaScript运算符)。支持的运算符有:^、*、/、%、+、-、<、<=、>、>=、==、!=、&&、||和??(按优先顺序)。
引用名称可以具有以下前缀之一:
- # - 表示变量引用本地上下文值。例如,在错误中,这是错误上下文,而在重命名操作中,它是正则表达式匹配组。
- $ - 指示变量引用上下文首选项对象中的全局上下文值,该对象作为验证函数的选项提供,或使用any.prefs()设置。
- 任何其他变量引用正在验证的当前值中的键。
公式语法还支持内置函数:
- if(condition, then, otherwise) - 当condition条件为真时返回then,否则返回otherwise。
- length(item) - 返回数组或字符串的长度,对象的键数,否则为null。
- msg(code) - 嵌入另一个错误代码消息。
- number(value) - 将值转换为数字。
以及以下常数:
- null
- true
- false
评论 (0)