ph-utils 0.1.6 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/dom.d.ts +9 -2
- package/lib/dom.js +16 -3
- package/lib/index.d.ts +1 -1
- package/lib/index_m.d.ts +1 -1
- package/lib/index_m.js +1 -1
- package/lib/validator.d.ts +44 -0
- package/lib/validator.js +219 -0
- package/lib/validator_m.d.ts +44 -0
- package/lib/validator_m.js +215 -0
- package/package.json +1 -1
package/README.md
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
|
5
5
|
### 后端(node server)
|
6
6
|
|
7
|
-
包含了一些 node 后端开发(web server) 时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`file` 文件操作相关工具类、`server` 一些只适用于后端的工具(使用了后端的 API 列表)
|
7
|
+
包含了一些 node 后端开发(web server) 时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`file` 文件操作相关工具类、`server` 一些只适用于后端的工具(使用了后端的 API 列表)、`validator` 数据验证
|
8
8
|
|
9
9
|
### 前端(web)
|
10
10
|
|
11
|
-
包含了一些前端网站开发时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`dom` 浏览器节点操作相关、`web`
|
11
|
+
包含了一些前端网站开发时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`dom` 浏览器节点操作相关、`web` 一些只适用于前端相关的工具、`validator` 数据验证
|
package/lib/dom.d.ts
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
* 根据选择器获取节点
|
3
3
|
* @param {string} selector 选择器
|
4
4
|
*/
|
5
|
-
export declare function elem(selector: string, dom?: HTMLElement): NodeListOf<HTMLElement
|
5
|
+
export declare function elem(selector: string | HTMLElement, dom?: HTMLElement): NodeListOf<HTMLElement> | HTMLElement[];
|
6
6
|
/**
|
7
7
|
* 为节点添加 class
|
8
8
|
* @param {HTMLElement} elem 待添加 class 的节点
|
@@ -37,6 +37,7 @@ export declare function transform(element: HTMLElement, value: string): void;
|
|
37
37
|
export declare function on(element: HTMLElement, listener: string, fn: (e: Event, target?: HTMLElement, flag?: string) => void, once?: boolean | {
|
38
38
|
once?: boolean;
|
39
39
|
eventFlag?: string;
|
40
|
+
eventStop?: boolean;
|
40
41
|
}): void;
|
41
42
|
/**
|
42
43
|
* 设置或获取节点的 innerHTML 属性
|
@@ -57,7 +58,7 @@ export declare function text(element: HTMLElement, textstr?: string): string;
|
|
57
58
|
* @param elems
|
58
59
|
* @param fn 遍历到节点时的回调,回调第一个参数为遍历到的节点,第2个参数为 index;如果回调函数返回 true,则会终止遍历(break)
|
59
60
|
*/
|
60
|
-
export declare function iterate(elems: NodeList, fn: (el: HTMLElement, index: number) => any): void;
|
61
|
+
export declare function iterate(elems: NodeList | HTMLElement[], fn: (el: HTMLElement, index: number) => any): void;
|
61
62
|
/**
|
62
63
|
* 设置或获取节点 data-* 属性
|
63
64
|
* @param elem
|
@@ -66,3 +67,9 @@ export declare function iterate(elems: NodeList, fn: (el: HTMLElement, index: nu
|
|
66
67
|
* @returns
|
67
68
|
*/
|
68
69
|
export declare function attr(elem: HTMLElement, key: string, value?: string): string;
|
70
|
+
/**
|
71
|
+
* 获取指定节点的父节点
|
72
|
+
* @param el
|
73
|
+
* @returns
|
74
|
+
*/
|
75
|
+
export declare function parent(el: HTMLElement): HTMLElement;
|
package/lib/dom.js
CHANGED
@@ -9,7 +9,12 @@ const vendorPrefix = ['', '-webkit', '-moz-'];
|
|
9
9
|
* @param {string} selector 选择器
|
10
10
|
*/
|
11
11
|
export function elem(selector, dom) {
|
12
|
-
|
12
|
+
if (typeof selector === 'string') {
|
13
|
+
return (dom || document).querySelectorAll(selector);
|
14
|
+
}
|
15
|
+
else {
|
16
|
+
return [selector];
|
17
|
+
}
|
13
18
|
}
|
14
19
|
/**
|
15
20
|
* 为节点添加 class
|
@@ -57,7 +62,7 @@ export function transform(element, value) {
|
|
57
62
|
* @param {boolean} onceOrConfig 是否是只运行一次的处理函数或者配置,其中 eventFlag 为 string,如果配置该项,则表明为委托事件
|
58
63
|
*/
|
59
64
|
export function on(element, listener, fn, once = false) {
|
60
|
-
let eventExtra = {};
|
65
|
+
let eventExtra = { eventStop: false };
|
61
66
|
if (typeof once === 'boolean') {
|
62
67
|
eventExtra.once = once;
|
63
68
|
}
|
@@ -75,7 +80,7 @@ export function on(element, listener, fn, once = false) {
|
|
75
80
|
target = target.parentNode;
|
76
81
|
}
|
77
82
|
} while (flag === '');
|
78
|
-
if (flag !== '__stop__') {
|
83
|
+
if (flag !== '__stop__' || eventExtra.eventStop) {
|
79
84
|
fn(e, target, flag);
|
80
85
|
}
|
81
86
|
}, eventExtra);
|
@@ -142,3 +147,11 @@ export function attr(elem, key, value) {
|
|
142
147
|
return elem.getAttribute('data-' + key);
|
143
148
|
}
|
144
149
|
}
|
150
|
+
/**
|
151
|
+
* 获取指定节点的父节点
|
152
|
+
* @param el
|
153
|
+
* @returns
|
154
|
+
*/
|
155
|
+
export function parent(el) {
|
156
|
+
return el.parentNode;
|
157
|
+
}
|
package/lib/index.d.ts
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
* @param str 待验证的字符串
|
7
7
|
* @param ignoreWhitespace 是否忽略空格(包括空白字符串以及[\r\t\n]之类的制表符),默认为true
|
8
8
|
*/
|
9
|
-
export declare function isBlank(str?: string, ignoreWhitespace?: boolean): boolean;
|
9
|
+
export declare function isBlank(str?: string | null, ignoreWhitespace?: boolean): boolean;
|
10
10
|
/**
|
11
11
|
* 屏蔽手机号,中间部分用 * 展示
|
12
12
|
* @param mobile 待屏蔽的手机号
|
package/lib/index_m.d.ts
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
* @param str 待验证的字符串
|
7
7
|
* @param ignoreWhitespace 是否忽略空格(包括空白字符串以及[\r\t\n]之类的制表符),默认为true
|
8
8
|
*/
|
9
|
-
export declare function isBlank(str?: string, ignoreWhitespace?: boolean): boolean;
|
9
|
+
export declare function isBlank(str?: string | null, ignoreWhitespace?: boolean): boolean;
|
10
10
|
/**
|
11
11
|
* 屏蔽手机号,中间部分用 * 展示
|
12
12
|
* @param mobile 待屏蔽的手机号
|
package/lib/index_m.js
CHANGED
@@ -36,7 +36,7 @@ export function shieldMobile(mobile) {
|
|
36
36
|
* @returns true 是数字, false 不是数字
|
37
37
|
*/
|
38
38
|
export function isNumeric(str, numericParam) {
|
39
|
-
numericParam =
|
39
|
+
numericParam = { isPositive: false, isFloat: true, ...(numericParam || {}) };
|
40
40
|
let symbol = numericParam.isPositive ? '[+]?' : '[+-]?';
|
41
41
|
let main = numericParam.isFloat ? '([0-9]*[.])?[0-9]+' : '[0-9]+';
|
42
42
|
return new RegExp('^' + symbol + main + '$').test(str);
|
@@ -0,0 +1,44 @@
|
|
1
|
+
interface RuleItem {
|
2
|
+
rule: RegExp | ((v: any) => boolean);
|
3
|
+
message: string;
|
4
|
+
sameKey?: string;
|
5
|
+
}
|
6
|
+
/**
|
7
|
+
* 数据验证器,除了进行数据验证外,还可以同时进行数据转化
|
8
|
+
*/
|
9
|
+
declare class Validator {
|
10
|
+
rules: {
|
11
|
+
[index: string]: RuleItem[];
|
12
|
+
};
|
13
|
+
types: {
|
14
|
+
[index: string]: string | ((v: any) => void);
|
15
|
+
};
|
16
|
+
/**
|
17
|
+
* 构造数据验证转换器
|
18
|
+
* @param schemas 配置验证转换规则
|
19
|
+
*/
|
20
|
+
constructor(schemas: {
|
21
|
+
key: string;
|
22
|
+
type?: string | ((v: any) => void);
|
23
|
+
rules: string | RegExp | ((v: any) => boolean) | (RegExp | string | ((v: any) => boolean) | {
|
24
|
+
rule: string | RegExp | ((v: any) => boolean);
|
25
|
+
message?: string;
|
26
|
+
})[];
|
27
|
+
}[]);
|
28
|
+
/**
|
29
|
+
* 进行数据验证,同时根据 type 进行数据类型转换
|
30
|
+
* @param data 待验证的数据
|
31
|
+
* @returns
|
32
|
+
*/
|
33
|
+
validate<T>(data: any): Promise<unknown>;
|
34
|
+
/**
|
35
|
+
* 只验证指定 key 的数据格式
|
36
|
+
* @param key 指定待验证的 key
|
37
|
+
* @param value 待验证的数据
|
38
|
+
*/
|
39
|
+
validateKey(key: string, value: any): Promise<unknown>;
|
40
|
+
private _conversionType;
|
41
|
+
private _validateRule;
|
42
|
+
private _parseStringRule;
|
43
|
+
}
|
44
|
+
export = Validator;
|
package/lib/validator.js
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* 数据验证器
|
4
|
+
*/
|
5
|
+
// 默认的错误提示信息
|
6
|
+
const defaultMsgs = {
|
7
|
+
mobile: '请输入正确的手机号',
|
8
|
+
same: '两次输入不一致',
|
9
|
+
required: '%s为必填字段',
|
10
|
+
};
|
11
|
+
const defaultMsg = '请输入正确的数据';
|
12
|
+
// 允许的内置 type
|
13
|
+
const validTypes = new Set(['string', 'boolean', 'number', 'float', 'int']);
|
14
|
+
// 一些常用的验证正则
|
15
|
+
const ruleRegexs = {
|
16
|
+
/** 验证跟其余数据相等的正则,一般用于验证再次输入密码 */
|
17
|
+
same: /^same:(.+)$/i,
|
18
|
+
/** 验证手机号的正则表达式 */
|
19
|
+
mobile: /^1[34578]\d{9}$/,
|
20
|
+
/** 非空验证的正则表达式 */
|
21
|
+
required: /^\S{1}.*/,
|
22
|
+
};
|
23
|
+
// 规则比对函数
|
24
|
+
const ruleFns = {
|
25
|
+
/** 验证相等 */
|
26
|
+
same(val1, val2) {
|
27
|
+
return val2 === val1;
|
28
|
+
},
|
29
|
+
/** 正则匹配 */
|
30
|
+
pattern(regex, val) {
|
31
|
+
if (val == null) {
|
32
|
+
return false;
|
33
|
+
}
|
34
|
+
return regex.test(String(val));
|
35
|
+
},
|
36
|
+
};
|
37
|
+
const typeFns = {
|
38
|
+
string(v) {
|
39
|
+
return String(v);
|
40
|
+
},
|
41
|
+
boolean(v) {
|
42
|
+
return Boolean(v);
|
43
|
+
},
|
44
|
+
number(v) {
|
45
|
+
return Number(v);
|
46
|
+
},
|
47
|
+
int(v) {
|
48
|
+
return parseInt(v, 10);
|
49
|
+
},
|
50
|
+
floag(v) {
|
51
|
+
return parseFloat(v);
|
52
|
+
},
|
53
|
+
};
|
54
|
+
class ValidateError extends Error {
|
55
|
+
name;
|
56
|
+
constructor(msg) {
|
57
|
+
super(msg);
|
58
|
+
this.name = 'ValidateError';
|
59
|
+
}
|
60
|
+
}
|
61
|
+
/**
|
62
|
+
* 数据验证器,除了进行数据验证外,还可以同时进行数据转化
|
63
|
+
*/
|
64
|
+
class Validator {
|
65
|
+
rules;
|
66
|
+
types;
|
67
|
+
/**
|
68
|
+
* 构造数据验证转换器
|
69
|
+
* @param schemas 配置验证转换规则
|
70
|
+
*/
|
71
|
+
constructor(schemas) {
|
72
|
+
let parsedRules = {};
|
73
|
+
let types = {};
|
74
|
+
for (let schema of schemas) {
|
75
|
+
// 解析 types 用于进行数据类型转换
|
76
|
+
if (typeof schema.type === 'function') {
|
77
|
+
types[schema.key] = schema.type;
|
78
|
+
}
|
79
|
+
else {
|
80
|
+
types[schema.key] = validTypes.has(schema.type || '') ? schema.type : 'string';
|
81
|
+
}
|
82
|
+
// 解析规则
|
83
|
+
let rules = [];
|
84
|
+
let rule = schema.rules;
|
85
|
+
if (typeof rule === 'string') {
|
86
|
+
rules = rules.concat(this._parseStringRule(rule));
|
87
|
+
}
|
88
|
+
else if (rule instanceof Array) {
|
89
|
+
for (let ruleItem of rule) {
|
90
|
+
if (typeof ruleItem === 'string') {
|
91
|
+
rules = rules.concat(this._parseStringRule(ruleItem));
|
92
|
+
}
|
93
|
+
else if (ruleItem instanceof RegExp || typeof ruleItem === 'function') {
|
94
|
+
rules.push({ rule: ruleItem, message: defaultMsg });
|
95
|
+
}
|
96
|
+
else {
|
97
|
+
if (typeof ruleItem.rule === 'string') {
|
98
|
+
rules = rules.concat(this._parseStringRule(ruleItem.rule));
|
99
|
+
}
|
100
|
+
else {
|
101
|
+
rules.push({ rule: ruleItem.rule, message: ruleItem.message || defaultMsg });
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
else {
|
107
|
+
rules.push({ rule, message: defaultMsg });
|
108
|
+
}
|
109
|
+
parsedRules[schema.key] = rules;
|
110
|
+
}
|
111
|
+
this.types = types;
|
112
|
+
this.rules = parsedRules;
|
113
|
+
}
|
114
|
+
/**
|
115
|
+
* 进行数据验证,同时根据 type 进行数据类型转换
|
116
|
+
* @param data 待验证的数据
|
117
|
+
* @returns
|
118
|
+
*/
|
119
|
+
validate(data) {
|
120
|
+
return new Promise((resolve, reject) => {
|
121
|
+
let errMsg = '';
|
122
|
+
let resData = {};
|
123
|
+
for (let key in this.rules) {
|
124
|
+
if ({}.hasOwnProperty.call(this.rules, key)) {
|
125
|
+
errMsg = this._validateRule(this.rules[key], data[key], data);
|
126
|
+
if (errMsg === '') {
|
127
|
+
resData[key] = this._conversionType(this.types[key], data[key]);
|
128
|
+
}
|
129
|
+
else {
|
130
|
+
errMsg = errMsg.replace('%s', key);
|
131
|
+
break;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
}
|
135
|
+
if (errMsg === '') {
|
136
|
+
resolve(resData);
|
137
|
+
}
|
138
|
+
else {
|
139
|
+
reject(new ValidateError(errMsg));
|
140
|
+
}
|
141
|
+
});
|
142
|
+
}
|
143
|
+
/**
|
144
|
+
* 只验证指定 key 的数据格式
|
145
|
+
* @param key 指定待验证的 key
|
146
|
+
* @param value 待验证的数据
|
147
|
+
*/
|
148
|
+
validateKey(key, value) {
|
149
|
+
return new Promise((resolve, reject) => {
|
150
|
+
let keyRules = this.rules[key];
|
151
|
+
let errMsg = this._validateRule(keyRules, value, null);
|
152
|
+
if (errMsg === '') {
|
153
|
+
resolve(this._conversionType(this.types[key], value));
|
154
|
+
}
|
155
|
+
else {
|
156
|
+
errMsg = errMsg.replace('%s', key);
|
157
|
+
reject(new ValidateError(errMsg));
|
158
|
+
}
|
159
|
+
});
|
160
|
+
}
|
161
|
+
_conversionType(type, v) {
|
162
|
+
if (typeof type === 'function') {
|
163
|
+
return type(v);
|
164
|
+
}
|
165
|
+
else {
|
166
|
+
return typeFns[type](v);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
_validateRule(rules, value, data) {
|
170
|
+
let errMsg = '';
|
171
|
+
for (let rule of rules) {
|
172
|
+
if (typeof rule.rule === 'function') {
|
173
|
+
if (!rule.rule(value)) {
|
174
|
+
errMsg = rule.message;
|
175
|
+
}
|
176
|
+
}
|
177
|
+
else if (rule.sameKey != null) {
|
178
|
+
if (data != null) {
|
179
|
+
if (!ruleFns.same(value, data[rule.sameKey])) {
|
180
|
+
errMsg = rule.message;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
else {
|
185
|
+
if (!ruleFns.pattern(rule.rule, value)) {
|
186
|
+
errMsg = rule.message;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
if (errMsg !== '') {
|
190
|
+
break;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
return errMsg;
|
194
|
+
}
|
195
|
+
_parseStringRule(rule) {
|
196
|
+
let rules = [];
|
197
|
+
let trule = rule.split('|');
|
198
|
+
for (let r of trule) {
|
199
|
+
let message = defaultMsg;
|
200
|
+
let rrule;
|
201
|
+
let sameKey;
|
202
|
+
if (ruleRegexs.same.test(r)) {
|
203
|
+
let m = r.match(ruleRegexs.same);
|
204
|
+
if (m != null) {
|
205
|
+
rrule = ruleRegexs.same;
|
206
|
+
sameKey = r.match(ruleRegexs.same)[1];
|
207
|
+
message = defaultMsgs['same'];
|
208
|
+
}
|
209
|
+
}
|
210
|
+
else if (ruleRegexs.hasOwnProperty(r)) {
|
211
|
+
rrule = ruleRegexs[r];
|
212
|
+
message = defaultMsgs[r] || defaultMsg;
|
213
|
+
}
|
214
|
+
rules.push({ rule: rrule, message: message, sameKey });
|
215
|
+
}
|
216
|
+
return rules;
|
217
|
+
}
|
218
|
+
}
|
219
|
+
module.exports = Validator;
|
@@ -0,0 +1,44 @@
|
|
1
|
+
interface RuleItem {
|
2
|
+
rule: RegExp | ((v: any) => boolean);
|
3
|
+
message: string;
|
4
|
+
sameKey?: string;
|
5
|
+
}
|
6
|
+
/**
|
7
|
+
* 数据验证器,除了进行数据验证外,还可以同时进行数据转化
|
8
|
+
*/
|
9
|
+
declare class Validator {
|
10
|
+
rules: {
|
11
|
+
[index: string]: RuleItem[];
|
12
|
+
};
|
13
|
+
types: {
|
14
|
+
[index: string]: string | ((v: any) => void);
|
15
|
+
};
|
16
|
+
/**
|
17
|
+
* 构造数据验证转换器
|
18
|
+
* @param schemas 配置验证转换规则
|
19
|
+
*/
|
20
|
+
constructor(schemas: {
|
21
|
+
key: string;
|
22
|
+
type?: string | ((v: any) => void);
|
23
|
+
rules: string | RegExp | ((v: any) => boolean) | (RegExp | string | ((v: any) => boolean) | {
|
24
|
+
rule: string | RegExp | ((v: any) => boolean);
|
25
|
+
message?: string;
|
26
|
+
})[];
|
27
|
+
}[]);
|
28
|
+
/**
|
29
|
+
* 进行数据验证,同时根据 type 进行数据类型转换
|
30
|
+
* @param data 待验证的数据
|
31
|
+
* @returns
|
32
|
+
*/
|
33
|
+
validate<T>(data: any): Promise<unknown>;
|
34
|
+
/**
|
35
|
+
* 只验证指定 key 的数据格式
|
36
|
+
* @param key 指定待验证的 key
|
37
|
+
* @param value 待验证的数据
|
38
|
+
*/
|
39
|
+
validateKey(key: string, value: any): Promise<unknown>;
|
40
|
+
private _conversionType;
|
41
|
+
private _validateRule;
|
42
|
+
private _parseStringRule;
|
43
|
+
}
|
44
|
+
export default Validator;
|
@@ -0,0 +1,215 @@
|
|
1
|
+
/**
|
2
|
+
* 数据验证器
|
3
|
+
*/
|
4
|
+
// 默认的错误提示信息
|
5
|
+
const defaultMsgs = {
|
6
|
+
mobile: '请输入正确的手机号',
|
7
|
+
same: '两次输入不一致',
|
8
|
+
required: '%s为必填字段',
|
9
|
+
};
|
10
|
+
const defaultMsg = '请输入正确的数据';
|
11
|
+
// 允许的内置 type
|
12
|
+
const validTypes = new Set(['string', 'boolean', 'number', 'float', 'int']);
|
13
|
+
// 一些常用的验证正则
|
14
|
+
const ruleRegexs = {
|
15
|
+
/** 验证跟其余数据相等的正则,一般用于验证再次输入密码 */
|
16
|
+
same: /^same:(.+)$/i,
|
17
|
+
/** 验证手机号的正则表达式 */
|
18
|
+
mobile: /^1[34578]\d{9}$/,
|
19
|
+
/** 非空验证的正则表达式 */
|
20
|
+
required: /^\S{1}.*/,
|
21
|
+
};
|
22
|
+
// 规则比对函数
|
23
|
+
const ruleFns = {
|
24
|
+
/** 验证相等 */
|
25
|
+
same(val1, val2) {
|
26
|
+
return val2 === val1;
|
27
|
+
},
|
28
|
+
/** 正则匹配 */
|
29
|
+
pattern(regex, val) {
|
30
|
+
if (val == null) {
|
31
|
+
return false;
|
32
|
+
}
|
33
|
+
return regex.test(String(val));
|
34
|
+
},
|
35
|
+
};
|
36
|
+
const typeFns = {
|
37
|
+
string(v) {
|
38
|
+
return String(v);
|
39
|
+
},
|
40
|
+
boolean(v) {
|
41
|
+
return Boolean(v);
|
42
|
+
},
|
43
|
+
number(v) {
|
44
|
+
return Number(v);
|
45
|
+
},
|
46
|
+
int(v) {
|
47
|
+
return parseInt(v, 10);
|
48
|
+
},
|
49
|
+
floag(v) {
|
50
|
+
return parseFloat(v);
|
51
|
+
},
|
52
|
+
};
|
53
|
+
class ValidateError extends Error {
|
54
|
+
constructor(msg) {
|
55
|
+
super(msg);
|
56
|
+
this.name = 'ValidateError';
|
57
|
+
}
|
58
|
+
}
|
59
|
+
/**
|
60
|
+
* 数据验证器,除了进行数据验证外,还可以同时进行数据转化
|
61
|
+
*/
|
62
|
+
class Validator {
|
63
|
+
/**
|
64
|
+
* 构造数据验证转换器
|
65
|
+
* @param schemas 配置验证转换规则
|
66
|
+
*/
|
67
|
+
constructor(schemas) {
|
68
|
+
let parsedRules = {};
|
69
|
+
let types = {};
|
70
|
+
for (let schema of schemas) {
|
71
|
+
// 解析 types 用于进行数据类型转换
|
72
|
+
if (typeof schema.type === 'function') {
|
73
|
+
types[schema.key] = schema.type;
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
types[schema.key] = validTypes.has(schema.type || '') ? schema.type : 'string';
|
77
|
+
}
|
78
|
+
// 解析规则
|
79
|
+
let rules = [];
|
80
|
+
let rule = schema.rules;
|
81
|
+
if (typeof rule === 'string') {
|
82
|
+
rules = rules.concat(this._parseStringRule(rule));
|
83
|
+
}
|
84
|
+
else if (rule instanceof Array) {
|
85
|
+
for (let ruleItem of rule) {
|
86
|
+
if (typeof ruleItem === 'string') {
|
87
|
+
rules = rules.concat(this._parseStringRule(ruleItem));
|
88
|
+
}
|
89
|
+
else if (ruleItem instanceof RegExp || typeof ruleItem === 'function') {
|
90
|
+
rules.push({ rule: ruleItem, message: defaultMsg });
|
91
|
+
}
|
92
|
+
else {
|
93
|
+
if (typeof ruleItem.rule === 'string') {
|
94
|
+
rules = rules.concat(this._parseStringRule(ruleItem.rule));
|
95
|
+
}
|
96
|
+
else {
|
97
|
+
rules.push({ rule: ruleItem.rule, message: ruleItem.message || defaultMsg });
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
else {
|
103
|
+
rules.push({ rule, message: defaultMsg });
|
104
|
+
}
|
105
|
+
parsedRules[schema.key] = rules;
|
106
|
+
}
|
107
|
+
this.types = types;
|
108
|
+
this.rules = parsedRules;
|
109
|
+
}
|
110
|
+
/**
|
111
|
+
* 进行数据验证,同时根据 type 进行数据类型转换
|
112
|
+
* @param data 待验证的数据
|
113
|
+
* @returns
|
114
|
+
*/
|
115
|
+
validate(data) {
|
116
|
+
return new Promise((resolve, reject) => {
|
117
|
+
let errMsg = '';
|
118
|
+
let resData = {};
|
119
|
+
for (let key in this.rules) {
|
120
|
+
if ({}.hasOwnProperty.call(this.rules, key)) {
|
121
|
+
errMsg = this._validateRule(this.rules[key], data[key], data);
|
122
|
+
if (errMsg === '') {
|
123
|
+
resData[key] = this._conversionType(this.types[key], data[key]);
|
124
|
+
}
|
125
|
+
else {
|
126
|
+
errMsg = errMsg.replace('%s', key);
|
127
|
+
break;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
if (errMsg === '') {
|
132
|
+
resolve(resData);
|
133
|
+
}
|
134
|
+
else {
|
135
|
+
reject(new ValidateError(errMsg));
|
136
|
+
}
|
137
|
+
});
|
138
|
+
}
|
139
|
+
/**
|
140
|
+
* 只验证指定 key 的数据格式
|
141
|
+
* @param key 指定待验证的 key
|
142
|
+
* @param value 待验证的数据
|
143
|
+
*/
|
144
|
+
validateKey(key, value) {
|
145
|
+
return new Promise((resolve, reject) => {
|
146
|
+
let keyRules = this.rules[key];
|
147
|
+
let errMsg = this._validateRule(keyRules, value, null);
|
148
|
+
if (errMsg === '') {
|
149
|
+
resolve(this._conversionType(this.types[key], value));
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
errMsg = errMsg.replace('%s', key);
|
153
|
+
reject(new ValidateError(errMsg));
|
154
|
+
}
|
155
|
+
});
|
156
|
+
}
|
157
|
+
_conversionType(type, v) {
|
158
|
+
if (typeof type === 'function') {
|
159
|
+
return type(v);
|
160
|
+
}
|
161
|
+
else {
|
162
|
+
return typeFns[type](v);
|
163
|
+
}
|
164
|
+
}
|
165
|
+
_validateRule(rules, value, data) {
|
166
|
+
let errMsg = '';
|
167
|
+
for (let rule of rules) {
|
168
|
+
if (typeof rule.rule === 'function') {
|
169
|
+
if (!rule.rule(value)) {
|
170
|
+
errMsg = rule.message;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
else if (rule.sameKey != null) {
|
174
|
+
if (data != null) {
|
175
|
+
if (!ruleFns.same(value, data[rule.sameKey])) {
|
176
|
+
errMsg = rule.message;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
}
|
180
|
+
else {
|
181
|
+
if (!ruleFns.pattern(rule.rule, value)) {
|
182
|
+
errMsg = rule.message;
|
183
|
+
}
|
184
|
+
}
|
185
|
+
if (errMsg !== '') {
|
186
|
+
break;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
return errMsg;
|
190
|
+
}
|
191
|
+
_parseStringRule(rule) {
|
192
|
+
let rules = [];
|
193
|
+
let trule = rule.split('|');
|
194
|
+
for (let r of trule) {
|
195
|
+
let message = defaultMsg;
|
196
|
+
let rrule;
|
197
|
+
let sameKey;
|
198
|
+
if (ruleRegexs.same.test(r)) {
|
199
|
+
let m = r.match(ruleRegexs.same);
|
200
|
+
if (m != null) {
|
201
|
+
rrule = ruleRegexs.same;
|
202
|
+
sameKey = r.match(ruleRegexs.same)[1];
|
203
|
+
message = defaultMsgs['same'];
|
204
|
+
}
|
205
|
+
}
|
206
|
+
else if (ruleRegexs.hasOwnProperty(r)) {
|
207
|
+
rrule = ruleRegexs[r];
|
208
|
+
message = defaultMsgs[r] || defaultMsg;
|
209
|
+
}
|
210
|
+
rules.push({ rule: rrule, message: message, sameKey });
|
211
|
+
}
|
212
|
+
return rules;
|
213
|
+
}
|
214
|
+
}
|
215
|
+
export default Validator;
|