|
| 1 | +import { AddressInfo, ListenOptions } from "net"; |
| 2 | +import { Server } from "http"; |
| 3 | +import { Server as SecureServer } from "https"; |
| 4 | +import { Checks } from "./checks"; |
| 5 | + |
| 6 | +export interface IListenOptions { |
| 7 | + server: Server | SecureServer; |
| 8 | + port: number; |
| 9 | + hostname: string; |
| 10 | +} |
| 11 | + |
| 12 | +/** |
| 13 | + * Utility class for handling common tasks for NodeJS HTTP/S server objects. |
| 14 | + */ |
| 15 | +export class Servers { |
| 16 | + /** |
| 17 | + * Returns with a promise that resolves when the server has been shut down. Rejects if anything goes wrong of if the |
| 18 | + * parameters are invalid. |
| 19 | + * |
| 20 | + * @param server The server object that will be shut down. |
| 21 | + */ |
| 22 | + public static async shutdown(server: Server | SecureServer): Promise<void> { |
| 23 | + if (!server) { |
| 24 | + throw new TypeError(`Servers#shutdown() server was falsy. Need object.`); |
| 25 | + } |
| 26 | + return new Promise<void>((resolve, reject) => { |
| 27 | + server.close((err: any) => { |
| 28 | + if (err) { |
| 29 | + reject( |
| 30 | + new Error( |
| 31 | + `Servers#shutdown() Failed to shut down server: ${err.stack}` |
| 32 | + ) |
| 33 | + ); |
| 34 | + } else { |
| 35 | + resolve(); |
| 36 | + } |
| 37 | + }); |
| 38 | + }); |
| 39 | + } |
| 40 | + |
| 41 | + public static async listen(options: IListenOptions): Promise<any> { |
| 42 | + const fnTag = "Servers#listen()"; |
| 43 | + |
| 44 | + Checks.truthy(options, `${fnTag} arg options`); |
| 45 | + Checks.truthy(options.server, `${fnTag} arg options.server`); |
| 46 | + Checks.truthy(options.port, `${fnTag} arg options.port`); |
| 47 | + Checks.truthy(options.hostname, `${fnTag} arg options.hostname`); |
| 48 | + const { server, port, hostname } = options; |
| 49 | + |
| 50 | + return new Promise((resolve, reject) => { |
| 51 | + server.on("error", (ex) => reject(ex)); |
| 52 | + |
| 53 | + const listenOptions: ListenOptions = { |
| 54 | + host: hostname, |
| 55 | + port, |
| 56 | + }; |
| 57 | + |
| 58 | + // called when the `listening` event is fired |
| 59 | + const onListeningHandler = () => { |
| 60 | + const addressInfo = options.server.address() as AddressInfo; |
| 61 | + resolve(addressInfo); |
| 62 | + }; |
| 63 | + |
| 64 | + server.listen(listenOptions, onListeningHandler); |
| 65 | + }); |
| 66 | + } |
| 67 | +} |
0 commit comments