mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-11 01:55:43 +00:00
dd0889e3d6
Introduce a SessionManager for relay-based remote sessions in the Tauri MGMT client: new SessionCommand API, start/stop/session input routing, clipboard/recording/quality controls, and notification read/dismiss state. Wire AppState with new mutexes and show main window on startup. CI: add SBOM generation (anchore) and Trivy vulnerability scan steps. Misc: change console Docker DB path, large README/CHANGELOG updates (chat E2E, unattended access/WOL, i18n expansion, CDAP/SDK docs), and many web-nodejs assets/locales/routes/views/services and server-side changes.
154 lines
4.6 KiB
Markdown
154 lines
4.6 KiB
Markdown
# Node.js SDK Reference — `betterdesk-cdap`
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install betterdesk-cdap
|
|
# or from source:
|
|
npm install ./sdks/nodejs/
|
|
```
|
|
|
|
**Requirements:** Node.js 18+, `ws ^8.18.0`
|
|
|
|
## CDAPBridge
|
|
|
|
The main class. Extends `EventEmitter`.
|
|
|
|
```javascript
|
|
const { CDAPBridge, Widget } = require('betterdesk-cdap');
|
|
```
|
|
|
|
### Constructor
|
|
|
|
```javascript
|
|
const bridge = new CDAPBridge({
|
|
serverUrl: 'ws://host:21122/cdap', // WebSocket URL
|
|
deviceId: 'MY-DEVICE', // Unique device ID
|
|
deviceName: 'My Device', // Human-readable name
|
|
deviceType: 'custom_agent', // Device type
|
|
authMethod: 'api_key', // api_key | device_token | user_password
|
|
apiKey: 'YOUR_KEY', // API key
|
|
capabilities: ['telemetry', 'commands'],
|
|
heartbeatSec: 15, // Heartbeat interval
|
|
reconnectSec: 5, // Base reconnect delay
|
|
});
|
|
```
|
|
|
|
### Methods
|
|
|
|
| Method | Description |
|
|
|--------|-------------|
|
|
| `addWidget(widget)` | Add a Widget to the manifest |
|
|
| `connect()` | Connect to server (auto-reconnects) |
|
|
| `disconnect()` | Gracefully disconnect |
|
|
| `updateWidget(id, value)` | Update a single widget value |
|
|
| `bulkUpdate(values)` | Update multiple widget values `{ id: value }` |
|
|
| `sendCommandResponse(cmdId, success, result)` | Respond to a command |
|
|
| `sendAlert(severity, message, source)` | Send an alert |
|
|
|
|
### Events
|
|
|
|
```javascript
|
|
bridge.on('connected', () => { /* auth + manifest done */ });
|
|
bridge.on('disconnected', () => { /* connection lost */ });
|
|
bridge.on('command', async (cmdId, command, args) => { /* handle command */ });
|
|
bridge.on('collectMetrics', async () => { /* return { id: value } */ });
|
|
bridge.on('error', (err) => { /* handle error */ });
|
|
```
|
|
|
|
## Widget
|
|
|
|
Factory class for creating CDAP widgets.
|
|
|
|
### Factory Methods
|
|
|
|
```javascript
|
|
Widget.gauge(id, label, { group, unit, min, max, danger, warning })
|
|
Widget.toggle(id, label, { group, onCommand, offCommand })
|
|
Widget.button(id, label, { group, command, confirm })
|
|
Widget.led(id, label, { group, onColor, offColor })
|
|
Widget.text(id, label, { group })
|
|
Widget.slider(id, label, { group, min, max, step, command })
|
|
Widget.select(id, label, { group, options, command })
|
|
Widget.chart(id, label, { group, maxPoints })
|
|
```
|
|
|
|
### Example
|
|
|
|
```javascript
|
|
bridge.addWidget(Widget.gauge('cpu', 'CPU Usage', {
|
|
group: 'System', unit: '%', min: 0, max: 100, danger: 90, warning: 70
|
|
}));
|
|
|
|
bridge.addWidget(Widget.text('hostname', 'Hostname', { group: 'Info' }));
|
|
|
|
bridge.addWidget(Widget.button('restart', 'Restart Service', {
|
|
group: 'Actions', command: 'restart_svc', confirm: true
|
|
}));
|
|
```
|
|
|
|
## Complete Example
|
|
|
|
```javascript
|
|
const { CDAPBridge, Widget } = require('betterdesk-cdap');
|
|
const os = require('os');
|
|
|
|
const bridge = new CDAPBridge({
|
|
serverUrl: process.env.CDAP_SERVER || 'ws://localhost:21122/cdap',
|
|
deviceId: `NODE-${os.hostname().toUpperCase()}`,
|
|
deviceName: os.hostname(),
|
|
deviceType: 'os_agent',
|
|
authMethod: 'api_key',
|
|
apiKey: process.env.CDAP_API_KEY,
|
|
capabilities: ['telemetry', 'commands']
|
|
});
|
|
|
|
bridge.addWidget(Widget.gauge('cpu', 'CPU', { group: 'System', unit: '%', max: 100, danger: 90 }));
|
|
bridge.addWidget(Widget.gauge('mem', 'Memory', { group: 'System', unit: '%', max: 100, danger: 85 }));
|
|
bridge.addWidget(Widget.text('uptime', 'Uptime', { group: 'Info' }));
|
|
|
|
bridge.on('connected', () => console.log('Connected to BetterDesk'));
|
|
|
|
bridge.on('collectMetrics', () => {
|
|
const cpus = os.cpus();
|
|
const idle = cpus.reduce((sum, c) => sum + c.times.idle, 0) / cpus.length;
|
|
const total = cpus.reduce((sum, c) => sum + Object.values(c.times).reduce((a, b) => a + b), 0) / cpus.length;
|
|
const freeMem = os.freemem();
|
|
const totalMem = os.totalmem();
|
|
|
|
return {
|
|
cpu: Math.round((1 - idle / total) * 100),
|
|
mem: Math.round(((totalMem - freeMem) / totalMem) * 100),
|
|
uptime: `${Math.floor(os.uptime() / 3600)}h ${Math.floor((os.uptime() % 3600) / 60)}m`
|
|
};
|
|
});
|
|
|
|
bridge.on('command', (cmdId, command, args) => {
|
|
if (command === 'get_hostname') {
|
|
bridge.sendCommandResponse(cmdId, true, os.hostname());
|
|
} else {
|
|
bridge.sendCommandResponse(cmdId, false, `Unknown command: ${command}`);
|
|
}
|
|
});
|
|
|
|
bridge.connect();
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
```javascript
|
|
bridge.on('error', (err) => {
|
|
console.error('Bridge error:', err.message);
|
|
// SDK handles reconnection automatically
|
|
});
|
|
|
|
// For unhandled command errors
|
|
bridge.on('command', async (cmdId, command, args) => {
|
|
try {
|
|
// ... your logic
|
|
} catch (err) {
|
|
bridge.sendCommandResponse(cmdId, false, err.message);
|
|
}
|
|
});
|
|
```
|