rosinterface 1.2.1 → 1.3.1

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.
Files changed (81) hide show
  1. package/README.md +381 -14
  2. package/dist/cli/{generate.js → Generate.js} +21 -2
  3. package/dist/cli/Generate.js.map +1 -0
  4. package/dist/cli/SchemaInferrer.d.ts +9 -0
  5. package/dist/cli/SchemaInferrer.js +22 -3
  6. package/dist/cli/SchemaInferrer.js.map +1 -1
  7. package/dist/client/CommandBuilder.d.ts +341 -2
  8. package/dist/client/CommandBuilder.js +422 -8
  9. package/dist/client/CommandBuilder.js.map +1 -1
  10. package/dist/client/MikrotikClient.d.ts +360 -4
  11. package/dist/client/MikrotikClient.js +477 -23
  12. package/dist/client/MikrotikClient.js.map +1 -1
  13. package/dist/client/MikrotikPool.d.ts +30 -0
  14. package/dist/client/MikrotikPool.js +33 -3
  15. package/dist/client/MikrotikPool.js.map +1 -1
  16. package/dist/client/MikrotikSwarm.d.ts +185 -0
  17. package/dist/client/MikrotikSwarm.js +270 -0
  18. package/dist/client/MikrotikSwarm.js.map +1 -0
  19. package/dist/client/MikrotikTransaction.d.ts +27 -0
  20. package/dist/client/MikrotikTransaction.js +28 -0
  21. package/dist/client/MikrotikTransaction.js.map +1 -1
  22. package/dist/client/ResultParser.d.ts +19 -0
  23. package/dist/client/ResultParser.js +31 -0
  24. package/dist/client/ResultParser.js.map +1 -1
  25. package/dist/client/SnapshotSubscription.d.ts +139 -0
  26. package/dist/client/SnapshotSubscription.js +169 -0
  27. package/dist/client/SnapshotSubscription.js.map +1 -1
  28. package/dist/core/Auth.d.ts +31 -0
  29. package/dist/core/Auth.js +46 -1
  30. package/dist/core/Auth.js.map +1 -1
  31. package/dist/core/CircuitBreaker.d.ts +26 -0
  32. package/dist/core/CircuitBreaker.js +26 -0
  33. package/dist/core/CircuitBreaker.js.map +1 -1
  34. package/dist/core/HttpConstants.d.ts +37 -0
  35. package/dist/core/HttpConstants.js +68 -0
  36. package/dist/core/HttpConstants.js.map +1 -0
  37. package/dist/core/OfflineQueue.d.ts +16 -0
  38. package/dist/core/OfflineQueue.js +10 -0
  39. package/dist/core/OfflineQueue.js.map +1 -1
  40. package/dist/core/RateLimiter.d.ts +24 -0
  41. package/dist/core/RateLimiter.js +43 -7
  42. package/dist/core/RateLimiter.js.map +1 -1
  43. package/dist/core/RestProtocol.d.ts +33 -0
  44. package/dist/core/RestProtocol.js +166 -0
  45. package/dist/core/RestProtocol.js.map +1 -0
  46. package/dist/core/RosError.d.ts +40 -0
  47. package/dist/core/RosError.js +106 -0
  48. package/dist/core/RosError.js.map +1 -0
  49. package/dist/core/RosProtocol.d.ts +21 -0
  50. package/dist/core/RosProtocol.js +40 -1
  51. package/dist/core/RosProtocol.js.map +1 -1
  52. package/dist/core/SchemaMapper.d.ts +41 -0
  53. package/dist/core/SchemaMapper.js +57 -2
  54. package/dist/core/SchemaMapper.js.map +1 -1
  55. package/dist/core/SocketClient.d.ts +34 -0
  56. package/dist/core/SocketClient.js +51 -3
  57. package/dist/core/SocketClient.js.map +1 -1
  58. package/dist/features/FileManager.d.ts +67 -3
  59. package/dist/features/FileManager.js +145 -17
  60. package/dist/features/FileManager.js.map +1 -1
  61. package/dist/features/LiveCollection.d.ts +51 -0
  62. package/dist/features/LiveCollection.js +69 -0
  63. package/dist/features/LiveCollection.js.map +1 -1
  64. package/dist/features/PrometheusExporter.d.ts +18 -1
  65. package/dist/features/PrometheusExporter.js +21 -1
  66. package/dist/features/PrometheusExporter.js.map +1 -1
  67. package/dist/index.d.ts +66 -0
  68. package/dist/index.js +78 -0
  69. package/dist/index.js.map +1 -1
  70. package/dist/types/index.d.ts +4 -0
  71. package/dist/types/index.js +24 -0
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/utils/Helpers.d.ts +16 -0
  74. package/dist/utils/Helpers.js +17 -1
  75. package/dist/utils/Helpers.js.map +1 -1
  76. package/dist/utils/MikrotikCollection.d.ts +86 -0
  77. package/dist/utils/MikrotikCollection.js +100 -1
  78. package/dist/utils/MikrotikCollection.js.map +1 -1
  79. package/package.json +18 -8
  80. package/dist/cli/generate.js.map +0 -1
  81. /package/dist/cli/{generate.d.ts → Generate.d.ts} +0 -0
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RosInterface v1.2
1
+ # RosInterface v1.3
2
2
 
3
3
  > **High-Performance RouterOS Automation A modern TypeScript and JavasScript Library for MikroTik interactions.**
4
4
  > Built with Reactive Streaming (onSnapshot), Circuit Breakers for fault tolerance, and an Offline Queue system.
@@ -16,8 +16,12 @@
16
16
 
17
17
  ## English Documentation
18
18
 
19
- **RosInterface** is designed for **ISPs and mission-critical environments**.
20
- It focuses on **connection stability**, **router hardware protection**, and **efficient data access**, even under unstable network conditions.
19
+ **RosInterface** is a high-performance Node.js library designed for ISPs and mission-critical network environments.
20
+ It goes beyond simple API wrappers by introducing a unique Hybrid Engine that seamlessly unifies the transactional safety of REST (HTTPS) with the real-time speed of Sockets (TCP).
21
+ This architecture allows for robust management of mixed environments (RouterOS v6 & v7) without code changes.
22
+
23
+ Built with stability and hardware protection at its core, **RosInterface** ensures efficient data access even under unstable network conditions, preventing CPU spikes and connection floods.
24
+
21
25
 
22
26
  ---
23
27
 
@@ -62,6 +66,19 @@ It focuses on **connection stability**, **router hardware protection**, and **ef
62
66
  - **Intelligent Throttling**
63
67
  Control the flow of real-time data with "Leading + Trailing Edge" strategies.
64
68
 
69
+ - **Intelligent Hybrid Engine:**
70
+
71
+ - Combines the security of the **REST (HTTPS)** protocol for CRUD commands with the speed of **Sockets (TCP)** for data streaming.
72
+ - *RouterOS v7:* Uses HTTPS + Sockets (Background).
73
+ - *RouterOS v6:* Uses pure Sockets (Legacy Mode).
74
+
75
+ - **Swarm Mode:**
76
+ Manages fleets of **50+ routers** from a single instance.
77
+ - Supports **Broadcast** (all nodes) and **Multicast** (selected groups).
78
+ - Fault Tolerance: If one router fails, the rest of the swarm continues operating.
79
+ - Protocol Agnosticism: Mixes modern and legacy routers in the same control group.
80
+
81
+
65
82
  ---
66
83
 
67
84
 
@@ -74,10 +91,47 @@ It focuses on **connection stability**, **router hardware protection**, and **ef
74
91
  Create a `.env` file in the root directory of your project:
75
92
 
76
93
  ```text
77
- MIKROTIK_HOST=ROUTER_IP
78
- MIKROTIK_USER=admin
79
- MIKROTIK_PASSWORD=your_password
80
- MIKROTIK_PORT=8729
94
+ Basic Credentials
95
+ These are the standard login credentials.
96
+
97
+ MIKROTIK_HOST: Your router's IP address (e.g., 192.168.1.1).
98
+
99
+ MIKROTIK_USER: Username with write permissions (e.g., admin).
100
+
101
+ MIKROTIK_PASSWORD: User password.
102
+
103
+ The Brain (Main Protocol)
104
+ Here you decide how commands (Create, Edit, Delete) will be sent.
105
+
106
+ MIKROTIK_PROTOCOL
107
+
108
+ rest: (Recommended for RouterOS v7+). Uses HTTPS. It is more secure and handles errors better.
109
+
110
+ socket: (For RouterOS v6). Uses a raw TCP connection. Use it only if your router is old and does not support REST.
111
+
112
+ MIKROTIK_PORT
113
+
114
+ This is the port for the protocol chosen above.
115
+
116
+ If you use rest: Enter 443 (the router's www-ssl port).
117
+
118
+ If you're using a socket: Enter 8728 (the API port).
119
+
120
+ SSL Security
121
+ MIKROTIK_INSECURE
122
+
123
+ true: (Almost always necessary on local networks). Tells the library: "Trust the router's certificate even if it's self-signed." Uses the secure dispatcher internally.
124
+
125
+ false: Only use this if you've purchased a real domain (e.g., router.example.com) and installed a valid certificate on the Mikrotik.
126
+
127
+ The "Listen" (Hybrid Engine)
128
+ This is the main variable for real-time events (onSnapshot) while using REST.
129
+
130
+ MIKROTIK_PORT_APISSL (or socketPort in the code)
131
+
132
+ If you leave it empty: Hybrid mode is disabled. You can only send commands, but you won't be able to listen for live changes.
133
+
134
+ If you enter 8728: You activate Hybrid Mode. The library will use REST to send commands and will open a hidden channel on 8728 to listen for onSnapshot.
81
135
  ```
82
136
 
83
137
  > ⚠️ **Security Notice**
@@ -95,6 +149,21 @@ MIKROTIK_PORT=8729
95
149
  > Use it **in moderation; excessive use of onSnapshot can negatively affect the performance of your devices**.
96
150
 
97
151
 
152
+ > ⚠️ **Basic Configurations on Your Equipment**
153
+ >
154
+ > Before running these codes, ensure your RouterOS configuration matches:
155
+ > > **Ports (Hybrid Mode):**
156
+ >>
157
+ > > REST (Commands): Requires the www-ssl service enabled on the router (Default port 443).
158
+ >>
159
+ > > Socket (Streaming): Requires the api service (Default 8728) or api-ssl (Default 8729).
160
+ > >
161
+ >> **Certificates (Self-Signed):**
162
+ > >
163
+ > > By setting `rejectUnauthorized: false` in the MikrotikClient options, the library uses the Undici Dispatcher (Agent with Scope).
164
+ > >
165
+ > **This means that traffic remains encrypted (HTTPS), but the library will accept the router's self-generated certificate without failure. This does not compromise the security of other external connections (such as Stripe/AWS) in your Node.js application.**
166
+
98
167
  ---
99
168
 
100
169
 
@@ -363,14 +432,125 @@ async function createSecureUser() {
363
432
  ```
364
433
 
365
434
 
435
+ #### 11. Hybrid Engine (REST + Sockets) & Idempotency
436
+
437
+ ```ts
438
+ import { MikrotikClient } from 'rosinterface';
439
+
440
+ const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
441
+
442
+ async function runHybridTest() {
443
+ console.log("Starting Hybrid Engine Test");
444
+
445
+ const client = new MikrotikClient({
446
+ host: '10.0.0.1',
447
+ user: 'admin',
448
+ password: 'password',
449
+ // HYBRID CONFIGURATION:
450
+ protocol: 'rest', // Primary Brain: HTTPS (Port 443)
451
+ port: 443,
452
+ socketPort: 8728, // Secondary Ear: TCP (Port 8728 for Streams)
453
+ rejectUnauthorized: false // Accept Self-Signed Certs (Safe Dispatcher)
454
+ });
455
+
456
+ try {
457
+ await client.connect();
458
+ console.log("Hybrid Connection Established (HTTPS + TCP)");
459
+
460
+ // LIVE MONITORING (Via Socket 8728)
461
+ console.log("Listening for changes...");
462
+ client.collection('/ppp/secret')
463
+ .onSnapshot(data => {
464
+ if ('added' in data) console.log('Live Stream [New]:', data.added.map(x => x.name));
465
+ if ('removed' in data) console.log('Live Stream [Deleted]:', data.removed.map(x => x.name));
466
+ })
467
+ .onDiff();
468
+
469
+ await delay(1000);
470
+
471
+ // IDEMPOTENCY (Via REST 443)
472
+ // Attempt to create the same user twice. The second time should NOT fail.
473
+ const userPayload = { name: 'hybrid_user', password: '123', service: 'pppoe' };
474
+
475
+ console.log("Creating User...");
476
+ await client.command('/ppp/secret').idempotent().add(userPayload);
477
+
478
+ console.log("Creating User Again (Idempotency Check)...");
479
+ // This will strictly recover the existing ID without throwing an error
480
+ const result = await client.command('/ppp/secret').idempotent().add(userPayload);
481
+ console.log("Idempotency Result:", result); // Should return the existing object
482
+
483
+ await delay(2000);
484
+
485
+ // Cleanup
486
+ await client.command('/ppp/secret').remove(result['.id']);
487
+ console.log("Cleanup done.");
488
+
489
+ } catch (e) {
490
+ console.error("Error:", e);
491
+ } finally {
492
+ // Graceful shutdown prevents "Socket Closed" errors
493
+ client.close();
494
+ }
495
+ }
496
+
497
+ runHybridTest();
498
+ ```
499
+
500
+ #### 12. Swarm Mode (Mass Management)
501
+
502
+ ```ts
503
+ import { MikrotikSwarm } from 'rosinterface';
504
+
505
+ async function runSwarmTest() {
506
+ const swarm = new MikrotikSwarm();
507
+
508
+ // Node A: Modern Router (v7) -> Uses REST
509
+ swarm.addNode('CORE_ROUTER', {
510
+ host: '192.168.1.1',
511
+ user: 'admin',
512
+ password: 'secure',
513
+ protocol: 'rest',
514
+ port: 443
515
+ });
516
+
517
+ // Node B: Legacy Router (v6) -> Uses Sockets
518
+ swarm.addNode('TOWER_A', {
519
+ host: '10.20.30.50',
520
+ user: 'admin',
521
+ password: 'old',
522
+ protocol: 'socket',
523
+ port: 8728
524
+ });
525
+
526
+ console.log("Connecting Swarm...");
527
+ await swarm.connectAll();
528
+
529
+ // BROADCAST: Send command to ALL routers in parallel
530
+ console.log("Broadcasting Firewall Rule...");
531
+ const results = await swarm.broadcast('/ip/dns/set', {
532
+ 'allow-remote-requests': 'yes'
533
+ });
534
+
535
+ results.forEach(res => {
536
+ console.log(`[${res.nodeId}] Success: ${res.success}`);
537
+ });
538
+
539
+ swarm.closeAll();
540
+ }
366
541
 
542
+ runSwarmTest();
543
+ ```
367
544
 
368
545
  ---
369
546
 
370
547
  ## Documentación en Español
371
548
 
372
- **RosInterface** está diseñado para **ISPs y entornos críticos**.
373
- Su objetivo es garantizar **estabilidad de conexión**, **protección del hardware MikroTik** y **consultas eficientes**, incluso con enlaces inestables.
549
+ **RosInterface** es una biblioteca Node.js de alto rendimiento diseñada para proveedores de servicios de internet (ISP) y entornos de red críticos.
550
+ Va más allá de los simples envoltorios de API al introducir un motor híbrido único que unifica a la perfección la seguridad transaccional de REST (HTTPS) con la velocidad en tiempo real de los sockets (TCP).
551
+ Esta arquitectura permite una gestión robusta de entornos mixtos (RouterOS v6 y v7) sin necesidad de modificar el código.
552
+
553
+ Construida con la estabilidad y la protección del hardware como base, **RosInterface** garantiza un acceso eficiente a los datos incluso en condiciones de red inestables, evitando picos de CPU y sobrecargas de conexión.
374
554
 
375
555
  ---
376
556
 
@@ -415,6 +595,20 @@ Su objetivo es garantizar **estabilidad de conexión**, **protección del hardwa
415
595
 
416
596
  Controle el flujo de datos en tiempo real con estrategias de vanguardia y vanguardia.
417
597
 
598
+ - **Motor Híbrido Inteligente:**
599
+
600
+ Combina la seguridad del protocolo **REST (HTTPS)** para comandos CRUD con la velocidad de **Sockets (TCP)** para streaming de datos.
601
+ - *RouterOS v7:* Usa HTTPS + Sockets (Background).
602
+ - *RouterOS v6:* Usa Sockets puro (Legacy Mode).
603
+
604
+ - **Modo Enjambre (Swarm):**
605
+
606
+ Administra flotas de **50+ routers** desde una sola instancia.
607
+ - Soporte para **Broadcast** (todos los nodos) y **Multicast** (grupos selectos).
608
+ - Tolerancia a fallos: Si un router no responde, el resto del enjambre sigue operando.
609
+ - Agnosticismo de Protocolo: Mezcla routers modernos y antiguos en el mismo grupo de control.
610
+
611
+
418
612
  ---
419
613
 
420
614
  ### ✨ Consideraciones Importantes
@@ -424,10 +618,49 @@ Su objetivo es garantizar **estabilidad de conexión**, **protección del hardwa
424
618
  Crea un archivo `.env` en el directorio raíz de tu proyecto:
425
619
 
426
620
  ```text
427
- MIKROTIK_HOST=IP_DEL_ROUTER
428
- MIKROTIK_USER=admin
429
- MIKROTIK_PASSWORD=tu_contraseña
430
- MIKROTIK_PORT=8729
621
+ Credenciales Básicas
622
+ Son los datos de acceso estándar.
623
+
624
+ MIKROTIK_HOST: La IP de tu router (ej. 192.168.1.1).
625
+
626
+ MIKROTIK_USER: Usuario con permisos de escritura (ej. admin).
627
+
628
+ MIKROTIK_PASSWORD: Contraseña del usuario.
629
+
630
+ El Cerebro (Protocolo Principal)
631
+ Aquí decides cómo se enviarán los comandos (Crear, Editar, Borrar).
632
+
633
+ MIKROTIK_PROTOCOL
634
+
635
+ rest: (Recomendado para RouterOS v7+). Usa HTTPS. Es más seguro y maneja mejor los errores.
636
+
637
+ socket: (Para RouterOS v6). Usa conexión TCP cruda. Úsalo solo si tu router es viejo y no soporta REST.
638
+
639
+ MIKROTIK_PORT
640
+
641
+ Es el puerto del protocolo elegido arriba.
642
+
643
+ Si usas rest: Pon 443 (el puerto www-ssl del router).
644
+
645
+ Si usas socket: Pon 8728 (el puerto api).
646
+
647
+ Seguridad SSL
648
+ MIKROTIK_INSECURE
649
+
650
+ true: (Casi siempre necesario en redes locales). Le dice a la librería: "Confía en el certificado del router aunque sea autofirmado". Usa el Dispatcher seguro internamente.
651
+
652
+ false: Solo úsalo si has comprado un dominio real (ej. router.ejemplo.com) y le instalaste un certificado válido al Mikrotik.
653
+
654
+
655
+ El "Oído" (Motor Híbrido)
656
+ Esta es la variable principal para tener eventos en tiempo real (onSnapshot) mientras usas REST.
657
+
658
+ MIKROTIK_PORT_APISSL (o socketPort en el código)
659
+
660
+ Si lo dejas vacío: El modo híbrido se apaga. Solo podrás enviar comandos, pero no escuchar cambios en vivo.
661
+
662
+ Si pones 8728: Activas el Modo Híbrido. La librería usará REST para mandar órdenes y abrirá un canal oculto en el 8728 para escuchar el onSnapshot.
663
+
431
664
  ```
432
665
 
433
666
  > ⚠️ **Aviso de Seguridad**
@@ -444,6 +677,22 @@ MIKROTIK_PORT=8729
444
677
  > Úsala **con moderación, el abuso de onSnapshot puede afectar el rendimiento de tus equipos**.
445
678
 
446
679
 
680
+ > ⚠️ **Configuraciones básicas en tus equipos**
681
+ > Antes de ejecutar estos códigos, asegúrese de que la configuración de RouterOS coincida:
682
+ > > **Puertos (Modo Híbrido):**
683
+ > >
684
+ > > REST (Comandos): Requiere el servicio www-ssl habilitado en el router (Puerto predeterminado 443).
685
+ > >
686
+ > > Socket (Streaming): Requiere el servicio api (Predeterminado 8728) o api-ssl (Predeterminado 8729).
687
+ > >
688
+ >> **Certificados (Autofirmados):**
689
+ > >
690
+ > >Al configurar `rejectUnauthorized: false` en las opciones de MikrotikClient, la biblioteca utiliza el Despachador Undici (Agente con Ámbito).
691
+ > >
692
+ > **Esto implica que el tráfico sigue estando cifrado (HTTPS), pero la biblioteca aceptará el certificado autogenerado del router sin fallar. Esto no compromete la seguridad de otras conexiones externas (como Stripe/AWS) en su aplicación Node.js.**
693
+
694
+
695
+
447
696
 
448
697
  ---
449
698
 
@@ -677,7 +926,7 @@ client.command('/log').print().then(result => {
677
926
  > > npm run codegen -- -p /ppp/secret -n ISecret
678
927
  >
679
928
  > OPCIÓN B: Configuración Manual (Pruebas Rápidas / CI)
680
- > PPasa los detalles de conexión directamente mediante banderas. Usa comillas dobles para contraseñas con caracteres especiales.
929
+ > Pasa los detalles de conexión directamente mediante banderas. Usa comillas dobles para contraseñas con caracteres especiales.
681
930
  > >npm run codegen -- -p /ppp/secret -n ISecret --host ROUTER_IP --user admin --pass "secret123" --port 8728
682
931
 
683
932
 
@@ -712,6 +961,124 @@ async function createSecureUser() {
712
961
  ```
713
962
 
714
963
 
964
+
965
+ #### 11. Hybrid Engine (REST + Sockets) & Idempotency
966
+
967
+ ```ts
968
+ import { MikrotikClient } from 'rosinterface';
969
+
970
+ const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
971
+
972
+ async function ejecutarTestHibrido() {
973
+ console.log("Iniciando Motor Híbrido");
974
+
975
+ const client = new MikrotikClient({
976
+ host: '192.168.1.1',
977
+ user: 'IVMEX',
978
+ password: 'password',
979
+ // CONFIGURACIÓN HÍBRIDA:
980
+ protocol: 'rest', // Cerebro Principal: HTTPS (Puerto 443)
981
+ port: 443,
982
+ socketPort: 8728, // Oído Secundario: TCP (Puerto 8728 para Streams)
983
+ rejectUnauthorized: false // Aceptar Certs Autofirmados (Usa Dispatcher Seguro)
984
+ });
985
+
986
+ try {
987
+ await client.connect();
988
+ console.log("Conexión Híbrida Establecida (HTTPS + TCP)");
989
+
990
+ // A. MONITOREO EN VIVO (Vía Socket 8728)
991
+ console.log("Escuchando cambios...");
992
+ client.collection('/ppp/secret')
993
+ .onSnapshot(data => {
994
+ if ('added' in data) console.log('Stream [Nuevo]:', data.added.map(x => x.name));
995
+ if ('removed' in data) console.log('Stream [Eliminado]:', data.removed.map(x => x.name));
996
+ })
997
+ .onDiff();
998
+
999
+ await delay(1000);
1000
+
1001
+ // B. IDEMPOTENCIA (Vía REST 443)
1002
+ // Intentamos crear el mismo usuario dos veces. La segunda NO debe fallar.
1003
+ const datosUsuario = { name: 'usuario_hibrido', password: '123', service: 'pppoe' };
1004
+
1005
+ console.log("Creando Usuario...");
1006
+ await client.command('/ppp/secret').idempotent().add(datosUsuario);
1007
+
1008
+ console.log("Creando Usuario Nuevamente (Prueba Idempotencia)...");
1009
+ // Esto recuperará el ID existente sin lanzar error
1010
+ const resultado = await client.command('/ppp/secret').idempotent().add(datosUsuario);
1011
+ console.log("Resultado Idempotencia:", resultado); // Debe devolver el objeto existente
1012
+
1013
+ await delay(2000);
1014
+
1015
+ // Limpieza
1016
+ await client.command('/ppp/secret').remove(resultado['.id']);
1017
+ console.log("Limpieza completada.");
1018
+
1019
+ } catch (e) {
1020
+ console.error("Error:", e);
1021
+ } finally {
1022
+ // Cierre elegante evita errores de "Socket Closed"
1023
+ client.close();
1024
+ }
1025
+ }
1026
+
1027
+ ejecutarTestHibrido();
1028
+ ```
1029
+
1030
+
1031
+
1032
+ #### 12. Swarm Mode (Mass Management)
1033
+
1034
+ ```ts
1035
+ import { MikrotikSwarm } from 'rosinterface';
1036
+
1037
+ async function ejecutarTestEnjambre() {
1038
+ const enjambre = new MikrotikSwarm();
1039
+
1040
+ // Nodo A: Router Moderno (v7) -> Usa REST
1041
+ enjambre.addNode('ROUTER_CENTRAL', {
1042
+ host: '192.168.1.1',
1043
+ user: 'admin',
1044
+ password: 'segura',
1045
+ protocol: 'rest',
1046
+ port: 443
1047
+ });
1048
+
1049
+ // Nodo B: Router Antiguo (v6) -> Usa Sockets
1050
+ enjambre.addNode('TORRE_NORTE', {
1051
+ host: '10.20.30.50',
1052
+ user: 'admin',
1053
+ password: 'vieja',
1054
+ protocol: 'socket',
1055
+ port: 8728
1056
+ });
1057
+
1058
+ console.log("Conectando Enjambre...");
1059
+ await enjambre.connectAll();
1060
+
1061
+ // BROADCAST: Enviar comando a TODOS los routers en paralelo
1062
+ console.log("Difundiendo configuración DNS...");
1063
+ const resultados = await enjambre.broadcast('/ip/dns/set', {
1064
+ 'allow-remote-requests': 'yes',
1065
+ 'servers': '8.8.8.8,1.1.1.1'
1066
+ });
1067
+
1068
+ resultados.forEach(res => {
1069
+ if (res.success) {
1070
+ console.log(`[${res.nodeId}] Éxito`);
1071
+ } else {
1072
+ console.log(`[${res.nodeId}] Falló: ${res.error}`);
1073
+ }
1074
+ });
1075
+
1076
+ enjambre.closeAll();
1077
+ }
1078
+
1079
+ ejecutarTestEnjambre();
1080
+ ```
1081
+
715
1082
  ---
716
1083
 
717
1084
  ## Author's Note / Nota del Autor
@@ -44,25 +44,37 @@ const path = __importStar(require("path"));
44
44
  const chalk_1 = __importDefault(require("chalk"));
45
45
  const ora_1 = __importDefault(require("ora"));
46
46
  const dotenv_1 = __importDefault(require("dotenv"));
47
+ // Load .env (if available)
47
48
  dotenv_1.default.config();
48
49
  const program = new commander_1.Command();
49
50
  program
50
51
  .name('ros-codegen')
51
52
  .description('Generates TypeScript interfaces from your live MikroTik router')
52
53
  .version('1.2.0')
54
+ // Mandatory Generation Params
53
55
  .requiredOption('-p, --path <menu>', 'MikroTik Menu Path (e.g. /ppp/secret)')
54
56
  .requiredOption('-n, --name <interface>', 'Name of the output Interface (e.g. PPPSecret)')
55
57
  .option('-o, --output <dir>', 'Output directory', './src/generated')
58
+ // Optional Connection Params (Overrides .env if provided)
56
59
  .option('--host <host>', 'Router Host/IP')
57
60
  .option('--user <user>', 'Router Username')
58
61
  .option('--pass <password>', 'Router Password')
59
62
  .option('--port <port>', 'Router API Port')
60
63
  .option('--tls', 'Use TLS (SSL) connection', false)
61
64
  .action(async (options) => {
65
+ // ==========================================
66
+ // 1. CREDENTIALS RESOLUTION STRATEGY
67
+ // Priority: CLI Flag > Environment Variable
68
+ // ==========================================
62
69
  const host = options.host || process.env.MIKROTIK_HOST;
63
70
  const user = options.user || process.env.MIKROTIK_USER;
64
71
  const password = options.pass || process.env.MIKROTIK_PASS;
72
+ // TLS Logic: Flag OR Env Var string 'true'
65
73
  const useTLS = options.tls || process.env.MIKROTIK_USE_TLS === 'true';
74
+ // Port Logic:
75
+ // 1. CLI Flag
76
+ // 2. Env Var
77
+ // 3. Default based on TLS (8729 vs 8728)
66
78
  let port;
67
79
  if (options.port) {
68
80
  port = parseInt(options.port, 10);
@@ -73,6 +85,7 @@ program
73
85
  else {
74
86
  port = useTLS ? 8729 : 8728;
75
87
  }
88
+ // Pre-flight Validation
76
89
  if (!host || !user || !password) {
77
90
  console.error(chalk_1.default.red('Error: Missing credentials.'));
78
91
  console.error(chalk_1.default.yellow('You must provide credentials via .env file OR CLI flags.'));
@@ -83,23 +96,27 @@ Usage Example:
83
96
  process.exit(1);
84
97
  }
85
98
  const spinner = (0, ora_1.default)(`Connecting to ${host}:${port}...`).start();
99
+ // Initialize Client
86
100
  const client = new MikrotikClient_1.MikrotikClient({
87
101
  host: host,
88
102
  user: user,
89
103
  password: password,
90
104
  port: port,
91
105
  useTLS: useTLS,
92
- allowInsecureConfig: true
106
+ allowInsecureConfig: true // Suppress warnings for CLI tool since hardcoding is expected here
93
107
  });
94
108
  try {
95
109
  await client.connect();
96
110
  spinner.text = `Fetching schema from ${options.path}...`;
111
+ // Fetch Real Data (The "Truth")
97
112
  const data = await client.write(`${options.path}/print`);
98
113
  if (data.length === 0) {
99
114
  spinner.warn(chalk_1.default.yellow(' Warning: No data found in this menu. Generated interface will be empty or generic.'));
100
115
  }
116
+ // Infer Schema
101
117
  spinner.text = 'Inferring Types & Generating Code...';
102
118
  const tsCode = SchemaInferrer_1.SchemaInferrer.generateInterface(options.name, data);
119
+ // Add File Header
103
120
  const fileContent = `
104
121
  /**
105
122
  * AUTO-GENERATED FILE - DO NOT EDIT MANUALLY
@@ -110,11 +127,13 @@ Usage Example:
110
127
 
111
128
  ${tsCode}
112
129
  `;
130
+ // Write to File
113
131
  const outputDir = path.resolve(options.output);
114
132
  await fs.ensureDir(outputDir);
115
133
  const filePath = path.join(outputDir, `${options.name}.ts`);
116
134
  await fs.writeFile(filePath, fileContent);
117
135
  spinner.succeed(chalk_1.default.green(`Successfully generated ${options.name}.ts in ${options.output}`));
136
+ // Show Preview
118
137
  console.log(chalk_1.default.gray('\nPreview:'));
119
138
  console.log(chalk_1.default.cyan(tsCode.split('\n').slice(0, 15).join('\n') + '\n...'));
120
139
  }
@@ -136,4 +155,4 @@ ${tsCode}
136
155
  }
137
156
  });
138
157
  program.parse(process.argv);
139
- //# sourceMappingURL=generate.js.map
158
+ //# sourceMappingURL=Generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Generate.js","sourceRoot":"","sources":["../../src/cli/Generate.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,13 @@
1
+ /**
2
+ * Analyzes raw MikroTik data and infers TypeScript types.
3
+ */
1
4
  export declare class SchemaInferrer {
5
+ /**
6
+ * Main entry point: Generates the Interface string from raw data items.
7
+ */
2
8
  static generateInterface(interfaceName: string, dataSample: Record<string, any>[]): string;
9
+ /**
10
+ * Heuristic Engine to determine the best TypeScript type.
11
+ */
3
12
  private static inferType;
4
13
  }
@@ -1,9 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SchemaInferrer = void 0;
4
+ /**
5
+ * Analyzes raw MikroTik data and infers TypeScript types.
6
+ */
4
7
  class SchemaInferrer {
8
+ /**
9
+ * Main entry point: Generates the Interface string from raw data items.
10
+ */
5
11
  static generateInterface(interfaceName, dataSample) {
6
12
  const fieldStats = {};
13
+ // Collect all possible values for each field across the sample
7
14
  dataSample.forEach(item => {
8
15
  Object.keys(item).forEach(key => {
9
16
  if (!fieldStats[key])
@@ -11,30 +18,42 @@ class SchemaInferrer {
11
18
  fieldStats[key].add(String(item[key]));
12
19
  });
13
20
  });
21
+ // Build the Interface lines
14
22
  const lines = [];
15
23
  lines.push(`export interface ${interfaceName} {`);
16
24
  Object.keys(fieldStats).sort().forEach(key => {
17
25
  const values = Array.from(fieldStats[key]);
18
26
  const type = this.inferType(key, values);
27
+ // MikroTik fields are mostly optional as they depend on configuration
19
28
  const isOptional = true;
20
- const propName = key.includes('-') ? `'${key}'` : key;
29
+ const propName = key.includes('-') ? `'${key}'` : key; // Quote kebab-case
21
30
  lines.push(` /** Sample values: ${values.slice(0, 3).join(', ')}... */`);
22
31
  lines.push(` ${propName}${isOptional ? '?' : ''}: ${type};`);
23
32
  });
24
33
  lines.push(`}`);
25
34
  return lines.join('\n');
26
35
  }
36
+ /**
37
+ * Heuristic Engine to determine the best TypeScript type.
38
+ */
27
39
  static inferType(key, values) {
40
+ // Boolean Detection (true/false/yes/no)
28
41
  const isBoolean = values.every(v => ['true', 'false', 'yes', 'no'].includes(v.toLowerCase()));
29
42
  if (isBoolean)
30
- return 'boolean | string';
43
+ return 'boolean | string'; // string fallback for safety
44
+ // Number Detection
45
+ // Checks if all values look like numbers (ignoring empty strings)
31
46
  const isNumber = values.every(v => v === '' || !isNaN(Number(v)));
32
47
  if (isNumber && values.length > 0)
33
48
  return 'number | string';
49
+ // Enum / Union Type Detection
50
+ // If we see very few unique values (e.g. 'running' | 'stopped'), create a Union.
51
+ // Limit: Max 10 unique values to consider it an Enum.
34
52
  if (values.length > 0 && values.length < 10 && !isNumber) {
35
53
  const union = values.map(v => `'${v}'`).join(' | ');
36
- return `${union} | string`;
54
+ return `${union} | string`; // Append string to allow future values
37
55
  }
56
+ // Default
38
57
  return 'string';
39
58
  }
40
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaInferrer.js","sourceRoot":"","sources":["../../src/cli/SchemaInferrer.ts"],"names":[],"mappings":";;;AAGA,MAAa,cAAc;IAKhB,MAAM,CAAC,iBAAiB,CAAC,aAAqB,EAAE,UAAiC;QACpF,MAAM,UAAU,GAAgC,EAAE,CAAC;QAGnD,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACtB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,UAAU,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;gBAClD,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAGH,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,oBAAoB,aAAa,IAAI,CAAC,CAAC;QAElD,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACzC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAGzC,MAAM,UAAU,GAAG,IAAI,CAAC;YACxB,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAEtD,KAAK,CAAC,IAAI,CAAC,0BAA0B,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC5E,KAAK,CAAC,IAAI,CAAC,OAAO,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,GAAG,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAKO,MAAM,CAAC,SAAS,CAAC,GAAW,EAAE,MAAgB;QAElD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC9F,IAAI,SAAS;YAAE,OAAO,kBAAkB,CAAC;QAIzC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,iBAAiB,CAAC;QAK5D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpD,OAAO,GAAG,KAAK,WAAW,CAAC;QAC/B,CAAC;QAGD,OAAO,QAAQ,CAAC;IACpB,CAAC;CACJ;AA5DD,wCA4DC"}
1
+ {"version":3,"file":"SchemaInferrer.js","sourceRoot":"","sources":["../../src/cli/SchemaInferrer.ts"],"names":[],"mappings":"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"}