@naplink/naplink 0.0.10 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -370,7 +370,7 @@ function handleCloseEvent(deps, event) {
|
|
|
370
370
|
return;
|
|
371
371
|
}
|
|
372
372
|
const state = getState();
|
|
373
|
-
if (state === "connected" /* CONNECTED */ || state === "reconnecting" /* RECONNECTING */ || state === "connecting" /* CONNECTING */) {
|
|
373
|
+
if (config.reconnect.enabled && (state === "connected" /* CONNECTED */ || state === "reconnecting" /* RECONNECTING */ || state === "connecting" /* CONNECTING */)) {
|
|
374
374
|
handleReconnect({
|
|
375
375
|
config,
|
|
376
376
|
logger,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/naplink.ts","../src/utils/logger.ts","../src/core/connection/manager.ts","../src/types/errors.ts","../src/core/reconnect.ts","../src/core/heartbeat.ts","../src/core/connection/state.ts","../src/core/connection/url.ts","../src/core/connection/heartbeat-runner.ts","../src/core/connection/retry-handler.ts","../src/core/connection/close-handler.ts","../src/core/connection/handlers.ts","../src/core/api/request-builder.ts","../src/core/api/response-registry.ts","../src/core/api/retry.ts","../src/core/api-client.ts","../src/core/event-router.ts","../src/core/dispatcher.ts","../src/core/connection/state-handler.ts","../src/api/onebot/message.ts","../src/api/onebot/media.ts","../src/api/onebot/account.ts","../src/api/onebot/group.ts","../src/api/onebot/files.ts","../src/api/onebot/stream.ts","../src/core/upload/stream.ts","../src/api/onebot/requests.ts","../src/api/onebot/system.ts","../src/api/onebot/napcat.ts","../src/api/onebot/raw.ts","../src/api/onebot/index.ts","../src/api/delegates.ts","../src/types/config.ts","../src/utils/merge-config.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport type { NapLinkConfig, PartialNapLinkConfig, Logger } from './types/config';\nimport { DefaultLogger } from './utils/logger';\nimport { ConnectionManager, ConnectionState } from './core/connection';\nimport { ApiClient } from './core/api-client';\nimport { EventRouter } from './core/event-router';\nimport { MessageDispatcher } from './core/dispatcher';\nimport { handleConnectionStateChange } from './core/connection/state-handler';\nimport { OneBotApi } from './api';\nimport { bindOneBotApiMethods, type OneBotApiMethods } from './api/delegates';\nimport type { OneBotMessageSegment } from './types/message-segment';\nimport { mergeConfig } from './utils/merge-config';\n\n/**\n * NapLink客户端\n * 现代化的NapCat WebSocket客户端SDK\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport class NapLink extends EventEmitter {\n private config: NapLinkConfig;\n private logger: Logger;\n private connection: ConnectionManager;\n private apiClient: ApiClient;\n private eventRouter: EventRouter;\n private dispatcher: MessageDispatcher;\n private oneBotApi: OneBotApi;\n\n constructor(config: PartialNapLinkConfig) {\n super();\n\n // 合并配置\n this.config = mergeConfig(config);\n\n // 初始化logger\n this.logger =\n this.config.logging.logger ||\n new DefaultLogger(this.config.logging.level);\n\n // 初始化事件路由器\n this.eventRouter = new EventRouter(this.logger);\n this.setupEventForwarding();\n\n // 初始化API客户端 (需要提前初始化以便传给 Dispatcher)\n // 使用箭头函数作为代理,解决 ConnectionManager 和 Dispatcher 之间的循环依赖\n this.connection = new ConnectionManager(\n this.config,\n this.logger,\n (message) => this.dispatcher.dispatch(message),\n (state, wasReconnecting) => handleConnectionStateChange(this, state, wasReconnecting || false),\n this // 传递 emitter 用于发送 connection:lost 事件\n );\n\n this.apiClient = new ApiClient(this.connection, this.config, this.logger);\n this.dispatcher = new MessageDispatcher(this.apiClient, this.eventRouter, this.logger);\n\n this.oneBotApi = new OneBotApi(this.apiClient, this.logger);\n bindOneBotApiMethods(this.oneBotApi, this);\n\n this.logger.info('NapLink 客户端已初始化');\n }\n\n /**\n * 连接到NapCat服务器\n */\n async connect(): Promise<void> {\n this.logger.info('开始连接...');\n await this.connection.connect();\n }\n\n /**\n * 断开连接\n */\n disconnect(): void {\n this.logger.info('断开连接...');\n this.connection.disconnect();\n this.apiClient.clearPendingRequests('连接已断开');\n }\n\n /**\n * 获取连接状态\n */\n getState(): ConnectionState {\n return this.connection.getState();\n }\n\n /**\n * 检查是否已连接\n */\n isConnected(): boolean {\n return this.connection.isConnected();\n }\n\n /**\n * 补充消息中的媒体直链\n * 自动通过 get_file / get_image / get_record 获取真实下载链接\n */\n async hydrateMessage(message: OneBotMessageSegment[]): Promise<void> {\n return this.api.hydrateMedia(message);\n }\n\n /**\n * 调用自定义API\n */\n async callApi<T = unknown>(method: string, params: Record<string, unknown> = {}): Promise<T> {\n return this.apiClient.call<T>(method, params);\n }\n\n /**\n * 暴露 OneBot API 便于直接使用\n */\n get api(): OneBotApi {\n return this.oneBotApi;\n }\n\n /**\n * 销毁客户端实例\n * 调用后不应再复用当前实例。\n */\n dispose(): void {\n this.logger.info('销毁客户端...');\n this.connection.disconnect();\n this.apiClient.destroy();\n }\n\n // ============ 内部方法 ============\n\n /**\n * 设置事件转发\n */\n private setupEventForwarding(): void {\n // 转发所有事件路由器的事件\n this.eventRouter.onAny((event, data) => {\n this.emit(event, data);\n });\n }\n\n}\n\n// 通过接口合并将动态绑定的方法暴露到实例类型\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging, @typescript-eslint/no-empty-object-type\nexport interface NapLink extends OneBotApiMethods { }\n","import type { Logger } from '../types/config';\n\n/**\n * 日志等级枚举\n */\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n OFF = 4,\n}\n\n/**\n * 日志等级映射\n */\nconst LOG_LEVEL_MAP: Record<string, LogLevel> = {\n debug: LogLevel.DEBUG,\n info: LogLevel.INFO,\n warn: LogLevel.WARN,\n error: LogLevel.ERROR,\n off: LogLevel.OFF,\n};\n\n/**\n * 默认Logger实现\n * 支持日志等级控制和漂亮的格式化输出\n */\nexport class DefaultLogger implements Logger {\n private level: LogLevel;\n\n constructor(level: 'debug' | 'info' | 'warn' | 'error' | 'off' = 'info') {\n this.level = LOG_LEVEL_MAP[level];\n }\n\n /**\n * 设置日志等级\n */\n setLevel(level: 'debug' | 'info' | 'warn' | 'error' | 'off'): void {\n this.level = LOG_LEVEL_MAP[level];\n }\n\n debug(message: string, ...meta: unknown[]): void {\n if (this.shouldLog(LogLevel.DEBUG)) {\n console.debug(this.format('DEBUG', message), ...meta);\n }\n }\n\n info(message: string, ...meta: unknown[]): void {\n if (this.shouldLog(LogLevel.INFO)) {\n console.info(this.format('INFO', message), ...meta);\n }\n }\n\n warn(message: string, ...meta: unknown[]): void {\n if (this.shouldLog(LogLevel.WARN)) {\n console.warn(this.format('WARN', message), ...meta);\n }\n }\n\n error(message: string, error?: Error, ...meta: unknown[]): void {\n if (this.shouldLog(LogLevel.ERROR)) {\n console.error(this.format('ERROR', message), error || '', ...meta);\n }\n }\n\n /**\n * 检查是否应该输出日志\n */\n private shouldLog(level: LogLevel): boolean {\n return level >= this.level;\n }\n\n /**\n * 格式化日志消息\n */\n private format(level: string, message: string): string {\n const timestamp = new Date().toISOString();\n return `[${timestamp}] [NapLink] ${level}: ${message}`;\n }\n}\n","import WebSocket from 'isomorphic-ws';\nimport type EventEmitter from 'events';\nimport type { NapLinkConfig, Logger } from '../../types/config';\nimport {\n ConnectionError,\n ConnectionClosedError,\n} from '../../types/errors';\nimport { ReconnectService } from '../reconnect';\nimport { HeartbeatService } from '../heartbeat';\nimport { ConnectionState } from './state';\nimport { buildWebSocketUrl } from './url';\nimport { startHeartbeat } from './heartbeat-runner';\nimport { handleCloseEvent } from './close-handler';\nimport { attachWebSocketHandlers } from './handlers';\n\n/**\n * WebSocket 连接管理器\n * 负责管理连接生命周期、重连、心跳等\n */\nexport class ConnectionManager {\n private ws?: WebSocket;\n private state: ConnectionState = ConnectionState.DISCONNECTED;\n private reconnectService: ReconnectService;\n private heartbeatService?: HeartbeatService;\n private connectPromise?: Promise<void>;\n private connectTimeout?: NodeJS.Timeout | number;\n private wasReconnecting: boolean = false; // 跟踪是否处于重连状态\n\n constructor(\n private config: NapLinkConfig,\n private logger: Logger,\n private onMessage: (data: string) => void,\n private onStateChange: (state: ConnectionState, wasReconnecting?: boolean) => void,\n private emitter?: Pick<EventEmitter, 'emit'> // 新增:用于发送 connection:lost 事件\n ) {\n this.reconnectService = new ReconnectService(config.reconnect, logger);\n }\n\n /**\n * 连接到WebSocket服务器\n */\n async connect(): Promise<void> {\n // 如果正在连接,返回现有的Promise\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.setState(ConnectionState.CONNECTING);\n\n this.connectPromise = this.performConnect();\n\n try {\n await this.connectPromise;\n } finally {\n this.connectPromise = undefined;\n }\n }\n\n /**\n * 执行实际的连接逻辑\n */\n private performConnect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const url = buildWebSocketUrl(this.config);\n this.logger.info(`连接到 ${url}`);\n\n try {\n // 清理旧的连接及其处理程序,防止“幽灵连接”分发消息\n if (this.ws) {\n this.logger.debug('清理旧的 WebSocket 连接');\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.close(1001, '正在重新连接');\n }\n this.ws = undefined;\n }\n\n this.ws = new WebSocket(url);\n } catch (error) {\n const err = new ConnectionError('WebSocket 创建失败', error);\n this.logger.error('连接失败', err);\n reject(err);\n return;\n }\n\n const timeoutHandle = attachWebSocketHandlers(\n this.ws,\n {\n config: this.config,\n logger: this.logger,\n setState: (s) => this.setState(s),\n resetReconnect: () => this.reconnectService.reset(),\n startHeartbeat: () => {\n this.heartbeatService = startHeartbeat({\n config: this.config,\n logger: this.logger,\n send: (payload) => this.send(payload),\n onTimeout: () => this.handleHeartbeatTimeout(),\n createService: (interval, onPing, onTimeout, logger) =>\n new HeartbeatService(interval, onPing, onTimeout, logger),\n });\n },\n recordPong: () => this.heartbeatService?.recordPong(),\n onMessage: (data: string) => this.onMessage(data),\n onClose: (event: any) => handleCloseEvent({\n getState: () => this.state,\n setState: (s) => this.setState(s),\n stopHeartbeat: () => this.stopHeartbeat(),\n logger: this.logger,\n config: this.config,\n reconnectService: this.reconnectService,\n reconnect: () => this.connect(),\n onMaxAttemptsReached: () => {\n // 达到最大重连次数,发送 connection:lost 事件\n if (this.emitter) {\n this.emitter.emit('connection:lost', {\n timestamp: Date.now(),\n attempts: this.reconnectService.getMaxAttempts()\n });\n }\n },\n }, event),\n clearConnectTimeout: () => this.clearConnectTimeout(),\n },\n resolve,\n reject,\n );\n this.connectTimeout = timeoutHandle;\n });\n }\n\n /**\n * 断开连接\n * @param code 关闭代码\n * @param reason 关闭原因\n */\n disconnect(code = 1000, reason = '正常关闭'): void {\n this.logger.info(`断开连接: ${reason}`);\n\n this.reconnectService.cancel();\n this.stopHeartbeat();\n this.clearConnectTimeout();\n\n if (this.ws) {\n try {\n // 清理监听器\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.close(code, reason);\n }\n } catch (error) {\n this.logger.error('关闭连接失败', error as Error);\n }\n this.ws = undefined;\n }\n\n this.setState(ConnectionState.DISCONNECTED);\n this.wasReconnecting = false;\n }\n\n /**\n * 发送数据\n */\n send(data: string): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new ConnectionClosedError(\n this.ws?.readyState || -1,\n '连接未建立或已关闭'\n );\n }\n\n this.ws.send(data);\n }\n\n /**\n * 获取当前状态\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * 检查是否已连接\n */\n isConnected(): boolean {\n return (\n this.state === ConnectionState.CONNECTED &&\n this.ws?.readyState === WebSocket.OPEN\n );\n }\n\n /**\n * 设置状态并通知\n */\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.logger.debug(`状态变更: ${state}`);\n\n // 记录是否处于重连状态\n if (state === ConnectionState.RECONNECTING) {\n this.wasReconnecting = true;\n } else if (state === ConnectionState.CONNECTED) {\n // 只在成功连接后传递 wasReconnecting\n this.onStateChange(state, this.wasReconnecting);\n this.wasReconnecting = false; // 重置标记\n return;\n }\n\n this.onStateChange(state, false);\n }\n }\n\n /**\n * 停止心跳\n */\n private stopHeartbeat(): void {\n if (this.heartbeatService) {\n this.heartbeatService.stop();\n this.heartbeatService = undefined;\n }\n }\n\n /**\n * 处理心跳超时\n */\n private handleHeartbeatTimeout(): void {\n this.logger.warn('心跳超时,主动断开连接');\n this.disconnect(4000, '心跳超时');\n }\n\n /**\n * 处理连接关闭并尝试重连\n */\n private clearConnectTimeout(): void {\n if (this.connectTimeout) {\n clearTimeout(this.connectTimeout as NodeJS.Timeout);\n this.connectTimeout = undefined;\n }\n }\n}\n","/**\n * NapLink 错误基类\n * 所有SDK错误都继承自此类\n */\nexport class NapLinkError extends Error {\n constructor(\n message: string,\n public code: string,\n public details?: unknown\n ) {\n super(message);\n this.name = this.constructor.name;\n\n // 保持正确的原型链\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n /**\n * 转换为JSON格式\n */\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n details: this.details,\n };\n }\n}\n\n/**\n * 连接错误\n * 当WebSocket连接失败时抛出\n */\nexport class ConnectionError extends NapLinkError {\n constructor(message: string, cause?: unknown) {\n super(message, 'E_CONNECTION', cause);\n }\n}\n\n/**\n * API超时错误\n * 当API调用超过设定时间时抛出\n */\nexport class ApiTimeoutError extends NapLinkError {\n constructor(method: string, timeout: number) {\n super(\n `API调用 ${method} 超时 (${timeout}ms)`,\n 'E_API_TIMEOUT',\n { method, timeout }\n );\n }\n}\n\n/**\n * API错误\n * 当API调用返回错误时抛出\n */\nexport class ApiError extends NapLinkError {\n constructor(\n method: string,\n retcode: number,\n message: string,\n wording?: string\n ) {\n super(\n wording || message || `API调用失败: ${method}`,\n 'E_API_FAILED',\n { method, retcode, message, wording }\n );\n }\n}\n\n/**\n * 达到最大重连次数错误\n */\nexport class MaxReconnectAttemptsError extends NapLinkError {\n constructor(attempts: number) {\n super(\n `达到最大重连次数 (${attempts})`,\n 'E_MAX_RECONNECT',\n { attempts }\n );\n }\n}\n\n/**\n * 连接关闭错误\n */\nexport class ConnectionClosedError extends NapLinkError {\n constructor(code: number, reason: string) {\n super(\n `连接已关闭: ${reason} (code: ${code})`,\n 'E_CONNECTION_CLOSED',\n { code, reason }\n );\n }\n}\n\n/**\n * 无效配置错误\n */\nexport class InvalidConfigError extends NapLinkError {\n constructor(field: string, reason: string) {\n super(\n `无效的配置: ${field} - ${reason}`,\n 'E_INVALID_CONFIG',\n { field, reason }\n );\n }\n}\n","import type { NapLinkConfig } from '../types/config';\nimport type { Logger } from '../types/config';\n\n/**\n * 重连服务\n * 实现指数退避算法,避免重连风暴\n */\nexport class ReconnectService {\n private currentAttempt = 0;\n private backoffMs: number;\n private reconnectTimer?: NodeJS.Timeout | number;\n\n constructor(\n private config: NapLinkConfig['reconnect'],\n private logger: Logger\n ) {\n this.backoffMs = config.backoff.initial;\n }\n\n hasRemainingAttempts(): boolean {\n return this.currentAttempt < this.config.maxAttempts;\n }\n\n getMaxAttempts(): number {\n return this.config.maxAttempts;\n }\n\n /**\n * 调度重连\n * @param reconnectFn 重连函数\n * @returns 是否调度成功\n */\n schedule(reconnectFn: () => Promise<void>): boolean {\n if (!this.config.enabled) {\n this.logger.warn('自动重连未启用');\n return false;\n }\n\n if (this.currentAttempt >= this.config.maxAttempts) {\n this.logger.error(\n `达到最大重连次数 (${this.config.maxAttempts})`,\n undefined,\n { attempts: this.currentAttempt }\n );\n return false;\n }\n\n this.currentAttempt++;\n\n this.logger.info(\n `将在 ${this.backoffMs}ms 后进行第 ${this.currentAttempt} 次重连...`\n );\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await reconnectFn();\n this.reset(); // 重连成功,重置状态\n } catch (error) {\n const err = error as Error;\n this.logger.error(`重连失败: ${err.message}`);\n this.logger.debug('详细错误信息', err);\n // 增加退避延迟\n this.backoffMs = Math.min(\n this.backoffMs * this.config.backoff.multiplier,\n this.config.backoff.max\n );\n // 继续尝试重连\n this.schedule(reconnectFn);\n }\n }, this.backoffMs);\n\n return true;\n }\n\n /**\n * 重置重连状态\n * 在连接成功后调用\n */\n reset(): void {\n this.currentAttempt = 0;\n this.backoffMs = this.config.backoff.initial;\n this.cancel();\n }\n\n /**\n * 取消待定的重连\n */\n cancel(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer as NodeJS.Timeout);\n this.reconnectTimer = undefined;\n }\n }\n\n /**\n * 获取当前重连尝试次数\n */\n getCurrentAttempt(): number {\n return this.currentAttempt;\n }\n}\n","import type { Logger } from '../types/config';\n\n/**\n * 心跳服务\n * 定期发送ping消息保持连接活跃\n */\nexport class HeartbeatService {\n private timer?: NodeJS.Timeout | number;\n private lastPongTime = 0;\n private missedPings = 0;\n private static readonly MAX_MISSED_PINGS = 3;\n\n constructor(\n private interval: number,\n private sendPing: () => void,\n private onTimeout: () => void,\n private logger: Logger\n ) { }\n\n /**\n * 启动心跳\n */\n start(): void {\n if (this.interval <= 0) {\n this.logger.debug('心跳已禁用 (interval: 0)');\n return;\n }\n\n this.logger.debug(`启动心跳服务 (间隔: ${this.interval}ms)`);\n this.lastPongTime = Date.now();\n this.missedPings = 0;\n\n this.timer = setInterval(() => {\n const now = Date.now();\n const elapsed = now - this.lastPongTime;\n\n // 检查是否超时\n if (elapsed > this.interval * HeartbeatService.MAX_MISSED_PINGS) {\n this.missedPings++;\n this.logger.warn(\n `心跳超时 (${this.missedPings}/${HeartbeatService.MAX_MISSED_PINGS})`,\n { elapsed }\n );\n\n if (this.missedPings >= HeartbeatService.MAX_MISSED_PINGS) {\n this.logger.error('心跳连续超时,触发重连');\n this.stop();\n this.onTimeout();\n return;\n }\n }\n\n // 发送ping\n this.logger.debug('发送心跳 ping');\n this.sendPing();\n }, this.interval);\n }\n\n /**\n * 停止心跳\n */\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer as NodeJS.Timeout);\n this.timer = undefined;\n this.logger.debug('心跳服务已停止');\n }\n }\n\n /**\n * 记录收到pong\n */\n recordPong(): void {\n this.lastPongTime = Date.now();\n this.missedPings = 0;\n this.logger.debug('收到心跳 pong');\n }\n\n /**\n * 检查心跳是否活跃\n */\n isActive(): boolean {\n return this.timer !== undefined;\n }\n}\n","/**\n * WebSocket 连接状态\n */\nexport enum ConnectionState {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n RECONNECTING = 'reconnecting',\n}\n","import type { NapLinkConfig } from '../../types/config';\n\nexport function buildWebSocketUrl(config: NapLinkConfig): string {\n const { url, token } = config.connection;\n if (token) {\n try {\n // Prefer structured URL mutation so we overwrite any existing access_token.\n const parsed = new URL(url);\n parsed.searchParams.set('access_token', token);\n return parsed.toString();\n } catch {\n const separator = url.includes('?') ? '&' : '?';\n // Token may contain URL-sensitive chars (+, &, #, % ...), must be encoded.\n return `${url}${separator}access_token=${encodeURIComponent(token)}`;\n }\n }\n return url;\n}\n","import type { HeartbeatService } from '../heartbeat';\nimport type { NapLinkConfig, Logger } from '../../types/config';\n\nexport type HeartbeatDeps = {\n config: NapLinkConfig;\n logger: Logger;\n heartbeatService?: HeartbeatService;\n send: (payload: string) => void;\n onTimeout: () => void;\n createService: (interval: number, onPing: () => void, onTimeout: () => void, logger: Logger) => HeartbeatService;\n};\n\nexport function startHeartbeat(deps: HeartbeatDeps): HeartbeatService | undefined {\n const { config, logger, send, onTimeout, createService } = deps;\n const interval = config.connection.pingInterval || 0;\n const heartbeatAction = config.connection.heartbeatAction;\n\n if (interval <= 0 || !heartbeatAction?.action) {\n return undefined;\n }\n\n const service = createService(\n interval,\n () => {\n try {\n const payload = {\n action: heartbeatAction.action,\n params: heartbeatAction.params ?? {},\n echo: `heartbeat_${Date.now()}`,\n };\n send(JSON.stringify(payload));\n } catch (error) {\n logger.error('发送心跳失败', error as Error);\n }\n },\n onTimeout,\n logger\n );\n service.start();\n return service;\n}\n","import type { NapLinkConfig, Logger } from '../../types/config';\nimport { MaxReconnectAttemptsError } from '../../types/errors';\nimport type { ReconnectService } from '../reconnect';\nimport { ConnectionState } from './state';\n\nexport type RetryDeps = {\n config: NapLinkConfig;\n logger: Logger;\n reconnectService: ReconnectService;\n setState: (state: ConnectionState) => void;\n connect: () => Promise<void>;\n onMaxAttemptsReached?: () => void; // 新增:达到最大重连次数时的回调\n};\n\nexport function handleReconnect(deps: RetryDeps): boolean {\n const { config, logger, reconnectService, setState, connect, onMaxAttemptsReached } = deps;\n\n if (!reconnectService.hasRemainingAttempts()) {\n setState(ConnectionState.DISCONNECTED);\n const err = new MaxReconnectAttemptsError(reconnectService.getMaxAttempts());\n logger.error('自动重连已达上限,停止重连', err);\n\n // 触发达到最大重连次数的回调\n if (onMaxAttemptsReached) {\n onMaxAttemptsReached();\n }\n\n return false;\n }\n\n setState(ConnectionState.RECONNECTING);\n const scheduled = reconnectService.schedule(() => connect());\n if (!scheduled) {\n setState(ConnectionState.DISCONNECTED);\n const err = new MaxReconnectAttemptsError(config.reconnect.maxAttempts);\n logger.error('自动重连已达上限,停止重连', err);\n\n // 触发达到最大重连次数的回调\n if (onMaxAttemptsReached) {\n onMaxAttemptsReached();\n }\n\n return false;\n }\n\n return true;\n}\n","import type { NapLinkConfig, Logger } from '../../types/config';\nimport { ConnectionState } from './state';\nimport { handleReconnect } from './retry-handler';\nimport type { ReconnectService } from '../reconnect';\n\nexport type CloseHandlerDeps = {\n getState: () => ConnectionState;\n setState: (state: ConnectionState) => void;\n stopHeartbeat: () => void;\n logger: Logger;\n config: NapLinkConfig;\n reconnect: () => Promise<void>;\n reconnectService: ReconnectService;\n onMaxAttemptsReached?: () => void; // 新增:达到最大重连次数时的回调\n};\n\nexport function handleCloseEvent(deps: CloseHandlerDeps, event: any): void {\n const { getState, setState, stopHeartbeat, logger, config, reconnectService, reconnect, onMaxAttemptsReached } = deps;\n\n stopHeartbeat();\n logger.info(`连接关闭 (code: ${event.code}, reason: ${event.reason})`);\n\n // 1000 是正常关闭,不触发重连\n if (event.code === 1000) {\n setState(ConnectionState.DISCONNECTED);\n return;\n }\n\n const state = getState();\n if (\n state === ConnectionState.CONNECTED ||\n state === ConnectionState.RECONNECTING ||\n state === ConnectionState.CONNECTING\n ) {\n handleReconnect({\n config,\n logger,\n reconnectService,\n setState,\n connect: reconnect,\n onMaxAttemptsReached, // 传递回调\n });\n } else {\n setState(ConnectionState.DISCONNECTED);\n }\n}\n","import WebSocket from 'isomorphic-ws';\nimport type { NapLinkConfig, Logger } from '../../types/config';\nimport { ConnectionError } from '../../types/errors';\nimport { ConnectionState } from './state';\n\nexport type HandlerDeps = {\n config: NapLinkConfig;\n logger: Logger;\n setState: (state: ConnectionState) => void;\n resetReconnect: () => void;\n startHeartbeat: () => void;\n recordPong: () => void;\n onMessage: (data: string) => void;\n onClose: (event: any) => void;\n clearConnectTimeout: () => void;\n};\n\nexport function attachWebSocketHandlers(\n ws: WebSocket,\n deps: HandlerDeps,\n resolve: () => void,\n reject: (err: Error) => void\n): NodeJS.Timeout | number {\n const { config, logger } = deps;\n\n // 设置连接超时\n const timeoutMs = config.connection.timeout || 30000;\n const connectTimeout = setTimeout(() => {\n if (ws && ws.readyState !== WebSocket.OPEN) {\n logger.error(`连接超时 (${timeoutMs}ms)`);\n ws.close();\n reject(new ConnectionError(`连接超时 (${timeoutMs}ms)`));\n }\n }, timeoutMs);\n\n ws.onopen = () => {\n deps.clearConnectTimeout();\n deps.setState(ConnectionState.CONNECTED);\n deps.resetReconnect();\n deps.startHeartbeat();\n deps.logger.info('WebSocket 连接已建立');\n resolve();\n };\n\n ws.onerror = (event: any) => {\n deps.clearConnectTimeout();\n const error = new ConnectionError('WebSocket 错误', event);\n deps.logger.error(`连接错误: ${error.message}`);\n deps.logger.debug('详细错误信息', error);\n reject(error);\n };\n\n ws.onclose = (event) => {\n deps.clearConnectTimeout();\n deps.onClose(event);\n };\n\n ws.onmessage = (event) => {\n try {\n deps.recordPong();\n deps.onMessage(event.data.toString());\n } catch (error) {\n deps.logger.error('消息处理失败', error as Error);\n }\n };\n\n return connectTimeout;\n}\n","export type BuiltRequest = {\n payload: string;\n echo: string;\n};\n\nexport function buildRequestPayload(method: string, params: unknown, echo: string): BuiltRequest {\n return {\n echo,\n payload: JSON.stringify({\n action: method,\n params,\n echo,\n }),\n };\n}\n","import { ApiTimeoutError } from '../../types/errors';\n\nexport interface PendingRequest {\n resolve: (data: unknown) => void;\n reject: (error: Error) => void;\n createdAt: number;\n method: string;\n timer: NodeJS.Timeout | number;\n timeoutMs: number;\n onPacket?: (packet: unknown) => void;\n onEnd?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport class ResponseRegistry {\n private pending = new Map<string, PendingRequest>();\n\n add(echo: string, request: Omit<PendingRequest, 'timer'>, timeout: number): PendingRequest {\n const timer = setTimeout(() => {\n this.pending.delete(echo);\n request.reject(new ApiTimeoutError(request.method, timeout));\n }, timeout);\n\n const entry: PendingRequest = { ...request, timer };\n this.pending.set(echo, entry);\n return entry;\n }\n\n get(echo: string): PendingRequest | undefined {\n return this.pending.get(echo);\n }\n\n refresh(echo: string): boolean {\n const req = this.pending.get(echo);\n if (!req) return false;\n\n clearTimeout(req.timer as NodeJS.Timeout);\n req.createdAt = Date.now();\n req.timer = setTimeout(() => {\n this.pending.delete(echo);\n req.reject(new ApiTimeoutError(req.method, req.timeoutMs));\n }, req.timeoutMs);\n return true;\n }\n\n resolve(echo: string, data: unknown) {\n const req = this.pending.get(echo);\n if (!req) return false;\n this.pending.delete(echo);\n clearTimeout(req.timer as NodeJS.Timeout);\n req.resolve(data);\n return true;\n }\n\n reject(echo: string, error: Error) {\n const req = this.pending.get(echo);\n if (!req) return false;\n this.pending.delete(echo);\n clearTimeout(req.timer as NodeJS.Timeout);\n req.reject(error);\n return true;\n }\n\n take(echo: string): PendingRequest | undefined {\n const req = this.pending.get(echo);\n if (req) {\n this.pending.delete(echo);\n clearTimeout(req.timer as NodeJS.Timeout);\n }\n return req;\n }\n\n clearAll(reason: string) {\n for (const [, req] of this.pending) {\n clearTimeout(req.timer as NodeJS.Timeout);\n req.reject(new Error(reason));\n }\n this.pending.clear();\n }\n\n cleanupStale(now: number, maxAge: number, onTimeout: (method: string, echo: string) => void) {\n for (const [echo, req] of this.pending) {\n if (now - req.createdAt > maxAge) {\n onTimeout(req.method, echo);\n this.reject(echo, new ApiTimeoutError(req.method, maxAge / 2));\n }\n }\n }\n}\n","import { ApiTimeoutError, ApiError } from '../../types/errors';\nimport type { Logger } from '../../types/config';\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n retries: number,\n method: string,\n logger: Logger,\n delayFn: (ms: number) => Promise<void>,\n) {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n // 最后一次尝试,直接抛出错误\n if (attempt === retries) {\n break;\n }\n\n // 如果是超时错误或API错误,进行重试\n if (\n error instanceof ApiTimeoutError ||\n error instanceof ApiError\n ) {\n logger.warn(\n `API调用失败,重试 ${attempt + 1}/${retries}: ${method}`,\n error\n );\n // 简单的延迟重试\n await delayFn(Math.min(1000 * (attempt + 1), 5000));\n } else {\n // 其他错误不重试\n throw error;\n }\n }\n }\n\n throw lastError;\n}\n","import type { Logger } from '../types/config';\nimport type { NapLinkConfig } from '../types/config';\nimport { ApiError, ConnectionClosedError } from '../types/errors';\nimport type { ConnectionManager } from './connection';\nimport { buildRequestPayload } from './api/request-builder';\nimport { ResponseRegistry } from './api/response-registry';\nimport { withRetry } from './api/retry';\n\ntype ApiResponseEnvelope = {\n stream?: string;\n status?: string;\n retcode?: number;\n message?: string;\n wording?: string;\n data?: Record<string, unknown>;\n};\n\ntype AsyncQueueWaiter<T> = {\n resolve: (result: IteratorResult<T>) => void;\n reject: (error: Error) => void;\n};\n\nclass AsyncQueue<T> implements AsyncIterable<T>, AsyncIterator<T> {\n private values: T[] = [];\n private waiters: AsyncQueueWaiter<T>[] = [];\n private closed = false;\n\n push(value: T) {\n if (this.closed) return;\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter.resolve({ value, done: false });\n } else {\n this.values.push(value);\n }\n }\n\n close() {\n if (this.closed) return;\n this.closed = true;\n while (this.waiters.length) {\n this.waiters.shift()!.resolve({ value: undefined as any, done: true });\n }\n }\n\n fail(error: Error) {\n if (this.closed) return;\n this.closed = true;\n while (this.waiters.length) {\n this.waiters.shift()!.reject(error);\n }\n this.values = [];\n }\n\n async next(): Promise<IteratorResult<T>> {\n if (this.values.length) {\n return { value: this.values.shift()!, done: false };\n }\n if (this.closed) {\n return { value: undefined as any, done: true };\n }\n return await new Promise<IteratorResult<T>>((resolve, reject) => {\n this.waiters.push({\n resolve,\n reject: (err) => reject(err),\n });\n });\n }\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return this;\n }\n}\n\n/**\n * API客户端\n * 负责发送API请求并处理响应\n * 支持超时控制、自动重试、请求清理\n */\nexport class ApiClient {\n private readonly registry = new ResponseRegistry();\n private cleanupTimer?: NodeJS.Timeout | number;\n private requestIdCounter = 0;\n\n constructor(\n private connection: ConnectionManager,\n private config: NapLinkConfig,\n private logger: Logger\n ) {\n this.startCleanupTimer();\n }\n\n /**\n * 调用API\n * @param method API方法名\n * @param params API参数\n * @param options 调用选项\n */\n async call<T = unknown>(\n method: string,\n params: Record<string, unknown> = {},\n options?: { timeout?: number; retries?: number }\n ): Promise<T> {\n const timeout = options?.timeout ?? this.config.api.timeout;\n const retries = options?.retries ?? this.config.api.retries;\n\n return withRetry(\n () => this.sendRequest<T>(method, params, timeout),\n retries,\n method,\n this.logger,\n this.delay.bind(this)\n );\n }\n\n /**\n * 调用流式 API(NapCat stream-action)\n * 会持续产出 data.type=stream 的分片包,并在 data.type=response 时结束。\n */\n callStream<TPacket = unknown, TFinal = unknown>(\n method: string,\n params: Record<string, unknown> = {},\n options?: { timeout?: number }\n ): { packets: AsyncIterable<TPacket>; result: Promise<TFinal> } {\n const timeout = options?.timeout ?? this.config.api.timeout;\n const queue = new AsyncQueue<TPacket>();\n\n const result = this.sendRequest<TFinal>(method, params, timeout, {\n onPacket: (packet) => queue.push(packet as TPacket),\n onEnd: () => queue.close(),\n onError: (error) => queue.fail(error),\n });\n\n return { packets: queue, result };\n }\n\n /**\n * 处理API响应\n * 由连接管理器调用\n */\n handleResponse(echo: string, response: ApiResponseEnvelope): void {\n const request = this.registry.get(echo);\n if (!request) {\n // 流式响应可能会产生多条分片包;如果请求已结束,这里不应刷屏\n if (response?.stream === 'stream-action') {\n this.logger.debug(`收到未知流式响应: ${echo}`);\n } else {\n this.logger.warn(`收到未知请求的响应: ${echo}`);\n }\n return;\n }\n\n const isStreamAction =\n response?.stream === 'stream-action' ||\n (typeof response?.data?.type === 'string' &&\n ['stream', 'response', 'reset', 'error'].includes(response.data.type));\n\n // 检查响应状态\n if (response.status === 'ok' || response.retcode === 0) {\n if (isStreamAction) {\n const packet = response.data;\n const packetType = packet?.type;\n\n // callStream() 模式:同一次请求会收到多包(file_info / file_chunk / file_complete)\n if (request.onPacket) {\n // 任意分片包都会刷新超时,避免大文件下载被超时打断\n this.registry.refresh(echo);\n\n request.onPacket(packet);\n if (packetType === 'response') {\n this.logger.debug(`API流式完成: ${request.method}`);\n this.registry.resolve(echo, packet);\n request.onEnd?.();\n }\n return;\n }\n\n // 普通 call():兼容 stream-action 但只有单包响应(如 upload_file_stream 的 chunk_received)\n this.logger.debug(`API成功(stream): ${request.method}`);\n this.registry.resolve(echo, packet);\n return;\n }\n\n this.logger.debug(`API成功: ${request.method}`);\n this.registry.resolve(echo, response.data);\n } else {\n this.logger.warn(`API失败: ${request.method}`, {\n retcode: response.retcode,\n message: response.message,\n });\n const error = new ApiError(\n request.method,\n typeof response.retcode === 'number' ? response.retcode : -1,\n typeof response.message === 'string' ? response.message : 'Unknown API error',\n response.wording\n );\n request.onError?.(error);\n this.registry.reject(echo, error);\n }\n }\n\n /**\n * 销毁API客户端\n */\n destroy(): void {\n this.clearPendingRequests('API客户端已销毁');\n\n // 停止清理定时器\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer as NodeJS.Timeout);\n this.cleanupTimer = undefined;\n }\n }\n\n /**\n * 清理所有待处理请求,但保留客户端可继续使用。\n * 适用于临时断线、主动 disconnect 后再次 connect 的场景。\n */\n clearPendingRequests(reason: string): void {\n this.registry.clearAll(reason);\n }\n\n /**\n * 发送API请求\n */\n private sendRequest<T>(\n method: string,\n params: Record<string, unknown>,\n timeout: number,\n hooks?: {\n onPacket?: (packet: unknown) => void;\n onEnd?: () => void;\n onError?: (error: Error) => void;\n }\n ): Promise<T> {\n return new Promise((resolve, reject) => {\n const echo = this.generateRequestId();\n\n this.logger.debug(`发送API请求: ${method}`, { echo, params });\n\n // 设置超时定时器\n this.registry.add(\n echo,\n {\n resolve: (data) => resolve(data as T),\n reject: (error) => reject(error),\n createdAt: Date.now(),\n method,\n timeoutMs: timeout,\n ...(hooks ?? {}),\n },\n timeout\n );\n\n // 发送请求\n try {\n if (!this.connection.isConnected()) {\n throw new ConnectionClosedError(-1, '连接未建立,请先调用 connect()');\n }\n const { payload } = buildRequestPayload(method, params, echo);\n this.connection.send(payload);\n } catch (error) {\n this.registry.reject(echo, error as Error);\n hooks?.onError?.(error as Error);\n reject(error);\n }\n });\n }\n\n /**\n * 延迟\n */\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * 生成请求ID\n */\n private generateRequestId(): string {\n return `naplink_${Date.now()}_${this.requestIdCounter++}`;\n }\n\n /**\n * 启动清理定时器\n * 定期清理超时的待处理请求\n */\n private startCleanupTimer(): void {\n this.cleanupTimer = setInterval(() => {\n const now = Date.now();\n const timeout = this.config.api.timeout;\n\n this.registry.cleanupStale(now, timeout * 2, (method, echo) => {\n this.logger.warn(`清理超时请求: ${method}`, { echo });\n });\n }, 60000); // 每分钟清理一次\n }\n}\n","import EventEmitter from 'events';\nimport type { Logger } from '../types/config';\nimport type { MetaEvent, MessageEvent, NoticeEvent, OneBotEvent, RequestEvent } from '../types/onebot';\n\ntype UnknownEventPayload = Record<string, unknown> & {\n post_type?: string;\n sub_type?: string;\n message_type?: string;\n notice_type?: string;\n meta_event_type?: string;\n request_type?: string;\n};\ntype RoutedEventPayload = OneBotEvent | UnknownEventPayload;\n\n/**\n * 事件路由器\n * 负责解析OneBot事件并分发到相应的事件处理器\n */\nexport class EventRouter extends EventEmitter {\n private anyListeners: ((event: string | symbol, data: RoutedEventPayload) => void)[] = [];\n\n constructor(private logger: Logger) {\n super();\n }\n\n /**\n * 监听所有事件\n */\n onAny(listener: (event: string | symbol, data: RoutedEventPayload) => void): this {\n this.anyListeners.push(listener);\n return this;\n }\n\n /**\n * 重写emit以支持onAny\n */\n override emit(event: string | symbol, ...args: [RoutedEventPayload]): boolean {\n // 先调用anyListeners\n this.anyListeners.forEach((listener) => {\n try {\n listener(event, args[0]);\n } catch (error) {\n this.logger.error('onAny listener error', error as Error);\n }\n });\n\n return super.emit(event, ...args);\n }\n\n /**\n * 路由消息到相应的事件\n * @param data 原始消息数据\n */\n route(data: RoutedEventPayload): void {\n try {\n const postType = data.post_type;\n const messageType = 'message_type' in data ? data.message_type : undefined;\n const noticeType = 'notice_type' in data ? data.notice_type : undefined;\n\n if (!postType) {\n this.logger.warn('收到无效消息: 缺少 post_type', data);\n return;\n }\n\n this.logger.debug(`路由事件: ${postType}`, {\n messageType,\n noticeType,\n });\n\n // 根据 post_type 分发\n switch (postType) {\n case 'meta_event':\n this.routeMetaEvent(data);\n break;\n case 'message':\n this.routeMessage(data);\n break;\n case 'message_sent':\n this.routeMessageSent(data);\n break;\n case 'notice':\n this.routeNotice(data);\n break;\n case 'request':\n this.routeRequest(data);\n break;\n default:\n this.logger.warn(`未知的 post_type: ${postType}`);\n this.emit('unknown', data);\n }\n\n // 同时触发原始事件\n this.emit('raw', data);\n } catch (error) {\n this.logger.error('事件路由失败', error as Error, data);\n }\n }\n\n /**\n * 路由元事件\n */\n private routeMetaEvent(data: RoutedEventPayload): void {\n if (!isMetaEventPayload(data))\n return\n\n const type = data.meta_event_type;\n const events = [`meta_event`, `meta_event.${type}`];\n const subType = 'sub_type' in data ? data.sub_type : undefined;\n\n if (type === 'lifecycle' && subType) {\n events.push(`meta_event.lifecycle.${subType}`);\n }\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由消息事件\n */\n private routeMessage(data: RoutedEventPayload): void {\n if (!isMessageEventPayload(data))\n return\n\n const messageType = data.message_type;\n const subType = data.sub_type;\n\n const events = [\n 'message',\n `message.${messageType}`,\n `message.${messageType}.${subType}`,\n ];\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由发送消息事件\n */\n private routeMessageSent(data: RoutedEventPayload): void {\n if (!isMessageEventPayload(data))\n return\n\n const messageType = data.message_type;\n const subType = data.sub_type;\n\n const events = [\n 'message_sent',\n `message_sent.${messageType}`,\n `message_sent.${messageType}.${subType}`,\n ];\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由通知事件\n */\n private routeNotice(data: RoutedEventPayload): void {\n if (!isNoticeEventPayload(data))\n return\n\n const noticeType = data.notice_type;\n const subType = 'sub_type' in data ? data.sub_type : undefined;\n\n const events = ['notice', `notice.${noticeType}`];\n\n if (subType) {\n events.push(`notice.${noticeType}.${subType}`);\n }\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由请求事件\n */\n private routeRequest(data: RoutedEventPayload): void {\n if (!isRequestEventPayload(data))\n return\n\n const requestType = data.request_type;\n const subType = 'sub_type' in data ? data.sub_type : undefined;\n\n const events = ['request', `request.${requestType}`];\n\n if (subType) {\n events.push(`request.${requestType}.${subType}`);\n }\n\n this.emitEvents(events, data);\n }\n\n /**\n * 触发多个事件\n */\n private emitEvents(events: string[], data: RoutedEventPayload): void {\n for (const event of events) {\n this.logger.debug(`触发事件: ${event}`);\n this.emit(event, data);\n }\n }\n}\n\nfunction isMessageEventPayload(data: RoutedEventPayload): data is MessageEvent | UnknownEventPayload {\n return data.post_type === 'message' || data.post_type === 'message_sent';\n}\n\nfunction isNoticeEventPayload(data: RoutedEventPayload): data is NoticeEvent | UnknownEventPayload {\n return data.post_type === 'notice';\n}\n\nfunction isRequestEventPayload(data: RoutedEventPayload): data is RequestEvent | UnknownEventPayload {\n return data.post_type === 'request';\n}\n\nfunction isMetaEventPayload(data: RoutedEventPayload): data is MetaEvent | UnknownEventPayload {\n return data.post_type === 'meta_event';\n}\n","import type { Logger } from '../types/config';\nimport type { ApiClient } from './api-client';\nimport type { EventRouter } from './event-router';\n\nexport class MessageDispatcher {\n constructor(\n private apiClient: ApiClient,\n private eventRouter: EventRouter,\n private logger: Logger\n ) { }\n\n /**\n * 分发消息\n * @param message WebSocket 接收到的原始字符串消息\n */\n dispatch(message: string): void {\n try {\n const data = JSON.parse(message);\n\n // API响应包可能存在 echo=null(如 token 校验失败),不能只依赖 truthy echo。\n const isApiResponse =\n data &&\n typeof data === 'object' &&\n ('echo' in data || 'status' in data || 'retcode' in data);\n\n if (isApiResponse) {\n // 忽略心跳响应\n if (typeof data.echo === 'string' && data.echo.startsWith('heartbeat_')) {\n return;\n }\n this.apiClient.handleResponse(data.echo, data);\n } else {\n // 否则是事件\n this.eventRouter.route(data);\n }\n } catch (error) {\n this.logger.error('消息解析失败', error as Error, { message });\n }\n }\n}\n","import EventEmitter from 'events';\nimport { ConnectionState } from './state';\n\n/**\n * 处理连接状态变化并触发相应事件\n * @param emitter 事件发射器 (通常是 NapLink 实例)\n * @param state 新的连接状态\n * @param wasReconnecting 是否从重连状态转换而来\n */\nexport function handleConnectionStateChange(\n emitter: EventEmitter,\n state: ConnectionState,\n wasReconnecting: boolean = false\n): void {\n emitter.emit('state_change', state);\n\n // 触发具体的状态事件\n switch (state) {\n case ConnectionState.CONNECTED:\n emitter.emit('connect');\n // 如果是从重连状态恢复,发送 connection:restored 事件\n if (wasReconnecting) {\n emitter.emit('connection:restored', { timestamp: Date.now() });\n }\n break;\n case ConnectionState.DISCONNECTED:\n emitter.emit('disconnect');\n break;\n case ConnectionState.RECONNECTING:\n emitter.emit('reconnecting');\n break;\n }\n}\n","import type { ApiClient } from '../../core/api-client';\nimport type { GroupHonorInfo, GroupSystemMessages } from '../../types/onebot';\n\nexport type MessageApi = {\n // 基础消息\n sendMessage(params: {\n message_type?: 'private' | 'group';\n user_id?: number | string;\n group_id?: number | string;\n message: any;\n auto_escape?: boolean;\n }): Promise<any>;\n sendPrivateMessage(userId: number | string, message: any): Promise<any>;\n sendGroupMessage(groupId: number | string, message: any): Promise<any>;\n deleteMessage(messageId: number | string): Promise<any>;\n getMessage(messageId: number | string): Promise<any>;\n getForwardMessage(id: string): Promise<any>;\n sendGroupForwardMessage(groupId: number | string, messages: any[]): Promise<any>;\n\n // 精华 / 已读 / @全体剩余\n setEssenceMessage(messageId: number | string): Promise<any>;\n deleteEssenceMessage(messageId: number | string): Promise<any>;\n getEssenceMessageList(groupId: number | string): Promise<any>;\n markMessageAsRead(messageId: number | string): Promise<any>;\n markGroupMsgAsRead(groupId: number | string): Promise<any>;\n markPrivateMsgAsRead(userId: number | string): Promise<any>;\n markAllMsgAsRead(): Promise<any>;\n getGroupAtAllRemain(groupId: number | string): Promise<number>;\n\n // 系统/荣誉消息\n getGroupSystemMsg(): Promise<GroupSystemMessages>;\n getGroupHonorInfo(\n groupId: number | string,\n type: 'all' | 'talkative' | 'performer' | 'legend' | 'strong_newbie' | 'emotion'\n ): Promise<GroupHonorInfo>;\n\n // 消息历史 / 最近会话(NapCat 扩展)\n getGroupMsgHistory(params: {\n group_id: number | string;\n message_seq: number | string;\n count: number;\n reverse_order?: boolean;\n }): Promise<any>;\n getFriendMsgHistory(params: {\n user_id: number | string;\n message_seq: number | string;\n count: number;\n reverse_order?: boolean;\n }): Promise<any>;\n getRecentContact(count: number): Promise<any>;\n\n // 表情回应(NapCat 扩展)\n setMsgEmojiLike(messageId: number | string, emojiId: number, set: boolean): Promise<any>;\n fetchEmojiLike(params: {\n message_id: number | string;\n emojiId: string;\n emojiType: string;\n group_id?: number | string;\n user_id?: number | string;\n count?: number;\n cookie?: string;\n }): Promise<any>;\n\n // 戳一戳(NapCat 扩展)\n sendGroupPoke(groupId: number | string, userId: number | string): Promise<any>;\n sendFriendPoke(userId: number | string): Promise<any>;\n sendPoke(targetId: number | string, groupId?: number | string): Promise<any>;\n};\n\nexport function createMessageApi(client: ApiClient): MessageApi {\n return {\n sendMessage(params) {\n return client.call('send_msg', params);\n },\n sendPrivateMessage(userId, message) {\n return client.call('send_private_msg', { user_id: userId, message });\n },\n sendGroupMessage(groupId, message) {\n return client.call('send_group_msg', { group_id: groupId, message });\n },\n deleteMessage(messageId) {\n return client.call('delete_msg', { message_id: messageId });\n },\n getMessage(messageId) {\n return client.call('get_msg', { message_id: messageId });\n },\n getForwardMessage(id) {\n return client.call('get_forward_msg', { id });\n },\n sendGroupForwardMessage(groupId, messages) {\n return client.call('send_group_forward_msg', { group_id: groupId, messages });\n },\n setEssenceMessage(messageId) {\n return client.call('set_essence_msg', { message_id: messageId });\n },\n deleteEssenceMessage(messageId) {\n return client.call('delete_essence_msg', { message_id: messageId });\n },\n getEssenceMessageList(groupId) {\n return client.call('get_essence_msg_list', { group_id: groupId });\n },\n markMessageAsRead(messageId) {\n return client.call('mark_msg_as_read', { message_id: messageId });\n },\n markGroupMsgAsRead(groupId) {\n return client.call('mark_group_msg_as_read', { group_id: groupId });\n },\n markPrivateMsgAsRead(userId) {\n return client.call('mark_private_msg_as_read', { user_id: userId });\n },\n markAllMsgAsRead() {\n return client.call('_mark_all_as_read');\n },\n getGroupAtAllRemain(groupId) {\n return client.call<number>('get_group_at_all_remain', { group_id: groupId });\n },\n getGroupSystemMsg() {\n return client.call<GroupSystemMessages>('get_group_system_msg');\n },\n getGroupHonorInfo(groupId, type) {\n return client.call<GroupHonorInfo>('get_group_honor_info', { group_id: groupId, type });\n },\n getGroupMsgHistory(params) {\n return client.call('get_group_msg_history', params);\n },\n getFriendMsgHistory(params) {\n return client.call('get_friend_msg_history', params);\n },\n getRecentContact(count) {\n return client.call('get_recent_contact', { count });\n },\n setMsgEmojiLike(messageId, emojiId, set) {\n return client.call('set_msg_emoji_like', { message_id: messageId, emoji_id: emojiId, set });\n },\n fetchEmojiLike(params) {\n return client.call('fetch_emoji_like', params);\n },\n sendGroupPoke(groupId, userId) {\n return client.call('group_poke', { group_id: groupId, user_id: userId });\n },\n sendFriendPoke(userId) {\n return client.call('friend_poke', { user_id: userId });\n },\n sendPoke(targetId, groupId) {\n return client.call('send_poke', groupId ? { group_id: groupId, target_id: targetId } : { user_id: targetId });\n },\n };\n}\n","import type { ApiClient } from '../../core/api-client';\nimport type { Logger } from '../../types/config';\nimport type { OneBotMessageSegment } from '../../types/message-segment';\n\ntype MediaFileResponse = {\n file?: string;\n url?: string;\n};\n\ntype HydratableSegment = Extract<\n OneBotMessageSegment,\n { type: 'image' | 'video' | 'record' | 'audio' | 'file' }\n>;\n\nexport type MediaApi = {\n getImage(file: string): Promise<MediaFileResponse>;\n getRecord(file: string, outFormat?: string): Promise<MediaFileResponse>;\n getFile(file: string): Promise<MediaFileResponse>;\n hydrateMedia(message: OneBotMessageSegment[]): Promise<void>;\n};\n\nexport function createMediaApi(client: ApiClient, logger: Logger): MediaApi {\n const api = {\n getImage(file: string) {\n return client.call<MediaFileResponse>('get_image', { file });\n },\n getRecord(file: string, outFormat?: string) {\n return client.call<MediaFileResponse>('get_record', { file, out_format: outFormat });\n },\n getFile(file: string) {\n return client.call<MediaFileResponse>('get_file', { file });\n },\n async hydrateMedia(message: OneBotMessageSegment[]) {\n if (!Array.isArray(message)) return;\n\n await Promise.all(message.map(async (segment) => {\n if (!isHydratableSegment(segment)) return;\n\n const type = segment?.type;\n const data = segment?.data;\n if (!type || !data) return;\n\n const fileId = data.file ?? data.file_id;\n // 如果已经是 http 或 file 协议,或者是 base64 (虽然 base64 一般不走这里),则跳过\n if (typeof fileId === 'string' && !/^https?:\\/\\//.test(fileId) && !fileId.startsWith('file://')) {\n try {\n // 优先尝试通用 get_file\n const res = await api.getFile(fileId);\n const hydratedUrl = res?.file ?? res?.url;\n if (hydratedUrl) {\n data.url = hydratedUrl;\n data.file = hydratedUrl;\n return;\n }\n\n // 针对特定类型的降级/专用获取\n if (type === 'record' || type === 'audio') {\n const rec = await api.getRecord(fileId, 'mp3');\n const recUrl = rec?.file ?? rec?.url;\n if (recUrl) {\n data.url = recUrl;\n data.file = recUrl;\n }\n } else if (type === 'image') {\n const img = await api.getImage(fileId);\n const imgUrl = img?.file ?? img?.url;\n if (imgUrl) {\n data.url = imgUrl;\n data.file = imgUrl;\n }\n }\n } catch (e) {\n logger.debug(`Failed to hydrate media for ${type}: ${fileId}`, e);\n }\n }\n }));\n }\n };\n return api;\n}\n\nfunction isHydratableSegment(segment: OneBotMessageSegment): segment is HydratableSegment {\n return ['image', 'video', 'record', 'audio', 'file'].includes(segment.type);\n}\n","import type { ApiClient } from '../../core/api-client';\n\nexport type AccountApi = {\n getLoginInfo(): Promise<any>;\n getStatus(): Promise<any>;\n getFriendList(): Promise<any>;\n getGroupList(): Promise<any>;\n getGroupInfo(groupId: number | string, noCache?: boolean): Promise<any>;\n getGroupMemberList(groupId: number | string): Promise<any>;\n getGroupMemberInfo(groupId: number | string, userId: number | string, noCache?: boolean): Promise<any>;\n getStrangerInfo(userId: number | string, noCache?: boolean): Promise<any>;\n getVersionInfo(): Promise<any>;\n};\n\nexport function createAccountApi(client: ApiClient): AccountApi {\n return {\n getLoginInfo() {\n return client.call('get_login_info');\n },\n getStatus() {\n return client.call('get_status');\n },\n getFriendList() {\n return client.call('get_friend_list');\n },\n getGroupList() {\n return client.call('get_group_list');\n },\n getGroupInfo(groupId, noCache = false) {\n return client.call('get_group_info', { group_id: groupId, no_cache: noCache });\n },\n getGroupMemberList(groupId) {\n return client.call('get_group_member_list', { group_id: groupId });\n },\n getGroupMemberInfo(groupId, userId, noCache = false) {\n return client.call('get_group_member_info', {\n group_id: groupId,\n user_id: userId,\n no_cache: noCache,\n });\n },\n getStrangerInfo(userId, noCache = false) {\n return client.call('get_stranger_info', { user_id: userId, no_cache: noCache });\n },\n getVersionInfo() {\n return client.call('get_version_info');\n },\n };\n}\n","import type { ApiClient } from '../../core/api-client';\n\nexport type GroupApi = {\n setGroupBan(groupId: number | string, userId: number | string, duration?: number): Promise<any>;\n unsetGroupBan(groupId: number | string, userId: number | string): Promise<any>;\n setGroupWholeBan(groupId: number | string, enable?: boolean): Promise<any>;\n setGroupKick(groupId: number | string, userId: number | string, rejectAddRequest?: boolean): Promise<any>;\n setGroupLeave(groupId: number | string, isDismiss?: boolean): Promise<any>;\n setGroupCard(groupId: number | string, userId: number | string, card: string): Promise<any>;\n setGroupName(groupId: number | string, groupName: string): Promise<any>;\n setGroupAdmin(groupId: number | string, userId: number | string, enable?: boolean): Promise<any>;\n setGroupAnonymousBan(groupId: number | string, anonymousFlag: string, duration?: number): Promise<any>;\n setGroupSpecialTitle(\n groupId: number | string,\n userId: number | string,\n specialTitle: string,\n duration?: number\n ): Promise<any>;\n sendLike(userId: number | string, times?: number): Promise<any>;\n};\n\nexport function createGroupApi(client: ApiClient): GroupApi {\n return {\n setGroupBan(groupId, userId, duration = 30 * 60) {\n return client.call('set_group_ban', { group_id: groupId, user_id: userId, duration });\n },\n unsetGroupBan(groupId, userId) {\n return client.call('set_group_ban', { group_id: groupId, user_id: userId, duration: 0 });\n },\n setGroupWholeBan(groupId, enable = true) {\n return client.call('set_group_whole_ban', { group_id: groupId, enable });\n },\n setGroupKick(groupId, userId, rejectAddRequest = false) {\n return client.call('set_group_kick', {\n group_id: groupId,\n user_id: userId,\n reject_add_request: rejectAddRequest,\n });\n },\n setGroupLeave(groupId, isDismiss = false) {\n return client.call('set_group_leave', { group_id: groupId, is_dismiss: isDismiss });\n },\n setGroupCard(groupId, userId, card) {\n return client.call('set_group_card', { group_id: groupId, user_id: userId, card });\n },\n setGroupName(groupId, groupName) {\n return client.call('set_group_name', { group_id: groupId, group_name: groupName });\n },\n setGroupAdmin(groupId, userId, enable = true) {\n return client.call('set_group_admin', { group_id: groupId, user_id: userId, enable });\n },\n setGroupAnonymousBan(groupId, anonymousFlag, duration = 30 * 60) {\n return client.call('set_group_anonymous_ban', {\n group_id: groupId,\n anonymous_flag: anonymousFlag,\n duration,\n });\n },\n setGroupSpecialTitle(groupId, userId, specialTitle, duration = -1) {\n return client.call('set_group_special_title', {\n group_id: groupId,\n user_id: userId,\n special_title: specialTitle,\n duration,\n });\n },\n sendLike(userId, times = 1) {\n return client.call('send_like', { user_id: userId, times });\n },\n };\n}\n","import { promises as fs, createWriteStream } from 'fs';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { pipeline } from 'stream/promises';\nimport type { ApiClient } from '../../core/api-client';\n\nexport type FileApi = {\n uploadGroupFile(groupId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream, name: string, folder?: string, uploadFile?: boolean): Promise<any>;\n uploadPrivateFile(userId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream, name: string, uploadFile?: boolean): Promise<any>;\n setGroupPortrait(groupId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream): Promise<any>;\n\n getGroupFileSystemInfo(groupId: number | string): Promise<any>;\n getGroupRootFiles(groupId: number | string): Promise<any>;\n getGroupFilesByFolder(groupId: number | string, folderId: string): Promise<any>;\n getGroupFileUrl(groupId: number | string, fileId: string, busid?: number): Promise<any>;\n deleteGroupFile(groupId: number | string, fileId: string, busid?: number): Promise<any>;\n createGroupFileFolder(groupId: number | string, name: string, parentId?: string): Promise<any>;\n deleteGroupFolder(groupId: number | string, folderId: string): Promise<any>;\n\n downloadFile(url: string, threadCount?: number, headers?: Record<string, string>): Promise<any>;\n};\n\nexport function createFileApi(client: ApiClient): FileApi {\n const normalizeFileInput = async (file: string | Buffer | Uint8Array | NodeJS.ReadableStream, name: string) => {\n if (typeof file === 'string') return file;\n\n const tempPath = join(tmpdir(), `${randomUUID()}-${name || 'naplink.tmp'}`);\n\n if (file instanceof Buffer || file instanceof Uint8Array) {\n await fs.writeFile(tempPath, file);\n return tempPath;\n }\n\n await pipeline(file, createWriteStream(tempPath));\n return tempPath;\n };\n\n return {\n async uploadGroupFile(groupId, file, name, folder, uploadFile = true) {\n const normalized = await normalizeFileInput(file, name);\n return client.call('upload_group_file', { group_id: groupId, file: normalized, name, folder, upload_file: uploadFile });\n },\n async uploadPrivateFile(userId, file, name, uploadFile = true) {\n const normalized = await normalizeFileInput(file, name);\n return client.call('upload_private_file', { user_id: userId, file: normalized, name, upload_file: uploadFile });\n },\n async setGroupPortrait(groupId, file) {\n return this.uploadGroupFile(groupId, file as any, 'portrait');\n },\n getGroupFileSystemInfo(groupId) {\n return client.call('get_group_file_system_info', { group_id: groupId });\n },\n getGroupRootFiles(groupId) {\n return client.call('get_group_root_files', { group_id: groupId });\n },\n getGroupFilesByFolder(groupId, folderId) {\n return client.call('get_group_files_by_folder', { group_id: groupId, folder_id: folderId });\n },\n getGroupFileUrl(groupId, fileId, busid) {\n return client.call('get_group_file_url', { group_id: groupId, file_id: fileId, busid });\n },\n deleteGroupFile(groupId, fileId, busid) {\n return client.call('delete_group_file', { group_id: groupId, file_id: fileId, busid });\n },\n createGroupFileFolder(groupId, name, parentId) {\n return client.call('create_group_file_folder', { group_id: groupId, name, parent_id: parentId });\n },\n deleteGroupFolder(groupId, folderId) {\n return client.call('delete_group_folder', { group_id: groupId, folder_id: folderId });\n },\n downloadFile(url, threadCount = 3, headers?: Record<string, string>) {\n return client.call('download_file', { url, thread_count: threadCount, headers });\n },\n };\n}\n","import { randomUUID } from 'crypto';\nimport type { ApiClient } from '../../core/api-client';\nimport { prepareStreamSource, computeSha256, iterateChunks } from '../../core/upload/stream';\nimport { createWriteStream } from 'fs';\nimport { promises as fs } from 'fs';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\n\nexport type StreamApi = {\n uploadFileStream(\n file: string | Buffer | Uint8Array | NodeJS.ReadableStream,\n options?: {\n chunkSize?: number;\n streamId?: string;\n expectedSha256?: string;\n fileRetention?: number;\n filename?: string;\n reset?: boolean;\n verifyOnly?: boolean;\n }\n ): Promise<any>;\n getUploadStreamStatus(streamId: string): Promise<any>;\n\n /**\n * 流式下载文件(原始分片包)\n * - data_type=file_info / file_chunk / file_complete\n * - type=stream / response\n */\n downloadFileStream(fileId: string, options?: { chunkSize?: number }): { packets: AsyncIterable<DownloadStreamPacket>; result: Promise<DownloadStreamPacket> };\n downloadFileStreamToFile(fileId: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: DownloadStreamPacket }>;\n\n downloadFileImageStream(fileId: string, options?: { chunkSize?: number }): { packets: AsyncIterable<DownloadStreamPacket>; result: Promise<DownloadStreamPacket> };\n downloadFileImageStreamToFile(fileId: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: DownloadStreamPacket }>;\n\n downloadFileRecordStream(fileId: string, outFormat?: string, options?: { chunkSize?: number; filename?: string }): { packets: AsyncIterable<DownloadStreamPacket>; result: Promise<DownloadStreamPacket> };\n downloadFileRecordStreamToFile(fileId: string, outFormat?: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: DownloadStreamPacket }>;\n\n cleanStreamTempFile(): Promise<any>;\n};\n\nexport type DownloadStreamPacket = {\n type: 'stream' | 'response' | 'reset' | 'error';\n data_type?: 'file_info' | 'file_chunk' | 'file_complete' | string;\n file_name?: string;\n file_size?: number;\n chunk_size?: number;\n index?: number;\n data?: string;\n size?: number;\n progress?: number;\n base64_size?: number;\n total_chunks?: number;\n total_bytes?: number;\n message?: string;\n width?: number;\n height?: number;\n out_format?: string;\n};\n\nexport function createStreamApi(client: ApiClient): StreamApi {\n const downloadToFile = async (\n action: string,\n params: Record<string, any>,\n filenameHint?: string,\n ): Promise<{ path: string; info?: DownloadStreamPacket }> => {\n const { packets } = client.callStream<DownloadStreamPacket, DownloadStreamPacket>(action, params);\n\n let fileInfo: DownloadStreamPacket | undefined;\n const tempPath = join(tmpdir(), `${randomUUID()}-${filenameHint || 'naplink.download'}`);\n const writeStream = createWriteStream(tempPath);\n\n try {\n for await (const packet of packets) {\n if (packet?.data_type === 'file_info') {\n fileInfo = packet;\n }\n if (packet?.data_type === 'file_chunk' && typeof packet.data === 'string') {\n writeStream.write(Buffer.from(packet.data, 'base64'));\n }\n }\n await new Promise<void>((resolve, reject) => {\n writeStream.once('error', reject);\n writeStream.end(() => resolve());\n });\n return { path: tempPath, info: fileInfo };\n } catch (error) {\n try {\n writeStream.destroy();\n } catch {\n // ignore\n }\n await fs.unlink(tempPath).catch(() => undefined);\n throw error;\n }\n };\n\n return {\n async uploadFileStream(file, options) {\n const chunkSize = options?.chunkSize ?? 256 * 1024;\n const streamId = options?.streamId ?? randomUUID();\n\n const { source, size, filename, cleanupTemp } = await prepareStreamSource(file, options?.filename);\n\n const expectedSha256 = options?.expectedSha256 ?? (await computeSha256(source));\n const totalChunks = Math.ceil(size / chunkSize);\n\n if (options?.reset) {\n await client.call('upload_file_stream', { stream_id: streamId, reset: true });\n }\n\n let chunkIndex = 0;\n for await (const chunk of iterateChunks(source, size, chunkSize)) {\n const payload: any = {\n stream_id: streamId,\n chunk_data: chunk.toString('base64'),\n chunk_index: chunkIndex,\n total_chunks: totalChunks,\n file_size: size,\n expected_sha256: expectedSha256,\n filename,\n };\n if (options?.fileRetention != null) {\n payload.file_retention = options.fileRetention;\n }\n if (options?.verifyOnly) {\n payload.verify_only = true;\n }\n\n await client.call('upload_file_stream', payload);\n chunkIndex++;\n }\n\n const completion = await client.call('upload_file_stream', {\n stream_id: streamId,\n is_complete: true,\n });\n\n await cleanupTemp?.();\n return completion;\n },\n\n getUploadStreamStatus(streamId: string) {\n return client.call('upload_file_stream', { stream_id: streamId, verify_only: true });\n },\n\n downloadFileStream(fileId, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return client.callStream<DownloadStreamPacket, DownloadStreamPacket>('download_file_stream', {\n file: fileId,\n chunk_size: chunkSize,\n });\n },\n async downloadFileStreamToFile(fileId, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return downloadToFile('download_file_stream', { file: fileId, chunk_size: chunkSize }, options?.filename);\n },\n\n downloadFileImageStream(fileId, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return client.callStream<DownloadStreamPacket, DownloadStreamPacket>('download_file_image_stream', {\n file: fileId,\n chunk_size: chunkSize,\n });\n },\n async downloadFileImageStreamToFile(fileId, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return downloadToFile('download_file_image_stream', { file: fileId, chunk_size: chunkSize }, options?.filename);\n },\n\n downloadFileRecordStream(fileId, outFormat, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return client.callStream<DownloadStreamPacket, DownloadStreamPacket>('download_file_record_stream', {\n file: fileId,\n chunk_size: chunkSize,\n out_format: outFormat,\n });\n },\n async downloadFileRecordStreamToFile(fileId, outFormat, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return downloadToFile(\n 'download_file_record_stream',\n { file: fileId, chunk_size: chunkSize, out_format: outFormat },\n options?.filename,\n );\n },\n\n cleanStreamTempFile() {\n return client.call('clean_stream_temp_file');\n },\n };\n}\n","import { promises as fs, createWriteStream, createReadStream } from 'fs';\nimport { tmpdir } from 'os';\nimport { join, basename } from 'path';\nimport { randomUUID, createHash } from 'crypto';\nimport { pipeline } from 'stream/promises';\n\nexport type StreamSource = {\n source: string | Buffer;\n size: number;\n filename: string;\n cleanupTemp?: () => Promise<void>;\n};\n\nexport async function prepareStreamSource(\n file: string | Buffer | Uint8Array | NodeJS.ReadableStream,\n overrideName?: string\n): Promise<StreamSource> {\n if (typeof file === 'string') {\n const stats = await fs.stat(file);\n return { source: file, size: stats.size, filename: overrideName || basename(file) };\n }\n\n if (file instanceof Buffer || file instanceof Uint8Array) {\n return { source: Buffer.from(file), size: file.length, filename: overrideName || 'upload.bin' };\n }\n\n // ReadableStream -> 写入临时文件\n const tempPath = join(tmpdir(), `${randomUUID()}-upload.tmp`);\n await pipeline(file, createWriteStream(tempPath));\n const stats = await fs.stat(tempPath);\n return {\n source: tempPath,\n size: stats.size,\n filename: overrideName || basename(tempPath),\n cleanupTemp: async () => {\n try { await fs.unlink(tempPath); } catch { /* ignore */ }\n }\n };\n}\n\nexport async function* iterateChunks(source: string | Buffer, size: number, chunkSize: number): AsyncGenerator<Buffer> {\n if (typeof source === 'string') {\n const stream = createReadStream(source, { highWaterMark: chunkSize });\n for await (const chunk of stream) {\n yield chunk as Buffer;\n }\n } else {\n let offset = 0;\n while (offset < size) {\n const end = Math.min(offset + chunkSize, size);\n yield source.slice(offset, end);\n offset = end;\n }\n }\n}\n\nexport async function computeSha256(source: string | Buffer): Promise<string> {\n const hash = createHash('sha256');\n\n if (typeof source === 'string') {\n const stream = createReadStream(source);\n for await (const chunk of stream) {\n hash.update(chunk as Buffer);\n }\n } else {\n hash.update(source);\n }\n\n return hash.digest('hex');\n}\n","import type { ApiClient } from '../../core/api-client';\n\nexport type RequestApi = {\n handleFriendRequest(flag: string, approve?: boolean, remark?: string): Promise<any>;\n handleGroupRequest(flag: string, subType: 'add' | 'invite', approve?: boolean, reason?: string): Promise<any>;\n};\n\nexport function createRequestApi(client: ApiClient): RequestApi {\n return {\n handleFriendRequest(flag, approve = true, remark?: string) {\n return client.call('set_friend_add_request', { flag, approve, remark });\n },\n handleGroupRequest(flag, subType, approve = true, reason?: string) {\n return client.call('set_group_add_request', { flag, sub_type: subType, approve, reason });\n },\n };\n}\n","import type { ApiClient } from '../../core/api-client';\n\nexport type SystemApi = {\n getOnlineClients(noCache?: boolean): Promise<any>;\n getRobotUinRange(): Promise<any>;\n canSendImage(): Promise<any>;\n canSendRecord(): Promise<any>;\n\n getCookies(domain: string): Promise<any>;\n getCsrfToken(): Promise<any>;\n getCredentials(domain: string): Promise<any>;\n\n setInputStatus(userId: number | string, eventType: number): Promise<any>;\n\n ocrImage(image: string, dot?: boolean): Promise<any>;\n translateEn2zh(words: string[]): Promise<any>;\n\n checkUrlSafely(url: string): Promise<any>;\n handleQuickOperation(context: any, operation: any): Promise<any>;\n\n getModelShow(model: string): Promise<any>;\n setModelShow(model: string, modelShow: string): Promise<any>;\n\n getPacketStatus(): Promise<any>;\n};\n\nexport function createSystemApi(client: ApiClient): SystemApi {\n return {\n getOnlineClients(noCache = false) {\n return client.call('get_online_clients', { no_cache: noCache });\n },\n getRobotUinRange() {\n return client.call('get_robot_uin_range');\n },\n canSendImage() {\n return client.call('can_send_image');\n },\n canSendRecord() {\n return client.call('can_send_record');\n },\n getCookies(domain: string) {\n return client.call('get_cookies', { domain });\n },\n getCsrfToken() {\n return client.call('get_csrf_token');\n },\n getCredentials(domain: string) {\n return client.call('get_credentials', { domain });\n },\n setInputStatus(userId: number | string, eventType: number) {\n // NapCat 侧字段是 event_type;WebUI 里也有 eventType 的旧写法\n return client.call('set_input_status', { user_id: userId, event_type: eventType, eventType });\n },\n ocrImage(image: string, dot = false) {\n return client.call(dot ? '.ocr_image' : 'ocr_image', { image });\n },\n translateEn2zh(words: string[]) {\n return client.call('translate_en2zh', { words });\n },\n checkUrlSafely(url: string) {\n return client.call('check_url_safely', { url });\n },\n handleQuickOperation(context: any, operation: any) {\n return client.call('.handle_quick_operation', { context, operation });\n },\n getModelShow(model: string) {\n return client.call('_get_model_show', { model });\n },\n setModelShow(model: string, modelShow: string) {\n return client.call('_set_model_show', { model, model_show: modelShow });\n },\n getPacketStatus() {\n return client.call('nc_get_packet_status');\n },\n };\n}\n\n","import type { ApiClient } from '../../core/api-client';\n\nexport type NapCatApi = {\n // RKey\n getRkeyEx(): Promise<any>;\n getRkeyServer(): Promise<any>;\n getRkey(): Promise<any>;\n\n // 好友/群扩展\n setFriendRemark(userId: number | string, remark: string): Promise<any>;\n deleteFriend(userId: number | string): Promise<any>;\n getUnidirectionalFriendList(): Promise<any>;\n\n setGroupRemark(groupId: number | string, remark: string): Promise<any>;\n getGroupInfoEx(groupId: number | string): Promise<any>;\n getGroupDetailInfo(groupId: number | string): Promise<any>;\n getGroupIgnoredNotifies(): Promise<any>;\n getGroupShutList(groupId: number | string): Promise<any>;\n\n // 合并转发(扩展)\n sendPrivateForwardMessage(params: { user_id: number | string; messages: any[]; news?: any[]; prompt?: string; summary?: string; source?: string }): Promise<any>;\n forwardFriendSingleMsg(userId: number | string, messageId: number | string): Promise<any>;\n forwardGroupSingleMsg(groupId: number | string, messageId: number | string): Promise<any>;\n sendForwardMsg(params: { group_id?: number | string; user_id?: number | string; messages: any[]; news?: any[]; prompt?: string; summary?: string; source?: string }): Promise<any>;\n\n // 群公告(go-cqhttp 扩展)\n sendGroupNotice(params: {\n group_id: number | string;\n content: string;\n image?: string;\n pinned?: number | string;\n type?: number | string;\n confirm_required?: number | string;\n is_show_edit_card?: number | string;\n tip_window_type?: number | string;\n }): Promise<any>;\n getGroupNotice(groupId: number | string): Promise<any>;\n delGroupNotice(groupId: number | string, noticeId: string): Promise<any>;\n\n // 在线状态(扩展)\n setOnlineStatus(status: number | string, extStatus: number | string, batteryStatus: number | string): Promise<any>;\n setDiyOnlineStatus(faceId: number | string, wording?: string, faceType?: number | string): Promise<any>;\n\n // Ark / 小程序\n sendArkShare(params: { user_id?: number | string; group_id?: number | string; phone_number?: string }): Promise<any>;\n sendGroupArkShare(groupId: number | string): Promise<any>;\n getMiniAppArk(payload: any): Promise<any>;\n\n // AI 语音\n getAiCharacters(groupId: number | string, chatType?: number | string): Promise<any>;\n getAiRecord(groupId: number | string, character: string, text: string): Promise<any>;\n sendGroupAiRecord(groupId: number | string, character: string, text: string): Promise<any>;\n\n // 群打卡\n setGroupSign(groupId: number | string): Promise<any>;\n sendGroupSign(groupId: number | string): Promise<any>;\n\n // 其他\n fetchCustomFace(params?: any): Promise<any>;\n getEmojiLikes(params: { message_id: string; emoji_id: string; emoji_type?: string; group_id?: string; count?: number }): Promise<any>;\n getClientkey(): Promise<any>;\n clickInlineKeyboardButton(params: {\n group_id: number | string;\n bot_appid: string;\n button_id?: string;\n callback_data?: string;\n msg_seq?: string;\n }): Promise<any>;\n};\n\nexport function createNapCatApi(client: ApiClient): NapCatApi {\n return {\n getRkeyEx() {\n return client.call('get_rkey');\n },\n getRkeyServer() {\n return client.call('get_rkey_server');\n },\n getRkey() {\n return client.call('nc_get_rkey');\n },\n setFriendRemark(userId, remark) {\n return client.call('set_friend_remark', { user_id: userId, remark });\n },\n deleteFriend(userId) {\n return client.call('delete_friend', { user_id: userId });\n },\n getUnidirectionalFriendList() {\n return client.call('get_unidirectional_friend_list');\n },\n setGroupRemark(groupId, remark) {\n return client.call('set_group_remark', { group_id: String(groupId), remark });\n },\n getGroupInfoEx(groupId) {\n return client.call('get_group_info_ex', { group_id: groupId });\n },\n getGroupDetailInfo(groupId) {\n return client.call('get_group_detail_info', { group_id: groupId });\n },\n getGroupIgnoredNotifies() {\n return client.call('get_group_ignored_notifies');\n },\n getGroupShutList(groupId) {\n return client.call('get_group_shut_list', { group_id: groupId });\n },\n sendPrivateForwardMessage(params) {\n return client.call('send_private_forward_msg', params);\n },\n forwardFriendSingleMsg(userId, messageId) {\n return client.call('forward_friend_single_msg', { user_id: userId, message_id: messageId });\n },\n forwardGroupSingleMsg(groupId, messageId) {\n return client.call('forward_group_single_msg', { group_id: groupId, message_id: messageId });\n },\n sendForwardMsg(params) {\n return client.call('send_forward_msg', params);\n },\n sendGroupNotice(params) {\n return client.call('_send_group_notice', params);\n },\n getGroupNotice(groupId) {\n return client.call('_get_group_notice', { group_id: groupId });\n },\n delGroupNotice(groupId, noticeId) {\n return client.call('_del_group_notice', { group_id: groupId, notice_id: +noticeId });\n },\n setOnlineStatus(status, extStatus, batteryStatus) {\n return client.call('set_online_status', { status, ext_status: extStatus, battery_status: batteryStatus });\n },\n setDiyOnlineStatus(faceId, wording = ' ', faceType = 1) {\n return client.call('set_diy_online_status', { face_id: faceId, wording, face_type: faceType });\n },\n sendArkShare(params) {\n return client.call('send_ark_share', params);\n },\n sendGroupArkShare(groupId) {\n return client.call('send_group_ark_share', { group_id: groupId });\n },\n getMiniAppArk(payload: any) {\n return client.call('get_mini_app_ark', payload);\n },\n getAiCharacters(groupId, chatType = 1) {\n return client.call('get_ai_characters', { group_id: groupId, chat_type: chatType });\n },\n getAiRecord(groupId, character, text) {\n return client.call('get_ai_record', { group_id: groupId, character, text });\n },\n sendGroupAiRecord(groupId, character, text) {\n return client.call('send_group_ai_record', { group_id: groupId, character, text });\n },\n setGroupSign(groupId) {\n return client.call('set_group_sign', { group_id: groupId });\n },\n sendGroupSign(groupId) {\n return client.call('send_group_sign', { group_id: groupId });\n },\n fetchCustomFace(params) {\n return client.call('fetch_custom_face', params ?? {});\n },\n getEmojiLikes(params) {\n return client.call('get_emoji_likes', params);\n },\n getClientkey() {\n return client.call('get_clientkey');\n },\n clickInlineKeyboardButton(params) {\n return client.call('click_inline_keyboard_button', {\n ...params,\n button_id: params.button_id ?? '',\n callback_data: params.callback_data ?? '',\n msg_seq: params.msg_seq ?? '10086',\n });\n },\n };\n}\n","import type { ApiClient } from '../../core/api-client';\n\n/**\n * NapCatQQ ActionName 全量列表(服务端路由表)\n * - 可用于“完全覆盖”服务端 action,而不必在 SDK 里为每个 action 单独写一层包装。\n * - 对于包含 '.'/'_' 等前缀的 action,建议使用 bracket 访问:api.raw['.ocr_image'](...)\n */\nexport const NAPCAT_ACTIONS = [\n '.get_word_slices',\n '.handle_quick_operation',\n '.ocr_image',\n 'ArkShareGroup',\n 'ArkSharePeer',\n '_del_group_notice',\n '_get_group_notice',\n '_get_model_show',\n '_mark_all_as_read',\n '_send_group_notice',\n '_set_model_show',\n 'bot_exit',\n 'can_send_image',\n 'can_send_record',\n 'check_url_safely',\n 'clean_cache',\n 'clean_stream_temp_file',\n 'click_inline_keyboard_button',\n 'create_collection',\n 'create_group_file_folder',\n 'del_group_album_media',\n 'delete_essence_msg',\n 'delete_friend',\n 'delete_group_file',\n 'delete_group_folder',\n 'delete_msg',\n 'delete_unidirectional_friend',\n 'do_group_album_comment',\n 'download_file',\n 'download_file_image_stream',\n 'download_file_record_stream',\n 'download_file_stream',\n 'fetch_custom_face',\n 'fetch_emoji_like',\n 'forward_friend_single_msg',\n 'forward_group_single_msg',\n 'friend_poke',\n 'get_ai_characters',\n 'get_ai_record',\n 'get_clientkey',\n 'get_collection_list',\n 'get_cookies',\n 'get_credentials',\n 'get_csrf_token',\n 'get_doubt_friends_add_request',\n 'get_essence_msg_list',\n 'get_file',\n 'get_forward_msg',\n 'get_friend_list',\n 'get_friend_msg_history',\n 'get_friends_with_category',\n 'get_group_album_media_list',\n 'get_group_at_all_remain',\n 'get_group_detail_info',\n 'get_group_file_system_info',\n 'get_group_file_url',\n 'get_group_files_by_folder',\n 'get_group_honor_info',\n 'get_group_ignore_add_request',\n 'get_group_ignored_notifies',\n 'get_group_info',\n 'get_group_info_ex',\n 'get_group_list',\n 'get_group_member_info',\n 'get_group_member_list',\n 'get_group_msg_history',\n 'get_group_root_files',\n 'get_group_shut_list',\n 'get_group_system_msg',\n 'get_guild_list',\n 'get_guild_service_profile',\n 'get_image',\n 'get_login_info',\n 'get_mini_app_ark',\n 'get_msg',\n 'get_online_clients',\n 'get_private_file_url',\n 'get_profile_like',\n 'get_qun_album_list',\n 'get_recent_contact',\n 'get_record',\n 'get_rkey',\n 'get_rkey_server',\n 'get_robot_uin_range',\n 'get_status',\n 'get_stranger_info',\n 'get_unidirectional_friend_list',\n 'get_version_info',\n 'group_poke',\n 'mark_group_msg_as_read',\n 'mark_msg_as_read',\n 'mark_private_msg_as_read',\n 'move_group_file',\n 'nc_get_packet_status',\n 'nc_get_rkey',\n 'nc_get_user_status',\n 'ocr_image',\n 'qidian_get_account_info',\n 'reboot_normal',\n 'reload_event_filter',\n 'rename_group_file',\n 'send_ark_share',\n 'send_forward_msg',\n 'send_group_ai_record',\n 'send_group_ark_share',\n 'send_group_forward_msg',\n 'send_group_msg',\n 'send_group_sign',\n 'send_like',\n 'send_msg',\n 'send_packet',\n 'send_poke',\n 'send_private_forward_msg',\n 'send_private_msg',\n 'set_diy_online_status',\n 'set_doubt_friends_add_request',\n 'set_essence_msg',\n 'set_friend_add_request',\n 'set_friend_remark',\n 'set_group_add_option',\n 'set_group_add_request',\n 'set_group_admin',\n 'set_group_album_media_like',\n 'set_group_anonymous',\n 'set_group_anonymous_ban',\n 'set_group_ban',\n 'set_group_card',\n 'set_group_kick',\n 'set_group_kick_members',\n 'set_group_leave',\n 'set_group_name',\n 'set_group_portrait',\n 'set_group_remark',\n 'set_group_robot_add_option',\n 'set_group_search',\n 'set_group_sign',\n 'set_group_special_title',\n 'set_group_todo',\n 'set_group_whole_ban',\n 'set_input_status',\n 'set_msg_emoji_like',\n 'set_online_status',\n 'set_qq_avatar',\n 'set_qq_profile',\n 'set_restart',\n 'set_self_longnick',\n 'test_auto_register_01',\n 'test_auto_register_02',\n 'test_download_stream',\n 'trans_group_file',\n 'translate_en2zh',\n 'unknown',\n 'upload_file_stream',\n 'upload_group_file',\n 'upload_image_to_qun_album',\n 'upload_private_file',\n] as const;\n\nexport type NapCatAction = typeof NAPCAT_ACTIONS[number];\n\nexport type RawActionApi = {\n [K in NapCatAction]: (params?: any) => Promise<any>;\n};\n\nexport function createRawActionApi(client: ApiClient): RawActionApi {\n const entries = NAPCAT_ACTIONS.map((action) => [\n action,\n (params?: any) => client.call(action, params ?? {}),\n ] as const);\n return Object.fromEntries(entries) as RawActionApi;\n}\n\n","import type { ApiClient } from '../../core/api-client';\nimport { createMessageApi, type MessageApi } from './message';\nimport { createMediaApi, type MediaApi } from './media';\nimport { createAccountApi, type AccountApi } from './account';\nimport { createGroupApi, type GroupApi } from './group';\nimport { createFileApi, type FileApi } from './files';\nimport { createStreamApi, type StreamApi } from './stream';\nimport { createRequestApi, type RequestApi } from './requests';\nimport { createSystemApi, type SystemApi } from './system';\nimport { createNapCatApi, type NapCatApi } from './napcat';\nimport { createRawActionApi, type RawActionApi } from './raw';\n\nimport type { Logger } from '../../types/config';\n\n/**\n * OneBot 11 API 封装\n * 将 ApiClient 的底层 call 转为清晰的业务方法\n * 通过组合各领域 API,保持类方法名称不变。\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport class OneBotApi {\n private messageApi: MessageApi;\n private mediaApi: MediaApi;\n private accountApi: AccountApi;\n private groupApi: GroupApi;\n private fileApi: FileApi;\n private streamApi: StreamApi;\n private requestApi: RequestApi;\n private systemApi: SystemApi;\n private napcatApi: NapCatApi;\n readonly raw: RawActionApi;\n\n constructor(client: ApiClient, logger: Logger) {\n this.messageApi = createMessageApi(client);\n this.mediaApi = createMediaApi(client, logger);\n this.accountApi = createAccountApi(client);\n this.groupApi = createGroupApi(client);\n this.fileApi = createFileApi(client);\n this.streamApi = createStreamApi(client);\n this.requestApi = createRequestApi(client);\n this.systemApi = createSystemApi(client);\n this.napcatApi = createNapCatApi(client);\n this.raw = createRawActionApi(client);\n\n Object.assign(\n this,\n this.messageApi,\n this.mediaApi,\n this.accountApi,\n this.groupApi,\n this.fileApi,\n this.streamApi,\n this.requestApi,\n this.systemApi,\n this.napcatApi,\n );\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport interface OneBotApi extends MessageApi, MediaApi, AccountApi, GroupApi, FileApi, StreamApi, RequestApi, SystemApi, NapCatApi { }\n","import type { OneBotApi } from './index';\n\n/**\n * 统一封装 OneBot API 代理,避免 NapLink 主类塞满转发方法。\n * 通过 bindOneBotApiMethods 在实例上动态挂载对应方法,保持对外 API 不变。\n */\nexport type OneBotApiMethods = {\n getLoginInfo(): Promise<any>;\n getStatus(): Promise<any>;\n sendMessage(params: {\n message_type?: 'private' | 'group';\n user_id?: number | string;\n group_id?: number | string;\n message: any;\n auto_escape?: boolean;\n }): Promise<any>;\n sendPrivateMessage(userId: number | string, message: any): Promise<any>;\n sendGroupMessage(groupId: number | string, message: any): Promise<any>;\n deleteMessage(messageId: number | string): Promise<any>;\n getMessage(messageId: number | string): Promise<any>;\n getForwardMessage(id: string): Promise<any>;\n getEssenceMessageList(groupId: number | string): Promise<any>;\n markMessageAsRead(messageId: number | string): Promise<any>;\n markGroupMsgAsRead(groupId: number | string): Promise<any>;\n markPrivateMsgAsRead(userId: number | string): Promise<any>;\n markAllMsgAsRead(): Promise<any>;\n getGroupAtAllRemain(groupId: number | string): Promise<any>;\n getGroupSystemMsg(): Promise<any>;\n getGroupHonorInfo(\n groupId: number | string,\n type: 'all' | 'talkative' | 'performer' | 'legend' | 'strong_newbie' | 'emotion'\n ): Promise<any>;\n getGroupFileSystemInfo(groupId: number | string): Promise<any>;\n getGroupRootFiles(groupId: number | string): Promise<any>;\n getGroupFilesByFolder(groupId: number | string, folderId: string): Promise<any>;\n getGroupFileUrl(groupId: number | string, fileId: string, busid?: number): Promise<any>;\n deleteGroupFile(groupId: number | string, fileId: string, busid?: number): Promise<any>;\n createGroupFileFolder(groupId: number | string, name: string, parentId?: string): Promise<any>;\n deleteGroupFolder(groupId: number | string, folderId: string): Promise<any>;\n downloadFile(url: string, threadCount?: number, headers?: Record<string, string>): Promise<any>;\n uploadFileStream(\n file: string | Buffer | Uint8Array | NodeJS.ReadableStream,\n options?: {\n chunkSize?: number;\n streamId?: string;\n expectedSha256?: string;\n fileRetention?: number;\n filename?: string;\n reset?: boolean;\n verifyOnly?: boolean;\n }\n ): Promise<any>;\n getUploadStreamStatus(streamId: string): Promise<any>;\n downloadFileStream(fileId: string, options?: { chunkSize?: number }): { packets: AsyncIterable<any>; result: Promise<any> };\n downloadFileStreamToFile(fileId: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: any }>;\n downloadFileImageStream(fileId: string, options?: { chunkSize?: number }): { packets: AsyncIterable<any>; result: Promise<any> };\n downloadFileImageStreamToFile(fileId: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: any }>;\n downloadFileRecordStream(fileId: string, outFormat?: string, options?: { chunkSize?: number; filename?: string }): { packets: AsyncIterable<any>; result: Promise<any> };\n downloadFileRecordStreamToFile(fileId: string, outFormat?: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: any }>;\n cleanStreamTempFile(): Promise<any>;\n sendGroupForwardMessage(groupId: number | string, messages: any[]): Promise<any>;\n getGroupMsgHistory(params: { group_id: number | string; message_seq: number | string; count: number; reverse_order?: boolean }): Promise<any>;\n getFriendMsgHistory(params: { user_id: number | string; message_seq: number | string; count: number; reverse_order?: boolean }): Promise<any>;\n getRecentContact(count: number): Promise<any>;\n setMsgEmojiLike(messageId: number | string, emojiId: number, set: boolean): Promise<any>;\n fetchEmojiLike(params: { message_id: number | string; emojiId: string; emojiType: string; group_id?: number | string; user_id?: number | string; count?: number; cookie?: string }): Promise<any>;\n getEmojiLikes(params: { message_id: string; emoji_id: string; emoji_type?: string; group_id?: string; count?: number }): Promise<any>;\n fetchCustomFace(params?: any): Promise<any>;\n sendGroupPoke(groupId: number | string, userId: number | string): Promise<any>;\n sendFriendPoke(userId: number | string): Promise<any>;\n sendPoke(targetId: number | string, groupId?: number | string): Promise<any>;\n getImage(file: string): Promise<any>;\n getRecord(file: string, outFormat?: string): Promise<any>;\n getFile(file: string): Promise<any>;\n getFriendList(): Promise<any>;\n getGroupList(): Promise<any>;\n getGroupInfo(groupId: number | string, noCache?: boolean): Promise<any>;\n getGroupMemberList(groupId: number | string): Promise<any>;\n getGroupMemberInfo(groupId: number | string, userId: number | string, noCache?: boolean): Promise<any>;\n setGroupBan(groupId: number | string, userId: number | string, duration?: number): Promise<any>;\n unsetGroupBan(groupId: number | string, userId: number | string): Promise<any>;\n setGroupWholeBan(groupId: number | string, enable?: boolean): Promise<any>;\n setGroupKick(groupId: number | string, userId: number | string, rejectAddRequest?: boolean): Promise<any>;\n setGroupLeave(groupId: number | string, isDismiss?: boolean): Promise<any>;\n setGroupCard(groupId: number | string, userId: number | string, card: string): Promise<any>;\n setGroupName(groupId: number | string, groupName: string): Promise<any>;\n setGroupPortrait(groupId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream): Promise<any>;\n setGroupAdmin(groupId: number | string, userId: number | string, enable?: boolean): Promise<any>;\n setGroupAnonymousBan(groupId: number | string, anonymousFlag: string, duration?: number): Promise<any>;\n setEssenceMessage(messageId: number | string): Promise<any>;\n deleteEssenceMessage(messageId: number | string): Promise<any>;\n setGroupSpecialTitle(\n groupId: number | string,\n userId: number | string,\n specialTitle: string,\n duration?: number\n ): Promise<any>;\n sendLike(userId: number | string, times?: number): Promise<any>;\n uploadGroupFile(groupId: number | string, file: string, name: string, folder?: string, uploadFile?: boolean): Promise<any>;\n uploadPrivateFile(userId: number | string, file: string, name: string, uploadFile?: boolean): Promise<any>;\n getStrangerInfo(userId: number | string, noCache?: boolean): Promise<any>;\n getVersionInfo(): Promise<any>;\n handleFriendRequest(flag: string, approve?: boolean, remark?: string): Promise<any>;\n handleGroupRequest(flag: string, subType: 'add' | 'invite', approve?: boolean, reason?: string): Promise<any>;\n\n // SystemApi (NapCat / go-cqhttp 扩展)\n getOnlineClients(noCache?: boolean): Promise<any>;\n getRobotUinRange(): Promise<any>;\n canSendImage(): Promise<any>;\n canSendRecord(): Promise<any>;\n getCookies(domain: string): Promise<any>;\n getCsrfToken(): Promise<any>;\n getCredentials(domain: string): Promise<any>;\n setInputStatus(userId: number | string, eventType: number): Promise<any>;\n ocrImage(image: string, dot?: boolean): Promise<any>;\n translateEn2zh(words: string[]): Promise<any>;\n checkUrlSafely(url: string): Promise<any>;\n handleQuickOperation(context: any, operation: any): Promise<any>;\n getModelShow(model: string): Promise<any>;\n setModelShow(model: string, modelShow: string): Promise<any>;\n getPacketStatus(): Promise<any>;\n\n // NapCatApi (扩展能力合集)\n getRkeyEx(): Promise<any>;\n getRkeyServer(): Promise<any>;\n getRkey(): Promise<any>;\n setFriendRemark(userId: number | string, remark: string): Promise<any>;\n deleteFriend(userId: number | string): Promise<any>;\n getUnidirectionalFriendList(): Promise<any>;\n setGroupRemark(groupId: number | string, remark: string): Promise<any>;\n getGroupInfoEx(groupId: number | string): Promise<any>;\n getGroupDetailInfo(groupId: number | string): Promise<any>;\n getGroupIgnoredNotifies(): Promise<any>;\n getGroupShutList(groupId: number | string): Promise<any>;\n sendPrivateForwardMessage(params: { user_id: number | string; messages: any[]; news?: any[]; prompt?: string; summary?: string; source?: string }): Promise<any>;\n forwardFriendSingleMsg(userId: number | string, messageId: number | string): Promise<any>;\n forwardGroupSingleMsg(groupId: number | string, messageId: number | string): Promise<any>;\n sendForwardMsg(params: { group_id?: number | string; user_id?: number | string; messages: any[]; news?: any[]; prompt?: string; summary?: string; source?: string }): Promise<any>;\n sendGroupNotice(params: { group_id: number | string; content: string; image?: string; pinned?: number | string; type?: number | string; confirm_required?: number | string; is_show_edit_card?: number | string; tip_window_type?: number | string }): Promise<any>;\n getGroupNotice(groupId: number | string): Promise<any>;\n delGroupNotice(groupId: number | string, noticeId: string): Promise<any>;\n setOnlineStatus(status: number | string, extStatus: number | string, batteryStatus: number | string): Promise<any>;\n setDiyOnlineStatus(faceId: number | string, wording?: string, faceType?: number | string): Promise<any>;\n sendArkShare(params: { user_id?: number | string; group_id?: number | string; phone_number?: string }): Promise<any>;\n sendGroupArkShare(groupId: number | string): Promise<any>;\n getMiniAppArk(payload: any): Promise<any>;\n getAiCharacters(groupId: number | string, chatType?: number | string): Promise<any>;\n getAiRecord(groupId: number | string, character: string, text: string): Promise<any>;\n sendGroupAiRecord(groupId: number | string, character: string, text: string): Promise<any>;\n setGroupSign(groupId: number | string): Promise<any>;\n sendGroupSign(groupId: number | string): Promise<any>;\n getClientkey(): Promise<any>;\n clickInlineKeyboardButton(params: { group_id: number | string; bot_appid: string; button_id?: string; callback_data?: string; msg_seq?: string }): Promise<any>;\n\n /**\n * Raw action table (ActionName 全覆盖)\n * 访问方式:client.raw['get_group_shut_list']({ group_id: 123 })\n */\n raw: any;\n};\n\nexport function bindOneBotApiMethods(api: OneBotApi, target: any): void {\n const bindings: Partial<OneBotApiMethods> = {\n getLoginInfo: () => api.getLoginInfo(),\n getStatus: () => api.getStatus(),\n sendMessage: (params) => api.sendMessage(params),\n sendPrivateMessage: (userId, message) => api.sendPrivateMessage(userId, message),\n sendGroupMessage: (groupId, message) => api.sendGroupMessage(groupId, message),\n deleteMessage: (messageId) => api.deleteMessage(messageId),\n getMessage: (messageId) => api.getMessage(messageId),\n getForwardMessage: (id) => api.getForwardMessage(id),\n getEssenceMessageList: (groupId) => api.getEssenceMessageList(groupId),\n markMessageAsRead: (messageId) => api.markMessageAsRead(messageId),\n markGroupMsgAsRead: (groupId) => api.markGroupMsgAsRead(groupId),\n markPrivateMsgAsRead: (userId) => api.markPrivateMsgAsRead(userId),\n markAllMsgAsRead: () => api.markAllMsgAsRead(),\n getGroupAtAllRemain: (groupId) => api.getGroupAtAllRemain(groupId),\n getGroupSystemMsg: () => api.getGroupSystemMsg(),\n getGroupHonorInfo: (groupId, type) => api.getGroupHonorInfo(groupId, type),\n getGroupFileSystemInfo: (groupId) => api.getGroupFileSystemInfo(groupId),\n getGroupRootFiles: (groupId) => api.getGroupRootFiles(groupId),\n getGroupFilesByFolder: (groupId, folderId) => api.getGroupFilesByFolder(groupId, folderId),\n getGroupFileUrl: (groupId, fileId, busid) => api.getGroupFileUrl(groupId, fileId, busid),\n deleteGroupFile: (groupId, fileId, busid) => api.deleteGroupFile(groupId, fileId, busid),\n createGroupFileFolder: (groupId, name, parentId) => api.createGroupFileFolder(groupId, name, parentId),\n deleteGroupFolder: (groupId, folderId) => api.deleteGroupFolder(groupId, folderId),\n downloadFile: (url, threadCount, headers) => api.downloadFile(url, threadCount, headers),\n uploadFileStream: (file, options) => api.uploadFileStream(file, options),\n getUploadStreamStatus: (streamId) => api.getUploadStreamStatus(streamId),\n downloadFileStream: (fileId, options) => api.downloadFileStream(fileId, options),\n downloadFileStreamToFile: (fileId, options) => api.downloadFileStreamToFile(fileId, options),\n downloadFileImageStream: (fileId, options) => api.downloadFileImageStream(fileId, options),\n downloadFileImageStreamToFile: (fileId, options) => api.downloadFileImageStreamToFile(fileId, options),\n downloadFileRecordStream: (fileId, outFormat, options) => api.downloadFileRecordStream(fileId, outFormat, options),\n downloadFileRecordStreamToFile: (fileId, outFormat, options) => api.downloadFileRecordStreamToFile(fileId, outFormat, options),\n cleanStreamTempFile: () => api.cleanStreamTempFile(),\n sendGroupForwardMessage: (groupId, messages) => api.sendGroupForwardMessage(groupId, messages),\n getGroupMsgHistory: (params) => api.getGroupMsgHistory(params),\n getFriendMsgHistory: (params) => api.getFriendMsgHistory(params),\n getRecentContact: (count) => api.getRecentContact(count),\n setMsgEmojiLike: (messageId, emojiId, set) => api.setMsgEmojiLike(messageId, emojiId, set),\n fetchEmojiLike: (params) => api.fetchEmojiLike(params),\n getEmojiLikes: (params) => (api as any).getEmojiLikes(params),\n sendGroupPoke: (groupId, userId) => api.sendGroupPoke(groupId, userId),\n sendFriendPoke: (userId) => api.sendFriendPoke(userId),\n sendPoke: (targetId, groupId) => api.sendPoke(targetId, groupId),\n getImage: (file) => api.getImage(file),\n getRecord: (file, outFormat) => api.getRecord(file, outFormat),\n getFile: (file) => api.getFile(file),\n getFriendList: () => api.getFriendList(),\n getGroupList: () => api.getGroupList(),\n getGroupInfo: (groupId, noCache = false) => api.getGroupInfo(groupId, noCache),\n getGroupMemberList: (groupId) => api.getGroupMemberList(groupId),\n getGroupMemberInfo: (groupId, userId, noCache = false) => api.getGroupMemberInfo(groupId, userId, noCache),\n setGroupBan: (groupId, userId, duration = 30 * 60) => api.setGroupBan(groupId, userId, duration),\n unsetGroupBan: (groupId, userId) => api.unsetGroupBan(groupId, userId),\n setGroupWholeBan: (groupId, enable = true) => api.setGroupWholeBan(groupId, enable),\n setGroupKick: (groupId, userId, rejectAddRequest = false) => api.setGroupKick(groupId, userId, rejectAddRequest),\n setGroupLeave: (groupId, isDismiss = false) => api.setGroupLeave(groupId, isDismiss),\n setGroupCard: (groupId, userId, card) => api.setGroupCard(groupId, userId, card),\n setGroupName: (groupId, groupName) => api.setGroupName(groupId, groupName),\n setGroupPortrait: (groupId, file) => api.setGroupPortrait(groupId, file),\n setGroupAdmin: (groupId, userId, enable = true) => api.setGroupAdmin(groupId, userId, enable),\n setGroupAnonymousBan: (groupId, anonymousFlag, duration = 30 * 60) =>\n api.setGroupAnonymousBan(groupId, anonymousFlag, duration),\n setEssenceMessage: (messageId) => api.setEssenceMessage(messageId),\n deleteEssenceMessage: (messageId) => api.deleteEssenceMessage(messageId),\n setGroupSpecialTitle: (groupId, userId, specialTitle, duration = -1) =>\n api.setGroupSpecialTitle(groupId, userId, specialTitle, duration),\n sendLike: (userId, times = 1) => api.sendLike(userId, times),\n uploadGroupFile: (groupId, file, name, folder, uploadFile) => api.uploadGroupFile(groupId, file, name, folder, uploadFile),\n uploadPrivateFile: (userId, file, name, uploadFile) => api.uploadPrivateFile(userId, file, name, uploadFile),\n getStrangerInfo: (userId, noCache = false) => api.getStrangerInfo(userId, noCache),\n getVersionInfo: () => api.getVersionInfo(),\n handleFriendRequest: (flag, approve = true, remark?: string) => api.handleFriendRequest(flag, approve, remark),\n handleGroupRequest: (flag, subType, approve = true, reason?: string) =>\n api.handleGroupRequest(flag, subType, approve, reason),\n\n // SystemApi\n getOnlineClients: (noCache = false) => (api as any).getOnlineClients(noCache),\n getRobotUinRange: () => (api as any).getRobotUinRange(),\n canSendImage: () => (api as any).canSendImage(),\n canSendRecord: () => (api as any).canSendRecord(),\n getCookies: (domain) => (api as any).getCookies(domain),\n getCsrfToken: () => (api as any).getCsrfToken(),\n getCredentials: (domain) => (api as any).getCredentials(domain),\n setInputStatus: (userId, eventType) => (api as any).setInputStatus(userId, eventType),\n ocrImage: (image, dot) => (api as any).ocrImage(image, dot),\n translateEn2zh: (words) => (api as any).translateEn2zh(words),\n checkUrlSafely: (url) => (api as any).checkUrlSafely(url),\n handleQuickOperation: (context, operation) => (api as any).handleQuickOperation(context, operation),\n getModelShow: (model) => (api as any).getModelShow(model),\n setModelShow: (model, modelShow) => (api as any).setModelShow(model, modelShow),\n getPacketStatus: () => (api as any).getPacketStatus(),\n\n // NapCatApi\n getRkeyEx: () => (api as any).getRkeyEx(),\n getRkeyServer: () => (api as any).getRkeyServer(),\n getRkey: () => (api as any).getRkey(),\n setFriendRemark: (userId, remark) => (api as any).setFriendRemark(userId, remark),\n deleteFriend: (userId) => (api as any).deleteFriend(userId),\n getUnidirectionalFriendList: () => (api as any).getUnidirectionalFriendList(),\n setGroupRemark: (groupId, remark) => (api as any).setGroupRemark(groupId, remark),\n getGroupInfoEx: (groupId) => (api as any).getGroupInfoEx(groupId),\n getGroupDetailInfo: (groupId) => (api as any).getGroupDetailInfo(groupId),\n getGroupIgnoredNotifies: () => (api as any).getGroupIgnoredNotifies(),\n getGroupShutList: (groupId) => (api as any).getGroupShutList(groupId),\n sendPrivateForwardMessage: (params) => (api as any).sendPrivateForwardMessage(params),\n forwardFriendSingleMsg: (userId, messageId) => (api as any).forwardFriendSingleMsg(userId, messageId),\n forwardGroupSingleMsg: (groupId, messageId) => (api as any).forwardGroupSingleMsg(groupId, messageId),\n sendForwardMsg: (params) => (api as any).sendForwardMsg(params),\n sendGroupNotice: (params) => (api as any).sendGroupNotice(params),\n getGroupNotice: (groupId) => (api as any).getGroupNotice(groupId),\n delGroupNotice: (groupId, noticeId) => (api as any).delGroupNotice(groupId, noticeId),\n setOnlineStatus: (status, extStatus, batteryStatus) => (api as any).setOnlineStatus(status, extStatus, batteryStatus),\n setDiyOnlineStatus: (faceId, wording, faceType) => (api as any).setDiyOnlineStatus(faceId, wording, faceType),\n sendArkShare: (params) => (api as any).sendArkShare(params),\n sendGroupArkShare: (groupId) => (api as any).sendGroupArkShare(groupId),\n getMiniAppArk: (payload) => (api as any).getMiniAppArk(payload),\n getAiCharacters: (groupId, chatType) => (api as any).getAiCharacters(groupId, chatType),\n getAiRecord: (groupId, character, text) => (api as any).getAiRecord(groupId, character, text),\n sendGroupAiRecord: (groupId, character, text) => (api as any).sendGroupAiRecord(groupId, character, text),\n setGroupSign: (groupId) => (api as any).setGroupSign(groupId),\n sendGroupSign: (groupId) => (api as any).sendGroupSign(groupId),\n fetchCustomFace: (params) => (api as any).fetchCustomFace(params),\n getClientkey: () => (api as any).getClientkey(),\n clickInlineKeyboardButton: (params) => (api as any).clickInlineKeyboardButton(params),\n raw: (api as any).raw,\n };\n\n Object.assign(target, bindings);\n}\n","/**\n * NapLink 配置接口\n * 提供完整的配置选项,所有参数都有合理的默认值\n */\nexport interface NapLinkConfig {\n /** 连接配置 */\n connection: {\n /** WebSocket 服务器 URL */\n url: string;\n /** 访问令牌(可选) */\n token?: string;\n /** 连接超时时间(毫秒) */\n timeout?: number;\n /** 心跳间隔(毫秒,0表示禁用) */\n pingInterval?: number;\n /** 自定义心跳动作(默认 get_status) */\n heartbeatAction?: {\n action: string;\n params?: Record<string, unknown>;\n };\n };\n\n /** 重连配置 */\n reconnect: {\n /** 是否启用自动重连 */\n enabled: boolean;\n /** 最大重连次数 */\n maxAttempts: number;\n /** 指数退避配置 */\n backoff: {\n /** 初始延迟(毫秒) */\n initial: number;\n /** 最大延迟(毫秒) */\n max: number;\n /** 退避倍数 */\n multiplier: number;\n };\n };\n\n /** 日志配置 */\n logging: {\n /** 日志等级 */\n level: 'debug' | 'info' | 'warn' | 'error' | 'off';\n /** 自定义logger(可选) */\n logger?: Logger;\n };\n\n /** API配置 */\n api: {\n /** API调用超时时间(毫秒) */\n timeout: number;\n /** 失败重试次数 */\n retries: number;\n };\n}\n\n/**\n * 日志接口\n * 允许用户提供自定义logger实现\n */\nexport interface Logger {\n debug(message: string, ...meta: unknown[]): void;\n info(message: string, ...meta: unknown[]): void;\n warn(message: string, ...meta: unknown[]): void;\n error(message: string, error?: Error, ...meta: unknown[]): void;\n}\n\n/**\n * 部分配置类型(用于构造函数)\n * 用户只需提供必要的配置,其他使用默认值\n */\nexport type PartialNapLinkConfig = {\n connection: {\n url: string;\n token?: string;\n timeout?: number;\n pingInterval?: number;\n heartbeatAction?: {\n action: string;\n params?: Record<string, unknown>;\n };\n };\n reconnect?: Partial<NapLinkConfig['reconnect']>;\n logging?: Partial<NapLinkConfig['logging']>;\n api?: Partial<NapLinkConfig['api']>;\n};\n\n/**\n * 默认配置\n */\nexport const DEFAULT_CONFIG: Omit<NapLinkConfig, 'connection'> = {\n reconnect: {\n enabled: true,\n maxAttempts: 10,\n backoff: {\n initial: 1000,\n max: 60000,\n multiplier: 2,\n },\n },\n logging: {\n level: 'info',\n },\n api: {\n timeout: 30000,\n retries: 3,\n },\n};\n","import type { NapLinkConfig, PartialNapLinkConfig } from '../types/config';\nimport { DEFAULT_CONFIG } from '../types/config';\nimport { InvalidConfigError } from '../types/errors';\n\n/**\n * 合并用户配置与默认配置,校验必填项。\n */\nexport function mergeConfig(userConfig: PartialNapLinkConfig): NapLinkConfig {\n if (!userConfig.connection?.url) {\n throw new InvalidConfigError('connection.url', '必须提供连接URL');\n }\n\n return {\n connection: {\n url: userConfig.connection.url,\n token: userConfig.connection.token,\n timeout: userConfig.connection.timeout ?? 30000,\n pingInterval: userConfig.connection.pingInterval ?? 30000,\n heartbeatAction: userConfig.connection.heartbeatAction ?? {\n action: 'get_status',\n params: {},\n },\n },\n reconnect: {\n enabled: userConfig.reconnect?.enabled ?? DEFAULT_CONFIG.reconnect.enabled,\n maxAttempts:\n userConfig.reconnect?.maxAttempts ?? DEFAULT_CONFIG.reconnect.maxAttempts,\n backoff: {\n initial:\n userConfig.reconnect?.backoff?.initial ??\n DEFAULT_CONFIG.reconnect.backoff.initial,\n max:\n userConfig.reconnect?.backoff?.max ??\n DEFAULT_CONFIG.reconnect.backoff.max,\n multiplier:\n userConfig.reconnect?.backoff?.multiplier ??\n DEFAULT_CONFIG.reconnect.backoff.multiplier,\n },\n },\n logging: {\n level: userConfig.logging?.level ?? DEFAULT_CONFIG.logging.level,\n logger: userConfig.logging?.logger,\n },\n api: {\n timeout: userConfig.api?.timeout ?? DEFAULT_CONFIG.api.timeout,\n retries: userConfig.api?.retries ?? DEFAULT_CONFIG.api.retries,\n },\n };\n}\n"],"mappings":"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A;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAC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","names":["EventEmitter","WebSocket","ConnectionState","WebSocket","randomUUID","fs","createWriteStream","tmpdir","join","randomUUID","pipeline","stats","createWriteStream","fs","tmpdir","join","randomUUID","EventEmitter"]}
|
|
1
|
+
{"version":3,"sources":["../src/naplink.ts","../src/utils/logger.ts","../src/core/connection/manager.ts","../src/types/errors.ts","../src/core/reconnect.ts","../src/core/heartbeat.ts","../src/core/connection/state.ts","../src/core/connection/url.ts","../src/core/connection/heartbeat-runner.ts","../src/core/connection/retry-handler.ts","../src/core/connection/close-handler.ts","../src/core/connection/handlers.ts","../src/core/api/request-builder.ts","../src/core/api/response-registry.ts","../src/core/api/retry.ts","../src/core/api-client.ts","../src/core/event-router.ts","../src/core/dispatcher.ts","../src/core/connection/state-handler.ts","../src/api/onebot/message.ts","../src/api/onebot/media.ts","../src/api/onebot/account.ts","../src/api/onebot/group.ts","../src/api/onebot/files.ts","../src/api/onebot/stream.ts","../src/core/upload/stream.ts","../src/api/onebot/requests.ts","../src/api/onebot/system.ts","../src/api/onebot/napcat.ts","../src/api/onebot/raw.ts","../src/api/onebot/index.ts","../src/api/delegates.ts","../src/types/config.ts","../src/utils/merge-config.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport type { NapLinkConfig, PartialNapLinkConfig, Logger } from './types/config';\nimport { DefaultLogger } from './utils/logger';\nimport { ConnectionManager, ConnectionState } from './core/connection';\nimport { ApiClient } from './core/api-client';\nimport { EventRouter } from './core/event-router';\nimport { MessageDispatcher } from './core/dispatcher';\nimport { handleConnectionStateChange } from './core/connection/state-handler';\nimport { OneBotApi } from './api';\nimport { bindOneBotApiMethods, type OneBotApiMethods } from './api/delegates';\nimport type { OneBotMessageSegment } from './types/message-segment';\nimport { mergeConfig } from './utils/merge-config';\n\n/**\n * NapLink客户端\n * 现代化的NapCat WebSocket客户端SDK\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport class NapLink extends EventEmitter {\n private config: NapLinkConfig;\n private logger: Logger;\n private connection: ConnectionManager;\n private apiClient: ApiClient;\n private eventRouter: EventRouter;\n private dispatcher: MessageDispatcher;\n private oneBotApi: OneBotApi;\n\n constructor(config: PartialNapLinkConfig) {\n super();\n\n // 合并配置\n this.config = mergeConfig(config);\n\n // 初始化logger\n this.logger =\n this.config.logging.logger ||\n new DefaultLogger(this.config.logging.level);\n\n // 初始化事件路由器\n this.eventRouter = new EventRouter(this.logger);\n this.setupEventForwarding();\n\n // 初始化API客户端 (需要提前初始化以便传给 Dispatcher)\n // 使用箭头函数作为代理,解决 ConnectionManager 和 Dispatcher 之间的循环依赖\n this.connection = new ConnectionManager(\n this.config,\n this.logger,\n (message) => this.dispatcher.dispatch(message),\n (state, wasReconnecting) => handleConnectionStateChange(this, state, wasReconnecting || false),\n this // 传递 emitter 用于发送 connection:lost 事件\n );\n\n this.apiClient = new ApiClient(this.connection, this.config, this.logger);\n this.dispatcher = new MessageDispatcher(this.apiClient, this.eventRouter, this.logger);\n\n this.oneBotApi = new OneBotApi(this.apiClient, this.logger);\n bindOneBotApiMethods(this.oneBotApi, this);\n\n this.logger.info('NapLink 客户端已初始化');\n }\n\n /**\n * 连接到NapCat服务器\n */\n async connect(): Promise<void> {\n this.logger.info('开始连接...');\n await this.connection.connect();\n }\n\n /**\n * 断开连接\n */\n disconnect(): void {\n this.logger.info('断开连接...');\n this.connection.disconnect();\n this.apiClient.clearPendingRequests('连接已断开');\n }\n\n /**\n * 获取连接状态\n */\n getState(): ConnectionState {\n return this.connection.getState();\n }\n\n /**\n * 检查是否已连接\n */\n isConnected(): boolean {\n return this.connection.isConnected();\n }\n\n /**\n * 补充消息中的媒体直链\n * 自动通过 get_file / get_image / get_record 获取真实下载链接\n */\n async hydrateMessage(message: OneBotMessageSegment[]): Promise<void> {\n return this.api.hydrateMedia(message);\n }\n\n /**\n * 调用自定义API\n */\n async callApi<T = unknown>(method: string, params: Record<string, unknown> = {}): Promise<T> {\n return this.apiClient.call<T>(method, params);\n }\n\n /**\n * 暴露 OneBot API 便于直接使用\n */\n get api(): OneBotApi {\n return this.oneBotApi;\n }\n\n /**\n * 销毁客户端实例\n * 调用后不应再复用当前实例。\n */\n dispose(): void {\n this.logger.info('销毁客户端...');\n this.connection.disconnect();\n this.apiClient.destroy();\n }\n\n // ============ 内部方法 ============\n\n /**\n * 设置事件转发\n */\n private setupEventForwarding(): void {\n // 转发所有事件路由器的事件\n this.eventRouter.onAny((event, data) => {\n this.emit(event, data);\n });\n }\n\n}\n\n// 通过接口合并将动态绑定的方法暴露到实例类型\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging, @typescript-eslint/no-empty-object-type\nexport interface NapLink extends OneBotApiMethods { }\n","import type { Logger } from '../types/config';\n\n/**\n * 日志等级枚举\n */\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n OFF = 4,\n}\n\n/**\n * 日志等级映射\n */\nconst LOG_LEVEL_MAP: Record<string, LogLevel> = {\n debug: LogLevel.DEBUG,\n info: LogLevel.INFO,\n warn: LogLevel.WARN,\n error: LogLevel.ERROR,\n off: LogLevel.OFF,\n};\n\n/**\n * 默认Logger实现\n * 支持日志等级控制和漂亮的格式化输出\n */\nexport class DefaultLogger implements Logger {\n private level: LogLevel;\n\n constructor(level: 'debug' | 'info' | 'warn' | 'error' | 'off' = 'info') {\n this.level = LOG_LEVEL_MAP[level];\n }\n\n /**\n * 设置日志等级\n */\n setLevel(level: 'debug' | 'info' | 'warn' | 'error' | 'off'): void {\n this.level = LOG_LEVEL_MAP[level];\n }\n\n debug(message: string, ...meta: unknown[]): void {\n if (this.shouldLog(LogLevel.DEBUG)) {\n console.debug(this.format('DEBUG', message), ...meta);\n }\n }\n\n info(message: string, ...meta: unknown[]): void {\n if (this.shouldLog(LogLevel.INFO)) {\n console.info(this.format('INFO', message), ...meta);\n }\n }\n\n warn(message: string, ...meta: unknown[]): void {\n if (this.shouldLog(LogLevel.WARN)) {\n console.warn(this.format('WARN', message), ...meta);\n }\n }\n\n error(message: string, error?: Error, ...meta: unknown[]): void {\n if (this.shouldLog(LogLevel.ERROR)) {\n console.error(this.format('ERROR', message), error || '', ...meta);\n }\n }\n\n /**\n * 检查是否应该输出日志\n */\n private shouldLog(level: LogLevel): boolean {\n return level >= this.level;\n }\n\n /**\n * 格式化日志消息\n */\n private format(level: string, message: string): string {\n const timestamp = new Date().toISOString();\n return `[${timestamp}] [NapLink] ${level}: ${message}`;\n }\n}\n","import WebSocket from 'isomorphic-ws';\nimport type EventEmitter from 'events';\nimport type { NapLinkConfig, Logger } from '../../types/config';\nimport {\n ConnectionError,\n ConnectionClosedError,\n} from '../../types/errors';\nimport { ReconnectService } from '../reconnect';\nimport { HeartbeatService } from '../heartbeat';\nimport { ConnectionState } from './state';\nimport { buildWebSocketUrl } from './url';\nimport { startHeartbeat } from './heartbeat-runner';\nimport { handleCloseEvent } from './close-handler';\nimport { attachWebSocketHandlers } from './handlers';\n\n/**\n * WebSocket 连接管理器\n * 负责管理连接生命周期、重连、心跳等\n */\nexport class ConnectionManager {\n private ws?: WebSocket;\n private state: ConnectionState = ConnectionState.DISCONNECTED;\n private reconnectService: ReconnectService;\n private heartbeatService?: HeartbeatService;\n private connectPromise?: Promise<void>;\n private connectTimeout?: NodeJS.Timeout | number;\n private wasReconnecting: boolean = false; // 跟踪是否处于重连状态\n\n constructor(\n private config: NapLinkConfig,\n private logger: Logger,\n private onMessage: (data: string) => void,\n private onStateChange: (state: ConnectionState, wasReconnecting?: boolean) => void,\n private emitter?: Pick<EventEmitter, 'emit'> // 新增:用于发送 connection:lost 事件\n ) {\n this.reconnectService = new ReconnectService(config.reconnect, logger);\n }\n\n /**\n * 连接到WebSocket服务器\n */\n async connect(): Promise<void> {\n // 如果正在连接,返回现有的Promise\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.setState(ConnectionState.CONNECTING);\n\n this.connectPromise = this.performConnect();\n\n try {\n await this.connectPromise;\n } finally {\n this.connectPromise = undefined;\n }\n }\n\n /**\n * 执行实际的连接逻辑\n */\n private performConnect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const url = buildWebSocketUrl(this.config);\n this.logger.info(`连接到 ${url}`);\n\n try {\n // 清理旧的连接及其处理程序,防止“幽灵连接”分发消息\n if (this.ws) {\n this.logger.debug('清理旧的 WebSocket 连接');\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.close(1001, '正在重新连接');\n }\n this.ws = undefined;\n }\n\n this.ws = new WebSocket(url);\n } catch (error) {\n const err = new ConnectionError('WebSocket 创建失败', error);\n this.logger.error('连接失败', err);\n reject(err);\n return;\n }\n\n const timeoutHandle = attachWebSocketHandlers(\n this.ws,\n {\n config: this.config,\n logger: this.logger,\n setState: (s) => this.setState(s),\n resetReconnect: () => this.reconnectService.reset(),\n startHeartbeat: () => {\n this.heartbeatService = startHeartbeat({\n config: this.config,\n logger: this.logger,\n send: (payload) => this.send(payload),\n onTimeout: () => this.handleHeartbeatTimeout(),\n createService: (interval, onPing, onTimeout, logger) =>\n new HeartbeatService(interval, onPing, onTimeout, logger),\n });\n },\n recordPong: () => this.heartbeatService?.recordPong(),\n onMessage: (data: string) => this.onMessage(data),\n onClose: (event: any) => handleCloseEvent({\n getState: () => this.state,\n setState: (s) => this.setState(s),\n stopHeartbeat: () => this.stopHeartbeat(),\n logger: this.logger,\n config: this.config,\n reconnectService: this.reconnectService,\n reconnect: () => this.connect(),\n onMaxAttemptsReached: () => {\n // 达到最大重连次数,发送 connection:lost 事件\n if (this.emitter) {\n this.emitter.emit('connection:lost', {\n timestamp: Date.now(),\n attempts: this.reconnectService.getMaxAttempts()\n });\n }\n },\n }, event),\n clearConnectTimeout: () => this.clearConnectTimeout(),\n },\n resolve,\n reject,\n );\n this.connectTimeout = timeoutHandle;\n });\n }\n\n /**\n * 断开连接\n * @param code 关闭代码\n * @param reason 关闭原因\n */\n disconnect(code = 1000, reason = '正常关闭'): void {\n this.logger.info(`断开连接: ${reason}`);\n\n this.reconnectService.cancel();\n this.stopHeartbeat();\n this.clearConnectTimeout();\n\n if (this.ws) {\n try {\n // 清理监听器\n this.ws.onopen = null;\n this.ws.onclose = null;\n this.ws.onerror = null;\n this.ws.onmessage = null;\n\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.close(code, reason);\n }\n } catch (error) {\n this.logger.error('关闭连接失败', error as Error);\n }\n this.ws = undefined;\n }\n\n this.setState(ConnectionState.DISCONNECTED);\n this.wasReconnecting = false;\n }\n\n /**\n * 发送数据\n */\n send(data: string): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new ConnectionClosedError(\n this.ws?.readyState || -1,\n '连接未建立或已关闭'\n );\n }\n\n this.ws.send(data);\n }\n\n /**\n * 获取当前状态\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * 检查是否已连接\n */\n isConnected(): boolean {\n return (\n this.state === ConnectionState.CONNECTED &&\n this.ws?.readyState === WebSocket.OPEN\n );\n }\n\n /**\n * 设置状态并通知\n */\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.logger.debug(`状态变更: ${state}`);\n\n // 记录是否处于重连状态\n if (state === ConnectionState.RECONNECTING) {\n this.wasReconnecting = true;\n } else if (state === ConnectionState.CONNECTED) {\n // 只在成功连接后传递 wasReconnecting\n this.onStateChange(state, this.wasReconnecting);\n this.wasReconnecting = false; // 重置标记\n return;\n }\n\n this.onStateChange(state, false);\n }\n }\n\n /**\n * 停止心跳\n */\n private stopHeartbeat(): void {\n if (this.heartbeatService) {\n this.heartbeatService.stop();\n this.heartbeatService = undefined;\n }\n }\n\n /**\n * 处理心跳超时\n */\n private handleHeartbeatTimeout(): void {\n this.logger.warn('心跳超时,主动断开连接');\n this.disconnect(4000, '心跳超时');\n }\n\n /**\n * 处理连接关闭并尝试重连\n */\n private clearConnectTimeout(): void {\n if (this.connectTimeout) {\n clearTimeout(this.connectTimeout as NodeJS.Timeout);\n this.connectTimeout = undefined;\n }\n }\n}\n","/**\n * NapLink 错误基类\n * 所有SDK错误都继承自此类\n */\nexport class NapLinkError extends Error {\n constructor(\n message: string,\n public code: string,\n public details?: unknown\n ) {\n super(message);\n this.name = this.constructor.name;\n\n // 保持正确的原型链\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n /**\n * 转换为JSON格式\n */\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n details: this.details,\n };\n }\n}\n\n/**\n * 连接错误\n * 当WebSocket连接失败时抛出\n */\nexport class ConnectionError extends NapLinkError {\n constructor(message: string, cause?: unknown) {\n super(message, 'E_CONNECTION', cause);\n }\n}\n\n/**\n * API超时错误\n * 当API调用超过设定时间时抛出\n */\nexport class ApiTimeoutError extends NapLinkError {\n constructor(method: string, timeout: number) {\n super(\n `API调用 ${method} 超时 (${timeout}ms)`,\n 'E_API_TIMEOUT',\n { method, timeout }\n );\n }\n}\n\n/**\n * API错误\n * 当API调用返回错误时抛出\n */\nexport class ApiError extends NapLinkError {\n constructor(\n method: string,\n retcode: number,\n message: string,\n wording?: string\n ) {\n super(\n wording || message || `API调用失败: ${method}`,\n 'E_API_FAILED',\n { method, retcode, message, wording }\n );\n }\n}\n\n/**\n * 达到最大重连次数错误\n */\nexport class MaxReconnectAttemptsError extends NapLinkError {\n constructor(attempts: number) {\n super(\n `达到最大重连次数 (${attempts})`,\n 'E_MAX_RECONNECT',\n { attempts }\n );\n }\n}\n\n/**\n * 连接关闭错误\n */\nexport class ConnectionClosedError extends NapLinkError {\n constructor(code: number, reason: string) {\n super(\n `连接已关闭: ${reason} (code: ${code})`,\n 'E_CONNECTION_CLOSED',\n { code, reason }\n );\n }\n}\n\n/**\n * 无效配置错误\n */\nexport class InvalidConfigError extends NapLinkError {\n constructor(field: string, reason: string) {\n super(\n `无效的配置: ${field} - ${reason}`,\n 'E_INVALID_CONFIG',\n { field, reason }\n );\n }\n}\n","import type { NapLinkConfig } from '../types/config';\nimport type { Logger } from '../types/config';\n\n/**\n * 重连服务\n * 实现指数退避算法,避免重连风暴\n */\nexport class ReconnectService {\n private currentAttempt = 0;\n private backoffMs: number;\n private reconnectTimer?: NodeJS.Timeout | number;\n\n constructor(\n private config: NapLinkConfig['reconnect'],\n private logger: Logger\n ) {\n this.backoffMs = config.backoff.initial;\n }\n\n hasRemainingAttempts(): boolean {\n return this.currentAttempt < this.config.maxAttempts;\n }\n\n getMaxAttempts(): number {\n return this.config.maxAttempts;\n }\n\n /**\n * 调度重连\n * @param reconnectFn 重连函数\n * @returns 是否调度成功\n */\n schedule(reconnectFn: () => Promise<void>): boolean {\n if (!this.config.enabled) {\n this.logger.warn('自动重连未启用');\n return false;\n }\n\n if (this.currentAttempt >= this.config.maxAttempts) {\n this.logger.error(\n `达到最大重连次数 (${this.config.maxAttempts})`,\n undefined,\n { attempts: this.currentAttempt }\n );\n return false;\n }\n\n this.currentAttempt++;\n\n this.logger.info(\n `将在 ${this.backoffMs}ms 后进行第 ${this.currentAttempt} 次重连...`\n );\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await reconnectFn();\n this.reset(); // 重连成功,重置状态\n } catch (error) {\n const err = error as Error;\n this.logger.error(`重连失败: ${err.message}`);\n this.logger.debug('详细错误信息', err);\n // 增加退避延迟\n this.backoffMs = Math.min(\n this.backoffMs * this.config.backoff.multiplier,\n this.config.backoff.max\n );\n // 继续尝试重连\n this.schedule(reconnectFn);\n }\n }, this.backoffMs);\n\n return true;\n }\n\n /**\n * 重置重连状态\n * 在连接成功后调用\n */\n reset(): void {\n this.currentAttempt = 0;\n this.backoffMs = this.config.backoff.initial;\n this.cancel();\n }\n\n /**\n * 取消待定的重连\n */\n cancel(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer as NodeJS.Timeout);\n this.reconnectTimer = undefined;\n }\n }\n\n /**\n * 获取当前重连尝试次数\n */\n getCurrentAttempt(): number {\n return this.currentAttempt;\n }\n}\n","import type { Logger } from '../types/config';\n\n/**\n * 心跳服务\n * 定期发送ping消息保持连接活跃\n */\nexport class HeartbeatService {\n private timer?: NodeJS.Timeout | number;\n private lastPongTime = 0;\n private missedPings = 0;\n private static readonly MAX_MISSED_PINGS = 3;\n\n constructor(\n private interval: number,\n private sendPing: () => void,\n private onTimeout: () => void,\n private logger: Logger\n ) { }\n\n /**\n * 启动心跳\n */\n start(): void {\n if (this.interval <= 0) {\n this.logger.debug('心跳已禁用 (interval: 0)');\n return;\n }\n\n this.logger.debug(`启动心跳服务 (间隔: ${this.interval}ms)`);\n this.lastPongTime = Date.now();\n this.missedPings = 0;\n\n this.timer = setInterval(() => {\n const now = Date.now();\n const elapsed = now - this.lastPongTime;\n\n // 检查是否超时\n if (elapsed > this.interval * HeartbeatService.MAX_MISSED_PINGS) {\n this.missedPings++;\n this.logger.warn(\n `心跳超时 (${this.missedPings}/${HeartbeatService.MAX_MISSED_PINGS})`,\n { elapsed }\n );\n\n if (this.missedPings >= HeartbeatService.MAX_MISSED_PINGS) {\n this.logger.error('心跳连续超时,触发重连');\n this.stop();\n this.onTimeout();\n return;\n }\n }\n\n // 发送ping\n this.logger.debug('发送心跳 ping');\n this.sendPing();\n }, this.interval);\n }\n\n /**\n * 停止心跳\n */\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer as NodeJS.Timeout);\n this.timer = undefined;\n this.logger.debug('心跳服务已停止');\n }\n }\n\n /**\n * 记录收到pong\n */\n recordPong(): void {\n this.lastPongTime = Date.now();\n this.missedPings = 0;\n this.logger.debug('收到心跳 pong');\n }\n\n /**\n * 检查心跳是否活跃\n */\n isActive(): boolean {\n return this.timer !== undefined;\n }\n}\n","/**\n * WebSocket 连接状态\n */\nexport enum ConnectionState {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n RECONNECTING = 'reconnecting',\n}\n","import type { NapLinkConfig } from '../../types/config';\n\nexport function buildWebSocketUrl(config: NapLinkConfig): string {\n const { url, token } = config.connection;\n if (token) {\n try {\n // Prefer structured URL mutation so we overwrite any existing access_token.\n const parsed = new URL(url);\n parsed.searchParams.set('access_token', token);\n return parsed.toString();\n } catch {\n const separator = url.includes('?') ? '&' : '?';\n // Token may contain URL-sensitive chars (+, &, #, % ...), must be encoded.\n return `${url}${separator}access_token=${encodeURIComponent(token)}`;\n }\n }\n return url;\n}\n","import type { HeartbeatService } from '../heartbeat';\nimport type { NapLinkConfig, Logger } from '../../types/config';\n\nexport type HeartbeatDeps = {\n config: NapLinkConfig;\n logger: Logger;\n heartbeatService?: HeartbeatService;\n send: (payload: string) => void;\n onTimeout: () => void;\n createService: (interval: number, onPing: () => void, onTimeout: () => void, logger: Logger) => HeartbeatService;\n};\n\nexport function startHeartbeat(deps: HeartbeatDeps): HeartbeatService | undefined {\n const { config, logger, send, onTimeout, createService } = deps;\n const interval = config.connection.pingInterval || 0;\n const heartbeatAction = config.connection.heartbeatAction;\n\n if (interval <= 0 || !heartbeatAction?.action) {\n return undefined;\n }\n\n const service = createService(\n interval,\n () => {\n try {\n const payload = {\n action: heartbeatAction.action,\n params: heartbeatAction.params ?? {},\n echo: `heartbeat_${Date.now()}`,\n };\n send(JSON.stringify(payload));\n } catch (error) {\n logger.error('发送心跳失败', error as Error);\n }\n },\n onTimeout,\n logger\n );\n service.start();\n return service;\n}\n","import type { NapLinkConfig, Logger } from '../../types/config';\nimport { MaxReconnectAttemptsError } from '../../types/errors';\nimport type { ReconnectService } from '../reconnect';\nimport { ConnectionState } from './state';\n\nexport type RetryDeps = {\n config: NapLinkConfig;\n logger: Logger;\n reconnectService: ReconnectService;\n setState: (state: ConnectionState) => void;\n connect: () => Promise<void>;\n onMaxAttemptsReached?: () => void; // 新增:达到最大重连次数时的回调\n};\n\nexport function handleReconnect(deps: RetryDeps): boolean {\n const { config, logger, reconnectService, setState, connect, onMaxAttemptsReached } = deps;\n\n if (!reconnectService.hasRemainingAttempts()) {\n setState(ConnectionState.DISCONNECTED);\n const err = new MaxReconnectAttemptsError(reconnectService.getMaxAttempts());\n logger.error('自动重连已达上限,停止重连', err);\n\n // 触发达到最大重连次数的回调\n if (onMaxAttemptsReached) {\n onMaxAttemptsReached();\n }\n\n return false;\n }\n\n setState(ConnectionState.RECONNECTING);\n const scheduled = reconnectService.schedule(() => connect());\n if (!scheduled) {\n setState(ConnectionState.DISCONNECTED);\n const err = new MaxReconnectAttemptsError(config.reconnect.maxAttempts);\n logger.error('自动重连已达上限,停止重连', err);\n\n // 触发达到最大重连次数的回调\n if (onMaxAttemptsReached) {\n onMaxAttemptsReached();\n }\n\n return false;\n }\n\n return true;\n}\n","import type { NapLinkConfig, Logger } from '../../types/config';\nimport { ConnectionState } from './state';\nimport { handleReconnect } from './retry-handler';\nimport type { ReconnectService } from '../reconnect';\n\nexport type CloseHandlerDeps = {\n getState: () => ConnectionState;\n setState: (state: ConnectionState) => void;\n stopHeartbeat: () => void;\n logger: Logger;\n config: NapLinkConfig;\n reconnect: () => Promise<void>;\n reconnectService: ReconnectService;\n onMaxAttemptsReached?: () => void; // 新增:达到最大重连次数时的回调\n};\n\nexport function handleCloseEvent(deps: CloseHandlerDeps, event: any): void {\n const { getState, setState, stopHeartbeat, logger, config, reconnectService, reconnect, onMaxAttemptsReached } = deps;\n\n stopHeartbeat();\n logger.info(`连接关闭 (code: ${event.code}, reason: ${event.reason})`);\n\n // 1000 是正常关闭,不触发重连\n if (event.code === 1000) {\n setState(ConnectionState.DISCONNECTED);\n return;\n }\n\n const state = getState();\n if (\n config.reconnect.enabled &&\n (state === ConnectionState.CONNECTED ||\n state === ConnectionState.RECONNECTING ||\n state === ConnectionState.CONNECTING)\n ) {\n handleReconnect({\n config,\n logger,\n reconnectService,\n setState,\n connect: reconnect,\n onMaxAttemptsReached, // 传递回调\n });\n } else {\n setState(ConnectionState.DISCONNECTED);\n }\n}\n","import WebSocket from 'isomorphic-ws';\nimport type { NapLinkConfig, Logger } from '../../types/config';\nimport { ConnectionError } from '../../types/errors';\nimport { ConnectionState } from './state';\n\nexport type HandlerDeps = {\n config: NapLinkConfig;\n logger: Logger;\n setState: (state: ConnectionState) => void;\n resetReconnect: () => void;\n startHeartbeat: () => void;\n recordPong: () => void;\n onMessage: (data: string) => void;\n onClose: (event: any) => void;\n clearConnectTimeout: () => void;\n};\n\nexport function attachWebSocketHandlers(\n ws: WebSocket,\n deps: HandlerDeps,\n resolve: () => void,\n reject: (err: Error) => void\n): NodeJS.Timeout | number {\n const { config, logger } = deps;\n\n // 设置连接超时\n const timeoutMs = config.connection.timeout || 30000;\n const connectTimeout = setTimeout(() => {\n if (ws && ws.readyState !== WebSocket.OPEN) {\n logger.error(`连接超时 (${timeoutMs}ms)`);\n ws.close();\n reject(new ConnectionError(`连接超时 (${timeoutMs}ms)`));\n }\n }, timeoutMs);\n\n ws.onopen = () => {\n deps.clearConnectTimeout();\n deps.setState(ConnectionState.CONNECTED);\n deps.resetReconnect();\n deps.startHeartbeat();\n deps.logger.info('WebSocket 连接已建立');\n resolve();\n };\n\n ws.onerror = (event: any) => {\n deps.clearConnectTimeout();\n const error = new ConnectionError('WebSocket 错误', event);\n deps.logger.error(`连接错误: ${error.message}`);\n deps.logger.debug('详细错误信息', error);\n reject(error);\n };\n\n ws.onclose = (event) => {\n deps.clearConnectTimeout();\n deps.onClose(event);\n };\n\n ws.onmessage = (event) => {\n try {\n deps.recordPong();\n deps.onMessage(event.data.toString());\n } catch (error) {\n deps.logger.error('消息处理失败', error as Error);\n }\n };\n\n return connectTimeout;\n}\n","export type BuiltRequest = {\n payload: string;\n echo: string;\n};\n\nexport function buildRequestPayload(method: string, params: unknown, echo: string): BuiltRequest {\n return {\n echo,\n payload: JSON.stringify({\n action: method,\n params,\n echo,\n }),\n };\n}\n","import { ApiTimeoutError } from '../../types/errors';\n\nexport interface PendingRequest {\n resolve: (data: unknown) => void;\n reject: (error: Error) => void;\n createdAt: number;\n method: string;\n timer: NodeJS.Timeout | number;\n timeoutMs: number;\n onPacket?: (packet: unknown) => void;\n onEnd?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport class ResponseRegistry {\n private pending = new Map<string, PendingRequest>();\n\n add(echo: string, request: Omit<PendingRequest, 'timer'>, timeout: number): PendingRequest {\n const timer = setTimeout(() => {\n this.pending.delete(echo);\n request.reject(new ApiTimeoutError(request.method, timeout));\n }, timeout);\n\n const entry: PendingRequest = { ...request, timer };\n this.pending.set(echo, entry);\n return entry;\n }\n\n get(echo: string): PendingRequest | undefined {\n return this.pending.get(echo);\n }\n\n refresh(echo: string): boolean {\n const req = this.pending.get(echo);\n if (!req) return false;\n\n clearTimeout(req.timer as NodeJS.Timeout);\n req.createdAt = Date.now();\n req.timer = setTimeout(() => {\n this.pending.delete(echo);\n req.reject(new ApiTimeoutError(req.method, req.timeoutMs));\n }, req.timeoutMs);\n return true;\n }\n\n resolve(echo: string, data: unknown) {\n const req = this.pending.get(echo);\n if (!req) return false;\n this.pending.delete(echo);\n clearTimeout(req.timer as NodeJS.Timeout);\n req.resolve(data);\n return true;\n }\n\n reject(echo: string, error: Error) {\n const req = this.pending.get(echo);\n if (!req) return false;\n this.pending.delete(echo);\n clearTimeout(req.timer as NodeJS.Timeout);\n req.reject(error);\n return true;\n }\n\n take(echo: string): PendingRequest | undefined {\n const req = this.pending.get(echo);\n if (req) {\n this.pending.delete(echo);\n clearTimeout(req.timer as NodeJS.Timeout);\n }\n return req;\n }\n\n clearAll(reason: string) {\n for (const [, req] of this.pending) {\n clearTimeout(req.timer as NodeJS.Timeout);\n req.reject(new Error(reason));\n }\n this.pending.clear();\n }\n\n cleanupStale(now: number, maxAge: number, onTimeout: (method: string, echo: string) => void) {\n for (const [echo, req] of this.pending) {\n if (now - req.createdAt > maxAge) {\n onTimeout(req.method, echo);\n this.reject(echo, new ApiTimeoutError(req.method, maxAge / 2));\n }\n }\n }\n}\n","import { ApiTimeoutError, ApiError } from '../../types/errors';\nimport type { Logger } from '../../types/config';\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n retries: number,\n method: string,\n logger: Logger,\n delayFn: (ms: number) => Promise<void>,\n) {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n // 最后一次尝试,直接抛出错误\n if (attempt === retries) {\n break;\n }\n\n // 如果是超时错误或API错误,进行重试\n if (\n error instanceof ApiTimeoutError ||\n error instanceof ApiError\n ) {\n logger.warn(\n `API调用失败,重试 ${attempt + 1}/${retries}: ${method}`,\n error\n );\n // 简单的延迟重试\n await delayFn(Math.min(1000 * (attempt + 1), 5000));\n } else {\n // 其他错误不重试\n throw error;\n }\n }\n }\n\n throw lastError;\n}\n","import type { Logger } from '../types/config';\nimport type { NapLinkConfig } from '../types/config';\nimport { ApiError, ConnectionClosedError } from '../types/errors';\nimport type { ConnectionManager } from './connection';\nimport { buildRequestPayload } from './api/request-builder';\nimport { ResponseRegistry } from './api/response-registry';\nimport { withRetry } from './api/retry';\n\ntype ApiResponseEnvelope = {\n stream?: string;\n status?: string;\n retcode?: number;\n message?: string;\n wording?: string;\n data?: Record<string, unknown>;\n};\n\ntype AsyncQueueWaiter<T> = {\n resolve: (result: IteratorResult<T>) => void;\n reject: (error: Error) => void;\n};\n\nclass AsyncQueue<T> implements AsyncIterable<T>, AsyncIterator<T> {\n private values: T[] = [];\n private waiters: AsyncQueueWaiter<T>[] = [];\n private closed = false;\n\n push(value: T) {\n if (this.closed) return;\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter.resolve({ value, done: false });\n } else {\n this.values.push(value);\n }\n }\n\n close() {\n if (this.closed) return;\n this.closed = true;\n while (this.waiters.length) {\n this.waiters.shift()!.resolve({ value: undefined as any, done: true });\n }\n }\n\n fail(error: Error) {\n if (this.closed) return;\n this.closed = true;\n while (this.waiters.length) {\n this.waiters.shift()!.reject(error);\n }\n this.values = [];\n }\n\n async next(): Promise<IteratorResult<T>> {\n if (this.values.length) {\n return { value: this.values.shift()!, done: false };\n }\n if (this.closed) {\n return { value: undefined as any, done: true };\n }\n return await new Promise<IteratorResult<T>>((resolve, reject) => {\n this.waiters.push({\n resolve,\n reject: (err) => reject(err),\n });\n });\n }\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return this;\n }\n}\n\n/**\n * API客户端\n * 负责发送API请求并处理响应\n * 支持超时控制、自动重试、请求清理\n */\nexport class ApiClient {\n private readonly registry = new ResponseRegistry();\n private cleanupTimer?: NodeJS.Timeout | number;\n private requestIdCounter = 0;\n\n constructor(\n private connection: ConnectionManager,\n private config: NapLinkConfig,\n private logger: Logger\n ) {\n this.startCleanupTimer();\n }\n\n /**\n * 调用API\n * @param method API方法名\n * @param params API参数\n * @param options 调用选项\n */\n async call<T = unknown>(\n method: string,\n params: Record<string, unknown> = {},\n options?: { timeout?: number; retries?: number }\n ): Promise<T> {\n const timeout = options?.timeout ?? this.config.api.timeout;\n const retries = options?.retries ?? this.config.api.retries;\n\n return withRetry(\n () => this.sendRequest<T>(method, params, timeout),\n retries,\n method,\n this.logger,\n this.delay.bind(this)\n );\n }\n\n /**\n * 调用流式 API(NapCat stream-action)\n * 会持续产出 data.type=stream 的分片包,并在 data.type=response 时结束。\n */\n callStream<TPacket = unknown, TFinal = unknown>(\n method: string,\n params: Record<string, unknown> = {},\n options?: { timeout?: number }\n ): { packets: AsyncIterable<TPacket>; result: Promise<TFinal> } {\n const timeout = options?.timeout ?? this.config.api.timeout;\n const queue = new AsyncQueue<TPacket>();\n\n const result = this.sendRequest<TFinal>(method, params, timeout, {\n onPacket: (packet) => queue.push(packet as TPacket),\n onEnd: () => queue.close(),\n onError: (error) => queue.fail(error),\n });\n\n return { packets: queue, result };\n }\n\n /**\n * 处理API响应\n * 由连接管理器调用\n */\n handleResponse(echo: string, response: ApiResponseEnvelope): void {\n const request = this.registry.get(echo);\n if (!request) {\n // 流式响应可能会产生多条分片包;如果请求已结束,这里不应刷屏\n if (response?.stream === 'stream-action') {\n this.logger.debug(`收到未知流式响应: ${echo}`);\n } else {\n this.logger.warn(`收到未知请求的响应: ${echo}`);\n }\n return;\n }\n\n const isStreamAction =\n response?.stream === 'stream-action' ||\n (typeof response?.data?.type === 'string' &&\n ['stream', 'response', 'reset', 'error'].includes(response.data.type));\n\n // 检查响应状态\n if (response.status === 'ok' || response.retcode === 0) {\n if (isStreamAction) {\n const packet = response.data;\n const packetType = packet?.type;\n\n // callStream() 模式:同一次请求会收到多包(file_info / file_chunk / file_complete)\n if (request.onPacket) {\n // 任意分片包都会刷新超时,避免大文件下载被超时打断\n this.registry.refresh(echo);\n\n request.onPacket(packet);\n if (packetType === 'response') {\n this.logger.debug(`API流式完成: ${request.method}`);\n this.registry.resolve(echo, packet);\n request.onEnd?.();\n }\n return;\n }\n\n // 普通 call():兼容 stream-action 但只有单包响应(如 upload_file_stream 的 chunk_received)\n this.logger.debug(`API成功(stream): ${request.method}`);\n this.registry.resolve(echo, packet);\n return;\n }\n\n this.logger.debug(`API成功: ${request.method}`);\n this.registry.resolve(echo, response.data);\n } else {\n this.logger.warn(`API失败: ${request.method}`, {\n retcode: response.retcode,\n message: response.message,\n });\n const error = new ApiError(\n request.method,\n typeof response.retcode === 'number' ? response.retcode : -1,\n typeof response.message === 'string' ? response.message : 'Unknown API error',\n response.wording\n );\n request.onError?.(error);\n this.registry.reject(echo, error);\n }\n }\n\n /**\n * 销毁API客户端\n */\n destroy(): void {\n this.clearPendingRequests('API客户端已销毁');\n\n // 停止清理定时器\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer as NodeJS.Timeout);\n this.cleanupTimer = undefined;\n }\n }\n\n /**\n * 清理所有待处理请求,但保留客户端可继续使用。\n * 适用于临时断线、主动 disconnect 后再次 connect 的场景。\n */\n clearPendingRequests(reason: string): void {\n this.registry.clearAll(reason);\n }\n\n /**\n * 发送API请求\n */\n private sendRequest<T>(\n method: string,\n params: Record<string, unknown>,\n timeout: number,\n hooks?: {\n onPacket?: (packet: unknown) => void;\n onEnd?: () => void;\n onError?: (error: Error) => void;\n }\n ): Promise<T> {\n return new Promise((resolve, reject) => {\n const echo = this.generateRequestId();\n\n this.logger.debug(`发送API请求: ${method}`, { echo, params });\n\n // 设置超时定时器\n this.registry.add(\n echo,\n {\n resolve: (data) => resolve(data as T),\n reject: (error) => reject(error),\n createdAt: Date.now(),\n method,\n timeoutMs: timeout,\n ...(hooks ?? {}),\n },\n timeout\n );\n\n // 发送请求\n try {\n if (!this.connection.isConnected()) {\n throw new ConnectionClosedError(-1, '连接未建立,请先调用 connect()');\n }\n const { payload } = buildRequestPayload(method, params, echo);\n this.connection.send(payload);\n } catch (error) {\n this.registry.reject(echo, error as Error);\n hooks?.onError?.(error as Error);\n reject(error);\n }\n });\n }\n\n /**\n * 延迟\n */\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * 生成请求ID\n */\n private generateRequestId(): string {\n return `naplink_${Date.now()}_${this.requestIdCounter++}`;\n }\n\n /**\n * 启动清理定时器\n * 定期清理超时的待处理请求\n */\n private startCleanupTimer(): void {\n this.cleanupTimer = setInterval(() => {\n const now = Date.now();\n const timeout = this.config.api.timeout;\n\n this.registry.cleanupStale(now, timeout * 2, (method, echo) => {\n this.logger.warn(`清理超时请求: ${method}`, { echo });\n });\n }, 60000); // 每分钟清理一次\n }\n}\n","import EventEmitter from 'events';\nimport type { Logger } from '../types/config';\nimport type { MetaEvent, MessageEvent, NoticeEvent, OneBotEvent, RequestEvent } from '../types/onebot';\n\ntype UnknownEventPayload = Record<string, unknown> & {\n post_type?: string;\n sub_type?: string;\n message_type?: string;\n notice_type?: string;\n meta_event_type?: string;\n request_type?: string;\n};\ntype RoutedEventPayload = OneBotEvent | UnknownEventPayload;\n\n/**\n * 事件路由器\n * 负责解析OneBot事件并分发到相应的事件处理器\n */\nexport class EventRouter extends EventEmitter {\n private anyListeners: ((event: string | symbol, data: RoutedEventPayload) => void)[] = [];\n\n constructor(private logger: Logger) {\n super();\n }\n\n /**\n * 监听所有事件\n */\n onAny(listener: (event: string | symbol, data: RoutedEventPayload) => void): this {\n this.anyListeners.push(listener);\n return this;\n }\n\n /**\n * 重写emit以支持onAny\n */\n override emit(event: string | symbol, ...args: [RoutedEventPayload]): boolean {\n // 先调用anyListeners\n this.anyListeners.forEach((listener) => {\n try {\n listener(event, args[0]);\n } catch (error) {\n this.logger.error('onAny listener error', error as Error);\n }\n });\n\n return super.emit(event, ...args);\n }\n\n /**\n * 路由消息到相应的事件\n * @param data 原始消息数据\n */\n route(data: RoutedEventPayload): void {\n try {\n const postType = data.post_type;\n const messageType = 'message_type' in data ? data.message_type : undefined;\n const noticeType = 'notice_type' in data ? data.notice_type : undefined;\n\n if (!postType) {\n this.logger.warn('收到无效消息: 缺少 post_type', data);\n return;\n }\n\n this.logger.debug(`路由事件: ${postType}`, {\n messageType,\n noticeType,\n });\n\n // 根据 post_type 分发\n switch (postType) {\n case 'meta_event':\n this.routeMetaEvent(data);\n break;\n case 'message':\n this.routeMessage(data);\n break;\n case 'message_sent':\n this.routeMessageSent(data);\n break;\n case 'notice':\n this.routeNotice(data);\n break;\n case 'request':\n this.routeRequest(data);\n break;\n default:\n this.logger.warn(`未知的 post_type: ${postType}`);\n this.emit('unknown', data);\n }\n\n // 同时触发原始事件\n this.emit('raw', data);\n } catch (error) {\n this.logger.error('事件路由失败', error as Error, data);\n }\n }\n\n /**\n * 路由元事件\n */\n private routeMetaEvent(data: RoutedEventPayload): void {\n if (!isMetaEventPayload(data))\n return\n\n const type = data.meta_event_type;\n const events = [`meta_event`, `meta_event.${type}`];\n const subType = 'sub_type' in data ? data.sub_type : undefined;\n\n if (type === 'lifecycle' && subType) {\n events.push(`meta_event.lifecycle.${subType}`);\n }\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由消息事件\n */\n private routeMessage(data: RoutedEventPayload): void {\n if (!isMessageEventPayload(data))\n return\n\n const messageType = data.message_type;\n const subType = data.sub_type;\n\n const events = [\n 'message',\n `message.${messageType}`,\n `message.${messageType}.${subType}`,\n ];\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由发送消息事件\n */\n private routeMessageSent(data: RoutedEventPayload): void {\n if (!isMessageEventPayload(data))\n return\n\n const messageType = data.message_type;\n const subType = data.sub_type;\n\n const events = [\n 'message_sent',\n `message_sent.${messageType}`,\n `message_sent.${messageType}.${subType}`,\n ];\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由通知事件\n */\n private routeNotice(data: RoutedEventPayload): void {\n if (!isNoticeEventPayload(data))\n return\n\n const noticeType = data.notice_type;\n const subType = 'sub_type' in data ? data.sub_type : undefined;\n\n const events = ['notice', `notice.${noticeType}`];\n\n if (subType) {\n events.push(`notice.${noticeType}.${subType}`);\n }\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由请求事件\n */\n private routeRequest(data: RoutedEventPayload): void {\n if (!isRequestEventPayload(data))\n return\n\n const requestType = data.request_type;\n const subType = 'sub_type' in data ? data.sub_type : undefined;\n\n const events = ['request', `request.${requestType}`];\n\n if (subType) {\n events.push(`request.${requestType}.${subType}`);\n }\n\n this.emitEvents(events, data);\n }\n\n /**\n * 触发多个事件\n */\n private emitEvents(events: string[], data: RoutedEventPayload): void {\n for (const event of events) {\n this.logger.debug(`触发事件: ${event}`);\n this.emit(event, data);\n }\n }\n}\n\nfunction isMessageEventPayload(data: RoutedEventPayload): data is MessageEvent | UnknownEventPayload {\n return data.post_type === 'message' || data.post_type === 'message_sent';\n}\n\nfunction isNoticeEventPayload(data: RoutedEventPayload): data is NoticeEvent | UnknownEventPayload {\n return data.post_type === 'notice';\n}\n\nfunction isRequestEventPayload(data: RoutedEventPayload): data is RequestEvent | UnknownEventPayload {\n return data.post_type === 'request';\n}\n\nfunction isMetaEventPayload(data: RoutedEventPayload): data is MetaEvent | UnknownEventPayload {\n return data.post_type === 'meta_event';\n}\n","import type { Logger } from '../types/config';\nimport type { ApiClient } from './api-client';\nimport type { EventRouter } from './event-router';\n\nexport class MessageDispatcher {\n constructor(\n private apiClient: ApiClient,\n private eventRouter: EventRouter,\n private logger: Logger\n ) { }\n\n /**\n * 分发消息\n * @param message WebSocket 接收到的原始字符串消息\n */\n dispatch(message: string): void {\n try {\n const data = JSON.parse(message);\n\n // API响应包可能存在 echo=null(如 token 校验失败),不能只依赖 truthy echo。\n const isApiResponse =\n data &&\n typeof data === 'object' &&\n ('echo' in data || 'status' in data || 'retcode' in data);\n\n if (isApiResponse) {\n // 忽略心跳响应\n if (typeof data.echo === 'string' && data.echo.startsWith('heartbeat_')) {\n return;\n }\n this.apiClient.handleResponse(data.echo, data);\n } else {\n // 否则是事件\n this.eventRouter.route(data);\n }\n } catch (error) {\n this.logger.error('消息解析失败', error as Error, { message });\n }\n }\n}\n","import EventEmitter from 'events';\nimport { ConnectionState } from './state';\n\n/**\n * 处理连接状态变化并触发相应事件\n * @param emitter 事件发射器 (通常是 NapLink 实例)\n * @param state 新的连接状态\n * @param wasReconnecting 是否从重连状态转换而来\n */\nexport function handleConnectionStateChange(\n emitter: EventEmitter,\n state: ConnectionState,\n wasReconnecting: boolean = false\n): void {\n emitter.emit('state_change', state);\n\n // 触发具体的状态事件\n switch (state) {\n case ConnectionState.CONNECTED:\n emitter.emit('connect');\n // 如果是从重连状态恢复,发送 connection:restored 事件\n if (wasReconnecting) {\n emitter.emit('connection:restored', { timestamp: Date.now() });\n }\n break;\n case ConnectionState.DISCONNECTED:\n emitter.emit('disconnect');\n break;\n case ConnectionState.RECONNECTING:\n emitter.emit('reconnecting');\n break;\n }\n}\n","import type { ApiClient } from '../../core/api-client';\nimport type { GroupHonorInfo, GroupSystemMessages } from '../../types/onebot';\n\nexport type MessageApi = {\n // 基础消息\n sendMessage(params: {\n message_type?: 'private' | 'group';\n user_id?: number | string;\n group_id?: number | string;\n message: any;\n auto_escape?: boolean;\n }): Promise<any>;\n sendPrivateMessage(userId: number | string, message: any): Promise<any>;\n sendGroupMessage(groupId: number | string, message: any): Promise<any>;\n deleteMessage(messageId: number | string): Promise<any>;\n getMessage(messageId: number | string): Promise<any>;\n getForwardMessage(id: string): Promise<any>;\n sendGroupForwardMessage(groupId: number | string, messages: any[]): Promise<any>;\n\n // 精华 / 已读 / @全体剩余\n setEssenceMessage(messageId: number | string): Promise<any>;\n deleteEssenceMessage(messageId: number | string): Promise<any>;\n getEssenceMessageList(groupId: number | string): Promise<any>;\n markMessageAsRead(messageId: number | string): Promise<any>;\n markGroupMsgAsRead(groupId: number | string): Promise<any>;\n markPrivateMsgAsRead(userId: number | string): Promise<any>;\n markAllMsgAsRead(): Promise<any>;\n getGroupAtAllRemain(groupId: number | string): Promise<number>;\n\n // 系统/荣誉消息\n getGroupSystemMsg(): Promise<GroupSystemMessages>;\n getGroupHonorInfo(\n groupId: number | string,\n type: 'all' | 'talkative' | 'performer' | 'legend' | 'strong_newbie' | 'emotion'\n ): Promise<GroupHonorInfo>;\n\n // 消息历史 / 最近会话(NapCat 扩展)\n getGroupMsgHistory(params: {\n group_id: number | string;\n message_seq: number | string;\n count: number;\n reverse_order?: boolean;\n }): Promise<any>;\n getFriendMsgHistory(params: {\n user_id: number | string;\n message_seq: number | string;\n count: number;\n reverse_order?: boolean;\n }): Promise<any>;\n getRecentContact(count: number): Promise<any>;\n\n // 表情回应(NapCat 扩展)\n setMsgEmojiLike(messageId: number | string, emojiId: number, set: boolean): Promise<any>;\n fetchEmojiLike(params: {\n message_id: number | string;\n emojiId: string;\n emojiType: string;\n group_id?: number | string;\n user_id?: number | string;\n count?: number;\n cookie?: string;\n }): Promise<any>;\n\n // 戳一戳(NapCat 扩展)\n sendGroupPoke(groupId: number | string, userId: number | string): Promise<any>;\n sendFriendPoke(userId: number | string): Promise<any>;\n sendPoke(targetId: number | string, groupId?: number | string): Promise<any>;\n};\n\nexport function createMessageApi(client: ApiClient): MessageApi {\n return {\n sendMessage(params) {\n return client.call('send_msg', params);\n },\n sendPrivateMessage(userId, message) {\n return client.call('send_private_msg', { user_id: userId, message });\n },\n sendGroupMessage(groupId, message) {\n return client.call('send_group_msg', { group_id: groupId, message });\n },\n deleteMessage(messageId) {\n return client.call('delete_msg', { message_id: messageId });\n },\n getMessage(messageId) {\n return client.call('get_msg', { message_id: messageId });\n },\n getForwardMessage(id) {\n return client.call('get_forward_msg', { id });\n },\n sendGroupForwardMessage(groupId, messages) {\n return client.call('send_group_forward_msg', { group_id: groupId, messages });\n },\n setEssenceMessage(messageId) {\n return client.call('set_essence_msg', { message_id: messageId });\n },\n deleteEssenceMessage(messageId) {\n return client.call('delete_essence_msg', { message_id: messageId });\n },\n getEssenceMessageList(groupId) {\n return client.call('get_essence_msg_list', { group_id: groupId });\n },\n markMessageAsRead(messageId) {\n return client.call('mark_msg_as_read', { message_id: messageId });\n },\n markGroupMsgAsRead(groupId) {\n return client.call('mark_group_msg_as_read', { group_id: groupId });\n },\n markPrivateMsgAsRead(userId) {\n return client.call('mark_private_msg_as_read', { user_id: userId });\n },\n markAllMsgAsRead() {\n return client.call('_mark_all_as_read');\n },\n getGroupAtAllRemain(groupId) {\n return client.call<number>('get_group_at_all_remain', { group_id: groupId });\n },\n getGroupSystemMsg() {\n return client.call<GroupSystemMessages>('get_group_system_msg');\n },\n getGroupHonorInfo(groupId, type) {\n return client.call<GroupHonorInfo>('get_group_honor_info', { group_id: groupId, type });\n },\n getGroupMsgHistory(params) {\n return client.call('get_group_msg_history', params);\n },\n getFriendMsgHistory(params) {\n return client.call('get_friend_msg_history', params);\n },\n getRecentContact(count) {\n return client.call('get_recent_contact', { count });\n },\n setMsgEmojiLike(messageId, emojiId, set) {\n return client.call('set_msg_emoji_like', { message_id: messageId, emoji_id: emojiId, set });\n },\n fetchEmojiLike(params) {\n return client.call('fetch_emoji_like', params);\n },\n sendGroupPoke(groupId, userId) {\n return client.call('group_poke', { group_id: groupId, user_id: userId });\n },\n sendFriendPoke(userId) {\n return client.call('friend_poke', { user_id: userId });\n },\n sendPoke(targetId, groupId) {\n return client.call('send_poke', groupId ? { group_id: groupId, target_id: targetId } : { user_id: targetId });\n },\n };\n}\n","import type { ApiClient } from '../../core/api-client';\nimport type { Logger } from '../../types/config';\nimport type { OneBotMessageSegment } from '../../types/message-segment';\n\ntype MediaFileResponse = {\n file?: string;\n url?: string;\n};\n\ntype HydratableSegment = Extract<\n OneBotMessageSegment,\n { type: 'image' | 'video' | 'record' | 'audio' | 'file' }\n>;\n\nexport type MediaApi = {\n getImage(file: string): Promise<MediaFileResponse>;\n getRecord(file: string, outFormat?: string): Promise<MediaFileResponse>;\n getFile(file: string): Promise<MediaFileResponse>;\n hydrateMedia(message: OneBotMessageSegment[]): Promise<void>;\n};\n\nexport function createMediaApi(client: ApiClient, logger: Logger): MediaApi {\n const api = {\n getImage(file: string) {\n return client.call<MediaFileResponse>('get_image', { file });\n },\n getRecord(file: string, outFormat?: string) {\n return client.call<MediaFileResponse>('get_record', { file, out_format: outFormat });\n },\n getFile(file: string) {\n return client.call<MediaFileResponse>('get_file', { file });\n },\n async hydrateMedia(message: OneBotMessageSegment[]) {\n if (!Array.isArray(message)) return;\n\n await Promise.all(message.map(async (segment) => {\n if (!isHydratableSegment(segment)) return;\n\n const type = segment?.type;\n const data = segment?.data;\n if (!type || !data) return;\n\n const fileId = data.file ?? data.file_id;\n // 如果已经是 http 或 file 协议,或者是 base64 (虽然 base64 一般不走这里),则跳过\n if (typeof fileId === 'string' && !/^https?:\\/\\//.test(fileId) && !fileId.startsWith('file://')) {\n try {\n // 优先尝试通用 get_file\n const res = await api.getFile(fileId);\n const hydratedUrl = res?.file ?? res?.url;\n if (hydratedUrl) {\n data.url = hydratedUrl;\n data.file = hydratedUrl;\n return;\n }\n\n // 针对特定类型的降级/专用获取\n if (type === 'record' || type === 'audio') {\n const rec = await api.getRecord(fileId, 'mp3');\n const recUrl = rec?.file ?? rec?.url;\n if (recUrl) {\n data.url = recUrl;\n data.file = recUrl;\n }\n } else if (type === 'image') {\n const img = await api.getImage(fileId);\n const imgUrl = img?.file ?? img?.url;\n if (imgUrl) {\n data.url = imgUrl;\n data.file = imgUrl;\n }\n }\n } catch (e) {\n logger.debug(`Failed to hydrate media for ${type}: ${fileId}`, e);\n }\n }\n }));\n }\n };\n return api;\n}\n\nfunction isHydratableSegment(segment: OneBotMessageSegment): segment is HydratableSegment {\n return ['image', 'video', 'record', 'audio', 'file'].includes(segment.type);\n}\n","import type { ApiClient } from '../../core/api-client';\n\nexport type AccountApi = {\n getLoginInfo(): Promise<any>;\n getStatus(): Promise<any>;\n getFriendList(): Promise<any>;\n getGroupList(): Promise<any>;\n getGroupInfo(groupId: number | string, noCache?: boolean): Promise<any>;\n getGroupMemberList(groupId: number | string): Promise<any>;\n getGroupMemberInfo(groupId: number | string, userId: number | string, noCache?: boolean): Promise<any>;\n getStrangerInfo(userId: number | string, noCache?: boolean): Promise<any>;\n getVersionInfo(): Promise<any>;\n};\n\nexport function createAccountApi(client: ApiClient): AccountApi {\n return {\n getLoginInfo() {\n return client.call('get_login_info');\n },\n getStatus() {\n return client.call('get_status');\n },\n getFriendList() {\n return client.call('get_friend_list');\n },\n getGroupList() {\n return client.call('get_group_list');\n },\n getGroupInfo(groupId, noCache = false) {\n return client.call('get_group_info', { group_id: groupId, no_cache: noCache });\n },\n getGroupMemberList(groupId) {\n return client.call('get_group_member_list', { group_id: groupId });\n },\n getGroupMemberInfo(groupId, userId, noCache = false) {\n return client.call('get_group_member_info', {\n group_id: groupId,\n user_id: userId,\n no_cache: noCache,\n });\n },\n getStrangerInfo(userId, noCache = false) {\n return client.call('get_stranger_info', { user_id: userId, no_cache: noCache });\n },\n getVersionInfo() {\n return client.call('get_version_info');\n },\n };\n}\n","import type { ApiClient } from '../../core/api-client';\n\nexport type GroupApi = {\n setGroupBan(groupId: number | string, userId: number | string, duration?: number): Promise<any>;\n unsetGroupBan(groupId: number | string, userId: number | string): Promise<any>;\n setGroupWholeBan(groupId: number | string, enable?: boolean): Promise<any>;\n setGroupKick(groupId: number | string, userId: number | string, rejectAddRequest?: boolean): Promise<any>;\n setGroupLeave(groupId: number | string, isDismiss?: boolean): Promise<any>;\n setGroupCard(groupId: number | string, userId: number | string, card: string): Promise<any>;\n setGroupName(groupId: number | string, groupName: string): Promise<any>;\n setGroupAdmin(groupId: number | string, userId: number | string, enable?: boolean): Promise<any>;\n setGroupAnonymousBan(groupId: number | string, anonymousFlag: string, duration?: number): Promise<any>;\n setGroupSpecialTitle(\n groupId: number | string,\n userId: number | string,\n specialTitle: string,\n duration?: number\n ): Promise<any>;\n sendLike(userId: number | string, times?: number): Promise<any>;\n};\n\nexport function createGroupApi(client: ApiClient): GroupApi {\n return {\n setGroupBan(groupId, userId, duration = 30 * 60) {\n return client.call('set_group_ban', { group_id: groupId, user_id: userId, duration });\n },\n unsetGroupBan(groupId, userId) {\n return client.call('set_group_ban', { group_id: groupId, user_id: userId, duration: 0 });\n },\n setGroupWholeBan(groupId, enable = true) {\n return client.call('set_group_whole_ban', { group_id: groupId, enable });\n },\n setGroupKick(groupId, userId, rejectAddRequest = false) {\n return client.call('set_group_kick', {\n group_id: groupId,\n user_id: userId,\n reject_add_request: rejectAddRequest,\n });\n },\n setGroupLeave(groupId, isDismiss = false) {\n return client.call('set_group_leave', { group_id: groupId, is_dismiss: isDismiss });\n },\n setGroupCard(groupId, userId, card) {\n return client.call('set_group_card', { group_id: groupId, user_id: userId, card });\n },\n setGroupName(groupId, groupName) {\n return client.call('set_group_name', { group_id: groupId, group_name: groupName });\n },\n setGroupAdmin(groupId, userId, enable = true) {\n return client.call('set_group_admin', { group_id: groupId, user_id: userId, enable });\n },\n setGroupAnonymousBan(groupId, anonymousFlag, duration = 30 * 60) {\n return client.call('set_group_anonymous_ban', {\n group_id: groupId,\n anonymous_flag: anonymousFlag,\n duration,\n });\n },\n setGroupSpecialTitle(groupId, userId, specialTitle, duration = -1) {\n return client.call('set_group_special_title', {\n group_id: groupId,\n user_id: userId,\n special_title: specialTitle,\n duration,\n });\n },\n sendLike(userId, times = 1) {\n return client.call('send_like', { user_id: userId, times });\n },\n };\n}\n","import { promises as fs, createWriteStream } from 'fs';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { pipeline } from 'stream/promises';\nimport type { ApiClient } from '../../core/api-client';\n\nexport type FileApi = {\n uploadGroupFile(groupId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream, name: string, folder?: string, uploadFile?: boolean): Promise<any>;\n uploadPrivateFile(userId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream, name: string, uploadFile?: boolean): Promise<any>;\n setGroupPortrait(groupId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream): Promise<any>;\n\n getGroupFileSystemInfo(groupId: number | string): Promise<any>;\n getGroupRootFiles(groupId: number | string): Promise<any>;\n getGroupFilesByFolder(groupId: number | string, folderId: string): Promise<any>;\n getGroupFileUrl(groupId: number | string, fileId: string, busid?: number): Promise<any>;\n deleteGroupFile(groupId: number | string, fileId: string, busid?: number): Promise<any>;\n createGroupFileFolder(groupId: number | string, name: string, parentId?: string): Promise<any>;\n deleteGroupFolder(groupId: number | string, folderId: string): Promise<any>;\n\n downloadFile(url: string, threadCount?: number, headers?: Record<string, string>): Promise<any>;\n};\n\nexport function createFileApi(client: ApiClient): FileApi {\n const normalizeFileInput = async (file: string | Buffer | Uint8Array | NodeJS.ReadableStream, name: string) => {\n if (typeof file === 'string') return file;\n\n const tempPath = join(tmpdir(), `${randomUUID()}-${name || 'naplink.tmp'}`);\n\n if (file instanceof Buffer || file instanceof Uint8Array) {\n await fs.writeFile(tempPath, file);\n return tempPath;\n }\n\n await pipeline(file, createWriteStream(tempPath));\n return tempPath;\n };\n\n return {\n async uploadGroupFile(groupId, file, name, folder, uploadFile = true) {\n const normalized = await normalizeFileInput(file, name);\n return client.call('upload_group_file', { group_id: groupId, file: normalized, name, folder, upload_file: uploadFile });\n },\n async uploadPrivateFile(userId, file, name, uploadFile = true) {\n const normalized = await normalizeFileInput(file, name);\n return client.call('upload_private_file', { user_id: userId, file: normalized, name, upload_file: uploadFile });\n },\n async setGroupPortrait(groupId, file) {\n return this.uploadGroupFile(groupId, file as any, 'portrait');\n },\n getGroupFileSystemInfo(groupId) {\n return client.call('get_group_file_system_info', { group_id: groupId });\n },\n getGroupRootFiles(groupId) {\n return client.call('get_group_root_files', { group_id: groupId });\n },\n getGroupFilesByFolder(groupId, folderId) {\n return client.call('get_group_files_by_folder', { group_id: groupId, folder_id: folderId });\n },\n getGroupFileUrl(groupId, fileId, busid) {\n return client.call('get_group_file_url', { group_id: groupId, file_id: fileId, busid });\n },\n deleteGroupFile(groupId, fileId, busid) {\n return client.call('delete_group_file', { group_id: groupId, file_id: fileId, busid });\n },\n createGroupFileFolder(groupId, name, parentId) {\n return client.call('create_group_file_folder', { group_id: groupId, name, parent_id: parentId });\n },\n deleteGroupFolder(groupId, folderId) {\n return client.call('delete_group_folder', { group_id: groupId, folder_id: folderId });\n },\n downloadFile(url, threadCount = 3, headers?: Record<string, string>) {\n return client.call('download_file', { url, thread_count: threadCount, headers });\n },\n };\n}\n","import { randomUUID } from 'crypto';\nimport type { ApiClient } from '../../core/api-client';\nimport { prepareStreamSource, computeSha256, iterateChunks } from '../../core/upload/stream';\nimport { createWriteStream } from 'fs';\nimport { promises as fs } from 'fs';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\n\nexport type StreamApi = {\n uploadFileStream(\n file: string | Buffer | Uint8Array | NodeJS.ReadableStream,\n options?: {\n chunkSize?: number;\n streamId?: string;\n expectedSha256?: string;\n fileRetention?: number;\n filename?: string;\n reset?: boolean;\n verifyOnly?: boolean;\n }\n ): Promise<any>;\n getUploadStreamStatus(streamId: string): Promise<any>;\n\n /**\n * 流式下载文件(原始分片包)\n * - data_type=file_info / file_chunk / file_complete\n * - type=stream / response\n */\n downloadFileStream(fileId: string, options?: { chunkSize?: number }): { packets: AsyncIterable<DownloadStreamPacket>; result: Promise<DownloadStreamPacket> };\n downloadFileStreamToFile(fileId: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: DownloadStreamPacket }>;\n\n downloadFileImageStream(fileId: string, options?: { chunkSize?: number }): { packets: AsyncIterable<DownloadStreamPacket>; result: Promise<DownloadStreamPacket> };\n downloadFileImageStreamToFile(fileId: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: DownloadStreamPacket }>;\n\n downloadFileRecordStream(fileId: string, outFormat?: string, options?: { chunkSize?: number; filename?: string }): { packets: AsyncIterable<DownloadStreamPacket>; result: Promise<DownloadStreamPacket> };\n downloadFileRecordStreamToFile(fileId: string, outFormat?: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: DownloadStreamPacket }>;\n\n cleanStreamTempFile(): Promise<any>;\n};\n\nexport type DownloadStreamPacket = {\n type: 'stream' | 'response' | 'reset' | 'error';\n data_type?: 'file_info' | 'file_chunk' | 'file_complete' | string;\n file_name?: string;\n file_size?: number;\n chunk_size?: number;\n index?: number;\n data?: string;\n size?: number;\n progress?: number;\n base64_size?: number;\n total_chunks?: number;\n total_bytes?: number;\n message?: string;\n width?: number;\n height?: number;\n out_format?: string;\n};\n\nexport function createStreamApi(client: ApiClient): StreamApi {\n const downloadToFile = async (\n action: string,\n params: Record<string, any>,\n filenameHint?: string,\n ): Promise<{ path: string; info?: DownloadStreamPacket }> => {\n const { packets } = client.callStream<DownloadStreamPacket, DownloadStreamPacket>(action, params);\n\n let fileInfo: DownloadStreamPacket | undefined;\n const tempPath = join(tmpdir(), `${randomUUID()}-${filenameHint || 'naplink.download'}`);\n const writeStream = createWriteStream(tempPath);\n\n try {\n for await (const packet of packets) {\n if (packet?.data_type === 'file_info') {\n fileInfo = packet;\n }\n if (packet?.data_type === 'file_chunk' && typeof packet.data === 'string') {\n writeStream.write(Buffer.from(packet.data, 'base64'));\n }\n }\n await new Promise<void>((resolve, reject) => {\n writeStream.once('error', reject);\n writeStream.end(() => resolve());\n });\n return { path: tempPath, info: fileInfo };\n } catch (error) {\n try {\n writeStream.destroy();\n } catch {\n // ignore\n }\n await fs.unlink(tempPath).catch(() => undefined);\n throw error;\n }\n };\n\n return {\n async uploadFileStream(file, options) {\n const chunkSize = options?.chunkSize ?? 256 * 1024;\n const streamId = options?.streamId ?? randomUUID();\n\n const { source, size, filename, cleanupTemp } = await prepareStreamSource(file, options?.filename);\n\n const expectedSha256 = options?.expectedSha256 ?? (await computeSha256(source));\n const totalChunks = Math.ceil(size / chunkSize);\n\n if (options?.reset) {\n await client.call('upload_file_stream', { stream_id: streamId, reset: true });\n }\n\n let chunkIndex = 0;\n for await (const chunk of iterateChunks(source, size, chunkSize)) {\n const payload: any = {\n stream_id: streamId,\n chunk_data: chunk.toString('base64'),\n chunk_index: chunkIndex,\n total_chunks: totalChunks,\n file_size: size,\n expected_sha256: expectedSha256,\n filename,\n };\n if (options?.fileRetention != null) {\n payload.file_retention = options.fileRetention;\n }\n if (options?.verifyOnly) {\n payload.verify_only = true;\n }\n\n await client.call('upload_file_stream', payload);\n chunkIndex++;\n }\n\n const completion = await client.call('upload_file_stream', {\n stream_id: streamId,\n is_complete: true,\n });\n\n await cleanupTemp?.();\n return completion;\n },\n\n getUploadStreamStatus(streamId: string) {\n return client.call('upload_file_stream', { stream_id: streamId, verify_only: true });\n },\n\n downloadFileStream(fileId, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return client.callStream<DownloadStreamPacket, DownloadStreamPacket>('download_file_stream', {\n file: fileId,\n chunk_size: chunkSize,\n });\n },\n async downloadFileStreamToFile(fileId, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return downloadToFile('download_file_stream', { file: fileId, chunk_size: chunkSize }, options?.filename);\n },\n\n downloadFileImageStream(fileId, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return client.callStream<DownloadStreamPacket, DownloadStreamPacket>('download_file_image_stream', {\n file: fileId,\n chunk_size: chunkSize,\n });\n },\n async downloadFileImageStreamToFile(fileId, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return downloadToFile('download_file_image_stream', { file: fileId, chunk_size: chunkSize }, options?.filename);\n },\n\n downloadFileRecordStream(fileId, outFormat, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return client.callStream<DownloadStreamPacket, DownloadStreamPacket>('download_file_record_stream', {\n file: fileId,\n chunk_size: chunkSize,\n out_format: outFormat,\n });\n },\n async downloadFileRecordStreamToFile(fileId, outFormat, options) {\n const chunkSize = options?.chunkSize ?? 64 * 1024;\n return downloadToFile(\n 'download_file_record_stream',\n { file: fileId, chunk_size: chunkSize, out_format: outFormat },\n options?.filename,\n );\n },\n\n cleanStreamTempFile() {\n return client.call('clean_stream_temp_file');\n },\n };\n}\n","import { promises as fs, createWriteStream, createReadStream } from 'fs';\nimport { tmpdir } from 'os';\nimport { join, basename } from 'path';\nimport { randomUUID, createHash } from 'crypto';\nimport { pipeline } from 'stream/promises';\n\nexport type StreamSource = {\n source: string | Buffer;\n size: number;\n filename: string;\n cleanupTemp?: () => Promise<void>;\n};\n\nexport async function prepareStreamSource(\n file: string | Buffer | Uint8Array | NodeJS.ReadableStream,\n overrideName?: string\n): Promise<StreamSource> {\n if (typeof file === 'string') {\n const stats = await fs.stat(file);\n return { source: file, size: stats.size, filename: overrideName || basename(file) };\n }\n\n if (file instanceof Buffer || file instanceof Uint8Array) {\n return { source: Buffer.from(file), size: file.length, filename: overrideName || 'upload.bin' };\n }\n\n // ReadableStream -> 写入临时文件\n const tempPath = join(tmpdir(), `${randomUUID()}-upload.tmp`);\n await pipeline(file, createWriteStream(tempPath));\n const stats = await fs.stat(tempPath);\n return {\n source: tempPath,\n size: stats.size,\n filename: overrideName || basename(tempPath),\n cleanupTemp: async () => {\n try { await fs.unlink(tempPath); } catch { /* ignore */ }\n }\n };\n}\n\nexport async function* iterateChunks(source: string | Buffer, size: number, chunkSize: number): AsyncGenerator<Buffer> {\n if (typeof source === 'string') {\n const stream = createReadStream(source, { highWaterMark: chunkSize });\n for await (const chunk of stream) {\n yield chunk as Buffer;\n }\n } else {\n let offset = 0;\n while (offset < size) {\n const end = Math.min(offset + chunkSize, size);\n yield source.slice(offset, end);\n offset = end;\n }\n }\n}\n\nexport async function computeSha256(source: string | Buffer): Promise<string> {\n const hash = createHash('sha256');\n\n if (typeof source === 'string') {\n const stream = createReadStream(source);\n for await (const chunk of stream) {\n hash.update(chunk as Buffer);\n }\n } else {\n hash.update(source);\n }\n\n return hash.digest('hex');\n}\n","import type { ApiClient } from '../../core/api-client';\n\nexport type RequestApi = {\n handleFriendRequest(flag: string, approve?: boolean, remark?: string): Promise<any>;\n handleGroupRequest(flag: string, subType: 'add' | 'invite', approve?: boolean, reason?: string): Promise<any>;\n};\n\nexport function createRequestApi(client: ApiClient): RequestApi {\n return {\n handleFriendRequest(flag, approve = true, remark?: string) {\n return client.call('set_friend_add_request', { flag, approve, remark });\n },\n handleGroupRequest(flag, subType, approve = true, reason?: string) {\n return client.call('set_group_add_request', { flag, sub_type: subType, approve, reason });\n },\n };\n}\n","import type { ApiClient } from '../../core/api-client';\n\nexport type SystemApi = {\n getOnlineClients(noCache?: boolean): Promise<any>;\n getRobotUinRange(): Promise<any>;\n canSendImage(): Promise<any>;\n canSendRecord(): Promise<any>;\n\n getCookies(domain: string): Promise<any>;\n getCsrfToken(): Promise<any>;\n getCredentials(domain: string): Promise<any>;\n\n setInputStatus(userId: number | string, eventType: number): Promise<any>;\n\n ocrImage(image: string, dot?: boolean): Promise<any>;\n translateEn2zh(words: string[]): Promise<any>;\n\n checkUrlSafely(url: string): Promise<any>;\n handleQuickOperation(context: any, operation: any): Promise<any>;\n\n getModelShow(model: string): Promise<any>;\n setModelShow(model: string, modelShow: string): Promise<any>;\n\n getPacketStatus(): Promise<any>;\n};\n\nexport function createSystemApi(client: ApiClient): SystemApi {\n return {\n getOnlineClients(noCache = false) {\n return client.call('get_online_clients', { no_cache: noCache });\n },\n getRobotUinRange() {\n return client.call('get_robot_uin_range');\n },\n canSendImage() {\n return client.call('can_send_image');\n },\n canSendRecord() {\n return client.call('can_send_record');\n },\n getCookies(domain: string) {\n return client.call('get_cookies', { domain });\n },\n getCsrfToken() {\n return client.call('get_csrf_token');\n },\n getCredentials(domain: string) {\n return client.call('get_credentials', { domain });\n },\n setInputStatus(userId: number | string, eventType: number) {\n // NapCat 侧字段是 event_type;WebUI 里也有 eventType 的旧写法\n return client.call('set_input_status', { user_id: userId, event_type: eventType, eventType });\n },\n ocrImage(image: string, dot = false) {\n return client.call(dot ? '.ocr_image' : 'ocr_image', { image });\n },\n translateEn2zh(words: string[]) {\n return client.call('translate_en2zh', { words });\n },\n checkUrlSafely(url: string) {\n return client.call('check_url_safely', { url });\n },\n handleQuickOperation(context: any, operation: any) {\n return client.call('.handle_quick_operation', { context, operation });\n },\n getModelShow(model: string) {\n return client.call('_get_model_show', { model });\n },\n setModelShow(model: string, modelShow: string) {\n return client.call('_set_model_show', { model, model_show: modelShow });\n },\n getPacketStatus() {\n return client.call('nc_get_packet_status');\n },\n };\n}\n\n","import type { ApiClient } from '../../core/api-client';\n\nexport type NapCatApi = {\n // RKey\n getRkeyEx(): Promise<any>;\n getRkeyServer(): Promise<any>;\n getRkey(): Promise<any>;\n\n // 好友/群扩展\n setFriendRemark(userId: number | string, remark: string): Promise<any>;\n deleteFriend(userId: number | string): Promise<any>;\n getUnidirectionalFriendList(): Promise<any>;\n\n setGroupRemark(groupId: number | string, remark: string): Promise<any>;\n getGroupInfoEx(groupId: number | string): Promise<any>;\n getGroupDetailInfo(groupId: number | string): Promise<any>;\n getGroupIgnoredNotifies(): Promise<any>;\n getGroupShutList(groupId: number | string): Promise<any>;\n\n // 合并转发(扩展)\n sendPrivateForwardMessage(params: { user_id: number | string; messages: any[]; news?: any[]; prompt?: string; summary?: string; source?: string }): Promise<any>;\n forwardFriendSingleMsg(userId: number | string, messageId: number | string): Promise<any>;\n forwardGroupSingleMsg(groupId: number | string, messageId: number | string): Promise<any>;\n sendForwardMsg(params: { group_id?: number | string; user_id?: number | string; messages: any[]; news?: any[]; prompt?: string; summary?: string; source?: string }): Promise<any>;\n\n // 群公告(go-cqhttp 扩展)\n sendGroupNotice(params: {\n group_id: number | string;\n content: string;\n image?: string;\n pinned?: number | string;\n type?: number | string;\n confirm_required?: number | string;\n is_show_edit_card?: number | string;\n tip_window_type?: number | string;\n }): Promise<any>;\n getGroupNotice(groupId: number | string): Promise<any>;\n delGroupNotice(groupId: number | string, noticeId: string): Promise<any>;\n\n // 在线状态(扩展)\n setOnlineStatus(status: number | string, extStatus: number | string, batteryStatus: number | string): Promise<any>;\n setDiyOnlineStatus(faceId: number | string, wording?: string, faceType?: number | string): Promise<any>;\n\n // Ark / 小程序\n sendArkShare(params: { user_id?: number | string; group_id?: number | string; phone_number?: string }): Promise<any>;\n sendGroupArkShare(groupId: number | string): Promise<any>;\n getMiniAppArk(payload: any): Promise<any>;\n\n // AI 语音\n getAiCharacters(groupId: number | string, chatType?: number | string): Promise<any>;\n getAiRecord(groupId: number | string, character: string, text: string): Promise<any>;\n sendGroupAiRecord(groupId: number | string, character: string, text: string): Promise<any>;\n\n // 群打卡\n setGroupSign(groupId: number | string): Promise<any>;\n sendGroupSign(groupId: number | string): Promise<any>;\n\n // 其他\n fetchCustomFace(params?: any): Promise<any>;\n getEmojiLikes(params: { message_id: string; emoji_id: string; emoji_type?: string; group_id?: string; count?: number }): Promise<any>;\n getClientkey(): Promise<any>;\n clickInlineKeyboardButton(params: {\n group_id: number | string;\n bot_appid: string;\n button_id?: string;\n callback_data?: string;\n msg_seq?: string;\n }): Promise<any>;\n};\n\nexport function createNapCatApi(client: ApiClient): NapCatApi {\n return {\n getRkeyEx() {\n return client.call('get_rkey');\n },\n getRkeyServer() {\n return client.call('get_rkey_server');\n },\n getRkey() {\n return client.call('nc_get_rkey');\n },\n setFriendRemark(userId, remark) {\n return client.call('set_friend_remark', { user_id: userId, remark });\n },\n deleteFriend(userId) {\n return client.call('delete_friend', { user_id: userId });\n },\n getUnidirectionalFriendList() {\n return client.call('get_unidirectional_friend_list');\n },\n setGroupRemark(groupId, remark) {\n return client.call('set_group_remark', { group_id: String(groupId), remark });\n },\n getGroupInfoEx(groupId) {\n return client.call('get_group_info_ex', { group_id: groupId });\n },\n getGroupDetailInfo(groupId) {\n return client.call('get_group_detail_info', { group_id: groupId });\n },\n getGroupIgnoredNotifies() {\n return client.call('get_group_ignored_notifies');\n },\n getGroupShutList(groupId) {\n return client.call('get_group_shut_list', { group_id: groupId });\n },\n sendPrivateForwardMessage(params) {\n return client.call('send_private_forward_msg', params);\n },\n forwardFriendSingleMsg(userId, messageId) {\n return client.call('forward_friend_single_msg', { user_id: userId, message_id: messageId });\n },\n forwardGroupSingleMsg(groupId, messageId) {\n return client.call('forward_group_single_msg', { group_id: groupId, message_id: messageId });\n },\n sendForwardMsg(params) {\n return client.call('send_forward_msg', params);\n },\n sendGroupNotice(params) {\n return client.call('_send_group_notice', params);\n },\n getGroupNotice(groupId) {\n return client.call('_get_group_notice', { group_id: groupId });\n },\n delGroupNotice(groupId, noticeId) {\n return client.call('_del_group_notice', { group_id: groupId, notice_id: +noticeId });\n },\n setOnlineStatus(status, extStatus, batteryStatus) {\n return client.call('set_online_status', { status, ext_status: extStatus, battery_status: batteryStatus });\n },\n setDiyOnlineStatus(faceId, wording = ' ', faceType = 1) {\n return client.call('set_diy_online_status', { face_id: faceId, wording, face_type: faceType });\n },\n sendArkShare(params) {\n return client.call('send_ark_share', params);\n },\n sendGroupArkShare(groupId) {\n return client.call('send_group_ark_share', { group_id: groupId });\n },\n getMiniAppArk(payload: any) {\n return client.call('get_mini_app_ark', payload);\n },\n getAiCharacters(groupId, chatType = 1) {\n return client.call('get_ai_characters', { group_id: groupId, chat_type: chatType });\n },\n getAiRecord(groupId, character, text) {\n return client.call('get_ai_record', { group_id: groupId, character, text });\n },\n sendGroupAiRecord(groupId, character, text) {\n return client.call('send_group_ai_record', { group_id: groupId, character, text });\n },\n setGroupSign(groupId) {\n return client.call('set_group_sign', { group_id: groupId });\n },\n sendGroupSign(groupId) {\n return client.call('send_group_sign', { group_id: groupId });\n },\n fetchCustomFace(params) {\n return client.call('fetch_custom_face', params ?? {});\n },\n getEmojiLikes(params) {\n return client.call('get_emoji_likes', params);\n },\n getClientkey() {\n return client.call('get_clientkey');\n },\n clickInlineKeyboardButton(params) {\n return client.call('click_inline_keyboard_button', {\n ...params,\n button_id: params.button_id ?? '',\n callback_data: params.callback_data ?? '',\n msg_seq: params.msg_seq ?? '10086',\n });\n },\n };\n}\n","import type { ApiClient } from '../../core/api-client';\n\n/**\n * NapCatQQ ActionName 全量列表(服务端路由表)\n * - 可用于“完全覆盖”服务端 action,而不必在 SDK 里为每个 action 单独写一层包装。\n * - 对于包含 '.'/'_' 等前缀的 action,建议使用 bracket 访问:api.raw['.ocr_image'](...)\n */\nexport const NAPCAT_ACTIONS = [\n '.get_word_slices',\n '.handle_quick_operation',\n '.ocr_image',\n 'ArkShareGroup',\n 'ArkSharePeer',\n '_del_group_notice',\n '_get_group_notice',\n '_get_model_show',\n '_mark_all_as_read',\n '_send_group_notice',\n '_set_model_show',\n 'bot_exit',\n 'can_send_image',\n 'can_send_record',\n 'check_url_safely',\n 'clean_cache',\n 'clean_stream_temp_file',\n 'click_inline_keyboard_button',\n 'create_collection',\n 'create_group_file_folder',\n 'del_group_album_media',\n 'delete_essence_msg',\n 'delete_friend',\n 'delete_group_file',\n 'delete_group_folder',\n 'delete_msg',\n 'delete_unidirectional_friend',\n 'do_group_album_comment',\n 'download_file',\n 'download_file_image_stream',\n 'download_file_record_stream',\n 'download_file_stream',\n 'fetch_custom_face',\n 'fetch_emoji_like',\n 'forward_friend_single_msg',\n 'forward_group_single_msg',\n 'friend_poke',\n 'get_ai_characters',\n 'get_ai_record',\n 'get_clientkey',\n 'get_collection_list',\n 'get_cookies',\n 'get_credentials',\n 'get_csrf_token',\n 'get_doubt_friends_add_request',\n 'get_essence_msg_list',\n 'get_file',\n 'get_forward_msg',\n 'get_friend_list',\n 'get_friend_msg_history',\n 'get_friends_with_category',\n 'get_group_album_media_list',\n 'get_group_at_all_remain',\n 'get_group_detail_info',\n 'get_group_file_system_info',\n 'get_group_file_url',\n 'get_group_files_by_folder',\n 'get_group_honor_info',\n 'get_group_ignore_add_request',\n 'get_group_ignored_notifies',\n 'get_group_info',\n 'get_group_info_ex',\n 'get_group_list',\n 'get_group_member_info',\n 'get_group_member_list',\n 'get_group_msg_history',\n 'get_group_root_files',\n 'get_group_shut_list',\n 'get_group_system_msg',\n 'get_guild_list',\n 'get_guild_service_profile',\n 'get_image',\n 'get_login_info',\n 'get_mini_app_ark',\n 'get_msg',\n 'get_online_clients',\n 'get_private_file_url',\n 'get_profile_like',\n 'get_qun_album_list',\n 'get_recent_contact',\n 'get_record',\n 'get_rkey',\n 'get_rkey_server',\n 'get_robot_uin_range',\n 'get_status',\n 'get_stranger_info',\n 'get_unidirectional_friend_list',\n 'get_version_info',\n 'group_poke',\n 'mark_group_msg_as_read',\n 'mark_msg_as_read',\n 'mark_private_msg_as_read',\n 'move_group_file',\n 'nc_get_packet_status',\n 'nc_get_rkey',\n 'nc_get_user_status',\n 'ocr_image',\n 'qidian_get_account_info',\n 'reboot_normal',\n 'reload_event_filter',\n 'rename_group_file',\n 'send_ark_share',\n 'send_forward_msg',\n 'send_group_ai_record',\n 'send_group_ark_share',\n 'send_group_forward_msg',\n 'send_group_msg',\n 'send_group_sign',\n 'send_like',\n 'send_msg',\n 'send_packet',\n 'send_poke',\n 'send_private_forward_msg',\n 'send_private_msg',\n 'set_diy_online_status',\n 'set_doubt_friends_add_request',\n 'set_essence_msg',\n 'set_friend_add_request',\n 'set_friend_remark',\n 'set_group_add_option',\n 'set_group_add_request',\n 'set_group_admin',\n 'set_group_album_media_like',\n 'set_group_anonymous',\n 'set_group_anonymous_ban',\n 'set_group_ban',\n 'set_group_card',\n 'set_group_kick',\n 'set_group_kick_members',\n 'set_group_leave',\n 'set_group_name',\n 'set_group_portrait',\n 'set_group_remark',\n 'set_group_robot_add_option',\n 'set_group_search',\n 'set_group_sign',\n 'set_group_special_title',\n 'set_group_todo',\n 'set_group_whole_ban',\n 'set_input_status',\n 'set_msg_emoji_like',\n 'set_online_status',\n 'set_qq_avatar',\n 'set_qq_profile',\n 'set_restart',\n 'set_self_longnick',\n 'test_auto_register_01',\n 'test_auto_register_02',\n 'test_download_stream',\n 'trans_group_file',\n 'translate_en2zh',\n 'unknown',\n 'upload_file_stream',\n 'upload_group_file',\n 'upload_image_to_qun_album',\n 'upload_private_file',\n] as const;\n\nexport type NapCatAction = typeof NAPCAT_ACTIONS[number];\n\nexport type RawActionApi = {\n [K in NapCatAction]: (params?: any) => Promise<any>;\n};\n\nexport function createRawActionApi(client: ApiClient): RawActionApi {\n const entries = NAPCAT_ACTIONS.map((action) => [\n action,\n (params?: any) => client.call(action, params ?? {}),\n ] as const);\n return Object.fromEntries(entries) as RawActionApi;\n}\n\n","import type { ApiClient } from '../../core/api-client';\nimport { createMessageApi, type MessageApi } from './message';\nimport { createMediaApi, type MediaApi } from './media';\nimport { createAccountApi, type AccountApi } from './account';\nimport { createGroupApi, type GroupApi } from './group';\nimport { createFileApi, type FileApi } from './files';\nimport { createStreamApi, type StreamApi } from './stream';\nimport { createRequestApi, type RequestApi } from './requests';\nimport { createSystemApi, type SystemApi } from './system';\nimport { createNapCatApi, type NapCatApi } from './napcat';\nimport { createRawActionApi, type RawActionApi } from './raw';\n\nimport type { Logger } from '../../types/config';\n\n/**\n * OneBot 11 API 封装\n * 将 ApiClient 的底层 call 转为清晰的业务方法\n * 通过组合各领域 API,保持类方法名称不变。\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport class OneBotApi {\n private messageApi: MessageApi;\n private mediaApi: MediaApi;\n private accountApi: AccountApi;\n private groupApi: GroupApi;\n private fileApi: FileApi;\n private streamApi: StreamApi;\n private requestApi: RequestApi;\n private systemApi: SystemApi;\n private napcatApi: NapCatApi;\n readonly raw: RawActionApi;\n\n constructor(client: ApiClient, logger: Logger) {\n this.messageApi = createMessageApi(client);\n this.mediaApi = createMediaApi(client, logger);\n this.accountApi = createAccountApi(client);\n this.groupApi = createGroupApi(client);\n this.fileApi = createFileApi(client);\n this.streamApi = createStreamApi(client);\n this.requestApi = createRequestApi(client);\n this.systemApi = createSystemApi(client);\n this.napcatApi = createNapCatApi(client);\n this.raw = createRawActionApi(client);\n\n Object.assign(\n this,\n this.messageApi,\n this.mediaApi,\n this.accountApi,\n this.groupApi,\n this.fileApi,\n this.streamApi,\n this.requestApi,\n this.systemApi,\n this.napcatApi,\n );\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport interface OneBotApi extends MessageApi, MediaApi, AccountApi, GroupApi, FileApi, StreamApi, RequestApi, SystemApi, NapCatApi { }\n","import type { OneBotApi } from './index';\n\n/**\n * 统一封装 OneBot API 代理,避免 NapLink 主类塞满转发方法。\n * 通过 bindOneBotApiMethods 在实例上动态挂载对应方法,保持对外 API 不变。\n */\nexport type OneBotApiMethods = {\n getLoginInfo(): Promise<any>;\n getStatus(): Promise<any>;\n sendMessage(params: {\n message_type?: 'private' | 'group';\n user_id?: number | string;\n group_id?: number | string;\n message: any;\n auto_escape?: boolean;\n }): Promise<any>;\n sendPrivateMessage(userId: number | string, message: any): Promise<any>;\n sendGroupMessage(groupId: number | string, message: any): Promise<any>;\n deleteMessage(messageId: number | string): Promise<any>;\n getMessage(messageId: number | string): Promise<any>;\n getForwardMessage(id: string): Promise<any>;\n getEssenceMessageList(groupId: number | string): Promise<any>;\n markMessageAsRead(messageId: number | string): Promise<any>;\n markGroupMsgAsRead(groupId: number | string): Promise<any>;\n markPrivateMsgAsRead(userId: number | string): Promise<any>;\n markAllMsgAsRead(): Promise<any>;\n getGroupAtAllRemain(groupId: number | string): Promise<any>;\n getGroupSystemMsg(): Promise<any>;\n getGroupHonorInfo(\n groupId: number | string,\n type: 'all' | 'talkative' | 'performer' | 'legend' | 'strong_newbie' | 'emotion'\n ): Promise<any>;\n getGroupFileSystemInfo(groupId: number | string): Promise<any>;\n getGroupRootFiles(groupId: number | string): Promise<any>;\n getGroupFilesByFolder(groupId: number | string, folderId: string): Promise<any>;\n getGroupFileUrl(groupId: number | string, fileId: string, busid?: number): Promise<any>;\n deleteGroupFile(groupId: number | string, fileId: string, busid?: number): Promise<any>;\n createGroupFileFolder(groupId: number | string, name: string, parentId?: string): Promise<any>;\n deleteGroupFolder(groupId: number | string, folderId: string): Promise<any>;\n downloadFile(url: string, threadCount?: number, headers?: Record<string, string>): Promise<any>;\n uploadFileStream(\n file: string | Buffer | Uint8Array | NodeJS.ReadableStream,\n options?: {\n chunkSize?: number;\n streamId?: string;\n expectedSha256?: string;\n fileRetention?: number;\n filename?: string;\n reset?: boolean;\n verifyOnly?: boolean;\n }\n ): Promise<any>;\n getUploadStreamStatus(streamId: string): Promise<any>;\n downloadFileStream(fileId: string, options?: { chunkSize?: number }): { packets: AsyncIterable<any>; result: Promise<any> };\n downloadFileStreamToFile(fileId: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: any }>;\n downloadFileImageStream(fileId: string, options?: { chunkSize?: number }): { packets: AsyncIterable<any>; result: Promise<any> };\n downloadFileImageStreamToFile(fileId: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: any }>;\n downloadFileRecordStream(fileId: string, outFormat?: string, options?: { chunkSize?: number; filename?: string }): { packets: AsyncIterable<any>; result: Promise<any> };\n downloadFileRecordStreamToFile(fileId: string, outFormat?: string, options?: { chunkSize?: number; filename?: string }): Promise<{ path: string; info?: any }>;\n cleanStreamTempFile(): Promise<any>;\n sendGroupForwardMessage(groupId: number | string, messages: any[]): Promise<any>;\n getGroupMsgHistory(params: { group_id: number | string; message_seq: number | string; count: number; reverse_order?: boolean }): Promise<any>;\n getFriendMsgHistory(params: { user_id: number | string; message_seq: number | string; count: number; reverse_order?: boolean }): Promise<any>;\n getRecentContact(count: number): Promise<any>;\n setMsgEmojiLike(messageId: number | string, emojiId: number, set: boolean): Promise<any>;\n fetchEmojiLike(params: { message_id: number | string; emojiId: string; emojiType: string; group_id?: number | string; user_id?: number | string; count?: number; cookie?: string }): Promise<any>;\n getEmojiLikes(params: { message_id: string; emoji_id: string; emoji_type?: string; group_id?: string; count?: number }): Promise<any>;\n fetchCustomFace(params?: any): Promise<any>;\n sendGroupPoke(groupId: number | string, userId: number | string): Promise<any>;\n sendFriendPoke(userId: number | string): Promise<any>;\n sendPoke(targetId: number | string, groupId?: number | string): Promise<any>;\n getImage(file: string): Promise<any>;\n getRecord(file: string, outFormat?: string): Promise<any>;\n getFile(file: string): Promise<any>;\n getFriendList(): Promise<any>;\n getGroupList(): Promise<any>;\n getGroupInfo(groupId: number | string, noCache?: boolean): Promise<any>;\n getGroupMemberList(groupId: number | string): Promise<any>;\n getGroupMemberInfo(groupId: number | string, userId: number | string, noCache?: boolean): Promise<any>;\n setGroupBan(groupId: number | string, userId: number | string, duration?: number): Promise<any>;\n unsetGroupBan(groupId: number | string, userId: number | string): Promise<any>;\n setGroupWholeBan(groupId: number | string, enable?: boolean): Promise<any>;\n setGroupKick(groupId: number | string, userId: number | string, rejectAddRequest?: boolean): Promise<any>;\n setGroupLeave(groupId: number | string, isDismiss?: boolean): Promise<any>;\n setGroupCard(groupId: number | string, userId: number | string, card: string): Promise<any>;\n setGroupName(groupId: number | string, groupName: string): Promise<any>;\n setGroupPortrait(groupId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream): Promise<any>;\n setGroupAdmin(groupId: number | string, userId: number | string, enable?: boolean): Promise<any>;\n setGroupAnonymousBan(groupId: number | string, anonymousFlag: string, duration?: number): Promise<any>;\n setEssenceMessage(messageId: number | string): Promise<any>;\n deleteEssenceMessage(messageId: number | string): Promise<any>;\n setGroupSpecialTitle(\n groupId: number | string,\n userId: number | string,\n specialTitle: string,\n duration?: number\n ): Promise<any>;\n sendLike(userId: number | string, times?: number): Promise<any>;\n uploadGroupFile(groupId: number | string, file: string, name: string, folder?: string, uploadFile?: boolean): Promise<any>;\n uploadPrivateFile(userId: number | string, file: string, name: string, uploadFile?: boolean): Promise<any>;\n getStrangerInfo(userId: number | string, noCache?: boolean): Promise<any>;\n getVersionInfo(): Promise<any>;\n handleFriendRequest(flag: string, approve?: boolean, remark?: string): Promise<any>;\n handleGroupRequest(flag: string, subType: 'add' | 'invite', approve?: boolean, reason?: string): Promise<any>;\n\n // SystemApi (NapCat / go-cqhttp 扩展)\n getOnlineClients(noCache?: boolean): Promise<any>;\n getRobotUinRange(): Promise<any>;\n canSendImage(): Promise<any>;\n canSendRecord(): Promise<any>;\n getCookies(domain: string): Promise<any>;\n getCsrfToken(): Promise<any>;\n getCredentials(domain: string): Promise<any>;\n setInputStatus(userId: number | string, eventType: number): Promise<any>;\n ocrImage(image: string, dot?: boolean): Promise<any>;\n translateEn2zh(words: string[]): Promise<any>;\n checkUrlSafely(url: string): Promise<any>;\n handleQuickOperation(context: any, operation: any): Promise<any>;\n getModelShow(model: string): Promise<any>;\n setModelShow(model: string, modelShow: string): Promise<any>;\n getPacketStatus(): Promise<any>;\n\n // NapCatApi (扩展能力合集)\n getRkeyEx(): Promise<any>;\n getRkeyServer(): Promise<any>;\n getRkey(): Promise<any>;\n setFriendRemark(userId: number | string, remark: string): Promise<any>;\n deleteFriend(userId: number | string): Promise<any>;\n getUnidirectionalFriendList(): Promise<any>;\n setGroupRemark(groupId: number | string, remark: string): Promise<any>;\n getGroupInfoEx(groupId: number | string): Promise<any>;\n getGroupDetailInfo(groupId: number | string): Promise<any>;\n getGroupIgnoredNotifies(): Promise<any>;\n getGroupShutList(groupId: number | string): Promise<any>;\n sendPrivateForwardMessage(params: { user_id: number | string; messages: any[]; news?: any[]; prompt?: string; summary?: string; source?: string }): Promise<any>;\n forwardFriendSingleMsg(userId: number | string, messageId: number | string): Promise<any>;\n forwardGroupSingleMsg(groupId: number | string, messageId: number | string): Promise<any>;\n sendForwardMsg(params: { group_id?: number | string; user_id?: number | string; messages: any[]; news?: any[]; prompt?: string; summary?: string; source?: string }): Promise<any>;\n sendGroupNotice(params: { group_id: number | string; content: string; image?: string; pinned?: number | string; type?: number | string; confirm_required?: number | string; is_show_edit_card?: number | string; tip_window_type?: number | string }): Promise<any>;\n getGroupNotice(groupId: number | string): Promise<any>;\n delGroupNotice(groupId: number | string, noticeId: string): Promise<any>;\n setOnlineStatus(status: number | string, extStatus: number | string, batteryStatus: number | string): Promise<any>;\n setDiyOnlineStatus(faceId: number | string, wording?: string, faceType?: number | string): Promise<any>;\n sendArkShare(params: { user_id?: number | string; group_id?: number | string; phone_number?: string }): Promise<any>;\n sendGroupArkShare(groupId: number | string): Promise<any>;\n getMiniAppArk(payload: any): Promise<any>;\n getAiCharacters(groupId: number | string, chatType?: number | string): Promise<any>;\n getAiRecord(groupId: number | string, character: string, text: string): Promise<any>;\n sendGroupAiRecord(groupId: number | string, character: string, text: string): Promise<any>;\n setGroupSign(groupId: number | string): Promise<any>;\n sendGroupSign(groupId: number | string): Promise<any>;\n getClientkey(): Promise<any>;\n clickInlineKeyboardButton(params: { group_id: number | string; bot_appid: string; button_id?: string; callback_data?: string; msg_seq?: string }): Promise<any>;\n\n /**\n * Raw action table (ActionName 全覆盖)\n * 访问方式:client.raw['get_group_shut_list']({ group_id: 123 })\n */\n raw: any;\n};\n\nexport function bindOneBotApiMethods(api: OneBotApi, target: any): void {\n const bindings: Partial<OneBotApiMethods> = {\n getLoginInfo: () => api.getLoginInfo(),\n getStatus: () => api.getStatus(),\n sendMessage: (params) => api.sendMessage(params),\n sendPrivateMessage: (userId, message) => api.sendPrivateMessage(userId, message),\n sendGroupMessage: (groupId, message) => api.sendGroupMessage(groupId, message),\n deleteMessage: (messageId) => api.deleteMessage(messageId),\n getMessage: (messageId) => api.getMessage(messageId),\n getForwardMessage: (id) => api.getForwardMessage(id),\n getEssenceMessageList: (groupId) => api.getEssenceMessageList(groupId),\n markMessageAsRead: (messageId) => api.markMessageAsRead(messageId),\n markGroupMsgAsRead: (groupId) => api.markGroupMsgAsRead(groupId),\n markPrivateMsgAsRead: (userId) => api.markPrivateMsgAsRead(userId),\n markAllMsgAsRead: () => api.markAllMsgAsRead(),\n getGroupAtAllRemain: (groupId) => api.getGroupAtAllRemain(groupId),\n getGroupSystemMsg: () => api.getGroupSystemMsg(),\n getGroupHonorInfo: (groupId, type) => api.getGroupHonorInfo(groupId, type),\n getGroupFileSystemInfo: (groupId) => api.getGroupFileSystemInfo(groupId),\n getGroupRootFiles: (groupId) => api.getGroupRootFiles(groupId),\n getGroupFilesByFolder: (groupId, folderId) => api.getGroupFilesByFolder(groupId, folderId),\n getGroupFileUrl: (groupId, fileId, busid) => api.getGroupFileUrl(groupId, fileId, busid),\n deleteGroupFile: (groupId, fileId, busid) => api.deleteGroupFile(groupId, fileId, busid),\n createGroupFileFolder: (groupId, name, parentId) => api.createGroupFileFolder(groupId, name, parentId),\n deleteGroupFolder: (groupId, folderId) => api.deleteGroupFolder(groupId, folderId),\n downloadFile: (url, threadCount, headers) => api.downloadFile(url, threadCount, headers),\n uploadFileStream: (file, options) => api.uploadFileStream(file, options),\n getUploadStreamStatus: (streamId) => api.getUploadStreamStatus(streamId),\n downloadFileStream: (fileId, options) => api.downloadFileStream(fileId, options),\n downloadFileStreamToFile: (fileId, options) => api.downloadFileStreamToFile(fileId, options),\n downloadFileImageStream: (fileId, options) => api.downloadFileImageStream(fileId, options),\n downloadFileImageStreamToFile: (fileId, options) => api.downloadFileImageStreamToFile(fileId, options),\n downloadFileRecordStream: (fileId, outFormat, options) => api.downloadFileRecordStream(fileId, outFormat, options),\n downloadFileRecordStreamToFile: (fileId, outFormat, options) => api.downloadFileRecordStreamToFile(fileId, outFormat, options),\n cleanStreamTempFile: () => api.cleanStreamTempFile(),\n sendGroupForwardMessage: (groupId, messages) => api.sendGroupForwardMessage(groupId, messages),\n getGroupMsgHistory: (params) => api.getGroupMsgHistory(params),\n getFriendMsgHistory: (params) => api.getFriendMsgHistory(params),\n getRecentContact: (count) => api.getRecentContact(count),\n setMsgEmojiLike: (messageId, emojiId, set) => api.setMsgEmojiLike(messageId, emojiId, set),\n fetchEmojiLike: (params) => api.fetchEmojiLike(params),\n getEmojiLikes: (params) => (api as any).getEmojiLikes(params),\n sendGroupPoke: (groupId, userId) => api.sendGroupPoke(groupId, userId),\n sendFriendPoke: (userId) => api.sendFriendPoke(userId),\n sendPoke: (targetId, groupId) => api.sendPoke(targetId, groupId),\n getImage: (file) => api.getImage(file),\n getRecord: (file, outFormat) => api.getRecord(file, outFormat),\n getFile: (file) => api.getFile(file),\n getFriendList: () => api.getFriendList(),\n getGroupList: () => api.getGroupList(),\n getGroupInfo: (groupId, noCache = false) => api.getGroupInfo(groupId, noCache),\n getGroupMemberList: (groupId) => api.getGroupMemberList(groupId),\n getGroupMemberInfo: (groupId, userId, noCache = false) => api.getGroupMemberInfo(groupId, userId, noCache),\n setGroupBan: (groupId, userId, duration = 30 * 60) => api.setGroupBan(groupId, userId, duration),\n unsetGroupBan: (groupId, userId) => api.unsetGroupBan(groupId, userId),\n setGroupWholeBan: (groupId, enable = true) => api.setGroupWholeBan(groupId, enable),\n setGroupKick: (groupId, userId, rejectAddRequest = false) => api.setGroupKick(groupId, userId, rejectAddRequest),\n setGroupLeave: (groupId, isDismiss = false) => api.setGroupLeave(groupId, isDismiss),\n setGroupCard: (groupId, userId, card) => api.setGroupCard(groupId, userId, card),\n setGroupName: (groupId, groupName) => api.setGroupName(groupId, groupName),\n setGroupPortrait: (groupId, file) => api.setGroupPortrait(groupId, file),\n setGroupAdmin: (groupId, userId, enable = true) => api.setGroupAdmin(groupId, userId, enable),\n setGroupAnonymousBan: (groupId, anonymousFlag, duration = 30 * 60) =>\n api.setGroupAnonymousBan(groupId, anonymousFlag, duration),\n setEssenceMessage: (messageId) => api.setEssenceMessage(messageId),\n deleteEssenceMessage: (messageId) => api.deleteEssenceMessage(messageId),\n setGroupSpecialTitle: (groupId, userId, specialTitle, duration = -1) =>\n api.setGroupSpecialTitle(groupId, userId, specialTitle, duration),\n sendLike: (userId, times = 1) => api.sendLike(userId, times),\n uploadGroupFile: (groupId, file, name, folder, uploadFile) => api.uploadGroupFile(groupId, file, name, folder, uploadFile),\n uploadPrivateFile: (userId, file, name, uploadFile) => api.uploadPrivateFile(userId, file, name, uploadFile),\n getStrangerInfo: (userId, noCache = false) => api.getStrangerInfo(userId, noCache),\n getVersionInfo: () => api.getVersionInfo(),\n handleFriendRequest: (flag, approve = true, remark?: string) => api.handleFriendRequest(flag, approve, remark),\n handleGroupRequest: (flag, subType, approve = true, reason?: string) =>\n api.handleGroupRequest(flag, subType, approve, reason),\n\n // SystemApi\n getOnlineClients: (noCache = false) => (api as any).getOnlineClients(noCache),\n getRobotUinRange: () => (api as any).getRobotUinRange(),\n canSendImage: () => (api as any).canSendImage(),\n canSendRecord: () => (api as any).canSendRecord(),\n getCookies: (domain) => (api as any).getCookies(domain),\n getCsrfToken: () => (api as any).getCsrfToken(),\n getCredentials: (domain) => (api as any).getCredentials(domain),\n setInputStatus: (userId, eventType) => (api as any).setInputStatus(userId, eventType),\n ocrImage: (image, dot) => (api as any).ocrImage(image, dot),\n translateEn2zh: (words) => (api as any).translateEn2zh(words),\n checkUrlSafely: (url) => (api as any).checkUrlSafely(url),\n handleQuickOperation: (context, operation) => (api as any).handleQuickOperation(context, operation),\n getModelShow: (model) => (api as any).getModelShow(model),\n setModelShow: (model, modelShow) => (api as any).setModelShow(model, modelShow),\n getPacketStatus: () => (api as any).getPacketStatus(),\n\n // NapCatApi\n getRkeyEx: () => (api as any).getRkeyEx(),\n getRkeyServer: () => (api as any).getRkeyServer(),\n getRkey: () => (api as any).getRkey(),\n setFriendRemark: (userId, remark) => (api as any).setFriendRemark(userId, remark),\n deleteFriend: (userId) => (api as any).deleteFriend(userId),\n getUnidirectionalFriendList: () => (api as any).getUnidirectionalFriendList(),\n setGroupRemark: (groupId, remark) => (api as any).setGroupRemark(groupId, remark),\n getGroupInfoEx: (groupId) => (api as any).getGroupInfoEx(groupId),\n getGroupDetailInfo: (groupId) => (api as any).getGroupDetailInfo(groupId),\n getGroupIgnoredNotifies: () => (api as any).getGroupIgnoredNotifies(),\n getGroupShutList: (groupId) => (api as any).getGroupShutList(groupId),\n sendPrivateForwardMessage: (params) => (api as any).sendPrivateForwardMessage(params),\n forwardFriendSingleMsg: (userId, messageId) => (api as any).forwardFriendSingleMsg(userId, messageId),\n forwardGroupSingleMsg: (groupId, messageId) => (api as any).forwardGroupSingleMsg(groupId, messageId),\n sendForwardMsg: (params) => (api as any).sendForwardMsg(params),\n sendGroupNotice: (params) => (api as any).sendGroupNotice(params),\n getGroupNotice: (groupId) => (api as any).getGroupNotice(groupId),\n delGroupNotice: (groupId, noticeId) => (api as any).delGroupNotice(groupId, noticeId),\n setOnlineStatus: (status, extStatus, batteryStatus) => (api as any).setOnlineStatus(status, extStatus, batteryStatus),\n setDiyOnlineStatus: (faceId, wording, faceType) => (api as any).setDiyOnlineStatus(faceId, wording, faceType),\n sendArkShare: (params) => (api as any).sendArkShare(params),\n sendGroupArkShare: (groupId) => (api as any).sendGroupArkShare(groupId),\n getMiniAppArk: (payload) => (api as any).getMiniAppArk(payload),\n getAiCharacters: (groupId, chatType) => (api as any).getAiCharacters(groupId, chatType),\n getAiRecord: (groupId, character, text) => (api as any).getAiRecord(groupId, character, text),\n sendGroupAiRecord: (groupId, character, text) => (api as any).sendGroupAiRecord(groupId, character, text),\n setGroupSign: (groupId) => (api as any).setGroupSign(groupId),\n sendGroupSign: (groupId) => (api as any).sendGroupSign(groupId),\n fetchCustomFace: (params) => (api as any).fetchCustomFace(params),\n getClientkey: () => (api as any).getClientkey(),\n clickInlineKeyboardButton: (params) => (api as any).clickInlineKeyboardButton(params),\n raw: (api as any).raw,\n };\n\n Object.assign(target, bindings);\n}\n","/**\n * NapLink 配置接口\n * 提供完整的配置选项,所有参数都有合理的默认值\n */\nexport interface NapLinkConfig {\n /** 连接配置 */\n connection: {\n /** WebSocket 服务器 URL */\n url: string;\n /** 访问令牌(可选) */\n token?: string;\n /** 连接超时时间(毫秒) */\n timeout?: number;\n /** 心跳间隔(毫秒,0表示禁用) */\n pingInterval?: number;\n /** 自定义心跳动作(默认 get_status) */\n heartbeatAction?: {\n action: string;\n params?: Record<string, unknown>;\n };\n };\n\n /** 重连配置 */\n reconnect: {\n /** 是否启用自动重连 */\n enabled: boolean;\n /** 最大重连次数 */\n maxAttempts: number;\n /** 指数退避配置 */\n backoff: {\n /** 初始延迟(毫秒) */\n initial: number;\n /** 最大延迟(毫秒) */\n max: number;\n /** 退避倍数 */\n multiplier: number;\n };\n };\n\n /** 日志配置 */\n logging: {\n /** 日志等级 */\n level: 'debug' | 'info' | 'warn' | 'error' | 'off';\n /** 自定义logger(可选) */\n logger?: Logger;\n };\n\n /** API配置 */\n api: {\n /** API调用超时时间(毫秒) */\n timeout: number;\n /** 失败重试次数 */\n retries: number;\n };\n}\n\n/**\n * 日志接口\n * 允许用户提供自定义logger实现\n */\nexport interface Logger {\n debug(message: string, ...meta: unknown[]): void;\n info(message: string, ...meta: unknown[]): void;\n warn(message: string, ...meta: unknown[]): void;\n error(message: string, error?: Error, ...meta: unknown[]): void;\n}\n\n/**\n * 部分配置类型(用于构造函数)\n * 用户只需提供必要的配置,其他使用默认值\n */\nexport type PartialNapLinkConfig = {\n connection: {\n url: string;\n token?: string;\n timeout?: number;\n pingInterval?: number;\n heartbeatAction?: {\n action: string;\n params?: Record<string, unknown>;\n };\n };\n reconnect?: Partial<NapLinkConfig['reconnect']>;\n logging?: Partial<NapLinkConfig['logging']>;\n api?: Partial<NapLinkConfig['api']>;\n};\n\n/**\n * 默认配置\n */\nexport const DEFAULT_CONFIG: Omit<NapLinkConfig, 'connection'> = {\n reconnect: {\n enabled: true,\n maxAttempts: 10,\n backoff: {\n initial: 1000,\n max: 60000,\n multiplier: 2,\n },\n },\n logging: {\n level: 'info',\n },\n api: {\n timeout: 30000,\n retries: 3,\n },\n};\n","import type { NapLinkConfig, PartialNapLinkConfig } from '../types/config';\nimport { DEFAULT_CONFIG } from '../types/config';\nimport { InvalidConfigError } from '../types/errors';\n\n/**\n * 合并用户配置与默认配置,校验必填项。\n */\nexport function mergeConfig(userConfig: PartialNapLinkConfig): NapLinkConfig {\n if (!userConfig.connection?.url) {\n throw new InvalidConfigError('connection.url', '必须提供连接URL');\n }\n\n return {\n connection: {\n url: userConfig.connection.url,\n token: userConfig.connection.token,\n timeout: userConfig.connection.timeout ?? 30000,\n pingInterval: userConfig.connection.pingInterval ?? 30000,\n heartbeatAction: userConfig.connection.heartbeatAction ?? {\n action: 'get_status',\n params: {},\n },\n },\n reconnect: {\n enabled: userConfig.reconnect?.enabled ?? DEFAULT_CONFIG.reconnect.enabled,\n maxAttempts:\n userConfig.reconnect?.maxAttempts ?? DEFAULT_CONFIG.reconnect.maxAttempts,\n backoff: {\n initial:\n userConfig.reconnect?.backoff?.initial ??\n DEFAULT_CONFIG.reconnect.backoff.initial,\n max:\n userConfig.reconnect?.backoff?.max ??\n DEFAULT_CONFIG.reconnect.backoff.max,\n multiplier:\n userConfig.reconnect?.backoff?.multiplier ??\n DEFAULT_CONFIG.reconnect.backoff.multiplier,\n },\n },\n logging: {\n level: userConfig.logging?.level ?? DEFAULT_CONFIG.logging.level,\n logger: userConfig.logging?.logger,\n },\n api: {\n timeout: userConfig.api?.timeout ?? DEFAULT_CONFIG.api.timeout,\n retries: userConfig.api?.retries ?? DEFAULT_CONFIG.api.retries,\n },\n };\n}\n"],"mappings":"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AA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AA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","names":["EventEmitter","WebSocket","ConnectionState","WebSocket","randomUUID","fs","createWriteStream","tmpdir","join","randomUUID","pipeline","stats","createWriteStream","fs","tmpdir","join","randomUUID","EventEmitter"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naplink/naplink",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "现代化的 NapCat WebSocket TypeScript/JavaScript 客户端 SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"lint:fix": "eslint src tests examples --ext .ts --fix",
|
|
26
26
|
"typecheck": "tsc --noEmit"
|
|
27
27
|
},
|
|
28
|
-
"packageManager": "pnpm@
|
|
28
|
+
"packageManager": "pnpm@11.2.2",
|
|
29
29
|
"keywords": [
|
|
30
30
|
"napcat",
|
|
31
31
|
"onebot",
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@eslint/eslintrc": "^3.3.3",
|
|
55
|
-
"@eslint/js": "^
|
|
55
|
+
"@eslint/js": "^10.0.0",
|
|
56
56
|
"@types/node": "^25.0.3",
|
|
57
57
|
"@types/ws": "^8.18.1",
|
|
58
58
|
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
59
59
|
"@typescript-eslint/parser": "^8.50.0",
|
|
60
60
|
"eslint": "^10.1.0",
|
|
61
61
|
"tsup": "^8.5.1",
|
|
62
|
-
"typescript": "^
|
|
62
|
+
"typescript": "^6.0.0",
|
|
63
63
|
"vitest": "^4.0.16"
|
|
64
64
|
},
|
|
65
65
|
"engines": {
|