diff --git a/.gitignore b/.gitignore index 8c87e52..1d3f01a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/ +logs/ dist/ .env .env.local diff --git a/backend/src/app.ts b/backend/src/app.ts index 6676cc1..dafccdd 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -7,7 +7,7 @@ import { DatabaseService } from "./services/DatabaseService"; import { setupMiddlewares } from "./middleware"; import routes from "./routes/api"; import { logger } from "./utils/logger"; - +import { errorHandler } from "./middleware/errorHandler"; class App { private app = express(); private databaseService = container.get(TYPES.DatabaseService); @@ -22,6 +22,8 @@ class App { // 设置路由 this.app.use("/", routes); + // 设置错误处理中间件 + this.app.use(errorHandler); } public async start(): Promise { diff --git a/backend/src/controllers/BaseController.ts b/backend/src/controllers/BaseController.ts index af3fbb9..b40cbdf 100644 --- a/backend/src/controllers/BaseController.ts +++ b/backend/src/controllers/BaseController.ts @@ -1,17 +1,22 @@ import { Request, Response } from "express"; import { ApiResponse } from "../core/ApiResponse"; +interface ApiResponseData { + data?: T; + message?: string; +} export abstract class BaseController { protected async handleRequest( req: Request, res: Response, - action: () => Promise + action: () => Promise> ): Promise { try { const result = await action(); - res.json(ApiResponse.success(result)); - } catch (error: any) { - res.status(500).json(ApiResponse.error(error?.message || "未知错误")); + res.json(ApiResponse.success(result.data, result.message)); + } catch (error: unknown) { + const errorMessage = error instanceof Error ? error.message : "未知错误"; + res.status(200).json(ApiResponse.error(errorMessage)); } } } diff --git a/backend/src/controllers/cloud115.ts b/backend/src/controllers/cloud115.ts index e63c356..7ff5c14 100644 --- a/backend/src/controllers/cloud115.ts +++ b/backend/src/controllers/cloud115.ts @@ -1,24 +1,9 @@ import { Request, Response } from "express"; import { Cloud115Service } from "../services/Cloud115Service"; -import { sendSuccess, sendError } from "../utils/response"; -import UserSetting from "../models/UserSetting"; import { BaseController } from "./BaseController"; import { injectable, inject } from "inversify"; import { TYPES } from "../core/types"; -const cloud115 = new Cloud115Service(); -const setCookie = async (req: Request): Promise => { - const userId = req.user?.userId; - const userSetting = await UserSetting.findOne({ - where: { userId }, - }); - if (userSetting && userSetting.dataValues.cloud115Cookie) { - cloud115.setCookie(userSetting.dataValues.cloud115Cookie); - } else { - throw new Error("请先设置115网盘cookie"); - } -}; - @injectable() export class Cloud115Controller extends BaseController { constructor(@inject(TYPES.Cloud115Service) private cloud115Service: Cloud115Service) { @@ -34,31 +19,23 @@ export class Cloud115Controller extends BaseController { } async getFolderList(req: Request, res: Response): Promise { - try { + await this.handleRequest(req, res, async () => { const { parentCid } = req.query; - await setCookie(req); - const result = await cloud115.getFolderList(parentCid as string); - sendSuccess(res, result); - } catch (error) { - sendError(res, { message: (error as Error).message || "获取目录列表失败" }); - } + await this.cloud115Service.setCookie(req); + return await this.cloud115Service.getFolderList(parentCid as string); + }); } async saveFile(req: Request, res: Response): Promise { - try { + await this.handleRequest(req, res, async () => { const { shareCode, receiveCode, fileId, folderId } = req.body; - await setCookie(req); - const result = await cloud115.saveSharedFile({ + await this.cloud115Service.setCookie(req); + return await this.cloud115Service.saveSharedFile({ shareCode, receiveCode, fileId, cid: folderId, }); - sendSuccess(res, result); - } catch (error) { - sendError(res, { message: (error as Error).message || "保存文件失败" }); - } + }); } } - -export const Cloud115ServiceInstance = cloud115; diff --git a/backend/src/controllers/quark.ts b/backend/src/controllers/quark.ts index afa390e..ec57fa0 100644 --- a/backend/src/controllers/quark.ts +++ b/backend/src/controllers/quark.ts @@ -3,7 +3,6 @@ import { injectable, inject } from "inversify"; import { TYPES } from "../core/types"; import { QuarkService } from "../services/QuarkService"; import { BaseController } from "./BaseController"; -import { sendSuccess } from "../utils/response"; @injectable() export class QuarkController extends BaseController { @@ -15,11 +14,7 @@ export class QuarkController extends BaseController { await this.handleRequest(req, res, async () => { const { shareCode, receiveCode } = req.query; await this.quarkService.setCookie(req); - const result = await this.quarkService.getShareInfo( - shareCode as string, - receiveCode as string - ); - sendSuccess(res, result); + return await this.quarkService.getShareInfo(shareCode as string, receiveCode as string); }); } @@ -27,16 +22,14 @@ export class QuarkController extends BaseController { await this.handleRequest(req, res, async () => { const { parentCid } = req.query; await this.quarkService.setCookie(req); - const result = await this.quarkService.getFolderList(parentCid as string); - sendSuccess(res, result); + return await this.quarkService.getFolderList(parentCid as string); }); } async saveFile(req: Request, res: Response): Promise { await this.handleRequest(req, res, async () => { await this.quarkService.setCookie(req); - const result = await this.quarkService.saveSharedFile(req.body); - sendSuccess(res, result); + return await this.quarkService.saveSharedFile(req.body); }); } } diff --git a/backend/src/controllers/resource.ts b/backend/src/controllers/resource.ts index c8635a0..59faeed 100644 --- a/backend/src/controllers/resource.ts +++ b/backend/src/controllers/resource.ts @@ -3,7 +3,6 @@ import { injectable, inject } from "inversify"; import { TYPES } from "../core/types"; import { Searcher } from "../services/Searcher"; import { BaseController } from "./BaseController"; -import { sendSuccess } from "../utils/response"; @injectable() export class ResourceController extends BaseController { @@ -14,12 +13,11 @@ export class ResourceController extends BaseController { async search(req: Request, res: Response): Promise { await this.handleRequest(req, res, async () => { const { keyword, channelId = "", lastMessageId = "" } = req.query; - const result = await this.searcher.searchAll( + return await this.searcher.searchAll( keyword as string, channelId as string, lastMessageId as string ); - sendSuccess(res, result); }); } } diff --git a/backend/src/controllers/setting.ts b/backend/src/controllers/setting.ts index f41b642..722a00d 100644 --- a/backend/src/controllers/setting.ts +++ b/backend/src/controllers/setting.ts @@ -12,7 +12,7 @@ export class SettingController extends BaseController { async get(req: Request, res: Response): Promise { await this.handleRequest(req, res, async () => { - const userId = Number(req.user?.userId); + const userId = req.user?.userId; const role = Number(req.user?.role); return await this.settingService.getSettings(userId, role); }); @@ -20,7 +20,7 @@ export class SettingController extends BaseController { async save(req: Request, res: Response): Promise { await this.handleRequest(req, res, async () => { - const userId = Number(req.user?.userId); + const userId = req.user?.userId; const role = Number(req.user?.role); return await this.settingService.saveSettings(userId, role, req.body); }); diff --git a/backend/src/controllers/user.ts b/backend/src/controllers/user.ts index 27bf0a5..f2ca4f3 100644 --- a/backend/src/controllers/user.ts +++ b/backend/src/controllers/user.ts @@ -12,8 +12,8 @@ export class UserController extends BaseController { async register(req: Request, res: Response): Promise { await this.handleRequest(req, res, async () => { - const { username, password, code } = req.body; - return await this.userService.register(username, password, code); + const { username, password, registerCode } = req.body; + return await this.userService.register(username, password, registerCode); }); } diff --git a/backend/src/core/ApiResponse.ts b/backend/src/core/ApiResponse.ts index a8d2c63..8bd467f 100644 --- a/backend/src/core/ApiResponse.ts +++ b/backend/src/core/ApiResponse.ts @@ -12,10 +12,10 @@ export class ApiResponse { } static success(data?: T, message = "操作成功"): ApiResponse { - return new ApiResponse(true, 200, data, message); + return new ApiResponse(true, 0, data, message); } - static error(message: string, code = 500): ApiResponse { + static error(message: string, code = 10000): ApiResponse { return new ApiResponse(false, code, null, message); } } diff --git a/backend/src/inversify.config.ts b/backend/src/inversify.config.ts index 41e6368..57db955 100644 --- a/backend/src/inversify.config.ts +++ b/backend/src/inversify.config.ts @@ -8,6 +8,8 @@ import { QuarkService } from "./services/QuarkService"; import { Searcher } from "./services/Searcher"; import { DoubanService } from "./services/DoubanService"; import { UserService } from "./services/UserService"; +import { ImageService } from "./services/ImageService"; +import { SettingService } from "./services/SettingService"; // Controllers import { Cloud115Controller } from "./controllers/cloud115"; @@ -25,6 +27,8 @@ container.bind(TYPES.DatabaseService).to(DatabaseService).inSin container.bind(TYPES.Cloud115Service).to(Cloud115Service).inSingletonScope(); container.bind(TYPES.QuarkService).to(QuarkService).inSingletonScope(); container.bind(TYPES.Searcher).to(Searcher).inSingletonScope(); +container.bind(TYPES.ImageService).to(ImageService).inSingletonScope(); +container.bind(TYPES.SettingService).to(SettingService).inSingletonScope(); container.bind(TYPES.DoubanService).to(DoubanService).inSingletonScope(); container.bind(TYPES.UserService).to(UserService).inSingletonScope(); diff --git a/backend/src/middleware/auth.ts b/backend/src/middleware/auth.ts index 6a41518..0511ef7 100644 --- a/backend/src/middleware/auth.ts +++ b/backend/src/middleware/auth.ts @@ -16,7 +16,8 @@ export const authMiddleware = async ( res: Response, next: NextFunction ): Promise => { - if (req.path === "/user/login" || req.path === "/user/register") { + console.log(req.path); + if (req.path === "/user/login" || req.path === "/user/register" || req.path === "/tele-images/") { return next(); } diff --git a/backend/src/middleware/errorHandler.ts b/backend/src/middleware/errorHandler.ts index c7ec51e..d7efa7b 100644 --- a/backend/src/middleware/errorHandler.ts +++ b/backend/src/middleware/errorHandler.ts @@ -5,7 +5,6 @@ interface CustomError extends Error { } export const errorHandler = (err: CustomError, req: Request, res: Response): void => { - console.error(err); res.status(err.status || 500).json({ success: false, error: err.message || "服务器内部错误", diff --git a/backend/src/middleware/index.ts b/backend/src/middleware/index.ts index ca06926..2bda0be 100644 --- a/backend/src/middleware/index.ts +++ b/backend/src/middleware/index.ts @@ -1,14 +1,14 @@ import { Application } from "express"; -import { errorHandler } from "./errorHandler"; +import express from "express"; import { authMiddleware } from "./auth"; import { requestLogger } from "./requestLogger"; import { rateLimiter } from "./rateLimiter"; import { cors } from "./cors"; export const setupMiddlewares = (app: Application) => { + app.use(express.json()); app.use(cors()); app.use(requestLogger()); app.use(rateLimiter()); app.use(authMiddleware); - app.use(errorHandler); }; diff --git a/backend/src/middleware/rateLimiter.ts b/backend/src/middleware/rateLimiter.ts index 27f742d..da8be8e 100644 --- a/backend/src/middleware/rateLimiter.ts +++ b/backend/src/middleware/rateLimiter.ts @@ -2,7 +2,7 @@ import { Request, Response, NextFunction } from "express"; const requestCounts = new Map(); const WINDOW_MS = 60 * 1000; // 1分钟窗口 -const MAX_REQUESTS = 60; // 每个IP每分钟最多60个请求 +const MAX_REQUESTS = 600; // 每个IP每分钟最多60个请求 export const rateLimiter = () => { return (req: Request, res: Response, next: NextFunction) => { diff --git a/backend/src/services/Cloud115Service.ts b/backend/src/services/Cloud115Service.ts index 89ceff9..53a06c8 100644 --- a/backend/src/services/Cloud115Service.ts +++ b/backend/src/services/Cloud115Service.ts @@ -5,7 +5,7 @@ import { injectable } from "inversify"; import { Request } from "express"; import UserSetting from "../models/UserSetting"; import { ICloudService } from "../types/services"; -import { logger } from "@/utils/logger"; +import { logger } from "../utils/logger"; interface Cloud115ListItem { cid: string; diff --git a/backend/src/services/Searcher.ts b/backend/src/services/Searcher.ts index cd39921..e99aa67 100644 --- a/backend/src/services/Searcher.ts +++ b/backend/src/services/Searcher.ts @@ -24,7 +24,7 @@ interface sourceItem { @injectable() export class Searcher { private static instance: Searcher; - private api: AxiosInstance; + private api: AxiosInstance | null = null; constructor() { this.initAxiosInstance(); diff --git a/backend/src/services/SettingService.ts b/backend/src/services/SettingService.ts index b1f9cb9..a30e1e8 100644 --- a/backend/src/services/SettingService.ts +++ b/backend/src/services/SettingService.ts @@ -5,7 +5,7 @@ import { Searcher } from "./Searcher"; @injectable() export class SettingService { - async getSettings(userId: number | undefined, role: number | undefined) { + async getSettings(userId: string | undefined, role: number | undefined) { if (!userId) { throw new Error("用户ID无效"); } @@ -28,7 +28,7 @@ export class SettingService { }; } - async saveSettings(userId: number | undefined, role: number | undefined, settings: any) { + async saveSettings(userId: string | undefined, role: number | undefined, settings: any) { if (!userId) { throw new Error("用户ID无效"); } diff --git a/backend/src/services/UserService.ts b/backend/src/services/UserService.ts index fdb9989..06c0eb5 100644 --- a/backend/src/services/UserService.ts +++ b/backend/src/services/UserService.ts @@ -19,7 +19,6 @@ export class UserService { globalSetting?.dataValues.CommonUserCode, globalSetting?.dataValues.AdminUserCode, ]; - if (!registerCode || !registerCodeList.includes(Number(registerCode))) { throw new Error("注册码错误"); } diff --git a/backend/src/utils/logger.ts b/backend/src/utils/logger.ts index 9923eb7..1770bdd 100644 --- a/backend/src/utils/logger.ts +++ b/backend/src/utils/logger.ts @@ -1,8 +1,8 @@ import winston from "winston"; -import { Config } from "../config"; +import { config } from "../config"; const logger = winston.createLogger({ - level: Config.app.env === "development" ? "debug" : "info", + level: config.app.env === "development" ? "debug" : "info", format: winston.format.combine(winston.format.timestamp(), winston.format.json()), transports: [ new winston.transports.File({ filename: "logs/error.log", level: "error" }), @@ -10,7 +10,7 @@ const logger = winston.createLogger({ ], }); -if (Config.app.env !== "production") { +if (config.app.env !== "production") { logger.add( new winston.transports.Console({ format: winston.format.simple(), diff --git a/frontend/src/api/quark.ts b/frontend/src/api/quark.ts index 68bebb5..2e7bb52 100644 --- a/frontend/src/api/quark.ts +++ b/frontend/src/api/quark.ts @@ -2,9 +2,9 @@ import request from "@/utils/request"; import type { ShareInfoResponse, Folder, SaveQuarkFileParams } from "@/types"; export const quarkApi = { - async getShareInfo(pwdId: string, passcode = "") { + async getShareInfo(shareCode: string, receiveCode = "") { const { data } = await request.get("/api/quark/share-info", { - params: { pwdId, passcode }, + params: { shareCode, receiveCode }, }); return data as ShareInfoResponse; }, diff --git a/frontend/src/stores/resource.ts b/frontend/src/stores/resource.ts index 4c5df53..c7b0ee9 100644 --- a/frontend/src/stores/resource.ts +++ b/frontend/src/stores/resource.ts @@ -42,7 +42,7 @@ interface CloudDriveConfig< // 云盘类型配置 export const CLOUD_DRIVES: [ CloudDriveConfig<{ shareCode: string; receiveCode: string }, Save115FileParams>, - CloudDriveConfig<{ pwdId: string }, SaveQuarkFileParams>, + CloudDriveConfig<{ shareCode: string }, SaveQuarkFileParams>, ] = [ { name: "115网盘", @@ -71,19 +71,20 @@ export const CLOUD_DRIVES: [ type: "quark", regex: /pan\.quark\.cn\/s\/([a-zA-Z0-9]+)/, api: { - getShareInfo: (parsedCode: { pwdId: string }) => quarkApi.getShareInfo(parsedCode.pwdId), + getShareInfo: (parsedCode: { shareCode: string }) => + quarkApi.getShareInfo(parsedCode.shareCode), saveFile: async (params: SaveQuarkFileParams) => { return await quarkApi.saveFile(params as SaveQuarkFileParams); }, }, - parseShareCode: (match: RegExpMatchArray) => ({ pwdId: match[1] }), + parseShareCode: (match: RegExpMatchArray) => ({ shareCode: match[1] }), getSaveParams: (shareInfo: ShareInfoResponse, folderId: string) => ({ fid_list: shareInfo.list.map((item: { fileId?: string }) => item.fileId || ""), fid_token_list: shareInfo.list.map( (item: { fileIdToken?: string }) => item.fileIdToken || "" ), to_pdir_fid: folderId, - pwd_id: shareInfo.pwdId || "", + pwd_id: shareInfo.shareCode || "", stoken: shareInfo.stoken || "", pdir_fid: "0", scene: "link", @@ -190,7 +191,7 @@ export const useResourceStore = defineStore("resource", { folderId: string, drive: | CloudDriveConfig<{ shareCode: string; receiveCode: string }, Save115FileParams> - | CloudDriveConfig<{ pwdId: string }, SaveQuarkFileParams> + | CloudDriveConfig<{ shareCode: string }, SaveQuarkFileParams> ): Promise { const link = resource.cloudLinks.find((link) => drive.regex.test(link)); if (!link) return; @@ -240,7 +241,7 @@ export const useResourceStore = defineStore("resource", { ? await matchedDrive.api.getShareInfo( parsedCode as { shareCode: string; receiveCode: string } ) - : await matchedDrive.api.getShareInfo(parsedCode as { pwdId: string }); + : await matchedDrive.api.getShareInfo(parsedCode as { shareCode: string }); if (Array.isArray(shareInfo)) { shareInfo = { @@ -304,7 +305,7 @@ export const useResourceStore = defineStore("resource", { } else { shareInfo = this.is115Drive(drive) ? await drive.api.getShareInfo(parsedCode as { shareCode: string; receiveCode: string }) - : await drive.api.getShareInfo(parsedCode as { pwdId: string }); + : await drive.api.getShareInfo(parsedCode as { shareCode: string }); } this.setLoadTree(false); if (shareInfo) { @@ -337,7 +338,7 @@ export const useResourceStore = defineStore("resource", { is115Drive( drive: | CloudDriveConfig<{ shareCode: string; receiveCode: string }, Save115FileParams> - | CloudDriveConfig<{ pwdId: string }, SaveQuarkFileParams> + | CloudDriveConfig<{ shareCode: string }, SaveQuarkFileParams> ): drive is CloudDriveConfig<{ shareCode: string; receiveCode: string }, Save115FileParams> { return drive.type === "pan115"; }, diff --git a/package-lock.json b/package-lock.json index 4d4e2b5..8d1ebe6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cloud-saver", - "version": "0.2.2", + "version": "0.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cloud-saver", - "version": "0.2.2", + "version": "0.2.3", "workspaces": [ "frontend", "backend" @@ -38,12 +38,14 @@ "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.18.3", + "inversify": "^7.1.0", "jsonwebtoken": "^9.0.2", "rss-parser": "^3.13.0", "sequelize": "^6.37.5", "socket.io": "^4.8.1", "sqlite3": "^5.1.7", - "tunnel": "^0.0.6" + "tunnel": "^0.0.6", + "winston": "^3.17.0" }, "devDependencies": { "@types/bcrypt": "^5.0.2", @@ -1718,6 +1720,15 @@ "node": ">=6.9.0" } }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -1740,6 +1751,17 @@ "node": ">=10" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "license": "MIT", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@element-plus/icons-vue": { "version": "2.3.1", "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz", @@ -2321,6 +2343,55 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@inversifyjs/common": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@inversifyjs/common/-/common-1.5.0.tgz", + "integrity": "sha512-Qj5BELk11AfI2rgZEAaLPmOftmQRLLmoCXgAjmaF0IngQN5vHomVT5ML7DZ3+CA5fgGcEVMcGbUDAun+Rz+oNg==", + "license": "MIT" + }, + "node_modules/@inversifyjs/container": { + "version": "1.5.4", + "resolved": "https://registry.npmmirror.com/@inversifyjs/container/-/container-1.5.4.tgz", + "integrity": "sha512-mHAaWjAQb8m6TJksm5EJXW/kPcZFVEc1UKkWv5OnLbwbU0QvxM2UbEsuXzusGVHcrNY4TQp9Uh2wkRY6TN2WJg==", + "license": "MIT", + "dependencies": { + "@inversifyjs/common": "1.5.0", + "@inversifyjs/core": "5.0.0", + "@inversifyjs/reflect-metadata-utils": "1.1.0" + }, + "peerDependencies": { + "reflect-metadata": "~0.2.2" + } + }, + "node_modules/@inversifyjs/core": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/@inversifyjs/core/-/core-5.0.0.tgz", + "integrity": "sha512-axOl+VZFGVA3nAMbs6RuHhQ8HvgO6/tKjlWJk4Nt0rUqed+1ksak4p5yZNtown1Kdm0GV2Oc57qLqqWd943hgA==", + "license": "MIT", + "dependencies": { + "@inversifyjs/common": "1.5.0", + "@inversifyjs/prototype-utils": "0.1.0", + "@inversifyjs/reflect-metadata-utils": "1.1.0" + } + }, + "node_modules/@inversifyjs/prototype-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/@inversifyjs/prototype-utils/-/prototype-utils-0.1.0.tgz", + "integrity": "sha512-lNz1yyajMRDXBHLvJsYYX81FcmeD15e5Qz1zAZ/3zeYTl+u7ZF/GxNRKJzNOloeMPMtuR8BnvzHA1SZxjR+J9w==", + "license": "MIT", + "dependencies": { + "@inversifyjs/common": "1.5.0" + } + }, + "node_modules/@inversifyjs/reflect-metadata-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@inversifyjs/reflect-metadata-utils/-/reflect-metadata-utils-1.1.0.tgz", + "integrity": "sha512-jmuAuC3eL1GnFAYfJGJOMKRDL9q1mgzOyrban6zxfM8Yg1FUHsj25h27bW2G7p8X1Amvhg3MLkaOuogszkrofA==", + "license": "MIT", + "peerDependencies": { + "reflect-metadata": "0.2.2" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -3634,6 +3705,12 @@ "@types/send": "*" } }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmmirror.com/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "license": "MIT" + }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -4356,7 +4433,6 @@ "version": "3.2.6", "resolved": "https://registry.npmmirror.com/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, "license": "MIT" }, "node_modules/async-function": { @@ -5033,6 +5109,16 @@ "resolved": "frontend", "link": true }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", @@ -5050,9 +5136,18 @@ "version": "1.1.4", "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmmirror.com/color-support/-/color-support-1.1.3.tgz", @@ -5062,6 +5157,31 @@ "color-support": "bin.js" } }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "license": "MIT", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5677,6 +5797,12 @@ "dev": true, "license": "MIT" }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", + "license": "MIT" + }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz", @@ -6458,6 +6584,12 @@ "reusify": "^1.0.4" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -6648,6 +6780,12 @@ "dev": true, "license": "ISC" }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", + "license": "MIT" + }, "node_modules/follow-redirects": { "version": "1.15.9", "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz", @@ -7428,6 +7566,20 @@ "node": ">= 0.4" } }, + "node_modules/inversify": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/inversify/-/inversify-7.1.0.tgz", + "integrity": "sha512-f8SlUTgecMZGr/rsFK36PD84/mH0+sp0/P/TuiGo3CcJywmF5kgoXeE2RW5IjaIt1SlqS5c5V9RuQc1+B8mw4Q==", + "license": "MIT", + "dependencies": { + "@inversifyjs/common": "1.5.0", + "@inversifyjs/container": "1.5.4", + "@inversifyjs/core": "5.0.0" + }, + "peerDependencies": { + "reflect-metadata": "~0.2.2" + } + }, "node_modules/ip-address": { "version": "9.0.5", "resolved": "https://registry.npmmirror.com/ip-address/-/ip-address-9.0.5.tgz", @@ -7809,7 +7961,6 @@ "version": "2.0.1", "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -8152,6 +8303,12 @@ "json-buffer": "3.0.1" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "license": "MIT" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz", @@ -8311,6 +8468,23 @@ "dev": true, "license": "MIT" }, + "node_modules/logform": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "license": "MIT", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz", @@ -9483,6 +9657,15 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "license": "MIT", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz", @@ -10197,6 +10380,13 @@ "node": ">=8.10.0" } }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0", + "peer": true + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -10570,6 +10760,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -11023,6 +11222,21 @@ "simple-concat": "^1.0.0" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -11397,6 +11611,15 @@ "node": ">=8" } }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmmirror.com/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", @@ -11842,6 +12065,12 @@ "node": ">=10" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", + "license": "MIT" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz", @@ -11938,6 +12167,15 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ts-api-utils": { "version": "1.4.3", "resolved": "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz", @@ -12999,6 +13237,42 @@ "node": ">=8" } }, + "node_modules/winston": { + "version": "3.17.0", + "resolved": "https://registry.npmmirror.com/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "license": "MIT", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.7.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.9.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.9.0", + "resolved": "https://registry.npmmirror.com/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "license": "MIT", + "dependencies": { + "logform": "^2.7.0", + "readable-stream": "^3.6.2", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/wkx": { "version": "0.5.0", "resolved": "https://registry.npmmirror.com/wkx/-/wkx-0.5.0.tgz",