@gx-design-vue/pro-utils 0.1.4 → 0.2.0-alpha.1

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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -2
  3. package/dist/array/index.d.ts +5 -0
  4. package/dist/array/index.js +6 -0
  5. package/dist/array/slice.d.ts +11 -0
  6. package/dist/array/slice.js +29 -0
  7. package/dist/array/sort.d.ts +41 -0
  8. package/dist/array/sort.js +65 -0
  9. package/dist/array/tree.d.ts +83 -0
  10. package/dist/array/tree.js +157 -0
  11. package/dist/array/unique.d.ts +12 -0
  12. package/dist/array/unique.js +14 -0
  13. package/dist/base64/index.d.ts +26 -0
  14. package/dist/base64/index.js +106 -0
  15. package/dist/class/index.d.ts +2 -0
  16. package/dist/class/index.js +3 -0
  17. package/dist/class/prefix.d.ts +25 -0
  18. package/dist/class/prefix.js +15 -0
  19. package/dist/clone/cloneDeep.d.ts +30 -0
  20. package/dist/clone/cloneDeep.js +35 -0
  21. package/dist/clone/cloneDeepWith.d.ts +14 -0
  22. package/dist/clone/cloneDeepWith.js +150 -0
  23. package/dist/clone/getTag.d.ts +10 -0
  24. package/dist/clone/getTag.js +13 -0
  25. package/dist/clone/index.d.ts +3 -0
  26. package/dist/clone/index.js +4 -0
  27. package/dist/clone/symbols.d.ts +10 -0
  28. package/dist/clone/symbols.js +13 -0
  29. package/dist/clone/tags.d.ts +47 -0
  30. package/dist/clone/tags.js +48 -0
  31. package/dist/dom/event.d.ts +21 -0
  32. package/dist/dom/event.js +26 -0
  33. package/dist/dom/index.d.ts +5 -0
  34. package/dist/dom/index.js +6 -0
  35. package/dist/dom/measure.d.ts +19 -0
  36. package/dist/dom/measure.js +42 -0
  37. package/dist/dom/raf.d.ts +14 -0
  38. package/dist/dom/raf.js +44 -0
  39. package/dist/dom/scroll.d.ts +20 -0
  40. package/dist/dom/scroll.js +97 -0
  41. package/dist/file/config.d.ts +13 -0
  42. package/dist/file/config.js +81 -0
  43. package/dist/file/convert.d.ts +41 -0
  44. package/dist/file/convert.js +69 -0
  45. package/dist/file/index.d.ts +5 -0
  46. package/dist/file/index.js +6 -0
  47. package/dist/file/media.d.ts +35 -0
  48. package/dist/file/media.js +161 -0
  49. package/dist/file/type.d.ts +25 -0
  50. package/dist/file/type.js +58 -0
  51. package/dist/function/copy.d.ts +12 -0
  52. package/dist/function/copy.js +13 -0
  53. package/dist/function/getValue.d.ts +12 -0
  54. package/dist/function/getValue.js +19 -0
  55. package/dist/function/index.d.ts +5 -0
  56. package/dist/function/index.js +6 -0
  57. package/dist/function/object.d.ts +24 -0
  58. package/dist/function/object.js +33 -0
  59. package/dist/function/run.d.ts +11 -0
  60. package/dist/function/run.js +15 -0
  61. package/dist/index.d.ts +59 -26
  62. package/dist/index.js +61 -0
  63. package/dist/is/base64.d.ts +17 -0
  64. package/dist/is/base64.js +27 -0
  65. package/dist/is/browser.d.ts +9 -0
  66. package/dist/is/browser.js +14 -0
  67. package/dist/is/deepEqual.d.ts +13 -0
  68. package/dist/is/deepEqual.js +62 -0
  69. package/dist/is/device.d.ts +21 -0
  70. package/dist/is/device.js +37 -0
  71. package/dist/is/equal.d.ts +12 -0
  72. package/dist/is/equal.js +34 -0
  73. package/dist/is/img.d.ts +10 -0
  74. package/dist/is/img.js +13 -0
  75. package/dist/is/index.d.ts +16 -0
  76. package/dist/is/index.js +17 -0
  77. package/dist/is/nil.d.ts +17 -0
  78. package/dist/is/nil.js +22 -0
  79. package/dist/is/plainObject.d.ts +17 -0
  80. package/dist/is/plainObject.js +30 -0
  81. package/dist/is/primitive.d.ts +10 -0
  82. package/dist/is/primitive.js +13 -0
  83. package/dist/is/server.d.ts +9 -0
  84. package/dist/is/server.js +10 -0
  85. package/dist/is/type.d.ts +60 -0
  86. package/dist/is/type.js +84 -0
  87. package/dist/is/typedArray.d.ts +30 -0
  88. package/dist/is/typedArray.js +33 -0
  89. package/dist/is/unsafeProperty.d.ts +10 -0
  90. package/dist/is/unsafeProperty.js +18 -0
  91. package/dist/is/url.d.ts +10 -0
  92. package/dist/is/url.js +20 -0
  93. package/dist/is/valid.d.ts +17 -0
  94. package/dist/is/valid.js +23 -0
  95. package/dist/merge/index.d.ts +19 -5
  96. package/dist/merge/index.js +42 -0
  97. package/dist/merge/mergeWith.d.ts +12 -0
  98. package/dist/merge/mergeWith.js +31 -0
  99. package/dist/merge/useDeepMege.d.ts +46 -0
  100. package/dist/merge/useDeepMege.js +56 -0
  101. package/dist/number/chinese.d.ts +10 -0
  102. package/dist/number/chinese.js +46 -0
  103. package/dist/number/format.d.ts +27 -0
  104. package/dist/number/format.js +72 -0
  105. package/dist/number/index.d.ts +3 -0
  106. package/dist/number/index.js +4 -0
  107. package/dist/object/classNames.d.ts +10 -0
  108. package/dist/object/classNames.js +30 -0
  109. package/dist/object/index.d.ts +5 -0
  110. package/dist/object/index.js +6 -0
  111. package/dist/object/omitBoolean.d.ts +10 -0
  112. package/dist/object/omitBoolean.js +13 -0
  113. package/dist/object/omitUndefined.d.ts +12 -0
  114. package/dist/object/omitUndefined.js +18 -0
  115. package/dist/object/omitUndefinedAndEmptyArr.d.ts +10 -0
  116. package/dist/object/omitUndefinedAndEmptyArr.js +19 -0
  117. package/dist/pro-utils.esm.js +948 -0
  118. package/dist/pro-utils.js +1 -0
  119. package/dist/string/duration.d.ts +10 -0
  120. package/dist/string/duration.js +25 -0
  121. package/dist/string/empty.d.ts +14 -0
  122. package/dist/string/empty.js +26 -0
  123. package/dist/string/index.d.ts +5 -0
  124. package/dist/string/index.js +6 -0
  125. package/dist/string/nanoid.d.ts +9 -0
  126. package/dist/string/nanoid.js +32 -0
  127. package/dist/string/uuid.d.ts +34 -0
  128. package/dist/string/uuid.js +57 -0
  129. package/dist/table/column.d.ts +27 -0
  130. package/dist/table/column.js +42 -0
  131. package/dist/table/index.d.ts +3 -0
  132. package/dist/table/index.js +4 -0
  133. package/dist/table/page.d.ts +13 -0
  134. package/dist/table/page.js +23 -0
  135. package/dist/typing.d.ts +262 -0
  136. package/dist/typing.js +1 -0
  137. package/dist/vue/index.d.ts +2 -0
  138. package/dist/vue/index.js +3 -0
  139. package/dist/vue/slots.d.ts +56 -0
  140. package/dist/vue/slots.js +89 -0
  141. package/package.json +45 -64
  142. package/dist/classNames/index.d.ts +0 -2
  143. package/dist/components/FieldLabel/index.d.ts +0 -77
  144. package/dist/components/FieldLabel/index.less +0 -107
  145. package/dist/components/LabelIconTip/index.d.ts +0 -20
  146. package/dist/components/LabelIconTip/index.less +0 -38
  147. package/dist/design/ant-design-theme.less +0 -4
  148. package/dist/design/ant-design-vue.less +0 -1
  149. package/dist/design/config.less +0 -2
  150. package/dist/isBrowser/index.d.ts +0 -1
  151. package/dist/isDeepEqualReact/index.d.ts +0 -1
  152. package/dist/isServer.d.ts +0 -2
  153. package/dist/omitBoolean/index.d.ts +0 -6
  154. package/dist/omitUndefined/index.d.ts +0 -5
  155. package/dist/pro-utils.es.js +0 -1044
  156. package/dist/pro-utils.umd.js +0 -1
  157. package/dist/proUtils.less +0 -4
  158. package/dist/scroll/easings.d.ts +0 -1
  159. package/dist/scroll/getScroll.d.ts +0 -2
  160. package/dist/scroll/index.d.ts +0 -4
  161. package/dist/scroll/raf.d.ts +0 -9
  162. package/dist/scroll/scrollTo.d.ts +0 -10
  163. package/dist/scroll/throttleByAnimationFrame.d.ts +0 -5
  164. package/dist/slots/index.d.ts +0 -9
  165. package/dist/style/index.less +0 -2
  166. package/dist/style.css +0 -1
  167. package/dist/style.less +0 -3
  168. package/dist/typings/index.d.ts +0 -30
  169. package/dist/utils/config.d.ts +0 -8
  170. package/dist/utils/index.d.ts +0 -208
  171. package/dist/utils/validate.d.ts +0 -25
@@ -0,0 +1,97 @@
1
+ import { isServer } from "../is/server.js";
2
+ import "../is/index.js";
3
+ import wrapperRaf from "./raf.js";
4
+
5
+ //#region src/dom/scroll.ts
6
+ function easeInOutCubic(t, b, c, d) {
7
+ const cc = c - b;
8
+ t /= d / 2;
9
+ if (t < 1) return cc / 2 * t * t * t + b;
10
+ return cc / 2 * ((t -= 2) * t * t + 2) + b;
11
+ }
12
+ function camelize(str) {
13
+ return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase());
14
+ }
15
+ function getStyle(element, styleName) {
16
+ if (isServer) return "";
17
+ if (!element || !styleName) return "";
18
+ styleName = camelize(styleName);
19
+ if (styleName === "float") styleName = "cssFloat";
20
+ try {
21
+ const style = element.style[styleName];
22
+ if (style) return style;
23
+ const computed = document?.defaultView?.getComputedStyle(element, "");
24
+ return computed ? computed[styleName] : "";
25
+ } catch {
26
+ return element.style[styleName];
27
+ }
28
+ }
29
+ function isScroll(el, isVertical) {
30
+ if (isServer) return;
31
+ return (isVertical === null || isVertical === void 0 ? getStyle(el, "overflow") : isVertical ? getStyle(el, "overflow-y") : getStyle(el, "overflow-x")).match(/(scroll|auto|overlay)/);
32
+ }
33
+ function getScrollContainer(el, isVertical) {
34
+ if (isServer) return;
35
+ let parent = el;
36
+ while (parent) {
37
+ if ([
38
+ window,
39
+ document,
40
+ document.documentElement
41
+ ].includes(parent)) return window;
42
+ if (isScroll(parent, isVertical)) return parent;
43
+ parent = parent.parentNode;
44
+ }
45
+ return parent;
46
+ }
47
+ function isInContainer(el, container) {
48
+ if (isServer || !el || !container) return false;
49
+ const elRect = el.getBoundingClientRect();
50
+ let containerRect;
51
+ if ([
52
+ window,
53
+ document,
54
+ document.documentElement,
55
+ null,
56
+ void 0
57
+ ].includes(container)) containerRect = {
58
+ top: 0,
59
+ right: window.innerWidth,
60
+ bottom: window.innerHeight,
61
+ left: 0
62
+ };
63
+ else containerRect = container.getBoundingClientRect();
64
+ return elRect.top < containerRect.bottom && elRect.bottom > containerRect.top && elRect.right > containerRect.left && elRect.left < containerRect.right;
65
+ }
66
+ function isWindow(obj) {
67
+ return obj !== null && obj !== void 0 && obj === obj.window;
68
+ }
69
+ function getScroll(target, top) {
70
+ if (typeof window === "undefined") return 0;
71
+ const method = top ? "scrollTop" : "scrollLeft";
72
+ let result = 0;
73
+ if (isWindow(target)) result = target[top ? "pageYOffset" : "pageXOffset"];
74
+ else if (target instanceof Document) result = target.documentElement[method];
75
+ else if (target) result = target[method];
76
+ if (target && !isWindow(target) && typeof result !== "number") result = (target.ownerDocument || target).documentElement?.[method];
77
+ return result;
78
+ }
79
+ function scrollTo(y, options = {}) {
80
+ const { getContainer = () => window, callback, duration = 450 } = options;
81
+ const container = getContainer();
82
+ const scrollTop = getScroll(container, true);
83
+ const startTime = Date.now();
84
+ const frameFunc = () => {
85
+ const time = Date.now() - startTime;
86
+ const nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration);
87
+ if (isWindow(container)) container.scrollTo(window.pageXOffset, nextScrollTop);
88
+ else if (container instanceof HTMLDocument || container.constructor.name === "HTMLDocument") container.documentElement.scrollTop = nextScrollTop;
89
+ else container.scrollTop = nextScrollTop;
90
+ if (time < duration) wrapperRaf(frameFunc);
91
+ else if (typeof callback === "function") callback();
92
+ };
93
+ if (container) wrapperRaf(frameFunc);
94
+ }
95
+
96
+ //#endregion
97
+ export { easeInOutCubic, getScroll, getScrollContainer, isInContainer, isScroll, isWindow, scrollTo };
@@ -0,0 +1,13 @@
1
+ //#region src/file/config.d.ts
2
+ /**
3
+ * 文件类型配置
4
+ */
5
+ declare const fileTypes: {
6
+ /** 允许的视频格式 */videoAllowType: string[]; /** 允许的音频格式 */
7
+ audioAllowType: string[]; /** 图片格式 */
8
+ imageType: string[]; /** 视频格式 */
9
+ videoType: string[]; /** 音频格式 */
10
+ audioType: string[];
11
+ };
12
+ //#endregion
13
+ export { fileTypes };
@@ -0,0 +1,81 @@
1
+ //#region src/file/config.ts
2
+ /**
3
+ * 文件类型配置
4
+ */
5
+ const fileTypes = {
6
+ videoAllowType: [
7
+ "mp4",
8
+ "webm",
9
+ "ogg"
10
+ ],
11
+ audioAllowType: [
12
+ "mp3",
13
+ "ogg",
14
+ "wav",
15
+ "aac",
16
+ "m4a",
17
+ "webm"
18
+ ],
19
+ imageType: [
20
+ "jpeg",
21
+ "jpg",
22
+ "png",
23
+ "gif",
24
+ "bmp",
25
+ "tiff",
26
+ "tif",
27
+ "webp",
28
+ "heic",
29
+ "heif",
30
+ "svg",
31
+ "ico",
32
+ "raw",
33
+ "cr2",
34
+ "nef",
35
+ "arw",
36
+ "dng",
37
+ "psd",
38
+ "eps"
39
+ ],
40
+ videoType: [
41
+ "mp4",
42
+ "avi",
43
+ "mov",
44
+ "wmv",
45
+ "mkv",
46
+ "flv",
47
+ "webm",
48
+ "mpeg",
49
+ "mpg",
50
+ "3gp",
51
+ "ogv",
52
+ "mxf",
53
+ "vob",
54
+ "rm",
55
+ "rmvb",
56
+ "ts",
57
+ "mts",
58
+ "m2ts",
59
+ "divx",
60
+ "xvid"
61
+ ],
62
+ audioType: [
63
+ "mp3",
64
+ "wav",
65
+ "aac",
66
+ "flac",
67
+ "ogg",
68
+ "wma",
69
+ "m4a",
70
+ "alac",
71
+ "opus",
72
+ "amr",
73
+ "aiff",
74
+ "au",
75
+ "pcm",
76
+ "ape"
77
+ ]
78
+ };
79
+
80
+ //#endregion
81
+ export { fileTypes };
@@ -0,0 +1,41 @@
1
+ //#region src/file/convert.d.ts
2
+ /**
3
+ * 获取 Blob URL
4
+ *
5
+ * @param blob - Blob 对象
6
+ * @returns Blob URL
7
+ */
8
+ declare function getBlobUrl(blob: Blob): string;
9
+ /**
10
+ * 获取文件 base64 编码
11
+ *
12
+ * @param file - 文件对象
13
+ * @returns base64 字符串
14
+ */
15
+ declare function getBase64(file: File): Promise<string | ArrayBuffer | null>;
16
+ /**
17
+ * Data URL 转 Blob 对象
18
+ *
19
+ * @param url - Data URL
20
+ * @returns Blob 对象
21
+ */
22
+ declare function dataURLtoBlob(url: any): Blob;
23
+ /**
24
+ * Data URL 转 File 对象
25
+ *
26
+ * @param url - Data URL
27
+ * @param filename - 文件名
28
+ * @returns File 对象
29
+ */
30
+ declare function dataURLtoFile(url: string, filename: string): File;
31
+ /**
32
+ * Blob 转 File 对象
33
+ *
34
+ * @param blob - Blob 对象
35
+ * @param fileName - 文件名
36
+ * @param fileType - 文件类型
37
+ * @returns File 对象
38
+ */
39
+ declare function blobToDataURL(blob: Blob, fileName: string, fileType: string): File;
40
+ //#endregion
41
+ export { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl };
@@ -0,0 +1,69 @@
1
+ //#region src/file/convert.ts
2
+ /**
3
+ * 获取 Blob URL
4
+ *
5
+ * @param blob - Blob 对象
6
+ * @returns Blob URL
7
+ */
8
+ function getBlobUrl(blob) {
9
+ return URL.createObjectURL(blob);
10
+ }
11
+ /**
12
+ * 获取文件 base64 编码
13
+ *
14
+ * @param file - 文件对象
15
+ * @returns base64 字符串
16
+ */
17
+ function getBase64(file) {
18
+ return new Promise((resolve, reject) => {
19
+ const reader = new FileReader();
20
+ reader.readAsDataURL(file);
21
+ reader.onload = () => resolve(reader.result);
22
+ reader.onerror = (error) => reject(error);
23
+ });
24
+ }
25
+ /**
26
+ * Data URL 转 Blob 对象
27
+ *
28
+ * @param url - Data URL
29
+ * @returns Blob 对象
30
+ */
31
+ function dataURLtoBlob(url) {
32
+ const arr = url.split(",");
33
+ const mime = arr[0].match(/:(.*?);/)[1];
34
+ const str = atob(arr[1]);
35
+ let n = str.length;
36
+ const u8arr = new Uint8Array(n);
37
+ while (n--) u8arr[n] = str.charCodeAt(n);
38
+ return new Blob([u8arr], { type: mime });
39
+ }
40
+ /**
41
+ * Data URL 转 File 对象
42
+ *
43
+ * @param url - Data URL
44
+ * @param filename - 文件名
45
+ * @returns File 对象
46
+ */
47
+ function dataURLtoFile(url, filename) {
48
+ const arr = url.split(",");
49
+ const mime = arr[0].match(/:(.*?);/)[1];
50
+ const str = atob(arr[1]);
51
+ let n = str.length;
52
+ const u8arr = new Uint8Array(n);
53
+ while (n--) u8arr[n] = str.charCodeAt(n);
54
+ return new File([u8arr], filename, { type: mime });
55
+ }
56
+ /**
57
+ * Blob 转 File 对象
58
+ *
59
+ * @param blob - Blob 对象
60
+ * @param fileName - 文件名
61
+ * @param fileType - 文件类型
62
+ * @returns File 对象
63
+ */
64
+ function blobToDataURL(blob, fileName, fileType) {
65
+ return new window.File([blob], fileName, { type: fileType });
66
+ }
67
+
68
+ //#endregion
69
+ export { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl };
@@ -0,0 +1,5 @@
1
+ import { fileTypes } from "./config.js";
2
+ import { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./convert.js";
3
+ import { generateVideoPicture, getMediaInfos, getVideoCoverPicture } from "./media.js";
4
+ import { checkFileType, getFileSuffix, getVideoFileUrl } from "./type.js";
5
+ export { blobToDataURL, checkFileType, dataURLtoBlob, dataURLtoFile, fileTypes, generateVideoPicture, getBase64, getBlobUrl, getFileSuffix, getMediaInfos, getVideoCoverPicture, getVideoFileUrl };
@@ -0,0 +1,6 @@
1
+ import { fileTypes } from "./config.js";
2
+ import { blobToDataURL, dataURLtoBlob, dataURLtoFile, getBase64, getBlobUrl } from "./convert.js";
3
+ import { checkFileType, getFileSuffix, getVideoFileUrl } from "./type.js";
4
+ import { generateVideoPicture, getMediaInfos, getVideoCoverPicture } from "./media.js";
5
+
6
+ export { blobToDataURL, checkFileType, dataURLtoBlob, dataURLtoFile, fileTypes, generateVideoPicture, getBase64, getBlobUrl, getFileSuffix, getMediaInfos, getVideoCoverPicture, getVideoFileUrl };
@@ -0,0 +1,35 @@
1
+ import { MediaOptions } from "../typing.js";
2
+
3
+ //#region src/file/media.d.ts
4
+ /**
5
+ * 获取媒体信息(图片/视频/音频)
6
+ *
7
+ * @param mediaInfo - 媒体信息配置
8
+ * @returns 媒体详细信息
9
+ */
10
+ declare function getMediaInfos(mediaInfo: {
11
+ url: any;
12
+ fileType?: string;
13
+ }): Promise<MediaOptions>;
14
+ /**
15
+ * 获取视频封面图
16
+ *
17
+ * @param videoInfo - 视频信息
18
+ * @returns 封面图 base64
19
+ */
20
+ declare function getVideoCoverPicture(videoInfo: {
21
+ url: any;
22
+ currentTime?: number;
23
+ videoSuffix?: string;
24
+ videoAllowPlay?: boolean;
25
+ }): Promise<string>;
26
+ /**
27
+ * 生成视频截图
28
+ *
29
+ * @param videoUrl - 视频 URL
30
+ * @param currentTime - 截图时间点
31
+ * @returns 截图 base64
32
+ */
33
+ declare function generateVideoPicture(videoUrl: string, currentTime?: number): Promise<string>;
34
+ //#endregion
35
+ export { generateVideoPicture, getMediaInfos, getVideoCoverPicture };
@@ -0,0 +1,161 @@
1
+ import { isBase64 } from "../is/base64.js";
2
+ import "../is/index.js";
3
+ import { fileTypes } from "./config.js";
4
+ import { checkFileType, getFileSuffix } from "./type.js";
5
+
6
+ //#region src/file/media.ts
7
+ /**
8
+ * 获取媒体信息(图片/视频/音频)
9
+ *
10
+ * @param mediaInfo - 媒体信息配置
11
+ * @returns 媒体详细信息
12
+ */
13
+ function getMediaInfos(mediaInfo) {
14
+ const { url = "", fileType = "1" } = mediaInfo || {};
15
+ let mediaUrl = "";
16
+ let result = {
17
+ play: false,
18
+ height: 0,
19
+ size: 0,
20
+ width: 0,
21
+ duration: 0
22
+ };
23
+ function resetResult() {
24
+ result = {
25
+ play: false,
26
+ height: 0,
27
+ size: 0,
28
+ width: 0,
29
+ duration: 0
30
+ };
31
+ }
32
+ if (url instanceof File) mediaUrl = URL.createObjectURL(url);
33
+ else if (isBase64(url)) mediaUrl = url;
34
+ else if (url instanceof Blob) mediaUrl = URL.createObjectURL(url);
35
+ else if (url.includes("https") || url.includes("http")) mediaUrl = fileType === "1" ? url : url;
36
+ return new Promise((resolve) => {
37
+ let el;
38
+ if (fileType === "4") {
39
+ resolve(result);
40
+ return;
41
+ }
42
+ if (fileType === "1") {
43
+ el = document.createElement("img");
44
+ el.src = mediaUrl;
45
+ } else if (fileType === "2") {
46
+ el = document.createElement("audio");
47
+ el.src = mediaUrl;
48
+ } else if (fileType === "3") {
49
+ el = document.createElement("video");
50
+ el.src = mediaUrl;
51
+ }
52
+ if (fileType === "1") el.onload = function() {
53
+ resetResult();
54
+ result.play = true;
55
+ result.width = el.width || 0;
56
+ result.height = el.height || 0;
57
+ resolve(result);
58
+ el = null;
59
+ };
60
+ else el.oncanplay = function() {
61
+ resetResult();
62
+ result.play = true;
63
+ result.width = el?.videoWidth || 0;
64
+ result.height = el?.videoHeight || 0;
65
+ result.duration = el?.duration || 0;
66
+ resolve(result);
67
+ el = null;
68
+ };
69
+ el.onerror = function() {
70
+ resetResult();
71
+ resolve(result);
72
+ el = null;
73
+ };
74
+ });
75
+ }
76
+ /**
77
+ * 获取视频封面图
78
+ *
79
+ * @param videoInfo - 视频信息
80
+ * @returns 封面图 base64
81
+ */
82
+ async function getVideoCoverPicture(videoInfo) {
83
+ const { url = "", currentTime, videoSuffix = "", videoAllowPlay = false } = videoInfo;
84
+ let videoUrl = "";
85
+ let fileSuffix = videoSuffix;
86
+ let fileType = "1";
87
+ let videoPlayInfo;
88
+ if (url instanceof File) {
89
+ videoUrl = URL.createObjectURL(url);
90
+ fileSuffix = getFileSuffix(url.name);
91
+ fileType = checkFileType(url.name);
92
+ } else if (url instanceof Blob) {
93
+ videoUrl = URL.createObjectURL(url);
94
+ fileType = checkFileType(url);
95
+ } else if (isBase64(url)) {
96
+ videoUrl = url;
97
+ fileType = checkFileType(url);
98
+ } else if (url.includes("https") || url.includes("http")) {
99
+ videoUrl = url;
100
+ fileSuffix = getFileSuffix(url);
101
+ fileType = checkFileType(url);
102
+ }
103
+ if (fileSuffix ? fileTypes.videoAllowType.includes(fileSuffix.toLowerCase()) : false) if (videoAllowPlay) return generateVideoPicture(videoUrl, currentTime);
104
+ else {
105
+ videoPlayInfo = await getMediaInfos({
106
+ url: videoUrl,
107
+ fileType
108
+ });
109
+ if (videoPlayInfo.play) return generateVideoPicture(videoUrl, currentTime);
110
+ else return new Promise((resolve) => {
111
+ resolve("");
112
+ });
113
+ }
114
+ else return new Promise((resolve) => {
115
+ resolve("");
116
+ });
117
+ }
118
+ /**
119
+ * 生成视频截图
120
+ *
121
+ * @param videoUrl - 视频 URL
122
+ * @param currentTime - 截图时间点
123
+ * @returns 截图 base64
124
+ */
125
+ async function generateVideoPicture(videoUrl, currentTime = 0) {
126
+ return new Promise((resolve) => {
127
+ let video = document.createElement("video");
128
+ if (video) {
129
+ video.controls = true;
130
+ video.muted = true;
131
+ video.setAttribute("src", videoUrl);
132
+ video.setAttribute("muted", String(true));
133
+ video.setAttribute("crossorigin", "anonymous");
134
+ video.setAttribute("autoplay", String(true));
135
+ video.addEventListener("loadeddata", async () => {
136
+ let seekResolve;
137
+ video?.addEventListener("seeked", async () => {
138
+ if (seekResolve) seekResolve();
139
+ });
140
+ while (currentTime < (video?.duration || 0)) {
141
+ if (video) video.currentTime = currentTime;
142
+ await new Promise((r) => seekResolve = r);
143
+ const canvas = document.createElement("canvas");
144
+ const scale = .8;
145
+ const ctx = canvas.getContext("2d");
146
+ const w = video?.videoWidth || 0 * scale;
147
+ const h = video?.videoHeight || 0 * scale;
148
+ const space = 0;
149
+ canvas.width = video?.videoWidth || 0 * scale;
150
+ canvas.height = video?.videoHeight || 0 * scale;
151
+ if (video) ctx.drawImage(video, 0, 0, w + space, h + space);
152
+ video = null;
153
+ resolve(w === 0 || h === 0 ? "" : canvas.toDataURL("image/png", 1));
154
+ }
155
+ });
156
+ }
157
+ });
158
+ }
159
+
160
+ //#endregion
161
+ export { generateVideoPicture, getMediaInfos, getVideoCoverPicture };
@@ -0,0 +1,25 @@
1
+ //#region src/file/type.d.ts
2
+ /**
3
+ * 获取文件后缀名
4
+ *
5
+ * @param url - 文件 URL
6
+ * @returns 后缀名
7
+ */
8
+ declare function getFileSuffix(url: string): string;
9
+ /**
10
+ * 截取视频 URL(去除参数)
11
+ *
12
+ * @param url - URL
13
+ * @returns 处理后的 URL
14
+ */
15
+ declare function getVideoFileUrl(url: string): string;
16
+ /**
17
+ * 检查文件类型
18
+ *
19
+ * @param url - 文件 URL 或对象
20
+ * @param type - 指定类型
21
+ * @returns 文件类型代码:1 图片, 2 音频, 3 视频, 4 其他
22
+ */
23
+ declare function checkFileType(url: any, type?: '1' | '2' | '3' | '4'): "1" | "2" | "3" | "4";
24
+ //#endregion
25
+ export { checkFileType, getFileSuffix, getVideoFileUrl };
@@ -0,0 +1,58 @@
1
+ import { isBase64 } from "../is/base64.js";
2
+ import "../is/index.js";
3
+ import { fileTypes } from "./config.js";
4
+
5
+ //#region src/file/type.ts
6
+ /**
7
+ * 获取文件后缀名
8
+ *
9
+ * @param url - 文件 URL
10
+ * @returns 后缀名
11
+ */
12
+ function getFileSuffix(url) {
13
+ if (!url || typeof url !== "string") return "";
14
+ const newUrl = getVideoFileUrl(url);
15
+ const index = newUrl.lastIndexOf(".");
16
+ return index > 0 ? `${newUrl?.substring?.(index)?.split("?")?.[0]}`?.split(".")?.[1] || "" : "";
17
+ }
18
+ /**
19
+ * 截取视频 URL(去除参数)
20
+ *
21
+ * @param url - URL
22
+ * @returns 处理后的 URL
23
+ */
24
+ function getVideoFileUrl(url) {
25
+ if (!url || typeof url !== "string") return "";
26
+ const index = url.indexOf("?");
27
+ return index > 0 ? `${url.substring(0, index)}` : url;
28
+ }
29
+ /**
30
+ * 检查文件类型
31
+ *
32
+ * @param url - 文件 URL 或对象
33
+ * @param type - 指定类型
34
+ * @returns 文件类型代码:1 图片, 2 音频, 3 视频, 4 其他
35
+ */
36
+ function checkFileType(url, type) {
37
+ if (type) return type;
38
+ if (!url) return "4";
39
+ if (url === "data:") return "4";
40
+ let fileType = "4";
41
+ if (isBase64(url)) {
42
+ if (url.includes("data:image/")) fileType = "png";
43
+ else if (url.includes("data:video/")) fileType = "mp4";
44
+ else if (url.includes("data:audio/")) fileType = "mp3";
45
+ } else if (url instanceof Blob) {
46
+ url = String(url);
47
+ if (url.includes("image")) fileType = "png";
48
+ else if (url.includes("video")) fileType = "mp4";
49
+ else if (url.includes("audio")) fileType = "mp3";
50
+ } else fileType = getFileSuffix(url).toLowerCase();
51
+ if (fileTypes.imageType.includes(fileType)) return "1";
52
+ if (fileTypes.videoType.includes(fileType)) return "3";
53
+ if (fileTypes.audioType.includes(fileType)) return "2";
54
+ return "4";
55
+ }
56
+
57
+ //#endregion
58
+ export { checkFileType, getFileSuffix, getVideoFileUrl };
@@ -0,0 +1,12 @@
1
+ import { RecordType } from "../typing.js";
2
+
3
+ //#region src/function/copy.d.ts
4
+ /**
5
+ * 简单深拷贝(使用 JSON 序列化)
6
+ *
7
+ * @param data - 要拷贝的数据
8
+ * @returns 拷贝后的数据
9
+ */
10
+ declare function deepCopy<T = RecordType>(data: any): T;
11
+ //#endregion
12
+ export { deepCopy };
@@ -0,0 +1,13 @@
1
+ //#region src/function/copy.ts
2
+ /**
3
+ * 简单深拷贝(使用 JSON 序列化)
4
+ *
5
+ * @param data - 要拷贝的数据
6
+ * @returns 拷贝后的数据
7
+ */
8
+ function deepCopy(data) {
9
+ return JSON.parse(JSON.stringify(data));
10
+ }
11
+
12
+ //#endregion
13
+ export { deepCopy };
@@ -0,0 +1,12 @@
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;
3
+ /**
4
+ * 根据 key 从对象中获取值(支持嵌套路径)
5
+ *
6
+ * @param object - 目标对象
7
+ * @param key - 键路径(支持用冒号分隔的嵌套路径)
8
+ * @returns 获取的值
9
+ */
10
+ declare function getValueFromObjectByKey<T extends object, K extends string | string[] = string>(object: T, key: K): DeepValueOf<T, K extends string ? K : string> | undefined;
11
+ //#endregion
12
+ export { getValueFromObjectByKey };
@@ -0,0 +1,19 @@
1
+ //#region src/function/getValue.ts
2
+ /**
3
+ * 根据 key 从对象中获取值(支持嵌套路径)
4
+ *
5
+ * @param object - 目标对象
6
+ * @param key - 键路径(支持用冒号分隔的嵌套路径)
7
+ * @returns 获取的值
8
+ */
9
+ function getValueFromObjectByKey(object, key) {
10
+ if (typeof key !== "string" && !Array.isArray(key)) return;
11
+ const keys = Array.isArray(key) ? key : key.split(":");
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]];
14
+ else return;
15
+ return currentValue;
16
+ }
17
+
18
+ //#endregion
19
+ export { getValueFromObjectByKey };
@@ -0,0 +1,5 @@
1
+ import { deepCopy } from "./copy.js";
2
+ import { getValueFromObjectByKey } from "./getValue.js";
3
+ import { forInObject, getSymbols, keysOf } from "./object.js";
4
+ import { runFunction } from "./run.js";
5
+ export { deepCopy, forInObject, getSymbols, getValueFromObjectByKey, keysOf, runFunction };
@@ -0,0 +1,6 @@
1
+ import { forInObject, getSymbols, keysOf } from "./object.js";
2
+ import { deepCopy } from "./copy.js";
3
+ import { getValueFromObjectByKey } from "./getValue.js";
4
+ import { runFunction } from "./run.js";
5
+
6
+ export { deepCopy, forInObject, getSymbols, getValueFromObjectByKey, keysOf, runFunction };