1declare module "net" {
2    import * as stream from "stream";
3    import * as events from "events";
4    import * as dns from "dns";
5
6    type LookupFunction = (hostname: string, options: dns.LookupOneOptions, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void) => void;
7
8    interface AddressInfo {
9        address: string;
10        family: string;
11        port: number;
12    }
13
14    interface SocketConstructorOpts {
15        fd?: number;
16        allowHalfOpen?: boolean;
17        readable?: boolean;
18        writable?: boolean;
19    }
20
21    interface TcpSocketConnectOpts {
22        port: number;
23        host?: string;
24        localAddress?: string;
25        localPort?: number;
26        hints?: number;
27        family?: number;
28        lookup?: LookupFunction;
29    }
30
31    interface IpcSocketConnectOpts {
32        path: string;
33    }
34
35    type SocketConnectOpts = TcpSocketConnectOpts | IpcSocketConnectOpts;
36
37    class Socket extends stream.Duplex {
38        constructor(options?: SocketConstructorOpts);
39
40        // Extended base methods
41        write(buffer: Buffer): boolean;
42        write(buffer: Buffer, cb?: Function): boolean;
43        write(str: string, cb?: Function): boolean;
44        write(str: string, encoding?: string, cb?: Function): boolean;
45        write(str: string, encoding?: string, fd?: string): boolean;
46        write(data: any, encoding?: string, callback?: Function): void;
47
48        connect(options: SocketConnectOpts, connectionListener?: Function): this;
49        connect(port: number, host: string, connectionListener?: Function): this;
50        connect(port: number, connectionListener?: Function): this;
51        connect(path: string, connectionListener?: Function): this;
52
53        setEncoding(encoding?: string): this;
54        pause(): this;
55        resume(): this;
56        setTimeout(timeout: number, callback?: Function): this;
57        setNoDelay(noDelay?: boolean): this;
58        setKeepAlive(enable?: boolean, initialDelay?: number): this;
59        address(): AddressInfo | string;
60        unref(): void;
61        ref(): void;
62
63        readonly bufferSize: number;
64        readonly bytesRead: number;
65        readonly bytesWritten: number;
66        readonly connecting: boolean;
67        readonly destroyed: boolean;
68        readonly localAddress: string;
69        readonly localPort: number;
70        readonly remoteAddress?: string;
71        readonly remoteFamily?: string;
72        readonly remotePort?: number;
73
74        // Extended base methods
75        end(): void;
76        end(buffer: Buffer, cb?: Function): void;
77        end(str: string, cb?: Function): void;
78        end(str: string, encoding?: string, cb?: Function): void;
79        end(data?: any, encoding?: string): void;
80
81        /**
82         * events.EventEmitter
83         *   1. close
84         *   2. connect
85         *   3. data
86         *   4. drain
87         *   5. end
88         *   6. error
89         *   7. lookup
90         *   8. timeout
91         */
92        addListener(event: string, listener: (...args: any[]) => void): this;
93        addListener(event: "close", listener: (had_error: boolean) => void): this;
94        addListener(event: "connect", listener: () => void): this;
95        addListener(event: "data", listener: (data: Buffer) => void): this;
96        addListener(event: "drain", listener: () => void): this;
97        addListener(event: "end", listener: () => void): this;
98        addListener(event: "error", listener: (err: Error) => void): this;
99        addListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this;
100        addListener(event: "timeout", listener: () => void): this;
101
102        emit(event: string | symbol, ...args: any[]): boolean;
103        emit(event: "close", had_error: boolean): boolean;
104        emit(event: "connect"): boolean;
105        emit(event: "data", data: Buffer): boolean;
106        emit(event: "drain"): boolean;
107        emit(event: "end"): boolean;
108        emit(event: "error", err: Error): boolean;
109        emit(event: "lookup", err: Error, address: string, family: string | number, host: string): boolean;
110        emit(event: "timeout"): boolean;
111
112        on(event: string, listener: (...args: any[]) => void): this;
113        on(event: "close", listener: (had_error: boolean) => void): this;
114        on(event: "connect", listener: () => void): this;
115        on(event: "data", listener: (data: Buffer) => void): this;
116        on(event: "drain", listener: () => void): this;
117        on(event: "end", listener: () => void): this;
118        on(event: "error", listener: (err: Error) => void): this;
119        on(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this;
120        on(event: "timeout", listener: () => void): this;
121
122        once(event: string, listener: (...args: any[]) => void): this;
123        once(event: "close", listener: (had_error: boolean) => void): this;
124        once(event: "connect", listener: () => void): this;
125        once(event: "data", listener: (data: Buffer) => void): this;
126        once(event: "drain", listener: () => void): this;
127        once(event: "end", listener: () => void): this;
128        once(event: "error", listener: (err: Error) => void): this;
129        once(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this;
130        once(event: "timeout", listener: () => void): this;
131
132        prependListener(event: string, listener: (...args: any[]) => void): this;
133        prependListener(event: "close", listener: (had_error: boolean) => void): this;
134        prependListener(event: "connect", listener: () => void): this;
135        prependListener(event: "data", listener: (data: Buffer) => void): this;
136        prependListener(event: "drain", listener: () => void): this;
137        prependListener(event: "end", listener: () => void): this;
138        prependListener(event: "error", listener: (err: Error) => void): this;
139        prependListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this;
140        prependListener(event: "timeout", listener: () => void): this;
141
142        prependOnceListener(event: string, listener: (...args: any[]) => void): this;
143        prependOnceListener(event: "close", listener: (had_error: boolean) => void): this;
144        prependOnceListener(event: "connect", listener: () => void): this;
145        prependOnceListener(event: "data", listener: (data: Buffer) => void): this;
146        prependOnceListener(event: "drain", listener: () => void): this;
147        prependOnceListener(event: "end", listener: () => void): this;
148        prependOnceListener(event: "error", listener: (err: Error) => void): this;
149        prependOnceListener(event: "lookup", listener: (err: Error, address: string, family: string | number, host: string) => void): this;
150        prependOnceListener(event: "timeout", listener: () => void): this;
151    }
152
153    interface ListenOptions {
154        port?: number;
155        host?: string;
156        backlog?: number;
157        path?: string;
158        exclusive?: boolean;
159        readableAll?: boolean;
160        writableAll?: boolean;
161    }
162
163    // https://github.com/nodejs/node/blob/master/lib/net.js
164    class Server extends events.EventEmitter {
165        constructor(connectionListener?: (socket: Socket) => void);
166        constructor(options?: { allowHalfOpen?: boolean, pauseOnConnect?: boolean }, connectionListener?: (socket: Socket) => void);
167
168        listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;
169        listen(port?: number, hostname?: string, listeningListener?: Function): this;
170        listen(port?: number, backlog?: number, listeningListener?: Function): this;
171        listen(port?: number, listeningListener?: Function): this;
172        listen(path: string, backlog?: number, listeningListener?: Function): this;
173        listen(path: string, listeningListener?: Function): this;
174        listen(options: ListenOptions, listeningListener?: Function): this;
175        listen(handle: any, backlog?: number, listeningListener?: Function): this;
176        listen(handle: any, listeningListener?: Function): this;
177        close(callback?: (err?: Error) => void): this;
178        address(): AddressInfo | string;
179        getConnections(cb: (error: Error | null, count: number) => void): void;
180        ref(): this;
181        unref(): this;
182        maxConnections: number;
183        connections: number;
184        listening: boolean;
185
186        /**
187         * events.EventEmitter
188         *   1. close
189         *   2. connection
190         *   3. error
191         *   4. listening
192         */
193        addListener(event: string, listener: (...args: any[]) => void): this;
194        addListener(event: "close", listener: () => void): this;
195        addListener(event: "connection", listener: (socket: Socket) => void): this;
196        addListener(event: "error", listener: (err: Error) => void): this;
197        addListener(event: "listening", listener: () => void): this;
198
199        emit(event: string | symbol, ...args: any[]): boolean;
200        emit(event: "close"): boolean;
201        emit(event: "connection", socket: Socket): boolean;
202        emit(event: "error", err: Error): boolean;
203        emit(event: "listening"): boolean;
204
205        on(event: string, listener: (...args: any[]) => void): this;
206        on(event: "close", listener: () => void): this;
207        on(event: "connection", listener: (socket: Socket) => void): this;
208        on(event: "error", listener: (err: Error) => void): this;
209        on(event: "listening", listener: () => void): this;
210
211        once(event: string, listener: (...args: any[]) => void): this;
212        once(event: "close", listener: () => void): this;
213        once(event: "connection", listener: (socket: Socket) => void): this;
214        once(event: "error", listener: (err: Error) => void): this;
215        once(event: "listening", listener: () => void): this;
216
217        prependListener(event: string, listener: (...args: any[]) => void): this;
218        prependListener(event: "close", listener: () => void): this;
219        prependListener(event: "connection", listener: (socket: Socket) => void): this;
220        prependListener(event: "error", listener: (err: Error) => void): this;
221        prependListener(event: "listening", listener: () => void): this;
222
223        prependOnceListener(event: string, listener: (...args: any[]) => void): this;
224        prependOnceListener(event: "close", listener: () => void): this;
225        prependOnceListener(event: "connection", listener: (socket: Socket) => void): this;
226        prependOnceListener(event: "error", listener: (err: Error) => void): this;
227        prependOnceListener(event: "listening", listener: () => void): this;
228    }
229
230    interface TcpNetConnectOpts extends TcpSocketConnectOpts, SocketConstructorOpts {
231        timeout?: number;
232    }
233
234    interface IpcNetConnectOpts extends IpcSocketConnectOpts, SocketConstructorOpts {
235        timeout?: number;
236    }
237
238    type NetConnectOpts = TcpNetConnectOpts | IpcNetConnectOpts;
239
240    function createServer(connectionListener?: (socket: Socket) => void): Server;
241    function createServer(options?: { allowHalfOpen?: boolean, pauseOnConnect?: boolean }, connectionListener?: (socket: Socket) => void): Server;
242    function connect(options: NetConnectOpts, connectionListener?: Function): Socket;
243    function connect(port: number, host?: string, connectionListener?: Function): Socket;
244    function connect(path: string, connectionListener?: Function): Socket;
245    function createConnection(options: NetConnectOpts, connectionListener?: Function): Socket;
246    function createConnection(port: number, host?: string, connectionListener?: Function): Socket;
247    function createConnection(path: string, connectionListener?: Function): Socket;
248    function isIP(input: string): number;
249    function isIPv4(input: string): boolean;
250    function isIPv6(input: string): boolean;
251}
252