import { verifyFormats } from './format'; export class Verify { // == 验证方法集合 verifies = {} constructor() { // == 初始化常用验证方法 this.addVerifies.apply(null, verifyFormats); } /** * 批量添加验证方法 * @param args,验证方法配置集合,单个配置格式如:['isNumber', format.is.number, false] */ addVerifies = (...args) => { for (let i = 0, n = args.length; i < n; i++) { let arg = args[i] this.addVerify(arg[0], arg[1], arg[2]); } } /** * 创建基础验证方法 * @param name 验证格式名称,如isNumber * @param check 核心验证方法, * 可以为函数也可以为正则,如果为正则默认使用test校验 * 如果为函数则执行后可能返回验证结果或返回配置后的验证函数 * @param reverse 是否反向验证 */ addVerify = (name, check, reverse) => { this.verifies[name] = function (value) { let passedOrCheckFunc = false; if(typeof check === 'function'){ passedOrCheckFunc = reverse ? !check.apply(null, arguments) : check.apply(null, arguments); }else{ passedOrCheckFunc = reverse ? !check.test(value) : check.test(value); } return passedOrCheckFunc; }; } /** * @param formats 验证配置集合,每个配置支持字符串、对象和数组等格式: * 字符串默认为验证格式名称,如require * 对象格式如:{require:'不能为空',inLength:{message:'4-8区间',args:[4,8]}} * 数组格式如:[['require','不能为空'],['inLength',{message:'4-8区间',args:[4,8]}],...] */ check = (...options) => { let self = this; /** * 具体校验执行方法,校验结果格式返回如: * {passed:false, errors:[{format: 'hasNumber', message: '格式错误'}],rights:[]} */ return (value) => { // 是否全部通过校验 let passedAll = true; let rValue = null; // 推荐值(修正后的值) let errors = [], rights = []; for (let i = 0, n = options.length; i < n; i++) { const option = options[i]; if(Array.isArray(option)){ // 数组格式,每个元素为一验证格式 for (let opt of option) { let formatName = opt[0]; let message = opt[1]; let isPassed = checkOne(formatName, message); passedAll = passedAll && isPassed; } }else if(typeof option === 'object'){ // 对象格式,1个对象包含多个验证格式 for (let formatName of Object.keys(option)) { let message = option[formatName]; let isPassed = checkOne(formatName, message); passedAll = passedAll && isPassed; } }else if(typeof option === 'string'){ let formatName = option; let isPassed = checkOne(formatName); passedAll = passedAll && isPassed; } } /** * 检查操作 * @param name vertify验证格式名 * @param option 验证配置,可为字符串或配置对象或函数 * @returns {*} */ function checkOne(name, option?) { let args, message, isPassed, verify; verify = self.verifies[name]; if(typeof option === 'string'){ message = option; }else if(typeof option === 'function'){ verify = option; }else if(typeof option === 'object'){ // 预配置验证函数需要的参数 args = option.args; message = option.message; // 如果存在args,则先执行获得验证函数 if(args) verify = self.verifies[name].apply(null,args); } if(!verify) throw new Error(`不存在${name}格式的验证方法`); const verifyRes = verify(value); // 返回结果是对象则读取message和passed if(typeof verifyRes === 'object'){ isPassed = verifyRes.passed; message = verifyRes.message; rValue = verifyRes.value; } else { isPassed = verifyRes; } if(isPassed) { rights.push({format: name}); }else{ errors.push({format: name, message}); } return isPassed; } return { passed: passedAll, rValue: rValue !== value ? rValue : null, value, rights, errors }; } } }