@fibercom/routeros-api
Version:
Robust MikroTik RouterOS API client for Node.js and TypeScript
134 lines • 9.24 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Channel = void 0;
const events_1 = require("events");
const RosException_1 = require("./RosException");
const debug = require("debug");
const info = debug("routeros-api:channel:info");
const error = debug("routeros-api:channel:error");
/**
* Channel class is responsible for issuing commands with a unique tag,
* and receiving corresponding replies via the RouterOS API. It listens for
* specific reply types such as !re, !done, and !trap.
*/
class Channel extends events_1.EventEmitter {
constructor(connector) {
super();
this.data = [];
this.trapped = false;
this.streaming = false;
this.id = Math.random().toString(36).substring(3);
this.connector = connector;
this.once("unknown", this.onUnknown.bind(this));
}
/**
* Get the unique ID assigned to this channel.
*/
get Id() {
return this.id;
}
/**
* Get the underlying connector used by this channel.
*/
get Connector() {
return this.connector;
}
/**
* Write a command to the RouterOS device with this channel's tag.
* Always returns a promise that resolves/rejects on done/trap.
*/
write(params, isStream = false, returnPromise = true) {
this.streaming = isStream;
params.push(".tag=" + this.id);
if (!returnPromise) {
this.readAndWrite(params);
return Promise.resolve([]);
}
this.data = []; // clear any old data
this.on("data", (packet) => this.data.push(packet));
return new Promise((resolve, reject) => {
this.once("done", (data) => resolve(data));
this.once("trap", (data) => {
const msg = (data === null || data === void 0 ? void 0 : data.message) || "Unknown error";
reject(new RosException_1.RosException("TRAP", { message: msg }));
});
this.readAndWrite(params);
});
}
/**
* Close the channel and stop reading its tag.
* Optionally force cleanup of event listeners.
*/
close(force = false) {
this.emit("close");
if (!this.streaming || force) {
this.removeAllListeners();
}
this.connector.stopRead(this.id);
}
/**
* Bind a tag reader and issue the command.
*/
readAndWrite(params) {
this.connector.read(this.id, (packet) => this.processPacket(packet));
this.connector.write(params);
}
/**
* Parse incoming replies and emit appropriate events.
*/
processPacket(packet) {
const reply = packet.shift();
info("Processing reply %s with data %o", reply, packet);
if (reply === "!empty") {
info("Received !empty — interpreted as empty [] response");
// Explicitly clear data
this.data = [];
return;
}
const parsed = this.parsePacket(packet);
if (reply === "!trap") {
this.trapped = true;
this.emit("trap", parsed);
return;
}
if (packet.length > 0 && !this.streaming) {
this.emit("data", parsed);
}
switch (reply) {
case "!re":
if (this.streaming)
this.emit("stream", parsed);
break;
case "!done":
if (!this.trapped)
this.emit("done", this.data);
this.close();
break;
default:
this.emit("unknown", reply);
this.close();
break;
}
}
/**
* Convert an array of lines like '=key=value' into an object.
*/
parsePacket(packet) {
const obj = {};
for (const line of packet) {
const linePair = line.split("=");
linePair.shift(); // Remove leading empty element
obj[linePair.shift()] = linePair.join("=");
}
info("Parsed line, got %o as result", obj);
return obj;
}
/**
* Handler for unexpected replies—emits and throws an error.
*/
onUnknown(reply) {
throw new RosException_1.RosException("UNKNOWNREPLY", { reply });
}
}
exports.Channel = Channel;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2hhbm5lbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9DaGFubmVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFzQztBQUV0QyxpREFBOEM7QUFDOUMsK0JBQStCO0FBRy9CLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0FBQ2hELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0FBRWxEOzs7O0dBSUc7QUFDSCxNQUFhLE9BQVEsU0FBUSxxQkFBWTtJQU92QyxZQUFZLFNBQW9CO1FBQzlCLEtBQUssRUFBRSxDQUFDO1FBTEYsU0FBSSxHQUFVLEVBQUUsQ0FBQztRQUNqQixZQUFPLEdBQVksS0FBSyxDQUFDO1FBQ3pCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFJakMsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksRUFBRTtRQUNKLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7T0FHRztJQUNJLEtBQUssQ0FDVixNQUFnQixFQUNoQixRQUFRLEdBQUcsS0FBSyxFQUNoQixhQUFhLEdBQUcsSUFBSTtRQUVwQixJQUFJLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQztRQUMxQixNQUFNLENBQUMsSUFBSSxDQUFD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