@@ -16,6 +16,46 @@ export interface SocketConnectionEventMap {
1616 ]
1717}
1818
19+ const kImplementation = Symbol ( 'kImplementation' )
20+ const kRestoreValue = Symbol ( 'kRestoreValue' )
21+
22+ /**
23+ * Apply a transparent proxy to the "node:net" module on the module's scope.
24+ * This way, this interceptor can function if it gets imported before the surface
25+ * that relies on "node:net", like "node:http" or "undici".
26+ *
27+ * @note You MUST import the interceptor BEFORE the surface relying on "node:net".
28+ */
29+ const { createConnection } = net
30+ Object . defineProperties ( net . createConnection , {
31+ [ kRestoreValue ] : {
32+ value : createConnection . bind ( createConnection ) ,
33+ enumerable : true ,
34+ } ,
35+ [ kImplementation ] : {
36+ value ( ) {
37+ return Reflect . get ( net . createConnection , kRestoreValue )
38+ } ,
39+ enumerable : true ,
40+ writable : true ,
41+ } ,
42+ } )
43+
44+ function createSwitchableProxy ( target : any ) {
45+ return new Proxy ( target , {
46+ apply ( target , thisArg , argArray ) {
47+ return Reflect . apply (
48+ Reflect . get ( target , kImplementation ) ,
49+ thisArg ,
50+ argArray
51+ )
52+ } ,
53+ } )
54+ }
55+
56+ net . connect = createSwitchableProxy ( net . connect )
57+ net . createConnection = createSwitchableProxy ( net . createConnection )
58+
1959export class SocketInterceptor extends Interceptor < SocketConnectionEventMap > {
2060 static symbol = Symbol ( 'SocketInterceptor' )
2161
@@ -24,20 +64,21 @@ export class SocketInterceptor extends Interceptor<SocketConnectionEventMap> {
2464 }
2565
2666 protected setup ( ) : void {
27- const {
28- connect : originalConnect ,
29- createConnection : originalCreateConnection ,
30- } = net
67+ const originalConnect = Reflect . get ( net . connect , kRestoreValue )
68+ const originalCreateConnection = Reflect . get (
69+ net . createConnection ,
70+ kRestoreValue
71+ )
3172
32- net . connect = ( ...args : Array < unknown > ) => {
73+ Reflect . set ( net . connect , kImplementation , ( ...args : Array < unknown > ) => {
3374 const [ options , connectionListener ] = normalizeNetConnectArgs (
3475 args as NetConnectArgs
3576 )
3677 const socket = new MockSocket ( {
3778 ...args ,
3879 onConnect : connectionListener ,
3980 createConnection ( ) {
40- return originalConnect . apply ( originalCreateConnection , args as any )
81+ return originalConnect . apply ( originalConnect , args as any )
4182 } ,
4283 } )
4384
@@ -47,31 +88,39 @@ export class SocketInterceptor extends Interceptor<SocketConnectionEventMap> {
4788 } )
4889
4990 return socket
50- }
91+ } )
5192
52- net . createConnection = ( ...args : Array < unknown > ) => {
53- const [ options ] = normalizeNetConnectArgs ( args as NetConnectArgs )
54- const socket = new MockSocket ( {
55- ...args ,
56- createConnection ( ) {
57- return originalCreateConnection . apply (
58- originalCreateConnection ,
59- args as any
60- )
61- } ,
62- } )
93+ Reflect . set (
94+ net . createConnection ,
95+ kImplementation ,
96+ ( ...args : Array < unknown > ) => {
97+ const [ options ] = normalizeNetConnectArgs ( args as NetConnectArgs )
98+ const socket = new MockSocket ( {
99+ ...args ,
100+ createConnection ( ) {
101+ return originalCreateConnection . apply (
102+ originalCreateConnection ,
103+ args as any
104+ )
105+ } ,
106+ } )
63107
64- this . emitter . emit ( 'connection' , {
65- options,
66- socket,
67- } )
108+ this . emitter . emit ( 'connection' , {
109+ options,
110+ socket,
111+ } )
68112
69- return socket
70- }
113+ return socket
114+ }
115+ )
71116
72117 this . subscriptions . push ( ( ) => {
73- net . connect = originalConnect
74- net . createConnection = originalCreateConnection
118+ Reflect . set ( net . connect , kImplementation , originalConnect )
119+ Reflect . set (
120+ net . createConnection ,
121+ kImplementation ,
122+ originalCreateConnection
123+ )
75124 } )
76125 }
77126}
0 commit comments