From dd9b2252b701ffe97e6d365364448a2901210985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Thu, 22 Jan 2026 17:35:54 +0800 Subject: [PATCH] Refactor type annotations and router initialization Standardized type annotations for interfaces in user.ts and improved type safety in webapi.ts. Updated all Express router initializations to explicitly declare the Router type. Added missing RequestHandler typings in uploader modules for better type checking. --- packages/napcat-core/apis/webapi.ts | 186 +++++++++--------- packages/napcat-core/types/user.ts | 26 +-- .../napcat-webui-backend/src/api/Debug.ts | 2 +- .../napcat-webui-backend/src/router/Base.ts | 2 +- .../napcat-webui-backend/src/router/File.ts | 2 +- .../napcat-webui-backend/src/router/Log.ts | 2 +- .../src/router/OB11Config.ts | 2 +- .../napcat-webui-backend/src/router/Plugin.ts | 2 +- .../src/router/Process.ts | 2 +- .../src/router/QQLogin.ts | 2 +- .../src/router/UpdateNapCat.ts | 2 +- .../src/router/WebUIConfig.ts | 2 +- .../napcat-webui-backend/src/router/auth.ts | 2 +- .../napcat-webui-backend/src/router/index.ts | 2 +- .../napcat-webui-backend/src/uploader/disk.ts | 4 +- .../src/uploader/webui_font.ts | 4 +- 16 files changed, 123 insertions(+), 121 deletions(-) diff --git a/packages/napcat-core/apis/webapi.ts b/packages/napcat-core/apis/webapi.ts index 0de0d5a0..ddf74a56 100644 --- a/packages/napcat-core/apis/webapi.ts +++ b/packages/napcat-core/apis/webapi.ts @@ -13,6 +13,17 @@ import { createHash } from 'node:crypto'; import { basename } from 'node:path'; import { qunAlbumControl } from '../data/webapi'; import { createAlbumCommentRequest, createAlbumFeedPublish, createAlbumMediaFeed } from '../data/album'; +export interface SetNoticeRetSuccess { + ec: number; + em: string; + id: number; + ltsm: number; + new_fid: string; + read_only: number; + role: number; + srv_code: number; +} + export class NTQQWebApi { context: InstanceContext; core: NapCatCore; @@ -25,12 +36,12 @@ export class NTQQWebApi { async shareDigest (groupCode: string, msgSeq: string, msgRandom: string, targetGroupCode: string) { const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); const url = `https://qun.qq.com/cgi-bin/group_digest/share_digest?${new URLSearchParams({ - bkn: this.getBknFromCookie(cookieObject), - group_code: groupCode, - msg_seq: msgSeq, - msg_random: msgRandom, - target_group_code: targetGroupCode, - }).toString()}`; + bkn: this.getBknFromCookie(cookieObject), + group_code: groupCode, + msg_seq: msgSeq, + msg_random: msgRandom, + target_group_code: targetGroupCode, + }).toString()}`; try { return RequestUtil.HttpGetText(url, 'GET', '', { Cookie: this.cookieToString(cookieObject) }); } catch { @@ -52,11 +63,11 @@ export class NTQQWebApi { async getGroupEssenceMsg (GroupCode: string, page_start: number = 0, page_limit: number = 50) { const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); const url = `https://qun.qq.com/cgi-bin/group_digest/digest_list?${new URLSearchParams({ - bkn: this.getBknFromCookie(cookieObject), - page_start: page_start.toString(), - page_limit: page_limit.toString(), - group_code: GroupCode, - }).toString()}`; + bkn: this.getBknFromCookie(cookieObject), + page_start: page_start.toString(), + page_limit: page_limit.toString(), + group_code: GroupCode, + }).toString()}`; try { const ret = await RequestUtil.HttpGetJson( url, @@ -76,16 +87,16 @@ export class NTQQWebApi { const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); const retList: Promise[] = []; const fastRet = await RequestUtil.HttpGetJson( - `https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({ - st: '0', - end: '40', - sort: '1', - gc: GroupCode, - bkn: this.getBknFromCookie(cookieObject), - }).toString()}`, - 'POST', - '', - { Cookie: this.cookieToString(cookieObject) } + `https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({ + st: '0', + end: '40', + sort: '1', + gc: GroupCode, + bkn: this.getBknFromCookie(cookieObject), + }).toString()}`, + 'POST', + '', + { Cookie: this.cookieToString(cookieObject) } ); if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) { return []; @@ -101,16 +112,16 @@ export class NTQQWebApi { // 遍历批量请求 for (let i = 2; i <= PageNum; i++) { const ret = RequestUtil.HttpGetJson( - `https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({ - st: ((i - 1) * 40).toString(), - end: (i * 40).toString(), - sort: '1', - gc: GroupCode, - bkn: this.getBknFromCookie(cookieObject), - }).toString()}`, - 'POST', - '', - { Cookie: this.cookieToString(cookieObject) } + `https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({ + st: ((i - 1) * 40).toString(), + end: (i * 40).toString(), + sort: '1', + gc: GroupCode, + bkn: this.getBknFromCookie(cookieObject), + }).toString()}`, + 'POST', + '', + { Cookie: this.cookieToString(cookieObject) } ); retList.push(ret); } @@ -153,16 +164,7 @@ export class NTQQWebApi { imgWidth: number = 540, imgHeight: number = 300 ) { - interface SetNoticeRetSuccess { - ec: number; - em: string; - id: number; - ltsm: number; - new_fid: string; - read_only: number; - role: number; - srv_code: number; - } + const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); @@ -178,18 +180,18 @@ export class NTQQWebApi { imgHeight: imgHeight.toString(), }; const ret: SetNoticeRetSuccess = await RequestUtil.HttpGetJson( - `https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?${new URLSearchParams({ - bkn: this.getBknFromCookie(cookieObject), - qid: GroupCode, - text: Content, - pinned: pinned.toString(), - type: type.toString(), - settings, - ...(picId === '' ? {} : externalParam), - }).toString()}`, - 'POST', - '', - { Cookie: this.cookieToString(cookieObject) } + `https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?${new URLSearchParams({ + bkn: this.getBknFromCookie(cookieObject), + qid: GroupCode, + text: Content, + pinned: pinned.toString(), + type: type.toString(), + settings, + ...(picId === '' ? {} : externalParam), + }).toString()}`, + 'POST', + '', + { Cookie: this.cookieToString(cookieObject) } ); return ret; } catch { @@ -201,20 +203,20 @@ export class NTQQWebApi { const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); try { const ret = await RequestUtil.HttpGetJson( - `https://web.qun.qq.com/cgi-bin/announce/get_t_list?${new URLSearchParams({ - bkn: this.getBknFromCookie(cookieObject), - qid: GroupCode, - ft: '23', - ni: '1', - n: '1', - i: '1', - log_read: '1', - platform: '1', - s: '-1', - }).toString()}&n=20`, - 'GET', - '', - { Cookie: this.cookieToString(cookieObject) } + `https://web.qun.qq.com/cgi-bin/announce/get_t_list?${new URLSearchParams({ + bkn: this.getBknFromCookie(cookieObject), + qid: GroupCode, + ft: '23', + ni: '1', + n: '1', + i: '1', + log_read: '1', + platform: '1', + s: '-1', + }).toString()}&n=20`, + 'GET', + '', + { Cookie: this.cookieToString(cookieObject) } ); return ret?.ec === 0 ? ret : undefined; } catch { @@ -222,17 +224,17 @@ export class NTQQWebApi { } } - private async getDataInternal (cookieObject: { [key: string]: string }, groupCode: string, type: number) { + private async getDataInternal (cookieObject: { [key: string]: string; }, groupCode: string, type: number) { let resJson; try { const res = await RequestUtil.HttpGetText( - `https://qun.qq.com/interactive/honorlist?${new URLSearchParams({ - gc: groupCode, - type: type.toString(), - }).toString()}`, - 'GET', - '', - { Cookie: this.cookieToString(cookieObject) } + `https://qun.qq.com/interactive/honorlist?${new URLSearchParams({ + gc: groupCode, + type: type.toString(), + }).toString()}`, + 'GET', + '', + { Cookie: this.cookieToString(cookieObject) } ); const match = /window\.__INITIAL_STATE__=(.*?);/.exec(res); if (match?.[1]) { @@ -245,7 +247,7 @@ export class NTQQWebApi { } } - private async getHonorList (cookieObject: { [key: string]: string }, groupCode: string, type: number) { + private async getHonorList (cookieObject: { [key: string]: string; }, groupCode: string, type: number) { const data = await this.getDataInternal(cookieObject, groupCode, type); if (!data) { this.context.logger.logError(`获取类型 ${type} 的荣誉信息失败`); @@ -304,11 +306,11 @@ export class NTQQWebApi { return HonorInfo; } - private cookieToString (cookieObject: { [key: string]: string }) { + private cookieToString (cookieObject: { [key: string]: string; }) { return Object.entries(cookieObject).map(([key, value]) => `${key}=${value}`).join('; '); } - public getBknFromCookie (cookieObject: { [key: string]: string }) { + public getBknFromCookie (cookieObject: { [key: string]: string; }) { const sKey = cookieObject['skey'] as string; let hash = 5381; @@ -361,7 +363,7 @@ export class NTQQWebApi { uin, getMemberRole: '0', }); - const response = await RequestUtil.HttpGetJson<{ data: { album: Array<{ id: string, title: string }> } }>(api + params.toString(), 'GET', '', { + const response = await RequestUtil.HttpGetJson<{ data: { album: Array<{ id: string, title: string; }>; }; }>(api + params.toString(), 'GET', '', { Cookie: cookies, }); return response.data.album; @@ -384,7 +386,7 @@ export class NTQQWebApi { sAlbumID, }); const api = `https://h5.qzone.qq.com/webapp/json/sliceUpload/FileBatchControl/${img_md5}?g_tk=${GTK}`; - const post = await RequestUtil.HttpGetJson<{ data: { session: string }, ret: number, msg: string }>(api, 'POST', body, { + const post = await RequestUtil.HttpGetJson<{ data: { session: string; }, ret: number, msg: string; }>(api, 'POST', body, { Cookie: cookie, 'Content-Type': 'application/json', }); @@ -430,7 +432,7 @@ export class NTQQWebApi { throw new Error(`HTTP error! status: ${response.status}`); } - const post = await response.json() as { ret: number, msg: string }; if (post.ret !== 0) { + const post = await response.json() as { ret: number, msg: string; }; if (post.ret !== 0) { throw new Error(`分片 ${seq} 上传失败: ${post.msg}`); } offset += chunk.length; @@ -475,10 +477,10 @@ export class NTQQWebApi { const client_key = Date.now() * 1000; return await this.context.session.getAlbumService().doQunComment( random_seq, { - map_info: [], - map_bytes_info: [], - map_user_account: [], - }, + map_info: [], + map_bytes_info: [], + map_user_account: [], + }, qunId, 2, createAlbumMediaFeed(uin, albumId, lloc), @@ -509,13 +511,13 @@ export class NTQQWebApi { const uin = this.core.selfInfo.uin || '10001'; return await this.context.session.getAlbumService().doQunLike( random_seq, { - map_info: [], - map_bytes_info: [], - map_user_account: [], - }, { - id, - status: 1, - }, + map_info: [], + map_bytes_info: [], + map_user_account: [], + }, { + id, + status: 1, + }, createAlbumFeedPublish(qunId, uin, albumId, lloc) ); } diff --git a/packages/napcat-core/types/user.ts b/packages/napcat-core/types/user.ts index fa76b731..669f2338 100644 --- a/packages/napcat-core/types/user.ts +++ b/packages/napcat-core/types/user.ts @@ -57,24 +57,24 @@ export interface BaseInfo { } // 音乐信息 -interface MusicInfo { +export interface MusicInfo { buf: string; } // 视频业务信息 -interface VideoBizInfo { +export interface VideoBizInfo { cid: string; tvUrl: string; synchType: string; } // 视频信息 -interface VideoInfo { +export interface VideoInfo { name: string; } // 扩展在线业务信息 -interface ExtOnlineBusinessInfo { +export interface ExtOnlineBusinessInfo { buf: string; customStatus: unknown; videoBizInfo: VideoBizInfo; @@ -82,12 +82,12 @@ interface ExtOnlineBusinessInfo { } // 扩展缓冲区 -interface ExtBuffer { +export interface ExtBuffer { buf: string; } // 用户状态 -interface UserStatus { +export interface UserStatus { uid: string; uin: string; status: number; @@ -109,14 +109,14 @@ interface UserStatus { } // 特权图标 -interface PrivilegeIcon { +export interface PrivilegeIcon { jumpUrl: string; openIconList: unknown[]; closeIconList: unknown[]; } // 增值服务信息 -interface VasInfo { +export interface VasInfo { vipFlag: boolean; yearVipFlag: boolean; svipFlag: boolean; @@ -149,7 +149,7 @@ interface VasInfo { } // 关系标志 -interface RelationFlags { +export interface RelationFlags { topTime: string; isBlock: boolean; isMsgDisturb: boolean; @@ -167,7 +167,7 @@ interface RelationFlags { } // 通用扩展信息 -interface CommonExt { +export interface CommonExt { constellation: number; shengXiao: number; kBloodType: number; @@ -193,14 +193,14 @@ export enum BuddyListReqType { } // 图片信息 -interface Pic { +export interface Pic { picId: string; picTime: number; picUrlMap: Record; } // 照片墙 -interface PhotoWall { +export interface PhotoWall { picList: Pic[]; } @@ -247,7 +247,7 @@ export interface ModifyProfileParams { nick: string; longNick: string; sex: NTSex; - birthday: { birthday_year: string, birthday_month: string, birthday_day: string }; + birthday: { birthday_year: string, birthday_month: string, birthday_day: string; }; location: unknown; } diff --git a/packages/napcat-webui-backend/src/api/Debug.ts b/packages/napcat-webui-backend/src/api/Debug.ts index 6ce26c54..95683c17 100644 --- a/packages/napcat-webui-backend/src/api/Debug.ts +++ b/packages/napcat-webui-backend/src/api/Debug.ts @@ -16,7 +16,7 @@ import json5 from 'json5'; type ActionNameType = typeof ActionName[keyof typeof ActionName]; -const router = Router(); +const router: Router = Router(); const DEFAULT_ADAPTER_NAME = 'debug-primary'; /** diff --git a/packages/napcat-webui-backend/src/router/Base.ts b/packages/napcat-webui-backend/src/router/Base.ts index 5efd1108..07dd95d8 100644 --- a/packages/napcat-webui-backend/src/router/Base.ts +++ b/packages/napcat-webui-backend/src/router/Base.ts @@ -3,7 +3,7 @@ import { GetThemeConfigHandler, GetNapCatVersion, QQVersionHandler, SetThemeConf import { StatusRealTimeHandler } from '@/napcat-webui-backend/src/api/Status'; import { GetProxyHandler } from '../api/Proxy'; -const router = Router(); +const router: Router = Router(); // router: 获取nc的package.json信息 router.get('/QQVersion', QQVersionHandler); router.get('/GetNapCatVersion', GetNapCatVersion); diff --git a/packages/napcat-webui-backend/src/router/File.ts b/packages/napcat-webui-backend/src/router/File.ts index 6069f033..c79830ea 100644 --- a/packages/napcat-webui-backend/src/router/File.ts +++ b/packages/napcat-webui-backend/src/router/File.ts @@ -18,7 +18,7 @@ import { DeleteWebUIFontHandler, // 添加上传处理器 } from '../api/File'; -const router = Router(); +const router: Router = Router(); const apiLimiter = rateLimit({ windowMs: 1 * 60 * 1000, // 1分钟内 diff --git a/packages/napcat-webui-backend/src/router/Log.ts b/packages/napcat-webui-backend/src/router/Log.ts index fcc021a0..9d29d24b 100644 --- a/packages/napcat-webui-backend/src/router/Log.ts +++ b/packages/napcat-webui-backend/src/router/Log.ts @@ -8,7 +8,7 @@ import { CloseTerminalHandler, } from '../api/Log'; -const router = Router(); +const router: Router = Router(); // 日志相关路由 router.get('/GetLog', LogHandler); diff --git a/packages/napcat-webui-backend/src/router/OB11Config.ts b/packages/napcat-webui-backend/src/router/OB11Config.ts index 82277e12..99f96681 100644 --- a/packages/napcat-webui-backend/src/router/OB11Config.ts +++ b/packages/napcat-webui-backend/src/router/OB11Config.ts @@ -2,7 +2,7 @@ import { Router } from 'express'; import { OB11GetConfigHandler, OB11SetConfigHandler } from '@/napcat-webui-backend/src/api/OB11Config'; -const router = Router(); +const router: Router = Router(); // router:读取配置 router.post('/GetConfig', OB11GetConfigHandler); // router:写入配置 diff --git a/packages/napcat-webui-backend/src/router/Plugin.ts b/packages/napcat-webui-backend/src/router/Plugin.ts index bd62a7a0..9e87d681 100644 --- a/packages/napcat-webui-backend/src/router/Plugin.ts +++ b/packages/napcat-webui-backend/src/router/Plugin.ts @@ -1,7 +1,7 @@ import { Router } from 'express'; import { GetPluginListHandler, ReloadPluginHandler, SetPluginStatusHandler, UninstallPluginHandler } from '@/napcat-webui-backend/src/api/Plugin'; -const router = Router(); +const router: Router = Router(); router.get('/List', GetPluginListHandler); router.post('/Reload', ReloadPluginHandler); diff --git a/packages/napcat-webui-backend/src/router/Process.ts b/packages/napcat-webui-backend/src/router/Process.ts index 7931a5c7..cde534e5 100644 --- a/packages/napcat-webui-backend/src/router/Process.ts +++ b/packages/napcat-webui-backend/src/router/Process.ts @@ -1,7 +1,7 @@ import { Router } from 'express'; import { RestartProcessHandler } from '../api/Process'; -const router = Router(); +const router: Router = Router(); // POST /api/Process/Restart - 重启进程 router.post('/Restart', RestartProcessHandler); diff --git a/packages/napcat-webui-backend/src/router/QQLogin.ts b/packages/napcat-webui-backend/src/router/QQLogin.ts index d5adf94d..3ceb63b6 100644 --- a/packages/napcat-webui-backend/src/router/QQLogin.ts +++ b/packages/napcat-webui-backend/src/router/QQLogin.ts @@ -12,7 +12,7 @@ import { QQRefreshQRcodeHandler, } from '@/napcat-webui-backend/src/api/QQLogin'; -const router = Router(); +const router: Router = Router(); // router:获取快速登录列表 router.all('/GetQuickLoginList', QQGetQuickLoginListHandler); // router:获取快速登录列表(新) diff --git a/packages/napcat-webui-backend/src/router/UpdateNapCat.ts b/packages/napcat-webui-backend/src/router/UpdateNapCat.ts index bb163b21..a0c0e01c 100644 --- a/packages/napcat-webui-backend/src/router/UpdateNapCat.ts +++ b/packages/napcat-webui-backend/src/router/UpdateNapCat.ts @@ -5,7 +5,7 @@ import { Router } from 'express'; import { UpdateNapCatHandler } from '@/napcat-webui-backend/src/api/UpdateNapCat'; -const router = Router(); +const router: Router = Router(); // POST /api/UpdateNapCat/update - 更新NapCat router.post('/update', UpdateNapCatHandler); diff --git a/packages/napcat-webui-backend/src/router/WebUIConfig.ts b/packages/napcat-webui-backend/src/router/WebUIConfig.ts index ccf80b7d..225e7e9c 100644 --- a/packages/napcat-webui-backend/src/router/WebUIConfig.ts +++ b/packages/napcat-webui-backend/src/router/WebUIConfig.ts @@ -8,7 +8,7 @@ import { UpdateWebUIConfigHandler, } from '@/napcat-webui-backend/src/api/WebUIConfig'; -const router = Router(); +const router: Router = Router(); // 获取WebUI基础配置 router.get('/GetConfig', GetWebUIConfigHandler); diff --git a/packages/napcat-webui-backend/src/router/auth.ts b/packages/napcat-webui-backend/src/router/auth.ts index 5f74e5f2..14701690 100644 --- a/packages/napcat-webui-backend/src/router/auth.ts +++ b/packages/napcat-webui-backend/src/router/auth.ts @@ -11,7 +11,7 @@ import { VerifyPasskeyAuthenticationHandler, } from '@/napcat-webui-backend/src/api/Auth'; -const router = Router(); +const router: Router = Router(); // router:登录 router.post('/login', LoginHandler); // router:检查登录状态 diff --git a/packages/napcat-webui-backend/src/router/index.ts b/packages/napcat-webui-backend/src/router/index.ts index 06e81abc..49e2521d 100644 --- a/packages/napcat-webui-backend/src/router/index.ts +++ b/packages/napcat-webui-backend/src/router/index.ts @@ -19,7 +19,7 @@ import DebugRouter from '@/napcat-webui-backend/src/api/Debug'; import { ProcessRouter } from './Process'; import { PluginRouter } from './Plugin'; -const router = Router(); +const router: Router = Router(); // 鉴权中间件 router.use(auth); diff --git a/packages/napcat-webui-backend/src/uploader/disk.ts b/packages/napcat-webui-backend/src/uploader/disk.ts index da54187b..c357e538 100644 --- a/packages/napcat-webui-backend/src/uploader/disk.ts +++ b/packages/napcat-webui-backend/src/uploader/disk.ts @@ -1,5 +1,5 @@ import multer from 'multer'; -import { Request, Response } from 'express'; +import { Request, Response, RequestHandler } from 'express'; import fs from 'fs'; import path from 'path'; import { randomUUID } from 'crypto'; @@ -65,7 +65,7 @@ export const createDiskStorage = (uploadPath: string) => { }); }; -export const createDiskUpload = (uploadPath: string) => { +export const createDiskUpload = (uploadPath: string): RequestHandler => { const upload = multer({ storage: createDiskStorage(uploadPath), limits: { diff --git a/packages/napcat-webui-backend/src/uploader/webui_font.ts b/packages/napcat-webui-backend/src/uploader/webui_font.ts index 635ea941..03e9abe8 100644 --- a/packages/napcat-webui-backend/src/uploader/webui_font.ts +++ b/packages/napcat-webui-backend/src/uploader/webui_font.ts @@ -1,7 +1,7 @@ import multer from 'multer'; import path from 'path'; import fs from 'fs'; -import type { Request, Response } from 'express'; +import type { Request, Response, RequestHandler } from 'express'; import { WebUiConfig } from '@/napcat-webui-backend/index'; // 支持的字体格式 @@ -42,7 +42,7 @@ export const webUIFontStorage = multer.diskStorage({ }, }); -export const webUIFontUpload = multer({ +export const webUIFontUpload: RequestHandler = multer({ storage: webUIFontStorage, fileFilter: (_, file, cb) => { // 验证文件类型