@fibercom/routeros-api
Version:
Robust MikroTik RouterOS API client for Node.js and TypeScript
162 lines • 13.2 kB
JavaScript
"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) {
super();
this.debug = false;
this.connected = false;
this.connecting = false;
this.host = options.host;
this.port = options.port || (options.tls ? 8729 : 8728);
this.timeout = options.timeout || 5;
this.debug = options.debug || false;
if (typeof options.tls === "boolean" && options.tls)
options.tls = {};
if (typeof options.tls === "object") {
const _a = options.tls, { pskCallback } = _a, safeTls = __rest(_a, ["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;
(_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}`);
rejectOnce(new RosException_1.RosException("APIFORBIDDEN", {
message: "Connection failed. API may be disabled or filtered. Code: " +
code,
}));
};
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("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) {
rejectOnce(new RosException_1.RosException("SOCKFAIL", { message: e.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.emit("close", this);
this.destroy();
}
onTimeout() {
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29ubmVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nvbm5lY3Rvci9Db25uZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBQSxtQ0FBc0M7QUFDdEMsNkJBQTZCO0FBQzdCLDJCQUEyQjtBQUMzQix5Q0FBc0M7QUFDdEMsK0NBQTRDO0FBQzVDLGtEQUErQztBQUMvQywrQkFBK0I7QUFHL0IsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUM7QUFDbEQsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7QUFFcEQsTUFBYSxTQUFVLFNBQVEscUJBQVk7SUFhekMsWUFBWSxPQUFvQjtRQUM5QixLQUFLLEVBQUUsQ0FBQztRQVZILFVBQUssR0FBWSxLQUFLLENBQUM7UUFLdEIsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUMzQixlQUFVLEdBQVksS0FBSyxDQUFDO1FBS2xDLElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQztRQUVwQyxJQUFJLE9BQU8sT0FBTyxDQUFDLEdBQUcsS0FBSyxTQUFTLElBQUksT0FBTyxDQUFDLEdBQUc7WUFBRSxPQUFPLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUN0RSxJQUFJLE9BQU8sT0FBTyxDQUFDLEdBQUcsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNwQyxNQUFNLEtBQThC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