From 43ca9881d82880827c77998620d81add32a505d8 Mon Sep 17 00:00:00 2001 From: longdayi <13477510+longdayilongdayi@user.noreply.gitee.com> Date: Wed, 5 Feb 2025 15:10:40 +0800 Subject: [PATCH] 02051510 --- .continue/prompts/coder.prompt | 19 +++ .continue/prompts/comment.prompt | 5 - apps/web/package.json | 181 ++++++++++----------- apps/web/src/hooks/useTusUpload.ts | 7 - packages/common/src/index.ts | 5 +- packages/common/src/models/course.ts | 7 + packages/common/src/models/department.ts | 15 ++ packages/common/src/models/index.ts | 9 + packages/common/src/models/message.ts | 7 + packages/common/src/models/post.ts | 35 ++++ packages/common/src/models/rbac.ts | 22 +++ packages/common/src/models/section.ts | 5 + packages/common/src/{ => models}/select.ts | 0 packages/common/src/models/staff.ts | 38 +++++ packages/common/src/models/term.ts | 8 + packages/common/src/types.ts | 138 ---------------- packages/common/src/utils.ts | 4 +- packages/utils/src/array-utils.ts | 0 packages/utils/src/browser-utils.ts | 0 packages/utils/src/crypto-utils.ts | 0 packages/utils/src/date-utils.ts | 0 packages/utils/src/dom-utils.ts | 0 packages/utils/src/file-utils.ts | 0 packages/utils/src/index.ts | 2 +- packages/utils/src/math-utils.ts | 99 +++++++++++ packages/utils/src/object-utils.ts | 59 +++++++ packages/utils/src/random-utils.ts | 85 ++++++++++ packages/utils/src/string-utils.ts | 80 +++++++++ packages/utils/src/type-utils.ts | 94 +++++++++++ packages/utils/src/types.ts | 1 - packages/utils/src/validation-utils.ts | 0 pnpm-lock.yaml | 146 ----------------- 32 files changed, 677 insertions(+), 394 deletions(-) create mode 100644 .continue/prompts/coder.prompt create mode 100644 packages/common/src/models/course.ts create mode 100644 packages/common/src/models/department.ts create mode 100644 packages/common/src/models/index.ts create mode 100644 packages/common/src/models/message.ts create mode 100644 packages/common/src/models/post.ts create mode 100644 packages/common/src/models/rbac.ts create mode 100644 packages/common/src/models/section.ts rename packages/common/src/{ => models}/select.ts (100%) create mode 100644 packages/common/src/models/staff.ts create mode 100644 packages/common/src/models/term.ts create mode 100644 packages/utils/src/array-utils.ts create mode 100644 packages/utils/src/browser-utils.ts create mode 100644 packages/utils/src/crypto-utils.ts create mode 100644 packages/utils/src/date-utils.ts create mode 100644 packages/utils/src/dom-utils.ts create mode 100644 packages/utils/src/file-utils.ts create mode 100644 packages/utils/src/math-utils.ts create mode 100644 packages/utils/src/object-utils.ts create mode 100644 packages/utils/src/random-utils.ts create mode 100644 packages/utils/src/string-utils.ts create mode 100644 packages/utils/src/type-utils.ts delete mode 100644 packages/utils/src/types.ts create mode 100644 packages/utils/src/validation-utils.ts diff --git a/.continue/prompts/coder.prompt b/.continue/prompts/coder.prompt new file mode 100644 index 0000000..dce8ee7 --- /dev/null +++ b/.continue/prompts/coder.prompt @@ -0,0 +1,19 @@ +temperature: 0.5 +maxTokens: 8192 +--- + +请扮演一名经验丰富的高级软件开发工程师,根据用户提供的指令创建、改进或扩展代码功能。 +输入要求: +1. 用户将提供目标文件名或需要实现的功能描述。 +2. 输入中可能包括文件路径、代码风格要求,以及与功能相关的具体业务逻辑或技术细节。 +任务描述: +1. 根据提供的文件名或功能需求,编写符合规范的代码文件或代码片段。 +2. 如果已有文件,检查并基于现有实现完善功能或修复问题。 +3. 遵循约定的开发框架、语言标准和最佳实践。 +4. 注重代码可维护性,添加适当的注释,确保逻辑清晰。 +输出要求: +1. 仅返回生成的代码或文件内容。 +2. 全程使用中文注释 +3. 尽量避免硬编码和不必要的复杂性,以提高代码的可重用性和效率。 +4. 如功能涉及外部接口或工具调用,请确保通过注释给出清晰的说明和依赖。 + \ No newline at end of file diff --git a/.continue/prompts/comment.prompt b/.continue/prompts/comment.prompt index 68cb798..37fbee4 100755 --- a/.continue/prompts/comment.prompt +++ b/.continue/prompts/comment.prompt @@ -4,11 +4,9 @@ maxTokens: 8192 角色定位: - 高级软件开发工程师 -- 代码文档化与知识传播专家 注释目标: 1. 顶部注释 - 模块/文件整体功能描述 - - 使用场景 2. 类注释 - 核心功能概述 - 设计模式解析 @@ -22,12 +20,9 @@ maxTokens: 8192 - 逐行解释代码意图 - 关键语句原理阐述 - 高级语言特性解读 - - 潜在的设计考量 注释风格要求: - 全程使用中文 - 专业、清晰、通俗易懂 -- 面向初学者的知识传递 -- 保持技术严谨性 输出约束: - 仅返回添加注释后的代码 - 注释与代码完美融合 diff --git a/apps/web/package.json b/apps/web/package.json index f17956d..0eff085 100755 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,92 +1,91 @@ { - "name": "web", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "lint": "eslint .", - "preview": "vite preview" - }, - "dependencies": { - "@ag-grid-community/client-side-row-model": "~32.3.2", - "@ag-grid-community/core": "~32.3.2", - "@ag-grid-community/react": "~32.3.2", - "@ag-grid-enterprise/clipboard": "~32.3.2", - "@ag-grid-enterprise/column-tool-panel": "~32.3.2", - "@ag-grid-enterprise/core": "~32.3.2", - "@ag-grid-enterprise/filter-tool-panel": "~32.3.2", - "@ag-grid-enterprise/master-detail": "~32.3.2", - "@ag-grid-enterprise/menu": "~32.3.2", - "@ag-grid-enterprise/range-selection": "~32.3.2", - "@ag-grid-enterprise/server-side-row-model": "~32.3.2", - "@ag-grid-enterprise/set-filter": "~32.3.2", - "@ag-grid-enterprise/status-bar": "~32.3.2", - "@ant-design/icons": "^5.4.0", - "@dnd-kit/core": "^6.3.1", - "@dnd-kit/sortable": "^10.0.0", - "@dnd-kit/utilities": "^3.2.2", - "@floating-ui/react": "^0.26.25", - "@heroicons/react": "^2.2.0", - "@hookform/resolvers": "^3.9.1", - "@nice/client": "workspace:^", - "@nice/common": "workspace:^", - "@nice/iconer": "workspace:^", - "mind-elixir": "workspace:^", - "@nice/ui": "workspace:^", - "@tanstack/query-async-storage-persister": "^5.51.9", - "@tanstack/react-query": "^5.51.21", - "@tanstack/react-query-persist-client": "^5.51.9", - "@trpc/client": "11.0.0-rc.456", - "@trpc/react-query": "11.0.0-rc.456", - "@trpc/server": "11.0.0-rc.456", - "@xyflow/react": "^12.3.6", - "ag-grid-community": "~32.3.2", - "ag-grid-enterprise": "~32.3.2", - "ag-grid-react": "~32.3.2", - "antd": "^5.19.3", - "axios": "^1.7.2", - "browser-image-compression": "^2.0.2", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "d3-dag": "^1.1.0", - "d3-hierarchy": "^3.1.2", - "dayjs": "^1.11.12", - "elkjs": "^0.9.3", - "framer-motion": "^11.15.0", - "hls.js": "^1.5.18", - "idb-keyval": "^6.2.1", - "mitt": "^3.0.1", - "quill": "2.0.3", - "react": "18.2.0", - "react-beautiful-dnd": "^13.1.1", - "react-dom": "18.2.0", - "react-dropzone": "^14.3.5", - "react-hook-form": "^7.54.2", - "react-hot-toast": "^2.4.1", - "react-resizable": "^3.0.5", - "react-router-dom": "^6.24.1", - "superjson": "^2.2.1", - "tailwind-merge": "^2.6.0", - "uuid": "^10.0.0", - "yjs": "^13.6.20", - "zod": "^3.23.8" - }, - "devDependencies": { - "@eslint/js": "^9.9.0", - "@types/react": "18.2.38", - "@types/react-dom": "18.2.15", - "@vitejs/plugin-react-swc": "^3.5.0", - "autoprefixer": "^10.4.20", - "eslint": "^9.9.0", - "eslint-plugin-react-hooks": "^5.1.0-rc.0", - "eslint-plugin-react-refresh": "^0.4.9", - "globals": "^15.9.0", - "postcss": "^8.4.41", - "tailwindcss": "^3.4.10", - "typescript": "^5.5.4", - "typescript-eslint": "^8.0.1", - "vite": "^5.4.1" - } -} + "name": "web", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@ag-grid-community/client-side-row-model": "~32.3.2", + "@ag-grid-community/core": "~32.3.2", + "@ag-grid-community/react": "~32.3.2", + "@ag-grid-enterprise/clipboard": "~32.3.2", + "@ag-grid-enterprise/column-tool-panel": "~32.3.2", + "@ag-grid-enterprise/core": "~32.3.2", + "@ag-grid-enterprise/filter-tool-panel": "~32.3.2", + "@ag-grid-enterprise/master-detail": "~32.3.2", + "@ag-grid-enterprise/menu": "~32.3.2", + "@ag-grid-enterprise/range-selection": "~32.3.2", + "@ag-grid-enterprise/server-side-row-model": "~32.3.2", + "@ag-grid-enterprise/set-filter": "~32.3.2", + "@ag-grid-enterprise/status-bar": "~32.3.2", + "@ant-design/icons": "^5.4.0", + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/sortable": "^10.0.0", + "@dnd-kit/utilities": "^3.2.2", + "@floating-ui/react": "^0.26.25", + "@heroicons/react": "^2.2.0", + "@hookform/resolvers": "^3.9.1", + "@nice/client": "workspace:^", + "@nice/common": "workspace:^", + "@nice/iconer": "workspace:^", + "@nice/utils": "workspace:^", + "mind-elixir": "workspace:^", + "@nice/ui": "workspace:^", + "@tanstack/query-async-storage-persister": "^5.51.9", + "@tanstack/react-query": "^5.51.21", + "@tanstack/react-query-persist-client": "^5.51.9", + "@trpc/client": "11.0.0-rc.456", + "@trpc/react-query": "11.0.0-rc.456", + "@trpc/server": "11.0.0-rc.456", + "@xyflow/react": "^12.3.6", + "ag-grid-community": "~32.3.2", + "ag-grid-enterprise": "~32.3.2", + "ag-grid-react": "~32.3.2", + "antd": "^5.19.3", + "axios": "^1.7.2", + "browser-image-compression": "^2.0.2", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "d3-dag": "^1.1.0", + "d3-hierarchy": "^3.1.2", + "dayjs": "^1.11.12", + "elkjs": "^0.9.3", + "framer-motion": "^11.15.0", + "hls.js": "^1.5.18", + "idb-keyval": "^6.2.1", + "mitt": "^3.0.1", + "quill": "2.0.3", + "react": "18.2.0", + "react-dom": "18.2.0", + "react-hook-form": "^7.54.2", + "react-hot-toast": "^2.4.1", + "react-resizable": "^3.0.5", + "react-router-dom": "^6.24.1", + "superjson": "^2.2.1", + "tailwind-merge": "^2.6.0", + "uuid": "^10.0.0", + "yjs": "^13.6.20", + "zod": "^3.23.8" + }, + "devDependencies": { + "@eslint/js": "^9.9.0", + "@types/react": "18.2.38", + "@types/react-dom": "18.2.15", + "@vitejs/plugin-react-swc": "^3.5.0", + "autoprefixer": "^10.4.20", + "eslint": "^9.9.0", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.9", + "globals": "^15.9.0", + "postcss": "^8.4.41", + "tailwindcss": "^3.4.10", + "typescript": "^5.5.4", + "typescript-eslint": "^8.0.1", + "vite": "^5.4.1" + } +} \ No newline at end of file diff --git a/apps/web/src/hooks/useTusUpload.ts b/apps/web/src/hooks/useTusUpload.ts index 695d5a4..a890d6e 100644 --- a/apps/web/src/hooks/useTusUpload.ts +++ b/apps/web/src/hooks/useTusUpload.ts @@ -45,13 +45,6 @@ export function useTusUpload() { onError: (error: Error) => void, fileKey: string // 添加文件唯一标识 ) => { - // if (!file || !file.name || !file.type) { - // const error = new Error("不可上传该类型文件"); - // setUploadError(error.message); - // onError(error); - // return; - // } - setIsUploading(true); setUploadProgress((prev) => ({ ...prev, [fileKey]: 0 })); setUploadError(null); diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index 033625d..ea8d9a7 100755 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -3,10 +3,9 @@ export * from "./enum" export * from "./types" export * from "./utils" export * from "./constants" -export * from "./select" export * from "./collaboration" export * from "./db" -// export * from "./generated" export * from "@prisma/client" export * from "./upload" -export * from "./tool" \ No newline at end of file +export * from "./tool" +export * from "./models" \ No newline at end of file diff --git a/packages/common/src/models/course.ts b/packages/common/src/models/course.ts new file mode 100644 index 0000000..94f7c17 --- /dev/null +++ b/packages/common/src/models/course.ts @@ -0,0 +1,7 @@ +import { Course, Enrollment } from "@prisma/client"; +import { SectionDto } from "./section"; + +export type CourseDto = Course & { + enrollments: Enrollment[]; + sections: SectionDto[]; +}; \ No newline at end of file diff --git a/packages/common/src/models/department.ts b/packages/common/src/models/department.ts new file mode 100644 index 0000000..c013723 --- /dev/null +++ b/packages/common/src/models/department.ts @@ -0,0 +1,15 @@ +import { Department } from "@prisma/client"; +import { TreeDataNode} from "../types"; +import { StaffDto } from "./staff"; +import { TermDto } from "./term"; + +export interface DeptSimpleTreeNode extends TreeDataNode { + hasStaff?: boolean; +} +export type DepartmentDto = Department & { + parent: DepartmentDto; + children: DepartmentDto[]; + hasChildren: boolean; + staffs: StaffDto[]; + terms: TermDto[]; +}; \ No newline at end of file diff --git a/packages/common/src/models/index.ts b/packages/common/src/models/index.ts new file mode 100644 index 0000000..1febb05 --- /dev/null +++ b/packages/common/src/models/index.ts @@ -0,0 +1,9 @@ +export * from "./course" +export * from "./department" +export * from "./message" +export * from "./staff" +export * from "./term" +export * from "./post" +export * from "./rbac" +export * from "./section" +export * from "./select" \ No newline at end of file diff --git a/packages/common/src/models/message.ts b/packages/common/src/models/message.ts new file mode 100644 index 0000000..6e9d0be --- /dev/null +++ b/packages/common/src/models/message.ts @@ -0,0 +1,7 @@ +import { Message, Staff } from "@prisma/client"; + +export type MessageDto = Message & { + readed: boolean; + receivers: Staff[]; + sender: Staff; +}; diff --git a/packages/common/src/models/post.ts b/packages/common/src/models/post.ts new file mode 100644 index 0000000..7d6ebd9 --- /dev/null +++ b/packages/common/src/models/post.ts @@ -0,0 +1,35 @@ +import { Post, Department, Staff } from "@prisma/client"; +import { StaffDto } from "./staff"; + +export type PostComment = { + id: string; + type: string; + title: string; + content: string; + authorId: string; + domainId: string; + referenceId: string; + resources: string[]; + createdAt: Date; + updatedAt: Date; + parentId: string; + author: { + id: string; + showname: string; + username: string; + avatar: string; + }; +}; +export type PostDto = Post & { + readed: boolean; + readedCount: number; + author: StaffDto; + limitedComments: PostComment[]; + commentsCount: number; + perms?: { + delete: boolean; + // edit: boolean; + }; + watchableDepts: Department[]; + watchableStaffs: Staff[]; +}; diff --git a/packages/common/src/models/rbac.ts b/packages/common/src/models/rbac.ts new file mode 100644 index 0000000..01e2bb3 --- /dev/null +++ b/packages/common/src/models/rbac.ts @@ -0,0 +1,22 @@ +import { RoleMap } from "@prisma/client"; +import { StaffDto } from "./staff"; + +export interface ResPerm { + instruction?: boolean; + createProgress?: boolean; + requestCancel?: boolean; + acceptCancel?: boolean; + + conclude?: boolean; + createRisk?: boolean; + editIndicator?: boolean; + editMethod?: boolean; + editOrg?: boolean; + + edit?: boolean; + delete?: boolean; + read?: boolean; +} +export type RoleMapDto = RoleMap & { + staff: StaffDto; +}; \ No newline at end of file diff --git a/packages/common/src/models/section.ts b/packages/common/src/models/section.ts new file mode 100644 index 0000000..0824441 --- /dev/null +++ b/packages/common/src/models/section.ts @@ -0,0 +1,5 @@ +import { Lecture, Section } from "@prisma/client"; + +export type SectionDto = Section & { + lectures: Lecture[]; +}; \ No newline at end of file diff --git a/packages/common/src/select.ts b/packages/common/src/models/select.ts similarity index 100% rename from packages/common/src/select.ts rename to packages/common/src/models/select.ts diff --git a/packages/common/src/models/staff.ts b/packages/common/src/models/staff.ts new file mode 100644 index 0000000..a6ace02 --- /dev/null +++ b/packages/common/src/models/staff.ts @@ -0,0 +1,38 @@ +import { Staff, Department } from "@prisma/client"; +import { RolePerms } from "../enum"; + +export type StaffRowModel = { + avatar: string; + dept_name: string; + officer_id: string; + phone_number: string; + showname: string; + username: string; +}; +export type UserProfile = Staff & { + permissions: RolePerms[]; + deptIds: string[]; + parentDeptIds: string[]; + domain: Department; + department: Department; +}; + +export type StaffDto = Staff & { + domain?: Department; + department?: Department; +}; +export interface AuthDto { + token: string; + staff: StaffDto; + refreshToken: string; + perms: string[]; +} +export interface JwtPayload { + sub: string; + username: string; +} +export interface TokenPayload { + id: string; + phoneNumber: string; + name: string; +} \ No newline at end of file diff --git a/packages/common/src/models/term.ts b/packages/common/src/models/term.ts new file mode 100644 index 0000000..cef8b61 --- /dev/null +++ b/packages/common/src/models/term.ts @@ -0,0 +1,8 @@ +import { Term } from "@prisma/client"; +import { ResPerm } from "./rbac"; + +export type TermDto = Term & { + permissions: ResPerm; + children: TermDto[]; + hasChildren: boolean; +}; \ No newline at end of file diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 41c1783..02ff9c9 100755 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -1,15 +1,3 @@ -import type { - Staff, - Department, - Term, - Message, - Post, - RoleMap, - Section, - Lecture, - Course, - Enrollment, -} from "@prisma/client"; import { SocketMsgType, RolePerms } from "./enum"; import { RowRequestSchema } from "./schema"; import { z } from "zod"; @@ -18,44 +6,11 @@ export interface SocketMessage { type: SocketMsgType; payload?: T; } - -export interface DataNode { - title: any; - key: string; - hasChildren?: boolean; - children?: DataNode[]; - value: string; - data?: any; - isLeaf?: boolean; -} - -export interface JwtPayload { - sub: string; - username: string; -} export type AppLocalSettings = { urgent?: number; important?: number; exploreTime?: Date; }; -export type StaffDto = Staff & { - domain?: Department; - department?: Department; -}; -export interface AuthDto { - token: string; - staff: StaffDto; - refreshToken: string; - perms: string[]; -} -export type UserProfile = Staff & { - permissions: RolePerms[]; - deptIds: string[]; - parentDeptIds: string[]; - domain: Department; - department: Department; -}; - export interface DataNode { title: any; key: string; @@ -70,99 +25,6 @@ export interface TreeDataNode extends DataNode { isLeaf?: boolean; pId?: string; } -export interface DeptSimpleTreeNode extends TreeDataNode { - hasStaff?: boolean; -} -export type StaffRowModel = { - avatar: string; - dept_name: string; - officer_id: string; - phone_number: string; - showname: string; - username: string; -}; -export interface TokenPayload { - id: string; - phoneNumber: string; - name: string; -} -export interface ResPerm { - instruction?: boolean; - createProgress?: boolean; - requestCancel?: boolean; - acceptCancel?: boolean; - - conclude?: boolean; - createRisk?: boolean; - editIndicator?: boolean; - editMethod?: boolean; - editOrg?: boolean; - - edit?: boolean; - delete?: boolean; - read?: boolean; -} - -export type MessageDto = Message & { - readed: boolean; - receivers: Staff[]; - sender: Staff; -}; -export type PostComment = { - id: string; - type: string; - title: string; - content: string; - authorId: string; - domainId: string; - referenceId: string; - resources: string[]; - createdAt: Date; - updatedAt: Date; - parentId: string; - author: { - id: string; - showname: string; - username: string; - avatar: string; - }; -}; -export type PostDto = Post & { - readed: boolean; - readedCount: number; - author: StaffDto; - limitedComments: PostComment[]; - commentsCount: number; - perms?: { - delete: boolean; - // edit: boolean; - }; - watchableDepts: Department[]; - watchableStaffs: Staff[]; -}; - -export type TermDto = Term & { - permissions: ResPerm; - children: TermDto[]; - hasChildren: boolean; -}; -export type DepartmentDto = Department & { - parent: DepartmentDto; - children: DepartmentDto[]; - hasChildren: boolean; - staffs: StaffDto[]; - terms: TermDto[]; -}; -export type RoleMapDto = RoleMap & { - staff: StaffDto; -}; -export type SectionDto = Section & { - lectures: Lecture[]; -}; -export type CourseDto = Course & { - enrollments: Enrollment[]; - sections: SectionDto[]; -}; export interface BaseSetting { appConfig?: { splashScreen?: string; diff --git a/packages/common/src/utils.ts b/packages/common/src/utils.ts index ee1e16d..083b229 100755 --- a/packages/common/src/utils.ts +++ b/packages/common/src/utils.ts @@ -1,5 +1,5 @@ import { Staff } from "@prisma/client"; -import { TermDto, TreeDataNode } from "./types"; +import { TreeDataNode } from "./types"; export function findNodeByKey( nodes: TreeDataNode[], targetKey: string @@ -318,7 +318,7 @@ export const mapPropertiesToObjects = (array: T[], key: K) * @returns {Array>} 映射后的对象数组 */ export const mapArrayToObjectArray = ( - array: T[], + array: T[], key: string = 'id' ): Array> => { return array.map(item => ({ [key]: item })); diff --git a/packages/utils/src/array-utils.ts b/packages/utils/src/array-utils.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/utils/src/browser-utils.ts b/packages/utils/src/browser-utils.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/utils/src/crypto-utils.ts b/packages/utils/src/crypto-utils.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/utils/src/date-utils.ts b/packages/utils/src/date-utils.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/utils/src/dom-utils.ts b/packages/utils/src/dom-utils.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/utils/src/file-utils.ts b/packages/utils/src/file-utils.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 77aa06e..b2ba304 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -38,4 +38,4 @@ export const getCompressedImageUrl = (originalUrl: string): string => { const lastSlashIndex = cleanUrl.lastIndexOf("/"); return `${cleanUrl.slice(0, lastSlashIndex)}/compressed/${cleanUrl.slice(lastSlashIndex + 1).replace(/\.[^.]+$/, ".webp")}`; }; -export * from "./types"; +export * from "./type-utils"; diff --git a/packages/utils/src/math-utils.ts b/packages/utils/src/math-utils.ts new file mode 100644 index 0000000..7e7dfb8 --- /dev/null +++ b/packages/utils/src/math-utils.ts @@ -0,0 +1,99 @@ +/*** 数学计算工具函数 + */ + +/*** 将数值限制在指定范围内 + * @paramvalue 要限制的值 + * @parammin 最小值 + * @parammax 最大值 + */export const clamp = (value: number, min: number, max: number): number => { + return Math.min(Math.max(value, min), max); +}; + +/** + * 将数值四舍五入到指定小数位 + * @param value要四舍五入的值* @param decimals 保留的小数位数 + */export const round = (value: number, decimals: number = 0): number => { + const multiplier = Math.pow(10, decimals); + return Math.round(value * multiplier) / multiplier; +};/** + * 生成指定范围内的随机数* @param min 最小值* @param max 最大值* @param isInteger 是否为整数,默认false + */ +export const random = (min: number, max: number, isInteger: boolean = false): number => { + const value = Math.random() * (max - min) + min; + return isInteger ? Math.floor(value) : value; +}; + +/*** 计算数组的平均值* @param numbers 数字数组 + */export const average = (numbers: number[]): number => { + if (numbers.length === 0) return 0; + return numbers.reduce((sum, num) => sum + num, 0) / numbers.length; +}; + +/** + * 计算数组的总和 + * @param numbers 数字数组 + */export const sum = (numbers: number[]): number => { + return numbers.reduce((sum, num) => sum + num, 0); +}; + +/** + *角度转弧度 + * @paramdegrees 角度 + */ +export const degreesToRadians = (degrees: number): number => { + return degrees * (Math.PI / 180); +};/** + * 弧度转角度 + * @param radians弧度 + */ +export const radiansToDegrees = (radians: number): number => { + return radians * (180 / Math.PI); +};/** + * 格式化数字为千分位表示 + * @param value 要格式化的数值*/ +export const formatThousands = (value: number): string => { + return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); +}; + +/*** 计算百分比* @param value 当前值 + *@param total 总值 + *@param decimals 保留小数位数 + */ +export const percentage = (value: number, total: number, decimals: number = 2): number => { + if (total === 0) return 0; return round((value / total) * 100, decimals); +}; + +/*** 判断两个数值是否近似相等 + * @param a第一个数值 + * @paramb 第二个数值 + *@param epsilon 误差范围,默认0.000001 + */ +export const approximatelyEqual = (a: number, b: number, epsilon: number = 0.000001): boolean => { + return Math.abs(a - b) < epsilon; +}; + +/** + * 将数值转换为带单位的字符串(K, M, B等) + * @param value 要转换的数值 + */ +export const formatUnit = (value: number): string => { + const units = ["", "K", "M", "B", "T"]; + const order = Math.floor(Math.log10(Math.abs(value)) / 3); if (order < 0) return value.toString(); + const unit = units[order]; const scaled = value / Math.pow(10, order * 3); + return `${round(scaled, 1)}${unit}`; +}; + +/** + * 计算两点之间的距离* @param x1 第一个点的x坐标 + *@param y1 第一个点的y坐标 + * @param x2 第二个点的x坐标 + * @param y2 第二个点的y坐标*/ +export const distance = (x1: number, y1: number, x2: number, y2: number): number => { + return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); +};/** + * 线性插值* @param start 起始值 + * @param end 结束值 + * @param t 插值系数(0-1)*/ +export const lerp = (start: number, end: number, t: number): number => { + return start + (end - start) * clamp(t, 0, 1); +}; \ No newline at end of file diff --git a/packages/utils/src/object-utils.ts b/packages/utils/src/object-utils.ts new file mode 100644 index 0000000..77a44ab --- /dev/null +++ b/packages/utils/src/object-utils.ts @@ -0,0 +1,59 @@ +// 优雅实现对象操作工具函数集合 + +/** + * 深拷贝对象或数组 + * @param input 需要深拷贝的对象或数组 + * @returns 深拷贝后的新对象/数组 + */ +export function deepClone(input: T): T { + if (input === null || typeof input !== 'object') return input; + if (Array.isArray(input)) return input.map(deepClone) as unknown as T; + + const result = {} as T; + for (const key in input) { + if (Object.prototype.hasOwnProperty.call(input, key)) { + result[key] = deepClone(input[key]); + } + } + return result; +} + +/** + * 合并多个对象 + * @param objects 需要合并的对象列表 + * @returns 合并后的对象 + */ +export function mergeObjects(...objects: Partial[]): T { + return objects.reduce((acc: Partial, obj) => { + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (typeof acc[key] === 'object' && typeof obj[key] === 'object') { + acc[key] = mergeObjects(acc[key], obj[key]); + } else { + acc[key] = obj[key]; + } + } + } + return acc; + }, {} as Partial) as T; +} + +/** + * 获取嵌套对象的属性值 + * @param obj 待操作对象 + * @param path 属性路径(以点分隔) + * @param defaultValue 默认值 + * @returns 属性值或默认值 + */ +export function getNestedValue(obj: T, path: string, defaultValue: U): U | unknown { + return path.split('.').reduce((acc: any, key: string) => acc && acc[key], obj) ?? defaultValue; +} + +/** + * 判断对象是否为空 + * @param obj 待检查对象 + * @returns 是否为空对象 + */ +export function isEmptyObject(obj: Record): boolean { + return Object.keys(obj).length === 0; +} diff --git a/packages/utils/src/random-utils.ts b/packages/utils/src/random-utils.ts new file mode 100644 index 0000000..a763060 --- /dev/null +++ b/packages/utils/src/random-utils.ts @@ -0,0 +1,85 @@ +/** + * 随机工具函数库 + * 提供生成随机数、随机字符串、随机数组等功能。 + */ + +/** + * 生成一个指定范围内的随机整数 (包含 min 和 max) + * @param min 最小值 (包含) + * @param max 最大值 (包含) + */ +export const getRandomInt = (min: number, max: number): number => { + const minimum = Math.ceil(min); + const maximum = Math.floor(max); + return Math.floor(Math.random() * (maximum - minimum + 1)) + minimum; +}; + +/** + * 生成一个指定长度的随机字符串 + * @param length 随机字符串的长度 + * @param chars 可选,使用的字符集,默认是字母 (大小写) 和数字 + */ +export const getRandomString = (length: number, chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'): string => { + let result = ''; + const charsLength = chars.length; + for (let i = 0; i < length; i++) { + result += chars.charAt(Math.floor(Math.random() * charsLength)); + } + return result; +}; + +/** + * 生成一个随机布尔值 (true 或 false) + */ +export const getRandomBoolean = (): boolean => { + return Math.random() >= 0.5; +}; + +/** + * 从数组中随机选取一个值 + * @param array 要随机提取的数组 + */ +export const getRandomFromArray = (array: T[]): T => { + return array[Math.floor(Math.random() * array.length)]; +}; + +/** + * 打乱一个数组 + * @param array 要打乱的数组 + */ +export const shuffleArray = (array: T[]): T[] => { + const shuffled = [...array]; // 创建一个副本以免修改原数组 + for (let i = shuffled.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; + } + return shuffled; +}; + +/** + * 生成一个随机的十六进制颜色代码 (如 "#a1b2c3") + */ +export const getRandomHexColor = (): string => { + return `#${Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, '0')}`; +}; + +/** + * 生成一个随机RGBA颜色 + * @param alpha 可选,透明度 (范围 0-1) + */ +export const getRandomRGBAColor = (alpha: number = 1): string => { + const r = getRandomInt(0, 255); + const g = getRandomInt(0, 255); + const b = getRandomInt(0, 255); + return `rgba(${r}, ${g}, ${b}, ${alpha})`; +}; + +/** + * 随机延迟一段时间 (返回一个 Promise,在随机时间后 resolve) + * @param min 最小延迟时间 (毫秒) + * @param max 最大延迟时间 (毫秒) + */ +export const randomDelay = (min: number, max: number): Promise => { + const delay = getRandomInt(min, max); + return new Promise(resolve => setTimeout(resolve, delay)); +}; \ No newline at end of file diff --git a/packages/utils/src/string-utils.ts b/packages/utils/src/string-utils.ts new file mode 100644 index 0000000..71d2494 --- /dev/null +++ b/packages/utils/src/string-utils.ts @@ -0,0 +1,80 @@ +/** + * 字符串工具函数库 + * 提供对字符串常见处理的常用工具函数。 + */ + +/** + * 检查字符串是否为空或仅包含空格 + */ +export const isEmptyOrWhitespace = (str: string): boolean => { + return !str || str.trim().length === 0; +}; + +/** + * 将字符串的首字母大写 + */ +export const capitalize = (str: string): string => { + if (!str) return ''; + return str.charAt(0).toUpperCase() + str.slice(1); +}; + +/** + * 转换成驼峰命名法 (camelCase) + */ +export const toCamelCase = (str: string): string => { + return str + .toLowerCase() + .replace(/[-_ ]+(\w)/g, (_, group: string) => group.toUpperCase()); +}; + +/** + * 转换成蛇形命名法 (snake_case) + */ +export const toSnakeCase = (str: string): string => { + return str + .replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`) + .replace(/[\s\-]+/g, '_') + .replace(/^_/, '') + .toLowerCase(); +}; + +/** + * 转换成烤串命名法 (kebab-case) + */ +export const toKebabCase = (str: string): string => { + return str + .replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`) + .replace(/[\s_]+/g, '-') + .replace(/^-/, '') + .toLowerCase(); +}; + +/** + * 截断字符串到指定长度,超出部分使用 "..." 表示 + */ +export const truncate = (str: string, length: number): string => { + if (str.length <= length) return str; + return str.slice(0, length) + '...'; +}; + +/** + * 统计字符串中每个字符的出现次数 + */ +export const charFrequency = (str: string): Record => { + return str.split('').reduce((acc: Record, char: string) => { + acc[char] = (acc[char] || 0) + 1; + return acc; + }, {}); +}; + +/** + * 检查字符串是否是有效的 JSON + */ +export const isValidJSON = (str: string): boolean => { + try { + JSON.parse(str); + return true; + } catch { + return false; + } +}; \ No newline at end of file diff --git a/packages/utils/src/type-utils.ts b/packages/utils/src/type-utils.ts new file mode 100644 index 0000000..ec3d76b --- /dev/null +++ b/packages/utils/src/type-utils.ts @@ -0,0 +1,94 @@ +/** + * 类型工具函数库 + * 提供对 TypeScript 类型的常见操作工具。 + */ + +// --------------------------- 类型工具 --------------------------- + +/** + * 从某个对象类型中挑选出指定的键。 + */ +export type PickKeys = { + [P in K]: T[P]; +}; + +/** + * 从某个对象类型中排除指定的键。 + */ +export type OmitKeys = Pick>; + +/** + * 将某些字段设置为可选。 + */ +export type PartialByKeys = Omit & Partial>; + +/** + * 将某些字段设置为必填。 + */ +export type RequiredByKeys = Omit & Required>; + +/** + * 可为空的类型。 + */ +export type Nullable = T | null; + +/** + * 可为 undefined 的类型。 + */ +export type Optional = T | undefined; + +/** + * 确保某个变量类型的检查 (主要用于类型推断辅助)。 + */ +export const assertType = (value: T): T => value; + +/** + * 获取数组元素的类型。 + */ +export type ArrayElement = A extends readonly (infer T)[] ? T : never; + +/** + * 获取某个对象中字段的值组成的联合类型。 + */ +export type ValueOf = T[keyof T]; + +/** + * 深部分可选:将嵌套对象所有字段设置为可选。 + */ +export type DeepPartial = { + [K in keyof T]?: T[K] extends object ? DeepPartial : T[K]; +}; + +/** + * 深部分必填:将嵌套对象所有字段设置为必填。 + */ +export type DeepRequired = { + [K in keyof T]-?: T[K] extends object ? DeepRequired : T[K]; +}; + +// --------------------------- 工具函数 --------------------------- + +/** + * 检查一个值是否为空 (null 或 undefined) + * @param val 要检查的值 + */ +export const isNullOrUndefined = (val: unknown): val is null | undefined => { + return val === null || val === undefined; +}; + +/** + * 检查一个值是否为对象。 + * @param val 要检查的值 + */ +export const isObject = (val: unknown): val is Record => { + return typeof val === 'object' && val !== null && !Array.isArray(val); +}; + +/** + * 检查一个对象是否为空 (没有属性)。 + * @param obj 要检查的对象 + */ +export const isEmptyObject = (obj: Record): boolean => { + return Object.keys(obj).length === 0; +}; +export type NonVoid = T extends void ? never : T; \ No newline at end of file diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts deleted file mode 100644 index d3ed883..0000000 --- a/packages/utils/src/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type NonVoid = T extends void ? never : T; \ No newline at end of file diff --git a/packages/utils/src/validation-utils.ts b/packages/utils/src/validation-utils.ts new file mode 100644 index 0000000..e69de29 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 90950c6..d020b0d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -377,15 +377,9 @@ importers: react: specifier: 18.2.0 version: 18.2.0 - react-beautiful-dnd: - specifier: ^13.1.1 - version: 13.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-dom: specifier: 18.2.0 version: 18.2.0(react@18.2.0) - react-dropzone: - specifier: ^14.3.5 - version: 14.3.5(react@18.2.0) react-hook-form: specifier: ^7.54.2 version: 7.54.2(react@18.2.0) @@ -3077,9 +3071,6 @@ packages: '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - '@types/hoist-non-react-statics@3.3.6': - resolution: {integrity: sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==} - '@types/http-errors@2.0.4': resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} @@ -3155,9 +3146,6 @@ packages: '@types/react-dom@18.2.15': resolution: {integrity: sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==} - '@types/react-redux@7.1.34': - resolution: {integrity: sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==} - '@types/react@18.2.38': resolution: {integrity: sha512-cBBXHzuPtQK6wNthuVMV6IjHAFkdl/FOPFIlkd81/Cd1+IqkHu/A+w4g43kaQQoYHik/ruaQBDL72HyCy1vuMw==} @@ -3710,10 +3698,6 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - attr-accept@2.2.5: - resolution: {integrity: sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==} - engines: {node: '>=4'} - autoprefixer@10.4.20: resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} @@ -4192,9 +4176,6 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - css-box-model@1.2.1: - resolution: {integrity: sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==} - cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -4764,10 +4745,6 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - file-selector@2.1.2: - resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} - engines: {node: '>= 12'} - filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} @@ -5037,9 +5014,6 @@ packages: hls.js@1.5.18: resolution: {integrity: sha512-znxR+2jecWluu/0KOBqUcvVyAB5tLff10vjMGrpAlz1eFY+ZhF1bY3r82V+Bk7WJdk03iTjtja9KFFz5BrqjSA==} - hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -5848,9 +5822,6 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} - memoize-one@5.2.1: - resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} - meow@8.1.2: resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} engines: {node: '>=10'} @@ -6423,9 +6394,6 @@ packages: resolution: {integrity: sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==} engines: {npm: '>=8.2.3'} - raf-schd@4.0.3: - resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==} - randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -6665,13 +6633,6 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - react-beautiful-dnd@13.1.1: - resolution: {integrity: sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==} - deprecated: 'react-beautiful-dnd is now deprecated. Context and options: https://github.com/atlassian/react-beautiful-dnd/issues/2672' - peerDependencies: - react: ^16.8.5 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.5 || ^17.0.0 || ^18.0.0 - react-dom@18.2.0: resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -6688,12 +6649,6 @@ packages: react: '>= 16.3.0' react-dom: '>= 16.3.0' - react-dropzone@14.3.5: - resolution: {integrity: sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ==} - engines: {node: '>= 10.13'} - peerDependencies: - react: '>= 16.8 || 18.0.0' - react-hook-form@7.54.2: resolution: {integrity: sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg==} engines: {node: '>=18.0.0'} @@ -6716,24 +6671,9 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-is@17.0.2: - resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - react-redux@7.2.9: - resolution: {integrity: sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==} - peerDependencies: - react: ^16.8.3 || ^17 || ^18 - react-dom: '*' - react-native: '*' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true - react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} @@ -6801,9 +6741,6 @@ packages: resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} engines: {node: '>=4'} - redux@4.2.1: - resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} - reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} @@ -7339,9 +7276,6 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tiny-invariant@1.3.3: - resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} - tinycolor2@1.6.0: resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} @@ -7580,11 +7514,6 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - use-memo-one@1.1.3: - resolution: {integrity: sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - use-sync-external-store@1.4.0: resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} peerDependencies: @@ -10687,11 +10616,6 @@ snapshots: dependencies: '@types/node': 20.17.12 - '@types/hoist-non-react-statics@3.3.6': - dependencies: - '@types/react': 18.2.38 - hoist-non-react-statics: 3.3.2 - '@types/http-errors@2.0.4': {} '@types/istanbul-lib-coverage@2.0.6': {} @@ -10761,13 +10685,6 @@ snapshots: dependencies: '@types/react': 18.3.18 - '@types/react-redux@7.1.34': - dependencies: - '@types/hoist-non-react-statics': 3.3.6 - '@types/react': 18.2.38 - hoist-non-react-statics: 3.3.2 - redux: 4.2.1 - '@types/react@18.2.38': dependencies: '@types/prop-types': 15.7.14 @@ -11553,8 +11470,6 @@ snapshots: asynckit@0.4.0: {} - attr-accept@2.2.5: {} - autoprefixer@10.4.20(postcss@8.4.49): dependencies: browserslist: 4.24.3 @@ -12088,10 +12003,6 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-box-model@1.2.1: - dependencies: - tiny-invariant: 1.3.3 - cssesc@3.0.0: {} csstype@3.1.3: {} @@ -12762,10 +12673,6 @@ snapshots: dependencies: flat-cache: 4.0.1 - file-selector@2.1.2: - dependencies: - tslib: 2.8.1 - filelist@1.0.4: dependencies: minimatch: 5.1.6 @@ -13045,10 +12952,6 @@ snapshots: hls.js@1.5.18: {} - hoist-non-react-statics@3.3.2: - dependencies: - react-is: 16.13.1 - hosted-git-info@2.8.9: {} hosted-git-info@4.1.0: @@ -14023,8 +13926,6 @@ snapshots: dependencies: fs-monkey: 1.0.6 - memoize-one@5.2.1: {} - meow@8.1.2: dependencies: '@types/minimist': 1.2.5 @@ -14548,8 +14449,6 @@ snapshots: parchment: 3.0.0 quill-delta: 5.1.0 - raf-schd@4.0.3: {} - randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 @@ -14883,20 +14782,6 @@ snapshots: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-beautiful-dnd@13.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): - dependencies: - '@babel/runtime': 7.26.0 - css-box-model: 1.2.1 - memoize-one: 5.2.1 - raf-schd: 4.0.3 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-redux: 7.2.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - redux: 4.2.1 - use-memo-one: 1.1.3(react@18.2.0) - transitivePeerDependencies: - - react-native - react-dom@18.2.0(react@18.2.0): dependencies: loose-envify: 1.4.0 @@ -14916,13 +14801,6 @@ snapshots: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-dropzone@14.3.5(react@18.2.0): - dependencies: - attr-accept: 2.2.5 - file-selector: 2.1.2 - prop-types: 15.8.1 - react: 18.2.0 - react-hook-form@7.54.2(react@18.2.0): dependencies: react: 18.2.0 @@ -14941,22 +14819,8 @@ snapshots: react-is@16.13.1: {} - react-is@17.0.2: {} - react-is@18.3.1: {} - react-redux@7.2.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0): - dependencies: - '@babel/runtime': 7.26.0 - '@types/react-redux': 7.1.34 - hoist-non-react-statics: 3.3.2 - loose-envify: 1.4.0 - prop-types: 15.8.1 - react: 18.2.0 - react-is: 17.0.2 - optionalDependencies: - react-dom: 18.2.0(react@18.2.0) - react-refresh@0.14.2: {} react-resizable@3.0.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0): @@ -15037,10 +14901,6 @@ snapshots: dependencies: redis-errors: 1.2.0 - redux@4.2.1: - dependencies: - '@babel/runtime': 7.26.0 - reflect-metadata@0.2.2: {} regenerator-runtime@0.14.1: {} @@ -15661,8 +15521,6 @@ snapshots: through@2.3.8: {} - tiny-invariant@1.3.3: {} - tinycolor2@1.6.0: {} tinyexec@0.3.2: {} @@ -15899,10 +15757,6 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - use-memo-one@1.1.3(react@18.2.0): - dependencies: - react: 18.2.0 - use-sync-external-store@1.4.0(react@18.2.0): dependencies: react: 18.2.0