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

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.d.ts CHANGED
@@ -7,6 +7,59 @@ import { ConfigType } from 'dayjs';
7
7
  export { Dayjs, default as dayjs } from 'dayjs';
8
8
  export { detect } from 'detect-browser';
9
9
 
10
+ /**
11
+ * 数字或字符串
12
+ */
13
+ type Numeric = number | string;
14
+ /**
15
+ * 可 Null
16
+ */
17
+ type Nullable<T> = T | null;
18
+ /**
19
+ * 可 Undefined
20
+ */
21
+ type Undefinable<T> = T | undefined;
22
+ /**
23
+ * 可 Null 或 Undefined
24
+ */
25
+ type NullOrUndefinable<T> = Nullable<Undefinable<T>>;
26
+ /**
27
+ * alias for NullOrUndefinable
28
+ */
29
+ type UnDef<T> = NullOrUndefinable<T>;
30
+ /**
31
+ * 请求结果
32
+ */
33
+ type Res<T = any> = Service.Response<T>;
34
+ /**
35
+ * 分页请求结果数据
36
+ */
37
+ type PageResData<T = any> = Service.PageResponseData<T>;
38
+ /**
39
+ * 分页请求结果
40
+ */
41
+ type PageRes<T = any> = Service.PageResponse<T>;
42
+ /**
43
+ * 分页请求参数
44
+ */
45
+ type PageReq<T extends Record<string, any> = NonNullable<unknown>> = Service.PageRequestParams<T>;
46
+ /**
47
+ * 可能是数组
48
+ */
49
+ type MaybeArray<T = any> = T | Array<T>;
50
+ /**
51
+ * 枚举键值对
52
+ */
53
+ type VK<T = string> = Record<string | number, T>;
54
+ /**
55
+ * 字典
56
+ */
57
+ type Dict<T = string> = Record<string, T>;
58
+ /**
59
+ * 使某键可选
60
+ */
61
+ type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
62
+
10
63
  /**
11
64
  * snake2Kebab
12
65
  * @param {string} str 字符串
@@ -217,43 +270,6 @@ declare const jLogDedupe: (...args: any[]) => void;
217
270
  */
218
271
  declare const jLogOnce: (...args: any[]) => void;
219
272
 
220
- /**
221
- * 数字或字符串
222
- */
223
- declare type Numeric = number | string;
224
- /**
225
- * 可 Null
226
- */
227
- declare type Nullable<T> = T | null;
228
- /**
229
- * 可 Undefined
230
- */
231
- declare type Undefinable<T> = T | undefined;
232
- /**
233
- * 可 Null 或 Undefined
234
- */
235
- declare type NullOrUndefinable<T> = Nullable<Undefinable<T>>;
236
- /**
237
- * alias for NullOrUndefinable
238
- */
239
- declare type UnDef<T> = NullOrUndefinable<T>;
240
- /**
241
- * 请求结果
242
- */
243
- declare type Res<T = any> = Service.Response<T>;
244
- /**
245
- * 分页请求结果数据
246
- */
247
- declare type PageResData<T = any> = Service.PageResponseData<T>;
248
- /**
249
- * 分页请求结果
250
- */
251
- declare type PageRes<T = any> = Service.PageResponse<T>;
252
- /**
253
- * 可能是数组
254
- */
255
- declare type MaybeArray<T = any> = T | Array<T>;
256
-
257
273
  /**
258
274
  * 隐藏中间部分
259
275
  * @param {string} str 需要隐藏的字符串
@@ -327,6 +343,10 @@ interface HostEnv {
327
343
  * 是否是浙政钉
328
344
  */
329
345
  readonly zzd: boolean
346
+ /**
347
+ * 是否是钉钉/专有钉/浙政钉
348
+ */
349
+ readonly dd: boolean
330
350
  /**
331
351
  * 是否是微信
332
352
  */
@@ -362,6 +382,16 @@ declare const fixiOSInputAutoZoomIn: () => void;
362
382
  declare const userAgent: string;
363
383
  /**
364
384
  * 获取宿主环境信息
385
+ * @returns {HostEnv} 宿主环境信息
386
+ * @example
387
+ * const hostEnv = getHostEnv()
388
+ * hostEnv.zlb // 浙里办
389
+ * hostEnv.zyd // 专有钉
390
+ * hostEnv.zzd // 浙政钉
391
+ * hostEnv.dd // 钉钉/专有钉/浙政钉
392
+ * hostEnv.wx // 微信
393
+ * hostEnv.zfb // 支付宝
394
+ * hostEnv.mini // 小程序
365
395
  */
366
396
  declare const getHostEnv: () => HostEnv;
367
397
 
@@ -378,12 +408,22 @@ declare const getCodeOfDate: () => number;
378
408
  */
379
409
  declare const getCodeOfMonth: () => number;
380
410
 
411
+ /**
412
+ * 设置文件基本路径
413
+ * @param baseUrl
414
+ */
415
+ declare function setBaseAttachUrl(baseUrl: string): void;
416
+ /**
417
+ * 获取文件基本路径
418
+ */
419
+ declare function getBaseAttachUrl(): string;
420
+
381
421
  /**
382
422
  * Json字符串转对象
383
423
  * @param str
384
424
  * @param reviver
385
425
  */
386
- declare const parseToJSON: <T = any>(str: string, reviver?: ((this: any, key: string, value: any) => any) | undefined) => Nullable<T>;
426
+ declare const parseToJSON: <T = any>(str: string, reviver?: (this: any, key: string, value: any) => any) => Nullable<T>;
387
427
  /**
388
428
  * JSON.stringify() second param
389
429
  * @param _
@@ -406,13 +446,25 @@ declare const filterObj: (obj: Record<string, any>, keys: string[], reverse?: bo
406
446
  [k: string]: any;
407
447
  };
408
448
 
449
+ /**
450
+ * 千位分隔符
451
+ * @param num
452
+ */
453
+ declare const toThousands: (num: number) => string | undefined;
454
+ /**
455
+ * 货币格式化
456
+ * @param {number | string | bigint} currency - 金额
457
+ * @param {number} [maximumFractionDigits] - 小数位数
458
+ */
459
+ declare const currencyFmt: (currency: UnDef<Numeric | bigint>, maximumFractionDigits?: number) => string;
460
+
409
461
  /**
410
462
  * 格式化时间
411
463
  * @param {import('dayjs').ConfigType} date 时间
412
464
  * @param {string} format 格式
413
465
  * @returns {string} 格式化后的时间
414
466
  */
415
- declare const dateFmt: (date: ConfigType, format?: string | 'date' | 'datetime') => string;
467
+ declare const dateFmt: (date: ConfigType, format?: string | "date" | "datetime") => string;
416
468
  /**
417
469
  * 格式化时间间隔
418
470
  * @param {import('dayjs').ConfigType} start 开始时间
@@ -420,29 +472,6 @@ declare const dateFmt: (date: ConfigType, format?: string | 'date' | 'datetime')
420
472
  */
421
473
  declare const dateDuration: (start: ConfigType, end: ConfigType) => string;
422
474
 
423
- /**
424
- * 设置文件基本路径
425
- * @param key
426
- * @param baseUrl
427
- */
428
- declare function setBaseAttachUrl(baseUrl: string): void;
429
- /**
430
- * 获取文件基本路径
431
- */
432
- declare function getBaseAttachUrl(): string;
433
-
434
- /**
435
- * 千位分隔符
436
- * @param num
437
- */
438
- declare const toThousands: (num: number) => string | undefined;
439
- /**
440
- * 货币格式化
441
- * @param {number | string | bigint} currency - 金额
442
- * @param {number} [maximumFractionDigits] - 小数位数
443
- */
444
- declare const currencyFmt: (currency: UnDef<Numeric | bigint>, maximumFractionDigits?: number) => string;
445
-
446
475
  type VantUploadFileStatus = '' | 'uploading' | 'done' | 'failed'
447
476
  type AntdUploadFileStatus = 'removed' | 'uploading' | 'done' | 'error'
448
477
  type ElementPlusUploadFileStatus = 'ready' | 'uploading' | 'success' | 'fail'
@@ -491,16 +520,16 @@ declare const recoverFile: (resource: Resource) => {
491
520
  group: string;
492
521
  id: string;
493
522
  name: string;
494
- size?: number | undefined;
495
- uid?: string | undefined;
496
- objectUrl?: string | undefined;
497
- isImage?: boolean | undefined;
498
- message?: string | undefined;
499
- deletable?: boolean | undefined;
500
- reupload?: boolean | undefined;
501
- fileName?: string | undefined;
502
- thumbUrl?: string | undefined;
503
- percentage?: number | undefined;
523
+ size?: number;
524
+ uid?: string;
525
+ objectUrl?: string;
526
+ isImage?: boolean;
527
+ message?: string;
528
+ deletable?: boolean;
529
+ reupload?: boolean;
530
+ fileName?: string;
531
+ thumbUrl?: string;
532
+ percentage?: number;
504
533
  };
505
534
  /**
506
535
  * 附件格式
@@ -515,18 +544,32 @@ declare const attachFmt: (data: UnDef<MaybeArray<Resource>> | string) => {
515
544
  group: string;
516
545
  id: string;
517
546
  name: string;
518
- size?: number | undefined;
519
- uid?: string | undefined;
520
- objectUrl?: string | undefined;
521
- isImage?: boolean | undefined;
522
- message?: string | undefined;
523
- deletable?: boolean | undefined;
524
- reupload?: boolean | undefined;
525
- fileName?: string | undefined;
526
- thumbUrl?: string | undefined;
527
- percentage?: number | undefined;
547
+ size?: number;
548
+ uid?: string;
549
+ objectUrl?: string;
550
+ isImage?: boolean;
551
+ message?: string;
552
+ deletable?: boolean;
553
+ reupload?: boolean;
554
+ fileName?: string;
555
+ thumbUrl?: string;
556
+ percentage?: number;
528
557
  }[];
529
558
 
559
+ /**
560
+ * 自然排序
561
+ * @param {UnDef<string>[] | UnDef<number>[]} arr - 数字或字符串数组
562
+ * @returns {UnDef<string>[] | UnDef<number>[]} - 排序后的数组
563
+ */
564
+ declare const naturalSort: (arr: UnDef<string>[] | UnDef<number>[]) => UnDef<string>[] | UnDef<number>[];
565
+ /**
566
+ * 根据 key 自然排序
567
+ * @param arr - 数组
568
+ * @param {string} key - 键名
569
+ * @returns {any[]} - 排序后的数组
570
+ */
571
+ declare const naturalSortBy: <T extends Record<string, UnDef<Numeric>>>(arr: T[], key: keyof T) => T[];
572
+
530
573
  /**
531
574
  * 检测变量类型
532
575
  * @param {any} val 检测的目标
@@ -576,7 +619,7 @@ declare const isObject: (val: any) => val is Record<any, any>;
576
619
  * 是否是数组
577
620
  * @param {any} val 检测的目标
578
621
  */
579
- declare const isArray: (val: any) => val is any[];
622
+ declare const isArray: (val: any) => val is Array<any>;
580
623
  /**
581
624
  * 是否是函数,但也有可能是Class
582
625
  * @param {any} val 检测的目标
@@ -664,7 +707,7 @@ declare const isArrStr: (str: UnDef<string>) => boolean;
664
707
  * ```
665
708
  * @returns {boolean} boolean
666
709
  */
667
- declare const isValidKey: (key: string | number | symbol, object: object) => key is never;
710
+ declare const isValidKey: (key: string | number | symbol, object: object) => key is keyof typeof object;
668
711
  /**
669
712
  * 是否是空值/空数组/空对象 null undefined '' [] {} Set Map
670
713
  * @param val
@@ -672,30 +715,15 @@ declare const isValidKey: (key: string | number | symbol, object: object) => key
672
715
  declare const isEmpty: (val: UnDef<Numeric | boolean | Record<any, any> | Array<any> | Set<any> | Map<any, any>>) => boolean;
673
716
 
674
717
  /**
675
- * 校验接口返回code
676
- * @param res
677
- * @param code
678
- */
679
- declare const isValidResCode: (res: Res, code?: number) => boolean;
680
- /**
681
- * 校验接口返回内容
682
- * @param res
683
- * @param code
684
- */
685
- declare const isValidRes: (res: Res, code?: number) => boolean;
686
- /**
687
- * 校验接口数组返回内容
688
- * @param res
689
- * @param code
690
- */
691
- declare const isValidArrRes: (res: Res<any[]>, code?: number) => boolean;
692
- /**
693
- * 校验接口分页返回内容
694
- * @param res
695
- * @param code
718
+ * 是否是[统一社会信用代码](https://zh.wikipedia.org/zh-cn/%E7%BB%9F%E4%B8%80%E7%A4%BE%E4%BC%9A%E4%BF%A1%E7%94%A8%E4%BB%A3%E7%A0%81)
719
+ * @example
720
+ * ```ts
721
+ * isUSCI('91350100M000100Y43') // true
722
+ * ```
723
+ * @param {UnDef<string>} val - 待校验的值
724
+ * @returns {boolean} 是否是统一社会信用代码
696
725
  */
697
- declare const isValidPageRes: (res: PageRes, code?: number) => boolean;
698
-
726
+ declare const isUSCI: (val: UnDef<string>) => boolean;
699
727
  /**
700
728
  * 是否是中国手机号
701
729
  * @param val
@@ -740,4 +768,29 @@ declare const nonASCII: (text: string) => boolean;
740
768
  */
741
769
  declare const isValidFileType: (file: File, type: string) => boolean;
742
770
 
743
- export { type MaybeArray, type NullOrUndefinable, type Nullable, type Numeric, type PageRes, type PageResData, type Res, type UnDef, type Undefinable, 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 };
771
+ /**
772
+ * 校验接口返回code
773
+ * @param res
774
+ * @param code
775
+ */
776
+ declare const isValidResCode: (res: Res, code?: number) => boolean;
777
+ /**
778
+ * 校验接口返回内容
779
+ * @param res
780
+ * @param code
781
+ */
782
+ declare const isValidRes: (res: Res, code?: number) => boolean;
783
+ /**
784
+ * 校验接口数组返回内容
785
+ * @param res
786
+ * @param code
787
+ */
788
+ declare const isValidArrRes: (res: Res<any[]>, code?: number) => boolean;
789
+ /**
790
+ * 校验接口分页返回内容
791
+ * @param res
792
+ * @param code
793
+ */
794
+ declare const isValidPageRes: (res: PageRes, code?: number) => boolean;
795
+
796
+ export { type Dict, type MaybeArray, type NullOrUndefinable, type Nullable, type Numeric, type PageReq, type PageRes, type PageResData, type PartialBy, type Res, type UnDef, type Undefinable, type VK, 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, 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/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,14 @@ 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
135
  const cnTelRE = /^0\d{9,11}$/;
136
+ const cnUSCIRE = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/;
137
+ const isUSCI = (val) => {
138
+ if (!isDef(val))
139
+ return false;
140
+ return cnUSCIRE.test(val);
141
+ };
137
142
  const isPhone = (val) => {
138
143
  if (!isDef(val))
139
144
  return false;
@@ -147,14 +152,14 @@ const isTel = (val) => {
147
152
  const isEmail = (val) => {
148
153
  if (!isDef(val))
149
154
  return false;
150
- const reg = /^[a-zA-Z\d](?:\w|-)+@[a-zA-Z\d]+\.[a-zA-Z]{2,5}$/;
155
+ const reg = /^[a-z\d](?:\w|-)+@[a-z\d]+\.[a-z]{2,5}$/i;
151
156
  return reg.test(val);
152
157
  };
153
158
  const isIdCard = (val, compatible = true) => {
154
159
  if (!isDef(val))
155
160
  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]$/;
161
+ const card15 = /^[1-9]\d{7}(?:0[1-9]|10|11|12)(?:[0-2][1-9]|10|20|30|31)\d{2}[\dX]$/i;
162
+ 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}[\dX]$/i;
158
163
  return card18.test(val) || (compatible ? card15.test(val) : false);
159
164
  };
160
165
  const isNumeric = (val) => {
@@ -190,10 +195,17 @@ const isValidFileType = (file, type) => {
190
195
  return validate(type);
191
196
  };
192
197
 
198
+ const isValidResCode = (res, code = 200) => res.code === code;
199
+ const isValidRes = (res, code) => isValidResCode(res, code) && isDef(res.data);
200
+ const isValidArrRes = (res, code) => isValidResCode(res, code) && Array.isArray(res.data);
201
+ const isValidPageRes = (res, code) => isValidResCode(res, code) && isDef(res.data) && Array.isArray(res.data.list || res.data.records);
202
+
193
203
  const hideMiddle = (str) => {
194
204
  if (!isDef(str))
195
205
  return "";
196
206
  const len = str.length;
207
+ if (len === 0)
208
+ return "";
197
209
  if (len === 1)
198
210
  return "*";
199
211
  if (len === 2)
@@ -216,6 +228,8 @@ const hideHead = (str, count) => {
216
228
  return "";
217
229
  const len = str.length;
218
230
  const cnt = count !== void 0 ? Math.max(Math.min(len, count), 0) : len - 1;
231
+ if (len === 0)
232
+ return "";
219
233
  if (len === 1)
220
234
  return "*";
221
235
  return "*".repeat(cnt) + str.substring(cnt);
@@ -225,6 +239,8 @@ const hideTail = (str, count) => {
225
239
  return "";
226
240
  const len = str.length;
227
241
  const cnt = count !== void 0 ? Math.max(Math.min(len, count), 0) : len - 1;
242
+ if (len === 0)
243
+ return "";
228
244
  if (len === 1)
229
245
  return "*";
230
246
  return str.substring(0, len - cnt) + "*".repeat(cnt);
@@ -300,14 +316,34 @@ const hideBankCard = (bankCard) => {
300
316
  return "";
301
317
  };
302
318
 
319
+ let __BASE_ATTACH_URL__;
320
+ function setBaseAttachUrl(baseUrl) {
321
+ __BASE_ATTACH_URL__ = baseUrl;
322
+ }
323
+ function getBaseAttachUrl() {
324
+ return __BASE_ATTACH_URL__;
325
+ }
326
+
303
327
  const parseToJSON = (str, reviver2) => isJSONStr(str) ? JSON.parse(str, reviver2) : null;
304
328
  const replacer = (_, value) => {
305
- if (value instanceof Map) {
329
+ if (isMap(value)) {
306
330
  return {
307
331
  dataType: "Map",
308
332
  value: [...value]
309
333
  };
310
334
  }
335
+ if (isSet(value)) {
336
+ return {
337
+ dataType: "Set",
338
+ value: [...value]
339
+ };
340
+ }
341
+ if (isDate(value)) {
342
+ return {
343
+ dataType: "Date",
344
+ value: value.toISOString()
345
+ };
346
+ }
311
347
  return value;
312
348
  };
313
349
  const reviver = (_, value) => {
@@ -315,11 +351,33 @@ const reviver = (_, value) => {
315
351
  if (value.dataType === "Map") {
316
352
  return new Map(value.value);
317
353
  }
354
+ if (value.dataType === "Set") {
355
+ return new Set(value.value);
356
+ }
357
+ if (value.dataType === "Date") {
358
+ return new Date(value.value);
359
+ }
318
360
  }
319
361
  return value;
320
362
  };
321
363
  const filterObj = (obj, keys, reverse = false) => Object.fromEntries(Object.entries(obj).filter(([key]) => reverse ? !keys.includes(key) : keys.includes(key)));
322
364
 
365
+ const toThousands = (num) => {
366
+ const arr = num.toString().split(".");
367
+ const integer = arr[0]?.replace(/(\d)(?=(?:\d{3})+$)/g, "$1,");
368
+ if (arr.length > 1)
369
+ return `${integer}.${arr[1]}`;
370
+ return integer;
371
+ };
372
+ const currencyFmt = (currency, maximumFractionDigits = 2) => {
373
+ if (!isDef(currency))
374
+ return "";
375
+ const num = Number(currency);
376
+ if (Number.isNaN(num))
377
+ return "";
378
+ return new Intl.NumberFormat("zh-CN", { style: "currency", currency: "CNY", maximumFractionDigits }).format(num);
379
+ };
380
+
323
381
  dayjs.extend(localeData).locale("zh-cn", zhCN);
324
382
  dayjs.extend(duration);
325
383
  dayjs.extend(relativeTime);
@@ -353,34 +411,10 @@ const dateDuration = (start, end) => {
353
411
  return dd.format(format);
354
412
  };
355
413
 
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
414
  const resUrl = (url) => {
381
415
  if (!isDef(url))
382
416
  return void 0;
383
- if (/^https?:\/\//.test(url) || /^blob:/.test(url) || /^data:/.test(url)) {
417
+ if (/^https?:\/\//.test(url) || url.startsWith("blob:") || url.startsWith("data:")) {
384
418
  return url;
385
419
  }
386
420
  const baseUrl = getBaseAttachUrl();
@@ -404,11 +438,11 @@ const recoverFile = (resource) => {
404
438
  const attachFmt = (data) => {
405
439
  let attachList = [];
406
440
  const prototype = Object.prototype.toString.call(data);
407
- if (!data)
441
+ if (!data) {
408
442
  attachList = [];
409
- else if (Array.isArray(data))
443
+ } else if (Array.isArray(data)) {
410
444
  attachList = data.filter(Boolean);
411
- else if (typeof data === "string") {
445
+ } else if (typeof data === "string") {
412
446
  if (isArrStr(data)) {
413
447
  attachList = (parseToJSON(data) || []).filter(Boolean);
414
448
  } else {
@@ -419,11 +453,29 @@ const attachFmt = (data) => {
419
453
  else
420
454
  attachList = [{ id: data, name: "name", uri: data, group: "default" }];
421
455
  }
422
- } else if (prototype === "[object Object]")
456
+ } else if (prototype === "[object Object]") {
423
457
  attachList = [data];
458
+ }
424
459
  return attachList.map(recoverFile);
425
460
  };
426
461
 
462
+ const isNumberArray = (arr) => arr.every((item) => typeof item === "number");
463
+ const isStringArray = (arr) => arr.every((item) => typeof item === "string");
464
+ const naturalSort = (arr) => {
465
+ if (isNumberArray(arr))
466
+ return [...arr].sort((a, b) => a - b);
467
+ if (isStringArray(arr)) {
468
+ return [...arr].sort((a, b) => a.localeCompare(b, "zh-CN")).sort((a, b) => a.length - b.length);
469
+ }
470
+ const newArr = [...arr].sort();
471
+ const validArr = newArr.filter((a) => isDef(a));
472
+ const invalidArr = newArr.filter((a) => !isDef(a));
473
+ return naturalSort(validArr).concat(invalidArr);
474
+ };
475
+ const naturalSortBy = (arr, key) => {
476
+ return [...arr].sort((a, b) => naturalSort([a[key], b[key]])[0] === a[key] ? -1 : 1);
477
+ };
478
+
427
479
  const inBrowser = typeof window !== "undefined";
428
480
  const waitTime = (time = 100) => {
429
481
  return new Promise((resolve) => {
@@ -445,7 +497,8 @@ const getHostEnv = () => {
445
497
  const ua = userAgent.toLowerCase();
446
498
  const zlb = ua.includes("@zlb");
447
499
  const zyd = ua.includes("saas");
448
- const zzd = ua.includes("zhejiang") || ua.includes("tauruszjd");
500
+ const zzd = ua.includes("zhejiang") || ua.includes("tauruszjd") || ua.includes("dingtalk-win");
501
+ const dd = ua.includes("taurusapp");
449
502
  const wx = ua.includes("micromessenger");
450
503
  const zfb = ua.includes("alipay");
451
504
  const mini = ua.includes("miniprogram");
@@ -453,6 +506,7 @@ const getHostEnv = () => {
453
506
  zlb,
454
507
  zyd,
455
508
  zzd,
509
+ dd,
456
510
  wx,
457
511
  zfb,
458
512
  mini
@@ -465,4 +519,4 @@ const getCodeOfHour = () => getCodeOfTime(`${dateFmt( new Date(), "YYYY-MM-DD HH
465
519
  const getCodeOfDate = () => getCodeOfTime(dateFmt(/* @__PURE__ */ new Date(), "date"));
466
520
  const getCodeOfMonth = () => getCodeOfTime(dateFmt(dayjs().endOf("month"), "date"));
467
521
 
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 };
522
+ 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, 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.10",
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": {