validate
2022-10-27 本文已影响0人
芸芸众生ing
// validate.ts
/**
* 判断url协议
* @param path url
* @returns boolean
*/
export function isExternal(path: string | any): boolean {
return /^(https?:|mailto:|tel:)/.test(path);
}
/**
* 获取数据类型
* @param arg 数据
* @returns string
*/
export function getType(arg: any): string {
return Object.prototype.toString.call(arg).replace(/^\[\w+\s(\w+)\]$/, '$1').toLowerCase()
}
/**
* 判断数据是否为指定类型
* @param arg 数据
* @param type 类型
* @returns Boolean
*/
export function isType(arg: any, type: string): boolean {
return getType(arg) === type.toString().toLowerCase();
}
/**
* 判断是否为空
* @param arg 数据
* @returns Boolean
*/
export function isNull(arg: any): boolean {
if (isType(arg, 'object')) return JSON.stringify(arg) == '{}';
if (isType(arg, 'string')) return arg === '' || arg === ' ';
if (isType(arg, 'null')) return true;
if (isType(arg, 'undefined')) return true;
return false
}
/**
* 验证邮箱
*/
export function isEmail(arg: string): boolean {
return /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(arg)
}
/**
* 验证手机号
*/
export function isPhone(arg: string): boolean {
return /^1[3-9][0-9]{9}$/.test(arg)
}
/**
* 校验身份证号码
*/
export function isIdCard(arg: string): boolean {
let x = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
let y = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"];
let i = arg.split('');
let t = x.reduce((total, item, index) => Number(i[index]) * item + total, 0);
let r = t % 11;
return arg.slice(-1) === y[r];
}
// validator.ts
import { getType, isNull, isType, isEmail } from "./validate";
interface Rule {
type?: string | any,
required?: boolean,
message?: string,
min?: number,
max?: number,
[key: string]: any
}
interface Rules {
[key: string]: Rule | Rule[] | string
}
interface Target {
[key: string]: boolean | string | boolean | object | any[]
}
interface Err {
key: string,
message: string
}
/**
* 验证器
* @param target 元数据
* @param rules 验证规则
* @returns Boolean || 不通过字段数组
*/
export default function validator(target: Target, rules: Rules): Promise<Err[] | boolean> {
return new Promise((resolve, reject) => {
const errorArr: Err[] = [];
for (let key in rules) {
let msg: string[] = [];
let rule = rules[key];
let val = target[key];
if (Array.isArray(rule)) rule.forEach((item: Rule) => validate(item, val, msg));
else if (typeof rule === 'string') validate({ type: rule }, val, msg);
else validate(rule, val, msg);
msg.length && errorArr.push({ key, message: msg.join(',且') });
}
errorArr.length ? reject(errorArr) : resolve(false);
});
}
function validate(rule: Rule, val: any, msg: string[]) {
let { type = null, required = false, min = 0, max = 0, message = '' } = rule;
if (required && isNull(val)) msg.push('不能为空');
if (isType(type, 'String')) type = type.toLowerCase();
if (isType(type, 'regexp') && new RegExp(type).test(val)) msg.push('校验失败');
if ((min || max) && (min > val.length || max < val.length)) msg.push('长度错误');
if (type === Array && !isType(val, 'array')) pushErrorInfo('array', getType(val));
if (type === Object && !isType(val, 'object')) pushErrorInfo('object', getType(val));
if (type === Number && !isType(val, 'number')) pushErrorInfo('number', getType(val));
if (type === String && !isType(val, 'string')) pushErrorInfo('string', getType(val));
if (type === Boolean && !isType(val, 'boolean')) pushErrorInfo('boolean', getType(val));
if (type === 'array' && !isType(val, 'array')) pushErrorInfo(type, getType(val));
if (type === 'object' && !isType(val, 'object')) pushErrorInfo(type, getType(val));
if (type === 'number' && !isType(val, 'number')) pushErrorInfo(type, getType(val));
if (type === 'string' && !isType(val, 'string')) pushErrorInfo(type, getType(val));
if (type === 'boolean' && !isType(val, 'boolean')) pushErrorInfo(type, getType(val));
if (type === 'email' && !isEmail(val)) msg.push('email地址错误');
function pushErrorInfo(a: string, b: string) {
msg.push(message || `需要[${a}], 但得到[${b}]`)
}
}