validator.js
7.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/**
* 接口参数校验
*
* Created by y.huang on 17/5/21.
*/
/**
* 返回一个错误对象
*
* msg 提示语
*/
const _errJson = (message) => {
return {
code: '203',
description: message,
name: '数据错误',
errKey: 'valid'
};
};
/**
* 数字校验方法、支持小数负数、支持字符串数字自动转换
*
* option object类型,包含校验条件,如下
* require 是否必须,boolean类型,默认false不必须
* empty 可以是空字符串, boolean类型,默认true可以
* isInteger 是否必须整数,boolean类型,默认false不必须
* equal 等于某个值,number类型
* equalArr 等于几个值中的一个,array类型,array元素为number类型,长度不限
* smaller 小于某个值,number类型
* bigger 大于某个值,number类型
*/
const _numberValid = (option) => {
const value = option.value;
// 设置默认值
option.require = option.require === undefined ? false : option.require;
option.integer = option.integer === undefined ? false : option.integer;
option.empty = option.empty === undefined ? true : option.empty;
if (value === undefined) {
if (option.require === true) {
throw _errJson(`${option.param} 参数是必须的`);
} else {
return value;
}
}
if (typeof value === 'boolean' || typeof value === 'object') {
throw _errJson(`${option.param} 参数类型必须是数字或字符串数字`);
}
if (value === '') {
if (option.empty === false) {
throw _errJson(`${option.param} 参数不能为空字符串`);
} else {
return undefined;
}
}
const numValue = Number(value);
if (!Number.isNaN(numValue) && Math.abs(numValue) !== Infinity) {
if (option.equal !== undefined) {
if (numValue !== option.equal) {
throw _errJson(`${option.param} 参数必须等于 ${option.equal}`);
}
return numValue;
}
if (option.equalArr !== undefined) {
let result = false;
for (let item of option.equalArr) {
if (item === numValue) {
result = true;
break;
}
}
if (!result) {
throw _errJson(`${option.param} 参数必须等于 ${option.equalArr} 中的某个`);
}
return numValue;
}
if (option.integer === true) {
if (!Number.isInteger(numValue)) {
throw _errJson(`${option.param} 参数必须是整数`);
}
}
if (option.smaller !== undefined) {
if (!numValue < option.smaller) {
throw _errJson(`${option.param} 参数必须小于 ${option.smaller}`);
}
}
if (option.bigger !== undefined) {
if (!numValue > option.bigger) {
throw _errJson(`${option.param} 参数必须大于 ${option.bigger}`);
}
}
return numValue;
} else {
throw _errJson(`${option.param} 参数类型必须是数字或字符串数字`);
}
};
/**
* 字符串校验方法、支持数字自动转换
*
* option object类型,包含校验条件,如下
* require 是否必须,boolean类型,默认false不必须
* empty 是否可以为空字符串,boolean类型,默认true可以
* emptyFilter 过滤空字符串,boolean类型,true为需要过滤, 使用时empty必须为true
* regex 正则匹配,其值应该是'phone,email'中的一个,或是一个自定义的正则对象或正则自面量
* start 字符串长度大于,number类型
* end 字符串长度小于,number类型
*/
const _stringValid = (option) => {
const value = option.value;
// 设置默认值
option.require = option.require || false;
option.empty = option.empty || true;
if (value === undefined) {
if (option.require === true) {
throw _errJson(`${option.param} 参数是必须的`);
} else {
return value;
}
}
if (Number.isNaN(value) || Math.abs(value) === Infinity || typeof value === 'boolean' || typeof value === 'object') {
throw _errJson(`${option.param} 参数类型必须是数字或字符串`);
}
const strValue = String(value).trim();
if (strValue === '') {
if (option.empty === false) {
throw _errJson(`${option.param} 参数不能为空`);
} else {
if (option.emptyFilter === true) {
return undefined;
}
return strValue;
}
}
if (option.regex !== undefined) {
switch (option.regex) {
case 'phone':
if (!/^1[0-9]{10}$/.test(strValue)) {
throw _errJson(`${option.param} 参数不符合手机格式`);
}
break;
case 'email':
if (!/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(strValue)) {
throw _errJson(`${option.param} 参数不符合邮箱格式`);
}
break;
default:
if (!option.regex.test(strValue)) {
throw _errJson(`${option.param} 参数不符合自定义格式`);
}
}
return strValue;
}
if (option.end !== undefined) {
if (!strValue.length < option.end) {
throw _errJson(`${option.param} 参数长度必须小于 ${option.end}`);
}
}
if (option.start !== undefined) {
if (!strValue.length > option.start) {
throw _errJson(`${option.param} 参数长度必须大于 ${option.start}`);
}
}
return strValue;
};
/**
* 布尔校验方法、支持字符串布尔类型自动转换
*
* option object类型,包含校验条件,如下
* require 是否必须,boolean类型,默认false不必需
* empty 是否可以为空字符串,boolean类型,默认true可以
* emptyFilter 过滤空字符串,boolean类型,true为需要过滤, 使用时empty必须为true
*/
const _booleanValid = (option) => {
const value = option.value;
// 设置默认值
option.require = option.require || false;
option.empty = option.empty || true;
if (value === undefined) {
if (option.require === true) {
throw _errJson(`${option.param} 参数是必须的`);
} else {
return value;
}
}
if (value === '') {
if (option.empty === false) {
throw _errJson(`${option.param} 参数不能为空`);
} else {
if (option.emptyFilter === true) {
return undefined;
}
return value;
}
} else {
if (typeof value !== 'boolean' && value !== 'true' && value !== 'false') {
throw _errJson(`${option.param} 参数类型必须为boolean`);
}
return Boolean(value);
}
};
/*
* data: 需要校验的数据对象
* option: 校验规则对象,eg: {'name', {type: 'string', require: true}}
*
*/
const valid = (data, option) => {
Object.keys(option).forEach(item => {
let opt = option[item];
opt.value = data[item];
opt.param = item;
switch (opt.type) {
case 'number':
data[item] = _numberValid(opt);
if (data[item] === undefined) {
delete data[item];
}
break;
case 'string':
data[item] = _stringValid(opt);
if (data[item] === undefined) {
delete data[item];
}
break;
case 'boolean':
data[item] = _booleanValid(opt);
if (data[item] === undefined) {
delete data[item];
}
break;
}
});
return data;
};
module.exports = valid;