@jhqn/utils-core 0.0.1-beta.8 → 0.0.2-beta.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.
package/dist/index.mjs CHANGED
@@ -1,3 +1,13 @@
1
+ import { detect } from 'detect-browser';
2
+ import dayjs from 'dayjs';
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';
7
+ import customParseFormat from 'dayjs/plugin/customParseFormat';
8
+ import objectSupport from 'dayjs/plugin/objectSupport';
9
+ import zhCN from 'dayjs/locale/zh-cn';
10
+
1
11
  const snake2Kebab = (str) => str.replace(/_([a-z])/g, (_, letter) => `-${letter.toLowerCase()}`);
2
12
  const snake2Pascal = (str) => str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/^[a-z]/, (letter) => letter.toUpperCase());
3
13
  const snake2Camel = (str) => str.replace(/(_([a-z]))/g, (match) => match[1].toUpperCase());
@@ -50,25 +60,61 @@ const jClear = console.clear.bind(console);
50
60
 
51
61
  const cnPhoneRE = /^1[3-9]\d{9}$/;
52
62
  const cnTelRE = /^0\d{9,11}$/;
53
- const isDef = (val) => val !== void 0 && val !== null;
54
- const isNumeric = (val) => typeof val === "number" || /^\d+(?:\.\d+)?$/.test(val);
63
+ const getVariableType = (val) => {
64
+ const value = Object.prototype.toString.call(val);
65
+ const result = value.match(/\[object (\S*)\]/)?.[1];
66
+ return result?.toLocaleLowerCase();
67
+ };
68
+ const isNumber = (val) => getVariableType(val) === "number";
69
+ const isString = (val) => getVariableType(val) === "string";
70
+ const isBoolean = (val) => getVariableType(val) === "boolean";
71
+ const isNull = (val) => getVariableType(val) === "null";
72
+ const isUndefined = (val) => getVariableType(val) === "undefined";
73
+ const isSymbol = (val) => getVariableType(val) === "symbol";
74
+ const isObject = (val) => getVariableType(val) === "object";
75
+ const isArray = (val) => getVariableType(val) === "array";
76
+ const isFunction = (val) => getVariableType(val) === "function";
77
+ const isDate = (val) => getVariableType(val) === "date";
78
+ const isRegExp = (val) => getVariableType(val) === "regexp";
79
+ const isPromise = (val) => getVariableType(val) === "promise";
80
+ const isSet = (val) => getVariableType(val) === "set";
81
+ const isMap = (val) => getVariableType(val) === "map";
82
+ const isWeakSet = (val) => getVariableType(val) === "weakset";
83
+ const isWeakMap = (val) => getVariableType(val) === "weakmap";
84
+ const isFile = (val) => getVariableType(val) === "file";
85
+ const isBlob = (val) => getVariableType(val) === "blob";
86
+ const isURL = (val) => getVariableType(val) === "url";
87
+ const isError = (val) => getVariableType(val) === "error";
88
+ const isDef = (val) => !isNull(val) && !isUndefined(val);
89
+ const isNumeric = (val) => {
90
+ if (isDef(val))
91
+ return typeof val === "number" || /^\d+(?:\.\d+)?$/.test(val);
92
+ return false;
93
+ };
55
94
  const checkImg = (ext) => {
56
95
  return /\.(?:jpg|jpeg|png|gif)$/.test((ext || "").toLowerCase());
57
96
  };
97
+ const isEmpty = (val) => {
98
+ return !isDef(val) || val === "" || Array.isArray(val) && val.length === 0 || Object.prototype.toString.call(val) === "[object Object]" && Object.keys(val).length === 0 || val instanceof Map && val.size === 0 || val instanceof Set && val.size === 0;
99
+ };
58
100
  const isJSONStr = (str) => {
59
- try {
60
- JSON.parse(str);
61
- return true;
62
- } catch (e) {
63
- return false;
64
- }
101
+ if (isDef(str))
102
+ try {
103
+ JSON.parse(str);
104
+ return true;
105
+ } catch (e) {
106
+ return false;
107
+ }
108
+ return false;
65
109
  };
66
110
  const isArrStr = (str) => {
67
- try {
68
- return Array.isArray(JSON.parse(str));
69
- } catch (e) {
70
- return false;
71
- }
111
+ if (isDef(str))
112
+ try {
113
+ return Array.isArray(JSON.parse(str));
114
+ } catch (e) {
115
+ return false;
116
+ }
117
+ return false;
72
118
  };
73
119
  const isValidKey = (key, object) => key in object;
74
120
  const isPhone = (val) => {
@@ -81,39 +127,48 @@ const isTel = (val) => {
81
127
  return false;
82
128
  return cnTelRE.test(val.toString());
83
129
  };
84
-
85
- const hidePhone = (str) => {
86
- if (str) {
87
- if (isPhone(str)) {
88
- return str.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2");
89
- }
90
- if (isTel(str)) {
91
- return str.replace(/^(\d{3,4})-?\d{3,4}(\d{4})$/, "$1****$2");
92
- }
93
- return str;
94
- }
95
- return "";
130
+ const isEmail = (val) => {
131
+ if (!isDef(val))
132
+ return false;
133
+ const reg = /^[a-zA-Z\d](?:\w|-)+@[a-zA-Z\d]+\.[a-zA-Z]{2,5}$/;
134
+ return reg.test(val);
96
135
  };
97
- const hideCardNo = (cardNo) => {
98
- if (cardNo) {
99
- return cardNo.replace(/^(.{4})\d+(.{2})$/, "$1*******$2");
100
- }
101
- return "";
136
+ const isIdCard = (val, compatible = true) => {
137
+ if (!isDef(val))
138
+ return false;
139
+ const card15 = /^[1-9]\d{7}(?:0[1-9]|10|11|12)(?:[0-2][1-9]|10|20|30|31)\d{2}[\dXx]$/;
140
+ 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]$/;
141
+ return card18.test(val) || (compatible ? card15.test(val) : false);
102
142
  };
103
- const hideName = (name) => {
104
- if (name) {
105
- let res = "";
106
- for (let i = 0; i < name.length; i += 1) {
107
- if (i === 0) {
108
- res += "*";
109
- } else {
110
- res += name[i];
111
- }
143
+ const nonASCII = (text) => /[^\x20-\x7E]/.test(text);
144
+ const isValidResCode = (res, code = 200) => res.code === code;
145
+ const isValidRes = (res, code) => isValidResCode(res, code) && isDef(res.data);
146
+ const isValidArrRes = (res, code) => isValidResCode(res, code) && Array.isArray(res.data);
147
+ const isValidPageRes = (res, code) => isValidResCode(res, code) && isDef(res.data) && Array.isArray(res.data.list || res.data.records);
148
+ const isValidFileType = (file, type) => {
149
+ if (type === "*")
150
+ return true;
151
+ const fileType = file.type;
152
+ const fileName = file.name;
153
+ function validate(item) {
154
+ if (item.startsWith(".")) {
155
+ return fileName.endsWith(item);
112
156
  }
113
- return res;
157
+ if (item.endsWith("/*")) {
158
+ return fileType.startsWith(item.replace("/*", ""));
159
+ }
160
+ if (item.includes("/")) {
161
+ return fileType === item;
162
+ }
163
+ return false;
114
164
  }
115
- return "";
165
+ const typeArrStr = type.split(",").map((item) => item.trim());
166
+ if (typeArrStr.length > 1) {
167
+ return typeArrStr.some(validate);
168
+ }
169
+ return validate(type);
116
170
  };
171
+
117
172
  const hideMiddle = (str) => {
118
173
  if (!isDef(str))
119
174
  return "";
@@ -135,6 +190,149 @@ const hideThird = (str) => {
135
190
  return "**";
136
191
  return str.slice(0, partLen) + "*".repeat(len - 2 * partLen) + str.slice(len - partLen);
137
192
  };
193
+ const hideHead = (str, count) => {
194
+ if (!isDef(str))
195
+ return "";
196
+ const len = str.length;
197
+ const cnt = count !== void 0 ? Math.max(Math.min(len, count), 0) : len - 1;
198
+ if (len === 1)
199
+ return "*";
200
+ return "*".repeat(cnt) + str.substring(cnt);
201
+ };
202
+ const hideTail = (str, count) => {
203
+ if (!isDef(str))
204
+ return "";
205
+ const len = str.length;
206
+ const cnt = count !== void 0 ? Math.max(Math.min(len, count), 0) : len - 1;
207
+ if (len === 1)
208
+ return "*";
209
+ return str.substring(0, len - cnt) + "*".repeat(cnt);
210
+ };
211
+ const hidePhone = (phone) => {
212
+ if (phone) {
213
+ if (isPhone(phone)) {
214
+ return phone.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2");
215
+ }
216
+ if (isTel(phone)) {
217
+ return phone.replace(/^(\d{3,4})-?\d{3,4}(\d{4})$/, "$1****$2");
218
+ }
219
+ return phone;
220
+ }
221
+ return "";
222
+ };
223
+ const hideCardNo = (cardNo, strong = true) => {
224
+ if (cardNo) {
225
+ if (isIdCard(cardNo, false)) {
226
+ return strong ? hideMiddle(cardNo) : cardNo.replace(/^(.)\d{3}(.{8})\d{5}(.)$/, "$1***$2*****$3");
227
+ }
228
+ return cardNo;
229
+ }
230
+ return "";
231
+ };
232
+ const hideName = (name) => {
233
+ if (name) {
234
+ let res = "";
235
+ for (let i = 0; i < name.length; i += 1) {
236
+ if (i === 0) {
237
+ res += "*";
238
+ } else {
239
+ res += name[i];
240
+ }
241
+ }
242
+ return res;
243
+ }
244
+ return "";
245
+ };
246
+ const hideSurname = (name) => {
247
+ return hideHead(name, 1);
248
+ };
249
+ const hideFirstName = (name) => {
250
+ return hideTail(name);
251
+ };
252
+ const hideEmail = (email) => {
253
+ if (email) {
254
+ if (!email.includes("@"))
255
+ return email;
256
+ const arr = email.split("@");
257
+ const name = arr[0];
258
+ const domain = arr[1];
259
+ if (!name || !domain)
260
+ return email;
261
+ const len = name.length;
262
+ let newName;
263
+ if (len <= 3) {
264
+ newName = `${name}***`;
265
+ } else {
266
+ newName = hideTail(name, 3);
267
+ }
268
+ return `${newName}@${domain}`;
269
+ }
270
+ return "";
271
+ };
272
+ const hideBankCard = (bankCard) => {
273
+ if (bankCard) {
274
+ const len = bankCard.length;
275
+ if (len <= 10)
276
+ return bankCard;
277
+ return bankCard.substring(0, 6) + "*".repeat(len - 10) + bankCard.substring(len - 4, len);
278
+ }
279
+ return "";
280
+ };
281
+
282
+ const inBrowser = typeof window !== "undefined";
283
+ const waitTime = (time = 100) => {
284
+ return new Promise((resolve) => {
285
+ setTimeout(() => {
286
+ resolve(true);
287
+ }, time);
288
+ });
289
+ };
290
+ const fixiOSInputAutoZoomIn = () => {
291
+ if (CSS.supports("(font:-apple-system-body) and (-webkit-touch-callout:none) and (-webkit-tap-highlight-color:hotpink)")) {
292
+ const viewport = document.querySelector('meta[name="viewport"]');
293
+ if (viewport !== null) {
294
+ viewport.content = `${viewport.content}, user-scalable=no`;
295
+ }
296
+ }
297
+ };
298
+ const userAgent = inBrowser ? window.navigator.userAgent : "";
299
+ const getHostEnv = () => {
300
+ const ua = userAgent.toLowerCase();
301
+ const baseInfo = detect();
302
+ const zlb = ua.includes("@zlb");
303
+ const zyd = ua.includes("saas");
304
+ const zzd = ua.includes("zhejiang") || ua.includes("tauruszjd");
305
+ const wx = ua.includes("micromessenger");
306
+ const zfb = ua.includes("alipay");
307
+ const mini = ua.includes("miniprogram");
308
+ return {
309
+ ...baseInfo,
310
+ /**
311
+ * 是否是浙里办
312
+ */
313
+ zlb,
314
+ /**
315
+ * 是否是专有钉
316
+ */
317
+ zyd,
318
+ /**
319
+ * 是否是浙政钉
320
+ */
321
+ zzd,
322
+ /**
323
+ * 是否是微信
324
+ */
325
+ wx,
326
+ /**
327
+ * 是否是支付宝
328
+ */
329
+ zfb,
330
+ /**
331
+ * 是否是小程序
332
+ */
333
+ mini
334
+ };
335
+ };
138
336
 
139
337
  const parseToJSON = (str, reviver2) => isJSONStr(str) ? JSON.parse(str, reviver2) : null;
140
338
  const replacer = (_, value) => {
@@ -156,4 +354,111 @@ const reviver = (_, value) => {
156
354
  };
157
355
  const filterObj = (obj, keys, reverse = false) => Object.fromEntries(Object.entries(obj).filter(([key]) => reverse ? !keys.includes(key) : keys.includes(key)));
158
356
 
159
- export { camel2Kebab, camel2Pascal, camel2Snake, camel2Title, checkImg, filterObj, hideCardNo, hideMiddle, hideName, hidePhone, hideThird, isArrStr, isDef, isJSONStr, isNumeric, isPhone, isTel, isValidKey, jClear, jDebug, jError, jGroup, jGroupC, jGroupE, jInfo, jLog, jTime, jTimeEnd, jWarn, kebab2Camel, kebab2Pascal, kebab2Snake, kebab2Title, parseToJSON, pascal2Camel, pascal2Kebab, pascal2Snake, pascal2Title, replacer, reviver, snake2Camel, snake2Kebab, snake2Pascal, snake2Title, title2Camel, title2Kebab, title2Pascal, title2Snake };
357
+ dayjs.extend(localeData).locale("zh-cn", zhCN);
358
+ dayjs.extend(duration);
359
+ dayjs.extend(relativeTime);
360
+ dayjs.extend(customParseFormat);
361
+ dayjs.extend(objectSupport);
362
+ const dateFmt = (date, format = "YYYY-MM-DD HH:mm:ss") => {
363
+ const dd = dayjs(date);
364
+ let fmt = format;
365
+ if (!isDef(date) || !dd.isValid())
366
+ return "";
367
+ if (format === "date")
368
+ fmt = "YYYY-MM-DD";
369
+ if (format === "datetime")
370
+ fmt = "YYYY-MM-DD HH:mm:ss";
371
+ return dd.format(fmt);
372
+ };
373
+ const dateDuration = (start, end) => {
374
+ const startDay = dayjs(start);
375
+ const endDay = dayjs(end);
376
+ if (!isDef(start) || !startDay.isValid() || !isDef(end) || !endDay.isValid())
377
+ return "";
378
+ const dd = dayjs.duration(endDay.diff(startDay));
379
+ const year = dd.years();
380
+ const month = dd.months();
381
+ const day = dd.days();
382
+ const format = [
383
+ year === 0 ? "" : "Y\u5E74",
384
+ month === 0 ? "" : "M\u4E2A\u6708",
385
+ day === 0 ? "" : `${day < 10 && (year !== 0 || month !== 0) ? "\u96F6" : ""}D\u5929`
386
+ ].join("");
387
+ return dd.format(format);
388
+ };
389
+
390
+ let BASE_ATTACH_URL;
391
+ function setBaseAttachUrl(baseUrl) {
392
+ BASE_ATTACH_URL = baseUrl;
393
+ }
394
+ function getBaseAttachUrl() {
395
+ return BASE_ATTACH_URL;
396
+ }
397
+ if (import.meta.env?.VITE_BASE_ATTACH_URL) {
398
+ setBaseAttachUrl(import.meta.env.VITE_BASE_ATTACH_URL);
399
+ }
400
+
401
+ const toThousands = (num) => {
402
+ const arr = num.toString().split(".");
403
+ const integer = arr[0]?.replace(/(\d)(?=(?:\d{3})+$)/g, "$1,");
404
+ if (arr.length > 1)
405
+ return `${integer}.${arr[1]}`;
406
+ return integer;
407
+ };
408
+ const currencyFmt = (currency, maximumFractionDigits = 2) => {
409
+ if (!isDef(currency))
410
+ return "";
411
+ const num = Number(currency);
412
+ if (Number.isNaN(num))
413
+ return "";
414
+ return new Intl.NumberFormat("zh-CN", { style: "currency", currency: "CNY", maximumFractionDigits }).format(num);
415
+ };
416
+
417
+ const resUrl = (url) => {
418
+ if (!isDef(url))
419
+ return void 0;
420
+ if (/^https?:\/\//.test(url) || /^blob:/.test(url) || /^data:/.test(url)) {
421
+ return url;
422
+ }
423
+ const baseUrl = getBaseAttachUrl();
424
+ if (!isDef(baseUrl)) {
425
+ throw new Error("\u8BF7\u5148\u8BBE\u7F6E import.meta\u200B.env.VITE_BASE_ATTACH_URL");
426
+ }
427
+ return `${baseUrl}/${url}`.replace(/([^:]\/)\/+/g, "$1");
428
+ };
429
+ const recoverFile = (resource) => {
430
+ const { uri, url, ...item } = resource;
431
+ const validUrl = uri || url;
432
+ return {
433
+ ...item,
434
+ url: resUrl(validUrl),
435
+ content: resUrl(validUrl),
436
+ uri: validUrl || "",
437
+ status: "done",
438
+ percent: 100
439
+ };
440
+ };
441
+ const attachFmt = (data) => {
442
+ let attachList = [];
443
+ const prototype = Object.prototype.toString.call(data);
444
+ if (!data)
445
+ attachList = [];
446
+ else if (Array.isArray(data))
447
+ attachList = data.filter(Boolean);
448
+ else if (typeof data === "string") {
449
+ if (isArrStr(data)) {
450
+ attachList = (parseToJSON(data) || []).filter(Boolean);
451
+ } else {
452
+ const jsonData = parseToJSON(data);
453
+ const prototypeJson = Object.prototype.toString.call(jsonData);
454
+ if (prototypeJson === "[object Object]")
455
+ attachList = [jsonData].filter(Boolean);
456
+ else
457
+ attachList = [{ id: data, name: "name", uri: data, group: "default" }];
458
+ }
459
+ } else if (prototype === "[object Object]")
460
+ attachList = [data];
461
+ return attachList.map(recoverFile);
462
+ };
463
+
464
+ export { attachFmt, camel2Kebab, camel2Pascal, camel2Snake, camel2Title, checkImg, currencyFmt, dateDuration, dateFmt, filterObj, fixiOSInputAutoZoomIn, getBaseAttachUrl, getHostEnv, getVariableType, hideBankCard, hideCardNo, hideEmail, hideFirstName, hideHead, hideMiddle, hideName, hidePhone, hideSurname, hideTail, hideThird, inBrowser, isArrStr, isArray, 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, 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 };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jhqn/utils-core",
3
3
  "type": "module",
4
- "version": "0.0.1-beta.8",
4
+ "version": "0.0.2-beta.0",
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",
@@ -20,9 +20,14 @@
20
20
  "sideEffects": false,
21
21
  "exports": {
22
22
  ".": {
23
- "types": "./dist/index.d.ts",
24
- "import": "./dist/index.mjs",
25
- "require": "./dist/index.cjs"
23
+ "import": {
24
+ "types": "./dist/index.d.mts",
25
+ "default": "./dist/index.mjs"
26
+ },
27
+ "require": {
28
+ "types": "./dist/index.d.cts",
29
+ "default": "./dist/index.cjs"
30
+ }
26
31
  }
27
32
  },
28
33
  "main": "dist/index.cjs",
@@ -31,9 +36,12 @@
31
36
  "files": [
32
37
  "dist"
33
38
  ],
39
+ "dependencies": {
40
+ "dayjs": "^1.11.10",
41
+ "detect-browser": "^5.3.0"
42
+ },
34
43
  "scripts": {
35
44
  "test": "vitest",
36
- "//build": "tsup",
37
45
  "build": "unbuild",
38
46
  "publint": "publint"
39
47
  }