rosinterface 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/CommandBuilder.d.ts +32 -0
- package/dist/client/CommandBuilder.js +168 -0
- package/dist/client/CommandBuilder.js.map +1 -0
- package/dist/client/MikrotikClient.d.ts +43 -0
- package/dist/client/MikrotikClient.js +276 -0
- package/dist/client/MikrotikClient.js.map +1 -0
- package/dist/client/MikrotikPool.d.ts +18 -0
- package/dist/client/MikrotikPool.js +55 -0
- package/dist/client/MikrotikPool.js.map +1 -0
- package/dist/client/ResultParser.d.ts +5 -0
- package/dist/client/ResultParser.js +30 -0
- package/dist/client/ResultParser.js.map +1 -0
- package/dist/core/Auth.d.ts +5 -0
- package/dist/core/Auth.js +87 -0
- package/dist/core/Auth.js.map +1 -0
- package/dist/core/CircuitBreaker.d.ts +23 -0
- package/dist/core/CircuitBreaker.js +64 -0
- package/dist/core/CircuitBreaker.js.map +1 -0
- package/dist/core/OfflineQueue.d.ts +13 -0
- package/dist/core/OfflineQueue.js +25 -0
- package/dist/core/OfflineQueue.js.map +1 -0
- package/dist/core/RateLimiter.d.ts +17 -0
- package/dist/core/RateLimiter.js +65 -0
- package/dist/core/RateLimiter.js.map +1 -0
- package/dist/core/RosProtocol.d.ts +7 -0
- package/dist/core/RosProtocol.js +80 -0
- package/dist/core/RosProtocol.js.map +1 -0
- package/dist/core/SchemaMapper.d.ts +14 -0
- package/dist/core/SchemaMapper.js +65 -0
- package/dist/core/SchemaMapper.js.map +1 -0
- package/dist/core/SocketClient.d.ts +22 -0
- package/dist/core/SocketClient.js +160 -0
- package/dist/core/SocketClient.js.map +1 -0
- package/dist/features/FileManager.d.ts +8 -0
- package/dist/features/FileManager.js +41 -0
- package/dist/features/FileManager.js.map +1 -0
- package/dist/features/PrometheusExporter.d.ts +15 -0
- package/dist/features/PrometheusExporter.js +38 -0
- package/dist/features/PrometheusExporter.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.js +47 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/Helpers.d.ts +4 -0
- package/dist/utils/Helpers.js +25 -0
- package/dist/utils/Helpers.js.map +1 -0
- package/dist/utils/MikrotikCollection.d.ts +14 -0
- package/dist/utils/MikrotikCollection.js +79 -0
- package/dist/utils/MikrotikCollection.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResultParser = void 0;
|
|
4
|
+
const Helpers_1 = require("../utils/Helpers");
|
|
5
|
+
class ResultParser {
|
|
6
|
+
static parse(rawData) {
|
|
7
|
+
return rawData.map(item => ResultParser.parseItem(item));
|
|
8
|
+
}
|
|
9
|
+
static parseItem(item) {
|
|
10
|
+
const cleanItem = {};
|
|
11
|
+
for (const key of Object.keys(item)) {
|
|
12
|
+
const value = item[key];
|
|
13
|
+
let newKey = key.startsWith('.') ? key.substring(1) : key;
|
|
14
|
+
newKey = (0, Helpers_1.kebabToCamel)(newKey);
|
|
15
|
+
cleanItem[newKey] = ResultParser.inferType(value);
|
|
16
|
+
}
|
|
17
|
+
return cleanItem;
|
|
18
|
+
}
|
|
19
|
+
static inferType(value) {
|
|
20
|
+
const boolVal = (0, Helpers_1.parseBoolean)(value);
|
|
21
|
+
if (boolVal !== null)
|
|
22
|
+
return boolVal;
|
|
23
|
+
if ((0, Helpers_1.isNumeric)(value) && (value.match(/\./g) || []).length <= 1) {
|
|
24
|
+
return parseFloat(value);
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.ResultParser = ResultParser;
|
|
30
|
+
//# sourceMappingURL=ResultParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResultParser.js","sourceRoot":"","sources":["../../src/client/ResultParser.ts"],"names":[],"mappings":";;;AAAA,8CAAyE;AAUzE,MAAa,YAAY;IAOd,MAAM,CAAC,KAAK,CAAC,OAAc;QAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7D,CAAC;IAKO,MAAM,CAAC,SAAS,CAAC,IAAS;QAC9B,MAAM,SAAS,GAAQ,EAAE,CAAC;QAE1B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YAIxB,IAAI,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAE1D,MAAM,GAAG,IAAA,sBAAY,EAAC,MAAM,CAAC,CAAC;YAG9B,SAAS,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;IAKO,MAAM,CAAC,SAAS,CAAC,KAAa;QAElC,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,KAAK,CAAC,CAAC;QACpC,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,OAAO,CAAC;QAMrC,IAAI,IAAA,mBAAS,EAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAG7D,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAGD,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AAtDD,oCAsDC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Auth = void 0;
|
|
37
|
+
const crypto = __importStar(require("crypto"));
|
|
38
|
+
const buffer_1 = require("buffer");
|
|
39
|
+
class Auth {
|
|
40
|
+
static calculateLegacyMD5(password, challengeHex) {
|
|
41
|
+
if (!challengeHex || typeof challengeHex !== 'string') {
|
|
42
|
+
throw new Error('[Auth] Security Error: Invalid challenge format received from router.');
|
|
43
|
+
}
|
|
44
|
+
if (!/^[0-9a-fA-F]+$/.test(challengeHex)) {
|
|
45
|
+
throw new Error('[Auth] Security Error: Non-hex characters detected in challenge.');
|
|
46
|
+
}
|
|
47
|
+
let bufferToHash = null;
|
|
48
|
+
try {
|
|
49
|
+
const challengeBytes = buffer_1.Buffer.from(challengeHex, 'hex');
|
|
50
|
+
const passwordBytes = buffer_1.Buffer.from(password, 'utf8');
|
|
51
|
+
const totalLength = 1 + passwordBytes.length + challengeBytes.length;
|
|
52
|
+
bufferToHash = buffer_1.Buffer.alloc(totalLength);
|
|
53
|
+
bufferToHash[0] = 0;
|
|
54
|
+
passwordBytes.copy(bufferToHash, 1);
|
|
55
|
+
challengeBytes.copy(bufferToHash, 1 + passwordBytes.length);
|
|
56
|
+
const hash = crypto.createHash('md5').update(bufferToHash).digest('hex');
|
|
57
|
+
return '00' + hash;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new Error(`[Auth] Cryptographic Failure: ${error.message}`);
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
if (bufferToHash) {
|
|
64
|
+
bufferToHash.fill(0);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
static mask(value) {
|
|
69
|
+
if (!value)
|
|
70
|
+
return '<empty>';
|
|
71
|
+
if (value.length < 4)
|
|
72
|
+
return '***';
|
|
73
|
+
const visibleStart = value.substring(0, 1);
|
|
74
|
+
const visibleEnd = value.substring(value.length - 1);
|
|
75
|
+
const maskLength = Math.min(value.length - 2, 8);
|
|
76
|
+
return `${visibleStart}${'*'.repeat(maskLength)}${visibleEnd}`;
|
|
77
|
+
}
|
|
78
|
+
static isSafeForLogging(key) {
|
|
79
|
+
const lowerKey = key.toLowerCase();
|
|
80
|
+
return !lowerKey.includes('pass') &&
|
|
81
|
+
!lowerKey.includes('secret') &&
|
|
82
|
+
!lowerKey.includes('key') &&
|
|
83
|
+
!lowerKey.includes('token');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.Auth = Auth;
|
|
87
|
+
//# sourceMappingURL=Auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Auth.js","sourceRoot":"","sources":["../../src/core/Auth.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,mCAAgC;AAYhC,MAAa,IAAI;IAYN,MAAM,CAAC,kBAAkB,CAAC,QAAgB,EAAE,YAAoB;QAEnE,IAAI,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC7F,CAAC;QAGD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACxF,CAAC;QAED,IAAI,YAAY,GAAkB,IAAI,CAAC;QAEvC,IAAI,CAAC;YAED,MAAM,cAAc,GAAG,eAAM,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;YACxD,MAAM,aAAa,GAAG,eAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAKpD,MAAM,WAAW,GAAG,CAAC,GAAG,aAAa,CAAC,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC;YACrE,YAAY,GAAG,eAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAIzC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAGpB,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;YAGpC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YAG5D,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEzE,OAAO,IAAI,GAAG,IAAI,CAAC;QAEvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,iCAAkC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACjF,CAAC;gBAAS,CAAC;YAIP,IAAI,YAAY,EAAE,CAAC;gBACf,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;IACL,CAAC;IASM,MAAM,CAAC,IAAI,CAAC,KAAyB;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAEnC,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAEjD,OAAO,GAAG,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,UAAU,EAAE,CAAC;IACnE,CAAC;IAMM,MAAM,CAAC,gBAAgB,CAAC,GAAW;QACtC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC7B,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC5B,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;YACzB,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;CACJ;AA5FD,oBA4FC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare enum CircuitBreakerState {
|
|
2
|
+
CLOSED = 0,
|
|
3
|
+
OPEN = 1,
|
|
4
|
+
HALF_OPEN = 2
|
|
5
|
+
}
|
|
6
|
+
export interface CircuitBreakerOptions {
|
|
7
|
+
failureThreshold?: number;
|
|
8
|
+
resetTimeout?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class CircuitBreaker {
|
|
11
|
+
private state;
|
|
12
|
+
private failureCount;
|
|
13
|
+
private lastFailureTime;
|
|
14
|
+
private readonly failureThreshold;
|
|
15
|
+
private readonly resetTimeout;
|
|
16
|
+
constructor(options?: CircuitBreakerOptions);
|
|
17
|
+
execute<T>(action: () => Promise<T>): Promise<T>;
|
|
18
|
+
private onSuccess;
|
|
19
|
+
private onFailure;
|
|
20
|
+
private transitionTo;
|
|
21
|
+
private isResetTimeoutExpired;
|
|
22
|
+
getState(): CircuitBreakerState;
|
|
23
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CircuitBreaker = exports.CircuitBreakerState = void 0;
|
|
4
|
+
var CircuitBreakerState;
|
|
5
|
+
(function (CircuitBreakerState) {
|
|
6
|
+
CircuitBreakerState[CircuitBreakerState["CLOSED"] = 0] = "CLOSED";
|
|
7
|
+
CircuitBreakerState[CircuitBreakerState["OPEN"] = 1] = "OPEN";
|
|
8
|
+
CircuitBreakerState[CircuitBreakerState["HALF_OPEN"] = 2] = "HALF_OPEN";
|
|
9
|
+
})(CircuitBreakerState || (exports.CircuitBreakerState = CircuitBreakerState = {}));
|
|
10
|
+
class CircuitBreaker {
|
|
11
|
+
constructor(options = {}) {
|
|
12
|
+
this.state = CircuitBreakerState.CLOSED;
|
|
13
|
+
this.failureCount = 0;
|
|
14
|
+
this.lastFailureTime = 0;
|
|
15
|
+
this.failureThreshold = options.failureThreshold || 5;
|
|
16
|
+
this.resetTimeout = options.resetTimeout || 10000;
|
|
17
|
+
}
|
|
18
|
+
async execute(action) {
|
|
19
|
+
if (this.state === CircuitBreakerState.OPEN) {
|
|
20
|
+
if (this.isResetTimeoutExpired()) {
|
|
21
|
+
this.transitionTo(CircuitBreakerState.HALF_OPEN);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const timeLeft = this.resetTimeout - (Date.now() - this.lastFailureTime);
|
|
25
|
+
throw new Error(`CircuitBreaker is OPEN. Fast-failing. Retry in ${timeLeft}ms.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const result = await action();
|
|
30
|
+
return this.onSuccess(result);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return this.onFailure(error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
onSuccess(result) {
|
|
37
|
+
if (this.state === CircuitBreakerState.HALF_OPEN) {
|
|
38
|
+
this.transitionTo(CircuitBreakerState.CLOSED);
|
|
39
|
+
}
|
|
40
|
+
this.failureCount = 0;
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
onFailure(error) {
|
|
44
|
+
this.failureCount++;
|
|
45
|
+
this.lastFailureTime = Date.now();
|
|
46
|
+
if (this.state === CircuitBreakerState.HALF_OPEN || this.failureCount >= this.failureThreshold) {
|
|
47
|
+
this.transitionTo(CircuitBreakerState.OPEN);
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
transitionTo(newState) {
|
|
52
|
+
this.state = newState;
|
|
53
|
+
const stateName = CircuitBreakerState[newState];
|
|
54
|
+
console.warn(`[CircuitBreaker] State changed to: ${stateName}`);
|
|
55
|
+
}
|
|
56
|
+
isResetTimeoutExpired() {
|
|
57
|
+
return (Date.now() - this.lastFailureTime) > this.resetTimeout;
|
|
58
|
+
}
|
|
59
|
+
getState() {
|
|
60
|
+
return this.state;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.CircuitBreaker = CircuitBreaker;
|
|
64
|
+
//# sourceMappingURL=CircuitBreaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CircuitBreaker.js","sourceRoot":"","sources":["../../src/core/CircuitBreaker.ts"],"names":[],"mappings":";;;AAIA,IAAY,mBAOX;AAPD,WAAY,mBAAmB;IAE3B,iEAAM,CAAA;IAEN,6DAAI,CAAA;IAEJ,uEAAS,CAAA;AACb,CAAC,EAPW,mBAAmB,mCAAnB,mBAAmB,QAO9B;AAgBD,MAAa,cAAc;IAQvB,YAAY,UAAiC,EAAE;QAPvC,UAAK,GAAwB,mBAAmB,CAAC,MAAM,CAAC;QACxD,iBAAY,GAAW,CAAC,CAAC;QACzB,oBAAe,GAAW,CAAC,CAAC;QAMhC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,KAAK,CAAC;IACtD,CAAC;IAMM,KAAK,CAAC,OAAO,CAAI,MAAwB;QAE5C,IAAI,IAAI,CAAC,KAAK,KAAK,mBAAmB,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;gBAC/B,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACJ,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;gBACzE,MAAM,IAAI,KAAK,CAAC,kDAAkD,QAAQ,KAAK,CAAC,CAAC;YACrF,CAAC;QACL,CAAC;QAGD,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,MAAM,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,SAAS,CAAC,KAAc,CAAC,CAAC;QAC1C,CAAC;IACL,CAAC;IAKO,SAAS,CAAI,MAAS;QAC1B,IAAI,IAAI,CAAC,KAAK,KAAK,mBAAmB,CAAC,SAAS,EAAE,CAAC;YAC/C,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,OAAO,MAAM,CAAC;IAClB,CAAC;IAKO,SAAS,CAAC,KAAY;QAC1B,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAElC,IAAI,IAAI,CAAC,KAAK,KAAK,mBAAmB,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC7F,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,KAAK,CAAC;IAChB,CAAC;IAEO,YAAY,CAAC,QAA6B;QAC9C,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;QACtB,MAAM,SAAS,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,sCAAsC,SAAS,EAAE,CAAC,CAAC;IACpE,CAAC;IAEO,qBAAqB;QACzB,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;IACnE,CAAC;IAEM,QAAQ;QACX,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;CACJ;AA3ED,wCA2EC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface DeferredTask {
|
|
2
|
+
id: string;
|
|
3
|
+
path: string;
|
|
4
|
+
action: 'add' | 'set' | 'remove';
|
|
5
|
+
params: any;
|
|
6
|
+
timestamp: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class OfflineQueue {
|
|
9
|
+
private static storage;
|
|
10
|
+
static enqueue(task: Omit<DeferredTask, 'id' | 'timestamp' | 'status'>): void;
|
|
11
|
+
static flush(): DeferredTask[];
|
|
12
|
+
static get size(): number;
|
|
13
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OfflineQueue = void 0;
|
|
4
|
+
class OfflineQueue {
|
|
5
|
+
static enqueue(task) {
|
|
6
|
+
const fullTask = {
|
|
7
|
+
id: Math.random().toString(36).substring(2, 15),
|
|
8
|
+
timestamp: Date.now(),
|
|
9
|
+
...task
|
|
10
|
+
};
|
|
11
|
+
this.storage.push(fullTask);
|
|
12
|
+
console.log(`Router offline. Task queued: ${fullTask.action.toUpperCase()} on ${fullTask.path}`);
|
|
13
|
+
}
|
|
14
|
+
static flush() {
|
|
15
|
+
const tasks = [...this.storage];
|
|
16
|
+
this.storage = [];
|
|
17
|
+
return tasks;
|
|
18
|
+
}
|
|
19
|
+
static get size() {
|
|
20
|
+
return this.storage.length;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.OfflineQueue = OfflineQueue;
|
|
24
|
+
OfflineQueue.storage = [];
|
|
25
|
+
//# sourceMappingURL=OfflineQueue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OfflineQueue.js","sourceRoot":"","sources":["../../src/core/OfflineQueue.ts"],"names":[],"mappings":";;;AAcA,MAAa,YAAY;IAMd,MAAM,CAAC,OAAO,CAAC,IAAuD;QACzE,MAAM,QAAQ,GAAiB;YAC3B,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC;YAC/C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,GAAG,IAAI;SACV,CAAC;QAEF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,gCAAgC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACrG,CAAC;IAMM,MAAM,CAAC,KAAK;QACf,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC;IACjB,CAAC;IAKM,MAAM,KAAK,IAAI;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC/B,CAAC;;AAhCL,oCAiCC;AAhCkB,oBAAO,GAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class RateLimiter {
|
|
2
|
+
private readonly maxTokens;
|
|
3
|
+
private refillRate;
|
|
4
|
+
private readonly minRefillRate;
|
|
5
|
+
private readonly originalRefillRate;
|
|
6
|
+
private tokens;
|
|
7
|
+
private queue;
|
|
8
|
+
private rttHistory;
|
|
9
|
+
private readonly historySize;
|
|
10
|
+
private readonly LATENCY_THRESHOLD_WARNING;
|
|
11
|
+
private readonly LATENCY_THRESHOLD_CRITICAL;
|
|
12
|
+
constructor(limitPerSecond?: number, burstSize?: number);
|
|
13
|
+
acquire(): Promise<void>;
|
|
14
|
+
submitFeedback(durationMs: number): void;
|
|
15
|
+
private refillTokens;
|
|
16
|
+
private adjustHealth;
|
|
17
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RateLimiter = void 0;
|
|
4
|
+
class RateLimiter {
|
|
5
|
+
constructor(limitPerSecond = 50, burstSize = 10) {
|
|
6
|
+
this.minRefillRate = 2;
|
|
7
|
+
this.queue = [];
|
|
8
|
+
this.rttHistory = [];
|
|
9
|
+
this.historySize = 10;
|
|
10
|
+
this.LATENCY_THRESHOLD_WARNING = 200;
|
|
11
|
+
this.LATENCY_THRESHOLD_CRITICAL = 500;
|
|
12
|
+
this.refillRate = limitPerSecond;
|
|
13
|
+
this.originalRefillRate = limitPerSecond;
|
|
14
|
+
this.maxTokens = burstSize;
|
|
15
|
+
this.tokens = burstSize;
|
|
16
|
+
setInterval(() => this.refillTokens(), 100);
|
|
17
|
+
}
|
|
18
|
+
async acquire() {
|
|
19
|
+
if (this.tokens >= 1) {
|
|
20
|
+
this.tokens -= 1;
|
|
21
|
+
return Promise.resolve();
|
|
22
|
+
}
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
this.queue.push(resolve);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
submitFeedback(durationMs) {
|
|
28
|
+
this.rttHistory.push(durationMs);
|
|
29
|
+
if (this.rttHistory.length > this.historySize) {
|
|
30
|
+
this.rttHistory.shift();
|
|
31
|
+
}
|
|
32
|
+
this.adjustHealth();
|
|
33
|
+
}
|
|
34
|
+
refillTokens() {
|
|
35
|
+
const tokensToAdd = this.refillRate / 10;
|
|
36
|
+
this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
|
|
37
|
+
while (this.queue.length > 0 && this.tokens >= 1) {
|
|
38
|
+
this.tokens -= 1;
|
|
39
|
+
const nextResolve = this.queue.shift();
|
|
40
|
+
if (nextResolve)
|
|
41
|
+
nextResolve();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
adjustHealth() {
|
|
45
|
+
if (this.rttHistory.length < 5)
|
|
46
|
+
return;
|
|
47
|
+
const avgLatency = this.rttHistory.reduce((a, b) => a + b, 0) / this.rttHistory.length;
|
|
48
|
+
if (avgLatency > this.LATENCY_THRESHOLD_CRITICAL) {
|
|
49
|
+
this.refillRate = this.minRefillRate;
|
|
50
|
+
this.tokens = 0;
|
|
51
|
+
if (Math.random() > 0.9)
|
|
52
|
+
console.warn(`[RateLimiter] High Congestion! Latency: ${avgLatency.toFixed(0)}ms. Throttling down.`);
|
|
53
|
+
}
|
|
54
|
+
else if (avgLatency > this.LATENCY_THRESHOLD_WARNING) {
|
|
55
|
+
this.refillRate = Math.max(this.minRefillRate, this.originalRefillRate / 2);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
if (this.refillRate < this.originalRefillRate) {
|
|
59
|
+
this.refillRate += 5;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.RateLimiter = RateLimiter;
|
|
65
|
+
//# sourceMappingURL=RateLimiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../src/core/RateLimiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RosProtocol = void 0;
|
|
4
|
+
class RosProtocol {
|
|
5
|
+
static encodeSentence(str) {
|
|
6
|
+
const encoded = Buffer.from(str, 'utf8');
|
|
7
|
+
const len = encoded.length;
|
|
8
|
+
let offset = 0;
|
|
9
|
+
let header;
|
|
10
|
+
if (len < 0x80) {
|
|
11
|
+
header = Buffer.alloc(1);
|
|
12
|
+
header[offset++] = len;
|
|
13
|
+
}
|
|
14
|
+
else if (len < 0x4000) {
|
|
15
|
+
header = Buffer.alloc(2);
|
|
16
|
+
const lenBytes = len | 0x8000;
|
|
17
|
+
header[offset++] = (lenBytes >> 8) & 0xff;
|
|
18
|
+
header[offset++] = lenBytes & 0xff;
|
|
19
|
+
}
|
|
20
|
+
else if (len < 0x200000) {
|
|
21
|
+
header = Buffer.alloc(3);
|
|
22
|
+
const lenBytes = len | 0xc00000;
|
|
23
|
+
header[offset++] = (lenBytes >> 16) & 0xff;
|
|
24
|
+
header[offset++] = (lenBytes >> 8) & 0xff;
|
|
25
|
+
header[offset++] = lenBytes & 0xff;
|
|
26
|
+
}
|
|
27
|
+
else if (len < 0x10000000) {
|
|
28
|
+
header = Buffer.alloc(4);
|
|
29
|
+
const lenBytes = len | 0xe0000000;
|
|
30
|
+
header[offset++] = (lenBytes >> 24) & 0xff;
|
|
31
|
+
header[offset++] = (lenBytes >> 16) & 0xff;
|
|
32
|
+
header[offset++] = (lenBytes >> 8) & 0xff;
|
|
33
|
+
header[offset++] = lenBytes & 0xff;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
header = Buffer.alloc(5);
|
|
37
|
+
header[offset++] = 0xf0;
|
|
38
|
+
header[offset++] = (len >> 24) & 0xff;
|
|
39
|
+
header[offset++] = (len >> 16) & 0xff;
|
|
40
|
+
header[offset++] = (len >> 8) & 0xff;
|
|
41
|
+
header[offset++] = len & 0xff;
|
|
42
|
+
}
|
|
43
|
+
return Buffer.concat([header, encoded]);
|
|
44
|
+
}
|
|
45
|
+
static decodeLength(buffer) {
|
|
46
|
+
if (buffer.length === 0)
|
|
47
|
+
return null;
|
|
48
|
+
const b = buffer[0];
|
|
49
|
+
if ((b & 0x80) === 0x00) {
|
|
50
|
+
return { length: b, byteLength: 1 };
|
|
51
|
+
}
|
|
52
|
+
if ((b & 0xC0) === 0x80) {
|
|
53
|
+
if (buffer.length < 2)
|
|
54
|
+
return null;
|
|
55
|
+
const len = ((b & 0x3F) << 8) | buffer[1];
|
|
56
|
+
return { length: len, byteLength: 2 };
|
|
57
|
+
}
|
|
58
|
+
if ((b & 0xE0) === 0xC0) {
|
|
59
|
+
if (buffer.length < 3)
|
|
60
|
+
return null;
|
|
61
|
+
const len = ((b & 0x1F) << 16) | (buffer[1] << 8) | buffer[2];
|
|
62
|
+
return { length: len, byteLength: 3 };
|
|
63
|
+
}
|
|
64
|
+
if ((b & 0xF0) === 0xE0) {
|
|
65
|
+
if (buffer.length < 4)
|
|
66
|
+
return null;
|
|
67
|
+
const len = ((b & 0x0F) << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
|
|
68
|
+
return { length: len, byteLength: 4 };
|
|
69
|
+
}
|
|
70
|
+
if (b === 0xF0) {
|
|
71
|
+
if (buffer.length < 5)
|
|
72
|
+
return null;
|
|
73
|
+
const len = (buffer[1] << 24) | (buffer[2] << 16) | (buffer[3] << 8) | buffer[4];
|
|
74
|
+
return { length: len, byteLength: 5 };
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.RosProtocol = RosProtocol;
|
|
80
|
+
//# sourceMappingURL=RosProtocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RosProtocol.js","sourceRoot":"","sources":["../../src/core/RosProtocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { MikrotikClient } from '../client/MikrotikClient';
|
|
2
|
+
export declare class SchemaMapper {
|
|
3
|
+
version: string;
|
|
4
|
+
majorVersion: number;
|
|
5
|
+
boardName: string;
|
|
6
|
+
architecture: string;
|
|
7
|
+
hasWireless: boolean;
|
|
8
|
+
private pathAliases;
|
|
9
|
+
load(client: MikrotikClient): Promise<void>;
|
|
10
|
+
private buildPathMap;
|
|
11
|
+
resolve(path: string): string;
|
|
12
|
+
isV7(): boolean;
|
|
13
|
+
isArm(): boolean;
|
|
14
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SchemaMapper = void 0;
|
|
4
|
+
class SchemaMapper {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.version = '';
|
|
7
|
+
this.majorVersion = 0;
|
|
8
|
+
this.boardName = '';
|
|
9
|
+
this.architecture = '';
|
|
10
|
+
this.hasWireless = false;
|
|
11
|
+
this.pathAliases = {};
|
|
12
|
+
}
|
|
13
|
+
async load(client) {
|
|
14
|
+
try {
|
|
15
|
+
const resourceCollection = await client.command('/system/resource').print();
|
|
16
|
+
const resource = resourceCollection.first();
|
|
17
|
+
if (resource) {
|
|
18
|
+
this.version = resource.version || '0.0.0';
|
|
19
|
+
this.majorVersion = parseInt(this.version.split('.')[0]);
|
|
20
|
+
this.boardName = resource['board-name'] || 'unknown';
|
|
21
|
+
this.architecture = resource['architecture-name'] || 'unknown';
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const packages = await client.command('/system/package').print();
|
|
25
|
+
this.hasWireless = packages.filter(p => p.name === 'wireless' || p.name === 'wifiwave2' || p.name === 'wifi').count() > 0;
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
console.warn('[SchemaMapper] Warning: Could not scan packages (Permission denied?). Defaulting features to false.');
|
|
29
|
+
}
|
|
30
|
+
this.buildPathMap();
|
|
31
|
+
console.log(`Schema Loaded: RouterOS v${this.version} (${this.architecture}) on ${this.boardName}`);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error('Schema Discovery Failed:', error);
|
|
35
|
+
this.majorVersion = 6;
|
|
36
|
+
this.buildPathMap();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
buildPathMap() {
|
|
40
|
+
if (this.majorVersion >= 7) {
|
|
41
|
+
this.pathAliases['wifi'] = '/interface/wifi';
|
|
42
|
+
this.pathAliases['bgp'] = '/routing/bgp/connection';
|
|
43
|
+
this.pathAliases['ospf'] = '/routing/ospf/instance';
|
|
44
|
+
this.pathAliases['firewall'] = '/ip/firewall/filter';
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.pathAliases['wifi'] = '/interface/wireless';
|
|
48
|
+
this.pathAliases['bgp'] = '/routing/bgp/peer';
|
|
49
|
+
this.pathAliases['ospf'] = '/routing/ospf/instance';
|
|
50
|
+
this.pathAliases['firewall'] = '/ip/firewall/filter';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
resolve(path) {
|
|
54
|
+
const cleanPath = path.startsWith('/') ? path.substring(1) : path;
|
|
55
|
+
return this.pathAliases[cleanPath] || path;
|
|
56
|
+
}
|
|
57
|
+
isV7() {
|
|
58
|
+
return this.majorVersion >= 7;
|
|
59
|
+
}
|
|
60
|
+
isArm() {
|
|
61
|
+
return this.architecture === 'arm' || this.architecture === 'arm64';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.SchemaMapper = SchemaMapper;
|
|
65
|
+
//# sourceMappingURL=SchemaMapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaMapper.js","sourceRoot":"","sources":["../../src/core/SchemaMapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { Buffer } from 'buffer';
|
|
3
|
+
export interface SocketClientOptions {
|
|
4
|
+
host: string;
|
|
5
|
+
port: number;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
useTLS?: boolean;
|
|
8
|
+
rejectUnauthorized?: boolean;
|
|
9
|
+
keepAlive?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare class SocketClient extends EventEmitter {
|
|
12
|
+
private socket;
|
|
13
|
+
private options;
|
|
14
|
+
private connected;
|
|
15
|
+
private receiveBuffer;
|
|
16
|
+
constructor(options: SocketClientOptions);
|
|
17
|
+
connect(): Promise<void>;
|
|
18
|
+
write(data: Buffer): void;
|
|
19
|
+
close(): void;
|
|
20
|
+
destroy(): void;
|
|
21
|
+
private handleDataChunk;
|
|
22
|
+
}
|