UNPKG

@tmlmobilidade/connectors

Version:

This package provides pre-made database connectors to streamline development and reduce boilerplate. By using these connectors, you can avoid re-implementing controller classes every time, ensuring consistency and saving development time.

100 lines (99 loc) 3.65 kB
/* * */ import { createTunnel } from 'tunnel-ssh'; /* * */ export class SshTunnelConnector { static _instance; get server() { return this._server; } _server; config; options; retries = 0; constructor(config, options = {}) { this.config = config; this.options = options; } /** * Get the singleton instance of SshTunnelConnector. */ static getInstance(config, options) { if (!SshTunnelConnector._instance) { if (!config) { throw new Error('SSH Config is required'); } SshTunnelConnector._instance = new SshTunnelConnector(config, options); } return SshTunnelConnector._instance; } /** * Establishes an SSH tunnel connection using the provided configuration options. * * @throws {Error} Throws an error if the connection fails after the maximum number of retries. * * @remarks * - The method attempts to create an SSH tunnel using the `createTunnel` function with the specified options. * - If the connection is successful, it logs the connected host port and sets up an error listener on the server. * - If the connection fails, it retries the connection up to a maximum number of retries specified in the options. * * @example * ```typescript * const sshTunnelConnector = new SshTunnelConnector(config); * sshTunnelConnector.connect(); * ``` */ async connect() { try { const [server] = await createTunnel(this.config.tunnelOptions, this.config.serverOptions, this.config.sshOptions, this.config.forwardOptions); console.log(`⤷ SSH Tunnel connected to host port ${server.address().port}`); this._server = server; server.on('error', (error) => { console.log(`⤷ SSH Tunnel Error:`, error); }); server.on('close', () => { console.log(`⤷ SSH Tunnel closed.`); }); } catch (error) { if (error.code === 'EADDRINUSE') { console.log(`⤷ ERROR: Port "${this.config.serverOptions.port}" already in use. Retrying with a different port...`); this.config.serverOptions.port = (this.config.serverOptions.port ?? 0) + 1; return; } console.log(`⤷ ERROR: Failed to connect to SSH Tunnel.`, error); if (this.retries < (this.options?.maxRetries || 3)) { this.retries++; console.log(`⤷ Retrying SSH connection...`); this.connect(); } else { throw new Error('Error connecting to SSH tunnel', error); } } } /** * Disconnects the SSH tunnel by closing the server. * * @returns {Promise<void>} A promise that resolves when the server is successfully closed. * @throws Will log an error message if the server fails to close. */ async disconnect() { try { this._server.close(); console.log(`⤷ SSH Tunnel disconnected.`); } catch (error) { console.log(`⤷ ERROR: Failed to disconnect from SSH Tunnel.`, error); } } /** * Reconnects the SSH tunnel by first disconnecting and then connecting again. * This method ensures that the connection is reset. * * @returns {Promise<void>} A promise that resolves when the reconnection process is complete. */ async reconnect() { await this.disconnect(); this.connect(); } }