iota-utools 0.0.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.
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ ## iota-tools
2
+
3
+ ### 类型判断:
4
+
5
+ ```ts
6
+ // 数据类型
7
+ function etTypeof(value: any): string
8
+
9
+ // 是否是数组
10
+ function isArray(value: any): boolean
11
+
12
+ // 是否是布尔值
13
+ function isBoolean(value: any): boolean
14
+
15
+ // 是否是字符串类型
16
+ function isString(value: any): boolean
17
+
18
+ // 是否是数字
19
+ function isNumber(value: any): boolean
20
+
21
+ // 是否是object 类型 - @::
22
+ function isObject(value: any): boolean
23
+
24
+ // 是否是一个方法
25
+ function isFunction(value: any): boolean
26
+
27
+ // 是否是一个Map
28
+ function isMap(value: any): boolean
29
+
30
+ // 是否是一个Set 类型
31
+ function isSet(value: any): boolean
32
+
33
+ // 是否是一个Symbol 类型
34
+ function isSymbol(value: any): boolean
35
+ ```
36
+
37
+ ### 复制文本的方法
38
+
39
+ ```ts
40
+ // 复制文本
41
+ function copyText(text: string): void
42
+ ```
43
+
44
+ ### 阻塞进程方法
45
+
46
+ ```ts
47
+ // 阻塞进程
48
+ function sleep(ms: number): void
49
+ ```
50
+
51
+ ### LocalStorage 存取
52
+
53
+ ```ts
54
+ // 向 localStorage 存数据
55
+ function setLocalStorage(key: string, data: any)
56
+
57
+ // 向 localStorage 取数据
58
+ function getLocalStorage(key: string): any
59
+
60
+ // 移除 localStorage 数据
61
+ function removeLocalStorageKey(...args: string[])
62
+ ```
63
+
64
+ ### SessionStorage 存取
65
+
66
+ ```ts
67
+ // 向 sessionStorage 存数据
68
+ function setSessionStorage(key: string, data: any)
69
+
70
+ // 向 sessionStorage 取数据
71
+ function getSessionStorage(key: string): any
72
+
73
+ // 移除 sessionStorage 数据
74
+ function removeSessionStorageKey(...args: string[])
75
+ ```
76
+
77
+ ### params 处理
78
+
79
+ ```ts
80
+ // 将字符串转成对象 {key:value}
81
+ function decodeParams(queryString: string)
82
+
83
+ // 将对象转成 ?key=value&key=value
84
+ function encodeParams(query: Record<string, any>)
85
+ ```
86
+
87
+ ### 拉流、文件流下载
88
+
89
+ ```ts
90
+ // 下载文件流
91
+ function downFile(stream: string | ArrayBuffer, name: string, mimeType: string = "text/plain;charset=utf-8")
92
+
93
+ // 拉流且下载文件流
94
+ function downStream(path: string, defaultName: string, token?: string, params?: Record<string, any>)
95
+ ```
96
+
97
+ ### 数组处理方法
98
+
99
+ ```ts
100
+ // 根据key 类型数据去去重
101
+ function uniqueArrayByProperty<T>(array: T[], key: keyof T): T[]
102
+ ```
103
+
104
+ ### Tree 数据处理
105
+
106
+ ```ts
107
+ // 树 -> 扁平树
108
+ function toFlatTree(origin: TreeData[])
109
+
110
+ // 扁平树 -> 树
111
+ function toTreeFlat<T extends TreeData>(origin: T[], parentId: number | string = "root")
112
+
113
+ // 深拷贝
114
+ function deepClone<T = any>(obj: T): T
115
+
116
+ // 删除某个节点 纯函数
117
+ function deleteTreeNode<T extends TreeData>(origin: T[], id: string | number, key: keyof T = "id"): T[]
118
+
119
+ // 查找某个节点
120
+ function findTreeNode<T extends TreeData>(origin: T[], findValue: any, key: keyof T = "id"): T | null
121
+
122
+ // 模糊查询 树节点
123
+ function fuzzySearchTree<T extends TreeData>(treeData: T[], findStr: string, label: keyof T = "title"): T[]
124
+ ```
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ presets: [
3
+ [
4
+ "@babel/preset-env",
5
+ {
6
+ targets: { node: "current" },
7
+ },
8
+ ],
9
+ "@babel/preset-typescript",
10
+ ],
11
+ };
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "iota-utools",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "main": "main.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "rollup -c",
9
+ "test": "jest --coverage --verbose -u",
10
+ "start": "rollup -c rollup.config.js --watch"
11
+ },
12
+ "keywords": [],
13
+ "author": "",
14
+ "license": "ISC",
15
+ "devDependencies": {
16
+ "@babel/core": "^7.21.3",
17
+ "@babel/preset-env": "^7.20.2",
18
+ "@babel/preset-typescript": "^7.21.0",
19
+ "@rollup/plugin-babel": "^6.0.3",
20
+ "@rollup/plugin-node-resolve": "^15.0.1",
21
+ "babel-jest": "^29.5.0",
22
+ "jest": "^29.5.0",
23
+ "rollup": "^3.29.4",
24
+ "rollup-plugin-babel": "^4.4.0",
25
+ "rollup-plugin-commonjs": "^10.1.0",
26
+ "rollup-plugin-livereload": "^2.0.5",
27
+ "rollup-plugin-node-resolve": "^5.2.0",
28
+ "rollup-plugin-serve": "^2.0.2",
29
+ "rollup-plugin-sourcemaps": "^0.6.3",
30
+ "rollup-plugin-typescript2": "^0.34.1",
31
+ "rollup-plugin-uglify": "^6.0.4",
32
+ "ts-jest": "^29.0.5",
33
+ "tslib": "^2.5.0",
34
+ "typescript": "^5.0.2"
35
+ }
36
+ }
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Document</title>
8
+ </head>
9
+
10
+ <body>
11
+ <h1>Test Fun In Page</h1>
12
+ <hr />
13
+ <h2>window utools object function!!</h2>
14
+ <hr />
15
+ <script type="module">
16
+ import * as utools from "../lib/bundle.esm.js"
17
+ window.utools = utools
18
+ </script>
19
+ </body>
20
+ </html>
@@ -0,0 +1,51 @@
1
+ // ./`rollup.config.js`
2
+ import babel from "@rollup/plugin-babel";
3
+ import commonjs from "rollup-plugin-commonjs";
4
+ import { uglify } from "rollup-plugin-uglify";
5
+ import sourceMaps from "rollup-plugin-sourcemaps";
6
+ import resolve from "@rollup/plugin-node-resolve";
7
+ import typescript from "rollup-plugin-typescript2";
8
+ import livereload from "rollup-plugin-livereload"; // hot
9
+ import serve from "rollup-plugin-serve";
10
+
11
+ export default {
12
+ input: "./src/main.ts",
13
+
14
+ output: [
15
+ {
16
+ format: "cjs",
17
+ file: "lib/bundle.cjs.js",
18
+ sourcemap: true,
19
+ },
20
+ {
21
+ format: "es",
22
+ file: "lib/bundle.esm.js",
23
+ sourcemap: true,
24
+ },
25
+ ],
26
+
27
+ plugins: [
28
+ resolve({
29
+ // 将自定义选项传递给解析插件
30
+ customResolveOptions: {
31
+ moduleDirectory: "node_modules",
32
+ },
33
+ }),
34
+ commonjs(),
35
+ typescript(),
36
+ sourceMaps(),
37
+ uglify(), // 压缩代码
38
+ livereload(),
39
+ babel({
40
+ runtimeHelpers: true,
41
+ // 只转换源代码,不运行外部依赖
42
+ exclude: "node_modules/**",
43
+ babelHelpers: "bundled",
44
+ }),
45
+ serve({
46
+ open: true,
47
+ port: 10801,
48
+ contentBase: ["", "./public"],
49
+ }),
50
+ ],
51
+ };
@@ -0,0 +1 @@
1
+ export * from "./uniqueArrayByProperty";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @description: 对象数组中去重处理
3
+ * @param array 数据源
4
+ * @param key 根据类型
5
+ * @return T[]
6
+ */
7
+ export function uniqueArrayByProperty<T>(array: T[], key: keyof T): T[] {
8
+ return array.reduce((acc, item) => {
9
+ if (!acc.some((existingItem) => existingItem[key] === item[key])) {
10
+ acc.push(item);
11
+ }
12
+ return acc;
13
+ }, [] as T[]);
14
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @description: 深拷贝
3
+ * @param {any} obj
4
+ * @return {*} obj
5
+ */
6
+ export const deepClone = <T = any>(obj: T): T => {
7
+ if (obj === null || typeof obj !== "object") {
8
+ return obj;
9
+ }
10
+
11
+ if (Array.isArray(obj)) {
12
+ const arrCopy: any[] = [];
13
+ for (const item of obj) {
14
+ arrCopy.push(deepClone(item));
15
+ }
16
+ return arrCopy as any;
17
+ }
18
+
19
+ const objCopy: { [key: string]: any } = {};
20
+ for (const key in obj) {
21
+ if (obj.hasOwnProperty(key)) {
22
+ objCopy[key] = deepClone((obj as { [key: string]: any })[key]);
23
+ }
24
+ }
25
+ return objCopy as T;
26
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @description: 过滤筛选树 -- search tree
3
+ * @param origin 数据源
4
+ * @param id
5
+ * @return new tree data 纯函数
6
+ */
7
+ export function deleteTreeNode<T extends TreeData>(origin: T[], id: string | number, key: keyof T = "id"): T[] {
8
+ return origin.filter((node) => {
9
+ if (node.children) {
10
+ node.children = deleteTreeNode(node.children as T[], id, key);
11
+ }
12
+ return node[key] !== id;
13
+ });
14
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @description: 查找树节点
3
+ * @param origin 数据源
4
+ * @param findValue 找到节点
5
+ * @param key 默认id
6
+ * @return T
7
+ */
8
+ export function findTreeNode<T extends TreeData>(origin: T[], findValue: any, key: keyof T = "id"): T | null {
9
+ let result: T | null = null;
10
+
11
+ const fun = (data: T[]) => {
12
+ if (Array.isArray(data)) {
13
+ for (let i = 0; i < data.length; i++) {
14
+ let item = data[i];
15
+ if (item[key] === findValue) {
16
+ result = item;
17
+ return;
18
+ }
19
+ if (item.children && item.children.length) {
20
+ fun(item.children as T[]);
21
+ }
22
+ }
23
+ }
24
+ };
25
+
26
+ fun(origin);
27
+ return result;
28
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @description: 过滤筛选树 -- search tree
3
+ * @param treeData 数据源
4
+ * @param findStr 关键字
5
+ * @param label 关键字段
6
+ * @return new tree data
7
+ */
8
+ export const fuzzySearchTree = <T extends TreeData>(treeData: T[], findStr: string, label: keyof T = "title"): T[] => {
9
+ if (!treeData) return [];
10
+ let list: T[] = [];
11
+
12
+ treeData.forEach((item) => {
13
+ // 确保label属性是字符串并且包含findStr
14
+ if (typeof item[label] === "string" && (item[label] as string).includes(findStr)) {
15
+ // 递归处理子节点
16
+ let children = item.children ? fuzzySearchTree(item.children as T[], findStr, label) : [];
17
+
18
+ // 如果子节点中没有匹配的项,则保留原子节点
19
+ children = children.length > 0 ? children : (item.children as T[]);
20
+
21
+ // 构造新的节点,保留匹配的子节点
22
+ const obj = { ...item, children };
23
+ list.push(obj);
24
+ } else if (item.children && item.children.length > 0) {
25
+ // 如果当前节点不匹配,但有子节点,则递归处理子节点
26
+ const children = fuzzySearchTree(item.children as T[], findStr, label);
27
+
28
+ // 如果子节点中有匹配的项,则保留当前节点,并更新其子节点
29
+ if (children.length > 0) {
30
+ const obj = { ...item, children };
31
+ list.push(obj);
32
+ }
33
+ }
34
+ });
35
+
36
+ return list;
37
+ };
@@ -0,0 +1,6 @@
1
+ export * from "./toFlatTree";
2
+ export * from "./toTreeFlat";
3
+ export * from "./findTreeNode";
4
+ export * from "./fuzzySearchTree";
5
+ export * from "./deleteTreeNode";
6
+ export * from "./deepClone";
@@ -0,0 +1,4 @@
1
+ type TreeData = {
2
+ [s: string]: any;
3
+ children?: TreeData[];
4
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @description: tree data -> 扁平树
3
+ * @param origin 数据源
4
+ * @return treedata
5
+ */
6
+ export function toFlatTree(origin: TreeData[]) {
7
+ return origin.reduce((res, item) => {
8
+ const { children, ...i } = item;
9
+ return res.concat(i, children && children.length ? toFlatTree(children) : []);
10
+ }, []);
11
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @description: 扁平树 -> tree data
3
+ * @param origins 数据源
4
+ * @param parentId 父级ID
5
+ * @return 平铺数据
6
+ */
7
+ export function toTreeFlat<T extends TreeData>(origin: T[], parentId: number | string = "root") {
8
+ // treeArr 变量数据
9
+ // 第一次:查找所有parentId为的数据组成第一级
10
+ const child = origin.filter((item: any) => item.parentId === parentId);
11
+ // 第一次:循环parentId为数组
12
+ return child.map((item: T) => {
13
+ return {
14
+ ...item,
15
+ // 当前存在id(id与parentId应该是必须有的)调用initTree() 查找所有parentId为本id的数据
16
+ children: toTreeFlat(origin, item.id),
17
+ };
18
+ });
19
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @description: 下载文件
3
+ * @param stream 文件源,string or buffer
4
+ * @param name 文件名称
5
+ * @param mimeType type josn
6
+ * @return new tree data 纯函数
7
+ */
8
+ export const downFile = (stream: string | ArrayBuffer, name: string, mimeType: string = "text/plain;charset=utf-8") => {
9
+ // 创建 Blob 对象
10
+ let blob: Blob;
11
+ if (typeof stream === "string") {
12
+ blob = new Blob([stream], { type: mimeType });
13
+ } else {
14
+ blob = new Blob([stream], { type: mimeType });
15
+ }
16
+
17
+ // 创建下载链接并触发下载
18
+ const a = document.createElement("a");
19
+ a.href = URL.createObjectURL(blob);
20
+ a.download = name;
21
+ a.style.display = "none";
22
+ document.body.appendChild(a);
23
+ a.click();
24
+ document.body.removeChild(a);
25
+
26
+ // 清理创建的 URL 对象
27
+ URL.revokeObjectURL(a.href);
28
+ };
@@ -0,0 +1,46 @@
1
+ import { downFile } from "./downFile";
2
+
3
+ /**
4
+ * @description: 拉流下载方法
5
+ * @param path 下载url
6
+ * @param defaultName 匹配请求如果没有使用名称
7
+ * @param token 鉴权 Authorization
8
+ * @param params 参数 object
9
+ */
10
+ export const downStream = (path: string, defaultName: string, token?: string, params?: Record<string, any>) => {
11
+ // 处理查询参数
12
+ const queryParams = new URLSearchParams(params).toString();
13
+ const urlWithParams = queryParams ? `${path}?${queryParams}` : path;
14
+
15
+ const xhr = new XMLHttpRequest();
16
+ xhr.open("GET", urlWithParams);
17
+ xhr.responseType = "blob";
18
+
19
+ if (token) xhr.setRequestHeader("Authorization", token);
20
+ xhr.onload = function () {
21
+ if (xhr.status === 200 || xhr.status === 304) {
22
+ const disposition = xhr.getResponseHeader("Content-Disposition");
23
+ let filename = defaultName;
24
+
25
+ // 从 Content-Disposition 中提取文件名
26
+ if (disposition && disposition.indexOf("attachment") !== -1) {
27
+ const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
28
+ const matches = filenameRegex.exec(disposition);
29
+ if (matches != null && matches[1]) {
30
+ filename = matches[1].replace(/['"]/g, "");
31
+ }
32
+ }
33
+
34
+ // 下载文件
35
+ downFile(this.response, filename);
36
+ } else {
37
+ console.error(`Failed to download file. Status: ${xhr.status}`);
38
+ }
39
+ };
40
+
41
+ xhr.onerror = function () {
42
+ console.error("Request failed.");
43
+ };
44
+
45
+ xhr.send();
46
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./downFile";
2
+ export * from "./downStream";
package/src/main.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./storage";
2
+ export * from "./utools";
3
+ export * from "./fileStream";
4
+ export * from "./datatree";
5
+ export * from "./uuid";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @description: 将params code 转成 object
3
+ * @param {string} [queryString]
4
+ * @return {*} object
5
+ */
6
+ export const decodeParams = (queryString: string) => {
7
+ const params = new URLSearchParams(queryString);
8
+ // 使用 Array.from 将迭代器转换为数组,然后使用 reduce 将数组转换为对象
9
+ return Array.from(params.entries()).reduce((acc: any, [key, value]) => {
10
+ acc[key] = value;
11
+ return acc;
12
+ }, {});
13
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @description: 将params code 转成 object
3
+ * @param {objct} [str:string]:any
4
+ * @return {*} string
5
+ */
6
+ export const encodeParams = (query: Record<string, any>) => {
7
+ const queryString = "?" + new URLSearchParams(query).toString();
8
+ return queryString;
9
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./decodeParams";
2
+ export * from "./encodeParams";
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @web 环境下才能使用注册
3
+ * 包含了storage 增删改查封装 存储监听等功能
4
+ * 监听的方式使用的浏览器evet 事件模型
5
+ */
6
+
7
+ export * from "./local";
8
+ export * from "./session";
9
+
10
+ // init envet storage change
11
+ const monitorLocalStorage = () => {
12
+ let originalSetItem = localStorage.setItem;
13
+ //重写setItem函数
14
+ localStorage.setItem = function (key, newValue) {
15
+ //创建setItemEvent事件
16
+ let event = new Event("setLocal") as any;
17
+ event.key = key;
18
+ event.newValue = newValue;
19
+ //提交setItemEvent事件
20
+ window.dispatchEvent(event);
21
+ //执行原setItem函数
22
+ originalSetItem.call(this, key, newValue);
23
+ };
24
+ };
25
+
26
+
27
+ /**
28
+ * @这个方法实际没多大用
29
+ */
30
+ const monitorSessionStorage = () => {
31
+ let originalSetItem = sessionStorage.setItem;
32
+ //重写setItem函数
33
+ sessionStorage.setItem = function (key, newValue) {
34
+ //创建setItemEvent事件
35
+ let event = new Event("setSessoin") as any;
36
+ event.key = key;
37
+ event.newValue = newValue;
38
+ //提交setItemEvent事件
39
+ window.dispatchEvent(event);
40
+ //执行原setItem函数
41
+ originalSetItem.call(this, key, newValue);
42
+ };
43
+ };
44
+
45
+ // 用于local 监听
46
+ const monitorStorage = () => {
47
+ monitorLocalStorage();
48
+ monitorSessionStorage();
49
+ };
50
+
51
+ monitorStorage();
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @description: get value
3
+ * @param {type: String}
4
+ * @return: [Object,String,null]
5
+ */
6
+ export function getLocalStorage(key: string): any {
7
+ let storageData = localStorage.getItem(key);
8
+ if (storageData) {
9
+ let storage;
10
+ try {
11
+ storage = JSON.parse(storageData);
12
+ } catch (err) {
13
+ storage = storageData;
14
+ }
15
+ return storage;
16
+ }
17
+ return storageData;
18
+ }
19
+
20
+ /**
21
+ * @description: set value
22
+ * @param {[key,data]}
23
+ * @return:void
24
+ */
25
+ export function setLocalStorage(key: string, data: any) {
26
+ typeof data === "string" ? localStorage.setItem(key, data) : localStorage.setItem(key, JSON.stringify(data));
27
+ }
28
+
29
+ /**
30
+ * @description: remove
31
+ * @param { arguments }
32
+ * @return: [Array,undefined]
33
+ */
34
+ export function removeLocalStorageKey(...args: string[]) {
35
+ let errArgs: string[] = [];
36
+ args.forEach((item) => {
37
+ typeof item === "string" ? localStorage.removeItem(item) : errArgs.push(item);
38
+ });
39
+ return errArgs.length ? { errMsg: "error param", errKey: errArgs } : undefined;
40
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @description: sessionStorage Value
3
+ * @param {type: String}
4
+ * @return: [Object,String,null]
5
+ */
6
+ export function getSessionStorage(key: string): any {
7
+ let storageData = sessionStorage.getItem(key);
8
+ if (storageData) {
9
+ let storage;
10
+ try {
11
+ storage = JSON.parse(storageData);
12
+ } catch (err) {
13
+ storage = storageData;
14
+ }
15
+ return storage;
16
+ }
17
+ return storageData;
18
+ }
19
+
20
+ /**
21
+ * @description: sessionStorage set Value
22
+ * @param {[key,data]}
23
+ * @return:void
24
+ */
25
+ export function setSessionStorage(key: string, data: any) {
26
+ typeof data === "string" ? sessionStorage.setItem(key, data) : sessionStorage.setItem(key, JSON.stringify(data));
27
+ }
28
+
29
+ /**
30
+ * @description: remove sessionStorage key
31
+ * @param { arguments }
32
+ * @return: [Array,undefined]
33
+ */
34
+ export function removeSessionStorageKey(...args: string[]) {
35
+ let errArgs: string[] = [];
36
+ args.forEach((item) => {
37
+ typeof item === "string" ? sessionStorage.removeItem(item) : errArgs.push(item);
38
+ });
39
+ return errArgs.length ? { errMsg: "error param", errKey: errArgs } : undefined;
40
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @description: 复制文本
3
+ * @param {string} content
4
+ * @return {*} string
5
+ */
6
+ export const copyText = (text: string) => {
7
+ if (navigator.clipboard && window.isSecureContext) {
8
+ // navigator clipboard 向剪贴板写文本
9
+ return navigator.clipboard.writeText(text);
10
+ } else {
11
+ const textarea = document.createElement("textarea");
12
+ textarea.value = text;
13
+ document.body.appendChild(textarea);
14
+ textarea.select();
15
+ document.execCommand("copy");
16
+ document.body.removeChild(textarea);
17
+ }
18
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./typeof";
2
+ export * from "./sleep";
3
+ export * from "./copyText";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @description: Sleep 主线程阻塞方法
3
+ * @return {*} int 单位 ms
4
+ */
5
+ export const sleep = (ms: number) => {
6
+ let target = new Date().getTime() + ms;
7
+ while (true) {
8
+ let now = new Date().getTime();
9
+ if (now >= target) break;
10
+ }
11
+ };
@@ -0,0 +1,39 @@
1
+ export function getTypeof(value: any): string {
2
+ return Object.prototype.toString.call(value).slice(8, -1);
3
+ }
4
+
5
+ export function isArray(value: any): boolean {
6
+ return getTypeof(value) === "Array";
7
+ }
8
+
9
+ export function isBoolean(value: any): boolean {
10
+ return getTypeof(value) === "Boolean";
11
+ }
12
+
13
+ export function isString(value: any): boolean {
14
+ return getTypeof(value) === "String";
15
+ }
16
+
17
+ export function isNumber(value: any): boolean {
18
+ return getTypeof(value) === "Number";
19
+ }
20
+
21
+ export function isObject(value: any): boolean {
22
+ return getTypeof(value) === "Object";
23
+ }
24
+
25
+ export function isFunction(value: any): boolean {
26
+ return getTypeof(value) === "Function";
27
+ }
28
+
29
+ export function isMap(value: any): boolean {
30
+ return getTypeof(value) === "Map";
31
+ }
32
+
33
+ export function isSet(value: any): boolean {
34
+ return getTypeof(value) === "Set";
35
+ }
36
+
37
+ export function isSymbol(value: any): boolean {
38
+ return getTypeof(value) === "Symbol";
39
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @description: 需要以字母开头的随机字符串
3
+ * @param length 字符串长度 默认8
4
+ * @return string
5
+ */
6
+ export const generateString = (length: number = 8): string => {
7
+ const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
8
+ const randomChar = () => characters.charAt(Math.floor(Math.random() * characters.length));
9
+
10
+ const timestamp = Date.now().toString(36); // Use timestamp for uniqueness
11
+ let result = timestamp + Array.from({ length: length - timestamp.length }, randomChar).join("");
12
+
13
+ return result.charAt(0).toUpperCase() + result.slice(1); // Ensure it starts with a letter
14
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @description: uuid
3
+ * @param template uuid模板 默认
4
+ * @return string
5
+ */
6
+ export const generateUUID = (template: string = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"): string => {
7
+ // Helper function to generate a random hex digit
8
+ const randomHexDigit = (c: string): string => {
9
+ const r = crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c === "x" ? 0 : 4));
10
+ return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
11
+ };
12
+
13
+ // Generate UUID based on template
14
+ return template.replace(/[xy]/g, randomHexDigit);
15
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./generateUUID";
2
+ export * from "./generateString";
@@ -0,0 +1,5 @@
1
+ const nodeList = [
2
+ { id: "1-1", children: [{ id: "1-2-1" }, { id: "1-2-2" }] },
3
+ { id: "2-1" },
4
+ { id: "3-1", children: [{ id: "3-2-1", children: [{ id: "3-3-1" }] }] },
5
+ ];
@@ -0,0 +1,74 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import { getTypeof, isArray, isNumber, isString, isBoolean, isObject, isFunction } from "../src/main";
3
+
4
+ describe("utools", () => {
5
+ test("get value typeof", () => {
6
+ expect(getTypeof("string")).toBe("String");
7
+ });
8
+ });
9
+
10
+ describe("utools", () => {
11
+ test("get value typeof", () => {
12
+ expect(getTypeof(1024)).toBe("Number");
13
+ });
14
+ });
15
+
16
+ describe("utools", () => {
17
+ test("get value typeof", () => {
18
+ expect(getTypeof(false)).toBe("Boolean");
19
+ });
20
+ });
21
+
22
+ describe("utools", () => {
23
+ test("value is Array", () => {
24
+ expect(isArray([1, 2, 3])).toBe(true);
25
+ });
26
+ });
27
+
28
+ describe("utools", () => {
29
+ test("value is Array", () => {
30
+ expect(isArray({ name: "lx" })).toBe(false);
31
+ });
32
+ });
33
+
34
+ describe("utools", () => {
35
+ test("value is number", () => {
36
+ expect(isNumber("hello world")).toBe(false);
37
+ });
38
+ });
39
+
40
+ describe("utools", () => {
41
+ test("value is number", () => {
42
+ expect(isNumber(1024)).toBe(true);
43
+ });
44
+ });
45
+
46
+ describe("utools", () => {
47
+ test("value is string", () => {
48
+ expect(isString(1024)).toBe(false);
49
+ });
50
+ });
51
+
52
+ describe("utools", () => {
53
+ test("value is String", () => {
54
+ expect(isString("hello world")).toBe(true);
55
+ });
56
+ });
57
+
58
+ describe("utools", () => {
59
+ test("value is bol", () => {
60
+ expect(isObject({ name: "lx" })).toBe(true);
61
+ });
62
+ });
63
+
64
+ describe("utools", () => {
65
+ test("value is bol", () => {
66
+ expect(isBoolean(false)).toBe(true);
67
+ });
68
+ });
69
+
70
+ describe("utools", () => {
71
+ test("value is bol", () => {
72
+ expect(isFunction({ name: "lx" })).toBe(false);
73
+ });
74
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,26 @@
1
+ /* tsconfig.json */
2
+ {
3
+ "compilerOptions": {
4
+ /* 基础配置 */
5
+ "target": "esnext",
6
+ "lib": [
7
+ "dom",
8
+ "esnext"
9
+ ],
10
+ "removeComments": false,
11
+ "declaration": true,
12
+ "sourceMap": true,
13
+ /* 强类型检查配置 */
14
+ "strict": true,
15
+ "noImplicitAny": false,
16
+ /* 模块分析配置 */
17
+ "baseUrl": ".",
18
+ "outDir": "./lib",
19
+ "esModuleInterop": true,
20
+ "moduleResolution": "node",
21
+ "resolveJsonModule": true
22
+ },
23
+ "include": [
24
+ "src"
25
+ ]
26
+ }