ph-utils 0.1.5 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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` 一些只适用于前端相关的工具 s
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 属性
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
- return (dom || document).querySelectorAll(selector);
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,14 +62,14 @@ 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
- eventExtra.once = true;
67
+ eventExtra.once = once;
63
68
  }
64
69
  else {
65
70
  eventExtra = once;
66
71
  }
67
- if (eventExtra.eventFlag !== null) {
72
+ if (eventExtra.eventFlag != null) {
68
73
  element.setAttribute(eventExtra.eventFlag, '__stop__');
69
74
  element.addEventListener(listener, (e) => {
70
75
  let target = e.target;
@@ -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);
@@ -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;
@@ -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;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "module": "lib/index_m.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "browser": "lib/index_m.js",
8
- "version": "0.1.5",
8
+ "version": "0.2.1",
9
9
  "repository": {
10
10
  "type": "git",
11
11
  "url": "git+https//gitee.com/towardly/ph.git",