util-helpers 4.8.2 → 4.10.0

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.
Files changed (54) hide show
  1. package/README.md +3 -1
  2. package/dist/util-helpers.js +192 -131
  3. package/dist/util-helpers.js.map +1 -1
  4. package/dist/util-helpers.min.js +1 -1
  5. package/dist/util-helpers.min.js.map +1 -1
  6. package/esm/index.js +2 -0
  7. package/esm/isBankCard.js +7 -7
  8. package/esm/isBusinessLicense.js +2 -2
  9. package/esm/isChinese.js +2 -2
  10. package/esm/isEmail.js +2 -2
  11. package/esm/isHMCard.js +2 -2
  12. package/esm/isIPv4.js +2 -2
  13. package/esm/isIPv6.js +2 -2
  14. package/esm/isIdCard.js +2 -2
  15. package/esm/isMobile.js +2 -2
  16. package/esm/isPassport.js +2 -2
  17. package/esm/isPostcode.js +2 -2
  18. package/esm/isQQ.js +2 -2
  19. package/esm/isSocialCreditCode.js +2 -2
  20. package/esm/isSwiftCode.js +29 -0
  21. package/esm/isTWCard.js +2 -2
  22. package/esm/isTelephone.js +2 -2
  23. package/esm/isUrl.js +3 -3
  24. package/esm/isVehicle.js +2 -2
  25. package/esm/isWX.js +2 -2
  26. package/esm/randomString.js +1 -1
  27. package/esm/strlen.js +38 -0
  28. package/lib/index.js +16 -0
  29. package/lib/isBankCard.js +7 -7
  30. package/lib/isBusinessLicense.js +2 -2
  31. package/lib/isChinese.js +2 -2
  32. package/lib/isEmail.js +2 -2
  33. package/lib/isHMCard.js +2 -2
  34. package/lib/isIPv4.js +2 -2
  35. package/lib/isIPv6.js +2 -2
  36. package/lib/isIdCard.js +2 -2
  37. package/lib/isMobile.js +2 -2
  38. package/lib/isPassport.js +2 -2
  39. package/lib/isPostcode.js +2 -2
  40. package/lib/isQQ.js +2 -2
  41. package/lib/isSocialCreditCode.js +2 -2
  42. package/lib/isSwiftCode.js +40 -0
  43. package/lib/isTWCard.js +2 -2
  44. package/lib/isTelephone.js +2 -2
  45. package/lib/isUrl.js +3 -3
  46. package/lib/isVehicle.js +2 -2
  47. package/lib/isWX.js +2 -2
  48. package/lib/randomString.js +1 -1
  49. package/lib/strlen.js +48 -0
  50. package/package.json +2 -1
  51. package/types/index.d.ts +2 -0
  52. package/types/isSwiftCode.d.ts +22 -0
  53. package/types/randomString.d.ts +1 -1
  54. package/types/strlen.d.ts +20 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # util-helpers
2
2
 
3
- [![npm][npm]][npm-url] ![GitHub](https://img.shields.io/github/license/doly-dev/util-helpers.svg) [![Build Status](https://travis-ci.org/doly-dev/util-helpers.svg?branch=master)](https://travis-ci.org/doly-dev/util-helpers)
3
+ [![npm][npm]][npm-url] ![GitHub](https://img.shields.io/github/license/doly-dev/util-helpers.svg)
4
4
 
5
5
  [util-helpers](https://doly-dev.github.io/util-helpers/index.html) 是一个基于业务场景的工具方法库。
6
6
 
@@ -70,6 +70,7 @@ formatMoney('1000'); // => 1,000.00
70
70
  - [isVehicle](https://doly-dev.github.io/util-helpers/module-Validator.html#.isVehicle) - 车牌号
71
71
  - [isBankCard](https://doly-dev.github.io/util-helpers/module-Validator.html#.isBankCard) - 银行卡
72
72
  - [isSocialCreditCode](https://doly-dev.github.io/util-helpers/module-Validator.html#.isSocialCreditCode) - 统一社会信用代码,也叫三证合一组织代码
73
+ - [isSwiftCode](https://doly-dev.github.io/util-helpers/module-Validator.html#.isSwiftCode) - Swift Code
73
74
  - [isPassword](https://doly-dev.github.io/util-helpers/module-Validator.html#.isPassword) 密码强度
74
75
  - [isPassport](https://doly-dev.github.io/util-helpers/module-Validator.html#.isPassport) - 护照号
75
76
  - [isPromiseLike](https://doly-dev.github.io/util-helpers/module-Validator.html#.isPromiseLike) - 类似 Promise 对象
@@ -82,6 +83,7 @@ formatMoney('1000'); // => 1,000.00
82
83
  - 其他
83
84
  - [calculateCursorPosition](https://doly-dev.github.io/util-helpers/module-Other.html#.calculateCursorPosition) - 计算光标位置
84
85
  - [randomString](https://doly-dev.github.io/util-helpers/module-Other.html#.randomString) - 随机字符串
86
+ - [strlen](https://doly-dev.github.io/util-helpers/module-Other.html#.strlen) - 字符长度
85
87
  - [waitTime](https://doly-dev.github.io/util-helpers/module-Other.html#.waitTime) - 等待时间返回 Promise
86
88
 
87
89
  ## 精选第三方工具库
@@ -4,6 +4,62 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.utilHelpers = {}));
5
5
  }(this, (function (exports) { 'use strict';
6
6
 
7
+ /**
8
+ * 检查值是否为Undefined
9
+ *
10
+ * @static
11
+ * @alias module:Type.isUndefined
12
+ * @since 1.1.0
13
+ * @param {*} value 检查值
14
+ * @returns {boolean} 是否为Undefined
15
+ * @example
16
+ *
17
+ * isUndefined(undefined)
18
+ * // => true
19
+ *
20
+ * isUndefined(void 0)
21
+ * // => true
22
+ *
23
+ * isUndefined(null)
24
+ * // => false
25
+ */
26
+ function isUndefined(value) {
27
+ return value === void 0;
28
+ }
29
+
30
+ /**
31
+ * 检查值是否为Null
32
+ *
33
+ * @static
34
+ * @alias module:Type.isNull
35
+ * @since 1.1.0
36
+ * @param {*} value 检查值
37
+ * @returns {boolean} 是否为Null
38
+ * @example
39
+ *
40
+ * isNull(null)
41
+ * // => true
42
+ *
43
+ * isNull(void 0)
44
+ * // => false
45
+ */
46
+ function isNull(value) {
47
+ return value === null;
48
+ }
49
+
50
+ /**
51
+ * 检查值是否为 undefined 或 null
52
+ *
53
+ * @static
54
+ * @alias module:Type.isNaN
55
+ * @since 4.3.0
56
+ * @param {*} value 检查值
57
+ * @returns {boolean} 是否为 undefined 或 null
58
+ */
59
+ function isNil(value) {
60
+ return isUndefined(value) || isNull(value);
61
+ }
62
+
7
63
  const toString = Object.prototype.toString;
8
64
 
9
65
  /**
@@ -49,8 +105,35 @@
49
105
  return isString(value) ? value : String(value);
50
106
  }
51
107
 
108
+ /**
109
+ * 规整化字符串。如果值为 undefined 或 null 将转为空字符串,如果值不是字符串类型将转为字符串。
110
+ *
111
+ * @static
112
+ * @alias module:Processor.normalizeString
113
+ * @see 参考 {@link https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String#string_instances|String}
114
+ * @since 4.3.0
115
+ * @param {*} value 待处理的值
116
+ * @returns {string} 规整化的值
117
+ * @example
118
+ * normalizeString(); // ''
119
+ * normalizeString(undefined); // ''
120
+ * normalizeString(void 0); // ''
121
+ * normalizeString(null); // ''
122
+ *
123
+ * normalizeString(true); // 'true'
124
+ * normalizeString(NaN); // 'NaN'
125
+ * normalizeString(1); // '1'
126
+ * normalizeString('a'); // 'a'
127
+ */
128
+ function normalizeString(value) {
129
+ if (isNil(value)) {
130
+ return '';
131
+ }
132
+ return convertToString(value);
133
+ }
134
+
52
135
  // 手机号码 11位数字,以1开头,第二位是3456789其中一个,后面再加9个数字
53
- const reg$c = /^1[3456789]\d{9}$/;
136
+ const reg$d = /^1[3456789]\d{9}$/;
54
137
 
55
138
  /**
56
139
  * 检测值是否为手机号码
@@ -70,12 +153,12 @@
70
153
  *
71
154
  */
72
155
  function isMobile(value) {
73
- const valueStr = convertToString(value);
74
- return reg$c.test(valueStr);
156
+ const valueStr = normalizeString(value);
157
+ return reg$d.test(valueStr);
75
158
  }
76
159
 
77
160
  // 固定电话 支持区号和分机号 3~4位区号,以0开头;7~8位直播号,以2~9开头;1~6位分机号
78
- const reg$b = /^(0\d{2,3}\-)?([2-9]\d{6,7})(\-\d{1,6})?$/;
161
+ const reg$c = /^(0\d{2,3}\-)?([2-9]\d{6,7})(\-\d{1,6})?$/;
79
162
 
80
163
  /**
81
164
  * 检测值是否为固定电话
@@ -101,12 +184,12 @@
101
184
  *
102
185
  */
103
186
  function isTelephone(value) {
104
- const valueStr = convertToString(value);
105
- return reg$b.test(valueStr);
187
+ const valueStr = normalizeString(value);
188
+ return reg$c.test(valueStr);
106
189
  }
107
190
 
108
191
  // 邮政编码
109
- const reg$a = /^\d{6}$/;
192
+ const reg$b = /^\d{6}$/;
110
193
 
111
194
  /**
112
195
  * 检测值是否为邮政编码,6位数字
@@ -126,8 +209,8 @@
126
209
  *
127
210
  */
128
211
  function isPostcode(value) {
129
- const valueStr = convertToString(value);
130
- return reg$a.test(valueStr);
212
+ const valueStr = normalizeString(value);
213
+ return reg$b.test(valueStr);
131
214
  }
132
215
 
133
216
  // 身份证号正则
@@ -185,7 +268,7 @@
185
268
  *
186
269
  */
187
270
  function isIdCard(value, { loose = false, checkCode = true } = {}) {
188
- const valueStr = convertToString(value);
271
+ const valueStr = normalizeString(value);
189
272
  if (valueStr.length === 15 && loose) {
190
273
  return regIdCard$1.test(valueStr);
191
274
  }
@@ -201,7 +284,7 @@
201
284
  }
202
285
 
203
286
  // 邮箱
204
- const reg$9 = /^[\da-z]+([\-\.\_]?[\da-z]+)*@[\da-z]+([\-\.]?[\da-z]+)*(\.[a-z]{2,})+$/i;
287
+ const reg$a = /^[\da-z]+([\-\.\_]?[\da-z]+)*@[\da-z]+([\-\.]?[\da-z]+)*(\.[a-z]{2,})+$/i;
205
288
 
206
289
  /**
207
290
  * 检测值是否为Email
@@ -221,12 +304,12 @@
221
304
  *
222
305
  */
223
306
  function isEmail(value) {
224
- const valueStr = convertToString(value);
225
- return reg$9.test(valueStr);
307
+ const valueStr = normalizeString(value);
308
+ return reg$a.test(valueStr);
226
309
  }
227
310
 
228
311
  // QQ号正则
229
- const reg$8 = /^[1-9]\d{4,10}$/;
312
+ const reg$9 = /^[1-9]\d{4,10}$/;
230
313
 
231
314
  /**
232
315
  * 检测值是否为QQ号,非0开头,5至11位数字
@@ -246,12 +329,12 @@
246
329
  *
247
330
  */
248
331
  function isQQ(value) {
249
- const valueStr = convertToString(value);
250
- return reg$8.test(valueStr);
332
+ const valueStr = normalizeString(value);
333
+ return reg$9.test(valueStr);
251
334
  }
252
335
 
253
336
  // 微信号 6至20位,以字母开头,字母,数字,减号(连接符),下划线
254
- const reg$7 = /^[a-z]([-_a-z0-9]{5,19})+$/i;
337
+ const reg$8 = /^[a-z]([-_a-z0-9]{5,19})+$/i;
255
338
 
256
339
  /**
257
340
  * 检测值是否为微信号
@@ -271,12 +354,12 @@
271
354
  *
272
355
  */
273
356
  function isWX(value) {
274
- const valueStr = convertToString(value);
275
- return reg$7.test(valueStr);
357
+ const valueStr = normalizeString(value);
358
+ return reg$8.test(valueStr);
276
359
  }
277
360
 
278
361
  // 车牌号正则
279
- const reg$6 = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([A-Z0-9]{4}[A-Z0-9挂学警港澳]{1})|([A-Z0-9]{5}[DF])|([DF][A-Z0-9]{5}))$/;
362
+ const reg$7 = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([A-Z0-9]{4}[A-Z0-9挂学警港澳]{1})|([A-Z0-9]{5}[DF])|([DF][A-Z0-9]{5}))$/;
280
363
 
281
364
  /**
282
365
  * 检测值是否为车牌号,支持新能源和非新能源车牌
@@ -306,24 +389,24 @@
306
389
  *
307
390
  */
308
391
  function isVehicle(value) {
309
- const valueStr = convertToString(value);
310
- return reg$6.test(valueStr);
392
+ const valueStr = normalizeString(value);
393
+ return reg$7.test(valueStr);
311
394
  }
312
395
 
313
396
  // 非0开头,10~21位数字
314
- const reg$5 = /^[1-9]\d{9,20}$/;
397
+ const reg$6 = /^[1-9]\d{9,20}$/;
315
398
 
316
399
  // 8~30位数字
317
400
  const regLoose = /^\d{8,30}$/;
318
401
 
319
402
  /**
320
403
  * luhn 计算校验位
321
- *
322
- * @param {string} num 银行卡前面数字
323
- * @returns
404
+ * @private
405
+ * @param {string} numStr 银行卡前面数字
406
+ * @returns {number}
324
407
  */
325
- function sumCheckCode$2(num) {
326
- const numArr = (num + '').replace(/\D/g, '').split('').reverse();
408
+ function sumCheckCode$2(numStr) {
409
+ const numArr = (numStr + '').replace(/\D/g, '').split('').reverse();
327
410
 
328
411
  let sum = 0;
329
412
  for (let i = 0; i < numArr.length; i++) {
@@ -362,8 +445,8 @@
362
445
  *
363
446
  */
364
447
  function isBankCard(value, { loose = false, luhn = false } = {}) {
365
- const valueStr = convertToString(value);
366
- const validateResult = loose ? regLoose.test(valueStr) : reg$5.test(valueStr);
448
+ const valueStr = normalizeString(value);
449
+ const validateResult = loose ? regLoose.test(valueStr) : reg$6.test(valueStr);
367
450
 
368
451
  if (validateResult && luhn) {
369
452
  const precode = valueStr.substring(0, valueStr.length - 1);
@@ -433,7 +516,7 @@
433
516
  *
434
517
  */
435
518
  function isSocialCreditCode(value, { loose = false } = {}) {
436
- const valueStr = convertToString(value);
519
+ const valueStr = normalizeString(value);
437
520
 
438
521
  const passBaseRule = baseReg$1.test(valueStr);
439
522
 
@@ -771,7 +854,7 @@
771
854
  }
772
855
 
773
856
  // 护照号 9位,包括首字母和数字;支持 普通护照(E*)、外交护照(DE)、公务护照(SE)、公务普通护照(PE)、香港特区护照(K/KJ)、澳门特区护照(MA)
774
- const reg$4 = /^((e[\da-z])|(de)|(se)|(pe)|(k[\da-z])|(kj)|(ma))[\da-z]{7}$/i;
857
+ const reg$5 = /^((e[\da-z])|(de)|(se)|(pe)|(k[\da-z])|(kj)|(ma))[\da-z]{7}$/i;
775
858
 
776
859
  /**
777
860
  * 检测值是否为护照号
@@ -793,8 +876,8 @@
793
876
  *
794
877
  */
795
878
  function isPassport(value) {
796
- const valueStr = convertToString(value);
797
- return reg$4.test(valueStr);
879
+ const valueStr = normalizeString(value);
880
+ return reg$5.test(valueStr);
798
881
  }
799
882
 
800
883
  const chineseDictionary = {
@@ -863,13 +946,13 @@
863
946
  *
864
947
  */
865
948
  function isChinese(value, { loose = false } = {}) {
866
- const valueStr = convertToString(value);
949
+ const valueStr = normalizeString(value);
867
950
  const reg = new RegExp(loose ? looseChineseRegExp : chineseRegExp, supportRegExpUnicode ? 'u' : undefined);
868
951
  return reg.test(valueStr);
869
952
  }
870
953
 
871
954
  // ipv4正则
872
- const reg$3 = /^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
955
+ const reg$4 = /^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
873
956
 
874
957
  /**
875
958
  * 检测值是否为ipv4
@@ -895,12 +978,12 @@
895
978
  *
896
979
  */
897
980
  function isIPv4(value) {
898
- const valueStr = convertToString(value);
899
- return reg$3.test(valueStr);
981
+ const valueStr = normalizeString(value);
982
+ return reg$4.test(valueStr);
900
983
  }
901
984
 
902
985
  // ipv6正则
903
- const reg$2 = /^((([0-9A-F]{1,4}:){7}([0-9A-F]{1,4}|:))|(([0-9A-F]{1,4}:){6}(:[0-9A-F]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3})|:))|(([0-9A-F]{1,4}:){5}(((:[0-9A-F]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3})|:))|(([0-9A-F]{1,4}:){4}(((:[0-9A-F]{1,4}){1,3})|((:[0-9A-F]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:))|(([0-9A-F]{1,4}:){3}(((:[0-9A-F]{1,4}){1,4})|((:[0-9A-F]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:))|(([0-9A-F]{1,4}:){2}(((:[0-9A-F]{1,4}){1,5})|((:[0-9A-F]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:))|(([0-9A-F]{1,4}:){1}(((:[0-9A-F]{1,4}){1,6})|((:[0-9A-F]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:))|(:(((:[0-9A-F]{1,4}){1,7})|((:[0-9A-F]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:)))(%.+)?$/i;
986
+ const reg$3 = /^((([0-9A-F]{1,4}:){7}([0-9A-F]{1,4}|:))|(([0-9A-F]{1,4}:){6}(:[0-9A-F]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3})|:))|(([0-9A-F]{1,4}:){5}(((:[0-9A-F]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3})|:))|(([0-9A-F]{1,4}:){4}(((:[0-9A-F]{1,4}){1,3})|((:[0-9A-F]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:))|(([0-9A-F]{1,4}:){3}(((:[0-9A-F]{1,4}){1,4})|((:[0-9A-F]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:))|(([0-9A-F]{1,4}:){2}(((:[0-9A-F]{1,4}){1,5})|((:[0-9A-F]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:))|(([0-9A-F]{1,4}:){1}(((:[0-9A-F]{1,4}){1,6})|((:[0-9A-F]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:))|(:(((:[0-9A-F]{1,4}){1,7})|((:[0-9A-F]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|\d{1,2})(\.(25[0-5]|2[0-4]\d|1\d\d|\d{1,2})){3}))|:)))(%.+)?$/i;
904
987
 
905
988
  /**
906
989
  * 检测值是否为ipv6
@@ -951,12 +1034,12 @@
951
1034
  *
952
1035
  */
953
1036
  function isIPv6(value) {
954
- const valueStr = convertToString(value);
955
- return reg$2.test(valueStr);
1037
+ const valueStr = normalizeString(value);
1038
+ return reg$3.test(valueStr);
956
1039
  }
957
1040
 
958
1041
  // url正则
959
- const reg$1 = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
1042
+ const reg$2 = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\*\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
960
1043
 
961
1044
  /**
962
1045
  * 检测值是否为url
@@ -991,8 +1074,8 @@
991
1074
  * // => true
992
1075
  */
993
1076
  function isUrl(value) {
994
- const valueStr = convertToString(value);
995
- return reg$1.test(valueStr);
1077
+ const valueStr = normalizeString(value);
1078
+ return reg$2.test(valueStr);
996
1079
  }
997
1080
 
998
1081
  // 基础规则,由14位数字本体码和1位数字校验码组成,其中本体码从左至右依次为:6位首次登记机关码、8位顺序码。
@@ -1058,7 +1141,7 @@
1058
1141
  * // => true
1059
1142
  */
1060
1143
  function isBusinessLicense(value, { loose = false } = {}) {
1061
- const valueStr = convertToString(value);
1144
+ const valueStr = normalizeString(value);
1062
1145
 
1063
1146
  const passBaseRule = baseReg.test(valueStr);
1064
1147
 
@@ -1126,7 +1209,7 @@
1126
1209
  * isHMCard('M32031177') // true
1127
1210
  */
1128
1211
  function isHMCard(value) {
1129
- const valueStr = convertToString(value);
1212
+ const valueStr = normalizeString(value);
1130
1213
  return regHMCard.test(valueStr);
1131
1214
  }
1132
1215
 
@@ -1150,10 +1233,37 @@
1150
1233
  * isTWCard('F290299977') // true
1151
1234
  */
1152
1235
  function isTWCard(value) {
1153
- const valueStr = convertToString(value);
1236
+ const valueStr = normalizeString(value);
1154
1237
  return regTWCard.test(valueStr);
1155
1238
  }
1156
1239
 
1240
+ const reg$1 = /^[A-Z]{6}[A-Z\d]{2}(?:[A-Z\d]{3})?$/;
1241
+
1242
+ /**
1243
+ * 检测值是否为 Swift Code。8位或11位,前6位为大写字母,7-8位为大写字母或数字,9-11位为可选的大写字母或数字。
1244
+ *
1245
+ * @static
1246
+ * @alias module:Validator.isSwiftCode
1247
+ * @see 参考 {@link https://zh.wikipedia.org/wiki/ISO_9362|ISO 9362}
1248
+ * @since 4.9.0
1249
+ * @param {*} value 要检测的值
1250
+ * @returns {boolean} 值是否为 Swift Code
1251
+ * @example
1252
+ *
1253
+ * isSwiftCode('DEUTDEFF') // true
1254
+ * isSwiftCode('deutdeff') // false
1255
+ *
1256
+ * isSwiftCode('BKTWTWTP010') // true
1257
+ * isSwiftCode('010BKTWTWTP') // false
1258
+ *
1259
+ * isSwiftCode('ICBKCNBJBJM') // true
1260
+ *
1261
+ */
1262
+ function isSwiftCode(value) {
1263
+ const valueStr = normalizeString(value);
1264
+ return reg$1.test(valueStr);
1265
+ }
1266
+
1157
1267
  // 最大安全数字
1158
1268
  const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
1159
1269
  // 最小安全数字
@@ -1455,89 +1565,6 @@
1455
1565
  return symbol + formatInt(intStr, thousand) + formatDec(decStr, precision, decimal);
1456
1566
  };
1457
1567
 
1458
- /**
1459
- * 检查值是否为Undefined
1460
- *
1461
- * @static
1462
- * @alias module:Type.isUndefined
1463
- * @since 1.1.0
1464
- * @param {*} value 检查值
1465
- * @returns {boolean} 是否为Undefined
1466
- * @example
1467
- *
1468
- * isUndefined(undefined)
1469
- * // => true
1470
- *
1471
- * isUndefined(void 0)
1472
- * // => true
1473
- *
1474
- * isUndefined(null)
1475
- * // => false
1476
- */
1477
- function isUndefined(value) {
1478
- return value === void 0;
1479
- }
1480
-
1481
- /**
1482
- * 检查值是否为Null
1483
- *
1484
- * @static
1485
- * @alias module:Type.isNull
1486
- * @since 1.1.0
1487
- * @param {*} value 检查值
1488
- * @returns {boolean} 是否为Null
1489
- * @example
1490
- *
1491
- * isNull(null)
1492
- * // => true
1493
- *
1494
- * isNull(void 0)
1495
- * // => false
1496
- */
1497
- function isNull(value) {
1498
- return value === null;
1499
- }
1500
-
1501
- /**
1502
- * 检查值是否为 undefined 或 null
1503
- *
1504
- * @static
1505
- * @alias module:Type.isNaN
1506
- * @since 4.3.0
1507
- * @param {*} value 检查值
1508
- * @returns {boolean} 是否为 undefined 或 null
1509
- */
1510
- function isNil(value) {
1511
- return isUndefined(value) || isNull(value);
1512
- }
1513
-
1514
- /**
1515
- * 规整化字符串。如果值为 undefined 或 null 将转为空字符串,如果值不是字符串类型将转为字符串。
1516
- *
1517
- * @static
1518
- * @alias module:Processor.normalizeString
1519
- * @see 参考 {@link https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String#string_instances|String}
1520
- * @since 4.3.0
1521
- * @param {*} value 待处理的值
1522
- * @returns {string} 规整化的值
1523
- * @example
1524
- * normalizeString(); // ''
1525
- * normalizeString(undefined); // ''
1526
- * normalizeString(void 0); // ''
1527
- * normalizeString(null); // ''
1528
- *
1529
- * normalizeString(true); // 'true'
1530
- * normalizeString(NaN); // 'NaN'
1531
- * normalizeString(1); // '1'
1532
- * normalizeString('a'); // 'a'
1533
- */
1534
- function normalizeString(value) {
1535
- if (isNil(value)) {
1536
- return '';
1537
- }
1538
- return convertToString(value);
1539
- }
1540
-
1541
1568
  /**
1542
1569
  * 格式化银行卡号
1543
1570
  *
@@ -2620,7 +2647,7 @@
2620
2647
  * @alias module:Other.randomString
2621
2648
  * @since 4.8.0
2622
2649
  * @param {number} [len=0] 长度
2623
- * @param {string} [optionalChars] 允许的字符,默认为数字和大小写字母
2650
+ * @param {string} [optionalChars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'] 允许的字符,默认为数字和大小写字母
2624
2651
  * @returns {string} 随机字符串
2625
2652
  * @example
2626
2653
  * randomString(5); // slk23
@@ -2637,6 +2664,38 @@
2637
2664
  return internalRandomString(len, realChars);
2638
2665
  }
2639
2666
 
2667
+ /**
2668
+ * 获取字符长度。中文汉字占2个字符,英文占1个字符,特殊如emoji占4个字符。
2669
+ *
2670
+ * @static
2671
+ * @alias module:Other.strlen
2672
+ * @since 4.10.0
2673
+ * @param {string} str 字符串
2674
+ * @returns {number} 字符长度
2675
+ * @example
2676
+ *
2677
+ * strlen('你好a'); // 5
2678
+ * strlen('你好,世界!'); // 12
2679
+ * strlen('严両丞丽'); // 8
2680
+ * strlen('abcde'); // 5
2681
+ * strlen('𠮷'); // 4
2682
+ * strlen('🍎'); // 4
2683
+ *
2684
+ */
2685
+ function strlen(str) {
2686
+ const realStr = normalizeString(str);
2687
+ let len = 0;
2688
+ for (let i = 0; i < realStr.length; i++) {
2689
+ const c = realStr.charCodeAt(i);
2690
+ if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
2691
+ len++;
2692
+ } else {
2693
+ len += 2;
2694
+ }
2695
+ }
2696
+ return len;
2697
+ }
2698
+
2640
2699
  exports.blobToDataURL = blobToDataURL;
2641
2700
  exports.bytesToSize = bytesToSize;
2642
2701
  exports.calculateCursorPosition = calculateCursorPosition;
@@ -2660,6 +2719,7 @@
2660
2719
  exports.isPromiseLike = isPromiseLike;
2661
2720
  exports.isQQ = isQQ;
2662
2721
  exports.isSocialCreditCode = isSocialCreditCode;
2722
+ exports.isSwiftCode = isSwiftCode;
2663
2723
  exports.isTWCard = isTWCard;
2664
2724
  exports.isTelephone = isTelephone;
2665
2725
  exports.isUrl = isUrl;
@@ -2677,6 +2737,7 @@
2677
2737
  exports.safeDate = safeDate;
2678
2738
  exports.setDataURLPrefix = setDataURLPrefix;
2679
2739
  exports.setDisableWarning = setDisableWarning;
2740
+ exports.strlen = strlen;
2680
2741
  exports.times = times;
2681
2742
  exports.validatePassword = validatePassword;
2682
2743
  exports.waitTime = waitTime;