@jhqn/utils-core 0.0.3-beta.1 → 0.0.3-beta.11

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/dist/index.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  export { detect } from 'detect-browser';
2
2
  import dayjs from 'dayjs';
3
3
  export { default as dayjs } from 'dayjs';
4
- import localeData from 'dayjs/plugin/localeData';
5
- import duration from 'dayjs/plugin/duration';
6
- import relativeTime from 'dayjs/plugin/relativeTime';
4
+ import zhCN from 'dayjs/locale/zh-cn';
7
5
  import customParseFormat from 'dayjs/plugin/customParseFormat';
6
+ import duration from 'dayjs/plugin/duration';
7
+ import localeData from 'dayjs/plugin/localeData';
8
8
  import objectSupport from 'dayjs/plugin/objectSupport';
9
- import zhCN from 'dayjs/locale/zh-cn';
9
+ import relativeTime from 'dayjs/plugin/relativeTime';
10
10
 
11
11
  const snake2Kebab = (str) => str.replace(/_([a-z])/g, (_, letter) => `-${letter.toLowerCase()}`);
12
12
  const snake2Pascal = (str) => str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/^[a-z]/, (letter) => letter.toUpperCase());
@@ -104,22 +104,26 @@ const isURL = (val) => getVariableType(val) === "url";
104
104
  const isError = (val) => getVariableType(val) === "error";
105
105
  const isDef = (val) => !isNull(val) && !isUndefined(val);
106
106
  const isJSONStr = (str) => {
107
- if (isDef(str))
107
+ if (isDef(str)) {
108
108
  try {
109
109
  JSON.parse(str);
110
110
  return true;
111
111
  } catch (e) {
112
+ jError("isJSONStr", e);
112
113
  return false;
113
114
  }
115
+ }
114
116
  return false;
115
117
  };
116
118
  const isArrStr = (str) => {
117
- if (isDef(str))
119
+ if (isDef(str)) {
118
120
  try {
119
121
  return Array.isArray(JSON.parse(str));
120
122
  } catch (e) {
123
+ jError("isArrStr", e);
121
124
  return false;
122
125
  }
126
+ }
123
127
  return false;
124
128
  };
125
129
  const isValidKey = (key, object) => key in object;
@@ -127,13 +131,18 @@ const isEmpty = (val) => {
127
131
  return !isDef(val) || val === "" || isArray(val) && val.length === 0 || isObject(val) && Object.keys(val).length === 0 || isMap(val) && val.size === 0 || isSet(val) && val.size === 0;
128
132
  };
129
133
 
130
- const isValidResCode = (res, code = 200) => res.code === code;
131
- const isValidRes = (res, code) => isValidResCode(res, code) && isDef(res.data);
132
- const isValidArrRes = (res, code) => isValidResCode(res, code) && Array.isArray(res.data);
133
- const isValidPageRes = (res, code) => isValidResCode(res, code) && isDef(res.data) && Array.isArray(res.data.list || res.data.records);
134
-
135
134
  const cnPhoneRE = /^1[3-9]\d{9}$/;
136
- const cnTelRE = /^0\d{9,11}$/;
135
+ const cnTelRE = /^0\d{2,3}-?\d{7,8}$/;
136
+ const cnTelRE2 = /^\(0\d{2,3}\)\d{7,8}$/;
137
+ const cnUSCIRE = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/;
138
+ const cnIdCard15Re = /^[1-9]\d{7}(?:0[1-9]|10|11|12)(?:[0-2][1-9]|10|20|30|31)\d{2}[\dX]$/i;
139
+ const cnIdCard18Re = /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|1[0-2])(?:[0-2][1-9]|10|20|30|31)\d{3}[\dX]$/i;
140
+ const emailRE = /^[a-z\d](?:\w|-)+@[a-z\d]+\.[a-z]{2,5}$/i;
141
+ const isUSCI = (val) => {
142
+ if (!isDef(val))
143
+ return false;
144
+ return cnUSCIRE.test(val);
145
+ };
137
146
  const isPhone = (val) => {
138
147
  if (!isDef(val))
139
148
  return false;
@@ -142,20 +151,18 @@ const isPhone = (val) => {
142
151
  const isTel = (val) => {
143
152
  if (!isDef(val))
144
153
  return false;
145
- return cnTelRE.test(val.toString());
154
+ const valStr = val.toString().replaceAll(" ", "");
155
+ return cnTelRE.test(valStr) || cnTelRE2.test(valStr);
146
156
  };
147
157
  const isEmail = (val) => {
148
158
  if (!isDef(val))
149
159
  return false;
150
- const reg = /^[a-zA-Z\d](?:\w|-)+@[a-zA-Z\d]+\.[a-zA-Z]{2,5}$/;
151
- return reg.test(val);
160
+ return emailRE.test(val);
152
161
  };
153
162
  const isIdCard = (val, compatible = true) => {
154
163
  if (!isDef(val))
155
164
  return false;
156
- const card15 = /^[1-9]\d{7}(?:0[1-9]|10|11|12)(?:[0-2][1-9]|10|20|30|31)\d{2}[\dXx]$/;
157
- const card18 = /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|1[0-2])(?:[0-2][1-9]|10|20|30|31)\d{3}[\dXx]$/;
158
- return card18.test(val) || (compatible ? card15.test(val) : false);
165
+ return cnIdCard18Re.test(val) || (compatible ? cnIdCard15Re.test(val) : false);
159
166
  };
160
167
  const isNumeric = (val) => {
161
168
  if (isDef(val))
@@ -190,10 +197,17 @@ const isValidFileType = (file, type) => {
190
197
  return validate(type);
191
198
  };
192
199
 
200
+ const isValidResCode = (res, code = 200) => res.code === code;
201
+ const isValidRes = (res, code) => isValidResCode(res, code) && isDef(res.data);
202
+ const isValidArrRes = (res, code) => isValidResCode(res, code) && Array.isArray(res.data);
203
+ const isValidPageRes = (res, code) => isValidResCode(res, code) && isDef(res.data) && Array.isArray(res.data.list || res.data.records);
204
+
193
205
  const hideMiddle = (str) => {
194
206
  if (!isDef(str))
195
207
  return "";
196
208
  const len = str.length;
209
+ if (len === 0)
210
+ return "";
197
211
  if (len === 1)
198
212
  return "*";
199
213
  if (len === 2)
@@ -216,6 +230,8 @@ const hideHead = (str, count) => {
216
230
  return "";
217
231
  const len = str.length;
218
232
  const cnt = count !== void 0 ? Math.max(Math.min(len, count), 0) : len - 1;
233
+ if (len === 0)
234
+ return "";
219
235
  if (len === 1)
220
236
  return "*";
221
237
  return "*".repeat(cnt) + str.substring(cnt);
@@ -225,17 +241,23 @@ const hideTail = (str, count) => {
225
241
  return "";
226
242
  const len = str.length;
227
243
  const cnt = count !== void 0 ? Math.max(Math.min(len, count), 0) : len - 1;
244
+ if (len === 0)
245
+ return "";
228
246
  if (len === 1)
229
247
  return "*";
230
248
  return str.substring(0, len - cnt) + "*".repeat(cnt);
231
249
  };
232
250
  const hidePhone = (phone) => {
233
251
  if (phone) {
234
- if (isPhone(phone)) {
235
- return phone.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2");
252
+ const phoneStr = phone.replaceAll(" ", "");
253
+ if (isPhone(phoneStr)) {
254
+ return phoneStr.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2");
236
255
  }
237
- if (isTel(phone)) {
238
- return phone.replace(/^(\d{3,4})-?\d{3,4}(\d{4})$/, "$1****$2");
256
+ if (cnTelRE.test(phoneStr)) {
257
+ return phoneStr.replace(/^(0\d{2,3})-?\d{3,4}(\d{4})$/, "$1****$2");
258
+ }
259
+ if (cnTelRE2.test(phoneStr)) {
260
+ return phoneStr.replace(/^\((0\d{2,3})\)\d{3,4}(\d{4})$/, "$1****$2");
239
261
  }
240
262
  return phone;
241
263
  }
@@ -300,14 +322,34 @@ const hideBankCard = (bankCard) => {
300
322
  return "";
301
323
  };
302
324
 
325
+ let __BASE_ATTACH_URL__;
326
+ function setBaseAttachUrl(baseUrl) {
327
+ __BASE_ATTACH_URL__ = baseUrl;
328
+ }
329
+ function getBaseAttachUrl() {
330
+ return __BASE_ATTACH_URL__;
331
+ }
332
+
303
333
  const parseToJSON = (str, reviver2) => isJSONStr(str) ? JSON.parse(str, reviver2) : null;
304
334
  const replacer = (_, value) => {
305
- if (value instanceof Map) {
335
+ if (isMap(value)) {
306
336
  return {
307
337
  dataType: "Map",
308
338
  value: [...value]
309
339
  };
310
340
  }
341
+ if (isSet(value)) {
342
+ return {
343
+ dataType: "Set",
344
+ value: [...value]
345
+ };
346
+ }
347
+ if (isDate(value)) {
348
+ return {
349
+ dataType: "Date",
350
+ value: value.toISOString()
351
+ };
352
+ }
311
353
  return value;
312
354
  };
313
355
  const reviver = (_, value) => {
@@ -315,11 +357,33 @@ const reviver = (_, value) => {
315
357
  if (value.dataType === "Map") {
316
358
  return new Map(value.value);
317
359
  }
360
+ if (value.dataType === "Set") {
361
+ return new Set(value.value);
362
+ }
363
+ if (value.dataType === "Date") {
364
+ return new Date(value.value);
365
+ }
318
366
  }
319
367
  return value;
320
368
  };
321
369
  const filterObj = (obj, keys, reverse = false) => Object.fromEntries(Object.entries(obj).filter(([key]) => reverse ? !keys.includes(key) : keys.includes(key)));
322
370
 
371
+ const toThousands = (num) => {
372
+ const arr = num.toString().split(".");
373
+ const integer = arr[0]?.replace(/(\d)(?=(?:\d{3})+$)/g, "$1,");
374
+ if (arr.length > 1)
375
+ return `${integer}.${arr[1]}`;
376
+ return integer;
377
+ };
378
+ const currencyFmt = (currency, maximumFractionDigits = 2) => {
379
+ if (!isDef(currency))
380
+ return "";
381
+ const num = Number(currency);
382
+ if (Number.isNaN(num))
383
+ return "";
384
+ return new Intl.NumberFormat("zh-CN", { style: "currency", currency: "CNY", maximumFractionDigits }).format(num);
385
+ };
386
+
323
387
  dayjs.extend(localeData).locale("zh-cn", zhCN);
324
388
  dayjs.extend(duration);
325
389
  dayjs.extend(relativeTime);
@@ -353,34 +417,10 @@ const dateDuration = (start, end) => {
353
417
  return dd.format(format);
354
418
  };
355
419
 
356
- let __BASE_ATTACH_URL__;
357
- function setBaseAttachUrl(baseUrl) {
358
- __BASE_ATTACH_URL__ = baseUrl;
359
- }
360
- function getBaseAttachUrl() {
361
- return __BASE_ATTACH_URL__;
362
- }
363
-
364
- const toThousands = (num) => {
365
- const arr = num.toString().split(".");
366
- const integer = arr[0]?.replace(/(\d)(?=(?:\d{3})+$)/g, "$1,");
367
- if (arr.length > 1)
368
- return `${integer}.${arr[1]}`;
369
- return integer;
370
- };
371
- const currencyFmt = (currency, maximumFractionDigits = 2) => {
372
- if (!isDef(currency))
373
- return "";
374
- const num = Number(currency);
375
- if (Number.isNaN(num))
376
- return "";
377
- return new Intl.NumberFormat("zh-CN", { style: "currency", currency: "CNY", maximumFractionDigits }).format(num);
378
- };
379
-
380
420
  const resUrl = (url) => {
381
421
  if (!isDef(url))
382
422
  return void 0;
383
- if (/^https?:\/\//.test(url) || /^blob:/.test(url) || /^data:/.test(url)) {
423
+ if (/^https?:\/\//.test(url) || url.startsWith("blob:") || url.startsWith("data:")) {
384
424
  return url;
385
425
  }
386
426
  const baseUrl = getBaseAttachUrl();
@@ -404,11 +444,11 @@ const recoverFile = (resource) => {
404
444
  const attachFmt = (data) => {
405
445
  let attachList = [];
406
446
  const prototype = Object.prototype.toString.call(data);
407
- if (!data)
447
+ if (!data) {
408
448
  attachList = [];
409
- else if (Array.isArray(data))
449
+ } else if (Array.isArray(data)) {
410
450
  attachList = data.filter(Boolean);
411
- else if (typeof data === "string") {
451
+ } else if (typeof data === "string") {
412
452
  if (isArrStr(data)) {
413
453
  attachList = (parseToJSON(data) || []).filter(Boolean);
414
454
  } else {
@@ -419,11 +459,29 @@ const attachFmt = (data) => {
419
459
  else
420
460
  attachList = [{ id: data, name: "name", uri: data, group: "default" }];
421
461
  }
422
- } else if (prototype === "[object Object]")
462
+ } else if (prototype === "[object Object]") {
423
463
  attachList = [data];
464
+ }
424
465
  return attachList.map(recoverFile);
425
466
  };
426
467
 
468
+ const isNumberArray = (arr) => arr.every((item) => typeof item === "number");
469
+ const isStringArray = (arr) => arr.every((item) => typeof item === "string");
470
+ const naturalSort = (arr) => {
471
+ if (isNumberArray(arr))
472
+ return [...arr].sort((a, b) => a - b);
473
+ if (isStringArray(arr)) {
474
+ return [...arr].sort((a, b) => a.localeCompare(b, "zh-CN")).sort((a, b) => a.length - b.length);
475
+ }
476
+ const newArr = [...arr].sort();
477
+ const validArr = newArr.filter((a) => isDef(a));
478
+ const invalidArr = newArr.filter((a) => !isDef(a));
479
+ return naturalSort(validArr).concat(invalidArr);
480
+ };
481
+ const naturalSortBy = (arr, key) => {
482
+ return [...arr].sort((a, b) => naturalSort([a[key], b[key]])[0] === a[key] ? -1 : 1);
483
+ };
484
+
427
485
  const inBrowser = typeof window !== "undefined";
428
486
  const waitTime = (time = 100) => {
429
487
  return new Promise((resolve) => {
@@ -445,7 +503,8 @@ const getHostEnv = () => {
445
503
  const ua = userAgent.toLowerCase();
446
504
  const zlb = ua.includes("@zlb");
447
505
  const zyd = ua.includes("saas");
448
- const zzd = ua.includes("zhejiang") || ua.includes("tauruszjd");
506
+ const zzd = ua.includes("zhejiang") || ua.includes("tauruszjd") || ua.includes("dingtalk-win");
507
+ const dd = ua.includes("taurusapp");
449
508
  const wx = ua.includes("micromessenger");
450
509
  const zfb = ua.includes("alipay");
451
510
  const mini = ua.includes("miniprogram");
@@ -453,6 +512,7 @@ const getHostEnv = () => {
453
512
  zlb,
454
513
  zyd,
455
514
  zzd,
515
+ dd,
456
516
  wx,
457
517
  zfb,
458
518
  mini
@@ -465,4 +525,4 @@ const getCodeOfHour = () => getCodeOfTime(`${dateFmt( new Date(), "YYYY-MM-DD HH
465
525
  const getCodeOfDate = () => getCodeOfTime(dateFmt(/* @__PURE__ */ new Date(), "date"));
466
526
  const getCodeOfMonth = () => getCodeOfTime(dateFmt(dayjs().endOf("month"), "date"));
467
527
 
468
- export { attachFmt, camel2Kebab, camel2Pascal, camel2Snake, camel2Title, checkImg, currencyFmt, dateDuration, dateFmt, filterObj, fixiOSInputAutoZoomIn, getBaseAttachUrl, getCodeOfDate, getCodeOfHour, getCodeOfMonth, getHostEnv, getVariableType, hideBankCard, hideCardNo, hideEmail, hideFirstName, hideHead, hideMiddle, hideName, hidePhone, hideSurname, hideTail, hideThird, inBrowser, isArrStr, isArray, isBigInt, isBlob, isBoolean, isDate, isDef, isEmail, isEmpty, isError, isFile, isFunction, isIdCard, isJSONStr, isMap, isNull, isNumber, isNumeric, isObject, isPhone, isPromise, isRegExp, isSet, isString, isSymbol, isTel, isURL, isUndefined, isValidArrRes, isValidFileType, isValidKey, isValidPageRes, isValidRes, isValidResCode, isWeakMap, isWeakSet, jClear, jDebug, jError, jGroup, jGroupC, jGroupE, jInfo, jLog, jLogDedupe, jLogOnce, jTime, jTimeEnd, jWarn, kebab2Camel, kebab2Pascal, kebab2Snake, kebab2Title, nonASCII, parseToJSON, pascal2Camel, pascal2Kebab, pascal2Snake, pascal2Title, recoverFile, replacer, resUrl, reviver, setBaseAttachUrl, snake2Camel, snake2Kebab, snake2Pascal, snake2Title, title2Camel, title2Kebab, title2Pascal, title2Snake, toThousands, userAgent, waitTime };
528
+ export { attachFmt, camel2Kebab, camel2Pascal, camel2Snake, camel2Title, checkImg, cnIdCard15Re, cnIdCard18Re, cnPhoneRE, cnTelRE, cnTelRE2, cnUSCIRE, currencyFmt, dateDuration, dateFmt, emailRE, filterObj, fixiOSInputAutoZoomIn, getBaseAttachUrl, getCodeOfDate, getCodeOfHour, getCodeOfMonth, getHostEnv, getVariableType, hideBankCard, hideCardNo, hideEmail, hideFirstName, hideHead, hideMiddle, hideName, hidePhone, hideSurname, hideTail, hideThird, inBrowser, isArrStr, isArray, isBigInt, isBlob, isBoolean, isDate, isDef, isEmail, isEmpty, isError, isFile, isFunction, isIdCard, isJSONStr, isMap, isNull, isNumber, isNumeric, isObject, isPhone, isPromise, isRegExp, isSet, isString, isSymbol, isTel, isURL, isUSCI, isUndefined, isValidArrRes, isValidFileType, isValidKey, isValidPageRes, isValidRes, isValidResCode, isWeakMap, isWeakSet, jClear, jDebug, jError, jGroup, jGroupC, jGroupE, jInfo, jLog, jLogDedupe, jLogOnce, jTime, jTimeEnd, jWarn, kebab2Camel, kebab2Pascal, kebab2Snake, kebab2Title, naturalSort, naturalSortBy, nonASCII, parseToJSON, pascal2Camel, pascal2Kebab, pascal2Snake, pascal2Title, recoverFile, replacer, resUrl, reviver, setBaseAttachUrl, snake2Camel, snake2Kebab, snake2Pascal, snake2Title, title2Camel, title2Kebab, title2Pascal, title2Snake, toThousands, userAgent, waitTime };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jhqn/utils-core",
3
3
  "type": "module",
4
- "version": "0.0.3-beta.1",
4
+ "version": "0.0.3-beta.11",
5
5
  "author": "jade-gjz <jiangang.zhang@jaderd.com>",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/jaderd-jh/utils/tree/main/packages/core#readme",
@@ -37,7 +37,7 @@
37
37
  "dist"
38
38
  ],
39
39
  "dependencies": {
40
- "dayjs": "^1.11.10",
40
+ "dayjs": "^1.11.13",
41
41
  "detect-browser": "^5.3.0"
42
42
  },
43
43
  "scripts": {