import WebSocket from "ws"; // const { Socket } = require("airdcpp-apisocket"); import { Socket } from "airdcpp-apisocket"; /** * Wrapper around the AirDC++ WebSocket API socket. * Provides methods to connect, disconnect, and interact with the AirDC++ API. */ class AirDCPPSocket { /** * Configuration options for the underlying socket. * @private */ private options: { url: string; autoReconnect: boolean; reconnectInterval: number; logLevel: string; ignoredListenerEvents: string[]; username: string; password: string; }; /** * Instance of the AirDC++ API socket. * @private */ private socketInstance: any; /** * Constructs a new AirDCPPSocket wrapper. * @param {{ protocol: string; hostname: string; username: string; password: string }} configuration * Connection configuration: protocol (ws or wss), hostname, username, and password. */ constructor(configuration: { protocol: string; hostname: string; username: string; password: string; }) { const socketProtocol = configuration.protocol === "https" ? "wss" : "ws"; this.options = { url: `${socketProtocol}://${configuration.hostname}/api/v1/`, autoReconnect: true, reconnectInterval: 5000, logLevel: "verbose", ignoredListenerEvents: [ "transfer_statistics", "hash_statistics", "hub_counts_updated", ], username: configuration.username, password: configuration.password, }; // Initialize the AirDC++ socket instance this.socketInstance = Socket(this.options, WebSocket); } /** * Establishes a connection to the AirDC++ server. * @async * @returns {Promise} Session information returned by the server. */ async connect(): Promise { if ( this.socketInstance && typeof this.socketInstance.connect === "function" ) { return await this.socketInstance.connect(); } return Promise.reject( new Error("Connect method not available on socket instance") ); } /** * Disconnects from the AirDC++ server. * @async * @returns {Promise} */ async disconnect(): Promise { if ( this.socketInstance && typeof this.socketInstance.disconnect === "function" ) { await this.socketInstance.disconnect(); } } /** * Sends a POST request to a specific AirDC++ endpoint. * @async * @param {string} endpoint - API endpoint path (e.g., "search"). * @param {object} [data={}] - Payload to send with the request. * @returns {Promise} Response from the AirDC++ server. */ async post(endpoint: string, data: object = {}): Promise { return await this.socketInstance.post(endpoint, data); } /** * Sends a GET request to a specific AirDC++ endpoint. * @async * @param {string} endpoint - API endpoint path (e.g., "search/123"). * @param {object} [data={}] - Query parameters to include. * @returns {Promise} Response from the AirDC++ server. */ async get(endpoint: string, data: object = {}): Promise { return await this.socketInstance.get(endpoint, data); } /** * Adds an event listener to the AirDC++ socket. * @async * @param {string} event - Event group (e.g., "search" or "queue"). * @param {string} handlerName - Specific event within the group (e.g., "search_result_added"). * @param {Function} callback - Callback to invoke when the event occurs. * @param {string|number} [id] - Optional identifier (e.g., search instance ID). * @returns {Promise} Listener registration result. */ async addListener( event: string, handlerName: string, callback: (...args: any[]) => void, id?: string | number ): Promise { return await this.socketInstance.addListener( event, handlerName, callback, id ); } } export default AirDCPPSocket;