@gx-design-vue/pro-utils 0.2.0-alpha.3 → 0.2.0-alpha.4

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 (68) hide show
  1. package/dist/array/index.d.ts +2 -2
  2. package/dist/array/index.js +2 -2
  3. package/dist/array/slice.js +0 -1
  4. package/dist/array/sort.js +4 -5
  5. package/dist/array/tree.d.ts +4 -4
  6. package/dist/array/tree.js +14 -12
  7. package/dist/array/unique.d.ts +24 -2
  8. package/dist/array/unique.js +34 -2
  9. package/dist/class/prefix.d.ts +2 -2
  10. package/dist/class/prefix.js +2 -2
  11. package/dist/clone/cloneDeepWith.js +3 -4
  12. package/dist/dom/index.d.ts +3 -2
  13. package/dist/dom/index.js +3 -2
  14. package/dist/dom/measure.js +8 -3
  15. package/dist/{file → dom}/media.d.ts +1 -1
  16. package/dist/{file → dom}/media.js +36 -17
  17. package/dist/dom/raf.d.ts +1 -1
  18. package/dist/dom/raf.js +1 -1
  19. package/dist/dom/scroll.js +4 -4
  20. package/dist/{base64/index.d.ts → encoding/base64.d.ts} +2 -2
  21. package/dist/{base64/index.js → encoding/base64.js} +29 -32
  22. package/dist/encoding/index.d.ts +2 -0
  23. package/dist/encoding/index.js +2 -0
  24. package/dist/file/convert.d.ts +6 -2
  25. package/dist/file/convert.js +7 -2
  26. package/dist/file/index.d.ts +2 -3
  27. package/dist/file/index.js +2 -3
  28. package/dist/file/type.js +6 -7
  29. package/dist/function/copy.d.ts +7 -0
  30. package/dist/function/copy.js +7 -0
  31. package/dist/function/getValue.d.ts +2 -2
  32. package/dist/function/getValue.js +3 -3
  33. package/dist/index.d.ts +11 -10
  34. package/dist/index.js +12 -20
  35. package/dist/is/base64.d.ts +7 -4
  36. package/dist/is/base64.js +9 -5
  37. package/dist/is/browser.js +1 -1
  38. package/dist/is/deepEqual.d.ts +10 -4
  39. package/dist/is/deepEqual.js +14 -8
  40. package/dist/is/device.js +3 -0
  41. package/dist/is/index.d.ts +3 -3
  42. package/dist/is/index.js +3 -3
  43. package/dist/is/plainObject.js +1 -1
  44. package/dist/is/url.js +1 -2
  45. package/dist/merge/{useDeepMege.d.ts → deepCloneMerge.d.ts} +3 -1
  46. package/dist/merge/{useDeepMege.js → deepCloneMerge.js} +5 -3
  47. package/dist/merge/index.d.ts +1 -1
  48. package/dist/merge/index.js +1 -3
  49. package/dist/merge/mergeWith.js +0 -1
  50. package/dist/number/chinese.js +0 -1
  51. package/dist/number/format.js +6 -3
  52. package/dist/object/classNames.js +0 -1
  53. package/dist/pro-utils.esm.js +486 -387
  54. package/dist/pro-utils.js +2 -1
  55. package/dist/{vue/slots.d.ts → slots/index.d.ts} +1 -1
  56. package/dist/{vue/slots.js → slots/index.js} +33 -17
  57. package/dist/string/index.d.ts +2 -2
  58. package/dist/string/index.js +2 -2
  59. package/dist/string/uuid.d.ts +10 -8
  60. package/dist/string/uuid.js +23 -33
  61. package/dist/table/column.js +5 -7
  62. package/dist/table/page.js +0 -1
  63. package/dist/typing.d.ts +2 -2
  64. package/package.json +2 -1
  65. package/dist/clone/symbols.d.ts +0 -10
  66. package/dist/clone/symbols.js +0 -12
  67. package/dist/vue/index.d.ts +0 -2
  68. package/dist/vue/index.js +0 -2
@@ -36,6 +36,10 @@ declare function dataURLtoFile(url: string, filename: string): File;
36
36
  * @param fileType - 文件类型
37
37
  * @returns File 对象
38
38
  */
39
- declare function blobToDataURL(blob: Blob, fileName: string, fileType: string): File;
39
+ declare function blobToFile(blob: Blob, fileName: string, fileType: string): File;
40
+ /**
41
+ * @deprecated 请使用 blobToFile,该函数实际返回 File 对象而非 Data URL
42
+ */
43
+ declare const blobToDataURL: typeof blobToFile;
40
44
  //#endregion
41
- export { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl };
45
+ export { blobToDataURL, blobToFile, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl };
@@ -61,8 +61,13 @@ function dataURLtoFile(url, filename) {
61
61
  * @param fileType - 文件类型
62
62
  * @returns File 对象
63
63
  */
64
- function blobToDataURL(blob, fileName, fileType) {
64
+ function blobToFile(blob, fileName, fileType) {
65
+ if (typeof window === "undefined") return null;
65
66
  return new window.File([blob], fileName, { type: fileType });
66
67
  }
68
+ /**
69
+ * @deprecated 请使用 blobToFile,该函数实际返回 File 对象而非 Data URL
70
+ */
71
+ const blobToDataURL = blobToFile;
67
72
  //#endregion
68
- export { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl };
73
+ export { blobToDataURL, blobToFile, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl };
@@ -1,5 +1,4 @@
1
1
  import { fileTypes } from "./config.js";
2
- import { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./convert.js";
3
- import { generateVideoPicture, getMediaInfos, getVideoCoverPicture } from "./media.js";
2
+ import { blobToDataURL, blobToFile, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./convert.js";
4
3
  import { checkFileType, getFileSuffix, getVideoFileUrl } from "./type.js";
5
- export { blobToDataURL, checkFileType, dataURLtoBlob, dataURLtoFile, fileTypes, generateVideoPicture, getBase64, getBlobUrl, getFileSuffix, getMediaInfos, getVideoCoverPicture, getVideoFileUrl };
4
+ export { blobToDataURL, blobToFile, checkFileType, dataURLtoBlob, dataURLtoFile, fileTypes, getBase64, getBlobUrl, getFileSuffix, getVideoFileUrl };
@@ -1,5 +1,4 @@
1
1
  import { fileTypes } from "./config.js";
2
- import { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./convert.js";
3
2
  import { checkFileType, getFileSuffix, getVideoFileUrl } from "./type.js";
4
- import { generateVideoPicture, getMediaInfos, getVideoCoverPicture } from "./media.js";
5
- export { blobToDataURL, checkFileType, dataURLtoBlob, dataURLtoFile, fileTypes, generateVideoPicture, getBase64, getBlobUrl, getFileSuffix, getMediaInfos, getVideoCoverPicture, getVideoFileUrl };
3
+ import { blobToDataURL, blobToFile, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./convert.js";
4
+ export { blobToDataURL, blobToFile, checkFileType, dataURLtoBlob, dataURLtoFile, fileTypes, getBase64, getBlobUrl, getFileSuffix, getVideoFileUrl };
package/dist/file/type.js CHANGED
@@ -1,5 +1,4 @@
1
- import { isBase64 } from "../is/base64.js";
2
- import "../is/index.js";
1
+ import { isMediaDataURI } from "../is/base64.js";
3
2
  import { fileTypes } from "./config.js";
4
3
  //#region src/file/type.ts
5
4
  /**
@@ -37,15 +36,15 @@ function checkFileType(url, type) {
37
36
  if (!url) return "4";
38
37
  if (url === "data:") return "4";
39
38
  let fileType = "4";
40
- if (isBase64(url)) {
39
+ if (isMediaDataURI(url)) {
41
40
  if (url.includes("data:image/")) fileType = "png";
42
41
  else if (url.includes("data:video/")) fileType = "mp4";
43
42
  else if (url.includes("data:audio/")) fileType = "mp3";
44
43
  } else if (url instanceof Blob) {
45
- url = String(url);
46
- if (url.includes("image")) fileType = "png";
47
- else if (url.includes("video")) fileType = "mp4";
48
- else if (url.includes("audio")) fileType = "mp3";
44
+ const mimeType = url.type || "";
45
+ if (mimeType.startsWith("image/")) fileType = "png";
46
+ else if (mimeType.startsWith("video/")) fileType = "mp4";
47
+ else if (mimeType.startsWith("audio/")) fileType = "mp3";
49
48
  } else fileType = getFileSuffix(url).toLowerCase();
50
49
  if (fileTypes.imageType.includes(fileType)) return "1";
51
50
  if (fileTypes.videoType.includes(fileType)) return "3";
@@ -4,6 +4,13 @@ import { RecordType } from "../typing.js";
4
4
  /**
5
5
  * 简单深拷贝(使用 JSON 序列化)
6
6
  *
7
+ * 注意:基于 `JSON.parse(JSON.stringify())` 实现,存在以下限制:
8
+ * - `undefined`、函数、`Symbol` 会丢失
9
+ * - `Date` 会变为字符串、`RegExp`/`Map`/`Set` 会变为空对象
10
+ * - 含循环引用时会抛错
11
+ *
12
+ * 如需完整深拷贝,请使用 {@link cloneDeep}。
13
+ *
7
14
  * @param data - 要拷贝的数据
8
15
  * @returns 拷贝后的数据
9
16
  */
@@ -2,6 +2,13 @@
2
2
  /**
3
3
  * 简单深拷贝(使用 JSON 序列化)
4
4
  *
5
+ * 注意:基于 `JSON.parse(JSON.stringify())` 实现,存在以下限制:
6
+ * - `undefined`、函数、`Symbol` 会丢失
7
+ * - `Date` 会变为字符串、`RegExp`/`Map`/`Set` 会变为空对象
8
+ * - 含循环引用时会抛错
9
+ *
10
+ * 如需完整深拷贝,请使用 {@link cloneDeep}。
11
+ *
5
12
  * @param data - 要拷贝的数据
6
13
  * @returns 拷贝后的数据
7
14
  */
@@ -1,10 +1,10 @@
1
1
  //#region src/function/getValue.d.ts
2
- type DeepValueOf<T, K> = K extends `${infer First}:${infer Rest}` ? First extends keyof T ? Rest extends '' ? T[First] : DeepValueOf<T[First], Rest> : undefined : K extends keyof T ? T[K] : undefined;
2
+ type DeepValueOf<T, K> = K extends `${infer First}.${infer Rest}` ? First extends keyof T ? Rest extends '' ? T[First] : DeepValueOf<T[First], Rest> : undefined : K extends `${infer First}:${infer Rest}` ? First extends keyof T ? Rest extends '' ? T[First] : DeepValueOf<T[First], Rest> : undefined : K extends keyof T ? T[K] : undefined;
3
3
  /**
4
4
  * 根据 key 从对象中获取值(支持嵌套路径)
5
5
  *
6
6
  * @param object - 目标对象
7
- * @param key - 键路径(支持用冒号分隔的嵌套路径)
7
+ * @param key - 键路径(支持 `.` 或 `:` 分隔的嵌套路径)
8
8
  * @returns 获取的值
9
9
  */
10
10
  declare function getValueFromObjectByKey<T extends object, K extends string | string[] = string>(object: T, key: K): DeepValueOf<T, K extends string ? K : string> | undefined;
@@ -3,14 +3,14 @@
3
3
  * 根据 key 从对象中获取值(支持嵌套路径)
4
4
  *
5
5
  * @param object - 目标对象
6
- * @param key - 键路径(支持用冒号分隔的嵌套路径)
6
+ * @param key - 键路径(支持 `.` 或 `:` 分隔的嵌套路径)
7
7
  * @returns 获取的值
8
8
  */
9
9
  function getValueFromObjectByKey(object, key) {
10
10
  if (typeof key !== "string" && !Array.isArray(key)) return;
11
- const keys = Array.isArray(key) ? key : key.split(":");
11
+ const keys = Array.isArray(key) ? key : key.split(/[.:]/);
12
12
  let currentValue = object;
13
- for (let i = 0; i < keys.length; i++) if (currentValue && Object.prototype.hasOwnProperty.call(currentValue, keys[i])) currentValue = currentValue[keys[i]];
13
+ for (let i = 0; i < keys.length; i++) if (currentValue && Object.hasOwn(currentValue, keys[i])) currentValue = currentValue[keys[i]];
14
14
  else return;
15
15
  return currentValue;
16
16
  }
package/dist/index.d.ts CHANGED
@@ -2,25 +2,26 @@ import { arraySlice } from "./array/slice.js";
2
2
  import { compareArray, compareArraySort, compareArrayTimeSort, compareTime } from "./array/sort.js";
3
3
  import { AlignType, BasicTablePageConfig, Breakpoint, CustomRender, DeepPartial, EmptyEmit, ExtendIfDefined, Fn, LimitDeepPartial, MediaOptions, Nullable, OmitUndefined, RecordType, SemanticClassNames, SemanticStyles, SizeType, VueNode, WithFalse, WithIfDefault, WithRequired } from "./typing.js";
4
4
  import { filterTree, findSourceByTree, findValueAndAncestors, getArrayLast, getLevelData, getMaxFloor, getSortIndex, treeData } from "./array/tree.js";
5
- import { arrayUnique } from "./array/unique.js";
5
+ import { arrayUnique, arrayUniqueBy } from "./array/unique.js";
6
6
  import { PrefixCls, getPrefixCls } from "./class/prefix.js";
7
7
  import { cloneDeep } from "./clone/cloneDeep.js";
8
8
  import { cloneDeepWith, cloneDeepWithImpl, copyProperties } from "./clone/cloneDeepWith.js";
9
9
  import { off, on } from "./dom/event.js";
10
10
  import { getTextWidth } from "./dom/measure.js";
11
- import wrapperRaf from "./dom/raf.js";
11
+ import { generateVideoPicture, getMediaInfos, getVideoCoverPicture } from "./dom/media.js";
12
+ import { wrapperRaf } from "./dom/raf.js";
12
13
  import { ScrollToOptions, easeInOutCubic, getScroll, getScrollContainer, isInContainer, isScroll, isWindow, scrollTo } from "./dom/scroll.js";
14
+ import { Base64 } from "./encoding/base64.js";
13
15
  import { fileTypes } from "./file/config.js";
14
- import { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./file/convert.js";
15
- import { generateVideoPicture, getMediaInfos, getVideoCoverPicture } from "./file/media.js";
16
+ import { blobToDataURL, blobToFile, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./file/convert.js";
16
17
  import { checkFileType, getFileSuffix, getVideoFileUrl } from "./file/type.js";
17
18
  import { deepCopy } from "./function/copy.js";
18
19
  import { getValueFromObjectByKey } from "./function/getValue.js";
19
20
  import { forInObject, getSymbols, keysOf } from "./function/object.js";
20
21
  import { runFunction } from "./function/run.js";
21
- import { isBase64, isDataURLBase64 } from "./is/base64.js";
22
+ import { isDataURLBase64, isMediaDataURI } from "./is/base64.js";
22
23
  import { isBrowser } from "./is/browser.js";
23
- import { isDeepEqualReact } from "./is/deepEqual.js";
24
+ import { isDeepEqual, isDeepEqualReact } from "./is/deepEqual.js";
24
25
  import { isMobile, isTablet, isWindowsOs } from "./is/device.js";
25
26
  import { isEqual } from "./is/equal.js";
26
27
  import { isImg } from "./is/img.js";
@@ -33,7 +34,7 @@ import { isTypedArray } from "./is/typedArray.js";
33
34
  import { isUnsafeProperty } from "./is/unsafeProperty.js";
34
35
  import { isUrl } from "./is/url.js";
35
36
  import { convertValueBoolean, isValid } from "./is/valid.js";
36
- import { useDeepMerge } from "./merge/useDeepMege.js";
37
+ import { useDeepMerge } from "./merge/deepCloneMerge.js";
37
38
  import { mergeWith } from "./merge/mergeWith.js";
38
39
  import { deepMerge, merge } from "./merge/index.js";
39
40
  import { toChinesNum } from "./number/chinese.js";
@@ -42,11 +43,11 @@ import classNames from "./object/classNames.js";
42
43
  import { omitBoolean } from "./object/omitBoolean.js";
43
44
  import { omitUndefined } from "./object/omitUndefined.js";
44
45
  import { omitUndefinedAndEmptyArr } from "./object/omitUndefinedAndEmptyArr.js";
46
+ import { RenderResult, SlotsPropsResult, filterEmpty, getKeys, getSlot, getSlotVNode, getSlotsChildren, getSlotsProps, isEmptyElement, slotRender } from "./slots/index.js";
45
47
  import { formatDuration } from "./string/duration.js";
46
48
  import { handleEmptyField } from "./string/empty.js";
47
49
  import { nanoid } from "./string/nanoid.js";
48
- import { getRandomNumber } from "./string/uuid.js";
50
+ import { createUUIDFactory } from "./string/uuid.js";
49
51
  import { genColumnKey, handleShowIndex } from "./table/column.js";
50
52
  import { handleCurrentPage } from "./table/page.js";
51
- import { RenderResult, SlotsPropsResult, filterEmpty, getKeys, getSlot, getSlotVNode, getSlotsChildren, getSlotsProps, isEmptyElement, slotRender } from "./vue/slots.js";
52
- export { AlignType, BasicTablePageConfig, Breakpoint, CustomRender, DeepPartial, EmptyEmit, ExtendIfDefined, Fn, LimitDeepPartial, MediaOptions, Nullable, OmitUndefined, PrefixCls, RecordType, RenderResult, ScrollToOptions, SemanticClassNames, SemanticStyles, SizeType, SlotsPropsResult, VueNode, WithFalse, WithIfDefault, WithRequired, arraySlice, arrayUnique, blobToDataURL, checkFileType, classNames, cloneDeep, cloneDeepWith, cloneDeepWithImpl, compareArray, compareArraySort, compareArrayTimeSort, compareTime, convertValueBoolean, copyProperties, dataURLtoBlob, dataURLtoFile, deepCopy, deepMerge, easeInOutCubic, fileTypes, filterEmpty, filterTree, findSourceByTree, findValueAndAncestors, forInObject, formatDuration, formatNumber, genColumnKey, generateVideoPicture, getArrayLast, getBase64, getBlobUrl, getFileSuffix, getKeys, getLevelData, getMaxFloor, getMediaInfos, getPrefixCls, getRandomNumber, getScroll, getScrollContainer, getSlot, getSlotVNode, getSlotsChildren, getSlotsProps, getSortIndex, getSymbols, getTextWidth, getValueFromObjectByKey, getVideoCoverPicture, getVideoFileUrl, handleCurrentPage, handleEmptyField, handleShowIndex, is, isArray, isBase64, isBoolean, isBrowser, isDataURLBase64, isDeepEqualReact, isEmptyElement, isEqual, isFunction, isImg, isInContainer, isJSONStr, isMobile, isNil, isNotNil, isNumber, isObject, isObjectWithSymbols, isPlainObject, isPrimitive, isScroll, isServer, isString, isTablet, isTypedArray, isUnsafeProperty, isUrl, isValid, isWindow, isWindowsOs, keysOf, merge, mergeWith, nanoid, off, omitBoolean, omitUndefined, omitUndefinedAndEmptyArr, on, wrapperRaf as raf, runFunction, scrollTo, slotRender, toChinesNum, toConvertNumberShow, treeData, useDeepMerge };
53
+ export { AlignType, Base64, BasicTablePageConfig, Breakpoint, CustomRender, DeepPartial, EmptyEmit, ExtendIfDefined, Fn, LimitDeepPartial, MediaOptions, Nullable, OmitUndefined, PrefixCls, RecordType, RenderResult, ScrollToOptions, SemanticClassNames, SemanticStyles, SizeType, SlotsPropsResult, VueNode, WithFalse, WithIfDefault, WithRequired, arraySlice, arrayUnique, arrayUniqueBy, blobToDataURL, blobToFile, checkFileType, classNames, cloneDeep, cloneDeepWith, cloneDeepWithImpl, compareArray, compareArraySort, compareArrayTimeSort, compareTime, convertValueBoolean, copyProperties, createUUIDFactory, dataURLtoBlob, dataURLtoFile, deepCopy, deepMerge, easeInOutCubic, fileTypes, filterEmpty, filterTree, findSourceByTree, findValueAndAncestors, forInObject, formatDuration, formatNumber, genColumnKey, generateVideoPicture, getArrayLast, getBase64, getBlobUrl, getFileSuffix, getKeys, getLevelData, getMaxFloor, getMediaInfos, getPrefixCls, getScroll, getScrollContainer, getSlot, getSlotVNode, getSlotsChildren, getSlotsProps, getSortIndex, getSymbols, getTextWidth, getValueFromObjectByKey, getVideoCoverPicture, getVideoFileUrl, handleCurrentPage, handleEmptyField, handleShowIndex, is, isArray, isBoolean, isBrowser, isDataURLBase64, isDeepEqual, isDeepEqualReact, isEmptyElement, isEqual, isFunction, isImg, isInContainer, isJSONStr, isMediaDataURI, isMobile, isNil, isNotNil, isNumber, isObject, isObjectWithSymbols, isPlainObject, isPrimitive, isScroll, isServer, isString, isTablet, isTypedArray, isUnsafeProperty, isUrl, isValid, isWindow, isWindowsOs, keysOf, merge, mergeWith, nanoid, off, omitBoolean, omitUndefined, omitUndefinedAndEmptyArr, on, wrapperRaf as raf, runFunction, scrollTo, slotRender, toChinesNum, toConvertNumberShow, treeData, useDeepMerge };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { isBase64, isDataURLBase64 } from "./is/base64.js";
1
+ import { isDataURLBase64, isMediaDataURI } from "./is/base64.js";
2
2
  import { isBrowser } from "./is/browser.js";
3
- import { isDeepEqualReact } from "./is/deepEqual.js";
3
+ import { isDeepEqual, isDeepEqualReact } from "./is/deepEqual.js";
4
4
  import { isMobile, isTablet, isWindowsOs } from "./is/device.js";
5
5
  import { isEqual } from "./is/equal.js";
6
6
  import { isImg } from "./is/img.js";
@@ -14,47 +14,39 @@ import { isTypedArray } from "./is/typedArray.js";
14
14
  import { isUnsafeProperty } from "./is/unsafeProperty.js";
15
15
  import { isUrl } from "./is/url.js";
16
16
  import { convertValueBoolean, isValid } from "./is/valid.js";
17
- import "./is/index.js";
18
17
  import { arraySlice } from "./array/slice.js";
19
18
  import { compareArray, compareArraySort, compareArrayTimeSort, compareTime } from "./array/sort.js";
20
19
  import { filterTree, findSourceByTree, findValueAndAncestors, getArrayLast, getLevelData, getMaxFloor, getSortIndex, treeData } from "./array/tree.js";
21
- import { arrayUnique } from "./array/unique.js";
22
- import "./array/index.js";
20
+ import { arrayUnique, arrayUniqueBy } from "./array/unique.js";
23
21
  import { getPrefixCls } from "./class/prefix.js";
24
22
  import { cloneDeepWith, cloneDeepWithImpl, copyProperties } from "./clone/cloneDeepWith.js";
25
23
  import { cloneDeep } from "./clone/cloneDeep.js";
26
- import "./clone/index.js";
27
24
  import { off, on } from "./dom/event.js";
28
25
  import { getTextWidth } from "./dom/measure.js";
29
- import wrapperRaf from "./dom/raf.js";
30
- import { easeInOutCubic, getScroll, getScrollContainer, isInContainer, isScroll, isWindow, scrollTo } from "./dom/scroll.js";
31
- import "./dom/index.js";
32
26
  import { fileTypes } from "./file/config.js";
33
- import { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./file/convert.js";
34
27
  import { checkFileType, getFileSuffix, getVideoFileUrl } from "./file/type.js";
35
- import { generateVideoPicture, getMediaInfos, getVideoCoverPicture } from "./file/media.js";
36
- import "./file/index.js";
28
+ import { generateVideoPicture, getMediaInfos, getVideoCoverPicture } from "./dom/media.js";
29
+ import { wrapperRaf } from "./dom/raf.js";
30
+ import { easeInOutCubic, getScroll, getScrollContainer, isInContainer, isScroll, isWindow, scrollTo } from "./dom/scroll.js";
31
+ import { Base64 } from "./encoding/base64.js";
32
+ import { blobToDataURL, blobToFile, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./file/convert.js";
37
33
  import { deepCopy } from "./function/copy.js";
38
34
  import { getValueFromObjectByKey } from "./function/getValue.js";
39
35
  import { runFunction } from "./function/run.js";
40
36
  import { mergeWith } from "./merge/mergeWith.js";
41
- import { useDeepMerge } from "./merge/useDeepMege.js";
37
+ import { useDeepMerge } from "./merge/deepCloneMerge.js";
42
38
  import { deepMerge, merge } from "./merge/index.js";
43
39
  import { toChinesNum } from "./number/chinese.js";
44
40
  import { formatNumber, toConvertNumberShow } from "./number/format.js";
45
- import "./number/index.js";
46
41
  import classNames from "./object/classNames.js";
47
42
  import { omitBoolean } from "./object/omitBoolean.js";
48
43
  import { omitUndefined } from "./object/omitUndefined.js";
49
44
  import { omitUndefinedAndEmptyArr } from "./object/omitUndefinedAndEmptyArr.js";
50
- import "./object/index.js";
45
+ import { filterEmpty, getKeys, getSlot, getSlotVNode, getSlotsChildren, getSlotsProps, isEmptyElement, slotRender } from "./slots/index.js";
51
46
  import { formatDuration } from "./string/duration.js";
52
47
  import { handleEmptyField } from "./string/empty.js";
53
48
  import { nanoid } from "./string/nanoid.js";
54
- import { getRandomNumber } from "./string/uuid.js";
49
+ import { createUUIDFactory } from "./string/uuid.js";
55
50
  import { genColumnKey, handleShowIndex } from "./table/column.js";
56
51
  import { handleCurrentPage } from "./table/page.js";
57
- import "./table/index.js";
58
- import { filterEmpty, getKeys, getSlot, getSlotVNode, getSlotsChildren, getSlotsProps, isEmptyElement, slotRender } from "./vue/slots.js";
59
- import "./vue/index.js";
60
- export { arraySlice, arrayUnique, blobToDataURL, checkFileType, classNames, cloneDeep, cloneDeepWith, cloneDeepWithImpl, compareArray, compareArraySort, compareArrayTimeSort, compareTime, convertValueBoolean, copyProperties, dataURLtoBlob, dataURLtoFile, deepCopy, deepMerge, easeInOutCubic, fileTypes, filterEmpty, filterTree, findSourceByTree, findValueAndAncestors, forInObject, formatDuration, formatNumber, genColumnKey, generateVideoPicture, getArrayLast, getBase64, getBlobUrl, getFileSuffix, getKeys, getLevelData, getMaxFloor, getMediaInfos, getPrefixCls, getRandomNumber, getScroll, getScrollContainer, getSlot, getSlotVNode, getSlotsChildren, getSlotsProps, getSortIndex, getSymbols, getTextWidth, getValueFromObjectByKey, getVideoCoverPicture, getVideoFileUrl, handleCurrentPage, handleEmptyField, handleShowIndex, is, isArray, isBase64, isBoolean, isBrowser, isDataURLBase64, isDeepEqualReact, isEmptyElement, isEqual, isFunction, isImg, isInContainer, isJSONStr, isMobile, isNil, isNotNil, isNumber, isObject, isObjectWithSymbols, isPlainObject, isPrimitive, isScroll, isServer, isString, isTablet, isTypedArray, isUnsafeProperty, isUrl, isValid, isWindow, isWindowsOs, keysOf, merge, mergeWith, nanoid, off, omitBoolean, omitUndefined, omitUndefinedAndEmptyArr, on, wrapperRaf as raf, runFunction, scrollTo, slotRender, toChinesNum, toConvertNumberShow, treeData, useDeepMerge };
52
+ export { Base64, arraySlice, arrayUnique, arrayUniqueBy, blobToDataURL, blobToFile, checkFileType, classNames, cloneDeep, cloneDeepWith, cloneDeepWithImpl, compareArray, compareArraySort, compareArrayTimeSort, compareTime, convertValueBoolean, copyProperties, createUUIDFactory, dataURLtoBlob, dataURLtoFile, deepCopy, deepMerge, easeInOutCubic, fileTypes, filterEmpty, filterTree, findSourceByTree, findValueAndAncestors, forInObject, formatDuration, formatNumber, genColumnKey, generateVideoPicture, getArrayLast, getBase64, getBlobUrl, getFileSuffix, getKeys, getLevelData, getMaxFloor, getMediaInfos, getPrefixCls, getScroll, getScrollContainer, getSlot, getSlotVNode, getSlotsChildren, getSlotsProps, getSortIndex, getSymbols, getTextWidth, getValueFromObjectByKey, getVideoCoverPicture, getVideoFileUrl, handleCurrentPage, handleEmptyField, handleShowIndex, is, isArray, isBoolean, isBrowser, isDataURLBase64, isDeepEqual, isDeepEqualReact, isEmptyElement, isEqual, isFunction, isImg, isInContainer, isJSONStr, isMediaDataURI, isMobile, isNil, isNotNil, isNumber, isObject, isObjectWithSymbols, isPlainObject, isPrimitive, isScroll, isServer, isString, isTablet, isTypedArray, isUnsafeProperty, isUrl, isValid, isWindow, isWindowsOs, keysOf, merge, mergeWith, nanoid, off, omitBoolean, omitUndefined, omitUndefinedAndEmptyArr, on, wrapperRaf as raf, runFunction, scrollTo, slotRender, toChinesNum, toConvertNumberShow, treeData, useDeepMerge };
@@ -1,11 +1,14 @@
1
1
  //#region src/is/base64.d.ts
2
2
  /**
3
- * 判断是否为 base64 编码的字符串
3
+ * 判断是否为媒体类型(image/video/audio)的 Data URL(data URI)
4
+ *
5
+ * 仅检测媒体类型 Data URL 的前缀(`data:image/`、`data:video/`、`data:audio/`),
6
+ * 不校验 Base64 编码内容。如需校验完整 Base64 编码,请使用 {@link isDataURLBase64}。
4
7
  *
5
8
  * @param str - 要判断的字符串
6
- * @returns 是否为 base64 编码
9
+ * @returns 是否为媒体类型 Data URL
7
10
  */
8
- declare function isBase64(str?: string): boolean;
11
+ declare function isMediaDataURI(str?: any): boolean;
9
12
  /**
10
13
  * 判断是否为 Data URL 格式的 base64 字符串
11
14
  *
@@ -14,4 +17,4 @@ declare function isBase64(str?: string): boolean;
14
17
  */
15
18
  declare function isDataURLBase64(str: string): boolean;
16
19
  //#endregion
17
- export { isBase64, isDataURLBase64 };
20
+ export { isDataURLBase64, isMediaDataURI };
package/dist/is/base64.js CHANGED
@@ -1,16 +1,20 @@
1
1
  //#region src/is/base64.ts
2
2
  /**
3
- * 判断是否为 base64 编码的字符串
3
+ * 判断是否为媒体类型(image/video/audio)的 Data URL(data URI)
4
+ *
5
+ * 仅检测媒体类型 Data URL 的前缀(`data:image/`、`data:video/`、`data:audio/`),
6
+ * 不校验 Base64 编码内容。如需校验完整 Base64 编码,请使用 {@link isDataURLBase64}。
4
7
  *
5
8
  * @param str - 要判断的字符串
6
- * @returns 是否为 base64 编码
9
+ * @returns 是否为媒体类型 Data URL
7
10
  */
8
- function isBase64(str = "") {
11
+ function isMediaDataURI(str = "") {
12
+ if (typeof str !== "string") return false;
9
13
  if (str && [
10
14
  "data:image/",
11
15
  "data:video/",
12
16
  "data:audio/"
13
- ].find((item) => str.includes(item))) return true;
17
+ ].some((item) => str.includes(item))) return true;
14
18
  return false;
15
19
  }
16
20
  /**
@@ -23,4 +27,4 @@ function isDataURLBase64(str) {
23
27
  return typeof str === "string" && /^data:(?:image|video|audio)\/[A-Za-z]+;base64,[A-Za-z0-9+/=]+$/.test(str);
24
28
  }
25
29
  //#endregion
26
- export { isBase64, isDataURLBase64 };
30
+ export { isDataURLBase64, isMediaDataURI };
@@ -1,5 +1,4 @@
1
1
  //#region src/is/browser.ts
2
- const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
3
2
  /**
4
3
  * 检查是否为浏览器环境
5
4
  *
@@ -7,6 +6,7 @@ const isNode = typeof process !== "undefined" && process.versions != null && pro
7
6
  */
8
7
  function isBrowser() {
9
8
  if (process.env.NODE_ENV === "TEST") return true;
9
+ const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
10
10
  return typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.matchMedia !== "undefined" && !isNode;
11
11
  }
12
12
  //#endregion
@@ -1,13 +1,19 @@
1
1
  //#region src/is/deepEqual.d.ts
2
2
  /**
3
- * React 深度比较
3
+ * 深度比较两个值是否相等
4
+ *
5
+ * 支持数组、Map、Set、TypedArray、RegExp 及普通对象的递归比较。
4
6
  *
5
7
  * @param a - 第一个值
6
8
  * @param b - 第二个值
7
9
  * @param ignoreKeys - 忽略的键
8
- * @param debug - 是否调试
10
+ * @param debug - 是否调试(打印首个不相等的键)
9
11
  * @returns 是否相等
10
12
  */
11
- declare function isDeepEqualReact(a: any, b: any, ignoreKeys?: string[], debug?: boolean): boolean;
13
+ declare function isDeepEqual(a: any, b: any, ignoreKeys?: string[], debug?: boolean): boolean;
14
+ /**
15
+ * @deprecated 请使用 isDeepEqual,该名称为历史遗留(早期移植自 React 实现)
16
+ */
17
+ declare const isDeepEqualReact: typeof isDeepEqual;
12
18
  //#endregion
13
- export { isDeepEqualReact };
19
+ export { isDeepEqual, isDeepEqualReact };
@@ -1,14 +1,16 @@
1
1
  //#region src/is/deepEqual.ts
2
2
  /**
3
- * React 深度比较
3
+ * 深度比较两个值是否相等
4
+ *
5
+ * 支持数组、Map、Set、TypedArray、RegExp 及普通对象的递归比较。
4
6
  *
5
7
  * @param a - 第一个值
6
8
  * @param b - 第二个值
7
9
  * @param ignoreKeys - 忽略的键
8
- * @param debug - 是否调试
10
+ * @param debug - 是否调试(打印首个不相等的键)
9
11
  * @returns 是否相等
10
12
  */
11
- function isDeepEqualReact(a, b, ignoreKeys, debug) {
13
+ function isDeepEqual(a, b, ignoreKeys, debug) {
12
14
  if (a === b) return true;
13
15
  if (a && b && typeof a === "object" && typeof b === "object") {
14
16
  if (a.constructor !== b.constructor) return false;
@@ -17,13 +19,13 @@ function isDeepEqualReact(a, b, ignoreKeys, debug) {
17
19
  if (Array.isArray(a)) {
18
20
  length = a.length;
19
21
  if (length != b.length) return false;
20
- for (i = length; i-- !== 0;) if (!isDeepEqualReact(a[i], b[i], ignoreKeys, debug)) return false;
22
+ for (i = length; i-- !== 0;) if (!isDeepEqual(a[i], b[i], ignoreKeys, debug)) return false;
21
23
  return true;
22
24
  }
23
25
  if (a instanceof Map && b instanceof Map) {
24
26
  if (a.size !== b.size) return false;
25
27
  for (i of a.entries()) if (!b.has(i[0])) return false;
26
- for (i of a.entries()) if (!isDeepEqualReact(i[1], b.get(i[0]), ignoreKeys, debug)) return false;
28
+ for (i of a.entries()) if (!isDeepEqual(i[1], b.get(i[0]), ignoreKeys, debug)) return false;
27
29
  return true;
28
30
  }
29
31
  if (a instanceof Set && b instanceof Set) {
@@ -43,12 +45,12 @@ function isDeepEqualReact(a, b, ignoreKeys, debug) {
43
45
  const keys = Object.keys(a);
44
46
  length = keys.length;
45
47
  if (length !== Object.keys(b).length) return false;
46
- for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
48
+ for (i = length; i-- !== 0;) if (!Object.hasOwn(b, keys[i])) return false;
47
49
  for (i = length; i-- !== 0;) {
48
50
  const key = keys[i];
49
51
  if (ignoreKeys?.includes(key)) continue;
50
52
  if (key === "_owner" && a.$$typeof) continue;
51
- if (!isDeepEqualReact(a[key], b[key], ignoreKeys, debug)) {
53
+ if (!isDeepEqual(a[key], b[key], ignoreKeys, debug)) {
52
54
  if (debug) console.log(key);
53
55
  return false;
54
56
  }
@@ -57,5 +59,9 @@ function isDeepEqualReact(a, b, ignoreKeys, debug) {
57
59
  }
58
60
  return a !== a && b !== b;
59
61
  }
62
+ /**
63
+ * @deprecated 请使用 isDeepEqual,该名称为历史遗留(早期移植自 React 实现)
64
+ */
65
+ const isDeepEqualReact = isDeepEqual;
60
66
  //#endregion
61
- export { isDeepEqualReact };
67
+ export { isDeepEqual, isDeepEqualReact };
package/dist/is/device.js CHANGED
@@ -5,6 +5,7 @@
5
5
  * @returns 是否为移动端
6
6
  */
7
7
  function isMobile() {
8
+ if (typeof navigator === "undefined") return false;
8
9
  const userAgent = navigator.userAgent || navigator.vendor;
9
10
  if (/iPhone/.test(userAgent)) return true;
10
11
  if (/Android/.test(userAgent) && /Mobile/.test(userAgent)) return true;
@@ -18,6 +19,7 @@ function isMobile() {
18
19
  * @returns 是否为平板
19
20
  */
20
21
  function isTablet() {
22
+ if (typeof navigator === "undefined" || typeof document === "undefined") return false;
21
23
  const userAgent = navigator.userAgent || navigator.vendor;
22
24
  if (/iPad/.test(userAgent)) return true;
23
25
  if (/Macintosh/.test(userAgent) && "ontouchend" in document) return true;
@@ -30,6 +32,7 @@ function isTablet() {
30
32
  * @returns 是否为 Windows 系统
31
33
  */
32
34
  function isWindowsOs() {
35
+ if (typeof navigator === "undefined") return false;
33
36
  return /windows|win32/i.test(navigator.userAgent);
34
37
  }
35
38
  //#endregion
@@ -1,6 +1,6 @@
1
- import { isBase64, isDataURLBase64 } from "./base64.js";
1
+ import { isDataURLBase64, isMediaDataURI } from "./base64.js";
2
2
  import { isBrowser } from "./browser.js";
3
- import { isDeepEqualReact } from "./deepEqual.js";
3
+ import { isDeepEqual, isDeepEqualReact } from "./deepEqual.js";
4
4
  import { isMobile, isTablet, isWindowsOs } from "./device.js";
5
5
  import { isEqual } from "./equal.js";
6
6
  import { isImg } from "./img.js";
@@ -13,4 +13,4 @@ import { isTypedArray } from "./typedArray.js";
13
13
  import { isUnsafeProperty } from "./unsafeProperty.js";
14
14
  import { isUrl } from "./url.js";
15
15
  import { convertValueBoolean, isValid } from "./valid.js";
16
- export { convertValueBoolean, is, isArray, isBase64, isBoolean, isBrowser, isDataURLBase64, isDeepEqualReact, isEqual, isFunction, isImg, isJSONStr, isMobile, isNil, isNotNil, isNumber, isObject, isObjectWithSymbols, isPlainObject, isPrimitive, isServer, isString, isTablet, isTypedArray, isUnsafeProperty, isUrl, isValid, isWindowsOs };
16
+ export { convertValueBoolean, is, isArray, isBoolean, isBrowser, isDataURLBase64, isDeepEqual, isDeepEqualReact, isEqual, isFunction, isImg, isJSONStr, isMediaDataURI, isMobile, isNil, isNotNil, isNumber, isObject, isObjectWithSymbols, isPlainObject, isPrimitive, isServer, isString, isTablet, isTypedArray, isUnsafeProperty, isUrl, isValid, isWindowsOs };
package/dist/is/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { isBase64, isDataURLBase64 } from "./base64.js";
1
+ import { isDataURLBase64, isMediaDataURI } from "./base64.js";
2
2
  import { isBrowser } from "./browser.js";
3
- import { isDeepEqualReact } from "./deepEqual.js";
3
+ import { isDeepEqual, isDeepEqualReact } from "./deepEqual.js";
4
4
  import { isMobile, isTablet, isWindowsOs } from "./device.js";
5
5
  import { isEqual } from "./equal.js";
6
6
  import { isImg } from "./img.js";
@@ -13,4 +13,4 @@ import { isTypedArray } from "./typedArray.js";
13
13
  import { isUnsafeProperty } from "./unsafeProperty.js";
14
14
  import { isUrl } from "./url.js";
15
15
  import { convertValueBoolean, isValid } from "./valid.js";
16
- export { convertValueBoolean, is, isArray, isBase64, isBoolean, isBrowser, isDataURLBase64, isDeepEqualReact, isEqual, isFunction, isImg, isJSONStr, isMobile, isNil, isNotNil, isNumber, isObject, isObjectWithSymbols, isPlainObject, isPrimitive, isServer, isString, isTablet, isTypedArray, isUnsafeProperty, isUrl, isValid, isWindowsOs };
16
+ export { convertValueBoolean, is, isArray, isBoolean, isBrowser, isDataURLBase64, isDeepEqual, isDeepEqualReact, isEqual, isFunction, isImg, isJSONStr, isMediaDataURI, isMobile, isNil, isNotNil, isNumber, isObject, isObjectWithSymbols, isPlainObject, isPrimitive, isServer, isString, isTablet, isTypedArray, isUnsafeProperty, isUrl, isValid, isWindowsOs };
@@ -11,7 +11,7 @@ function isPlainObject(value) {
11
11
  if (!isObject(value)) return false;
12
12
  const proto = Object.getPrototypeOf(value);
13
13
  if (proto === null) return true;
14
- const ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
14
+ const ctor = Object.hasOwn(proto, "constructor") && proto.constructor;
15
15
  return typeof ctor === "function" && ctor instanceof ctor && Function.prototype.toString.call(ctor) === Function.prototype.toString.call(Object);
16
16
  }
17
17
  /**
package/dist/is/url.js CHANGED
@@ -10,8 +10,7 @@ function isUrl(path) {
10
10
  if (!path.startsWith("http")) return false;
11
11
  try {
12
12
  return !!new URL(path);
13
- } catch (_) {
14
- console.error("isUrl error", _);
13
+ } catch {
15
14
  return false;
16
15
  }
17
16
  }
@@ -1,4 +1,4 @@
1
- //#region src/merge/useDeepMege.d.ts
1
+ //#region src/merge/deepCloneMerge.d.ts
2
2
  /**
3
3
  * Merges the properties of the source object into a deep clone of the target object.
4
4
  * Unlike `merge`, This function does not modify the original target object.
@@ -10,6 +10,8 @@
10
10
  *
11
11
  * Note that this function does not mutate the target object.
12
12
  *
13
+ * 注意:函数名保留 `use` 前缀为历史命名,本函数是**纯函数**、非 Vue composable,无响应式副作用。
14
+ *
13
15
  * @param {T} target - The target object to be cloned and merged into. This object is not modified directly.
14
16
  * @param {S} source - The source object whose properties will be merged into the cloned target object.
15
17
  * @returns {T & S} A new object with properties from the source object merged into a deep clone of the target object.
@@ -1,7 +1,7 @@
1
1
  import { isPlainObject } from "../is/plainObject.js";
2
- import "../is/index.js";
2
+ import { cloneDeep } from "../clone/cloneDeep.js";
3
3
  import { mergeWith } from "./mergeWith.js";
4
- //#region src/merge/useDeepMege.ts
4
+ //#region src/merge/deepCloneMerge.ts
5
5
  /**
6
6
  * Merges the properties of the source object into a deep clone of the target object.
7
7
  * Unlike `merge`, This function does not modify the original target object.
@@ -13,6 +13,8 @@ import { mergeWith } from "./mergeWith.js";
13
13
  *
14
14
  * Note that this function does not mutate the target object.
15
15
  *
16
+ * 注意:函数名保留 `use` 前缀为历史命名,本函数是**纯函数**、非 Vue composable,无响应式副作用。
17
+ *
16
18
  * @param {T} target - The target object to be cloned and merged into. This object is not modified directly.
17
19
  * @param {S} source - The source object whose properties will be merged into the cloned target object.
18
20
  * @returns {T & S} A new object with properties from the source object merged into a deep clone of the target object.
@@ -45,7 +47,7 @@ import { mergeWith } from "./mergeWith.js";
45
47
  * // Output: { a: [1, 2, 3] }
46
48
  */
47
49
  function useDeepMerge(target, source) {
48
- return mergeWith(target, source, function mergeRecursively(targetValue, sourceValue) {
50
+ return mergeWith(cloneDeep(target), source, function mergeRecursively(targetValue, sourceValue) {
49
51
  if (isPlainObject(sourceValue)) if (isPlainObject(targetValue)) return mergeWith(targetValue, sourceValue, mergeRecursively);
50
52
  else return mergeWith({}, sourceValue, mergeRecursively);
51
53
  });
@@ -1,4 +1,4 @@
1
- import { useDeepMerge } from "./useDeepMege.js";
1
+ import { useDeepMerge } from "./deepCloneMerge.js";
2
2
  import { mergeWith } from "./mergeWith.js";
3
3
 
4
4
  //#region src/merge/index.d.ts
@@ -1,9 +1,7 @@
1
1
  import { isPlainObject } from "../is/plainObject.js";
2
- import "../is/index.js";
3
2
  import { cloneDeep } from "../clone/cloneDeep.js";
4
- import "../clone/index.js";
5
3
  import { mergeWith } from "./mergeWith.js";
6
- import { useDeepMerge } from "./useDeepMege.js";
4
+ import { useDeepMerge } from "./deepCloneMerge.js";
7
5
  //#region src/merge/index.ts
8
6
  /**
9
7
  * 合并多个对象
@@ -1,6 +1,5 @@
1
1
  import { isPlainObject } from "../is/plainObject.js";
2
2
  import { isUnsafeProperty } from "../is/unsafeProperty.js";
3
- import "../is/index.js";
4
3
  //#region src/merge/mergeWith.ts
5
4
  /**
6
5
  * 合并对象(带自定义处理)
@@ -1,5 +1,4 @@
1
1
  import { isNumber } from "../is/type.js";
2
- import "../is/index.js";
3
2
  //#region src/number/chinese.ts
4
3
  /**
5
4
  * 数字转中文
@@ -1,6 +1,6 @@
1
1
  import { isNumber } from "../is/type.js";
2
- import "../is/index.js";
3
2
  //#region src/number/format.ts
3
+ const formatNumberRegexCache = /* @__PURE__ */ new Map();
4
4
  /**
5
5
  * 格式化数字,保留指定小数位
6
6
  *
@@ -9,8 +9,11 @@ import "../is/index.js";
9
9
  * @returns 格式化后的字符串
10
10
  */
11
11
  function formatNumber(fixedNum, value) {
12
- const regexPattern = `^\\d+(?:\\.\\d{0,${fixedNum}})?`;
13
- const match = new RegExp(regexPattern);
12
+ let match = formatNumberRegexCache.get(fixedNum);
13
+ if (!match) {
14
+ match = new RegExp(`^\\d+(?:\\.\\d{0,${fixedNum}})?`);
15
+ formatNumberRegexCache.set(fixedNum, match);
16
+ }
14
17
  const result = value.toString().match(match);
15
18
  if (result) {
16
19
  const formattedValue = result[0];
@@ -1,5 +1,4 @@
1
1
  import { isArray, isObject, isString } from "../is/type.js";
2
- import "../is/index.js";
3
2
  //#region src/object/classNames.ts
4
3
  /**
5
4
  * 类名合并工具