1 |
|
2 |
|
3 | import { EventEmitter } from "events";
|
4 | import {
|
5 | Agent,
|
6 | ClientRequest,
|
7 | ClientRequestArgs,
|
8 | IncomingMessage,
|
9 | OutgoingHttpHeaders,
|
10 | Server as HTTPServer,
|
11 | } from "http";
|
12 | import { Server as HTTPSServer } from "https";
|
13 | import { Duplex, DuplexOptions } from "stream";
|
14 | import { SecureContextOptions } from "tls";
|
15 | import { URL } from "url";
|
16 | import { ZlibOptions } from "zlib";
|
17 |
|
18 |
|
19 |
|
20 | type BufferLike =
|
21 | | string
|
22 | | Buffer
|
23 | | DataView
|
24 | | number
|
25 | | ArrayBufferView
|
26 | | Uint8Array
|
27 | | ArrayBuffer
|
28 | | SharedArrayBuffer
|
29 | | readonly any[]
|
30 | | readonly number[]
|
31 | | { valueOf(): ArrayBuffer }
|
32 | | { valueOf(): SharedArrayBuffer }
|
33 | | { valueOf(): Uint8Array }
|
34 | | { valueOf(): readonly number[] }
|
35 | | { valueOf(): string }
|
36 | | { [Symbol.toPrimitive](hint: string): string };
|
37 |
|
38 |
|
39 | declare class WebSocket extends EventEmitter {
|
40 |
|
41 | static readonly CONNECTING: 0;
|
42 |
|
43 | static readonly OPEN: 1;
|
44 |
|
45 | static readonly CLOSING: 2;
|
46 |
|
47 | static readonly CLOSED: 3;
|
48 |
|
49 | binaryType: "nodebuffer" | "arraybuffer" | "fragments";
|
50 | readonly bufferedAmount: number;
|
51 | readonly extensions: string;
|
52 |
|
53 | readonly isPaused: boolean;
|
54 | readonly protocol: string;
|
55 |
|
56 | readonly readyState:
|
57 | | typeof WebSocket.CONNECTING
|
58 | | typeof WebSocket.OPEN
|
59 | | typeof WebSocket.CLOSING
|
60 | | typeof WebSocket.CLOSED;
|
61 | readonly url: string;
|
62 |
|
63 |
|
64 | readonly CONNECTING: 0;
|
65 |
|
66 | readonly OPEN: 1;
|
67 |
|
68 | readonly CLOSING: 2;
|
69 |
|
70 | readonly CLOSED: 3;
|
71 |
|
72 | onopen: ((event: WebSocket.Event) => void) | null;
|
73 | onerror: ((event: WebSocket.ErrorEvent) => void) | null;
|
74 | onclose: ((event: WebSocket.CloseEvent) => void) | null;
|
75 | onmessage: ((event: WebSocket.MessageEvent) => void) | null;
|
76 |
|
77 | constructor(address: null);
|
78 | constructor(address: string | URL, options?: WebSocket.ClientOptions | ClientRequestArgs);
|
79 | constructor(
|
80 | address: string | URL,
|
81 | protocols?: string | string[],
|
82 | options?: WebSocket.ClientOptions | ClientRequestArgs,
|
83 | );
|
84 |
|
85 | close(code?: number, data?: string | Buffer): void;
|
86 | ping(data?: any, mask?: boolean, cb?: (err: Error) => void): void;
|
87 | pong(data?: any, mask?: boolean, cb?: (err: Error) => void): void;
|
88 | // https://github.com/websockets/ws/issues/2076#issuecomment-1250354722
|
89 | send(data: BufferLike, cb?: (err?: Error) => void): void;
|
90 | send(
|
91 | data: BufferLike,
|
92 | options: {
|
93 | mask?: boolean | undefined;
|
94 | binary?: boolean | undefined;
|
95 | compress?: boolean | undefined;
|
96 | fin?: boolean | undefined;
|
97 | },
|
98 | cb?: (err?: Error) => void,
|
99 | ): void;
|
100 | terminate(): void;
|
101 |
|
102 | /**
|
103 | * Pause the websocket causing it to stop emitting events. Some events can still be
|
104 | * emitted after this is called, until all buffered data is consumed. This method
|
105 | * is a noop if the ready state is `CONNECTING` or `CLOSED`.
|
106 | */
|
107 | pause(): void;
|
108 | /**
|
109 | * Make a paused socket resume emitting events. This method is a noop if the ready
|
110 | * state is `CONNECTING` or `CLOSED`.
|
111 | */
|
112 | resume(): void;
|
113 |
|
114 | // HTML5 WebSocket events
|
115 | addEventListener<K extends keyof WebSocket.WebSocketEventMap>(
|
116 | type: K,
|
117 | listener: (event: WebSocket.WebSocketEventMap[K]) => void,
|
118 | options?: WebSocket.EventListenerOptions,
|
119 | ): void;
|
120 | removeEventListener<K extends keyof WebSocket.WebSocketEventMap>(
|
121 | type: K,
|
122 | listener: (event: WebSocket.WebSocketEventMap[K]) => void,
|
123 | ): void;
|
124 |
|
125 | // Events
|
126 | on(event: "close", listener: (this: WebSocket, code: number, reason: Buffer) => void): this;
|
127 | on(event: "error", listener: (this: WebSocket, err: Error) => void): this;
|
128 | on(event: "upgrade", listener: (this: WebSocket, request: IncomingMessage) => void): this;
|
129 | on(event: "message", listener: (this: WebSocket, data: WebSocket.RawData, isBinary: boolean) => void): this;
|
130 | on(event: "open", listener: (this: WebSocket) => void): this;
|
131 | on(event: "ping" | "pong", listener: (this: WebSocket, data: Buffer) => void): this;
|
132 | on(
|
133 | event: "unexpected-response",
|
134 | listener: (this: WebSocket, request: ClientRequest, response: IncomingMessage) => void,
|
135 | ): this;
|
136 | on(event: string | symbol, listener: (this: WebSocket, ...args: any[]) => void): this;
|
137 |
|
138 | once(event: "close", listener: (this: WebSocket, code: number, reason: Buffer) => void): this;
|
139 | once(event: "error", listener: (this: WebSocket, err: Error) => void): this;
|
140 | once(event: "upgrade", listener: (this: WebSocket, request: IncomingMessage) => void): this;
|
141 | once(event: "message", listener: (this: WebSocket, data: WebSocket.RawData, isBinary: boolean) => void): this;
|
142 | once(event: "open", listener: (this: WebSocket) => void): this;
|
143 | once(event: "ping" | "pong", listener: (this: WebSocket, data: Buffer) => void): this;
|
144 | once(
|
145 | event: "unexpected-response",
|
146 | listener: (this: WebSocket, request: ClientRequest, response: IncomingMessage) => void,
|
147 | ): this;
|
148 | once(event: string | symbol, listener: (this: WebSocket, ...args: any[]) => void): this;
|
149 |
|
150 | off(event: "close", listener: (this: WebSocket, code: number, reason: Buffer) => void): this;
|
151 | off(event: "error", listener: (this: WebSocket, err: Error) => void): this;
|
152 | off(event: "upgrade", listener: (this: WebSocket, request: IncomingMessage) => void): this;
|
153 | off(event: "message", listener: (this: WebSocket, data: WebSocket.RawData, isBinary: boolean) => void): this;
|
154 | off(event: "open", listener: (this: WebSocket) => void): this;
|
155 | off(event: "ping" | "pong", listener: (this: WebSocket, data: Buffer) => void): this;
|
156 | off(
|
157 | event: "unexpected-response",
|
158 | listener: (this: WebSocket, request: ClientRequest, response: IncomingMessage) => void,
|
159 | ): this;
|
160 | off(event: string | symbol, listener: (this: WebSocket, ...args: any[]) => void): this;
|
161 |
|
162 | addListener(event: "close", listener: (code: number, reason: Buffer) => void): this;
|
163 | addListener(event: "error", listener: (err: Error) => void): this;
|
164 | addListener(event: "upgrade", listener: (request: IncomingMessage) => void): this;
|
165 | addListener(event: "message", listener: (data: WebSocket.RawData, isBinary: boolean) => void): this;
|
166 | addListener(event: "open", listener: () => void): this;
|
167 | addListener(event: "ping" | "pong", listener: (data: Buffer) => void): this;
|
168 | addListener(
|
169 | event: "unexpected-response",
|
170 | listener: (request: ClientRequest, response: IncomingMessage) => void,
|
171 | ): this;
|
172 | addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
173 |
|
174 | removeListener(event: "close", listener: (code: number, reason: Buffer) => void): this;
|
175 | removeListener(event: "error", listener: (err: Error) => void): this;
|
176 | removeListener(event: "upgrade", listener: (request: IncomingMessage) => void): this;
|
177 | removeListener(event: "message", listener: (data: WebSocket.RawData, isBinary: boolean) => void): this;
|
178 | removeListener(event: "open", listener: () => void): this;
|
179 | removeListener(event: "ping" | "pong", listener: (data: Buffer) => void): this;
|
180 | removeListener(
|
181 | event: "unexpected-response",
|
182 | listener: (request: ClientRequest, response: IncomingMessage) => void,
|
183 | ): this;
|
184 | removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
185 | }
|
186 |
|
187 | declare const WebSocketAlias: typeof WebSocket;
|
188 | interface WebSocketAlias extends WebSocket {} // eslint-disable-line @typescript-eslint/no-empty-interface
|
189 |
|
190 | declare namespace WebSocket {
|
191 | /**
|
192 | * Data represents the raw message payload received over the WebSocket.
|
193 | */
|
194 | type RawData = Buffer | ArrayBuffer | Buffer[];
|
195 |
|
196 | /**
|
197 | * Data represents the message payload received over the WebSocket.
|
198 | */
|
199 | type Data = string | Buffer | ArrayBuffer | Buffer[];
|
200 |
|
201 | /**
|
202 | * CertMeta represents the accepted types for certificate & key data.
|
203 | */
|
204 | type CertMeta = string | string[] | Buffer | Buffer[];
|
205 |
|
206 | /**
|
207 | * VerifyClientCallbackSync is a synchronous callback used to inspect the
|
208 | * incoming message. The return value (boolean) of the function determines
|
209 | * whether or not to accept the handshake.
|
210 | */
|
211 | type VerifyClientCallbackSync<Request extends IncomingMessage = IncomingMessage> = (info: {
|
212 | origin: string;
|
213 | secure: boolean;
|
214 | req: Request;
|
215 | }) => boolean;
|
216 |
|
217 | |
218 |
|
219 |
|
220 |
|
221 |
|
222 | type VerifyClientCallbackAsync<Request extends IncomingMessage = IncomingMessage> = (
|
223 | info: { origin: string; secure: boolean; req: Request },
|
224 | callback: (res: boolean, code?: number, message?: string, headers?: OutgoingHttpHeaders) => void,
|
225 | ) => void;
|
226 |
|
227 | |
228 |
|
229 |
|
230 |
|
231 |
|
232 | type FinishRequestCallback = (request: IncomingMessage, websocket: WebSocket) => void;
|
233 |
|
234 | interface ClientOptions extends SecureContextOptions {
|
235 | protocol?: string | undefined;
|
236 | followRedirects?: boolean | undefined;
|
237 | generateMask?(mask: Buffer): void;
|
238 | handshakeTimeout?: number | undefined;
|
239 | maxRedirects?: number | undefined;
|
240 | perMessageDeflate?: boolean | PerMessageDeflateOptions | undefined;
|
241 | localAddress?: string | undefined;
|
242 | protocolVersion?: number | undefined;
|
243 | headers?: { [key: string]: string } | undefined;
|
244 | origin?: string | undefined;
|
245 | agent?: Agent | undefined;
|
246 | host?: string | undefined;
|
247 | family?: number | undefined;
|
248 | checkServerIdentity?(servername: string, cert: CertMeta): boolean;
|
249 | rejectUnauthorized?: boolean | undefined;
|
250 | maxPayload?: number | undefined;
|
251 | skipUTF8Validation?: boolean | undefined;
|
252 | finishRequest?: FinishRequestCallback | undefined;
|
253 | }
|
254 |
|
255 | interface PerMessageDeflateOptions {
|
256 | serverNoContextTakeover?: boolean | undefined;
|
257 | clientNoContextTakeover?: boolean | undefined;
|
258 | serverMaxWindowBits?: number | undefined;
|
259 | clientMaxWindowBits?: number | undefined;
|
260 | zlibDeflateOptions?: {
|
261 | flush?: number | undefined;
|
262 | finishFlush?: number | undefined;
|
263 | chunkSize?: number | undefined;
|
264 | windowBits?: number | undefined;
|
265 | level?: number | undefined;
|
266 | memLevel?: number | undefined;
|
267 | strategy?: number | undefined;
|
268 | dictionary?: Buffer | Buffer[] | DataView | undefined;
|
269 | info?: boolean | undefined;
|
270 | } | undefined;
|
271 | zlibInflateOptions?: ZlibOptions | undefined;
|
272 | threshold?: number | undefined;
|
273 | concurrencyLimit?: number | undefined;
|
274 | }
|
275 |
|
276 | interface Event {
|
277 | type: string;
|
278 | target: WebSocket;
|
279 | }
|
280 |
|
281 | interface ErrorEvent {
|
282 | error: any;
|
283 | message: string;
|
284 | type: string;
|
285 | target: WebSocket;
|
286 | }
|
287 |
|
288 | interface CloseEvent {
|
289 | wasClean: boolean;
|
290 | code: number;
|
291 | reason: string;
|
292 | type: string;
|
293 | target: WebSocket;
|
294 | }
|
295 |
|
296 | interface MessageEvent {
|
297 | data: Data;
|
298 | type: string;
|
299 | target: WebSocket;
|
300 | }
|
301 |
|
302 | interface WebSocketEventMap {
|
303 | open: Event;
|
304 | error: ErrorEvent;
|
305 | close: CloseEvent;
|
306 | message: MessageEvent;
|
307 | }
|
308 |
|
309 | interface EventListenerOptions {
|
310 | once?: boolean | undefined;
|
311 | }
|
312 |
|
313 | interface ServerOptions<
|
314 | U extends typeof WebSocket.WebSocket = typeof WebSocket.WebSocket,
|
315 | V extends typeof IncomingMessage = typeof IncomingMessage,
|
316 | > {
|
317 | host?: string | undefined;
|
318 | port?: number | undefined;
|
319 | backlog?: number | undefined;
|
320 | server?: HTTPServer<V> | HTTPSServer<V> | undefined;
|
321 | verifyClient?:
|
322 | | VerifyClientCallbackAsync<InstanceType<V>>
|
323 | | VerifyClientCallbackSync<InstanceType<V>>
|
324 | | undefined;
|
325 | handleProtocols?: (protocols: Set<string>, request: InstanceType<V>) => string | false;
|
326 | path?: string | undefined;
|
327 | noServer?: boolean | undefined;
|
328 | clientTracking?: boolean | undefined;
|
329 | perMessageDeflate?: boolean | PerMessageDeflateOptions | undefined;
|
330 | maxPayload?: number | undefined;
|
331 | skipUTF8Validation?: boolean | undefined;
|
332 | WebSocket?: U | undefined;
|
333 | }
|
334 |
|
335 | interface AddressInfo {
|
336 | address: string;
|
337 | family: string;
|
338 | port: number;
|
339 | }
|
340 |
|
341 |
|
342 | class Server<
|
343 | T extends typeof WebSocket.WebSocket = typeof WebSocket.WebSocket,
|
344 | U extends typeof IncomingMessage = typeof IncomingMessage,
|
345 | > extends EventEmitter {
|
346 | options: ServerOptions<T, U>;
|
347 | path: string;
|
348 | clients: Set<InstanceType<T>>;
|
349 |
|
350 | constructor(options?: ServerOptions<T, U>, callback?: () => void);
|
351 |
|
352 | address(): AddressInfo | string | null;
|
353 | close(cb?: (err?: Error) => void): void;
|
354 | handleUpgrade(
|
355 | request: InstanceType<U>,
|
356 | socket: Duplex,
|
357 | upgradeHead: Buffer,
|
358 | callback: (client: InstanceType<T>, request: InstanceType<U>) => void,
|
359 | ): void;
|
360 | shouldHandle(request: InstanceType<U>): boolean | Promise<boolean>;
|
361 |
|
362 | // Events
|
363 | on(event: "connection", cb: (this: Server<T>, socket: InstanceType<T>, request: InstanceType<U>) => void): this;
|
364 | on(event: "error", cb: (this: Server<T>, error: Error) => void): this;
|
365 | on(event: "headers", cb: (this: Server<T>, headers: string[], request: InstanceType<U>) => void): this;
|
366 | on(event: "close" | "listening", cb: (this: Server<T>) => void): this;
|
367 | on(event: string | symbol, listener: (this: Server<T>, ...args: any[]) => void): this;
|
368 |
|
369 | once(
|
370 | event: "connection",
|
371 | cb: (this: Server<T>, socket: InstanceType<T>, request: InstanceType<U>) => void,
|
372 | ): this;
|
373 | once(event: "error", cb: (this: Server<T>, error: Error) => void): this;
|
374 | once(event: "headers", cb: (this: Server<T>, headers: string[], request: InstanceType<U>) => void): this;
|
375 | once(event: "close" | "listening", cb: (this: Server<T>) => void): this;
|
376 | once(event: string | symbol, listener: (this: Server<T>, ...args: any[]) => void): this;
|
377 |
|
378 | off(
|
379 | event: "connection",
|
380 | cb: (this: Server<T>, socket: InstanceType<T>, request: InstanceType<U>) => void,
|
381 | ): this;
|
382 | off(event: "error", cb: (this: Server<T>, error: Error) => void): this;
|
383 | off(event: "headers", cb: (this: Server<T>, headers: string[], request: InstanceType<U>) => void): this;
|
384 | off(event: "close" | "listening", cb: (this: Server<T>) => void): this;
|
385 | off(event: string | symbol, listener: (this: Server<T>, ...args: any[]) => void): this;
|
386 |
|
387 | addListener(event: "connection", cb: (client: InstanceType<T>, request: InstanceType<U>) => void): this;
|
388 | addListener(event: "error", cb: (err: Error) => void): this;
|
389 | addListener(event: "headers", cb: (headers: string[], request: InstanceType<U>) => void): this;
|
390 | addListener(event: "close" | "listening", cb: () => void): this;
|
391 | addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
392 |
|
393 | removeListener(event: "connection", cb: (client: InstanceType<T>, request: InstanceType<U>) => void): this;
|
394 | removeListener(event: "error", cb: (err: Error) => void): this;
|
395 | removeListener(event: "headers", cb: (headers: string[], request: InstanceType<U>) => void): this;
|
396 | removeListener(event: "close" | "listening", cb: () => void): this;
|
397 | removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
398 | }
|
399 |
|
400 | const WebSocketServer: typeof Server;
|
401 | interface WebSocketServer extends Server {}
|
402 | const WebSocket: typeof WebSocketAlias;
|
403 | interface WebSocket extends WebSocketAlias {}
|
404 |
|
405 |
|
406 | function createWebSocketStream(websocket: WebSocket, options?: DuplexOptions): Duplex;
|
407 | }
|
408 |
|
409 | export = WebSocket;
|