@naplink/naplink 0.0.2 → 0.0.3

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/README.md CHANGED
@@ -32,11 +32,7 @@
32
32
  ## 📦 安装
33
33
 
34
34
  ```bash
35
- npm install naplink
36
- # 或
37
35
  pnpm add naplink
38
- # 或
39
- yarn add naplink
40
36
  ```
41
37
 
42
38
  ## 🔧 配置示例
@@ -68,19 +64,19 @@ const client = new NapLink({
68
64
 
69
65
  ```bash
70
66
  # 安装依赖
71
- npm install
67
+ pnpm install
72
68
 
73
69
  # 开发模式
74
- npm run dev
70
+ pnpm dev
75
71
 
76
72
  # 构建
77
- npm run build
73
+ pnpm build
78
74
 
79
75
  # 测试
80
- npm test
76
+ pnpm test
81
77
 
82
78
  # 类型检查
83
- npm run typecheck
79
+ pnpm typecheck
84
80
  ```
85
81
 
86
82
  ## 📄 许可证
package/dist/index.d.ts CHANGED
@@ -101,13 +101,15 @@ declare class ConnectionManager {
101
101
  private logger;
102
102
  private onMessage;
103
103
  private onStateChange;
104
+ private emitter?;
104
105
  private ws?;
105
106
  private state;
106
107
  private reconnectService;
107
108
  private heartbeatService?;
108
109
  private connectPromise?;
109
110
  private connectTimeout?;
110
- constructor(config: NapLinkConfig, logger: Logger, onMessage: (data: string) => void, onStateChange: (state: ConnectionState) => void);
111
+ private wasReconnecting;
112
+ constructor(config: NapLinkConfig, logger: Logger, onMessage: (data: string) => void, onStateChange: (state: ConnectionState, wasReconnecting?: boolean) => void, emitter?: any | undefined);
111
113
  /**
112
114
  * 连接到WebSocket服务器
113
115
  */
package/dist/index.js CHANGED
@@ -328,11 +328,14 @@ function startHeartbeat(deps) {
328
328
 
329
329
  // src/core/connection/retry-handler.ts
330
330
  function handleReconnect(deps) {
331
- const { config, logger, reconnectService, setState, connect } = deps;
331
+ const { config, logger, reconnectService, setState, connect, onMaxAttemptsReached } = deps;
332
332
  if (!reconnectService.hasRemainingAttempts()) {
333
333
  setState("disconnected" /* DISCONNECTED */);
334
334
  const err = new MaxReconnectAttemptsError(reconnectService.getMaxAttempts());
335
335
  logger.error("\u81EA\u52A8\u91CD\u8FDE\u5DF2\u8FBE\u4E0A\u9650\uFF0C\u505C\u6B62\u91CD\u8FDE", err);
336
+ if (onMaxAttemptsReached) {
337
+ onMaxAttemptsReached();
338
+ }
336
339
  return false;
337
340
  }
338
341
  setState("reconnecting" /* RECONNECTING */);
@@ -341,6 +344,9 @@ function handleReconnect(deps) {
341
344
  setState("disconnected" /* DISCONNECTED */);
342
345
  const err = new MaxReconnectAttemptsError(config.reconnect.maxAttempts);
343
346
  logger.error("\u81EA\u52A8\u91CD\u8FDE\u5DF2\u8FBE\u4E0A\u9650\uFF0C\u505C\u6B62\u91CD\u8FDE", err);
347
+ if (onMaxAttemptsReached) {
348
+ onMaxAttemptsReached();
349
+ }
344
350
  return false;
345
351
  }
346
352
  return true;
@@ -348,7 +354,7 @@ function handleReconnect(deps) {
348
354
 
349
355
  // src/core/connection/close-handler.ts
350
356
  function handleCloseEvent(deps, event) {
351
- const { getState, setState, stopHeartbeat, logger, config, reconnectService, reconnect } = deps;
357
+ const { getState, setState, stopHeartbeat, logger, config, reconnectService, reconnect, onMaxAttemptsReached } = deps;
352
358
  stopHeartbeat();
353
359
  logger.info(`\u8FDE\u63A5\u5173\u95ED (code: ${event.code}, reason: ${event.reason})`);
354
360
  if (event.code === 1e3) {
@@ -362,7 +368,9 @@ function handleCloseEvent(deps, event) {
362
368
  logger,
363
369
  reconnectService,
364
370
  setState,
365
- connect: reconnect
371
+ connect: reconnect,
372
+ onMaxAttemptsReached
373
+ // 传递回调
366
374
  });
367
375
  } else {
368
376
  setState("disconnected" /* DISCONNECTED */);
@@ -412,11 +420,13 @@ function attachWebSocketHandlers(ws, deps, resolve, reject) {
412
420
 
413
421
  // src/core/connection/manager.ts
414
422
  var ConnectionManager = class {
415
- constructor(config, logger, onMessage, onStateChange) {
423
+ // 跟踪是否处于重连状态
424
+ constructor(config, logger, onMessage, onStateChange, emitter) {
416
425
  this.config = config;
417
426
  this.logger = logger;
418
427
  this.onMessage = onMessage;
419
428
  this.onStateChange = onStateChange;
429
+ this.emitter = emitter;
420
430
  this.reconnectService = new ReconnectService(config.reconnect, logger);
421
431
  }
422
432
  ws;
@@ -425,6 +435,7 @@ var ConnectionManager = class {
425
435
  heartbeatService;
426
436
  connectPromise;
427
437
  connectTimeout;
438
+ wasReconnecting = false;
428
439
  /**
429
440
  * 连接到WebSocket服务器
430
441
  */
@@ -480,7 +491,15 @@ var ConnectionManager = class {
480
491
  logger: this.logger,
481
492
  config: this.config,
482
493
  reconnectService: this.reconnectService,
483
- reconnect: () => this.connect()
494
+ reconnect: () => this.connect(),
495
+ onMaxAttemptsReached: () => {
496
+ if (this.emitter) {
497
+ this.emitter.emit("connection:lost", {
498
+ timestamp: Date.now(),
499
+ attempts: this.reconnectService.getMaxAttempts()
500
+ });
501
+ }
502
+ }
484
503
  }, event),
485
504
  clearConnectTimeout: () => this.clearConnectTimeout()
486
505
  },
@@ -540,7 +559,14 @@ var ConnectionManager = class {
540
559
  if (this.state !== state) {
541
560
  this.state = state;
542
561
  this.logger.debug(`\u72B6\u6001\u53D8\u66F4: ${state}`);
543
- this.onStateChange(state);
562
+ if (state === "reconnecting" /* RECONNECTING */) {
563
+ this.wasReconnecting = true;
564
+ } else if (state === "connected" /* CONNECTED */) {
565
+ this.onStateChange(state, this.wasReconnecting);
566
+ this.wasReconnecting = false;
567
+ return;
568
+ }
569
+ this.onStateChange(state, false);
544
570
  }
545
571
  }
546
572
  /**
@@ -1050,11 +1076,14 @@ var MessageDispatcher = class {
1050
1076
  };
1051
1077
 
1052
1078
  // src/core/connection/state-handler.ts
1053
- function handleConnectionStateChange(emitter, state) {
1079
+ function handleConnectionStateChange(emitter, state, wasReconnecting = false) {
1054
1080
  emitter.emit("state_change", state);
1055
1081
  switch (state) {
1056
1082
  case "connected" /* CONNECTED */:
1057
1083
  emitter.emit("connect");
1084
+ if (wasReconnecting) {
1085
+ emitter.emit("connection:restored", { timestamp: Date.now() });
1086
+ }
1058
1087
  break;
1059
1088
  case "disconnected" /* DISCONNECTED */:
1060
1089
  emitter.emit("disconnect");
@@ -2097,7 +2126,9 @@ var NapLink = class extends EventEmitter2 {
2097
2126
  this.config,
2098
2127
  this.logger,
2099
2128
  (message) => this.dispatcher.dispatch(message),
2100
- (state) => handleConnectionStateChange(this, state)
2129
+ (state, wasReconnecting) => handleConnectionStateChange(this, state, wasReconnecting || false),
2130
+ this
2131
+ // 传递 emitter 用于发送 connection:lost 事件
2101
2132
  );
2102
2133
  this.apiClient = new ApiClient(this.connection, this.config, this.logger);
2103
2134
  this.dispatcher = new MessageDispatcher(this.apiClient, this.eventRouter, this.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 { 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) => handleConnectionStateChange(this, state)\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.destroy();\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: any[]): Promise<void> {\n return this.api.hydrateMedia(message);\n }\n\n /**\n * 调用自定义API\n */\n async callApi<T = any>(method: string, params: any = {}): 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 */\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\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: any[]): void {\n if (this.shouldLog(LogLevel.DEBUG)) {\n console.debug(this.format('DEBUG', message), ...meta);\n }\n }\n\n info(message: string, ...meta: any[]): void {\n if (this.shouldLog(LogLevel.INFO)) {\n console.info(this.format('INFO', message), ...meta);\n }\n }\n\n warn(message: string, ...meta: any[]): 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: any[]): 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 { 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\n constructor(\n private config: NapLinkConfig,\n private logger: Logger,\n private onMessage: (data: string) => void,\n private onStateChange: (state: ConnectionState) => void\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 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 }, 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\n if (this.ws) {\n try {\n this.ws.close(code, reason);\n } catch (error) {\n this.logger.error('关闭连接失败', error as Error);\n }\n this.ws = undefined;\n }\n\n this.setState(ConnectionState.DISCONNECTED);\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 this.onStateChange(state);\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?: any\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?: any) {\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 this.logger.error('重连失败', error as Error);\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 const separator = url.includes('?') ? '&' : '?';\n return `${url}${separator}access_token=${token}`;\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};\n\nexport function handleReconnect(deps: RetryDeps): boolean {\n const { config, logger, reconnectService, setState, connect } = deps;\n\n if (!reconnectService.hasRemainingAttempts()) {\n setState(ConnectionState.DISCONNECTED);\n const err = new MaxReconnectAttemptsError(reconnectService.getMaxAttempts());\n logger.error('自动重连已达上限,停止重连', err);\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 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};\n\nexport function handleCloseEvent(deps: CloseHandlerDeps, event: any): void {\n const { getState, setState, stopHeartbeat, logger, config, reconnectService, reconnect } = 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 });\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);\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: any, 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: any) => void;\n reject: (error: Error) => void;\n createdAt: number;\n method: string;\n timer: NodeJS.Timeout | number;\n timeoutMs: number;\n onPacket?: (packet: any) => 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: any) {\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 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 = any>(\n method: string,\n params: any = {},\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 = any, TFinal = any>(\n method: string,\n params: any = {},\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: any): 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 // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\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 response.retcode,\n response.message,\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 // 清理所有待处理的请求\n this.registry.clearAll('API客户端已销毁');\n\n // 停止清理定时器\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer as NodeJS.Timeout);\n this.cleanupTimer = undefined;\n }\n }\n\n /**\n * 发送API请求\n */\n private sendRequest<T>(\n method: string,\n params: any,\n timeout: number,\n hooks?: {\n onPacket?: (packet: any) => 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),\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';\n\n/**\n * 事件路由器\n * 负责解析OneBot事件并分发到相应的事件处理器\n */\nexport class EventRouter extends EventEmitter {\n private anyListeners: ((event: string | symbol, ...args: any[]) => void)[] = [];\n\n constructor(private logger: Logger) {\n super();\n }\n\n /**\n * 监听所有事件\n */\n onAny(listener: (event: string | symbol, ...args: any[]) => void): this {\n this.anyListeners.push(listener);\n return this;\n }\n\n /**\n * 重写emit以支持onAny\n */\n override emit(event: string | symbol, ...args: any[]): boolean {\n // 先调用anyListeners\n this.anyListeners.forEach((listener) => {\n try {\n listener(event, ...args);\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: any): void {\n try {\n const postType = data.post_type;\n\n if (!postType) {\n this.logger.warn('收到无效消息: 缺少 post_type', data);\n return;\n }\n\n this.logger.debug(`路由事件: ${postType}`, {\n messageType: data.message_type,\n noticeType: data.notice_type,\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: any): void {\n const type = data.meta_event_type;\n const events = [`meta_event`, `meta_event.${type}`];\n\n if (type === 'lifecycle') {\n events.push(`meta_event.lifecycle.${data.sub_type}`);\n }\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由消息事件\n */\n private routeMessage(data: any): void {\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: any): void {\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: any): void {\n const noticeType = data.notice_type;\n const subType = data.sub_type;\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: any): void {\n const requestType = data.request_type;\n const subType = data.sub_type;\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: any): void {\n for (const event of events) {\n this.logger.debug(`触发事件: ${event}`);\n this.emit(event, data);\n }\n }\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 // 如果有echo,说明是API响应\n if (data.echo) {\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 */\nexport function handleConnectionStateChange(emitter: EventEmitter, state: ConnectionState): void {\n emitter.emit('state_change', state);\n\n // 触发具体的状态事件\n switch (state) {\n case ConnectionState.CONNECTED:\n emitter.emit('connect');\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 }): 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';\n\nexport type MediaApi = {\n getImage(file: string): Promise<any>;\n getRecord(file: string, outFormat?: string): Promise<any>;\n getFile(file: string): Promise<any>;\n hydrateMedia(message: any[]): Promise<void>;\n};\n\nexport function createMediaApi(client: ApiClient, logger: Logger): MediaApi {\n const api = {\n getImage(file: string) {\n return client.call('get_image', { file });\n },\n getRecord(file: string, outFormat?: string) {\n return client.call('get_record', { file, out_format: outFormat });\n },\n getFile(file: string) {\n return client.call('get_file', { file });\n },\n async hydrateMedia(message: any[]) {\n if (!Array.isArray(message)) return;\n\n await Promise.all(message.map(async (segment) => {\n const type = segment?.type;\n const data = segment?.data;\n if (!type || !data) return;\n\n if (['image', 'video', 'record', 'audio', 'file'].includes(type)) {\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 };\n return api;\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): Promise<any>;\n uploadPrivateFile(userId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream, name: string): 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) {\n const normalized = await normalizeFileInput(file, name);\n return client.call('upload_group_file', { group_id: groupId, file: normalized, name });\n },\n async uploadPrivateFile(userId, file, name) {\n const normalized = await normalizeFileInput(file, name);\n return client.call('upload_private_file', { user_id: userId, file: normalized, name });\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 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 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 }): 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): Promise<any>;\n uploadPrivateFile(userId: number | string, file: string, name: string): 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 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) => api.uploadGroupFile(groupId, file, name),\n uploadPrivateFile: (userId, file, name) => api.uploadPrivateFile(userId, file, name),\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, any>;\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: any[]): void;\n info(message: string, ...meta: any[]): void;\n warn(message: string, ...meta: any[]): void;\n error(message: string, error?: Error, ...meta: any[]): 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, any>;\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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","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 { 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.destroy();\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: any[]): Promise<void> {\n return this.api.hydrateMedia(message);\n }\n\n /**\n * 调用自定义API\n */\n async callApi<T = any>(method: string, params: any = {}): 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 */\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: any[]): void {\n if (this.shouldLog(LogLevel.DEBUG)) {\n console.debug(this.format('DEBUG', message), ...meta);\n }\n }\n\n info(message: string, ...meta: any[]): void {\n if (this.shouldLog(LogLevel.INFO)) {\n console.info(this.format('INFO', message), ...meta);\n }\n }\n\n warn(message: string, ...meta: any[]): 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: any[]): 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 { 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?: any // 新增:用于发送 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 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\n if (this.ws) {\n try {\n this.ws.close(code, reason);\n } catch (error) {\n this.logger.error('关闭连接失败', error as Error);\n }\n this.ws = undefined;\n }\n\n this.setState(ConnectionState.DISCONNECTED);\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?: any\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?: any) {\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 this.logger.error('重连失败', error as Error);\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 const separator = url.includes('?') ? '&' : '?';\n return `${url}${separator}access_token=${token}`;\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);\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: any, 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: any) => void;\n reject: (error: Error) => void;\n createdAt: number;\n method: string;\n timer: NodeJS.Timeout | number;\n timeoutMs: number;\n onPacket?: (packet: any) => 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: any) {\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 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 = any>(\n method: string,\n params: any = {},\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 = any, TFinal = any>(\n method: string,\n params: any = {},\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: any): 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 response.retcode,\n response.message,\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 // 清理所有待处理的请求\n this.registry.clearAll('API客户端已销毁');\n\n // 停止清理定时器\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer as NodeJS.Timeout);\n this.cleanupTimer = undefined;\n }\n }\n\n /**\n * 发送API请求\n */\n private sendRequest<T>(\n method: string,\n params: any,\n timeout: number,\n hooks?: {\n onPacket?: (packet: any) => 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),\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';\n\n/**\n * 事件路由器\n * 负责解析OneBot事件并分发到相应的事件处理器\n */\nexport class EventRouter extends EventEmitter {\n private anyListeners: ((event: string | symbol, ...args: any[]) => void)[] = [];\n\n constructor(private logger: Logger) {\n super();\n }\n\n /**\n * 监听所有事件\n */\n onAny(listener: (event: string | symbol, ...args: any[]) => void): this {\n this.anyListeners.push(listener);\n return this;\n }\n\n /**\n * 重写emit以支持onAny\n */\n override emit(event: string | symbol, ...args: any[]): boolean {\n // 先调用anyListeners\n this.anyListeners.forEach((listener) => {\n try {\n listener(event, ...args);\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: any): void {\n try {\n const postType = data.post_type;\n\n if (!postType) {\n this.logger.warn('收到无效消息: 缺少 post_type', data);\n return;\n }\n\n this.logger.debug(`路由事件: ${postType}`, {\n messageType: data.message_type,\n noticeType: data.notice_type,\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: any): void {\n const type = data.meta_event_type;\n const events = [`meta_event`, `meta_event.${type}`];\n\n if (type === 'lifecycle') {\n events.push(`meta_event.lifecycle.${data.sub_type}`);\n }\n\n this.emitEvents(events, data);\n }\n\n /**\n * 路由消息事件\n */\n private routeMessage(data: any): void {\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: any): void {\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: any): void {\n const noticeType = data.notice_type;\n const subType = data.sub_type;\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: any): void {\n const requestType = data.request_type;\n const subType = data.sub_type;\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: any): void {\n for (const event of events) {\n this.logger.debug(`触发事件: ${event}`);\n this.emit(event, data);\n }\n }\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 // 如果有echo,说明是API响应\n if (data.echo) {\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 }): 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';\n\nexport type MediaApi = {\n getImage(file: string): Promise<any>;\n getRecord(file: string, outFormat?: string): Promise<any>;\n getFile(file: string): Promise<any>;\n hydrateMedia(message: any[]): Promise<void>;\n};\n\nexport function createMediaApi(client: ApiClient, logger: Logger): MediaApi {\n const api = {\n getImage(file: string) {\n return client.call('get_image', { file });\n },\n getRecord(file: string, outFormat?: string) {\n return client.call('get_record', { file, out_format: outFormat });\n },\n getFile(file: string) {\n return client.call('get_file', { file });\n },\n async hydrateMedia(message: any[]) {\n if (!Array.isArray(message)) return;\n\n await Promise.all(message.map(async (segment) => {\n const type = segment?.type;\n const data = segment?.data;\n if (!type || !data) return;\n\n if (['image', 'video', 'record', 'audio', 'file'].includes(type)) {\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 };\n return api;\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): Promise<any>;\n uploadPrivateFile(userId: number | string, file: string | Buffer | Uint8Array | NodeJS.ReadableStream, name: string): 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) {\n const normalized = await normalizeFileInput(file, name);\n return client.call('upload_group_file', { group_id: groupId, file: normalized, name });\n },\n async uploadPrivateFile(userId, file, name) {\n const normalized = await normalizeFileInput(file, name);\n return client.call('upload_private_file', { user_id: userId, file: normalized, name });\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 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 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 }): 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): Promise<any>;\n uploadPrivateFile(userId: number | string, file: string, name: string): 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 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) => api.uploadGroupFile(groupId, file, name),\n uploadPrivateFile: (userId, file, name) => api.uploadPrivateFile(userId, file, name),\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, any>;\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: any[]): void;\n info(message: string, ...meta: any[]): void;\n warn(message: string, ...meta: any[]): void;\n error(message: string, error?: Error, ...meta: any[]): 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, any>;\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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","names":["EventEmitter","WebSocket","ConnectionState","WebSocket","randomUUID","fs","createWriteStream","tmpdir","join","randomUUID","pipeline","stats","createWriteStream","fs","tmpdir","join","randomUUID","EventEmitter"]}
package/package.json CHANGED
@@ -1,57 +1,59 @@
1
1
  {
2
- "name": "@naplink/naplink",
3
- "version": "0.0.2",
4
- "description": "现代化的 NapCat WebSocket 客户端 SDK",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
- }
13
- },
14
- "files": [
15
- "dist",
16
- "README.md",
17
- "LICENSE"
18
- ],
19
- "scripts": {
20
- "build": "tsup",
21
- "dev": "tsup --watch",
22
- "test": "vitest",
23
- "test:ui": "vitest --ui",
24
- "lint": "eslint src --ext .ts",
25
- "lint:fix": "eslint src --ext .ts --fix",
26
- "typecheck": "tsc --noEmit"
27
- },
28
- "keywords": [
29
- "napcat",
30
- "onebot",
31
- "onebot-11",
32
- "qq",
33
- "bot",
34
- "websocket",
35
- "sdk",
36
- "typescript"
37
- ],
38
- "author": "",
39
- "license": "MIT",
40
- "dependencies": {
41
- "isomorphic-ws": "^5.0.0",
42
- "ws": "^8.18.0"
43
- },
44
- "devDependencies": {
45
- "@types/node": "^22.0.0",
46
- "@types/ws": "^8.5.0",
47
- "@typescript-eslint/eslint-plugin": "^7.0.0",
48
- "@typescript-eslint/parser": "^7.0.0",
49
- "eslint": "^8.57.0",
50
- "tsup": "^8.0.0",
51
- "typescript": "^5.4.0",
52
- "vitest": "^1.6.0"
53
- },
54
- "engines": {
55
- "node": ">=18.0.0"
2
+ "name": "@naplink/naplink",
3
+ "version": "0.0.3",
4
+ "description": "现代化的 NapCat WebSocket 客户端 SDK",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
56
12
  }
57
- }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "keywords": [
20
+ "napcat",
21
+ "onebot",
22
+ "onebot-11",
23
+ "qq",
24
+ "bot",
25
+ "websocket",
26
+ "sdk",
27
+ "typescript"
28
+ ],
29
+ "author": "",
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "isomorphic-ws": "^5.0.0",
33
+ "ws": "^8.18.3"
34
+ },
35
+ "devDependencies": {
36
+ "@eslint/eslintrc": "^3.3.3",
37
+ "@eslint/js": "^9.39.2",
38
+ "@types/node": "^25.0.3",
39
+ "@types/ws": "^8.18.1",
40
+ "@typescript-eslint/eslint-plugin": "^8.50.0",
41
+ "@typescript-eslint/parser": "^8.50.0",
42
+ "eslint": "^9.39.2",
43
+ "tsup": "^8.5.1",
44
+ "typescript": "^5.9.3",
45
+ "vitest": "^4.0.16"
46
+ },
47
+ "engines": {
48
+ "node": ">=18.0.0"
49
+ },
50
+ "scripts": {
51
+ "build": "tsup",
52
+ "dev": "tsup --watch",
53
+ "test": "vitest",
54
+ "test:ui": "vitest --ui",
55
+ "lint": "eslint src --ext .ts",
56
+ "lint:fix": "eslint src --ext .ts --fix",
57
+ "typecheck": "tsc --noEmit"
58
+ }
59
+ }