11import { vi } from 'vitest' ;
22import { EventEmitter } from 'events' ;
33
4+ // WebSocket event interfaces
5+ interface WebSocketEventBase {
6+ type : string ;
7+ target : WebSocket ;
8+ currentTarget : WebSocket ;
9+ }
10+
11+ interface WebSocketMessageEvent extends WebSocketEventBase {
12+ data : string | Buffer ;
13+ isBinary : boolean ;
14+ }
15+
16+ interface WebSocketCloseEvent extends WebSocketEventBase {
17+ code : number ;
18+ reason : string ;
19+ wasClean : boolean ;
20+ }
21+
22+ interface WebSocketErrorEvent extends WebSocketEventBase {
23+ error : Error ;
24+ message : string ;
25+ }
26+
427export class ExtendedWsMock extends EventEmitter {
528 // WebSocket state constants
629 public readonly CONNECTING = 0 as const ;
@@ -18,10 +41,10 @@ export class ExtendedWsMock extends EventEmitter {
1841 public isPaused = false ;
1942
2043 // Event handlers
21- onopen : ( ( event : any ) => void ) | null = null ;
22- onclose : ( ( event : any ) => void ) | null = null ;
23- onerror : ( ( event : any ) => void ) | null = null ;
24- onmessage : ( ( event : any ) => void ) | null = null ;
44+ onopen : ( ( event : WebSocketEventBase ) => void ) | null = null ;
45+ onclose : ( ( event : WebSocketCloseEvent ) => void ) | null = null ;
46+ onerror : ( ( event : WebSocketErrorEvent ) => void ) | null = null ;
47+ onmessage : ( ( event : WebSocketMessageEvent ) => void ) | null = null ;
2548
2649 constructor ( ) {
2750 super ( ) ;
@@ -39,36 +62,36 @@ export class ExtendedWsMock extends EventEmitter {
3962 this . resume = this . resume . bind ( this ) ;
4063 }
4164
42- private createWsEvent ( type : string , data : any ) : any {
43- const event = {
65+ private createWsEvent < T extends WebSocketEventBase > ( type : string , data : Partial < T > ) : T {
66+ return {
4467 type,
45- target : this ,
46- currentTarget : this ,
68+ target : this as unknown as WebSocket ,
69+ currentTarget : this as unknown as WebSocket ,
4770 ...data
48- } ;
49- return event ;
71+ } as T ;
5072 }
5173
52- addEventListener ( type : string , listener : ( event : any ) => void ) : void {
53- const boundListener = ( ( event : any ) => {
74+ addEventListener ( type : string , listener : ( event : WebSocketEventBase ) => void ) : void {
75+ const boundListener = ( ( event : WebSocketEventBase ) => {
5476 listener . apply ( this , [ event ] ) ;
5577 } ) ;
5678 this . on ( type , boundListener ) ;
5779 }
5880
59- removeEventListener ( type : string , listener : ( event : any ) => void ) : void {
81+ removeEventListener ( type : string , listener : ( event : WebSocketEventBase ) => void ) : void {
6082 this . removeListener ( type , listener ) ;
6183 }
6284
63- public send = vi . fn ( ( data : any ) : this => {
85+ public send = vi . fn ( ( data : string | Buffer ) : this => {
6486 if ( this . isPaused ) return this ;
6587
6688 const isBinary = ! ( typeof data === 'string' ) ;
67- const event = this . createWsEvent ( 'message' , {
68- data : data
89+ const event = this . createWsEvent < WebSocketMessageEvent > ( 'message' , {
90+ data : data ,
91+ isBinary : isBinary
6992 } ) ;
7093
71- this . emit ( 'message' , data , isBinary ) ;
94+ this . emit ( 'message' , event ) ;
7295 this . onmessage ?. apply ( this , [ event ] ) ;
7396
7497 return this ;
@@ -90,27 +113,27 @@ export class ExtendedWsMock extends EventEmitter {
90113
91114 public close = vi . fn ( ( code ?: number , reason ?: string ) : this => {
92115 this . readyState = this . CLOSED ;
93- const event = this . createWsEvent ( 'close' , {
116+ const event = this . createWsEvent < WebSocketCloseEvent > ( 'close' , {
94117 code,
95118 reason,
96119 wasClean : true
97120 } ) ;
98121
99- this . emit ( 'close' , code , Buffer . from ( reason || '' ) ) ;
122+ this . emit ( 'close' , event ) ;
100123 this . onclose ?. apply ( this , [ event ] ) ;
101124
102125 return this ;
103126 } ) ;
104127
105128 public terminate = vi . fn ( ( ) : this => {
106129 this . readyState = this . CLOSED ;
107- const event = this . createWsEvent ( 'close' , {
130+ const event = this . createWsEvent < WebSocketCloseEvent > ( 'close' , {
108131 code : 1006 ,
109132 reason : 'Connection terminated' ,
110133 wasClean : false
111134 } ) ;
112135
113- this . emit ( 'close' , 1006 , Buffer . from ( 'Connection terminated' ) ) ;
136+ this . emit ( 'close' , event ) ;
114137 this . onclose ?. apply ( this , [ event ] ) ;
115138
116139 return this ;
@@ -134,64 +157,64 @@ export class ExtendedWsMock extends EventEmitter {
134157}
135158
136159// Create mock event classes for Node.js environment
137- class MockEvent {
160+ class MockEvent implements WebSocketEventBase {
138161 readonly type : string ;
139- readonly target : any ;
140- readonly currentTarget : any ;
162+ readonly target : WebSocket ;
163+ readonly currentTarget : WebSocket ;
141164
142- constructor ( type : string , target ?: any ) {
165+ constructor ( type : string , target ?: WebSocket ) {
143166 this . type = type ;
144- this . target = target || ( mockWebSocket as any ) ;
167+ this . target = target || ( mockWebSocket as unknown as WebSocket ) ;
145168 this . currentTarget = this . target ;
146169 }
147170}
148171
149- class MockMessageEvent extends MockEvent {
150- readonly data : any ;
172+ class MockMessageEvent extends MockEvent implements WebSocketMessageEvent {
173+ readonly data : string | Buffer ;
151174 readonly isBinary : boolean ;
152175
153- constructor ( type : string , init ?: { data ?: any ; isBinary ?: boolean ; target ?: any } ) {
176+ constructor ( type : string , init ?: { data ?: string | Buffer ; isBinary ?: boolean ; target ?: WebSocket } ) {
154177 super ( type , init ?. target ) ;
155178 this . data = init ?. data ?? '' ;
156179 this . isBinary = init ?. isBinary ?? false ;
157180 }
158181}
159182
160- class MockCloseEvent extends MockEvent {
183+ class MockCloseEvent extends MockEvent implements WebSocketCloseEvent {
161184 readonly code : number ;
162185 readonly reason : string ;
163186 readonly wasClean : boolean ;
164187
165- constructor ( type : string , init ?: { code ?: number ; reason ?: string ; wasClean ?: boolean ; target ?: any } ) {
188+ constructor ( type : string , init ?: { code ?: number ; reason ?: string ; wasClean ?: boolean ; target ?: WebSocket } ) {
166189 super ( type , init ?. target ) ;
167190 this . code = init ?. code ?? 1000 ;
168191 this . reason = init ?. reason ?? '' ;
169192 this . wasClean = init ?. wasClean ?? true ;
170193 }
171194}
172195
173- class MockErrorEvent extends MockEvent {
196+ class MockErrorEvent extends MockEvent implements WebSocketErrorEvent {
174197 readonly error : Error ;
175198 readonly message : string ;
176199
177- constructor ( type : string , init ?: { error ?: Error ; message ?: string ; target ?: any } ) {
200+ constructor ( type : string , init ?: { error ?: Error ; message ?: string ; target ?: WebSocket } ) {
178201 super ( type , init ?. target ) ;
179202 this . error = init ?. error ?? new Error ( 'WebSocket Error' ) ;
180203 this . message = init ?. message ?? 'WebSocket Error' ;
181204 }
182205}
183206
184207if ( typeof Event === 'undefined' ) {
185- ( global as { Event ?: typeof MockEvent } ) . Event = MockEvent ;
208+ ( global as any ) . Event = MockEvent ;
186209}
187210if ( typeof MessageEvent === 'undefined' ) {
188- ( global as unknown as { MessageEvent : typeof MockMessageEvent } ) . MessageEvent = MockMessageEvent ;
211+ ( global as any ) . MessageEvent = MockMessageEvent ;
189212}
190213if ( typeof CloseEvent === 'undefined' ) {
191- ( global as { CloseEvent ?: typeof MockCloseEvent } ) . CloseEvent = MockCloseEvent ;
214+ ( global as any ) . CloseEvent = MockCloseEvent ;
192215}
193216if ( typeof ErrorEvent === 'undefined' ) {
194- ( global as { ErrorEvent ?: typeof MockErrorEvent } ) . ErrorEvent = MockErrorEvent ;
217+ ( global as any ) . ErrorEvent = MockErrorEvent ;
195218}
196219
197220// Export a singleton instance
0 commit comments