UNPKG

@fibercom/routeros-api

Version:

Robust MikroTik RouterOS API client for Node.js and TypeScript

175 lines 14.6 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Connector = void 0; const events_1 = require("events"); const net_1 = require("net"); const tls = require("tls"); const Receiver_1 = require("./Receiver"); const Transmitter_1 = require("./Transmitter"); const RosException_1 = require("../RosException"); const debug = require("debug"); const info = debug("routeros-api:connector:info"); const error = debug("routeros-api:connector:error"); class Connector extends events_1.EventEmitter { constructor(options) { var _a, _b, _c; super(); this.debug = false; this.connected = false; this.connecting = false; this.host = options.host; this.port = (_a = options.port) !== null && _a !== void 0 ? _a : (options.tls ? 8729 : 8728); this.timeout = (_b = options.timeout) !== null && _b !== void 0 ? _b : 5; this.debug = (_c = options.debug) !== null && _c !== void 0 ? _c : false; const tlsOptions = options.tls === true ? {} : options.tls; if (typeof tlsOptions === "object") { const { pskCallback } = tlsOptions, safeTls = __rest(tlsOptions, ["pskCallback"]); this.tlsOptions = safeTls; } } log(message) { if (this.debug) console.debug(message); } connect() { if (this.connected || this.connecting) { this.log("[DEBUG] Already connected or connecting."); return Promise.resolve(this); } this.connecting = true; return new Promise((resolve, reject) => { var _a, _b, _c, _d; const timeoutMs = this.timeout * 1000; const timeout = setTimeout(() => { var _a; this.log("[DEBUG] Connection timeout triggered."); (_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy(); this.connecting = false; rejectOnce(new RosException_1.RosException("SOCKTMOUT", { message: "Connection timed out. API may be disabled, filtered, or unreachable.", seconds: this.timeout.toString(), })); }, timeoutMs); let resolved = false; const resolveOnce = () => { if (!resolved) { resolved = true; clearTimeout(timeout); resolve(this); } }; const rejectOnce = (err) => { if (!resolved) { resolved = true; clearTimeout(timeout); reject(err); } }; const onConnected = () => { this.log("[DEBUG] Socket connect event fired."); this.connecting = false; this.connected = true; this.transmitter.runPool(); this.emit("connected", this); resolveOnce(); // ✅ resolve immediately }; const onError = (err) => { var _a; this.connecting = false; this.connected = false; (_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy(); const code = (err === null || err === void 0 ? void 0 : err.code) || (err === null || err === void 0 ? void 0 : err.errno) || "UNKNOWN"; this.log(`[DEBUG] Socket error: ${code}`); const socketError = new RosException_1.RosException("APIFORBIDDEN", { message: "Connection failed. API may be disabled or filtered. Code: " + code, }); if (resolved) this.emit("error", socketError, this); else rejectOnce(socketError); }; try { if (this.tlsOptions) { this.log("[DEBUG] Using TLS socket"); this.socket = tls.connect(this.port, this.host, this.tlsOptions, onConnected); } else { this.log("[DEBUG] Using plain TCP socket"); this.socket = new net_1.Socket(); this.socket.connect(this.port, this.host); this.socket.once("connect", onConnected); } this.transmitter = new Transmitter_1.Transmitter(this.socket); this.receiver = new Receiver_1.Receiver(this.socket); this.socket.on("data", (data) => { this.onData(data); }); this.socket.once("end", this.onEnd.bind(this)); this.socket.once("close", this.onClose.bind(this)); this.socket.once("timeout", this.onTimeout.bind(this)); this.socket.once("error", onError); (_b = (_a = this.socket).setTimeout) === null || _b === void 0 ? void 0 : _b.call(_a, timeoutMs); (_d = (_c = this.socket).setKeepAlive) === null || _d === void 0 ? void 0 : _d.call(_c, true); } catch (e) { const message = e instanceof Error ? e.message : String(e); rejectOnce(new RosException_1.RosException("SOCKFAIL", { message })); } }); } write(data) { for (const line of data) this.transmitter.write(line); this.transmitter.write(null); return this; } read(tag, cb) { this.receiver.read(tag, cb); } stopRead(tag) { this.receiver.stop(tag); } close() { var _a; (_a = this.socket) === null || _a === void 0 ? void 0 : _a.end(); } destroy() { var _a; (_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy(); this.removeAllListeners(); } onEnd() { this.log("[DEBUG] Socket end event fired."); } onClose() { this.connected = false; this.connecting = false; this.emit("close", this); } onTimeout() { this.connected = false; this.connecting = false; const timeoutErr = new RosException_1.RosException("SOCKTMOUT", { seconds: this.timeout, }); this.emit("timeout", timeoutErr, this); this.destroy(); } onData(data) { this.receiver.processRawData(data); } } exports.Connector = Connector; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29ubmVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nvbm5lY3Rvci9Db25uZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBQSxtQ0FBc0M7QUFDdEMsNkJBQTZCO0FBQzdCLDJCQUEyQjtBQUMzQix5Q0FBc0M7QUFDdEMsK0NBQTRDO0FBQzVDLGtEQUErQztBQUMvQywrQkFBZ0M7QUFHaEMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUM7QUFDbEQsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7QUFFcEQsTUFBYSxTQUFVLFNBQVEscUJBQVk7SUFhekMsWUFBWSxPQUFvQjs7UUFDOUIsS0FBSyxFQUFFLENBQUM7UUFWSCxVQUFLLEdBQVksS0FBSyxDQUFDO1FBS3RCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFDM0IsZUFBVSxHQUFZLEtBQUssQ0FBQztRQUtsQyxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFBLE9BQU8sQ0FBQyxJQUFJLG1DQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4RCxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQUEsT0FBTyxDQUFDLE9BQU8sbUNBQUksQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBQSxPQUFPLENBQUMsS0FBSyxtQ0FBSSxLQUFLLENBQUM7UUFFcEMsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUMzRCxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lB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