import KoaRouter from "@koa/router"; import type { Layer, LayerOptions, RouterContext as KoaRouterContext, RouterMiddleware } from "@koa/router"; import type { Request } from "koa"; import type { IncomingMessage, Server } from "node:http"; import { WebSocket, WebSocketServer, type ServerOptions } from "ws"; export type RouterContext = KoaRouterContext & { request: Request & { body: unknown; }; }; export type { Next } from "koa"; export type WebSocketUpgradeAuthorizer = (request: IncomingMessage) => boolean; /** 与 ws 既有默认值一致,保持未显式配置的协议路由向后兼容。 */ export declare const DEFAULT_WEBSOCKET_MAX_PAYLOAD_BYTES: number; export interface WebSocketRouteOptions { /** 在协议升级前授权请求;返回 false 或抛错时以 HTTP 401 拒绝。 */ authorize?: WebSocketUpgradeAuthorizer; /** 单条入站 WebSocket 消息的最大字节数,超限连接以 1009 关闭。 */ maxPayloadBytes?: number; /** 同一路径允许的最大并发连接数;满载时在升级前以 HTTP 503 拒绝。 */ maxConnections?: number; } export interface WebSocketRouteStats { activeConnections: number; maxConnections?: number; capacityRejections: number; } export interface RouterRegistrationOwner { readonly platform: string; /** 省略时表示平台 Adapter 自身拥有的全局路由。 */ readonly account_id?: string; } export declare class HttpRouteConflictError extends Error { readonly path: string; readonly methods: string[]; readonly registeringOwner?: RouterRegistrationOwner; readonly existingOwner?: RouterRegistrationOwner; constructor(path: string, methods: string[], registeringOwner?: RouterRegistrationOwner, existingOwner?: RouterRegistrationOwner); } export declare class WebSocketRouteConflictError extends Error { readonly path: string; readonly registeringOwner?: RouterRegistrationOwner; readonly existingOwner?: RouterRegistrationOwner; constructor(path: string, registeringOwner?: RouterRegistrationOwner, existingOwner?: RouterRegistrationOwner); } export declare class WsServer extends WebSocketServer { readonly path: string; constructor(options: WsServer.Options); } export declare namespace WsServer { interface Options extends ServerOptions { path: string; } } /** * 归属一个账号构造与启动周期的 Router 注册。 * close 后出现的迟到注册会被立即撤销,避免旧扩展在回滚后重新占用路径。 */ export declare class RouterRegistrationScope { private readonly router; /** @internal 供 Router 生成冲突诊断。 */ readonly owner?: RouterRegistrationOwner; private readonly parent?; private readonly httpLayers; private readonly wsServers; private readonly children; private closed; constructor(router: Router, /** @internal 供 Router 生成冲突诊断。 */ owner?: RouterRegistrationOwner, parent?: RouterRegistrationScope); /** 子协议作用域能独立释放,也必须随未完成的账号构造一起清理。 */ trackScope(scope: RouterRegistrationScope): void; run(operation: () => T): T; close(): void; /** @internal 仅由 Router.register 调用。 */ trackHttp(layer: Layer): void; /** @internal 仅由 Router.ws 调用。 */ trackWs(path: string, server: WsServer): void; } /** * Koa HTTP Router 与同一 Server 上的 WebSocket upgrade 注册表。 * * WebSocket 路径始终是客户端请求的绝对 pathname,不继承 Koa Router prefix。 * Router 拥有所有 WsServer,并负责在宿主停止时先拒绝新 upgrade、再终止现有连接。 */ export declare class Router extends KoaRouter { private readonly server; private readonly wsMap; private readonly wsAuthorizers; private readonly wsConnectionLimits; private readonly wsCapacityRejections; private readonly wsOwners; private readonly registrationScope; private readonly httpOwners; private readonly readinessScope; private readonly wsReadiness; private enforceReadiness; private registrationDepth; private upgradeHandler?; constructor(server: Server, options?: ConstructorParameters[0]); private attachUpgradeHandler; private rejectUpgrade; private detachUpgradeHandler; private normalizeWsPath; createRegistrationScope(owner?: RouterRegistrationOwner): RouterRegistrationScope; /** @internal 由 RouterRegistrationScope.run 建立异步注册归属。 */ runInRegistrationScope(scope: RouterRegistrationScope, operation: () => T): T; /** 分阶段宿主启用协议接入闸门;普通嵌入式启动保留既有契约。 */ enableProtocolReadiness(): void; /** 独立于账号清理作用域,仅给协议构造/启动注册的路由附加就绪条件。 */ runWithProtocolReadiness(ready: () => boolean, operation: () => T): T; private routeIsReady; register(path: string | RegExp | string[], methods: string[], middleware: RouterMiddleware | RouterMiddleware[], additionalOptions?: LayerOptions): Layer | KoaRouter; private assertNoHttpRouteConflicts; private isSameHttpPath; private formatHttpPath; /** 注册不受 Koa prefix 影响的 WebSocket pathname。 */ ws(path: string, options?: WebSocketRouteOptions): WsServer; /** @internal 仅撤销作用域实际创建的 Layer。 */ removeScopedHttpLayer(layer: Layer): void; /** @internal 记录账号作用域拥有的 HTTP Layer。 */ assignScopedHttpOwner(layer: Layer, owner?: RouterRegistrationOwner): void; /** @internal 路径已被新作用域接管时,不允许旧作用域误删新服务。 */ removeScopedWs(path: string, expected: WsServer): void; private terminateClients; private closeWsServer; /** 移除一个 WebSocket pathname,并立即终止其现有连接。 */ removeWs(path: string): boolean; /** 同步发起全部连接关闭;需要等待完成时使用 cleanupAsync。 */ cleanup(): void; /** 拒绝新 upgrade、终止现有连接,并等待所有 WebSocketServer 完成关闭。 */ cleanupAsync(): Promise; getWsPaths(): string[]; /** 返回指定 WebSocket pathname 的瞬时容量证据,不枚举或公开其他路由。 */ getWsRouteStats(path: string): WebSocketRouteStats | undefined; }