// mcp/src/client/WhkerDBClient.ts
import type {
CreateRoomResponse,
GetRoomByInviteCodeResponse,
GetRoomInfoResponse,
UploadPdfResponse,
UploadImageResponse,
} from './types.js';
import type { RoomSnapshot, PDFInfo, ImageInfo } from '@whkerdb/shared';
/**
* WhkerDB HTTP API 客户端
*/
export class WhkerDBClient {
private baseUrl: string;
constructor(baseUrl: string = 'http://localhost:3001') {
this.baseUrl = baseUrl.replace(/\/$/, '');
}
/**
* 创建房间
*/
async createRoom(roomId?: string): Promise<CreateRoomResponse> {
const response = await fetch(`${this.baseUrl}/api/rooms`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ roomId }),
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.error || `Failed to create room: ${response.status}`);
}
return response.json();
}
/**
* 通过邀请码获取房间
*/
async getRoomByInviteCode(inviteCode: string): Promise<GetRoomByInviteCodeResponse> {
const response = await fetch(`${this.baseUrl}/api/rooms/invite/${inviteCode}`);
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.error || `Room not found: ${response.status}`);
}
return response.json();
}
/**
* 获取房间信息
*/
async getRoomInfo(roomId: string): Promise<GetRoomInfoResponse> {
const response = await fetch(`${this.baseUrl}/api/rooms/${roomId}`);
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.error || `Room not found: ${response.status}`);
}
return response.json();
}
/**
* 上传 PDF 文件
*/
async uploadPdf(
roomId: string,
file: Buffer | Blob,
filename: string
): Promise<UploadPdfResponse> {
const formData = new FormData();
const blob = file instanceof Buffer ? new Blob([file], { type: 'application/pdf' }) : file;
formData.append('file', blob, filename);
const response = await fetch(`${this.baseUrl}/api/rooms/${roomId}/upload/pdf`, {
method: 'POST',
body: formData,
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.error || `Failed to upload PDF: ${response.status}`);
}
return response.json();
}
/**
* 获取 PDF 信息
*/
async getPdfInfo(pdfId: string): Promise<PDFInfo> {
const response = await fetch(`${this.baseUrl}/api/pdf/${pdfId}/info`);
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.error || `PDF not found: ${response.status}`);
}
return response.json();
}
/**
* 获取 PDF 文件 URL
*/
getPdfFileUrl(pdfId: string): string {
return `${this.baseUrl}/api/pdf/${pdfId}/file`;
}
/**
* 上传图片
*/
async uploadImage(
roomId: string,
file: Buffer | Blob,
filename: string,
mimeType: string = 'image/png'
): Promise<UploadImageResponse> {
const formData = new FormData();
const blob = file instanceof Buffer ? new Blob([file], { type: mimeType }) : file;
formData.append('file', blob, filename);
const response = await fetch(`${this.baseUrl}/api/rooms/${roomId}/upload/image`, {
method: 'POST',
body: formData,
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.error || `Failed to upload image: ${response.status}`);
}
return response.json();
}
/**
* 获取图片 URL
*/
getImageUrl(imageId: string): string {
return `${this.baseUrl}/api/image/${imageId}`;
}
/**
* 获取服务器基础 URL
*/
getBaseUrl(): string {
return this.baseUrl;
}
}