From f711fec00b980774bbc2d204dbc06c953a496b42 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 12 Aug 2026 11:26:13 +0800 Subject: [PATCH 01/60] =?UTF-8?q?=E6=8E=A5=E5=85=A5Docker=E8=93=9D?= =?UTF-8?q?=E7=BB=BF=E9=83=A8=E7=BD=B2=EF=BC=9A=E8=87=AA=E5=8C=85=E5=90=AB?= =?UTF-8?q?=E5=A4=9A=E9=98=B6=E6=AE=B5=E6=9E=84=E5=BB=BA=E3=80=81=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=A4=96=E9=83=A8=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增根目录Dockerfile:多阶段构建(Vue前端 + Go后端),包含main.go依赖的 internal/packed资源打包步骤(原来依赖gf build外部产出,未提交进仓库) - 新增server/manifest/config/config.template:数据库/Redis连接串、 token密钥等敏感配置改为占位符,运行时通过entrypoint.sh用envsubst生成 真正的config.yaml,不再需要在仓库里维护包含真实密码的config.yaml - entrypoint.sh改为先渲染配置再启动 - 修复web/pnpm-lock.yaml与package.json不同步的问题(有依赖被加进 package.json但没重新生成锁文件) - 新增web/pnpm-workspace.yaml:较新版本pnpm默认禁止依赖包运行构建脚本 (供应链安全特性),需要显式在这里批准esbuild/@swc/core等的构建脚本, 否则CI环境下frozen-lockfile安装会直接失败 --- Dockerfile | 50 ++ server/manifest/config/config.template | 303 ++++++++ server/manifest/docker/entrypoint.sh | 15 +- web/pnpm-lock.yaml | 951 ++++++++++++++++--------- web/pnpm-workspace.yaml | 5 + 5 files changed, 998 insertions(+), 326 deletions(-) create mode 100644 Dockerfile create mode 100644 server/manifest/config/config.template create mode 100644 web/pnpm-workspace.yaml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1e9e22b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,50 @@ +# ---- Stage 1: build the Vue frontend ---- +FROM node:22-alpine AS web-build +WORKDIR /web +RUN npm install -g pnpm +COPY web/package.json web/pnpm-lock.yaml web/pnpm-workspace.yaml ./ +RUN pnpm install --frozen-lockfile +COPY web/ . +RUN pnpm run build + +# ---- Stage 2: build the Go backend, embedding the frontend build ---- +FROM golang:1.24-alpine AS server-build +RUN apk add --no-cache git +WORKDIR /src +COPY server/go.mod server/go.sum ./ +RUN go mod download +COPY server/ . + +# Same layout the project's own Makefile produces: built frontend goes into +# resource/public/admin/ before packing/building the backend. +RUN rm -rf resource/public/admin && mkdir -p resource/public/admin +COPY --from=web-build /web/dist/ ./resource/public/admin/ + +# main.go does `import _ "hotgo/internal/packed"`, a file normally generated by +# `gf build` (see server/hack/config.yaml: packSrc/packDst) and gitignored — +# generate it explicitly with the same gf CLI version pinned in go.mod. +RUN go install github.com/gogf/gf/cmd/gf/v2@v2.10.0 +RUN gf pack resource internal/packed/packed.go + +RUN CGO_ENABLED=0 go build -o /out/hotgo main.go + +# ---- Stage 3: runtime ---- +FROM alpine:3.22 + +RUN apk add --no-cache ca-certificates gettext bash + +WORKDIR /app + +COPY --from=server-build /src/manifest ./manifest +COPY --from=server-build /out/hotgo . +COPY server/manifest/docker/entrypoint.sh . + +RUN mkdir -p storage/logs storage/data storage/cache storage/diskqueue \ + && chmod +x entrypoint.sh hotgo + +HEALTHCHECK --interval=1m --timeout=3s --start-period=20s \ + CMD nc -z localhost 8000 || exit 1 + +EXPOSE 8000 + +ENTRYPOINT ["./entrypoint.sh"] diff --git a/server/manifest/config/config.template b/server/manifest/config/config.template new file mode 100644 index 0000000..f35a467 --- /dev/null +++ b/server/manifest/config/config.template @@ -0,0 +1,303 @@ +# hotgo系统配置 +system: + # 应用名称 + appName: "hotgo" + # debug开关,开启后接口出现错误时会向前端输出堆栈信息,可选:false|true,默认为true + debug: true + # gf运行模式,可选:not-set|develop|testing|staging|product。product模式下后台【开发工具】菜单自动隐藏 + mode: "develop" + # IP归属地解析方法,可选:cz88|whois,默认为whois + ipMethod: "whois" + # 是否为演示系统,可选:false|true + isDemo: false + # 是否为集群部署,可选:false|true 默认为false。开启集群必须配置redis,通过redis发布订阅进行集群之间的数据同步 + isCluster: false + # 全局请求日志 + log: + switch: true # 日志开关,可选:false|true,默认为true + queue: true # 是否启用队列,启用时需要配置队列信息,可选:false|true,默认为true + module: [ "admin", "api", "default" ] # 需要记录的模块 + skipCode: [ ] # 不记录的状态码,如: ["0", "-1"] + # 系统日志,用于在后台统计异常日志 + serveLog: + switch: true # 日志开关,可选:false|true,默认为true + queue: true # 是否启用队列,启用时需要配置队列信息,可选:false|true,默认为true + levelFormat: [ "WARN", "ERRO", "FATA", "PANI" ] # 需要记录的等级 + # 国际化 + i18n: + switch: true # 国际化开关,可选:false|true,默认为true + defaultLanguage: "zh-CN" # 默认使用语言,可选:zh-CN|zh-TW|en,默认为zh-CN + # 插件资源目录,用于静态文件和模版文件的路径,默认为resource + addonsResourcePath: "resource" + + +# 统一默认日志配置 +defaultLogger: &defaultLogger + level: "all" + flags: 42 + file: "{Y-m-d}.log" # 日志文件格式。默认为"{Y-m-d}.log" + stdoutColorDisabled: false # 关闭终端的颜色打印。可选:false|true,默认false + writerColorEnable: false # 日志文件是否带上颜色。可选:false|true,默认false,表示不带颜色 + rotateExpire: "7d" # 日志保留天数 + rotateBackupLimit: 2 # 最大备份数量 + rotateBackupCompress: 2 # 日志文件压缩级别,0-9,9最高 + + +# gf配置,配置参考:https://goframe.org/pages/viewpage.action?pageId=44449486 +server: + address: ":8000" # 本地监听地址。默认":8000",多个地址以","号分隔。例如:"192.168.2.3:8000,10.0.3.10:8001" + openapiPath: "/api.json" # OpenAPI接口文档地址 + swaggerPath: "/swagger" # 内置SwaggerUI展示地址 + serverRoot: "resource/public" # 静态文件服务的目录根路径,配置时自动开启静态文件服务。 + DumpRouterMap: false # 是否在Server启动时打印所有的路由列表。 + logPath: "logs/server" # 服务日志保存路径 + ErrorStack: true # 当Server捕获到异常时是否记录堆栈信息到日志中。默认为true + ErrorLogEnabled: true # 是否记录异常日志信息到日志中。默认为true + errorLogPattern: "error/{Y-m-d}.log" # 异常错误日志文件格式。默认为"error-{Ymd}.log" + accessLogEnabled: true # 是否记录访问日志。默认为false + accessLogPattern: "access/{Y-m-d}.log" # 访问日志文件格式。默认为"access-{Ymd}.log" + maxHeaderBytes: "100KB" # 请求头大小限制,请求头包括客户端提交的Cookie数据,默认设置为100KB + clientMaxBodySize: "200MB" # 客户端提交的Body大小限制,同时也影响文件上传大小,默认设置为200MB + serverAgent: "HG HTTP Server" # 服务端Agent信息。默认为"HG HTTP Server" + # PProf配置 + pprofEnabled: true # 是否开启PProf性能调试特性。默认为false + pprofPattern: "/pprof" # 开启PProf时有效,表示PProf特性的页面访问路径,对当前Server绑定的所有域名有效。 + # 服务日志配置 + logger: + path: "logs/server" # 日志文件路径。默认为空,表示关闭,仅输出到终端 + <<: *defaultLogger + + +# tcp服务 +tcp: + # 服务器 + server: + address: ":8099" + # 客户端 + client: + # 定时任务 + cron: + group: "cron" # 分组名称 + name: "cron1" # 客户端名称 + address: "127.0.0.1:8099" # 服务器地址 + appId: "1002" # 应用名称 + secretKey: "hotgo" # 密钥 + # 系统授权 + auth: + group: "auth" # 分组名称 + name: "auth1" # 客户端名称 + address: "127.0.0.1:8099" # 服务器地址 + appId: "mengshuai" # 应用名称 + secretKey: "123456" # 密钥 + + +# 日志配置 +logger: + # 全局日志:g.Log() + path: "logs/logger" # 日志文件路径。默认为空,表示关闭,仅输出到终端 + <<: *defaultLogger + # 定时任务:g.Log("cron") + cron: + path: "logs/cron" # 日志文件路径。默认为空,表示关闭,仅输出到终端 + <<: *defaultLogger + # 消息队列:g.Log("cron") + queue: + path: "logs/queue" # 日志文件路径。默认为空,表示关闭,仅输出到终端 + <<: *defaultLogger + # tcp服务器:g.Log("tcpServer") + tcpServer: + path: "logs/tcpServer" # 日志文件路径。默认为空,表示关闭,仅输出到终端 + <<: *defaultLogger + # tcp客户端:g.Log("tcpClient") + tcpClient: + path: "logs/tcpClient" # 日志文件路径。默认为空,表示关闭,仅输出到终端 + <<: *defaultLogger + + +# Viewer. 配置参考:https://goframe.org/pages/viewpage.action?pageId=1114335 +viewer: + paths: "resource/template" + defaultFile: "index.html" + delimiters: [ "@{", "}" ] + homeLayout: "home/index.html" + + +# 内容设置 +setting: + title: "HotGo" + keywords: "中后台解决方案,gf框架,vue3" + description: "hotgo 是一个基于 goframe2,vue3,vite2,TypeScript,uniapp 的中后台解决方案,它可以帮助你快速搭建企业级中后台项目,相信不管是从新技术使用还是其他方面,都能帮助到你,持续更新中。" + + +# 路由配置 +router: + # 后台 + admin: + # 前缀 + prefix: "/admin" + # 不需要验证登录的路由地址 + exceptLogin: [ + "/sms/send", # 短信验证码 + "/wechat/authorizeCall", # 微信用户授权回调 + ] + # 不需要验证权限的路由地址 + exceptAuth: [ + "/member/info", # 登录用户信息 + "/role/dynamic", # 获取动态路由 + "/notice/pullMessages", # 拉取我的消息 + "/notice/readAll", # 设置全部已读公告 + "/notice/upRead", # 已读指定公告 + "/dictData/option", # 单个数据字典 + "/dictData/options", # 多个数据字典 + "/provinces/select", # 动态省市区选项 + "/provinces/cityLabel", # 动态解析省市区名称 + "/member/option", # 用户选项 + ] + # 接口 + api: + # 前缀 + prefix: "/api" + # 不需要验证登录的路由地址 + exceptLogin: [ ] + # websocket + websocket: + # 前缀 + prefix: "/socket" + # 不需要验证登录的路由地址 + exceptLogin: [ ] + # 前台页面 + home: + # 前缀 + prefix: "/home" + # 不需要验证登录的路由地址 + exceptLogin: [ ] + + +# 缓存驱动 +cache: + adapter: "redis" # 缓存驱动方式,支持:memory|redis|file,不填默认memory + fileDir: "./storage/cache" # 文件缓存路径,adapter=file时必填 + + +# 登录令牌 +token: + secretKey: "$TOKEN_SECRET_KEY" # 令牌加密秘钥,考虑安全问题生产环境中请修改默认值 + expires: 604800 # 令牌有效期,单位:秒。默认7天 + autoRefresh: true # 是否开启自动刷新过期时间, false|true 默认为true + refreshInterval: 86400 # 刷新间隔,单位:秒。必须小于expires,否则无法触发。默认1天内只允许刷新一次 + maxRefreshTimes: 30 # 最大允许刷新次数,-1不限制。默认30次 + multiLogin: true # 是否允许多端登录, false|true 默认为true + + +# 消息队列 +queue: + switch: true # 队列开关,可选:true|false,默认为true + driver: "redis" # 队列驱动,可选:disk|redis|rocketmq|kafka,默认为disk + groupName: "hotgo" # mq群组名称 + # 磁盘队列 + disk: + path: "./storage/diskqueue" # 数据存放路径 + batchSize: 100 # 每100条消息同步一次,batchSize和batchTime满足其一就会同步一次 + batchTime: 1 # 每1秒消息同步一次 + segmentSize: 10485760 # 每个topic分片数据文件最大字节,默认10M + segmentLimit: 3000 # 每个topic最大分片数据文件数量,超出部分将会丢弃 + # redis,默认使用全局redis运行队列 + redis: + timeout: 0 # 队列超时时间以秒为单位,0表示永不超时。如果队列在设定的超时时间内没有被消费,则会被销毁 + rocketmq: + nameSrvAdders: ["127.0.0.1:9876"] # nameSrvAdder+端口,支持多个 + accessKey: "" # 选填。如果开启了acl控制就必填 + secretKey: "" # 选填。如果开启了acl控制就必填 + brokerAddr: "127.0.0.1:10911" # brokerAddr+端口,选填。用于消费者订阅主题前会检查主题是否存在,不存在会自动创建。你也可以在rocketmq控制台手动创建主题 + retry: 0 # 重试次数 + logLevel: "info" # rocketmq日志输出级别,可选:all|close|debug|info|warn|error|fatal + kafka: + address: "127.0.0.1:9092" # kafka地址+端口 + version: "2.0.0.0" # kafka专属配置,默认2.0.0.0 + randClient: true # 开启随机生成clientID,可以实现启动多实例同时一起消费相同topic,加速消费能力的特性,默认为true + multiConsumer: true # 是否支持创建多个消费者 + + +# Redis. 配置参考:https://goframe.org/pages/viewpage.action?pageId=1114217 +redis: + default: + address: "$REDIS_ADDR" + db: "$REDIS_DB" + pass: "$REDIS_PASSWORD" + idleTimeout: "20" + + +# Database. 配置参考:https://goframe.org/pages/viewpage.action?pageId=1114245 +database: + logger: + path: "logs/database" # 日志文件路径。默认为空,表示关闭,仅输出到终端 + <<: *defaultLogger + stdout: true + default: + link: "$MYSQL_DSN" + debug: true + Prefix: "hg_" + + +# 链路追踪 +jaeger: + switch: false # 链路追踪开关,可选:true|false,默认为false + endpoint: "127.0.0.1:6831" # jaeger-agent上报地址 + + +# 生成代码 +hggen: + allowedIPs: [ "127.0.0.1", "*" ] # 白名单,*代表所有,只有允许的IP后台才能使用生成代码功能 + selectDbs: [ "default" ] # 可选生成表的数据库配置名称,支持多库 + disableTables: [ "hg_sys_gen_codes","hg_admin_role_casbin" ] # 禁用的表,禁用以后将不会在选择表中看到 + delimiters: [ "@{", "}" ] # 模板引擎变量分隔符号 + # 生成应用模型,所有生成模板允许自定义,可以参考default模板进行改造 + application: + # CRUD和关系树列表模板 + crud: + templates: + # 默认的主包模板 + - group: "default" # 分组名称 + isAddon: false # 是否为插件模板 false|true + masterPackage: "sys" # 主包名称,需和controllerPath、logicPath、inputPath保持关联 + templatePath: "./resource/generate/default/curd" # 模板路径 + apiPath: "./api/admin" # goApi生成路径 + controllerPath: "./internal/controller/admin/sys" # 控制器生成路径 + logicPath: "./internal/logic/sys" # 主要业务生成路径 + inputPath: "./internal/model/input/sysin" # 表单过滤器生成路径 + routerPath: "./internal/router/genrouter" # 生成路由表路径 + sqlPath: "./storage/data/generate" # 生成sql语句路径 + webApiPath: "../web/src/api" # webApi生成路径 + webViewsPath: "../web/src/views" # web页面生成路径 + + # 默认的插件包模板,{$name}会自动替换成实际的插件名称 + - group: "addon" # 分组名称 + isAddon: true # 是否为插件模板 false|true + masterPackage: "sys" # 主包名称,需和controllerPath、logicPath、inputPath保持关联 + templatePath: "./resource/generate/default/curd" # 模板路径 + apiPath: "./addons/{$name}/api/admin" # goApi生成路径 + controllerPath: "./addons/{$name}/controller/admin/sys" # 控制器生成路径 + logicPath: "./addons/{$name}/logic/sys" # 主要业务生成路径 + inputPath: "./addons/{$name}/model/input/sysin" # 表单过滤器生成路径 + routerPath: "./addons/{$name}/router/genrouter" # 生成路由表路径 + sqlPath: "./storage/data/generate/addons" # 生成sql语句路径 + webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径 + webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径 + + # 消息队列模板 + queue: + templates: + - group: "default" + templatePath: "./resource/generate/default/queue" + + # 定时任务模板 + cron: + templates: + - group: "default" + templatePath: "./resource/generate/default/cron" + + # 生成插件模块,通过后台创建新插件时使用的模板,允许自定义,可以参考default模板进行改造 + addon: + srcPath: "./resource/generate/default/addon" # 生成模板路径 + webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径 + webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径 diff --git a/server/manifest/docker/entrypoint.sh b/server/manifest/docker/entrypoint.sh index e8f6e9b..74d61b4 100644 --- a/server/manifest/docker/entrypoint.sh +++ b/server/manifest/docker/entrypoint.sh @@ -1,5 +1,12 @@ -#!/bin/bash +#!/bin/sh +set -e -cd /app && ./hotgo & -echo "hotgo start all server.." -tail -f /dev/null \ No newline at end of file +cd /app + +# Render the real config from the template using only the specific env vars we +# expect — avoids accidentally substituting anything else that might contain a +# literal '$' in the YAML. +envsubst '$MYSQL_DSN $REDIS_ADDR $REDIS_DB $REDIS_PASSWORD $TOKEN_SECRET_KEY' \ + < manifest/config/config.template > manifest/config/config.yaml + +exec ./hotgo diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index ec069a7..c7820e0 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -40,7 +40,7 @@ importers: version: 11.0.3(vue@3.4.38(typescript@5.5.4)) axios: specifier: ^1.7.7 - version: 1.7.7 + version: 1.7.7(debug@4.3.6(supports-color@8.1.1)) blueimp-md5: specifier: ^2.19.0 version: 2.19.0 @@ -75,8 +75,8 @@ importers: specifier: ^3.0.1 version: 3.0.1 naive-ui: - specifier: ^2.41.0 - version: 2.42.0(vue@3.4.38(typescript@5.5.4)) + specifier: ^2.44.1 + version: 2.44.1(vue@3.4.38(typescript@5.5.4)) pinia: specifier: ^2.2.2 version: 2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4)) @@ -110,6 +110,9 @@ importers: vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) + vue-i18n: + specifier: ^11.1.11 + version: 11.4.8(vue@3.4.38(typescript@5.5.4)) vue-router: specifier: ^4.4.3 version: 4.4.3(vue@3.4.38(typescript@5.5.4)) @@ -120,8 +123,8 @@ importers: specifier: ^2.6.0 version: 2.6.0 vue3-json-viewer: - specifier: ^2.2.2 - version: 2.2.2(vue@3.4.38(typescript@5.5.4)) + specifier: ^2.4.1 + version: 2.4.1(vue@3.4.38(typescript@5.5.4)) vuedraggable: specifier: ^4.1.0 version: 4.1.0(vue@3.4.38(typescript@5.5.4)) @@ -137,7 +140,7 @@ importers: version: 19.4.1 '@eslint/eslintrc': specifier: ^3.1.0 - version: 3.1.0 + version: 3.1.0(supports-color@8.1.1) '@types/fs-extra': specifier: ^11.0.4 version: 11.0.4 @@ -152,22 +155,22 @@ importers: version: 22.5.2 '@typescript-eslint/eslint-plugin': specifier: ^8.4.0 - version: 8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + version: 8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) '@typescript-eslint/parser': specifier: ^8.4.0 - version: 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + version: 8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) '@vitejs/plugin-vue': specifier: ^5.1.3 version: 5.1.3(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4)) '@vitejs/plugin-vue-jsx': specifier: ^4.0.1 - version: 4.0.1(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4)) + version: 4.0.1(supports-color@8.1.1)(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4)) '@vue/compiler-sfc': specifier: ^3.4.38 version: 3.4.38 '@vue/eslint-config-typescript': specifier: ^13.0.0 - version: 13.0.0(eslint-plugin-vue@9.28.0(eslint@9.9.1(jiti@1.21.6)))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + version: 13.0.0(eslint-plugin-vue@9.28.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) autoprefixer: specifier: ^10.4.20 version: 10.4.20(postcss@8.4.44) @@ -191,22 +194,22 @@ importers: version: 16.4.5 eslint: specifier: ^9.9.1 - version: 9.9.1(jiti@1.21.6) + version: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@9.9.1(jiti@1.21.6)) + version: 9.1.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1)) eslint-define-config: specifier: 2.1.0 version: 2.1.0 eslint-plugin-jest: specifier: ^28.8.2 - version: 28.8.2(@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)))(typescript@5.5.4) + version: 28.8.2(@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(jest@29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)))(supports-color@8.1.1)(typescript@5.5.4) eslint-plugin-prettier: specifier: ^5.2.1 - version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.6)))(eslint@9.9.1(jiti@1.21.6))(prettier@3.3.3) + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1)))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(prettier@3.3.3) eslint-plugin-vue: specifier: ^9.28.0 - version: 9.28.0(eslint@9.9.1(jiti@1.21.6)) + version: 9.28.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1) esno: specifier: ^4.7.0 version: 4.7.0 @@ -221,7 +224,7 @@ importers: version: 9.1.5 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) + version: 29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) less: specifier: ^4.2.0 version: 4.2.0 @@ -230,7 +233,7 @@ importers: version: 12.2.0(less@4.2.0)(webpack@5.94.0(@swc/core@1.7.23)(esbuild@0.23.1)) lint-staged: specifier: ^15.2.10 - version: 15.2.10 + version: 15.2.10(supports-color@8.1.1) mockjs: specifier: ^1.1.0 version: 1.1.0 @@ -251,43 +254,46 @@ importers: version: 6.0.1 stylelint: specifier: ^16.9.0 - version: 16.9.0(typescript@5.5.4) + version: 16.9.0(supports-color@8.1.1)(typescript@5.5.4) stylelint-config-prettier: specifier: ^9.0.5 - version: 9.0.5(stylelint@16.9.0(typescript@5.5.4)) + version: 9.0.5(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)) stylelint-config-standard: specifier: ^36.0.1 - version: 36.0.1(stylelint@16.9.0(typescript@5.5.4)) + version: 36.0.1(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)) stylelint-order: specifier: ^6.0.4 - version: 6.0.4(stylelint@16.9.0(typescript@5.5.4)) + version: 6.0.4(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)) stylelint-scss: specifier: ^6.5.1 - version: 6.5.1(stylelint@16.9.0(typescript@5.5.4)) + version: 6.5.1(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)) tailwindcss: specifier: ^3.4.10 version: 3.4.10(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) typescript: specifier: ^5.5.4 version: 5.5.4 + unplugin-auto-import: + specifier: ^20.2.0 + version: 20.3.0(@vueuse/core@11.0.3(vue@3.4.38(typescript@5.5.4))) unplugin-vue-components: specifier: ^0.27.4 - version: 0.27.4(@babel/parser@7.25.6)(rollup@4.21.2)(vue@3.4.38(typescript@5.5.4)) + version: 0.27.4(@babel/parser@7.25.6)(rollup@4.21.2)(supports-color@8.1.1)(vue@3.4.38(typescript@5.5.4)) vite: specifier: ^5.4.2 version: 5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6) vite-plugin-compression: specifier: ^0.5.1 - version: 0.5.1(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)) + version: 0.5.1(supports-color@8.1.1)(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)) vite-plugin-html: specifier: ^3.2.2 version: 3.2.2(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)) vite-plugin-mock: specifier: ^3.0.2 - version: 3.0.2(esbuild@0.23.1)(mockjs@1.1.0)(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)) + version: 3.0.2(esbuild@0.23.1)(mockjs@1.1.0)(supports-color@8.1.1)(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)) vite-plugin-require-transform: specifier: ^1.0.21 - version: 1.0.21 + version: 1.0.21(supports-color@8.1.1) vite-plugin-style-import: specifier: ^2.0.0 version: 2.0.0(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)) @@ -305,7 +311,7 @@ importers: version: 2.2.1(sortablejs@1.14.0)(vue@3.4.38(typescript@5.5.4)) vue-eslint-parser: specifier: ^9.4.3 - version: 9.4.3(eslint@9.9.1(jiti@1.21.6)) + version: 9.4.3(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1) packages: @@ -1007,6 +1013,22 @@ packages: resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} engines: {node: '>=18.18'} + '@intlify/core-base@11.4.8': + resolution: {integrity: sha512-A+Q7SKm5oEcy1E/cghqd7n/St4XjTqLhiiyDuieNcMrJcrHlkY5n0jp7Q9dD3txvVHzvsmBVV5M9wD5/s1zfzw==} + engines: {node: '>= 22'} + + '@intlify/devtools-types@11.4.8': + resolution: {integrity: sha512-MGpID+rlfzGUbNcnC20bm5NMSBHPrvx0atLTfv9dftn3kjXw1hGKDcIcwrO99tSrZEc2i+hczRL7ks8qXsHPkQ==} + engines: {node: '>= 22'} + + '@intlify/message-compiler@11.4.8': + resolution: {integrity: sha512-vbzk17dYwduYiv52EK61+FDCyhfVg1uPUtPmiD/d45W99uJIcXywrweOBcHv7n9/iEqmXiMGT52bgJbZDQqK3w==} + engines: {node: '>= 22'} + + '@intlify/shared@11.4.8': + resolution: {integrity: sha512-XbRgrv+XEuvDr7UCY55oibVrh+o4u+A0VB6nSL0F5Z8LcZxE/8j573LYG6bCrOigIcHdGpSNI7Rh5UpC5/B/eg==} + engines: {node: '>= 22'} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1089,6 +1111,9 @@ packages: resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -1103,6 +1128,9 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -1202,46 +1230,55 @@ packages: resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.21.2': resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.21.2': resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.21.2': resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.21.2': resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-s390x-gnu@4.21.2': resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.21.2': resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.21.2': resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.21.2': resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==} @@ -1290,24 +1327,28 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [glibc] '@swc/core-linux-arm64-musl@1.7.23': resolution: {integrity: sha512-JEdtwdthazKq4PBz53KSubwwK8MvqODAihGSAzc8u3Unq4ojcvaS8b0CwLBeD+kTQ78HpxOXTt3DsFIxpgaCAA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [musl] '@swc/core-linux-x64-gnu@1.7.23': resolution: {integrity: sha512-V51gFPWaVAHbI1yg9ahsoya3aB4uawye3SZ5uQWgcP7wdCdiv60dw4F5nuPJf5Z1oXD3U/BslXuamv8Oh9vXqQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [glibc] '@swc/core-linux-x64-musl@1.7.23': resolution: {integrity: sha512-BBqQi4+UdeRqag3yM4IJjaHG4yc1o3l9ksENHToE0o/u2DT0FY5+K/DiYGZLC1JHbSFzNqRCYsa7DIzRtZ0A1A==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [musl] '@swc/core-win32-arm64-msvc@1.7.23': resolution: {integrity: sha512-JPk6pvCKncL6bXG7p+NLZf8PWx4FakVvKNdwGeMrYunb+yk1IZf7qf9LJk8+GDGF5QviDXPs8opZrTrfsW80fA==} @@ -1396,12 +1437,12 @@ packages: '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - '@types/katex@0.16.7': - resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} - '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + '@types/lodash@4.17.25': + resolution: {integrity: sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==} + '@types/lodash@4.17.7': resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} @@ -1705,6 +1746,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + engines: {node: '>=0.4.0'} + hasBin: true + ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -2067,6 +2113,12 @@ packages: confbox@0.1.7: resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + connect-history-api-fallback@1.6.0: resolution: {integrity: sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==} engines: {node: '>=0.8'} @@ -2148,6 +2200,7 @@ packages: crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + deprecated: Active development of CryptoJS has been discontinued. This library is no longer maintained. css-functions-list@3.2.2: resolution: {integrity: sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==} @@ -2194,6 +2247,9 @@ packages: date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + date-fns@4.4.0: + resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -2418,6 +2474,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + eslint-config-prettier@9.1.0: resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true @@ -2427,6 +2487,7 @@ packages: eslint-define-config@2.1.0: resolution: {integrity: sha512-QUp6pM9pjKEVannNAbSJNeRuYwW3LshejfyBBpjeMGaJjaDUpVps4C6KVR8R7dWZnD3i0synmrE36znjTkJvdQ==} engines: {node: '>=18.0.0', npm: '>=9.0.0', pnpm: '>=8.6.0'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. eslint-plugin-jest@28.8.2: resolution: {integrity: sha512-mC3OyklHmS5i7wYU1rGId9EnxRI8TVlnFG56AE+8U9iRy6zwaNygZR+DsdZuCL0gRG0wVeyzq+uWcPt6yJrrMA==} @@ -2527,6 +2588,9 @@ packages: estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -2564,6 +2628,9 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + exsolve@1.1.1: + resolution: {integrity: sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} @@ -2606,6 +2673,15 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -2763,6 +2839,7 @@ packages: git-raw-commits@4.0.0: resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} engines: {node: '>=16'} + deprecated: Deprecated and no longer maintained. Use @conventional-changelog/git-client instead. hasBin: true glob-parent@5.1.2: @@ -2778,16 +2855,18 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@11.0.0: resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} engines: {node: 20 || >=22} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} @@ -3237,6 +3316,9 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -3349,6 +3431,10 @@ packages: resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} + local-pkg@1.2.1: + resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} + engines: {node: '>=14'} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -3372,6 +3458,7 @@ packages: lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} @@ -3437,6 +3524,9 @@ packages: magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -3542,6 +3632,9 @@ packages: mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + mockjs@1.1.0: resolution: {integrity: sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==} hasBin: true @@ -3562,8 +3655,9 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - naive-ui@2.42.0: - resolution: {integrity: sha512-c7cXR2YgOjgtBadXHwiWL4Y0tpGLAI5W5QzzHksOi22iuHXoSGMAzdkVTGVPE/PM0MSGQ/JtUIzCx2Y0hU0vTQ==} + naive-ui@2.44.1: + resolution: {integrity: sha512-reo8Esw0p58liZwbUutC7meW24Xbn3EwNv91zReWKm2W4JPu+zfgJRn/F7aO0BFmvN+h2brA2M5lRvYqLq4kuA==} + engines: {node: '>=20'} peerDependencies: vue: ^3.0.0 @@ -3781,6 +3875,9 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} @@ -3792,6 +3889,10 @@ packages: resolution: {integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==} engines: {node: '>=10'} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} @@ -3839,6 +3940,12 @@ packages: pkg-types@1.2.0: resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.3.1: + resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} + postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} @@ -3950,6 +4057,9 @@ packages: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -4083,6 +4193,12 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + seemly@0.3.10: + resolution: {integrity: sha512-2+SMxtG1PcsL0uyhkumlOU6Qo9TAQ/WyH7tthnPIOQB05/12jz9naq6GZ6iZ6ApVsO3rr2gsnTf3++OV63kE1Q==} + seemly@0.3.8: resolution: {integrity: sha512-MW8Qs6vbzo0pHmDpFSYPna+lwpZ6Zk1ancbajw/7E8TKtHdV+1DfZZD+kKJEhG/cAoB/i+LiT+5msZOqj0DwRA==} @@ -4243,6 +4359,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + strip-outer@1.0.1: resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} engines: {node: '>=0.10.0'} @@ -4379,6 +4498,10 @@ packages: tiny-emitter@2.1.0: resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -4459,6 +4582,9 @@ packages: ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -4466,6 +4592,10 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} + unimport@5.7.0: + resolution: {integrity: sha512-njnL6sp8lEA8QQbZrt+52p/g4X0rw3bnGGmUcJnt1jeG8+iiqO779aGz0PirCtydAIVcuTBRlJ52F0u46z309Q==} + engines: {node: '>=18.12.0'} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -4474,6 +4604,22 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unplugin-auto-import@20.3.0: + resolution: {integrity: sha512-RcSEQiVv7g0mLMMXibYVKk8mpteKxvyffGuDKqZZiFr7Oq3PB1HwgHdK5O7H4AzbhzHoVKG0NnMnsk/1HIVYzQ==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': ^4.0.0 + '@vueuse/core': '*' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@vueuse/core': + optional: true + + unplugin-utils@0.3.2: + resolution: {integrity: sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==} + engines: {node: '>=20.19.0'} + unplugin-vue-components@0.27.4: resolution: {integrity: sha512-1XVl5iXG7P1UrOMnaj2ogYa5YTq8aoh5jwDPQhemwO/OrXW+lPQKDXd1hMz15qxQPxgb/XXlbgo3HQ2rLEbmXQ==} engines: {node: '>=14'} @@ -4491,6 +4637,10 @@ packages: resolution: {integrity: sha512-my8DH0/T/Kx33KO+6QXAqdeMYgyy0GktlOpdQjpagfHKw5DrD0ctPr7SHUyOT3g4ZVpzCQGt/qcpuoKJ/pniHA==} engines: {node: '>=14.0.0'} + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + update-browserslist-db@1.1.0: resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true @@ -4515,6 +4665,7 @@ packages: uuid@10.0.0: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true v8-compile-cache-lib@3.0.1: @@ -4627,6 +4778,12 @@ packages: peerDependencies: eslint: '>=6.0.0' + vue-i18n@11.4.8: + resolution: {integrity: sha512-0ULeHP6Z9CGvAm67S77ZEp41cfGXIREGL8qfhos2BMgcQQewtQcDKuojt6jjasAD/S8GwfTp2ySPmDSpwvrCMQ==} + engines: {node: '>= 22'} + peerDependencies: + vue: ^3.0.0 + vue-router@4.4.3: resolution: {integrity: sha512-sv6wmNKx2j3aqJQDMxLFzs/u/mjA9Z5LCgy6BE0f7yFWMjrPLnS/sPNn8ARY/FXw6byV18EFutn5lTO6+UsV5A==} peerDependencies: @@ -4644,10 +4801,10 @@ packages: vue-waterfall-plugin-next@2.6.0: resolution: {integrity: sha512-GgovHXWkEP0flI/60GPeTC9vQAnYXLfhohAe8BudIljlcpBS+UCFXOS+S7FCsoujhvdcUY1heKxZglf13KGl9g==} - vue3-json-viewer@2.2.2: - resolution: {integrity: sha512-56l3XDGggnpwEqZieXsSMhNT4NhtO6d7zuSAxHo4i0UVxymyY2jRb7UMQOU1ztChKALZCAzX7DlgrsnEhxu77A==} + vue3-json-viewer@2.4.1: + resolution: {integrity: sha512-Z1sunvS58lJ3ZcpNhl3jYQapBVw2wjnXbemigfMWm3QnjCeg3CPMq8R6pxHUYahxMfPKLvrbGve6mUXqhWyLaQ==} peerDependencies: - vue: ^3.2.0 + vue: ^3.5.16 vue@3.4.38: resolution: {integrity: sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==} @@ -4662,8 +4819,8 @@ packages: peerDependencies: vue: ^3.0.1 - vueuc@0.4.64: - resolution: {integrity: sha512-wlJQj7fIwKK2pOEoOq4Aro8JdPOGpX8aWQhV8YkTW9OgWD2uj2O8ANzvSsIGjx7LTOc7QbS7sXdxHi6XvRnHPA==} + vueuc@0.4.65: + resolution: {integrity: sha512-lXuMl+8gsBmruudfxnMF9HW4be8rFziylXFu1VHVNbLVhRTXXV4njvpRuJapD/8q+oFEMSfQMH16E/85VoWRyQ==} peerDependencies: vue: ^3.0.11 @@ -4793,20 +4950,20 @@ snapshots: '@babel/compat-data@7.25.4': {} - '@babel/core@7.25.2': + '@babel/core@7.25.2(supports-color@8.1.1)': dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.24.7 '@babel/generator': 7.25.6 '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1) '@babel/helpers': 7.25.6 '@babel/parser': 7.25.6 '@babel/template': 7.25.0 - '@babel/traverse': 7.25.6 + '@babel/traverse': 7.25.6(supports-color@8.1.1) '@babel/types': 7.25.6 convert-source-map: 2.0.0 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -4832,22 +4989,22 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.25.4(@babel/core@7.25.2)': + '@babel/helper-create-class-features-plugin@7.25.4(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/helper-member-expression-to-functions': 7.24.8(supports-color@8.1.1) '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/traverse': 7.25.6 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7(supports-color@8.1.1) + '@babel/traverse': 7.25.6(supports-color@8.1.1) semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-member-expression-to-functions@7.24.8': + '@babel/helper-member-expression-to-functions@7.24.8(supports-color@8.1.1)': dependencies: - '@babel/traverse': 7.25.6 + '@babel/traverse': 7.25.6(supports-color@8.1.1) '@babel/types': 7.25.6 transitivePeerDependencies: - supports-color @@ -4856,20 +5013,20 @@ snapshots: dependencies: '@babel/types': 7.25.6 - '@babel/helper-module-imports@7.24.7': + '@babel/helper-module-imports@7.24.7(supports-color@8.1.1)': dependencies: - '@babel/traverse': 7.25.6 + '@babel/traverse': 7.25.6(supports-color@8.1.1) '@babel/types': 7.25.6 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-simple-access': 7.24.7 + '@babel/core': 7.25.2(supports-color@8.1.1) + '@babel/helper-module-imports': 7.24.7(supports-color@8.1.1) + '@babel/helper-simple-access': 7.24.7(supports-color@8.1.1) '@babel/helper-validator-identifier': 7.24.7 - '@babel/traverse': 7.25.6 + '@babel/traverse': 7.25.6(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -4879,25 +5036,25 @@ snapshots: '@babel/helper-plugin-utils@7.24.8': {} - '@babel/helper-replace-supers@7.25.0(@babel/core@7.25.2)': + '@babel/helper-replace-supers@7.25.0(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/core': 7.25.2(supports-color@8.1.1) + '@babel/helper-member-expression-to-functions': 7.24.8(supports-color@8.1.1) '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/traverse': 7.25.6 + '@babel/traverse': 7.25.6(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/helper-simple-access@7.24.7': + '@babel/helper-simple-access@7.24.7(supports-color@8.1.1)': dependencies: - '@babel/traverse': 7.25.6 + '@babel/traverse': 7.25.6(supports-color@8.1.1) '@babel/types': 7.25.6 transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + '@babel/helper-skip-transparent-expression-wrappers@7.24.7(supports-color@8.1.1)': dependencies: - '@babel/traverse': 7.25.6 + '@babel/traverse': 7.25.6(supports-color@8.1.1) '@babel/types': 7.25.6 transitivePeerDependencies: - supports-color @@ -4924,99 +5081,99 @@ snapshots: dependencies: '@babel/types': 7.25.6 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-import-attributes@7.25.6(@babel/core@7.25.2)': + '@babel/plugin-syntax-import-attributes@7.25.6(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-typescript@7.25.2(@babel/core@7.25.2)': + '@babel/plugin-transform-typescript@7.25.2(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) + '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.25.2) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7(supports-color@8.1.1) + '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.25.2(supports-color@8.1.1)) transitivePeerDependencies: - supports-color @@ -5026,14 +5183,14 @@ snapshots: '@babel/parser': 7.25.6 '@babel/types': 7.25.6 - '@babel/traverse@7.25.6': + '@babel/traverse@7.25.6(supports-color@8.1.1)': dependencies: '@babel/code-frame': 7.24.7 '@babel/generator': 7.25.6 '@babel/parser': 7.25.6 '@babel/template': 7.25.0 '@babel/types': 7.25.6 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -5446,25 +5603,25 @@ snapshots: '@esbuild/win32-x64@0.23.1': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.9.1(jiti@1.21.6))': + '@eslint-community/eslint-utils@4.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))': dependencies: - eslint: 9.9.1(jiti@1.21.6) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.11.0': {} - '@eslint/config-array@0.18.0': + '@eslint/config-array@0.18.0(supports-color@8.1.1)': dependencies: '@eslint/object-schema': 2.1.4 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/eslintrc@3.1.0': + '@eslint/eslintrc@3.1.0(supports-color@8.1.1)': dependencies: ajv: 6.12.6 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) espree: 10.1.0 globals: 14.0.0 ignore: 5.3.2 @@ -5483,6 +5640,24 @@ snapshots: '@humanwhocodes/retry@0.3.0': {} + '@intlify/core-base@11.4.8': + dependencies: + '@intlify/devtools-types': 11.4.8 + '@intlify/message-compiler': 11.4.8 + '@intlify/shared': 11.4.8 + + '@intlify/devtools-types@11.4.8': + dependencies: + '@intlify/core-base': 11.4.8 + '@intlify/shared': 11.4.8 + + '@intlify/message-compiler@11.4.8': + dependencies: + '@intlify/shared': 11.4.8 + source-map-js: 1.2.0 + + '@intlify/shared@11.4.8': {} + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -5511,12 +5686,12 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4))': + '@jest/core@29.7.0(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4))': dependencies: '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 + '@jest/reporters': 29.7.0(supports-color@8.1.1) '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 '@types/node': 22.5.2 ansi-escapes: 4.3.2 @@ -5525,15 +5700,15 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) + jest-config: 29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 + jest-resolve-dependencies: 29.7.0(supports-color@8.1.1) + jest-runner: 29.7.0(supports-color@8.1.1) + jest-runtime: 29.7.0(supports-color@8.1.1) + jest-snapshot: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 jest-validate: 29.7.0 jest-watcher: 29.7.0 @@ -5557,10 +5732,10 @@ snapshots: dependencies: jest-get-type: 29.6.3 - '@jest/expect@29.7.0': + '@jest/expect@29.7.0(supports-color@8.1.1)': dependencies: expect: 29.7.0 - jest-snapshot: 29.7.0 + jest-snapshot: 29.7.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -5573,21 +5748,21 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 - '@jest/globals@29.7.0': + '@jest/globals@29.7.0(supports-color@8.1.1)': dependencies: '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 + '@jest/expect': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 jest-mock: 29.7.0 transitivePeerDependencies: - supports-color - '@jest/reporters@29.7.0': + '@jest/reporters@29.7.0(supports-color@8.1.1)': dependencies: '@bcoe/v8-coverage': 0.2.3 '@jest/console': 29.7.0 '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 '@types/node': 22.5.2 @@ -5597,9 +5772,9 @@ snapshots: glob: 7.2.3 graceful-fs: 4.2.11 istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 + istanbul-lib-instrument: 6.0.3(supports-color@8.1.1) istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 + istanbul-lib-source-maps: 4.0.1(supports-color@8.1.1) istanbul-reports: 3.1.7 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -5635,12 +5810,12 @@ snapshots: jest-haste-map: 29.7.0 slash: 3.0.0 - '@jest/transform@29.7.0': + '@jest/transform@29.7.0(supports-color@8.1.1)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - babel-plugin-istanbul: 6.1.1 + babel-plugin-istanbul: 6.1.1(supports-color@8.1.1) chalk: 4.1.2 convert-source-map: 2.0.0 fast-json-stable-stringify: 2.1.0 @@ -5670,6 +5845,11 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/set-array@1.2.1': {} @@ -5681,6 +5861,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -5933,12 +6115,12 @@ snapshots: dependencies: '@types/node': 22.5.2 - '@types/katex@0.16.7': {} - '@types/lodash-es@4.17.12': dependencies: '@types/lodash': 4.17.7 + '@types/lodash@4.17.25': {} + '@types/lodash@4.17.7': {} '@types/node@22.5.2': @@ -5960,15 +6142,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4)': dependencies: '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + '@typescript-eslint/parser': 7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) - '@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + '@typescript-eslint/type-utils': 7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) + '@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) '@typescript-eslint/visitor-keys': 7.18.0 - eslint: 9.9.1(jiti@1.21.6) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -5978,15 +6160,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': + '@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4)': dependencies: '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + '@typescript-eslint/parser': 8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.4.0 - '@typescript-eslint/type-utils': 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) - '@typescript-eslint/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) + '@typescript-eslint/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) '@typescript-eslint/visitor-keys': 8.4.0 - eslint: 9.9.1(jiti@1.21.6) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -5996,27 +6178,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': + '@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 7.18.0(supports-color@8.1.1)(typescript@5.5.4) '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.3.6 - eslint: 9.9.1(jiti@1.21.6) + debug: 4.3.6(supports-color@8.1.1) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': + '@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4)': dependencies: '@typescript-eslint/scope-manager': 8.4.0 '@typescript-eslint/types': 8.4.0 - '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 8.4.0(supports-color@8.1.1)(typescript@5.5.4) '@typescript-eslint/visitor-keys': 8.4.0 - debug: 4.3.6 - eslint: 9.9.1(jiti@1.21.6) + debug: 4.3.6(supports-color@8.1.1) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: @@ -6032,23 +6214,23 @@ snapshots: '@typescript-eslint/types': 8.4.0 '@typescript-eslint/visitor-keys': 8.4.0 - '@typescript-eslint/type-utils@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': + '@typescript-eslint/type-utils@7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4)': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) - '@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) - debug: 4.3.6 - eslint: 9.9.1(jiti@1.21.6) + '@typescript-eslint/typescript-estree': 7.18.0(supports-color@8.1.1)(typescript@5.5.4) + '@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) + debug: 4.3.6(supports-color@8.1.1) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': + '@typescript-eslint/type-utils@8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4)': dependencies: - '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) - debug: 4.3.6 + '@typescript-eslint/typescript-estree': 8.4.0(supports-color@8.1.1)(typescript@5.5.4) + '@typescript-eslint/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) + debug: 4.3.6(supports-color@8.1.1) ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: typescript: 5.5.4 @@ -6060,11 +6242,11 @@ snapshots: '@typescript-eslint/types@8.4.0': {} - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)': + '@typescript-eslint/typescript-estree@7.18.0(supports-color@8.1.1)(typescript@5.5.4)': dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.5 @@ -6075,11 +6257,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.4.0(typescript@5.5.4)': + '@typescript-eslint/typescript-estree@8.4.0(supports-color@8.1.1)(typescript@5.5.4)': dependencies: '@typescript-eslint/types': 8.4.0 '@typescript-eslint/visitor-keys': 8.4.0 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 @@ -6090,24 +6272,24 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': + '@typescript-eslint/utils@7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6)) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1)) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) - eslint: 9.9.1(jiti@1.21.6) + '@typescript-eslint/typescript-estree': 7.18.0(supports-color@8.1.1)(typescript@5.5.4) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': + '@typescript-eslint/utils@8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6)) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1)) '@typescript-eslint/scope-manager': 8.4.0 '@typescript-eslint/types': 8.4.0 - '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) - eslint: 9.9.1(jiti@1.21.6) + '@typescript-eslint/typescript-estree': 8.4.0(supports-color@8.1.1)(typescript@5.5.4) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) transitivePeerDependencies: - supports-color - typescript @@ -6126,11 +6308,11 @@ snapshots: '@vicons/ionicons5@0.12.0': {} - '@vitejs/plugin-vue-jsx@4.0.1(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4))': + '@vitejs/plugin-vue-jsx@4.0.1(supports-color@8.1.1)(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4))': dependencies: - '@babel/core': 7.25.2 - '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2) - '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.25.2) + '@babel/core': 7.25.2(supports-color@8.1.1) + '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1) + '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1) vite: 5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6) vue: 3.4.38(typescript@5.5.4) transitivePeerDependencies: @@ -6143,28 +6325,28 @@ snapshots: '@vue/babel-helper-vue-transform-on@1.2.2': {} - '@vue/babel-plugin-jsx@1.2.2(@babel/core@7.25.2)': + '@vue/babel-plugin-jsx@1.2.2(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2(supports-color@8.1.1)) '@babel/template': 7.25.0 - '@babel/traverse': 7.25.6 + '@babel/traverse': 7.25.6(supports-color@8.1.1) '@babel/types': 7.25.6 '@vue/babel-helper-vue-transform-on': 1.2.2 - '@vue/babel-plugin-resolve-type': 1.2.2(@babel/core@7.25.2) + '@vue/babel-plugin-resolve-type': 1.2.2(@babel/core@7.25.2(supports-color@8.1.1)) camelcase: 6.3.0 html-tags: 3.3.1 svg-tags: 1.0.0 optionalDependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@vue/babel-plugin-resolve-type@1.2.2(@babel/core@7.25.2)': + '@vue/babel-plugin-resolve-type@1.2.2(@babel/core@7.25.2(supports-color@8.1.1))': dependencies: '@babel/code-frame': 7.24.7 - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.24.8 '@babel/parser': 7.25.6 @@ -6202,13 +6384,13 @@ snapshots: '@vue/devtools-api@6.6.3': {} - '@vue/eslint-config-typescript@13.0.0(eslint-plugin-vue@9.28.0(eslint@9.9.1(jiti@1.21.6)))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': + '@vue/eslint-config-typescript@13.0.0(eslint-plugin-vue@9.28.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4)': dependencies: - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) - '@typescript-eslint/parser': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) - eslint: 9.9.1(jiti@1.21.6) - eslint-plugin-vue: 9.28.0(eslint@9.9.1(jiti@1.21.6)) - vue-eslint-parser: 9.4.3(eslint@9.9.1(jiti@1.21.6)) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) + '@typescript-eslint/parser': 7.18.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) + eslint-plugin-vue: 9.28.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1) + vue-eslint-parser: 9.4.3(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: @@ -6381,6 +6563,8 @@ snapshots: acorn@8.12.1: {} + acorn@8.18.0: {} + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 @@ -6472,33 +6656,33 @@ snapshots: postcss: 8.4.44 postcss-value-parser: 4.2.0 - axios@1.7.7: + axios@1.7.7(debug@4.3.6(supports-color@8.1.1)): dependencies: - follow-redirects: 1.15.6 + follow-redirects: 1.15.6(debug@4.3.6(supports-color@8.1.1)) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - babel-jest@29.7.0(@babel/core@7.25.2): + babel-jest@29.7.0(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1): dependencies: - '@babel/core': 7.25.2 - '@jest/transform': 29.7.0 + '@babel/core': 7.25.2(supports-color@8.1.1) + '@jest/transform': 29.7.0(supports-color@8.1.1) '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.25.2) + babel-plugin-istanbul: 6.1.1(supports-color@8.1.1) + babel-preset-jest: 29.6.3(@babel/core@7.25.2(supports-color@8.1.1)) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 transitivePeerDependencies: - supports-color - babel-plugin-istanbul@6.1.1: + babel-plugin-istanbul@6.1.1(supports-color@8.1.1): dependencies: '@babel/helper-plugin-utils': 7.24.8 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 + istanbul-lib-instrument: 5.2.1(supports-color@8.1.1) test-exclude: 6.0.0 transitivePeerDependencies: - supports-color @@ -6510,30 +6694,30 @@ snapshots: '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.6 - babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.2): + babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.2(supports-color@8.1.1)): dependencies: - '@babel/core': 7.25.2 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-import-attributes': 7.25.6(@babel/core@7.25.2) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) + '@babel/core': 7.25.2(supports-color@8.1.1) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-import-attributes': 7.25.6(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2(supports-color@8.1.1)) - babel-preset-jest@29.6.3(@babel/core@7.25.2): + babel-preset-jest@29.6.3(@babel/core@7.25.2(supports-color@8.1.1)): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2(supports-color@8.1.1)) balanced-match@1.0.2: {} @@ -6785,12 +6969,16 @@ snapshots: confbox@0.1.7: {} + confbox@0.1.8: {} + + confbox@0.2.4: {} + connect-history-api-fallback@1.6.0: {} - connect@3.7.0: + connect@3.7.0(supports-color@8.1.1): dependencies: - debug: 2.6.9 - finalhandler: 1.1.2 + debug: 2.6.9(supports-color@8.1.1) + finalhandler: 1.1.2(supports-color@8.1.1) parseurl: 1.3.3 utils-merge: 1.0.1 transitivePeerDependencies: @@ -6847,13 +7035,13 @@ snapshots: optionalDependencies: typescript: 5.5.4 - create-jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)): + create-jest@29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) + jest-config: 29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -6923,19 +7111,25 @@ snapshots: dargs@8.1.0: {} - date-fns-tz@3.2.0(date-fns@3.6.0): + date-fns-tz@3.2.0(date-fns@4.4.0): dependencies: - date-fns: 3.6.0 + date-fns: 4.4.0 date-fns@3.6.0: {} - debug@2.6.9: + date-fns@4.4.0: {} + + debug@2.6.9(supports-color@8.1.1): dependencies: ms: 2.0.0 + optionalDependencies: + supports-color: 8.1.1 - debug@4.3.6: + debug@4.3.6(supports-color@8.1.1): dependencies: ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 dedent@0.7.0: {} @@ -7152,42 +7346,44 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.6)): + escape-string-regexp@5.0.0: {} + + eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1)): dependencies: - eslint: 9.9.1(jiti@1.21.6) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) eslint-define-config@2.1.0: {} - eslint-plugin-jest@28.8.2(@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)))(typescript@5.5.4): + eslint-plugin-jest@28.8.2(@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(jest@29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)))(supports-color@8.1.1)(typescript@5.5.4): dependencies: - '@typescript-eslint/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) - eslint: 9.9.1(jiti@1.21.6) + '@typescript-eslint/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) - jest: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) + '@typescript-eslint/eslint-plugin': 8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.5.4) + jest: 29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) transitivePeerDependencies: - supports-color - typescript - eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.6)))(eslint@9.9.1(jiti@1.21.6))(prettier@3.3.3): + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1)))(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(prettier@3.3.3): dependencies: - eslint: 9.9.1(jiti@1.21.6) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) prettier: 3.3.3 prettier-linter-helpers: 1.0.0 synckit: 0.9.1 optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@9.9.1(jiti@1.21.6)) + eslint-config-prettier: 9.1.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1)) - eslint-plugin-vue@9.28.0(eslint@9.9.1(jiti@1.21.6)): + eslint-plugin-vue@9.28.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6)) - eslint: 9.9.1(jiti@1.21.6) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1)) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) globals: 13.24.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 semver: 7.6.3 - vue-eslint-parser: 9.4.3(eslint@9.9.1(jiti@1.21.6)) + vue-eslint-parser: 9.4.3(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color @@ -7212,12 +7408,12 @@ snapshots: eslint-visitor-keys@4.0.0: {} - eslint@9.9.1(jiti@1.21.6): + eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6)) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1)) '@eslint-community/regexpp': 4.11.0 - '@eslint/config-array': 0.18.0 - '@eslint/eslintrc': 3.1.0 + '@eslint/config-array': 0.18.0(supports-color@8.1.1) + '@eslint/eslintrc': 3.1.0(supports-color@8.1.1) '@eslint/js': 9.9.1 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.3.0 @@ -7225,7 +7421,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint-scope: 8.0.2 eslint-visitor-keys: 4.0.0 @@ -7286,6 +7482,10 @@ snapshots: estree-walker@2.0.2: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + esutils@2.0.3: {} eventemitter3@2.0.3: {} @@ -7335,6 +7535,8 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 + exsolve@1.1.1: {} + extend@3.0.2: {} external-editor@3.1.0: @@ -7375,6 +7577,10 @@ snapshots: dependencies: bser: 2.1.1 + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 @@ -7403,9 +7609,9 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@1.1.2: + finalhandler@1.1.2(supports-color@8.1.1): dependencies: - debug: 2.6.9 + debug: 2.6.9(supports-color@8.1.1) encodeurl: 1.0.2 escape-html: 1.0.3 on-finished: 2.3.0 @@ -7465,7 +7671,9 @@ snapshots: flatted@3.3.1: {} - follow-redirects@1.15.6: {} + follow-redirects@1.15.6(debug@4.3.6(supports-color@8.1.1)): + optionalDependencies: + debug: 4.3.6(supports-color@8.1.1) foreground-child@3.3.0: dependencies: @@ -7835,9 +8043,9 @@ snapshots: istanbul-lib-coverage@3.2.2: {} - istanbul-lib-instrument@5.2.1: + istanbul-lib-instrument@5.2.1(supports-color@8.1.1): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/parser': 7.25.6 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 @@ -7845,9 +8053,9 @@ snapshots: transitivePeerDependencies: - supports-color - istanbul-lib-instrument@6.0.3: + istanbul-lib-instrument@6.0.3(supports-color@8.1.1): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/parser': 7.25.6 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 @@ -7861,9 +8069,9 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@4.0.1: + istanbul-lib-source-maps@4.0.1(supports-color@8.1.1): dependencies: - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -7899,10 +8107,10 @@ snapshots: jest-util: 29.7.0 p-limit: 3.1.0 - jest-circus@29.7.0: + jest-circus@29.7.0(supports-color@8.1.1): dependencies: '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 + '@jest/expect': 29.7.0(supports-color@8.1.1) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 '@types/node': 22.5.2 @@ -7913,8 +8121,8 @@ snapshots: jest-each: 29.7.0 jest-matcher-utils: 29.7.0 jest-message-util: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 + jest-runtime: 29.7.0(supports-color@8.1.1) + jest-snapshot: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 p-limit: 3.1.0 pretty-format: 29.7.0 @@ -7925,16 +8133,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)): + jest-cli@29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) + '@jest/core': 29.7.0(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) + create-jest: 29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) + jest-config: 29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -7944,23 +8152,23 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)): + jest-config@29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.25.2) + babel-jest: 29.7.0(@babel/core@7.25.2(supports-color@8.1.1))(supports-color@8.1.1) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 glob: 7.2.3 graceful-fs: 4.2.11 - jest-circus: 29.7.0 + jest-circus: 29.7.0(supports-color@8.1.1) jest-environment-node: 29.7.0 jest-get-type: 29.6.3 jest-regex-util: 29.6.3 jest-resolve: 29.7.0 - jest-runner: 29.7.0 + jest-runner: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 jest-validate: 29.7.0 micromatch: 4.0.8 @@ -8057,10 +8265,10 @@ snapshots: jest-regex-util@29.6.3: {} - jest-resolve-dependencies@29.7.0: + jest-resolve-dependencies@29.7.0(supports-color@8.1.1): dependencies: jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 + jest-snapshot: 29.7.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -8076,12 +8284,12 @@ snapshots: resolve.exports: 2.0.2 slash: 3.0.0 - jest-runner@29.7.0: + jest-runner@29.7.0(supports-color@8.1.1): dependencies: '@jest/console': 29.7.0 '@jest/environment': 29.7.0 '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 '@types/node': 22.5.2 chalk: 4.1.2 @@ -8093,7 +8301,7 @@ snapshots: jest-leak-detector: 29.7.0 jest-message-util: 29.7.0 jest-resolve: 29.7.0 - jest-runtime: 29.7.0 + jest-runtime: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 jest-watcher: 29.7.0 jest-worker: 29.7.0 @@ -8102,14 +8310,14 @@ snapshots: transitivePeerDependencies: - supports-color - jest-runtime@29.7.0: + jest-runtime@29.7.0(supports-color@8.1.1): dependencies: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 + '@jest/globals': 29.7.0(supports-color@8.1.1) '@jest/source-map': 29.6.3 '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 '@types/node': 22.5.2 chalk: 4.1.2 @@ -8122,24 +8330,24 @@ snapshots: jest-mock: 29.7.0 jest-regex-util: 29.6.3 jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 + jest-snapshot: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 slash: 3.0.0 strip-bom: 4.0.0 transitivePeerDependencies: - supports-color - jest-snapshot@29.7.0: + jest-snapshot@29.7.0(supports-color@8.1.1): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.2(supports-color@8.1.1) '@babel/generator': 7.25.6 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.25.2) + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2(supports-color@8.1.1)) + '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.25.2(supports-color@8.1.1)) '@babel/types': 7.25.6 '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2(supports-color@8.1.1)) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -8197,12 +8405,12 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)): + jest@29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) + '@jest/core': 29.7.0(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) + jest-cli: 29.7.0(@types/node@22.5.2)(supports-color@8.1.1)(ts-node@10.9.2(@swc/core@1.7.23)(@types/node@22.5.2)(typescript@5.5.4)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -8213,6 +8421,8 @@ snapshots: js-tokens@4.0.0: {} + js-tokens@9.0.1: {} + js-yaml@3.14.1: dependencies: argparse: 1.0.10 @@ -8287,11 +8497,11 @@ snapshots: lines-and-columns@1.2.4: {} - lint-staged@15.2.10: + lint-staged@15.2.10(supports-color@8.1.1): dependencies: chalk: 5.3.0 commander: 12.1.0 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) execa: 8.0.1 lilconfig: 3.1.2 listr2: 8.2.4 @@ -8321,6 +8531,12 @@ snapshots: mlly: 1.7.1 pkg-types: 1.2.0 + local-pkg@1.2.1: + dependencies: + mlly: 1.8.2 + pkg-types: 2.3.1 + quansync: 0.2.11 + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -8398,6 +8614,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + make-dir@2.1.0: dependencies: pify: 4.0.1 @@ -8486,6 +8706,13 @@ snapshots: pkg-types: 1.2.0 ufo: 1.5.4 + mlly@1.8.2: + dependencies: + acorn: 8.18.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 + mockjs@1.1.0: dependencies: commander: 12.1.0 @@ -8504,28 +8731,27 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - naive-ui@2.42.0(vue@3.4.38(typescript@5.5.4)): + naive-ui@2.44.1(vue@3.4.38(typescript@5.5.4)): dependencies: '@css-render/plugin-bem': 0.15.14(css-render@0.15.14) '@css-render/vue3-ssr': 0.15.14(vue@3.4.38(typescript@5.5.4)) - '@types/katex': 0.16.7 - '@types/lodash': 4.17.7 + '@types/lodash': 4.17.25 '@types/lodash-es': 4.17.12 async-validator: 4.2.5 css-render: 0.15.14 csstype: 3.1.3 - date-fns: 3.6.0 - date-fns-tz: 3.2.0(date-fns@3.6.0) + date-fns: 4.4.0 + date-fns-tz: 3.2.0(date-fns@4.4.0) evtd: 0.2.4 highlight.js: 11.10.0 lodash: 4.17.21 lodash-es: 4.17.21 - seemly: 0.3.8 + seemly: 0.3.10 treemate: 0.3.11 vdirs: 0.1.8(vue@3.4.38(typescript@5.5.4)) vooks: 0.2.12(vue@3.4.38(typescript@5.5.4)) vue: 3.4.38(typescript@5.5.4) - vueuc: 0.4.64(vue@3.4.38(typescript@5.5.4)) + vueuc: 0.4.65(vue@3.4.38(typescript@5.5.4)) nanoid@3.3.7: {} @@ -8722,12 +8948,16 @@ snapshots: pathe@1.1.2: {} + pathe@2.0.3: {} + picocolors@1.1.0: {} picomatch@2.3.1: {} picomatch@3.0.1: {} + picomatch@4.0.5: {} + pidtree@0.6.0: {} pify@2.3.0: {} @@ -8763,6 +8993,18 @@ snapshots: mlly: 1.7.1 pathe: 1.1.2 + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + pkg-types@2.3.1: + dependencies: + confbox: 0.2.4 + exsolve: 1.1.1 + pathe: 2.0.3 + postcss-import@15.1.0(postcss@8.4.44): dependencies: postcss: 8.4.44 @@ -8862,6 +9104,8 @@ snapshots: dependencies: side-channel: 1.0.6 + quansync@0.2.11: {} + queue-microtask@1.2.3: {} quill-delta@3.6.3: @@ -9023,6 +9267,10 @@ snapshots: ajv-keywords: 3.5.2(ajv@6.12.6) optional: true + scule@1.3.0: {} + + seemly@0.3.10: {} + seemly@0.3.8: {} select@1.1.2: {} @@ -9178,32 +9426,36 @@ snapshots: strip-json-comments@3.1.1: {} + strip-literal@3.1.0: + dependencies: + js-tokens: 9.0.1 + strip-outer@1.0.1: dependencies: escape-string-regexp: 1.0.5 style-mod@4.1.2: {} - stylelint-config-prettier@9.0.5(stylelint@16.9.0(typescript@5.5.4)): + stylelint-config-prettier@9.0.5(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)): dependencies: - stylelint: 16.9.0(typescript@5.5.4) + stylelint: 16.9.0(supports-color@8.1.1)(typescript@5.5.4) - stylelint-config-recommended@14.0.1(stylelint@16.9.0(typescript@5.5.4)): + stylelint-config-recommended@14.0.1(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)): dependencies: - stylelint: 16.9.0(typescript@5.5.4) + stylelint: 16.9.0(supports-color@8.1.1)(typescript@5.5.4) - stylelint-config-standard@36.0.1(stylelint@16.9.0(typescript@5.5.4)): + stylelint-config-standard@36.0.1(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)): dependencies: - stylelint: 16.9.0(typescript@5.5.4) - stylelint-config-recommended: 14.0.1(stylelint@16.9.0(typescript@5.5.4)) + stylelint: 16.9.0(supports-color@8.1.1)(typescript@5.5.4) + stylelint-config-recommended: 14.0.1(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)) - stylelint-order@6.0.4(stylelint@16.9.0(typescript@5.5.4)): + stylelint-order@6.0.4(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)): dependencies: postcss: 8.4.44 postcss-sorting: 8.0.2(postcss@8.4.44) - stylelint: 16.9.0(typescript@5.5.4) + stylelint: 16.9.0(supports-color@8.1.1)(typescript@5.5.4) - stylelint-scss@6.5.1(stylelint@16.9.0(typescript@5.5.4)): + stylelint-scss@6.5.1(stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4)): dependencies: css-tree: 2.3.1 is-plain-object: 5.0.0 @@ -9212,9 +9464,9 @@ snapshots: postcss-resolve-nested-selector: 0.1.6 postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - stylelint: 16.9.0(typescript@5.5.4) + stylelint: 16.9.0(supports-color@8.1.1)(typescript@5.5.4) - stylelint@16.9.0(typescript@5.5.4): + stylelint@16.9.0(supports-color@8.1.1)(typescript@5.5.4): dependencies: '@csstools/css-parser-algorithms': 3.0.1(@csstools/css-tokenizer@3.0.1) '@csstools/css-tokenizer': 3.0.1 @@ -9226,7 +9478,7 @@ snapshots: cosmiconfig: 9.0.0(typescript@5.5.4) css-functions-list: 3.2.2 css-tree: 2.3.1 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) fast-glob: 3.3.2 fastest-levenshtein: 1.0.16 file-entry-cache: 9.1.0 @@ -9377,6 +9629,11 @@ snapshots: tiny-emitter@2.1.0: {} + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -9447,20 +9704,55 @@ snapshots: ufo@1.5.4: {} + ufo@1.6.4: {} + undici-types@6.19.8: {} unicorn-magic@0.1.0: {} + unimport@5.7.0: + dependencies: + acorn: 8.18.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.2.1 + magic-string: 0.30.21 + mlly: 1.8.2 + pathe: 2.0.3 + picomatch: 4.0.5 + pkg-types: 2.3.1 + scule: 1.3.0 + strip-literal: 3.1.0 + tinyglobby: 0.2.17 + unplugin: 2.3.11 + unplugin-utils: 0.3.2 + universalify@2.0.1: {} unpipe@1.0.0: {} - unplugin-vue-components@0.27.4(@babel/parser@7.25.6)(rollup@4.21.2)(vue@3.4.38(typescript@5.5.4)): + unplugin-auto-import@20.3.0(@vueuse/core@11.0.3(vue@3.4.38(typescript@5.5.4))): + dependencies: + local-pkg: 1.2.1 + magic-string: 0.30.21 + picomatch: 4.0.5 + unimport: 5.7.0 + unplugin: 2.3.11 + unplugin-utils: 0.3.2 + optionalDependencies: + '@vueuse/core': 11.0.3(vue@3.4.38(typescript@5.5.4)) + + unplugin-utils@0.3.2: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.5 + + unplugin-vue-components@0.27.4(@babel/parser@7.25.6)(rollup@4.21.2)(supports-color@8.1.1)(vue@3.4.38(typescript@5.5.4)): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.0(rollup@4.21.2) chokidar: 3.6.0 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) fast-glob: 3.3.2 local-pkg: 0.5.0 magic-string: 0.30.11 @@ -9480,6 +9772,13 @@ snapshots: webpack-sources: 3.2.3 webpack-virtual-modules: 0.6.2 + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.18.0 + picomatch: 4.0.5 + webpack-virtual-modules: 0.6.2 + update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: browserslist: 4.23.3 @@ -9520,10 +9819,10 @@ snapshots: vfonts@0.0.3: {} - vite-plugin-compression@0.5.1(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)): + vite-plugin-compression@0.5.1(supports-color@8.1.1)(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)): dependencies: chalk: 4.1.2 - debug: 4.3.6 + debug: 4.3.6(supports-color@8.1.1) fs-extra: 10.1.0 vite: 5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6) transitivePeerDependencies: @@ -9545,12 +9844,12 @@ snapshots: pathe: 0.2.0 vite: 5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6) - vite-plugin-mock@3.0.2(esbuild@0.23.1)(mockjs@1.1.0)(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)): + vite-plugin-mock@3.0.2(esbuild@0.23.1)(mockjs@1.1.0)(supports-color@8.1.1)(vite@5.4.2(@types/node@22.5.2)(less@4.2.0)(terser@5.31.6)): dependencies: bundle-require: 4.2.1(esbuild@0.23.1) chokidar: 3.6.0 - connect: 3.7.0 - debug: 4.3.6 + connect: 3.7.0(supports-color@8.1.1) + debug: 4.3.6(supports-color@8.1.1) esbuild: 0.23.1 fast-glob: 3.3.2 mockjs: 1.1.0 @@ -9560,11 +9859,11 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-require-transform@1.0.21: + vite-plugin-require-transform@1.0.21(supports-color@8.1.1): dependencies: '@babel/generator': 7.25.6 '@babel/parser': 7.25.6 - '@babel/traverse': 7.25.6 + '@babel/traverse': 7.25.6(supports-color@8.1.1) '@babel/types': 7.25.6 transitivePeerDependencies: - supports-color @@ -9621,10 +9920,10 @@ snapshots: sortablejs: 1.14.0 vue: 3.4.38(typescript@5.5.4) - vue-eslint-parser@9.4.3(eslint@9.9.1(jiti@1.21.6)): + vue-eslint-parser@9.4.3(eslint@9.9.1(jiti@1.21.6)(supports-color@8.1.1))(supports-color@8.1.1): dependencies: - debug: 4.3.6 - eslint: 9.9.1(jiti@1.21.6) + debug: 4.3.6(supports-color@8.1.1) + eslint: 9.9.1(jiti@1.21.6)(supports-color@8.1.1) eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 @@ -9634,6 +9933,14 @@ snapshots: transitivePeerDependencies: - supports-color + vue-i18n@11.4.8(vue@3.4.38(typescript@5.5.4)): + dependencies: + '@intlify/core-base': 11.4.8 + '@intlify/devtools-types': 11.4.8 + '@intlify/shared': 11.4.8 + '@vue/devtools-api': 6.6.3 + vue: 3.4.38(typescript@5.5.4) + vue-router@4.4.3(vue@3.4.38(typescript@5.5.4)): dependencies: '@vue/devtools-api': 6.6.3 @@ -9647,7 +9954,7 @@ snapshots: vue-waterfall-plugin-next@2.6.0: {} - vue3-json-viewer@2.2.2(vue@3.4.38(typescript@5.5.4)): + vue3-json-viewer@2.4.1(vue@3.4.38(typescript@5.5.4)): dependencies: clipboard: 2.0.11 vue: 3.4.38(typescript@5.5.4) @@ -9667,7 +9974,7 @@ snapshots: sortablejs: 1.14.0 vue: 3.4.38(typescript@5.5.4) - vueuc@0.4.64(vue@3.4.38(typescript@5.5.4)): + vueuc@0.4.65(vue@3.4.38(typescript@5.5.4)): dependencies: '@css-render/vue3-ssr': 0.15.14(vue@3.4.38(typescript@5.5.4)) '@juggle/resize-observer': 3.4.0 diff --git a/web/pnpm-workspace.yaml b/web/pnpm-workspace.yaml new file mode 100644 index 0000000..791bef2 --- /dev/null +++ b/web/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +allowBuilds: + '@swc/core': true + core-js: true + esbuild: true + vue-demi: true From b315d20197cc9cf3b617b6ef7956cf9c11e48fa0 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 12 Aug 2026 11:26:48 +0800 Subject: [PATCH 02/60] =?UTF-8?q?=E6=96=B0=E5=A2=9EGitea=20Actions?= =?UTF-8?q?=E8=93=9D=E7=BB=BF=E5=8F=91=E5=B8=83workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 手动触发(workflow_dispatch),构建镜像后调用宿主机上的 /opt/apps/im-manager/deploy.sh完成蓝绿切换。 --- .gitea/workflows/deploy.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .gitea/workflows/deploy.yml diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..6ab06e4 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,34 @@ +name: Deploy im-manager (Blue-Green) + +on: + workflow_dispatch: + inputs: + image_tag: + description: '镜像tag,留空则使用commit短哈希' + required: false + +jobs: + deploy: + runs-on: deploy-host + steps: + - uses: actions/checkout@v4 + + - name: 确定镜像tag + id: vars + run: | + TAG="${{ github.event.inputs.image_tag }}" + [ -z "$TAG" ] && TAG=$(git rev-parse --short HEAD) + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + + - name: 构建镜像(前端+后端一体,自包含多阶段构建) + run: docker build -t im-manager:${{ steps.vars.outputs.tag }} . + + - name: 蓝绿部署 + env: + MYSQL_DSN: ${{ secrets.MYSQL_DSN }} + REDIS_ADDR: ${{ secrets.REDIS_ADDR }} + REDIS_DB: ${{ secrets.REDIS_DB }} + REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }} + TOKEN_SECRET_KEY: ${{ secrets.TOKEN_SECRET_KEY }} + run: | + IMAGE=im-manager:${{ steps.vars.outputs.tag }} /opt/apps/im-manager/deploy.sh From 616d11202e1e1deb1e6e1d0ff0cc506e338350c6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 12 Aug 2026 11:32:37 +0800 Subject: [PATCH 03/60] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E5=B4=A9=E6=BA=83=E5=BE=AA=E7=8E=AF:=20alpine=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E6=97=B6=E9=95=9C=E5=83=8F=E7=BC=BA=E5=B0=91tzdata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:容器起来后一直重启,日志显示 "time.LoadLocation failed for zone Asia/Shanghai: unknown time zone"。 alpine默认不带IANA时区数据库,补上tzdata包解决。 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1e9e22b..218e340 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,7 @@ RUN CGO_ENABLED=0 go build -o /out/hotgo main.go # ---- Stage 3: runtime ---- FROM alpine:3.22 -RUN apk add --no-cache ca-certificates gettext bash +RUN apk add --no-cache ca-certificates gettext bash tzdata WORKDIR /app From 5ac3a5b96c4d2db0423cec17f76e030a4b434036 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 12 Aug 2026 11:40:13 +0800 Subject: [PATCH 04/60] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E5=B4=A9=E6=BA=83:=20hggen=E5=88=9D=E5=A7=8B=E5=8C=96=E9=9C=80?= =?UTF-8?q?=E8=A6=81hack/config.yaml,=20=E8=BF=90=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E9=95=9C=E5=83=8F=E6=9C=AA=E6=8B=B7=E8=B4=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hotgo/internal/library/hggen.InIt()在HTTP命令初始化时会读取hack/config.yaml (在线代码生成功能依赖), 之前只拷贝了manifest目录导致运行时找不到该文件而致命退出 --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 218e340..d124c3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,6 +36,7 @@ RUN apk add --no-cache ca-certificates gettext bash tzdata WORKDIR /app COPY --from=server-build /src/manifest ./manifest +COPY --from=server-build /src/hack ./hack COPY --from=server-build /out/hotgo . COPY server/manifest/docker/entrypoint.sh . From 543c7b624ef6f66d3387daa80988b41a03f97c48 Mon Sep 17 00:00:00 2001 From: richjohnrambo Date: Fri, 21 Aug 2026 15:09:39 +0800 Subject: [PATCH 05/60] feat: expand IM admin controls --- server/api/admin/imauditlog/im_audit_log.go | 8 + server/api/admin/imtenant/im_tenant.go | 32 +++ server/api/admin/imuser/im_user.go | 24 ++ .../controller/admin/sys/im_audit_log.go | 6 + .../controller/admin/sys/im_tenant.go | 32 +++ .../internal/controller/admin/sys/im_user.go | 26 +++ server/internal/logic/sys/im_audit_log.go | 38 +++- server/internal/logic/sys/im_tenant.go | 137 ++++++++++++ server/internal/logic/sys/im_user.go | 208 ++++++++++++++++++ .../model/input/sysin/im_audit_log.go | 21 +- .../internal/model/input/sysin/im_tenant.go | 64 ++++++ server/internal/model/input/sysin/im_user.go | 53 +++++ server/internal/service/sys.go | 16 ++ .../data/generate/im_audit_log_menu.sql | 4 + .../storage/data/generate/im_tenant_menu.sql | 16 ++ server/storage/data/generate/im_user_menu.sql | 12 + .../data/im_registration_invite_hotgo.sql | 51 +++++ web/src/api/imAuditLog/index.ts | 7 +- web/src/api/imTenant/index.ts | 33 +++ web/src/api/imUser/index.ts | 27 +++ web/src/views/im/registrationInvite/index.vue | 46 +++- web/src/views/imAuditLog/index.vue | 72 ++++-- web/src/views/imTenant/deletionCheck.vue | 103 +++++++++ web/src/views/imTenant/index.vue | 49 ++++- web/src/views/imTenant/model.ts | 19 ++ web/src/views/imTenant/usage.vue | 83 +++++++ web/src/views/imUser/DevicesModal.vue | 57 +++++ web/src/views/imUser/index.vue | 41 +++- web/src/views/imUser/model.ts | 62 +++++- 29 files changed, 1308 insertions(+), 39 deletions(-) create mode 100644 web/src/views/imTenant/deletionCheck.vue create mode 100644 web/src/views/imTenant/usage.vue create mode 100644 web/src/views/imUser/DevicesModal.vue diff --git a/server/api/admin/imauditlog/im_audit_log.go b/server/api/admin/imauditlog/im_audit_log.go index 492f527..01b9b36 100644 --- a/server/api/admin/imauditlog/im_audit_log.go +++ b/server/api/admin/imauditlog/im_audit_log.go @@ -22,6 +22,14 @@ type ListRes struct { List []*sysin.ImAuditLogListModel `json:"list" dc:"数据列表"` } +// ExportReq 导出IM审计日志列表 +type ExportReq struct { + g.Meta `path:"/imAuditLog/export" method:"get" tags:"IM审计日志" summary:"导出IM审计日志列表"` + sysin.ImAuditLogListInp +} + +type ExportRes struct{} + // ViewReq 获取IM审计日志指定信息 type ViewReq struct { g.Meta `path:"/imAuditLog/view" method:"get" tags:"IM审计日志" summary:"获取IM审计日志指定信息"` diff --git a/server/api/admin/imtenant/im_tenant.go b/server/api/admin/imtenant/im_tenant.go index 01af2d3..a5eedb5 100644 --- a/server/api/admin/imtenant/im_tenant.go +++ b/server/api/admin/imtenant/im_tenant.go @@ -48,3 +48,35 @@ type StatusReq struct { } type StatusRes struct{} + +type UsageReq struct { + g.Meta `path:"/imTenant/usage" method:"get" tags:"IM租户" summary:"获取IM租户用量和健康状态"` + sysin.ImTenantUsageInp +} + +type UsageRes struct { + *sysin.ImTenantUsageModel +} + +type DeletionCheckReq struct { + g.Meta `path:"/imTenant/deletionCheck" method:"get" tags:"IM租户" summary:"IM租户删除前检查"` + sysin.ImTenantDeletionCheckInp +} + +type DeletionCheckRes struct { + *sysin.ImTenantDeletionCheckModel +} + +type EnterDeletingReq struct { + g.Meta `path:"/imTenant/enterDeleting" method:"post" tags:"IM租户" summary:"IM租户进入删除流程"` + sysin.ImTenantLifecycleInp +} + +type EnterDeletingRes struct{} + +type RestoreReq struct { + g.Meta `path:"/imTenant/restore" method:"post" tags:"IM租户" summary:"恢复IM租户"` + sysin.ImTenantLifecycleInp +} + +type RestoreRes struct{} diff --git a/server/api/admin/imuser/im_user.go b/server/api/admin/imuser/im_user.go index 03e565a..36ae4ed 100644 --- a/server/api/admin/imuser/im_user.go +++ b/server/api/admin/imuser/im_user.go @@ -39,3 +39,27 @@ type ResetPasswordReq struct { } type ResetPasswordRes struct{} + +type RevokeSessionsReq struct { + g.Meta `path:"/imUser/revokeSessions" method:"post" tags:"IM用户" summary:"撤销IM用户会话"` + sysin.ImUserRevokeSessionsInp +} + +type RevokeSessionsRes struct{} + +type StatusReq struct { + g.Meta `path:"/imUser/status" method:"post" tags:"IM用户" summary:"更新IM用户状态"` + sysin.ImUserStatusInp +} + +type StatusRes struct{} + +type DevicesReq struct { + g.Meta `path:"/imUser/devices" method:"get" tags:"IM用户" summary:"获取IM用户设备列表"` + sysin.ImUserDeviceListInp +} + +type DevicesRes struct { + form.PageRes + List []*sysin.ImUserDeviceListModel `json:"list" dc:"设备列表"` +} diff --git a/server/internal/controller/admin/sys/im_audit_log.go b/server/internal/controller/admin/sys/im_audit_log.go index 460eba1..45ba525 100644 --- a/server/internal/controller/admin/sys/im_audit_log.go +++ b/server/internal/controller/admin/sys/im_audit_log.go @@ -31,6 +31,12 @@ func (c *cImAuditLog) List(ctx context.Context, req *imauditlog.ListReq) (res *i return } +// Export 导出IM审计日志列表 +func (c *cImAuditLog) Export(ctx context.Context, req *imauditlog.ExportReq) (res *imauditlog.ExportRes, err error) { + err = service.SysImAuditLog().Export(ctx, &req.ImAuditLogListInp) + return +} + // View 获取指定IM审计日志信息 func (c *cImAuditLog) View(ctx context.Context, req *imauditlog.ViewReq) (res *imauditlog.ViewRes, err error) { data, err := service.SysImAuditLog().View(ctx, &req.ImAuditLogViewInp) diff --git a/server/internal/controller/admin/sys/im_tenant.go b/server/internal/controller/admin/sys/im_tenant.go index 3acd490..197fdd5 100644 --- a/server/internal/controller/admin/sys/im_tenant.go +++ b/server/internal/controller/admin/sys/im_tenant.go @@ -58,3 +58,35 @@ func (c *cImTenant) Status(ctx context.Context, req *imtenant.StatusReq) (res *i err = service.SysImTenant().Status(ctx, &req.ImTenantStatusInp) return } + +func (c *cImTenant) Usage(ctx context.Context, req *imtenant.UsageReq) (res *imtenant.UsageRes, err error) { + data, err := service.SysImTenant().Usage(ctx, &req.ImTenantUsageInp) + if err != nil { + return + } + + res = new(imtenant.UsageRes) + res.ImTenantUsageModel = data + return +} + +func (c *cImTenant) DeletionCheck(ctx context.Context, req *imtenant.DeletionCheckReq) (res *imtenant.DeletionCheckRes, err error) { + data, err := service.SysImTenant().DeletionCheck(ctx, &req.ImTenantDeletionCheckInp) + if err != nil { + return + } + + res = new(imtenant.DeletionCheckRes) + res.ImTenantDeletionCheckModel = data + return +} + +func (c *cImTenant) EnterDeleting(ctx context.Context, req *imtenant.EnterDeletingReq) (res *imtenant.EnterDeletingRes, err error) { + err = service.SysImTenant().EnterDeleting(ctx, &req.ImTenantLifecycleInp) + return +} + +func (c *cImTenant) Restore(ctx context.Context, req *imtenant.RestoreReq) (res *imtenant.RestoreRes, err error) { + err = service.SysImTenant().Restore(ctx, &req.ImTenantLifecycleInp) + return +} diff --git a/server/internal/controller/admin/sys/im_user.go b/server/internal/controller/admin/sys/im_user.go index 993d275..ce931ea 100644 --- a/server/internal/controller/admin/sys/im_user.go +++ b/server/internal/controller/admin/sys/im_user.go @@ -51,3 +51,29 @@ func (c *cImUser) ResetPassword(ctx context.Context, req *imuser.ResetPasswordRe err = service.SysImUser().ResetPassword(ctx, &req.ImUserPasswordResetInp) return } + +func (c *cImUser) RevokeSessions(ctx context.Context, req *imuser.RevokeSessionsReq) (res *imuser.RevokeSessionsRes, err error) { + err = service.SysImUser().RevokeSessions(ctx, &req.ImUserRevokeSessionsInp) + return +} + +func (c *cImUser) Status(ctx context.Context, req *imuser.StatusReq) (res *imuser.StatusRes, err error) { + err = service.SysImUser().Status(ctx, &req.ImUserStatusInp) + return +} + +func (c *cImUser) Devices(ctx context.Context, req *imuser.DevicesReq) (res *imuser.DevicesRes, err error) { + list, totalCount, err := service.SysImUser().Devices(ctx, &req.ImUserDeviceListInp) + if err != nil { + return + } + + if list == nil { + list = []*sysin.ImUserDeviceListModel{} + } + + res = new(imuser.DevicesRes) + res.List = list + res.PageRes.Pack(req, totalCount) + return +} diff --git a/server/internal/logic/sys/im_audit_log.go b/server/internal/logic/sys/im_audit_log.go index 943ef75..50b50a5 100644 --- a/server/internal/logic/sys/im_audit_log.go +++ b/server/internal/logic/sys/im_audit_log.go @@ -7,12 +7,18 @@ package sys import ( "context" + "fmt" "hotgo/internal/library/imtenant" + "hotgo/internal/model/input/form" "hotgo/internal/model/input/sysin" "hotgo/internal/service" + "hotgo/utility/convert" + "hotgo/utility/excel" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gctx" + "github.com/gogf/gf/v2/util/gconv" ) type sSysImAuditLog struct{} @@ -30,7 +36,11 @@ func (s *sSysImAuditLog) List(ctx context.Context, in *sysin.ImAuditLogListInp) if err = in.Filter(ctx); err != nil { return } - db, tenant, err := imtenant.DB(ctx, in.TenantId) + scope, err := resolveImAdminScope(ctx, in.TenantId) + if err != nil { + return + } + db, tenant, err := imtenant.DB(ctx, scope.TenantId) if err != nil { return } @@ -107,7 +117,11 @@ func (s *sSysImAuditLog) View(ctx context.Context, in *sysin.ImAuditLogViewInp) if err = in.Filter(ctx); err != nil { return } - db, tenant, err := imtenant.DB(ctx, in.TenantId) + scope, err := resolveImAdminScope(ctx, in.TenantId) + if err != nil { + return nil, err + } + db, tenant, err := imtenant.DB(ctx, scope.TenantId) if err != nil { return nil, err } @@ -123,3 +137,23 @@ func (s *sSysImAuditLog) View(ctx context.Context, in *sysin.ImAuditLogViewInp) res.TenantName = tenant.Name return } + +// Export 导出IM审计日志列表 +func (s *sSysImAuditLog) Export(ctx context.Context, in *sysin.ImAuditLogListInp) (err error) { + list, totalCount, err := s.List(ctx, in) + if err != nil { + return + } + tags, err := convert.GetEntityDescTags(sysin.ImAuditLogExportModel{}) + if err != nil { + return + } + + var exports []sysin.ImAuditLogExportModel + if err = gconv.Scan(list, &exports); err != nil { + return + } + fileName := "导出IM审计日志-" + gctx.CtxId(ctx) + sheetName := fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list)) + return excel.ExportByStructs(ctx, tags, exports, fileName, sheetName) +} diff --git a/server/internal/logic/sys/im_tenant.go b/server/internal/logic/sys/im_tenant.go index f9c8d02..e55308a 100644 --- a/server/internal/logic/sys/im_tenant.go +++ b/server/internal/logic/sys/im_tenant.go @@ -7,10 +7,13 @@ package sys import ( "context" + "fmt" + "hotgo/internal/consts" "hotgo/internal/dao" "hotgo/internal/library/contexts" "hotgo/internal/library/hgorm/handler" "hotgo/internal/library/hgorm/hook" + "hotgo/internal/library/imtenant" "hotgo/internal/model/entity" "hotgo/internal/model/input/sysin" "hotgo/internal/service" @@ -272,3 +275,137 @@ func (s *sSysImTenant) Status(ctx context.Context, in *sysin.ImTenantStatusInp) } return } + +func (s *sSysImTenant) Usage(ctx context.Context, in *sysin.ImTenantUsageInp) (res *sysin.ImTenantUsageModel, err error) { + if err = in.Filter(ctx); err != nil { + return + } + + var tenant *entity.ImTenant + if err = s.Model(ctx).WherePri(in.Id).Scan(&tenant); err != nil { + return nil, gerror.Wrap(err, "获取IM租户信息失败,请稍后重试!") + } + if tenant == nil || tenant.Id <= 0 { + return nil, gerror.New("IM租户不存在") + } + + res = &sysin.ImTenantUsageModel{ + Id: tenant.Id, + Code: tenant.Code, + Name: tenant.Name, + DbName: tenant.DbName, + DbDsnConfigured: tenant.DbDsn != "", + Warnings: []string{}, + } + + db, _, dbErr := imtenant.DB(ctx, tenant.Id) + if dbErr != nil { + res.DbReachable = false + res.DbCheckError = dbErr.Error() + return res, nil + } + if _, pingErr := db.GetValue(ctx, "SELECT 1"); pingErr != nil { + res.DbReachable = false + res.DbCheckError = pingErr.Error() + return res, nil + } + res.DbReachable = true + + res.SchemaVersion = s.queryScalarString(ctx, db, "kvmeta.version", "SELECT value FROM kvmeta WHERE key_='version' LIMIT 1", &res.Warnings) + res.UserCount = s.queryScalarInt64(ctx, db, "im_users.total", "SELECT COUNT(*) FROM im_users", &res.Warnings) + res.ActiveUserCount = s.queryScalarInt64(ctx, db, "im_users.active", "SELECT COUNT(*) FROM im_users WHERE state=0", &res.Warnings) + res.GroupCount = s.queryScalarInt64(ctx, db, "im_group_settings", "SELECT COUNT(*) FROM im_group_settings WHERE group_status<>'dissolved'", &res.Warnings) + res.DeviceCount = s.queryScalarInt64(ctx, db, "im_devices", "SELECT COUNT(*) FROM im_devices", &res.Warnings) + res.PushTokenCount = s.queryScalarInt64(ctx, db, "im_device_push_tokens", "SELECT COUNT(*) FROM im_device_push_tokens", &res.Warnings) + res.InviteUseCount = s.queryScalarInt64(ctx, db, "im_registration_invite_uses", "SELECT COUNT(*) FROM im_registration_invite_uses", &res.Warnings) + res.OutboxPendingCount = s.queryScalarInt64(ctx, db, "im_business_events_outbox", "SELECT COUNT(*) FROM im_business_events_outbox WHERE status='pending'", &res.Warnings) + return +} + +func (s *sSysImTenant) queryScalarInt64(ctx context.Context, db gdb.DB, label, sql string, warnings *[]string) int64 { + value, err := db.GetValue(ctx, sql) + if err != nil { + *warnings = append(*warnings, label+": "+err.Error()) + return 0 + } + return value.Int64() +} + +func (s *sSysImTenant) queryScalarString(ctx context.Context, db gdb.DB, label, sql string, warnings *[]string) string { + value, err := db.GetValue(ctx, sql) + if err != nil { + *warnings = append(*warnings, label+": "+err.Error()) + return "" + } + return value.String() +} + +func (s *sSysImTenant) DeletionCheck(ctx context.Context, in *sysin.ImTenantDeletionCheckInp) (res *sysin.ImTenantDeletionCheckModel, err error) { + if err = in.Filter(ctx); err != nil { + return + } + usage, err := s.Usage(ctx, &sysin.ImTenantUsageInp{Id: in.Id}) + if err != nil { + return nil, err + } + res = &sysin.ImTenantDeletionCheckModel{ + Id: usage.Id, + Code: usage.Code, + Name: usage.Name, + Blockers: []string{}, + Warnings: usage.Warnings, + UserCount: usage.UserCount, + GroupCount: usage.GroupCount, + PendingOutbox: usage.OutboxPendingCount, + } + if !usage.DbReachable { + res.Blockers = append(res.Blockers, "租户业务库不可达:"+usage.DbCheckError) + } + if usage.UserCount > 0 { + res.Blockers = append(res.Blockers, fmt.Sprintf("租户仍有 %d 个用户", usage.UserCount)) + } + if usage.GroupCount > 0 { + res.Blockers = append(res.Blockers, fmt.Sprintf("租户仍有 %d 个群", usage.GroupCount)) + } + if usage.OutboxPendingCount > 0 { + res.Blockers = append(res.Blockers, fmt.Sprintf("租户仍有 %d 条待处理 Outbox", usage.OutboxPendingCount)) + } + res.CanEnterDeleting = len(res.Blockers) == 0 + return +} + +func (s *sSysImTenant) EnterDeleting(ctx context.Context, in *sysin.ImTenantLifecycleInp) (err error) { + if err = in.Filter(ctx); err != nil { + return + } + check, err := s.DeletionCheck(ctx, &sysin.ImTenantDeletionCheckInp{Id: in.Id}) + if err != nil { + return err + } + if !check.CanEnterDeleting { + return gerror.New("租户未通过删除前检查,不能进入删除流程") + } + if _, err = s.Model(ctx).WherePri(in.Id).Data(g.Map{ + dao.ImTenant.Columns().State: consts.ImTenantStateDeleting, + dao.ImTenant.Columns().UpdatedBy: contexts.GetUserId(ctx), + }).Update(); err != nil { + return gerror.Wrap(err, "设置IM租户删除流程失败,请稍后重试!") + } + return +} + +func (s *sSysImTenant) Restore(ctx context.Context, in *sysin.ImTenantLifecycleInp) (err error) { + if err = in.Filter(ctx); err != nil { + return + } + if _, err = s.Model(ctx). + WherePri(in.Id). + WhereIn(dao.ImTenant.Columns().State, []int{consts.ImTenantStateSuspended, consts.ImTenantStateDeleting}). + Data(g.Map{ + dao.ImTenant.Columns().State: consts.ImTenantStateActive, + dao.ImTenant.Columns().UpdatedBy: contexts.GetUserId(ctx), + }).Update(); err != nil { + return gerror.Wrap(err, "恢复IM租户失败,请稍后重试!") + } + return +} diff --git a/server/internal/logic/sys/im_user.go b/server/internal/logic/sys/im_user.go index 924e525..30e2cf0 100644 --- a/server/internal/logic/sys/im_user.go +++ b/server/internal/logic/sys/im_user.go @@ -11,6 +11,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "hotgo/internal/consts" "hotgo/internal/library/imtenant" "hotgo/internal/model/input/sysin" "hotgo/internal/service" @@ -248,6 +249,213 @@ func (s *sSysImUser) ResetPassword(ctx context.Context, in *sysin.ImUserPassword return err } +func (s *sSysImUser) RevokeSessions(ctx context.Context, in *sysin.ImUserRevokeSessionsInp) (err error) { + if err = in.Filter(ctx); err != nil { + return + } + scope, err := resolveImAdminScope(ctx, in.TenantId) + if err != nil { + return err + } + userId, err := sysin.ParseOptionalInt64(in.UserId) + if err != nil { + return err + } + db, _, err := imtenant.DB(ctx, scope.TenantId) + if err != nil { + return err + } + err = revokeIMUserSessions(ctx, db, scope, userId, "security.sessions_revoked") + result := "success" + if err != nil { + result = "failed" + } + _ = writeImAdminAudit(ctx, scope.TenantId, "user_sessions_revoke", "user", userId, result, nil) + return err +} + +func (s *sSysImUser) Status(ctx context.Context, in *sysin.ImUserStatusInp) (err error) { + if err = in.Filter(ctx); err != nil { + return + } + if in.State != consts.ImUserStateOk && in.State != consts.ImUserStateSuspended { + return gerror.New("账号状态只能设置为正常或已停用") + } + scope, err := resolveImAdminScope(ctx, in.TenantId) + if err != nil { + return err + } + userId, err := sysin.ParseOptionalInt64(in.UserId) + if err != nil { + return err + } + db, _, err := imtenant.DB(ctx, scope.TenantId) + if err != nil { + return err + } + err = updateIMUserStatus(ctx, db, scope, userId, in.State) + result := "success" + if err != nil { + result = "failed" + } + _ = writeImAdminAudit(ctx, scope.TenantId, "user_status_update", "user", userId, result, map[string]any{"state": in.State}) + return err +} + +func (s *sSysImUser) Devices(ctx context.Context, in *sysin.ImUserDeviceListInp) (list []*sysin.ImUserDeviceListModel, totalCount int, err error) { + if err = in.Filter(ctx); err != nil { + return + } + scope, err := resolveImAdminScope(ctx, in.TenantId) + if err != nil { + return + } + userId, err := sysin.ParseOptionalInt64(in.UserId) + if err != nil { + return + } + db, tenant, err := imtenant.DB(ctx, scope.TenantId) + if err != nil { + return + } + + mod := db.Model("im_devices d").Safe().Ctx(ctx). + LeftJoin("im_device_push_tokens p", "p.user_id=d.userid AND p.device_id=d.deviceid"). + Fields( + "CAST(d.userid AS CHAR) user_id", + "d.deviceid device_id", + "COALESCE(d.platform, '') platform", + "COALESCE(d.lang, '') lang", + "d.lastseen last_seen", + "COALESCE(p.provider, '') push_provider", + "COALESCE(p.platform, '') push_platform", + "COALESCE(p.app_version, '') push_app_version", + "(p.id IS NOT NULL) push_token_configured", + "p.updated_at push_updated_at", + ). + Where("d.userid", userId). + Page(in.Page, in.PerPage). + OrderDesc("d.lastseen") + + if err = mod.ScanAndCount(&list, &totalCount, false); err != nil { + return nil, 0, gerror.Wrap(err, "获取IM用户设备列表失败,请稍后重试!") + } + for _, item := range list { + item.TenantId = tenant.Id + item.TenantName = tenant.Name + } + return +} + +func updateIMUserStatus(ctx context.Context, db gdb.DB, scope imAdminScope, userId int64, state int) error { + securityId, err := imtenant.NextSnowflakeID(ctx) + if err != nil { + return gerror.Wrap(err, "生成安全记录ID失败") + } + eventId, err := imtenant.NextSnowflakeID(ctx) + if err != nil { + return gerror.Wrap(err, "生成安全事件ID失败") + } + now := time.Now().UTC().Round(time.Millisecond) + requestId := scope.RequestId + if requestId == "" { + requestId = gctx.CtxId(ctx) + } + if requestId == "" { + requestId = guid.S() + } + eventKeyBytes := sha256.Sum256([]byte(fmt.Sprintf("user-status:%d:%d:%d:%s", scope.TenantId, userId, state, requestId))) + eventKey := hex.EncodeToString(eventKeyBytes[:]) + return db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { + current, txErr := tx.GetValue("SELECT state FROM im_users WHERE id=? LIMIT 1", userId) + if txErr != nil { + return txErr + } + if current.IsNil() { + return gerror.New("IM用户不存在") + } + if current.Int() == consts.ImUserStateDeleted { + return gerror.New("已删除账号不能变更状态") + } + if current.Int() == state { + return nil + } + if _, txErr = tx.Exec("UPDATE im_users SET state=?, updatedat=? WHERE id=?", state, now, userId); txErr != nil { + return txErr + } + if _, txErr = tx.Exec(`INSERT INTO im_user_security + (id,user_id,auth_version,created_at,updated_at) + VALUES(?,?,?,?,?) + ON DUPLICATE KEY UPDATE auth_version=auth_version+1,updated_at=VALUES(updated_at)`, + securityId, userId, 2, now, now); txErr != nil { + return txErr + } + version, txErr := tx.GetValue("SELECT auth_version FROM im_user_security WHERE user_id=?", userId) + if txErr != nil { + return txErr + } + payload, _ := json.Marshal(map[string]any{ + "user_id": userId, "operator_id": scope.OperatorId, "request_id": requestId, "state": state, "auth_version": version.Int(), + }) + _, txErr = tx.Exec(`INSERT INTO im_business_events_outbox + (id,event_id,target_type,target,actor_user_id,event_type,payload,status,created_at,updated_at) + VALUES(?,?,?,?,?,?,CAST(? AS JSON),'pending',?,?) + ON DUPLICATE KEY UPDATE event_id=VALUES(event_id)`, eventId, eventKey, "user", + fmt.Sprintf("%d", userId), 0, "security.user_status_changed", string(payload), now, now) + return txErr + }) +} + +func revokeIMUserSessions(ctx context.Context, db gdb.DB, scope imAdminScope, userId int64, eventType string) error { + securityId, err := imtenant.NextSnowflakeID(ctx) + if err != nil { + return gerror.Wrap(err, "生成安全记录ID失败") + } + eventId, err := imtenant.NextSnowflakeID(ctx) + if err != nil { + return gerror.Wrap(err, "生成安全事件ID失败") + } + now := time.Now().UTC().Round(time.Millisecond) + requestId := scope.RequestId + if requestId == "" { + requestId = gctx.CtxId(ctx) + } + if requestId == "" { + requestId = guid.S() + } + eventKeyBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%d:%d:%s", eventType, scope.TenantId, userId, requestId))) + eventKey := hex.EncodeToString(eventKeyBytes[:]) + return db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { + exists, txErr := tx.GetValue("SELECT EXISTS(SELECT 1 FROM im_users WHERE id=? LIMIT 1)", userId) + if txErr != nil { + return txErr + } + if !exists.Bool() { + return gerror.New("IM用户不存在") + } + if _, txErr = tx.Exec(`INSERT INTO im_user_security + (id,user_id,auth_version,created_at,updated_at) + VALUES(?,?,?,?,?) + ON DUPLICATE KEY UPDATE auth_version=auth_version+1,updated_at=VALUES(updated_at)`, + securityId, userId, 2, now, now); txErr != nil { + return txErr + } + version, txErr := tx.GetValue("SELECT auth_version FROM im_user_security WHERE user_id=?", userId) + if txErr != nil { + return txErr + } + payload, _ := json.Marshal(map[string]any{ + "user_id": userId, "operator_id": scope.OperatorId, "request_id": requestId, "auth_version": version.Int(), + }) + _, txErr = tx.Exec(`INSERT INTO im_business_events_outbox + (id,event_id,target_type,target,actor_user_id,event_type,payload,status,created_at,updated_at) + VALUES(?,?,?,?,?,?,CAST(? AS JSON),'pending',?,?) + ON DUPLICATE KEY UPDATE event_id=VALUES(event_id)`, eventId, eventKey, "user", + fmt.Sprintf("%d", userId), 0, eventType, string(payload), now, now) + return txErr + }) +} + func resetIMUserPassword(ctx context.Context, db gdb.DB, scope imAdminScope, userId int64, newPassword string) error { passwordHash, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost) if err != nil { diff --git a/server/internal/model/input/sysin/im_audit_log.go b/server/internal/model/input/sysin/im_audit_log.go index 3589a35..717c826 100644 --- a/server/internal/model/input/sysin/im_audit_log.go +++ b/server/internal/model/input/sysin/im_audit_log.go @@ -29,9 +29,6 @@ type ImAuditLogListInp struct { } func (in *ImAuditLogListInp) Filter(ctx context.Context) (err error) { - if in.TenantId <= 0 { - return gerror.New("请选择租户") - } return } @@ -61,9 +58,6 @@ type ImAuditLogViewInp struct { } func (in *ImAuditLogViewInp) Filter(ctx context.Context) (err error) { - if in.TenantId <= 0 { - return gerror.New("请选择租户") - } if in.Id <= 0 { return gerror.New("ID不能为空") } @@ -73,3 +67,18 @@ func (in *ImAuditLogViewInp) Filter(ctx context.Context) (err error) { type ImAuditLogViewModel struct { ImAuditLogListModel } + +type ImAuditLogExportModel struct { + Id int64 `json:"id" dc:"ID"` + TenantName string `json:"tenantName" dc:"租户名称"` + ActorUid int64 `json:"actorUid" dc:"操作人UID"` + ActorRole string `json:"actorRole" dc:"操作角色"` + Action string `json:"action" dc:"操作类型"` + TargetType string `json:"targetType" dc:"目标类型"` + TargetId string `json:"targetId" dc:"目标ID"` + Reason string `json:"reason" dc:"操作原因"` + RequestId string `json:"requestId" dc:"请求ID"` + Ip string `json:"ip" dc:"IP"` + UserAgent string `json:"userAgent" dc:"客户端"` + CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"` +} diff --git a/server/internal/model/input/sysin/im_tenant.go b/server/internal/model/input/sysin/im_tenant.go index 3b887f7..7bdd32d 100644 --- a/server/internal/model/input/sysin/im_tenant.go +++ b/server/internal/model/input/sysin/im_tenant.go @@ -155,3 +155,67 @@ func (in *ImTenantStatusInp) Filter(ctx context.Context) (err error) { } type ImTenantStatusModel struct{} + +type ImTenantUsageInp struct { + Id int64 `json:"id" v:"required#ID不能为空" dc:"ID"` +} + +func (in *ImTenantUsageInp) Filter(ctx context.Context) (err error) { + if in.Id <= 0 { + return gerror.New("ID不能为空") + } + return +} + +type ImTenantUsageModel struct { + Id int64 `json:"id" dc:"租户ID"` + Code string `json:"code" dc:"租户编码"` + Name string `json:"name" dc:"租户名称"` + DbName string `json:"dbName" dc:"业务库名"` + DbDsnConfigured bool `json:"dbDsnConfigured" dc:"是否配置独立连接串"` + DbReachable bool `json:"dbReachable" dc:"业务库是否可达"` + DbCheckError string `json:"dbCheckError" dc:"业务库检查错误"` + SchemaVersion string `json:"schemaVersion" dc:"Schema版本"` + UserCount int64 `json:"userCount" dc:"用户数"` + ActiveUserCount int64 `json:"activeUserCount" dc:"正常用户数"` + GroupCount int64 `json:"groupCount" dc:"群数"` + DeviceCount int64 `json:"deviceCount" dc:"设备数"` + PushTokenCount int64 `json:"pushTokenCount" dc:"Push Token数"` + InviteUseCount int64 `json:"inviteUseCount" dc:"邀请码使用次数"` + OutboxPendingCount int64 `json:"outboxPendingCount" dc:"待处理Outbox数"` + Warnings []string `json:"warnings" dc:"警告信息"` +} + +type ImTenantDeletionCheckInp struct { + Id int64 `json:"id" v:"required#ID不能为空" dc:"ID"` +} + +func (in *ImTenantDeletionCheckInp) Filter(ctx context.Context) (err error) { + if in.Id <= 0 { + return gerror.New("ID不能为空") + } + return +} + +type ImTenantDeletionCheckModel struct { + Id int64 `json:"id" dc:"租户ID"` + Code string `json:"code" dc:"租户编码"` + Name string `json:"name" dc:"租户名称"` + CanEnterDeleting bool `json:"canEnterDeleting" dc:"是否可进入删除流程"` + Blockers []string `json:"blockers" dc:"阻断原因"` + Warnings []string `json:"warnings" dc:"警告信息"` + UserCount int64 `json:"userCount" dc:"用户数"` + GroupCount int64 `json:"groupCount" dc:"群数"` + PendingOutbox int64 `json:"pendingOutbox" dc:"待处理Outbox"` +} + +type ImTenantLifecycleInp struct { + Id int64 `json:"id" v:"required#ID不能为空" dc:"ID"` +} + +func (in *ImTenantLifecycleInp) Filter(ctx context.Context) (err error) { + if in.Id <= 0 { + return gerror.New("ID不能为空") + } + return +} diff --git a/server/internal/model/input/sysin/im_user.go b/server/internal/model/input/sysin/im_user.go index a8c6b92..7a75886 100644 --- a/server/internal/model/input/sysin/im_user.go +++ b/server/internal/model/input/sysin/im_user.go @@ -87,6 +87,31 @@ func (in *ImUserPasswordResetInp) Filter(ctx context.Context) error { return nil } +type ImUserRevokeSessionsInp struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + UserId string `json:"userId" v:"required#用户ID不能为空" dc:"用户ID"` +} + +func (in *ImUserRevokeSessionsInp) Filter(ctx context.Context) error { + if _, err := ParseOptionalInt64(in.UserId); err != nil { + return err + } + return nil +} + +type ImUserStatusInp struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + UserId string `json:"userId" v:"required#用户ID不能为空" dc:"用户ID"` + State int `json:"state" dc:"账号状态"` +} + +func (in *ImUserStatusInp) Filter(ctx context.Context) error { + if _, err := ParseOptionalInt64(in.UserId); err != nil { + return err + } + return nil +} + type ImUserViewModel struct { ImUserListModel Signature string `json:"signature" dc:"个性签名"` @@ -97,3 +122,31 @@ type ImUserViewModel struct { AccessJson string `json:"accessJson" dc:"访问权限"` ProfileVersion int `json:"profileVersion" dc:"资料版本"` } + +type ImUserDeviceListInp struct { + form.PageReq + TenantId int64 `json:"tenantId" dc:"租户ID"` + UserId string `json:"userId" v:"required#用户ID不能为空" dc:"用户ID"` +} + +func (in *ImUserDeviceListInp) Filter(ctx context.Context) (err error) { + if _, err = ParseOptionalInt64(in.UserId); err != nil { + return gerror.New("用户ID不能为空") + } + return +} + +type ImUserDeviceListModel struct { + TenantId int64 `json:"tenantId" dc:"租户ID"` + TenantName string `json:"tenantName" dc:"租户名称"` + UserId string `json:"userId" dc:"用户ID"` + DeviceId string `json:"deviceId" dc:"设备ID"` + Platform string `json:"platform" dc:"平台"` + Lang string `json:"lang" dc:"语言"` + LastSeen *gtime.Time `json:"lastSeen" dc:"最后活跃时间"` + PushProvider string `json:"pushProvider" dc:"Push服务商"` + PushPlatform string `json:"pushPlatform" dc:"Push平台"` + PushAppVersion string `json:"pushAppVersion" dc:"App版本"` + PushTokenConfigured bool `json:"pushTokenConfigured" dc:"是否配置Push Token"` + PushUpdatedAt *gtime.Time `json:"pushUpdatedAt" dc:"Push更新时间"` +} diff --git a/server/internal/service/sys.go b/server/internal/service/sys.go index e8ace97..2f135ab 100644 --- a/server/internal/service/sys.go +++ b/server/internal/service/sys.go @@ -182,6 +182,14 @@ type ( View(ctx context.Context, in *sysin.ImTenantViewInp) (res *sysin.ImTenantViewModel, err error) // Status 更新IM租户状态 Status(ctx context.Context, in *sysin.ImTenantStatusInp) (err error) + // Usage 获取IM租户用量和健康状态 + Usage(ctx context.Context, in *sysin.ImTenantUsageInp) (res *sysin.ImTenantUsageModel, err error) + // DeletionCheck IM租户删除前检查 + DeletionCheck(ctx context.Context, in *sysin.ImTenantDeletionCheckInp) (res *sysin.ImTenantDeletionCheckModel, err error) + // EnterDeleting IM租户进入删除流程 + EnterDeleting(ctx context.Context, in *sysin.ImTenantLifecycleInp) (err error) + // Restore 恢复IM租户 + Restore(ctx context.Context, in *sysin.ImTenantLifecycleInp) (err error) } ISysImRegistration interface { // GetConfig 获取IM注册配置 @@ -212,6 +220,12 @@ type ( View(ctx context.Context, in *sysin.ImUserViewInp) (res *sysin.ImUserViewModel, err error) // ResetPassword 管理员重置IM用户密码 ResetPassword(ctx context.Context, in *sysin.ImUserPasswordResetInp) (err error) + // RevokeSessions 撤销IM用户会话 + RevokeSessions(ctx context.Context, in *sysin.ImUserRevokeSessionsInp) (err error) + // Status 更新IM用户状态 + Status(ctx context.Context, in *sysin.ImUserStatusInp) (err error) + // Devices 获取IM用户设备列表 + Devices(ctx context.Context, in *sysin.ImUserDeviceListInp) (list []*sysin.ImUserDeviceListModel, totalCount int, err error) } ISysImGroup interface { // List 获取IM群组列表 @@ -252,6 +266,8 @@ type ( ISysImAuditLog interface { // List 获取IM审计日志列表 List(ctx context.Context, in *sysin.ImAuditLogListInp) (list []*sysin.ImAuditLogListModel, totalCount int, err error) + // Export 导出IM审计日志列表 + Export(ctx context.Context, in *sysin.ImAuditLogListInp) (err error) // View 获取IM审计日志指定信息 View(ctx context.Context, in *sysin.ImAuditLogViewInp) (res *sysin.ImAuditLogViewModel, err error) } diff --git a/server/storage/data/generate/im_audit_log_menu.sql b/server/storage/data/generate/im_audit_log_menu.sql index c8be0e4..533c2c6 100644 --- a/server/storage/data/generate/im_audit_log_menu.sql +++ b/server/storage/data/generate/im_audit_log_menu.sql @@ -27,3 +27,7 @@ SELECT @auditListId := `id` FROM `hg_admin_menu` WHERE `name` = 'imAuditLogIndex INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) SELECT NULL, @auditListId, '审计详情', 'imAuditLogView', '', '', '3', '', '/imAuditLog/view', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @auditDirId, ' tr_', @auditListId, ' '), '10', '', '1', @now, @now WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imAuditLogView'); + +INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) +SELECT NULL, @auditListId, '导出审计日志', 'imAuditLogExport', '', '', '3', '', '/imAuditLog/export', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @auditDirId, ' tr_', @auditListId, ' '), '20', '', '1', @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imAuditLogExport'); diff --git a/server/storage/data/generate/im_tenant_menu.sql b/server/storage/data/generate/im_tenant_menu.sql index 835fed0..becfd21 100644 --- a/server/storage/data/generate/im_tenant_menu.sql +++ b/server/storage/data/generate/im_tenant_menu.sql @@ -35,3 +35,19 @@ WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantEdit'); INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) SELECT NULL, @tenantListId, '修改租户状态', 'imTenantStatus', '', '', '3', '', '/imTenant/status', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '30', '', '1', @now, @now WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantStatus'); + +INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) +SELECT NULL, @tenantListId, '租户用量与健康', 'imTenantUsage', '', '', '3', '', '/imTenant/usage', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '40', '', '1', @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantUsage'); + +INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) +SELECT NULL, @tenantListId, '租户删除前检查', 'imTenantDeletionCheck', '', '', '3', '', '/imTenant/deletionCheck', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '50', '', '1', @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantDeletionCheck'); + +INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) +SELECT NULL, @tenantListId, '租户进入删除流程', 'imTenantEnterDeleting', '', '', '3', '', '/imTenant/enterDeleting', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '60', '', '1', @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantEnterDeleting'); + +INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) +SELECT NULL, @tenantListId, '恢复租户', 'imTenantRestore', '', '', '3', '', '/imTenant/restore', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @tenantDirId, ' tr_', @tenantListId, ' '), '70', '', '1', @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imTenantRestore'); diff --git a/server/storage/data/generate/im_user_menu.sql b/server/storage/data/generate/im_user_menu.sql index d3ed726..4bf5e46 100644 --- a/server/storage/data/generate/im_user_menu.sql +++ b/server/storage/data/generate/im_user_menu.sql @@ -31,3 +31,15 @@ WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserView'); INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) SELECT NULL, @userListId, '重置用户密码', 'imUserResetPassword', '', '', '3', '', '/imUser/resetPassword', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '20', '', '1', @now, @now WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserResetPassword'); + +INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) +SELECT NULL, @userListId, '用户设备列表', 'imUserDevices', '', '', '3', '', '/imUser/devices', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '30', '', '1', @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserDevices'); + +INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) +SELECT NULL, @userListId, '撤销用户会话', 'imUserRevokeSessions', '', '', '3', '', '/imUser/revokeSessions', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '40', '', '1', @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserRevokeSessions'); + +INSERT INTO `hg_admin_menu` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) +SELECT NULL, @userListId, '更新用户状态', 'imUserStatus', '', '', '3', '', '/imUser/status', '', '', '1', '', '0', '0', '', '0', '1', '0', '4', CONCAT('tr_', @imRootId, ' tr_', @userDirId, ' tr_', @userListId, ' '), '50', '', '1', @now, @now +WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imUserStatus'); diff --git a/server/storage/data/im_registration_invite_hotgo.sql b/server/storage/data/im_registration_invite_hotgo.sql index 0eace16..6301bfc 100644 --- a/server/storage/data/im_registration_invite_hotgo.sql +++ b/server/storage/data/im_registration_invite_hotgo.sql @@ -139,6 +139,25 @@ WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imRegistrationInvite SET @invitePage := (SELECT id FROM hg_admin_menu WHERE name = 'imRegistrationInviteIndex' LIMIT 1); UPDATE hg_admin_menu SET tree = CONCAT('tr_', id, ' tr_', @imRoot, ' ') WHERE id = @invitePage; +SET @imTenantPage := (SELECT id FROM hg_admin_menu WHERE name = 'imTenantIndex' LIMIT 1); +INSERT INTO hg_admin_menu + (pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at) +SELECT @imTenantPage, 4, CONCAT('tr_', @imTenantPage, ' '), '租户用量与健康', 'imTenantUsage', '', '', 3, + '/imTenant/usage', '', 1, 40, 1, NOW(), NOW() +WHERE @imTenantPage IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imTenantUsage'); + +INSERT INTO hg_admin_menu + (pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at) +SELECT @imTenantPage, 4, CONCAT('tr_', @imTenantPage, ' '), title, name, '', '', 3, permissions, '', 1, sort, 1, NOW(), NOW() +FROM ( + SELECT '租户删除前检查' title, 'imTenantDeletionCheck' name, '/imTenant/deletionCheck' permissions, 50 sort UNION ALL + SELECT '租户进入删除流程', 'imTenantEnterDeleting', '/imTenant/enterDeleting', 60 UNION ALL + SELECT '恢复租户', 'imTenantRestore', '/imTenant/restore', 70 +) p +WHERE @imTenantPage IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM hg_admin_menu m WHERE m.name = p.name); + INSERT INTO hg_admin_menu (pid, level, tree, title, name, path, icon, type, permissions, component, sort, status, created_at, updated_at) SELECT @invitePage, 3, CONCAT('tr_', @invitePage, ' tr_', @imRoot, ' '), title, name, '', '', 3, permissions, '', sort, 1, NOW(), NOW() @@ -152,6 +171,17 @@ FROM ( ) p WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu m WHERE m.name = p.name); +SET @systemConfigPage := (SELECT id FROM hg_admin_menu WHERE name = 'system_config' LIMIT 1); +INSERT INTO hg_admin_menu + (pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at) +SELECT @systemConfigPage, 3, CONCAT('tr_', @systemConfigPage, ' '), title, name, '', '', 3, permissions, '', 1, sort, 1, NOW(), NOW() +FROM ( + SELECT '查看IM注册配置' title, 'imRegistrationConfigGet' name, '/imRegistration/config/get' permissions, 80 sort UNION ALL + SELECT '更新IM注册配置', 'imRegistrationConfigUpdate', '/imRegistration/config/update', 90 +) p +WHERE @systemConfigPage IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM hg_admin_menu m WHERE m.name = p.name); + SET @imUserPage := (SELECT id FROM hg_admin_menu WHERE name = 'imUserIndex' LIMIT 1); INSERT INTO hg_admin_menu (pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at) @@ -159,3 +189,24 @@ SELECT @imUserPage, 4, CONCAT('tr_', @imUserPage, ' '), '重置用户密码', 'i '/imUser/resetPassword', '', 1, 20, 1, NOW(), NOW() WHERE @imUserPage IS NOT NULL AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imUserResetPassword'); + +INSERT INTO hg_admin_menu + (pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at) +SELECT @imUserPage, 4, CONCAT('tr_', @imUserPage, ' '), '用户设备列表', 'imUserDevices', '', '', 3, + '/imUser/devices', '', 1, 30, 1, NOW(), NOW() +WHERE @imUserPage IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imUserDevices'); + +INSERT INTO hg_admin_menu + (pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at) +SELECT @imUserPage, 4, CONCAT('tr_', @imUserPage, ' '), '撤销用户会话', 'imUserRevokeSessions', '', '', 3, + '/imUser/revokeSessions', '', 1, 40, 1, NOW(), NOW() +WHERE @imUserPage IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imUserRevokeSessions'); + +INSERT INTO hg_admin_menu + (pid, level, tree, title, name, path, icon, type, permissions, component, hidden, sort, status, created_at, updated_at) +SELECT @imUserPage, 4, CONCAT('tr_', @imUserPage, ' '), '更新用户状态', 'imUserStatus', '', '', 3, + '/imUser/status', '', 1, 50, 1, NOW(), NOW() +WHERE @imUserPage IS NOT NULL + AND NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'imUserStatus'); diff --git a/web/src/api/imAuditLog/index.ts b/web/src/api/imAuditLog/index.ts index 52bdfc8..1e43cba 100644 --- a/web/src/api/imAuditLog/index.ts +++ b/web/src/api/imAuditLog/index.ts @@ -1,4 +1,4 @@ -import { http } from '@/utils/http/axios'; +import { http, jumpExport } from '@/utils/http/axios'; // 获取IM审计日志列表 export function List(params) { @@ -17,3 +17,8 @@ export function View(params) { params, }); } + +// 导出IM审计日志 +export function Export(params) { + jumpExport('/imAuditLog/export', params); +} diff --git a/web/src/api/imTenant/index.ts b/web/src/api/imTenant/index.ts index bab11ec..4007456 100644 --- a/web/src/api/imTenant/index.ts +++ b/web/src/api/imTenant/index.ts @@ -35,3 +35,36 @@ export function View(params) { params, }); } + +// 获取IM租户用量和健康状态 +export function Usage(params) { + return http.request({ + url: '/imTenant/usage', + method: 'GET', + params, + }); +} + +export function DeletionCheck(params) { + return http.request({ + url: '/imTenant/deletionCheck', + method: 'GET', + params, + }); +} + +export function EnterDeleting(params) { + return http.request({ + url: '/imTenant/enterDeleting', + method: 'POST', + params, + }); +} + +export function Restore(params) { + return http.request({ + url: '/imTenant/restore', + method: 'POST', + params, + }); +} diff --git a/web/src/api/imUser/index.ts b/web/src/api/imUser/index.ts index 443d32a..e874962 100644 --- a/web/src/api/imUser/index.ts +++ b/web/src/api/imUser/index.ts @@ -26,3 +26,30 @@ export function ResetPassword(params) { params, }); } + +// 撤销IM用户会话 +export function RevokeSessions(params) { + return http.request({ + url: '/imUser/revokeSessions', + method: 'POST', + params, + }); +} + +// 更新IM用户状态 +export function Status(params) { + return http.request({ + url: '/imUser/status', + method: 'POST', + params, + }); +} + +// 获取IM用户设备列表 +export function Devices(params) { + return http.request({ + url: '/imUser/devices', + method: 'GET', + params, + }); +} diff --git a/web/src/views/im/registrationInvite/index.vue b/web/src/views/im/registrationInvite/index.vue index 9bef541..4fe11c2 100644 --- a/web/src/views/im/registrationInvite/index.vue +++ b/web/src/views/im/registrationInvite/index.vue @@ -1,7 +1,7 @@