refactor(onebot): inline ctx.bridge.apis.groupFile direct calls

Remove 6 passthrough fields from ApiActionContext for the group-file
area (`uploadGroupFile / uploadPrivateFile / getGroupFileUrl /
createGroupFileFolder / getPrivateFileUrl / getGroupFileCount`).
Action sites (`actions/group-file.ts` and one site in
`actions/extended.ts`) now call `ctx.bridge.apis.groupFile.<method>`
directly.

`getGroupFiles` stays on the ctx because its module helper
(`getGroupFiles(bridge, groupId, folderId)` in `modules/contact-actions.ts`)
does identity-lookup enrichment of uploader/creator names — not a pure
passthrough.

Behavior preserved: same default values (`name = ''`, `folderId = '/'`,
`busId = 102`, `uploadFile = true`) — they were baked into the ctx
wrapper before, now they're explicit in the action site (`asString`
returns `''`, `... || '/'`, `... || 102`, `asBoolean(..., true)`).
The result-unwrap (`fileId` extraction from `UploadFileResult`) moves
from the ctx wrapper into the action handler.

Part 2 of the OneBot-side slim-down. 552/552 tests still green.
This commit is contained in:
DrSmoothl
2026-05-21 09:19:27 +08:00
parent cb698d2435
commit 4c4ce60bf2
4 changed files with 18 additions and 38 deletions
+3 -11
View File
@@ -573,18 +573,10 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
h.registerAction('get_group_file_system_info', async (params) => {
const groupId = asNumber(params.group_id);
if (!groupId) return failedResponse(RETCODE.BAD_REQUEST, 'group_id is required');
if (ctx.getGroupFileCount) {
const info = await ctx.getGroupFileCount(groupId);
return okResponse({
file_count: info.fileCount,
limit_count: info.maxCount,
used_space: 0,
total_space: 10737418240,
});
}
const info = await ctx.bridge.apis.groupFile.getCount(groupId);
return okResponse({
file_count: 0,
limit_count: 10000,
file_count: info.fileCount,
limit_count: info.maxCount,
used_space: 0,
total_space: 10737418240,
});
+7 -7
View File
@@ -11,8 +11,8 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
const folderId = asString(params.folder) || asString(params.folder_id) || '/';
const uploadFile = asBoolean(params.upload_file, true);
if (!groupId || !file) return failedResponse(RETCODE.BAD_REQUEST, 'group_id and file are required');
const fileId = await ctx.uploadGroupFile(groupId, file, name, folderId, uploadFile);
return okResponse({ file_id: fileId });
const result = await ctx.bridge.apis.groupFile.upload(groupId, file, name, folderId, uploadFile);
return okResponse({ file_id: result.fileId });
});
h.registerAction('upload_private_file', async (params) => {
@@ -21,8 +21,8 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
const name = asString(params.name);
const uploadFile = asBoolean(params.upload_file, true);
if (!userId || !file) return failedResponse(RETCODE.BAD_REQUEST, 'user_id and file are required');
const fileId = await ctx.uploadPrivateFile(userId, file, name, uploadFile);
return okResponse({ file_id: fileId });
const result = await ctx.bridge.apis.groupFile.uploadPrivate(userId, file, name, uploadFile);
return okResponse({ file_id: result.fileId });
});
h.registerAction('get_group_file_url', async (params) => {
@@ -32,7 +32,7 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
if (!groupId || !fileId) {
return failedResponse(RETCODE.BAD_REQUEST, 'group_id and file_id are required');
}
return okResponse({ url: await ctx.getGroupFileUrl(groupId, fileId, busId) });
return okResponse({ url: await ctx.bridge.apis.groupFile.getUrl(groupId, fileId, busId) });
});
h.registerAction('get_group_root_files', async (params) => {
@@ -81,7 +81,7 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
if (!groupId || !name) {
return failedResponse(RETCODE.BAD_REQUEST, 'group_id and name are required');
}
await ctx.createGroupFileFolder(groupId, name, parentId);
await ctx.bridge.apis.groupFile.createFolder(groupId, name, parentId);
return okResponse();
});
@@ -113,6 +113,6 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
if (!userId || !fileId || !fileHash) {
return failedResponse(RETCODE.BAD_REQUEST, 'user_id, file_id and file_hash are required');
}
return okResponse({ url: await ctx.getPrivateFileUrl(userId, fileId, fileHash) });
return okResponse({ url: await ctx.bridge.apis.groupFile.getPrivateUrl(userId, fileId, fileHash) });
});
}
+5 -7
View File
@@ -65,14 +65,12 @@ export interface ApiActionContext {
// accessed directly through `ctx.bridge.apis.groupAdmin.method()`
// after the #6 OneBot-side slim-down; no per-method passthrough
// here anymore.
// Group file (adapters: field extraction + Bridge name translation)
uploadGroupFile: (groupId: number, file: string, name?: string, folderId?: string, uploadFile?: boolean) => Promise<string | null>;
uploadPrivateFile: (userId: number, file: string, name?: string, uploadFile?: boolean) => Promise<string | null>;
getGroupFileUrl: (groupId: number, fileId: string, busId?: number) => Promise<string>;
// Group file passthroughs are gone — actions call
// `ctx.bridge.apis.groupFile.{upload,uploadPrivate,getUrl,
// createFolder,getPrivateUrl,getCount}` directly. `getGroupFiles`
// stays because it composes through the `getGroupFiles` module
// helper (identity-lookup enrichment of uploader names).
getGroupFiles: (groupId: number, folderId?: string) => Promise<JsonObject>;
createGroupFileFolder: (groupId: number, name: string, parentId?: string) => Promise<void>;
getPrivateFileUrl: (userId: number, fileId: string, fileHash: string) => Promise<string>;
getGroupFileCount: (groupId: number) => Promise<{ fileCount: number; maxCount: number }>;
// Requests (adapters: rename to OneBot vocabulary)
handleFriendRequest: (flag: string, approve: boolean) => Promise<void>;
handleGroupRequest: (flag: string, subType: string, approve: boolean, reason: string) => Promise<void>;
+3 -13
View File
@@ -114,19 +114,10 @@ export function buildApiContext(ref: OneBotInstanceContext): ApiActionContext {
// Group admin — actions now call `ctx.bridge.apis.groupAdmin.X(...)`
// directly; no per-method passthrough here anymore.
// Group file — fileId field extraction + defaults.
uploadGroupFile: async (groupId, file, name, folderId, uploadFile) => {
const result = await bridge.apis.groupFile.upload(groupId, file, name ?? '', folderId ?? '/', uploadFile ?? true);
return result.fileId;
},
uploadPrivateFile: async (userId, file, name, uploadFile) => {
const result = await bridge.apis.groupFile.uploadPrivate(userId, file, name ?? '', uploadFile ?? true);
return result.fileId;
},
getGroupFileUrl: (groupId, fileId, busId) => bridge.apis.groupFile.getUrl(groupId, fileId, busId ?? 102),
// Group file — `getGroupFiles` stays because the module helper
// enriches uploader/creator names from the identity cache; the
// rest of the area is called directly via `ctx.bridge.apis.groupFile.*`.
getGroupFiles: (groupId, folderId) => getGroupFiles(bridge, groupId, folderId),
createGroupFileFolder: (groupId, name, parentId) => bridge.apis.groupFile.createFolder(groupId, name, parentId ?? '/'),
getPrivateFileUrl: (userId, fileId, fileHash) => bridge.apis.groupFile.getPrivateUrl(userId, fileId, fileHash),
// Requests — name translation.
handleFriendRequest: (flag, approve) => bridge.apis.friend.handleRequest(flag, approve),
@@ -161,7 +152,6 @@ export function buildApiContext(ref: OneBotInstanceContext): ApiActionContext {
forceFetchClientKey: () => bridge.apis.web.forceFetchClientKey(),
setFriendRemark: (userId, remark) => bridge.apis.friend.setRemark(userId, remark),
setGroupAvatar: (groupId, source) => bridge.apis.profile.setGroupAvatar(groupId, source),
getGroupFileCount: (groupId) => bridge.apis.groupFile.getCount(groupId),
// Cross-store: looks up the meta then routes through Bridge.
setMsgEmojiLike: async (messageId, emojiId, set) => {